IFC Array - option to use local space instead of global (#2905)

This commit is contained in:
Andrej730
2023-03-28 15:39:18 +05:00
parent f6ca12d3b8
commit 75f56462b5
4 changed files with 45 additions and 28 deletions
@@ -34,7 +34,7 @@ class AddArray(bpy.types.Operator, tool.Ifc.Operator):
obj = context.active_object obj = context.active_object
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
array = {"children": [], "count": 1, "x": 0.0, "y": 0.0, "z": 0.0} array = {"children": [], "count": 1, "x": 0.0, "y": 0.0, "z": 0.0, "use_local_space": True}
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Array") pset = ifcopenshell.util.element.get_pset(element, "BBIM_Array")
@@ -61,7 +61,27 @@ class DisableEditingArray(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER"} bl_options = {"REGISTER"}
def _execute(self, context): def _execute(self, context):
props = context.active_object.BIMArrayProperties.is_editing = -1 context.active_object.BIMArrayProperties.is_editing = -1
return {"FINISHED"}
class EnableEditingArray(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.enable_editing_array"
bl_label = "Enable Editing Array"
bl_options = {"REGISTER"}
item: bpy.props.IntProperty()
def _execute(self, context):
obj = context.active_object
element = tool.Ifc.get_entity(obj)
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Array", "Data"))[self.item]
props = obj.BIMArrayProperties
props.count = data["count"]
props.x = data["x"]
props.y = data["y"]
props.z = data["z"]
props.use_local_space = data.get("use_local_space", False)
props.is_editing = self.item
return {"FINISHED"} return {"FINISHED"}
@@ -84,6 +104,7 @@ class EditArray(bpy.types.Operator, tool.Ifc.Operator):
"x": props.x, "x": props.x,
"y": props.y, "y": props.y,
"z": props.z, "z": props.z,
"use_local_space": props.use_local_space,
} }
props.is_editing = -1 props.is_editing = -1
@@ -101,25 +122,6 @@ class EditArray(bpy.types.Operator, tool.Ifc.Operator):
return {"FINISHED"} return {"FINISHED"}
class EnableEditingArray(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.enable_editing_array"
bl_label = "Enable Editing Array"
bl_options = {"REGISTER"}
item: bpy.props.IntProperty()
def _execute(self, context):
obj = context.active_object
element = tool.Ifc.get_entity(obj)
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Array", "Data"))[self.item]
props = obj.BIMArrayProperties
props.count = data["count"]
props.x = data["x"]
props.y = data["y"]
props.z = data["z"]
props.is_editing = self.item
return {"FINISHED"}
class RemoveArray(bpy.types.Operator, tool.Ifc.Operator): class RemoveArray(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_array" bl_idname = "bim.remove_array"
bl_label = "Remove Array" bl_label = "Remove Array"
@@ -249,11 +249,18 @@ class BIMModelProperties(PropertyGroup):
class BIMArrayProperties(PropertyGroup): class BIMArrayProperties(PropertyGroup):
is_editing: bpy.props.IntProperty(default=-1) is_editing: bpy.props.IntProperty(
default=-1, description="Currently edited array index. -1 if not in array editing mode."
)
count: bpy.props.IntProperty(name="Count", default=0) count: bpy.props.IntProperty(name="Count", default=0)
x: bpy.props.FloatProperty(name="X", default=0) x: bpy.props.FloatProperty(name="X", default=0)
y: bpy.props.FloatProperty(name="Y", default=0) y: bpy.props.FloatProperty(name="Y", default=0)
z: bpy.props.FloatProperty(name="Z", default=0) z: bpy.props.FloatProperty(name="Z", default=0)
use_local_space: bpy.props.BoolProperty(
name="Use Local Space",
description="Use local space for array items offset instead of world space",
default=True,
)
class BIMStairProperties(PropertyGroup): class BIMStairProperties(PropertyGroup):
@@ -224,6 +224,8 @@ class BIM_PT_array(bpy.types.Panel):
row.operator("bim.edit_array", icon="CHECKMARK", text="").item = i row.operator("bim.edit_array", icon="CHECKMARK", text="").item = i
row.operator("bim.disable_editing_array", icon="CANCEL", text="") row.operator("bim.disable_editing_array", icon="CANCEL", text="")
row = box.row(align=True) row = box.row(align=True)
row.prop(props, "use_local_space")
row = box.row(align=True)
row.prop(props, "x") row.prop(props, "x")
row.prop(props, "y") row.prop(props, "y")
row.prop(props, "z") row.prop(props, "z")
@@ -234,6 +236,8 @@ class BIM_PT_array(bpy.types.Panel):
row.operator("bim.enable_editing_array", icon="GREASEPENCIL", text="").item = i row.operator("bim.enable_editing_array", icon="GREASEPENCIL", text="").item = i
row.operator("bim.remove_array", icon="X", text="").item = i row.operator("bim.remove_array", icon="X", text="").item = i
row = box.row(align=True) row = box.row(align=True)
row.label(text=f"Use Local Space: {array.get('use_local_space', False)}")
row = box.row(align=True)
row.label(text=f"X: {array['x']}") row.label(text=f"X: {array['x']}")
row.label(text=f"Y: {array['y']}") row.label(text=f"Y: {array['y']}")
row.label(text=f"Z: {array['z']}") row.label(text=f"Z: {array['z']}")
+10 -6
View File
@@ -153,10 +153,12 @@ class Model(blenderbim.core.tool.Model):
cls.circles = [] cls.circles = []
if isinstance(axis, list): if isinstance(axis, list):
cls.vertices.extend([ cls.vertices.extend(
position @ Vector(cls.convert_unit_to_si(axis[0])).to_3d(), [
position @ Vector(cls.convert_unit_to_si(axis[1])).to_3d(), position @ Vector(cls.convert_unit_to_si(axis[0])).to_3d(),
]) position @ Vector(cls.convert_unit_to_si(axis[1])).to_3d(),
]
)
cls.edges.append([0, 1]) cls.edges.append([0, 1])
else: else:
cls.import_curve(obj, position, axis) cls.import_curve(obj, position, axis)
@@ -405,6 +407,7 @@ class Model(blenderbim.core.tool.Model):
def regenerate_array(cls, parent, data): def regenerate_array(cls, parent, data):
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
obj_stack = [parent] obj_stack = [parent]
for array in data: for array in data:
child_i = 0 child_i = 0
existing_children = set(array["children"]) existing_children = set(array["children"])
@@ -412,7 +415,7 @@ class Model(blenderbim.core.tool.Model):
children_elements = [] children_elements = []
children_objs = [] children_objs = []
base_offset = Vector([array["x"], array["y"], array["z"]]) * unit_scale base_offset = Vector([array["x"], array["y"], array["z"]]) * unit_scale
for i in range(0, array["count"]): for i in range(array["count"]):
if i == 0: if i == 0:
continue continue
offset = base_offset * i offset = base_offset * i
@@ -441,7 +444,8 @@ class Model(blenderbim.core.tool.Model):
) )
new_matrix = obj.matrix_world.copy() new_matrix = obj.matrix_world.copy()
new_matrix.col[3] = (obj.matrix_world.col[3].to_3d() + offset).to_4d() current_obj_offset = obj.matrix_world @ offset if array["use_local_space"] else offset
new_matrix.col[3] = (obj.matrix_world.col[3].to_3d() + current_obj_offset).to_4d()
child_obj.matrix_world = new_matrix child_obj.matrix_world = new_matrix
children_objs.append(child_obj) children_objs.append(child_obj)
children_elements.append(child_element) children_elements.append(child_element)