mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 10:57:49 +00:00
Minor fix.
This commit is contained in:
@@ -155,7 +155,7 @@ class IfcExporter:
|
||||
float(props.blender_x_axis_ordinate),
|
||||
)
|
||||
if not np.allclose(ifc_matrix, blender_matrix, atol=0.0001):
|
||||
blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Surveyor, obj=obj)
|
||||
blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
|
||||
return element
|
||||
|
||||
def sync_grid_axis_object_placement(self, obj, element):
|
||||
|
||||
@@ -54,7 +54,7 @@ class EditObjectPlacement(bpy.types.Operator, Operator):
|
||||
def _execute(self, context):
|
||||
objs = [bpy.data.objects.get(self.obj)] if self.obj else context.selected_objects
|
||||
for obj in objs:
|
||||
core.edit_object_placement(tool.Ifc, tool.Surveyor, obj=obj)
|
||||
core.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
|
||||
|
||||
|
||||
class AddRepresentation(bpy.types.Operator, Operator):
|
||||
@@ -153,7 +153,7 @@ class UpdateRepresentation(bpy.types.Operator):
|
||||
ifcopenshell.api.run("grid.create_axis_curve", self.file, **{"axis_curve": obj, "grid_axis": product})
|
||||
return
|
||||
|
||||
core.edit_object_placement(tool.Ifc, tool.Surveyor, obj=obj)
|
||||
core.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
|
||||
|
||||
old_representation = self.file.by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||
context_of_items = old_representation.ContextOfItems
|
||||
|
||||
@@ -22,7 +22,6 @@ import blenderbim.tool as tool
|
||||
|
||||
def refresh():
|
||||
AuthoringData.is_loaded = False
|
||||
WorkspaceData.is_loaded = False
|
||||
|
||||
|
||||
class AuthoringData:
|
||||
@@ -31,21 +30,23 @@ class AuthoringData:
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.is_loaded = True
|
||||
cls.data = {
|
||||
"ifc_classes": cls.ifc_classes(),
|
||||
"relating_types": cls.relating_types(),
|
||||
}
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def ifc_classes(cls):
|
||||
results = []
|
||||
classes = set([e.is_a() for e in tool.Ifc.get().by_type("IfcElementType")])
|
||||
classes = {e.is_a() for e in tool.Ifc.get().by_type("IfcElementType")}
|
||||
results.extend([(c, c, "") for c in sorted(classes)])
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def relating_types(cls):
|
||||
if not cls.ifc_classes():
|
||||
return []
|
||||
results = []
|
||||
ifc_class = bpy.context.scene.BIMModelProperties.ifc_class
|
||||
if ifc_class:
|
||||
@@ -53,7 +54,3 @@ class AuthoringData:
|
||||
results.extend(sorted(elements, key=lambda s: s[1]))
|
||||
return results
|
||||
return []
|
||||
|
||||
|
||||
class WorkspaceData(AuthoringData):
|
||||
pass
|
||||
|
||||
@@ -21,7 +21,7 @@ import bpy
|
||||
import blenderbim.bim.module.type.prop as type_prop
|
||||
from bpy.types import WorkSpaceTool
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.model.data import WorkspaceData
|
||||
from blenderbim.bim.module.model.data import AuthoringData
|
||||
|
||||
|
||||
class BimTool(WorkSpaceTool):
|
||||
@@ -52,19 +52,19 @@ class BimTool(WorkSpaceTool):
|
||||
)
|
||||
|
||||
def draw_settings(context, layout, tool):
|
||||
if not WorkspaceData.is_loaded:
|
||||
WorkspaceData.load()
|
||||
if not AuthoringData.is_loaded:
|
||||
AuthoringData.load()
|
||||
|
||||
row = layout.row(align=True)
|
||||
if not IfcStore.get_file():
|
||||
row.label(text="No IFC Project", icon="ERROR")
|
||||
return
|
||||
props = context.scene.BIMModelProperties
|
||||
if WorkspaceData.data["ifc_classes"]:
|
||||
if AuthoringData.data["ifc_classes"]:
|
||||
row.prop(props, "ifc_class", text="")
|
||||
else:
|
||||
row.label(text="No IFC Class")
|
||||
if WorkspaceData.data["relating_types"]:
|
||||
if AuthoringData.data["relating_types"]:
|
||||
row.prop(props, "relating_type", text="")
|
||||
else:
|
||||
row.label(text="No Relating Type")
|
||||
@@ -75,7 +75,7 @@ class BimTool(WorkSpaceTool):
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="Add Type Instance", icon="EVENT_A")
|
||||
|
||||
if not ifc_classes_is_empty:
|
||||
if AuthoringData.data["ifc_classes"]:
|
||||
if props.ifc_class == "IfcWallType":
|
||||
row = layout.row()
|
||||
row.label(text="Join")
|
||||
@@ -147,9 +147,9 @@ class Hotkey(bpy.types.Operator):
|
||||
|
||||
def _execute(self, context):
|
||||
self.props = context.scene.BIMModelProperties
|
||||
self.ifc_classes_is_empty = True
|
||||
self.has_ifc_class = True
|
||||
try:
|
||||
self.ifc_classes_is_empty = bool(self.props.ifc_class)
|
||||
self.has_ifc_class = bool(self.props.ifc_class)
|
||||
except:
|
||||
pass
|
||||
getattr(self, f"hotkey_{self.hotkey}")()
|
||||
@@ -159,13 +159,13 @@ class Hotkey(bpy.types.Operator):
|
||||
bpy.ops.bim.add_type_instance()
|
||||
|
||||
def hotkey_S_C(self):
|
||||
if not self.ifc_classes_is_empty and self.props.ifc_class == "IfcWallType":
|
||||
if self.has_ifc_class and self.props.ifc_class == "IfcWallType":
|
||||
bpy.ops.bim.align_wall(align_type="CENTERLINE")
|
||||
else:
|
||||
bpy.ops.bim.align_product(align_type="CENTERLINE")
|
||||
|
||||
def hotkey_S_E(self):
|
||||
if self.ifc_classes_is_empty:
|
||||
if not self.has_ifc_class:
|
||||
return
|
||||
if self.props.ifc_class == "IfcWallType":
|
||||
bpy.ops.bim.join_wall(join_type="T")
|
||||
@@ -173,13 +173,13 @@ class Hotkey(bpy.types.Operator):
|
||||
bpy.ops.bim.extend_profile()
|
||||
|
||||
def hotkey_S_V(self):
|
||||
if not self.ifc_classes_is_empty and self.props.ifc_class == "IfcWallType":
|
||||
if self.has_ifc_class and self.props.ifc_class == "IfcWallType":
|
||||
bpy.ops.bim.align_wall(align_type="INTERIOR")
|
||||
else:
|
||||
bpy.ops.bim.align_product(align_type="POSITIVE")
|
||||
|
||||
def hotkey_S_X(self):
|
||||
if not self.ifc_classes_is_empty and self.props.ifc_class == "IfcWallType":
|
||||
if self.has_ifc_class and self.props.ifc_class == "IfcWallType":
|
||||
if bpy.ops.bim.align_wall.poll():
|
||||
bpy.ops.bim.align_wall(align_type="EXTERIOR")
|
||||
else:
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
import blenderbim.core.style
|
||||
|
||||
|
||||
def edit_object_placement(ifc, surveyor, obj=None):
|
||||
def edit_object_placement(ifc, geometry, surveyor, obj=None):
|
||||
element = ifc.get_entity(obj)
|
||||
if element:
|
||||
geometry.clear_scale(obj)
|
||||
ifc.run("geometry.edit_object_placement", product=element, matrix=surveyor.get_absolute_matrix(obj))
|
||||
|
||||
|
||||
@@ -32,7 +33,7 @@ def add_representation(
|
||||
if not element:
|
||||
return
|
||||
|
||||
edit_object_placement(ifc, surveyor, obj=obj)
|
||||
edit_object_placement(ifc, geometry, surveyor, obj=obj)
|
||||
data = geometry.get_object_data(obj)
|
||||
|
||||
if not data:
|
||||
|
||||
@@ -74,6 +74,7 @@ class Context:
|
||||
class Geometry:
|
||||
def change_object_data(cls, obj, data, is_global=False): pass
|
||||
def clear_modifiers(cls, obj): pass
|
||||
def clear_scale(cls, obj): pass
|
||||
def create_dynamic_voids(cls, obj): pass
|
||||
def delete_data(cls, data): pass
|
||||
def does_object_have_mesh_with_faces(cls, obj): pass
|
||||
|
||||
@@ -39,6 +39,17 @@ class Geometry(blenderbim.core.tool.Geometry):
|
||||
for modifier in obj.modifiers:
|
||||
obj.modifiers.remove(modifier)
|
||||
|
||||
@classmethod
|
||||
def clear_scale(cls, obj):
|
||||
if obj.scale != Vector((1.0, 1.0, 1.0)):
|
||||
if obj.data.users == 1:
|
||||
context_override = {}
|
||||
context_override["object"] = context_override["active_object"] = obj
|
||||
context_override["selected_objects"] = context_override["selected_editable_objects"] = [obj]
|
||||
bpy.ops.object.transform_apply(context_override, location=False, rotation=False, scale=True)
|
||||
else:
|
||||
obj.scale = Vector((1.0, 1.0, 1.0))
|
||||
|
||||
@classmethod
|
||||
def create_dynamic_voids(cls, obj):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
|
||||
@@ -22,19 +22,20 @@ from test.core.bootstrap import ifc, surveyor, geometry, style
|
||||
|
||||
|
||||
class TestEditObjectPlacement:
|
||||
def predict(self, ifc, surveyor):
|
||||
def predict(self, ifc, geometry, surveyor):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
geometry.clear_scale("obj").should_be_called()
|
||||
surveyor.get_absolute_matrix("obj").should_be_called().will_return("matrix")
|
||||
ifc.run("geometry.edit_object_placement", product="element", matrix="matrix").should_be_called()
|
||||
|
||||
def test_run(self, ifc, surveyor):
|
||||
self.predict(ifc, surveyor)
|
||||
subject.edit_object_placement(ifc, surveyor, obj="obj")
|
||||
def test_run(self, ifc, geometry, surveyor):
|
||||
self.predict(ifc, geometry, surveyor)
|
||||
subject.edit_object_placement(ifc, geometry, surveyor, obj="obj")
|
||||
|
||||
|
||||
class TestAddRepresentation:
|
||||
def test_run(self, ifc, geometry, style, surveyor):
|
||||
TestEditObjectPlacement.predict(self, ifc, surveyor)
|
||||
TestEditObjectPlacement.predict(self, ifc, geometry, surveyor)
|
||||
|
||||
# Add representation
|
||||
geometry.get_object_data("obj").should_be_called().will_return("data")
|
||||
@@ -96,7 +97,7 @@ class TestAddRepresentation:
|
||||
)
|
||||
|
||||
def test_not_handling_styles_if_representation_has_no_faces(self, ifc, geometry, style, surveyor):
|
||||
TestEditObjectPlacement.predict(self, ifc, surveyor)
|
||||
TestEditObjectPlacement.predict(self, ifc, geometry, surveyor)
|
||||
|
||||
# Add representation
|
||||
geometry.get_object_data("obj").should_be_called().will_return("data")
|
||||
@@ -145,7 +146,7 @@ class TestAddRepresentation:
|
||||
)
|
||||
|
||||
def test_only_updating_the_placement_if_there_is_no_object_data(self, ifc, geometry, style, surveyor):
|
||||
TestEditObjectPlacement.predict(self, ifc, surveyor)
|
||||
TestEditObjectPlacement.predict(self, ifc, geometry, surveyor)
|
||||
|
||||
# Add representation
|
||||
geometry.get_object_data("obj").should_be_called().will_return(None)
|
||||
|
||||
@@ -61,6 +61,14 @@ class TestClearModifiers(NewFile):
|
||||
assert len(obj.modifiers) == 0
|
||||
|
||||
|
||||
class TestClearScale(NewFile):
|
||||
def test_run(self):
|
||||
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||
obj.scale[0] = 2
|
||||
subject.clear_scale(obj)
|
||||
assert list(obj.scale) == [1, 1, 1]
|
||||
|
||||
|
||||
class TestCreateDynamicVoids(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
|
||||
@@ -66,15 +66,6 @@ class Usecase:
|
||||
return any([abs((tM @ v.co).z) > threshold for v in face.verts])
|
||||
|
||||
def evaluate_geometry(self):
|
||||
if self.settings["blender_object"].scale != Vector((1., 1., 1.)):
|
||||
if self.settings["blender_object"].data.users == 1:
|
||||
context_override = {}
|
||||
context_override["object"] = context_override["active_object"] = self.settings["blender_object"]
|
||||
context_override["selected_objects"] = context_override["selected_editable_objects"] = [self.settings["blender_object"]]
|
||||
bpy.ops.object.transform_apply(context_override, location=False, rotation=False, scale=True)
|
||||
else:
|
||||
self.settings["blender_object"].scale = Vector((1., 1., 1.))
|
||||
|
||||
for modifier in self.settings["blender_object"].modifiers:
|
||||
if modifier.type == "BOOLEAN":
|
||||
modifier.show_viewport = False
|
||||
|
||||
Reference in New Issue
Block a user