This commit is contained in:
Dion Moult
2025-01-10 15:21:18 +11:00
parent 4a1422d292
commit e4412e2f51
16 changed files with 63 additions and 59 deletions
-1
View File
@@ -1129,7 +1129,6 @@ class IfcImporter:
tool.Aggregate.constrain_all_parts_to_aggregate(relating_obj) tool.Aggregate.constrain_all_parts_to_aggregate(relating_obj)
bpy.context.scene.BIMAggregateProperties.aggregate_decorator = True bpy.context.scene.BIMAggregateProperties.aggregate_decorator = True
def lock_scales(self) -> None: def lock_scales(self) -> None:
elements = set(self.file.by_type("IfcProduct")) elements = set(self.file.by_type("IfcProduct"))
while elements: while elements:
@@ -207,7 +207,6 @@ class AggregateDecorator:
parts = ifcopenshell.util.element.get_parts(tool.Ifc.get_entity(aggregate)) parts = ifcopenshell.util.element.get_parts(tool.Ifc.get_entity(aggregate))
parts_objs = [tool.Ifc.get_object(p) for p in parts] parts_objs = [tool.Ifc.get_object(p) for p in parts]
indices, edges = create_bounding_box(parts_objs) indices, edges = create_bounding_box(parts_objs)
self.line_shader.uniform_float("lineWidth", 0.5) self.line_shader.uniform_float("lineWidth", 0.5)
self.draw_batch("LINES", indices, color, edges) self.draw_batch("LINES", indices, color, edges)
@@ -230,9 +229,7 @@ class AggregateModeDecorator:
cls.handlers.append( cls.handlers.append(
SpaceView3D.draw_handler_add(handler.draw_aggregate_empty, (context,), "WINDOW", "POST_VIEW") SpaceView3D.draw_handler_add(handler.draw_aggregate_empty, (context,), "WINDOW", "POST_VIEW")
) )
cls.handlers.append( cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_new_objects, (context,), "WINDOW", "POST_VIEW"))
SpaceView3D.draw_handler_add(handler.draw_new_objects, (context,), "WINDOW", "POST_VIEW")
)
cls.is_installed = True cls.is_installed = True
@classmethod @classmethod
@@ -352,12 +349,11 @@ class AggregateModeDecorator:
new_objs = [o for o in new_objs if o.data] new_objs = [o for o in new_objs if o.data]
for obj in new_objs: for obj in new_objs:
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
if (aggregate := ifcopenshell.util.element.get_aggregate(element)) == tool.Ifc.get_entity(props.editing_aggregate): if (aggregate := ifcopenshell.util.element.get_aggregate(element)) == tool.Ifc.get_entity(
props.editing_aggregate
):
continue continue
if element and element.is_a("IfcElement"): if element and element.is_a("IfcElement"):
data = ItemDecorator.get_obj_data(obj) data = ItemDecorator.get_obj_data(obj)
if data: if data:
self.draw_batch( self.draw_batch("TRIS", data["verts"], transparent_color((1, 0, 0, 1)), data["tris"])
"TRIS", data["verts"], transparent_color((1, 0, 0, 1)), data["tris"]
)
@@ -375,6 +375,7 @@ class BIM_OT_select_linked_aggregates(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class BIM_OT_disable_aggregate_mode(bpy.types.Operator): class BIM_OT_disable_aggregate_mode(bpy.types.Operator):
bl_idname = "bim.disable_aggregate_mode" bl_idname = "bim.disable_aggregate_mode"
bl_label = "Disable Aggregate Mode" bl_label = "Disable Aggregate Mode"
@@ -385,6 +386,7 @@ class BIM_OT_disable_aggregate_mode(bpy.types.Operator):
bonsai.core.aggregate.disable_aggregate_mode(tool.Aggregate) bonsai.core.aggregate.disable_aggregate_mode(tool.Aggregate)
return {"FINISHED"} return {"FINISHED"}
class BIM_OT_toggle_aggregate_mode_local_view(bpy.types.Operator): class BIM_OT_toggle_aggregate_mode_local_view(bpy.types.Operator):
bl_idname = "bim.toggle_aggregate_mode_local_view" bl_idname = "bim.toggle_aggregate_mode_local_view"
bl_label = "Toggle Aggregate Mode Local View" bl_label = "Toggle Aggregate Mode Local View"
@@ -403,6 +405,7 @@ class BIM_OT_toggle_aggregate_mode_local_view(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class BIM_OT_aggregate_assign_new_objects_in_aggregate_mode(bpy.types.Operator): class BIM_OT_aggregate_assign_new_objects_in_aggregate_mode(bpy.types.Operator):
bl_idname = "bim.aggregate_assign_new_objects_in_aggregate_mode" bl_idname = "bim.aggregate_assign_new_objects_in_aggregate_mode"
bl_label = "Aggregate Assign New Objects In Aggregate Mode" bl_label = "Aggregate Assign New Objects In Aggregate Mode"
@@ -424,7 +427,9 @@ class BIM_OT_aggregate_assign_new_objects_in_aggregate_mode(bpy.types.Operator):
new_objs = [o for o in new_objs if o.data] new_objs = [o for o in new_objs if o.data]
for obj in new_objs: for obj in new_objs:
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
if (aggregate := ifcopenshell.util.element.get_aggregate(element)) == tool.Ifc.get_entity(props.editing_aggregate): if (aggregate := ifcopenshell.util.element.get_aggregate(element)) == tool.Ifc.get_entity(
props.editing_aggregate
):
continue continue
if element and element.is_a("IfcElement"): if element and element.is_a("IfcElement"):
obj.select_set(True) obj.select_set(True)
@@ -439,4 +444,3 @@ class BIM_OT_aggregate_assign_new_objects_in_aggregate_mode(bpy.types.Operator):
BIM_OT_aggregate_assign_object._execute(self, context) BIM_OT_aggregate_assign_object._execute(self, context)
return {"FINISHED"} return {"FINISHED"}
@@ -1858,7 +1858,7 @@ class OverrideEscape(bpy.types.Operator):
bpy.ops.bim.hide_all_openings() bpy.ops.bim.hide_all_openings()
elif context.scene.BIMAggregateProperties.in_aggregate_mode: elif context.scene.BIMAggregateProperties.in_aggregate_mode:
bpy.ops.bim.disable_aggregate_mode() bpy.ops.bim.disable_aggregate_mode()
elif active_object:=context.active_object: elif active_object := context.active_object:
if tool.Blender.Modifier.try_canceling_editing_modifier_parameters_or_path(active_object): if tool.Blender.Modifier.try_canceling_editing_modifier_parameters_or_path(active_object):
pass pass
return {"FINISHED"} return {"FINISHED"}
@@ -1902,7 +1902,9 @@ class OverrideModeSetEdit(bpy.types.Operator, tool.Ifc.Operator):
self.report({"ERROR"}, f"Element '{obj.name}' is in item mode and cannot be edited directly") self.report({"ERROR"}, f"Element '{obj.name}' is in item mode and cannot be edited directly")
elif obj in [o.obj for o in context.scene.BIMAggregateProperties.not_editing_objects]: elif obj in [o.obj for o in context.scene.BIMAggregateProperties.not_editing_objects]:
obj.select_set(False) obj.select_set(False)
self.report({"ERROR"}, f"Element '{obj.name}' does not belong to this aggregate and cannot be edited directly") self.report(
{"ERROR"}, f"Element '{obj.name}' does not belong to this aggregate and cannot be edited directly"
)
elif obj in bpy.context.scene.BIMProjectProperties.clipping_planes_objs: elif obj in bpy.context.scene.BIMProjectProperties.clipping_planes_objs:
self.report({"ERROR"}, "Clipping planes cannot be edited") self.report({"ERROR"}, "Clipping planes cannot be edited")
elif element: elif element:
@@ -25,7 +25,7 @@ import bmesh
import ifcopenshell import ifcopenshell
import bonsai.tool as tool import bonsai.tool as tool
import math import math
from math import sin, cos, radians from math import sin, cos, radians
from bpy.types import SpaceView3D from bpy.types import SpaceView3D
from bpy_extras import view3d_utils from bpy_extras import view3d_utils
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
@@ -785,7 +785,7 @@ class ProductDecorator:
@classmethod @classmethod
def uninstall(cls): def uninstall(cls):
props = bpy.context.scene.BIMProductPreviewProperties # updated by model/polyline.py props = bpy.context.scene.BIMProductPreviewProperties # updated by model/polyline.py
props.verts.clear() props.verts.clear()
props.edges.clear() props.edges.clear()
props.tris.clear() props.tris.clear()
@@ -806,7 +806,7 @@ class ProductDecorator:
props = context.scene.BIMProductPreviewProperties props = context.scene.BIMProductPreviewProperties
data = {} data = {}
data["verts"] = [(*v.value_3d,) for v in props.verts] data["verts"] = [(*v.value_3d,) for v in props.verts]
data["edges"] = [(int(e.value_2d[0]),int(e.value_2d[1])) for e in props.edges] data["edges"] = [(int(e.value_2d[0]), int(e.value_2d[1])) for e in props.edges]
data["tris"] = [(int(t.value_3d[0]), int(t.value_3d[1]), int(t.value_3d[2])) for t in props.tris] data["tris"] = [(int(t.value_3d[0]), int(t.value_3d[1]), int(t.value_3d[2])) for t in props.tris]
return data return data
+17 -19
View File
@@ -200,6 +200,7 @@ def get_wall_preview_data(context, relating_type):
return data return data
def get_vertical_profile_preview_data(context, relating_type): def get_vertical_profile_preview_data(context, relating_type):
material = ifcopenshell.util.element.get_material(relating_type) material = ifcopenshell.util.element.get_material(relating_type)
try: try:
@@ -261,7 +262,7 @@ def get_vertical_profile_preview_data(context, relating_type):
# Create extrusion bmesh # Create extrusion bmesh
bm = bmesh.new() bm = bmesh.new()
grouped_verts.append(grouped_verts[0]) # Close profile grouped_verts.append(grouped_verts[0]) # Close profile
new_verts = [bm.verts.new(v) for v in grouped_verts] new_verts = [bm.verts.new(v) for v in grouped_verts]
new_edges = [bm.edges.new((new_verts[i], new_verts[i + 1])) for i in range(len(grouped_verts) - 1)] new_edges = [bm.edges.new((new_verts[i], new_verts[i + 1])) for i in range(len(grouped_verts) - 1)]
@@ -296,11 +297,13 @@ def get_vertical_profile_preview_data(context, relating_type):
# Add only profile edges # Add only profile edges
edges = [] edges = []
for edge in bm.edges: for edge in bm.edges:
if (edge.verts[0].co.z == min_z and edge.verts[1].co.z == min_z) or (edge.verts[0].co.z == max_z and edge.verts[1].co.z == max_z): if (edge.verts[0].co.z == min_z and edge.verts[1].co.z == min_z) or (
edge.verts[0].co.z == max_z and edge.verts[1].co.z == max_z
):
edges.append(edge) edges.append(edge)
# Add axis edge # Add axis edge
edges = [(edge.verts[0].index, edge.verts[1].index) for edge in edges] edges = [(edge.verts[0].index, edge.verts[1].index) for edge in edges]
edges.append((len(verts)-1, len(verts)-2)) edges.append((len(verts) - 1, len(verts) - 2))
data["verts"] = verts data["verts"] = verts
data["edges"] = edges data["edges"] = edges
data["tris"] = tris data["tris"] = tris
@@ -327,7 +330,7 @@ def get_horizontal_profile_preview_data(context, relating_type):
return return
for point in polyline_points: for point in polyline_points:
polyline_verts.append(Vector((point.x, point.y, point.z))) polyline_verts.append(Vector((point.x, point.y, point.z)))
polyline_edges = [(i, i+1) for i in range(len(polyline_verts)-1)] polyline_edges = [(i, i + 1) for i in range(len(polyline_verts) - 1)]
# Get profile shape # Get profile shape
settings = ifcopenshell.geom.settings() settings = ifcopenshell.geom.settings()
@@ -372,26 +375,25 @@ def get_horizontal_profile_preview_data(context, relating_type):
case "9": case "9":
grouped_verts = [(v[0] + x_offset, v[1] - y_offset, v[2]) for v in grouped_verts] grouped_verts = [(v[0] + x_offset, v[1] - y_offset, v[2]) for v in grouped_verts]
# Create profile curve # Create profile curve
scale_mat = Matrix.Scale(-1, 4, (1.0, 0.0, 0.0)) scale_mat = Matrix.Scale(-1, 4, (1.0, 0.0, 0.0))
grouped_verts = [scale_mat @ Vector(v) for v in grouped_verts] grouped_verts = [scale_mat @ Vector(v) for v in grouped_verts]
profile_curve = bpy.data.curves.new("Profile", type='CURVE') profile_curve = bpy.data.curves.new("Profile", type="CURVE")
profile_curve.dimensions = "2D" profile_curve.dimensions = "2D"
profile_curve.splines.new('POLY') profile_curve.splines.new("POLY")
profile_curve.splines[0].points.add(len(grouped_verts)) profile_curve.splines[0].points.add(len(grouped_verts))
for i, point in enumerate(profile_curve.splines[0].points): for i, point in enumerate(profile_curve.splines[0].points):
if i == len(grouped_verts): # Close curve if i == len(grouped_verts): # Close curve
point.co = Vector((*grouped_verts[0], 0)) point.co = Vector((*grouped_verts[0], 0))
continue continue
point.co = Vector((*grouped_verts[i], 0)) point.co = Vector((*grouped_verts[i], 0))
profile_obj = bpy.data.objects.new("Profile", profile_curve) profile_obj = bpy.data.objects.new("Profile", profile_curve)
# Create path curve with profile object as bevel # Create path curve with profile object as bevel
path_curve = bpy.data.curves.new("Polyline", type='CURVE') path_curve = bpy.data.curves.new("Polyline", type="CURVE")
path_curve.dimensions = "2D" path_curve.dimensions = "2D"
path_curve.splines.new('POLY') path_curve.splines.new("POLY")
path_curve.splines[0].points.add(len(polyline_verts) - 1) path_curve.splines[0].points.add(len(polyline_verts) - 1)
for i, point in enumerate(path_curve.splines[0].points): for i, point in enumerate(path_curve.splines[0].points):
point.co = Vector((*polyline_verts[i], 0)) point.co = Vector((*polyline_verts[i], 0))
@@ -400,12 +402,12 @@ def get_horizontal_profile_preview_data(context, relating_type):
path_curve.bevel_object = profile_obj path_curve.bevel_object = profile_obj
# Convert path curve to mesh # Convert path curve to mesh
# This operation throws a warning when done during gpu drawing, so it was removed from the decorator file to be handled here # This operation throws a warning when done during gpu drawing, so it was removed from the decorator file to be handled here
path_obj = bpy.data.objects.new("Preview", path_curve) path_obj = bpy.data.objects.new("Preview", path_curve)
context.scene.collection.objects.link(path_obj) context.scene.collection.objects.link(path_obj)
bpy.context.view_layer.objects.active = path_obj bpy.context.view_layer.objects.active = path_obj
dg = context.evaluated_depsgraph_get() dg = context.evaluated_depsgraph_get()
path_obj = path_obj.evaluated_get(dg) path_obj = path_obj.evaluated_get(dg)
me = path_obj.to_mesh() me = path_obj.to_mesh()
# Create bmesh from path mesh # Create bmesh from path mesh
@@ -812,13 +814,9 @@ class PolylineOperator:
tool.Blender.update_viewport() tool.Blender.update_viewport()
def get_product_preview_data(self, context: bpy.types.Context, relating_type: ifcopenshell.entity_isntance): def get_product_preview_data(self, context: bpy.types.Context, relating_type: ifcopenshell.entity_isntance):
if ( if tool.Model.get_usage_type(relating_type) == "PROFILE" and relating_type.is_a() not in {"IfcColumnType"}:
tool.Model.get_usage_type(relating_type) == "PROFILE" and relating_type.is_a() not in {"IfcColumnType"}
):
data = get_horizontal_profile_preview_data(context, relating_type) data = get_horizontal_profile_preview_data(context, relating_type)
elif ( elif tool.Model.get_usage_type(relating_type) == "PROFILE" and relating_type.is_a() in {"IfcColumnType"}:
tool.Model.get_usage_type(relating_type) == "PROFILE" and relating_type.is_a() in {"IfcColumnType"}
):
data = get_vertical_profile_preview_data(context, relating_type) data = get_vertical_profile_preview_data(context, relating_type)
elif tool.Model.get_usage_type(relating_type) == "LAYER2": elif tool.Model.get_usage_type(relating_type) == "LAYER2":
data = get_wall_preview_data(context, relating_type) data = get_wall_preview_data(context, relating_type)
@@ -832,7 +830,7 @@ class PolylineOperator:
props.verts.clear() props.verts.clear()
props.edges.clear() props.edges.clear()
props.tris.clear() props.tris.clear()
for vert in data["verts"]: for vert in data["verts"]:
v = props.verts.add() v = props.verts.add()
v.value_3d = vert v.value_3d = vert
@@ -1145,7 +1145,6 @@ class DrawPolylineProfile(bpy.types.Operator, PolylineOperator):
for profile1, profile2 in zip(profiles[:-1], profiles[1:]): for profile1, profile2 in zip(profiles[:-1], profiles[1:]):
DumbProfileJoiner().join_V(profile2["obj"], profile1["obj"]) DumbProfileJoiner().join_V(profile2["obj"], profile1["obj"])
def modal(self, context, event): def modal(self, context, event):
if not self.relating_type: if not self.relating_type:
self.report({"WARNING"}, "You need to select a profile type.") self.report({"WARNING"}, "You need to select a profile type.")
@@ -1176,7 +1175,6 @@ class DrawPolylineProfile(bpy.types.Operator, PolylineOperator):
size = len(items) size = len(items)
context.scene.BIMModelProperties.offset_type = items[((index + 1) % size)] context.scene.BIMModelProperties.offset_type = items[((index + 1) % size)]
props = bpy.context.scene.BIMModelProperties props = bpy.context.scene.BIMModelProperties
wall_config = f"""Direction: {props.direction_sense} wall_config = f"""Direction: {props.direction_sense}
Offset Type: {props.offset_type} Offset Type: {props.offset_type}
@@ -1222,4 +1220,3 @@ class DrawPolylineProfile(bpy.types.Operator, PolylineOperator):
self.tool_state.use_default_container = True self.tool_state.use_default_container = True
self.tool_state.plane_method = "XY" self.tool_state.plane_method = "XY"
return {"RUNNING_MODAL"} return {"RUNNING_MODAL"}
+2 -1
View File
@@ -821,12 +821,13 @@ class BIMPolylineProperties(PropertyGroup):
insertion_polyline: bpy.props.CollectionProperty(type=Polyline) insertion_polyline: bpy.props.CollectionProperty(type=Polyline)
measurement_polyline: bpy.props.CollectionProperty(type=Polyline) measurement_polyline: bpy.props.CollectionProperty(type=Polyline)
class ProductPreviewItem(PropertyGroup): class ProductPreviewItem(PropertyGroup):
value_3d: bpy.props.FloatVectorProperty() value_3d: bpy.props.FloatVectorProperty()
value_2d: bpy.props.FloatVectorProperty(size=2) value_2d: bpy.props.FloatVectorProperty(size=2)
class BIMProductPreviewProperties(PropertyGroup): class BIMProductPreviewProperties(PropertyGroup):
verts: bpy.props.CollectionProperty(type=ProductPreviewItem) verts: bpy.props.CollectionProperty(type=ProductPreviewItem)
edges: bpy.props.CollectionProperty(type=ProductPreviewItem) edges: bpy.props.CollectionProperty(type=ProductPreviewItem)
tris: bpy.props.CollectionProperty(type=ProductPreviewItem) tris: bpy.props.CollectionProperty(type=ProductPreviewItem)
@@ -591,7 +591,7 @@ class EditObjectUI:
op = row.operator("bim.disable_aggregate_mode", text="", icon="X") op = row.operator("bim.disable_aggregate_mode", text="", icon="X")
op = row.operator("bim.toggle_aggregate_mode_local_view", text="", icon="ZOOM_SELECTED") op = row.operator("bim.toggle_aggregate_mode_local_view", text="", icon="ZOOM_SELECTED")
op = row.operator("bim.aggregate_assign_new_objects_in_aggregate_mode", text="", icon="CUBE") op = row.operator("bim.aggregate_assign_new_objects_in_aggregate_mode", text="", icon="CUBE")
text = format_ifc_camel_case(AuthoringData.data["active_class"]) text = format_ifc_camel_case(AuthoringData.data["active_class"])
layout.label(text=f"{text} Edit Tools:", icon="RESTRICT_SELECT_OFF") layout.label(text=f"{text} Edit Tools:", icon="RESTRICT_SELECT_OFF")
cls.draw_parameter_adjustments(context) cls.draw_parameter_adjustments(context)
@@ -954,7 +954,7 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
def hotkey_S_A(self): def hotkey_S_A(self):
props = bpy.context.scene.BIMModelProperties props = bpy.context.scene.BIMModelProperties
relating_type_id = AuthoringData.data["relating_type_id_current"] relating_type_id = AuthoringData.data["relating_type_id_current"]
relating_type_class = AuthoringData.data["ifc_class_current"] relating_type_class = AuthoringData.data["ifc_class_current"]
if relating_type_id is None: if relating_type_id is None:
self.report({"ERROR"}, "No relating type selected") self.report({"ERROR"}, "No relating type selected")
return return
@@ -993,7 +993,9 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
): ):
bpy.ops.bim.draw_polyline_slab("INVOKE_DEFAULT") bpy.ops.bim.draw_polyline_slab("INVOKE_DEFAULT")
elif ( elif (
relating_type_id and tool.Model.get_usage_type(tool.Ifc.get().by_id(int(relating_type_id))) == "PROFILE" and relating_type_class not in {"IfcColumnType"} relating_type_id
and tool.Model.get_usage_type(tool.Ifc.get().by_id(int(relating_type_id))) == "PROFILE"
and relating_type_class not in {"IfcColumnType"}
): ):
bpy.ops.bim.draw_polyline_profile("INVOKE_DEFAULT") bpy.ops.bim.draw_polyline_profile("INVOKE_DEFAULT")
else: else:
+3 -1
View File
@@ -197,7 +197,9 @@ def draw_psetqto_ui(
row = box.row(align=True) row = box.row(align=True)
row.scale_y = 0.8 row.scale_y = 0.8
row.label(text=prop["Name"]) row.label(text=prop["Name"])
op = row.operator("bim.select_similar", text=get_display_value(nominal_value), icon="NONE", emboss=False) op = row.operator(
"bim.select_similar", text=get_display_value(nominal_value), icon="NONE", emboss=False
)
op.key = '"' + pset["Name"].replace('"', '\\"') + '"."' + prop["Name"].replace('"', '\\"') + '"' op.key = '"' + pset["Name"].replace('"', '\\"') + '"."' + prop["Name"].replace('"', '\\"') + '"'
# calculate sum of all selected objects # calculate sum of all selected objects
if active_operator: if active_operator:
+9 -7
View File
@@ -246,9 +246,10 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
) )
should_play_chaching_sound: BoolProperty(name="Play A Cha-Ching Sound When Project Costs Updates", default=False) should_play_chaching_sound: BoolProperty(name="Play A Cha-Ching Sound When Project Costs Updates", default=False)
spatial_elements_unselectable: BoolProperty( spatial_elements_unselectable: BoolProperty(
name="Make Spatial Elements Unselectable By Default", name="Make Spatial Elements Unselectable By Default",
default=True, default=True,
description="If disabled, it will be possible to select spatial elements in the 3D viewport.\nIt is recommended to keep this `Enabled`, as this can have unintended consequences") description="If disabled, it will be possible to select spatial elements in the 3D viewport.\nIt is recommended to keep this `Enabled`, as this can have unintended consequences",
)
decorations_colour: bpy.props.FloatVectorProperty( decorations_colour: bpy.props.FloatVectorProperty(
name="Decorations Color", subtype="COLOR", default=(1, 1, 1, 1), min=0.0, max=1.0, size=4 name="Decorations Color", subtype="COLOR", default=(1, 1, 1, 1), min=0.0, max=1.0, size=4
) )
@@ -1191,15 +1192,16 @@ def draw_custom_context_menu(self: bpy.types.Menu, context: bpy.types.Context) -
url_op = layout.operator("bim.open_uri", icon="URL", text="Online IFC Documentation") url_op = layout.operator("bim.open_uri", icon="URL", text="Online IFC Documentation")
url_op.uri = url url_op.uri = url
class BIM_PT_decorators_overlay(Panel): class BIM_PT_decorators_overlay(Panel):
bl_space_type = 'VIEW_3D' bl_space_type = "VIEW_3D"
bl_region_type = 'HEADER' bl_region_type = "HEADER"
bl_parent_id = 'VIEW3D_PT_overlay' bl_parent_id = "VIEW3D_PT_overlay"
bl_label = "Bonsai Decorators" bl_label = "Bonsai Decorators"
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.mode == 'OBJECT' return context.mode == "OBJECT"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
+6 -1
View File
@@ -86,12 +86,17 @@ def add_part_to_object(
assign_object(ifc, aggregator, collector, relating_obj=obj, related_obj=part_obj) assign_object(ifc, aggregator, collector, relating_obj=obj, related_obj=part_obj)
blender.set_active_object(obj) blender.set_active_object(obj)
def enable_aggregate_mode(aggregator: tool.Aggregate, obj: bpy.types.Object,):
def enable_aggregate_mode(
aggregator: tool.Aggregate,
obj: bpy.types.Object,
):
if aggregator.get_aggregate_mode(): if aggregator.get_aggregate_mode():
disable_aggregate_mode(aggregator) disable_aggregate_mode(aggregator)
aggregator.enable_aggregate_mode(obj) aggregator.enable_aggregate_mode(obj)
def disable_aggregate_mode(aggregator: tool.Aggregate): def disable_aggregate_mode(aggregator: tool.Aggregate):
aggregator.disable_aggregate_mode() aggregator.disable_aggregate_mode()
+1 -3
View File
@@ -1795,9 +1795,7 @@ class Geometry(bonsai.core.tool.Geometry):
return False return False
@classmethod @classmethod
def get_bvh_tree(cls, obj:bpy.types.Object) -> BVHTree: def get_bvh_tree(cls, obj: bpy.types.Object) -> BVHTree:
bm = tool.Blender.get_bmesh_for_mesh(obj.data) bm = tool.Blender.get_bmesh_for_mesh(obj.data)
bm.transform(obj.matrix_world) bm.transform(obj.matrix_world)
return BVHTree.FromBMesh(bm) return BVHTree.FromBMesh(bm)
+1 -2
View File
@@ -983,8 +983,7 @@ class Loader(bonsai.core.tool.Loader):
tool.Loader.load_indexed_colour_map(rep, mesh) tool.Loader.load_indexed_colour_map(rep, mesh)
ios_edges_values = [ ios_edges_values = [
(e.vertices[0], e.vertices[1]) in ios_edges (e.vertices[0], e.vertices[1]) in ios_edges or (e.vertices[1], e.vertices[0]) in ios_edges
or (e.vertices[1], e.vertices[0]) in ios_edges
for e in mesh.edges for e in mesh.edges
] ]
tool.Blender.Attribute.fill_attribute(mesh, "ios_edges", "EDGE", "BOOLEAN", ios_edges_values) tool.Blender.Attribute.fill_attribute(mesh, "ios_edges", "EDGE", "BOOLEAN", ios_edges_values)
+1 -1
View File
@@ -206,7 +206,7 @@ class Raycast(bonsai.core.tool.Raycast):
bm.free() bm.free()
snapping_points = [] snapping_points = []
sorted_points = sorted(points, key=lambda x : x[0]) sorted_points = sorted(points, key=lambda x: x[0])
for p in sorted_points: for p in sorted_points:
point = copy.deepcopy(p) point = copy.deepcopy(p)
snapping_points.append(point[1]) snapping_points.append(point[1])
-1
View File
@@ -354,7 +354,6 @@ class Root(bonsai.core.tool.Root):
tool.Aggregate.constrain_all_parts_to_aggregate(tool.Ifc.get_object(new_aggregate[0])) tool.Aggregate.constrain_all_parts_to_aggregate(tool.Ifc.get_object(new_aggregate[0]))
tool.Blender.select_and_activate_single_object(bpy.context, tool.Ifc.get_object(new_aggregate[0])) tool.Blender.select_and_activate_single_object(bpy.context, tool.Ifc.get_object(new_aggregate[0]))
@classmethod @classmethod
def run_geometry_add_representation( def run_geometry_add_representation(
cls, cls,