This commit is contained in:
Andrej730
2025-05-16 18:48:50 +05:00
parent 9e6320d545
commit aa5f08880b
6 changed files with 39 additions and 12 deletions
@@ -1650,7 +1650,7 @@ class CutDecorator:
all_vertex_i_offset = 0
selected_vertex_i_offset = 0
classes_no_cut_str = bpy.context.scene.DocProperties.classes_no_cut
classes_no_cut_str = tool.Drawing.get_document_props().classes_no_cut
classes_no_cut = [word.strip() for word in classes_no_cut_str.split(",")]
for obj in [o for o in bpy.context.visible_objects if o.type == "MESH"]:
@@ -225,14 +225,27 @@ class CreateDrawing(bpy.types.Operator):
+ "Add the CTRL modifier to optionally open drawings to view them as\n"
+ "they are created"
)
print_all: bpy.props.BoolProperty(name="Print All", default=False, options={"SKIP_SAVE"})
open_viewer: bpy.props.BoolProperty(name="Open in Viewer", default=False, options={"SKIP_SAVE"})
sync: bpy.props.BoolProperty(
print_all: bpy.props.BoolProperty( # pyright: ignore[reportRedeclaration]
name="Print All",
default=False,
options={"SKIP_SAVE"},
)
open_viewer: bpy.props.BoolProperty( # pyright: ignore[reportRedeclaration]
name="Open in Viewer",
default=False,
options={"SKIP_SAVE"},
)
sync: bpy.props.BoolProperty( # pyright: ignore[reportRedeclaration]
name="Sync Before Creating Drawing",
description="Could save some time if you're sure IFC and current Blender session are already in sync",
default=True,
)
if TYPE_CHECKING:
print_all: bool
open_viewer: bool
sync: bool
drawing_name: str
is_manifold_cache: dict[str, bool]
@@ -268,6 +281,7 @@ class CreateDrawing(bpy.types.Operator):
assert context.scene and context.scene.camera
active_drawing_id = tool.Blender.get_ifc_definition_id(context.scene.camera)
original_drawing_id = None
if self.print_all:
original_drawing_id = active_drawing_id
drawings_to_print = [d.ifc_definition_id for d in self.props.drawings if d.is_selected and d.is_drawing]
@@ -338,6 +352,7 @@ class CreateDrawing(bpy.types.Operator):
if not self.open_viewer:
self.report({"INFO"}, f"{len(drawings_to_print)} drawings created...")
if self.print_all:
assert original_drawing_id is not None
bpy.ops.bim.activate_drawing(drawing=original_drawing_id, should_view_from_camera=False)
return {"FINISHED"}
@@ -2150,6 +2165,7 @@ class ActivateDrawingBase(tool.Ifc.Operator):
return self.execute(context)
def _execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
assert context.scene
props = tool.Drawing.get_document_props()
if props.is_editing_drawings == False:
bpy.ops.bim.load_drawings()
@@ -2161,12 +2177,14 @@ class ActivateDrawingBase(tool.Ifc.Operator):
tool.Blender.activate_camera(tool.Drawing.import_temporary_drawing_camera(drawing))
return {"FINISHED"}
viewport_position = None
if not self.should_view_from_camera:
viewport_position = tool.Blender.get_viewport_position()
core.activate_drawing_view(tool.Ifc, tool.Blender, tool.Drawing, drawing=drawing)
if not self.should_view_from_camera:
assert viewport_position
tool.Blender.set_viewport_position(viewport_position)
dprops.active_drawing_id = self.drawing
@@ -2182,6 +2200,7 @@ class ActivateDrawingBase(tool.Ifc.Operator):
# Save drawing bounds to the .ifc file
camera = context.scene.camera
assert camera
camera_props = tool.Drawing.get_camera_props(camera)
if camera_props.update_representation(camera.matrix_world):
bpy.ops.bim.update_representation(obj=camera.name, ifc_representation_class="")
@@ -496,6 +496,7 @@ class DocProperties(PropertyGroup):
imperial_precision: str
tolerance: float
classes_to_wireframe: str
classes_no_cut: str
def get_active_drawing(self) -> Union[ifcopenshell.entity_instance, None]:
drawing_id = self.active_drawing_id
@@ -22,7 +22,9 @@ import bmesh
import numpy as np
import numpy.typing as npt
import ifcopenshell
import ifcopenshell.api.geometry
import ifcopenshell.api.layer
import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.style
import ifcopenshell.util.element
@@ -583,9 +585,9 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator):
# We are explicitly casting to a tessellation, so remove all parametric materials.
element_type = ifcopenshell.util.element.get_type(product)
if element_type: # Some invalid IFCs use material sets without a type.
ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), products=[element_type])
ifcopenshell.api.material.unassign_material(self.file, products=[element_type])
tool.Material.ensure_material_unassigned([element_type])
ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), products=[product])
ifcopenshell.api.material.unassign_material(self.file, products=[product])
tool.Material.ensure_material_unassigned([product])
else:
# These objects are parametrically based on an axis and should not be modified as a mesh
@@ -603,6 +605,7 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator):
# added this as a fallback for easier transition some annotation types to 3d
# if they were create before as 2d
element = tool.Ifc.get_entity(obj)
assert element
if tool.Drawing.is_annotation_object_type(element, ("FALL", "SECTION_LEVEL", "PLAN_LEVEL")):
context_of_items = tool.Drawing.get_annotation_context("MODEL_VIEW")
@@ -626,7 +629,7 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator):
representation_data["text_literal"] = tool.Geometry.get_text_literal(old_representation)
# TODO: replace with core.add_representation?
new_representation = ifcopenshell.api.run("geometry.add_representation", self.file, **representation_data)
new_representation = ifcopenshell.api.geometry.add_representation(self.file, **representation_data)
if new_representation is None:
self.report({"ERROR"}, "Error creating representation for Blender object.")
return {"CANCELLED"}
+1 -1
View File
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
import bonsai.tool as tool
def resize_to_storey(misc: tool.Misc, ifc: tool.Ifc, obj: bpy.types.Object, total_storeys: int) -> None:
def resize_to_storey(misc: type[tool.Misc], ifc: type[tool.Ifc], obj: bpy.types.Object, total_storeys: int) -> None:
storey = misc.get_object_storey(obj)
if not storey:
return
+8 -4
View File
@@ -26,7 +26,11 @@ if TYPE_CHECKING:
def copy_class(
ifc: tool.Ifc, collector: tool.Collector, geometry: tool.Geometry, root: tool.Root, obj: bpy.types.Object
ifc: type[tool.Ifc],
collector: type[tool.Collector],
geometry: type[tool.Geometry],
root: type[tool.Root],
obj: bpy.types.Object,
) -> ifcopenshell.entity_instance | None:
element = ifc.get_entity(obj)
if not element:
@@ -55,9 +59,9 @@ def copy_class(
def assign_class(
ifc: tool.Ifc,
collector: tool.Collector,
root: tool.Root,
ifc: type[tool.Ifc],
collector: type[tool.Collector],
root: type[tool.Root],
obj: bpy.types.Object,
ifc_class: str,
context: Optional[ifcopenshell.entity_instance] = None,