diff --git a/media/attribution.js b/media/attribution.js
index 7bcbc20b..49c10d82 100644
--- a/media/attribution.js
+++ b/media/attribution.js
@@ -20905,6 +20905,16 @@ const attributionData = {
"https://www.homedepot.com/p/L-I-F-Industries-36-in-x-80-in-Gray-Flush-Exit-Left-Hand-Fire-Proof-Steel-Prehung-Commercial-Door-with-Welded-Frame-UWX3680L/202510508"
]
},
+ {
+ prefix: "./media/buildings/Sheds/",
+ all: null,
+ authors: [
+ "chemicalcrux"
+ ],
+ citations: [
+ "https://lpcorp.com/products/exterior/sheds/buying-vs-building/pick-a-plan"
+ ]
+ },
{
prefix: "./media/objects/Cards/",
all: null,
diff --git a/media/buildings/Sheds/Large Shed-Angled.svg b/media/buildings/Sheds/Large Shed-Angled.svg
new file mode 100644
index 00000000..4ce7f95d
--- /dev/null
+++ b/media/buildings/Sheds/Large Shed-Angled.svg
@@ -0,0 +1,105 @@
+
+
diff --git a/media/buildings/Sheds/Large Shed-Back.svg b/media/buildings/Sheds/Large Shed-Back.svg
new file mode 100644
index 00000000..db815503
--- /dev/null
+++ b/media/buildings/Sheds/Large Shed-Back.svg
@@ -0,0 +1,87 @@
+
+
diff --git a/media/buildings/Sheds/Large Shed-Corner.svg b/media/buildings/Sheds/Large Shed-Corner.svg
new file mode 100644
index 00000000..343e9f1b
--- /dev/null
+++ b/media/buildings/Sheds/Large Shed-Corner.svg
@@ -0,0 +1,93 @@
+
+
diff --git a/media/buildings/Sheds/Large Shed-Front.svg b/media/buildings/Sheds/Large Shed-Front.svg
new file mode 100644
index 00000000..5987d135
--- /dev/null
+++ b/media/buildings/Sheds/Large Shed-Front.svg
@@ -0,0 +1,90 @@
+
+
diff --git a/media/buildings/Sheds/Large Shed-Side.svg b/media/buildings/Sheds/Large Shed-Side.svg
new file mode 100644
index 00000000..51189d8c
--- /dev/null
+++ b/media/buildings/Sheds/Large Shed-Side.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/media/buildings/Sheds/Large Shed-Top.svg b/media/buildings/Sheds/Large Shed-Top.svg
new file mode 100644
index 00000000..81fe4d79
--- /dev/null
+++ b/media/buildings/Sheds/Large Shed-Top.svg
@@ -0,0 +1,55 @@
+
+
diff --git a/media/buildings/Sheds/Medium Shed-Angled.svg b/media/buildings/Sheds/Medium Shed-Angled.svg
new file mode 100644
index 00000000..1b9428a2
--- /dev/null
+++ b/media/buildings/Sheds/Medium Shed-Angled.svg
@@ -0,0 +1,111 @@
+
+
diff --git a/media/buildings/Sheds/Medium Shed-Back.svg b/media/buildings/Sheds/Medium Shed-Back.svg
new file mode 100644
index 00000000..b31b2632
--- /dev/null
+++ b/media/buildings/Sheds/Medium Shed-Back.svg
@@ -0,0 +1,81 @@
+
+
diff --git a/media/buildings/Sheds/Medium Shed-Corner.svg b/media/buildings/Sheds/Medium Shed-Corner.svg
new file mode 100644
index 00000000..e9972532
--- /dev/null
+++ b/media/buildings/Sheds/Medium Shed-Corner.svg
@@ -0,0 +1,99 @@
+
+
diff --git a/media/buildings/Sheds/Medium Shed-Front.svg b/media/buildings/Sheds/Medium Shed-Front.svg
new file mode 100644
index 00000000..d944c569
--- /dev/null
+++ b/media/buildings/Sheds/Medium Shed-Front.svg
@@ -0,0 +1,90 @@
+
+
diff --git a/media/buildings/Sheds/Medium Shed-Side.svg b/media/buildings/Sheds/Medium Shed-Side.svg
new file mode 100644
index 00000000..7498e2a5
--- /dev/null
+++ b/media/buildings/Sheds/Medium Shed-Side.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/media/buildings/Sheds/Medium Shed-Top.svg b/media/buildings/Sheds/Medium Shed-Top.svg
new file mode 100644
index 00000000..cd6c7a32
--- /dev/null
+++ b/media/buildings/Sheds/Medium Shed-Top.svg
@@ -0,0 +1,55 @@
+
+
diff --git a/media/buildings/Sheds/Small Shed-Angled.svg b/media/buildings/Sheds/Small Shed-Angled.svg
new file mode 100644
index 00000000..7a33bed8
--- /dev/null
+++ b/media/buildings/Sheds/Small Shed-Angled.svg
@@ -0,0 +1,99 @@
+
+
diff --git a/media/buildings/Sheds/Small Shed-Back.svg b/media/buildings/Sheds/Small Shed-Back.svg
new file mode 100644
index 00000000..162ed498
--- /dev/null
+++ b/media/buildings/Sheds/Small Shed-Back.svg
@@ -0,0 +1,74 @@
+
+
diff --git a/media/buildings/Sheds/Small Shed-Corner.svg b/media/buildings/Sheds/Small Shed-Corner.svg
new file mode 100644
index 00000000..ffd1fc63
--- /dev/null
+++ b/media/buildings/Sheds/Small Shed-Corner.svg
@@ -0,0 +1,96 @@
+
+
diff --git a/media/buildings/Sheds/Small Shed-Front.svg b/media/buildings/Sheds/Small Shed-Front.svg
new file mode 100644
index 00000000..7b8d8a2e
--- /dev/null
+++ b/media/buildings/Sheds/Small Shed-Front.svg
@@ -0,0 +1,84 @@
+
+
diff --git a/media/buildings/Sheds/Small Shed-Side.svg b/media/buildings/Sheds/Small Shed-Side.svg
new file mode 100644
index 00000000..33d968c1
--- /dev/null
+++ b/media/buildings/Sheds/Small Shed-Side.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/media/buildings/Sheds/Small Shed-Top.svg b/media/buildings/Sheds/Small Shed-Top.svg
new file mode 100644
index 00000000..bb94241f
--- /dev/null
+++ b/media/buildings/Sheds/Small Shed-Top.svg
@@ -0,0 +1,55 @@
+
+
diff --git a/presets/buildings.js b/presets/buildings.js
index d23c0782..0a658132 100644
--- a/presets/buildings.js
+++ b/presets/buildings.js
@@ -346,6 +346,7 @@ function makeBuildings() {
/* ***Fences*** */ results.push(makeModel({"name": "Fences", "kind": "buildings", "forms": [{"name": "Picket", "views": [{"name": "Front", "height": 1.198826789855957, "extra": 1.0032463354037267, "bottom": 0.003225393982374819}, {"name": "Angled", "height": 1.198826789855957, "extra": 1.0030113600426571, "bottom": 0.0029933320416477963}, {"name": "Corner", "height": 1.198826789855957, "extra": 1.0043504818571962, "bottom": 0.004312954992306321}, {"name": "Side", "height": 1.198826789855957, "extra": 1.0012004801920769, "bottom": 0.0011976047904191617}, {"name": "Top", "height": 0.12314067780971527, "extra": 1.0294348106917595, "bottom": 0.027798333333333345}]}, {"name": "Wrought Iron", "views": [{"name": "Front", "height": 0.9687931537628174, "extra": 1.0031269052863436, "bottom": 0.003107471746679822}, {"name": "Angled", "height": 0.9687931537628174, "extra": 1.0039823942771011, "bottom": 0.003950925987021264}, {"name": "Corner", "height": 0.9687931537628174, "extra": 1.0022842993630574, "bottom": 0.002273910777177546}, {"name": "Side", "height": 0.9687931537628174, "extra": 1.0009630172676205, "bottom": 0.0009611660286552252}, {"name": "Top", "height": 0.07901737093925476, "extra": 1.0543478819116272, "bottom": 0.049019653258358886}]}]}));
/* ***Doors*** */ results.push(makeModel({"name": "Doors", "kind": "buildings", "forms": [{"name": "6 Panel Door", "views": [{"name": "Front", "height": 2.0320000648498535, "mass": 11.793399810791016}, {"name": "Angled", "height": 2.0320000648498535, "mass": 11.793399810791016}, {"name": "Side", "height": 2.0320000648498535, "mass": 11.793399810791016}, {"name": "Top", "height": 0.03492499887943268, "mass": 11.793399810791016}]}, {"name": "French Door", "views": [{"name": "Front", "height": 2.0320000648498535, "mass": 31.75149917602539}, {"name": "Angled", "height": 2.0320000648498535, "mass": 31.75149917602539}, {"name": "Side", "height": 2.0320000648498535, "mass": 31.75149917602539}, {"name": "Top", "height": 0.03492499887943268, "mass": 31.75149917602539}]}, {"name": "Fire Door", "views": [{"name": "Front", "height": 2.0320000648498535, "mass": 54.54545593261719}, {"name": "Angled", "height": 2.0320000648498535, "mass": 54.54545593261719}, {"name": "Side", "height": 2.0320000648498535, "mass": 54.54545593261719}, {"name": "Top", "height": 0.10518216341733932, "mass": 54.54545593261719}]}]}));
/* ***Times Square NYE*** */ results.push(makeModel({"name": "Times Square NYE", "kind": "buildings", "forms": [{"name": "Ball", "views": [{"name": "Front", "height": 3.4989547729492188, "mass": 5397.72705078125, "extra": 1.0016937456872217, "bottom": 0.0016880275085964648}, {"name": "Angled", "height": 3.4989547729492188, "mass": 5397.72705078125, "extra": 1.0025409836065575, "bottom": 0.00252813570380047}, {"name": "Corner", "height": 3.4989547729492188, "mass": 5397.72705078125, "extra": 1.0018165582086815, "bottom": 0.00180998233215548}, {"name": "Side", "height": 3.4989547729492188, "mass": 5397.72705078125, "extra": 1.001850383633639, "bottom": 0.001843561043274757}, {"name": "Back", "height": 3.4989547729492188, "mass": 5397.72705078125, "extra": 1.0016623910180016, "bottom": 0.0016568822456753673}, {"name": "Top", "height": 3.657600164413452, "mass": 5397.72705078125, "extra": 1.001771054685155, "bottom": 0.001764803557935817}]}, {"name": "Tower", "views": [{"name": "Front", "height": 23.458213806152344, "extra": 1.0016112545018008, "bottom": 0.0016060788980911244}, {"name": "Angled", "height": 23.458213806152344, "extra": 1.0016112545018008, "bottom": 0.0016060788980911244}, {"name": "Corner", "height": 23.458213806152344, "extra": 1.0016112545018008, "bottom": 0.0016060788980911244}, {"name": "Side", "height": 23.458213806152344, "extra": 1.0016112545018008, "bottom": 0.0016060788980911244}, {"name": "Back", "height": 23.458213806152344, "extra": 1.0016112545018008, "bottom": 0.0016060788980911244}, {"name": "Top", "height": 1.5605759620666504, "extra": 1.0015567074184117, "bottom": 0.0015518757853168342}]}, {"name": "2022", "views": [{"name": "Front", "height": 2.1339330673217773, "extra": 1.003530708012506, "bottom": 0.0035059510336938327}, {"name": "Angled", "height": 2.1339330673217773, "extra": 1.0047998012242747, "bottom": 0.004754163148077668}, {"name": "Corner", "height": 2.1339330673217773, "extra": 1.0028325, "bottom": 0.002816544276672584}, {"name": "Side", "height": 2.1339330673217773, "extra": 1.001694837935174, "bottom": 0.0016891123916577266}, {"name": "Back", "height": 2.1339330673217773, "extra": 1.003530708012506, "bottom": 0.0035059510336938327}, {"name": "Top", "height": 0.4862631559371948, "extra": 1.0157526272448099, "bottom": 0.01527149491119562}]}]}));
+ /* ***Sheds*** */ results.push(makeModel({"name": "Sheds", "kind": "buildings", "forms": [{"name": "Small Shed", "views": [{"name": "Front", "height": 3.479300022125244, "extra": 1.005440565201383, "bottom": 0.0053820029257200174}, {"name": "Angled", "height": 3.479300022125244, "extra": 1.0054253856774116, "bottom": 0.0053671479818332875}, {"name": "Corner", "height": 3.479300022125244, "extra": 1.0053985294117647, "bottom": 0.005340863791242229}, {"name": "Side", "height": 3.479300022125244, "extra": 1.0054021608643458, "bottom": 0.005344418052256532}, {"name": "Back", "height": 3.479300022125244, "extra": 1.005440565201383, "bottom": 0.0053820029257200174}, {"name": "Top", "height": 2.638400077819824, "extra": 1.0066026410564226, "bottom": 0.006516587677725118}]}, {"name": "Medium Shed", "views": [{"name": "Front", "height": 3.9618988037109375, "extra": 1.0048322228224984, "bottom": 0.004785969084423278}, {"name": "Angled", "height": 3.9618988037109375, "extra": 1.0047982893157263, "bottom": 0.004752679849837231}, {"name": "Corner", "height": 3.9618988037109375, "extra": 1.004316382460414, "bottom": 0.004279439068938889}, {"name": "Side", "height": 3.9618988037109375, "extra": 1.0048019207683074, "bottom": 0.0047562425683709865}, {"name": "Back", "height": 3.9618988037109375, "extra": 1.0048322228224984, "bottom": 0.004785969084423278}, {"name": "Top", "height": 3.0480000972747803, "extra": 1.006093637454982, "bottom": 0.006020266808357238}]}, {"name": "Large Shed", "views": [{"name": "Front", "height": 4.26669979095459, "extra": 1.0041839246053184, "bottom": 0.004149204686160603}, {"name": "Angled", "height": 4.26669979095459, "extra": 1.0043687027707808, "bottom": 0.004330862270776434}, {"name": "Corner", "height": 4.26669979095459, "extra": 1.0035310734463276, "bottom": 0.0035063113604488078}, {"name": "Side", "height": 4.26669979095459, "extra": 1.004201680672269, "bottom": 0.004166666666666667}, {"name": "Back", "height": 4.26669979095459, "extra": 1.0041839246053184, "bottom": 0.004149204686160603}, {"name": "Top", "height": 3.857600212097168, "extra": 1.0048019207683074, "bottom": 0.0047562425683709865}]}]}));
/* ***INSERT HERE*** */
results.sort((b1, b2) => {
diff --git a/scripts/blender/addons/macrovision/ops.py b/scripts/blender/addons/macrovision/ops.py
index 0004b39a..c94bdbe4 100644
--- a/scripts/blender/addons/macrovision/ops.py
+++ b/scripts/blender/addons/macrovision/ops.py
@@ -6,6 +6,7 @@ import pathlib
import os
from math import pi
import random
+import bmesh
VIEW_DATA = {
"FRONT": [0, 1, 2, "Front"],
@@ -80,6 +81,10 @@ class MVConfigCollection(bpy.types.Operator):
new_cam = bpy.data.cameras.new("cam")
new_obj = bpy.data.objects.new("cam", new_cam)
context.scene.collection.objects.link(new_obj)
+ if "cam2" not in bpy.data.objects:
+ new_cam = bpy.data.cameras.new("cam2")
+ new_obj = bpy.data.objects.new("cam2", new_cam)
+ context.scene.collection.objects.link(new_obj)
if "Lines" not in bpy.data.materials:
mat = bpy.data.materials.new("Lines")
@@ -118,14 +123,13 @@ class MVAssignMaterials(bpy.types.Operator):
collections = mv.children
for coll in collections:
+ object: bpy.types.Object
for object in coll.objects:
if object.type != "MESH":
continue
-
- for index in range(len(object.material_slots)):
- if object.material_slots[index].material.name in ('light', 'medium', 'dark'):
- continue
- if context.scene.mv_material_mode == 'RANDOM':
+
+ if context.scene.mv_material_mode == 'RANDOM':
+ for index in range(len(object.material_slots)):
choices = [
bpy.data.materials['light'],
bpy.data.materials['medium'],
@@ -133,8 +137,11 @@ class MVAssignMaterials(bpy.types.Operator):
]
object.material_slots[index].material = random.choice(choices)
+ elif context.scene.mv_material_mode == 'NAMES':
+ for index in range(len(object.material_slots)):
+ if object.material_slots[index].material.name in ('light', 'medium', 'dark'):
+ continue
- if context.scene.mv_material_mode == 'NAMES':
material = object.material_slots[index].material
light_choices = context.scene.mv_material_names_light.split(",")
medium_choices = context.scene.mv_material_names_medium.split(",")
@@ -155,6 +162,53 @@ class MVAssignMaterials(bpy.types.Operator):
chosen = bpy.data.materials['dark']
object.material_slots[index].material = chosen
+ elif context.scene.mv_material_mode == 'FACE_MAPS':
+ while len(object.material_slots) > 0:
+ bpy.ops.object.material_slot_remove({'object': object})
+
+ light_choices = context.scene.mv_material_names_light.split(",")
+ medium_choices = context.scene.mv_material_names_medium.split(",")
+
+ for map in object.face_maps:
+
+ chosen = None
+
+ if map.name in light_choices:
+ chosen = bpy.data.materials['light']
+ if map.name in medium_choices:
+ chosen = bpy.data.materials['medium']
+
+ if chosen is None:
+ chosen = bpy.data.materials['dark']
+
+ bpy.ops.object.material_slot_add({'object': object})
+ index = len(object.material_slots) - 1
+ object.material_slots[index].material = chosen
+
+ bpy.ops.object.material_slot_add({'object': object})
+ missing_idx = len(object.material_slots) - 1
+ object.material_slots[missing_idx].material = bpy.data.materials['dark']
+ bm: bpy.types.BMesh
+
+ bpy.ops.object.select_all(action='DESELECT')
+ object.select_set(True)
+ bpy.ops.object.mode_set(mode = 'EDIT')
+ bm = bmesh.from_edit_mesh(object.data)
+
+ fm = bm.faces.layers.face_map.verify()
+
+ for face in bm.faces:
+ idx = face[fm]
+ print(idx)
+ if idx >= 0:
+ face.material_index = idx
+ else:
+ face.material_index = missing_idx
+
+ object.data.update()
+ bm.free()
+ print("OK")
+ bpy.ops.object.mode_set(mode = 'OBJECT')
return {'FINISHED'}
@@ -172,12 +226,14 @@ class MVExport(bpy.types.Operator):
parent_workdir = config["work-directory"]
c = bpy.data.objects["cam"]
+ c2 = bpy.data.objects["cam2"]
context.scene.camera = c
lineart = bpy.data.objects["lineart"]
lineart.grease_pencil_modifiers['Lineart'].source_type = 'COLLECTION'
c.data.type = "ORTHO"
+ c2.data.type = "ORTHO"
bpy.data.scenes["Scene"].render.resolution_x = 2000
bpy.data.scenes["Scene"].render.resolution_y = 2000
@@ -257,6 +313,12 @@ class MVExport(bpy.types.Operator):
c.data.clip_start = size / 4
c.data.clip_end = size * 8
+ c2.rotation_euler = Euler([angles[1] * pi / 2 + 0.001, 0.001, angles[0] * pi / 2 + 0.001])
+ c2.location = c.location
+ c2.data.ortho_scale = c.data.ortho_scale
+ c2.data.clip_start = c.data.clip_start
+ c2.data.clip_end = c2.data.clip_end
+
scale_factor = (10 ** context.scene.mv_scale_factor)
height = dimensions[angles[2]] * scale_factor
diff --git a/scripts/blender/addons/macrovision/props.py b/scripts/blender/addons/macrovision/props.py
index c3446f08..b12d8466 100644
--- a/scripts/blender/addons/macrovision/props.py
+++ b/scripts/blender/addons/macrovision/props.py
@@ -57,7 +57,8 @@ scene_props["mv_material_mode"] = bpy.props.EnumProperty(
description = "How to decide what to replace each material with",
items = (
('RANDOM', "Random", 'Randomly assign materials'),
- ('NAMES', "Names", 'Turn the specified names medium or light; the rest become dark')
+ ('NAMES', "Names", 'Turn the specified names medium or light; the rest become dark'),
+ ('FACE_MAPS', "Face Maps", "Assign a material for each face map")
),
)
diff --git a/scripts/blender/addons/macrovision/ui.py b/scripts/blender/addons/macrovision/ui.py
index f7d75464..c7b57d67 100644
--- a/scripts/blender/addons/macrovision/ui.py
+++ b/scripts/blender/addons/macrovision/ui.py
@@ -60,7 +60,7 @@ class MVPanel(bpy.types.Panel):
box.prop(context.scene, "mv_material_mode")
- if context.scene.mv_material_mode == "NAMES":
+ if context.scene.mv_material_mode in ('NAMES', 'FACE_MAPS'):
box.prop(context.scene, "mv_material_names_light")
box.prop(context.scene, "mv_material_names_medium")