This commit is contained in:
Andrej730
2025-04-29 15:05:25 +05:00
parent 1856eeddeb
commit ecf461e1e0
7 changed files with 47 additions and 31 deletions
+15 -5
View File
@@ -198,11 +198,16 @@ class MaterialCreator:
class IfcImporter:
file: ifcopenshell.file
"""Either provided by user as an attribute or will be loaded from ``input_file`` during ``execute()``."""
elements: set[ifcopenshell.entity_instance]
"""Set of IfcElements to import. Excluding ``gross_elements`` and ```native_elements``."""
def __init__(self, ifc_import_settings: IfcImportSettings):
self.ifc_import_settings = ifc_import_settings
tool.Loader.set_settings(ifc_import_settings)
self.diff = None
self.file: ifcopenshell.file = None
self.project = None
self.has_existing_project = False
# element guids to blender collections mapping
@@ -300,6 +305,7 @@ class IfcImporter:
bpy.context.window_manager.progress_end()
def process_context_filter(self) -> None:
"""Setup contexts. Necessary for importing elements representations."""
contexts = self.file.by_type("IfcGeometricRepresentationContext")
if len(contexts) > 100: # Probably something strange happening. Encountered from Revizto.
print("Warning! Excessive contexts were found and merged where applicable.")
@@ -384,6 +390,7 @@ class IfcImporter:
return results
def parse_native_elements(self) -> None:
# TODO: move to `process_element_filter` to incapsulate all `self.elements` logic.
if not self.ifc_import_settings.should_load_geometry:
return
if not self.file.by_type("IfcSweptDiskSolid"):
@@ -1129,7 +1136,7 @@ class IfcImporter:
bpy.ops.view3d.view_selected()
bpy.ops.object.select_all(action="DESELECT")
def setup_arrays(self):
def setup_arrays(self, elements: Optional[set[ifcopenshell.entity_instance]] = None):
for pset in self.file.by_type("IfcPropertySet"):
if pset.Name != "BBIM_Array":
continue
@@ -1144,9 +1151,10 @@ class IfcImporter:
class IfcImportSettings:
input_file: Union[str, None] = None
logger: Union[logging.Logger, None] = None
def __init__(self):
self.logger: logging.Logger = None
self.input_file = None
self.diff_file = None
self.geometry_library = "opencascade"
self.should_use_cpu_multiprocessing = True
@@ -1177,7 +1185,9 @@ class IfcImportSettings:
self.load_indexed_maps = False
@staticmethod
def factory(context=None, input_file=None, logger=None):
def factory(
context=None, input_file: Optional[str] = None, logger: Optional[logging.Logger] = None
) -> IfcImportSettings:
scene_diff = tool.Blender.get_diff_props()
props = tool.Project.get_project_props()
settings = IfcImportSettings()
@@ -58,6 +58,7 @@ from bpy_extras.image_utils import load_image
if TYPE_CHECKING:
from bonsai.bim.module.project.prop import Link
from bpy._typing import rna_enums
cwd = os.path.dirname(os.path.realpath(__file__))
@@ -223,6 +224,7 @@ class CreateDrawing(bpy.types.Operator):
)
drawing_name: str
is_manifold_cache: dict[str, bool]
@classmethod
def poll(cls, context):
@@ -1225,7 +1227,7 @@ class CreateDrawing(bpy.types.Operator):
)
return classes
def is_manifold(self, obj):
def is_manifold(self, obj) -> bool:
result = self.is_manifold_cache.get(obj.data.name, None)
if result is not None:
return result
@@ -2127,14 +2129,14 @@ class ActivateModel(bpy.types.Operator):
class ActivateDrawingBase:
def invoke(self, context, event):
def invoke(self, context, event) -> set["rna_enums.OperatorReturnItems"]:
if event.type == "LEFTMOUSE" and event.alt:
self.should_view_from_camera = False
if event.type == "LEFTMOUSE" and event.shift:
self.use_quick_preview = True
return self.execute(context)
def execute(self, context):
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
props = tool.Drawing.get_document_props()
if props.is_editing_drawings == False:
bpy.ops.bim.load_drawings()
+8 -7
View File
@@ -20,6 +20,7 @@ import bpy
import json
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.pset
import ifcopenshell.util.element
import ifcopenshell.util.unit
import bonsai.tool as tool
@@ -33,8 +34,9 @@ class AddArray(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
obj = context.active_object
element = tool.Ifc.get_entity(obj)
assert (obj := context.active_object)
assert (element := tool.Ifc.get_entity(obj))
ifc_file = tool.Ifc.get()
array = {
"children": [],
@@ -54,14 +56,13 @@ class AddArray(bpy.types.Operator, tool.Ifc.Operator):
data.append(array)
pset = tool.Ifc.get().by_id(pset["id"])
else:
pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="BBIM_Array")
pset = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="BBIM_Array")
data = [array]
ifcopenshell.api.run(
"pset.edit_pset",
tool.Ifc.get(),
ifcopenshell.api.pset.edit_pset(
ifc_file,
pset=pset,
properties={"Parent": element.GlobalId, "Data": tool.Ifc.get().createIfcText(json.dumps(data))},
properties={"Parent": element.GlobalId, "Data": ifc_file.create_entity("IfcText", json.dumps(data))},
)
return {"FINISHED"}
+14 -7
View File
@@ -18,14 +18,17 @@
import bpy
import ifcopenshell.api
import ifcopenshell.api.grid
import bonsai.tool as tool
import bonsai.core.root
from bpy.types import Operator
from bpy.props import FloatProperty, IntProperty
from mathutils import Vector
from typing import TYPE_CHECKING
def add_object(self, context):
def add_object(self: "BIM_OT_add_object", context: bpy.types.Context) -> None:
ifc_file = tool.Ifc.get()
obj = bpy.data.objects.new("Grid", None)
obj.name = "Grid"
@@ -33,6 +36,7 @@ def add_object(self, context):
tool.Ifc, tool.Collector, tool.Root, obj=obj, ifc_class="IfcGrid", should_add_representation=False
)
grid = tool.Ifc.get_entity(obj)
assert grid
for i in range(0, self.total_u):
verts = [
@@ -46,9 +50,7 @@ def add_object(self, context):
tag = chr(ord("A") + i)
obj = bpy.data.objects.new(f"IfcGridAxis/{tag}", mesh)
result = ifcopenshell.api.run(
"grid.create_grid_axis", tool.Ifc.get(), axis_tag=tag, uvw_axes="UAxes", grid=grid
)
result = ifcopenshell.api.grid.create_grid_axis(ifc_file, axis_tag=tag, uvw_axes="UAxes", grid=grid)
tool.Ifc.link(result, obj)
tool.Model.create_axis_curve(obj, result)
tool.Collector.assign(obj)
@@ -65,9 +67,7 @@ def add_object(self, context):
tag = str(i + 1).zfill(2)
obj = bpy.data.objects.new(f"IfcGridAxis/{tag}", mesh)
result = ifcopenshell.api.run(
"grid.create_grid_axis", tool.Ifc.get(), axis_tag=tag, uvw_axes="VAxes", grid=grid
)
result = ifcopenshell.api.grid.create_grid_axis(ifc_file, axis_tag=tag, uvw_axes="VAxes", grid=grid)
tool.Ifc.link(result, obj)
tool.Model.create_axis_curve(obj, result)
tool.Collector.assign(obj)
@@ -78,6 +78,7 @@ def add_object(self, context):
class BIM_OT_add_object(Operator, tool.Ifc.Operator):
bl_idname = "mesh.add_grid"
bl_label = "Grid"
bl_description = "Add IfcGrid."
bl_options = {"REGISTER", "UNDO"}
u_spacing: FloatProperty(name="U Spacing", default=10)
@@ -85,6 +86,12 @@ class BIM_OT_add_object(Operator, tool.Ifc.Operator):
v_spacing: FloatProperty(name="V Spacing", default=10)
total_v: IntProperty(name="Number of V Grids", default=3)
if TYPE_CHECKING:
u_spacing: float
total_u: int
v_spacing: float
total_v: int
@classmethod
def poll(cls, context):
return tool.Ifc.get() and context.mode == "OBJECT"
+1
View File
@@ -2123,6 +2123,7 @@ class Model(bonsai.core.tool.Model):
@classmethod
def create_axis_curve(cls, obj: bpy.types.Object, grid_axis: ifcopenshell.entity_instance) -> None:
m = tool.Surveyor.get_absolute_matrix(obj)
assert isinstance(obj.data, bpy.types.Mesh)
points = [m @ np.array(v.co.to_4d()) for v in obj.data.vertices[0:2]]
ifcopenshell.api.grid.create_axis_curve(
tool.Ifc.get(), p1=points[0], p2=points[1], is_si=True, grid_axis=grid_axis