mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Add support for adding curvelike items
This commit is contained in:
@@ -20,6 +20,7 @@ import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
classes = (
|
||||
operator.AddCurvelikeItem,
|
||||
operator.AddMeshlikeItem,
|
||||
operator.AddRepresentation,
|
||||
operator.AddSweptAreaSolidItem,
|
||||
|
||||
@@ -2637,7 +2637,7 @@ class AddSweptAreaSolidItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if self.shape == "CUBE":
|
||||
curve = builder.rectangle(size=Vector((0.5, 0.5)) / unit_scale)
|
||||
elif self.shape == "CYLINDER":
|
||||
curve = builder.circle(radius=0.25)
|
||||
curve = builder.circle(radius=0.25 / unit_scale)
|
||||
item = builder.extrude(
|
||||
curve,
|
||||
magnitude=0.5 / unit_scale,
|
||||
@@ -2656,3 +2656,59 @@ class AddSweptAreaSolidItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
obj.data.BIMMeshProperties.ifc_definition_id = item.id()
|
||||
tool.Geometry.import_item(obj)
|
||||
tool.Geometry.import_item_attributes(obj)
|
||||
|
||||
|
||||
class AddCurvelikeItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_curvelike_item"
|
||||
bl_label = "Add Curvelike Item"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
shape: bpy.props.StringProperty(name="Shape")
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMGeometryProperties
|
||||
|
||||
representation = tool.Geometry.get_active_representation(props.representation_obj)
|
||||
is_2d = representation.ContextOfItems.ContextType == "Plan"
|
||||
representation = ifcopenshell.util.representation.resolve_representation(representation)
|
||||
|
||||
mesh = bpy.data.meshes.new("Tmp")
|
||||
obj = bpy.data.objects.new("Tmp", mesh)
|
||||
scene = bpy.context.scene
|
||||
scene.collection.objects.link(obj)
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
new = props.item_objs.add()
|
||||
new.obj = obj
|
||||
tool.Geometry.lock_object(obj)
|
||||
|
||||
matrix = props.representation_obj.matrix_world.copy()
|
||||
matrix.translation = context.scene.cursor.location
|
||||
local_matrix = props.representation_obj.matrix_world.inverted() @ matrix
|
||||
|
||||
obj.show_in_front = True
|
||||
obj.matrix_world = matrix
|
||||
tool.Geometry.record_object_position(obj)
|
||||
|
||||
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
|
||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
|
||||
offset = local_matrix.translation.to_2d() / unit_scale
|
||||
if not is_2d:
|
||||
offset = offset.to_3d()
|
||||
|
||||
if self.shape == "LINE":
|
||||
if is_2d:
|
||||
points = [Vector((0, 0)), Vector((0.5 / unit_scale, 0))]
|
||||
else:
|
||||
points = [Vector((0, 0, 0)), Vector((0.5 / unit_scale, 0, 0))]
|
||||
item = builder.polyline(points=points, position_offset=offset)
|
||||
elif self.shape == "CIRCLE":
|
||||
item = builder.circle(radius=0.25 / unit_scale, center=offset)
|
||||
|
||||
representation.Items = list(representation.Items) + [item]
|
||||
tool.Geometry.reload_representation(bpy.context.scene.BIMGeometryProperties.representation_obj)
|
||||
|
||||
obj.name = obj.data.name = f"Item/{item.is_a()}/{item.id()}"
|
||||
obj.data.BIMMeshProperties.ifc_definition_id = item.id()
|
||||
tool.Geometry.import_item(obj)
|
||||
tool.Geometry.import_item_attributes(obj)
|
||||
|
||||
@@ -308,6 +308,10 @@ class BIM_MT_add_representation_item(Menu):
|
||||
"bim.add_swept_area_solid_item", icon="MESH_CYLINDER", text="Extruded Area Solid Cylinder"
|
||||
).shape = "CYLINDER"
|
||||
|
||||
if ItemData.data["representation_type"] in ("Annotation2D"):
|
||||
self.layout.operator("bim.add_curvelike_item", icon="IPO_CONSTANT", text="Polycurve").shape = "LINE"
|
||||
self.layout.operator("bim.add_curvelike_item", icon="MESH_CIRCLE", text="Circle").shape = "CIRCLE"
|
||||
|
||||
|
||||
class CreateObjectUI:
|
||||
@classmethod
|
||||
|
||||
@@ -871,7 +871,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
|
||||
@classmethod
|
||||
def is_movable(cls, item: ifcopenshell.entity_instance) -> bool:
|
||||
return item.is_a("IfcSweptAreaSolid") or item.is_a("IfcConic")
|
||||
return item.is_a("IfcSweptAreaSolid")
|
||||
|
||||
@classmethod
|
||||
def is_profile_based(cls, data: bpy.types.Mesh) -> bool:
|
||||
@@ -1471,7 +1471,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
if not (obj := item_obj.obj):
|
||||
continue
|
||||
item = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||
if (is_swept_area := item.is_a("IfcSweptAreaSolid")) or item.is_a("IfcConic"):
|
||||
if (is_swept_area := item.is_a("IfcSweptAreaSolid")):
|
||||
if not tool.Ifc.is_moved(obj):
|
||||
continue
|
||||
has_changed = True
|
||||
@@ -1529,7 +1529,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
|
||||
obj.matrix_world = rep_obj.matrix_world.copy()
|
||||
|
||||
if (is_swept_area := item.is_a("IfcSweptAreaSolid")) or item.is_a("IfcConic"):
|
||||
if (is_swept_area := item.is_a("IfcSweptAreaSolid")):
|
||||
position = item.Position
|
||||
# Positional is optional only for SweptAreaSolid.
|
||||
if position or not is_swept_area:
|
||||
|
||||
@@ -455,14 +455,13 @@ class Model(bonsai.core.tool.Model):
|
||||
if is_closed:
|
||||
cls.edges.append([len(cls.vertices) - 1, offset]) # Close the loop
|
||||
elif curve.is_a("IfcCircle"):
|
||||
center = cls.convert_unit_to_si(
|
||||
Matrix(ifcopenshell.util.placement.get_axis2placement(curve.Position).tolist()).translation
|
||||
)
|
||||
circle_position = Matrix(ifcopenshell.util.placement.get_axis2placement(curve.Position).tolist())
|
||||
circle_position.translation *= cls.unit_scale
|
||||
radius = cls.convert_unit_to_si(curve.Radius)
|
||||
cls.vertices.extend(
|
||||
[
|
||||
position @ Vector((center[0], center[1] - radius, 0.0)),
|
||||
position @ Vector((center[0], center[1] + radius, 0.0)),
|
||||
position @ circle_position @ Vector((0, 0 - radius, 0.0)),
|
||||
position @ circle_position @ Vector((0, 0 + radius, 0.0)),
|
||||
]
|
||||
)
|
||||
cls.circles.append([offset, offset + 1])
|
||||
|
||||
Reference in New Issue
Block a user