Minor fix.

This commit is contained in:
Dion Moult
2021-11-10 12:46:07 +11:00
parent d733960068
commit c1c50f8868
10 changed files with 50 additions and 40 deletions
+1 -1
View File
@@ -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:
+3 -2
View File
@@ -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:
+1
View File
@@ -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)
+8 -7
View File
@@ -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