diff --git a/src/blenderbim/blenderbim/bim/module/drawing/data.py b/src/blenderbim/blenderbim/bim/module/drawing/data.py index 04ab5925ef..20cc167c93 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/data.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/data.py @@ -87,9 +87,10 @@ class DrawingsData: @classmethod def location_hint(cls): - if bpy.context.scene.DocProperties.target_view == "PLAN_VIEW": + if bpy.context.scene.DocProperties.target_view in ["PLAN_VIEW", "REFLECTED_PLAN_VIEW"]: results = [("0", "Origin", "")] results.extend( [(str(s.id()), s.Name or "Unnamed", "") for s in tool.Ifc.get().by_type("IfcBuildingStorey")] ) return results + return [(h.upper(), h, "") for h in ["North", "South", "East", "West"]] diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index 9ed497d0cf..1ee6427847 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -72,12 +72,15 @@ class AddDrawing(bpy.types.Operator, Operator): def _execute(self, context): self.props = context.scene.DocProperties + hint = self.props.location_hint + if self.props.target_view in ["PLAN_VIEW", "REFLECTED_PLAN_VIEW"]: + hint = int(hint) core.add_drawing( tool.Ifc, tool.Collector, tool.Drawing, target_view=self.props.target_view, - location_hint=int(self.props.location_hint), + location_hint=hint, ) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/prop.py b/src/blenderbim/blenderbim/bim/module/drawing/prop.py index 5ce6e7477f..db666f0991 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/prop.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/prop.py @@ -57,6 +57,10 @@ def purge(): vector_styles_enum = [] +def update_target_view(self, context): + DrawingsData.data["location_hint"] = DrawingsData.location_hint() + + def get_location_hint(self, context): if not DrawingsData.is_loaded: DrawingsData.load() @@ -291,6 +295,7 @@ class DocProperties(PropertyGroup): ], name="Target View", default="PLAN_VIEW", + update=update_target_view, ) location_hint: EnumProperty(items=get_location_hint, name="Location Hint") drawings: CollectionProperty(name="Drawings", type=Drawing) diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index ff6b1bf444..d7ad08489a 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -119,13 +119,36 @@ class Drawing(blenderbim.core.tool.Drawing): @classmethod def generate_drawing_matrix(cls, target_view, location_hint): + x = 0 if location_hint == 0 else bpy.context.scene.cursor.matrix[0][3] + y = 0 if location_hint == 0 else bpy.context.scene.cursor.matrix[1][3] + z = 0 if location_hint == 0 else bpy.context.scene.cursor.matrix[2][3] if target_view == "PLAN_VIEW": if location_hint: - m = tool.Ifc.get_object(tool.Ifc.get().by_id(location_hint)).matrix_world.copy() - m[0][3] = bpy.context.scene.cursor.matrix[0][3] - m[1][3] = bpy.context.scene.cursor.matrix[1][3] - m[2][3] += 1.6 - return m + z = tool.Ifc.get_object(tool.Ifc.get().by_id(location_hint)).matrix_world[2][3] + return mathutils.Matrix(((1, 0, 0, x), (0, 1, 0, y), (0, 0, 1, z + 1.6), (0, 0, 0, 1))) + elif target_view == "REFLECTED_PLAN_VIEW": + if location_hint: + z = tool.Ifc.get_object(tool.Ifc.get().by_id(location_hint)).matrix_world[2][3] + return mathutils.Matrix(((-1, 0, 0, x), (0, 1, 0, y), (0, 0, -1, z + 1.6), (0, 0, 0, 1))) + return mathutils.Matrix(((-1, 0, 0, 0), (0, 1, 0, 0), (0, 0, -1, 0), (0, 0, 0, 1))) + elif target_view == "ELEVATION_VIEW": + if location_hint == "NORTH": + return mathutils.Matrix(((-1, 0, 0, x), (0, 0, 1, y), (0, 1, 0, z), (0, 0, 0, 1))) + elif location_hint == "SOUTH": + return mathutils.Matrix(((1, 0, 0, x), (0, 0, -1, y), (0, 1, 0, z), (0, 0, 0, 1))) + elif location_hint == "EAST": + return mathutils.Matrix(((0, 0, 1, x), (1, 0, 0, y), (0, 1, 0, z), (0, 0, 0, 1))) + elif location_hint == "WEST": + return mathutils.Matrix(((0, 0, -1, x), (-1, 0, 0, y), (0, 1, 0, z), (0, 0, 0, 1))) + elif target_view == "SECTION_VIEW": + if location_hint == "NORTH": + return mathutils.Matrix(((1, 0, 0, x), (0, 0, -1, y), (0, 1, 0, z), (0, 0, 0, 1))) + elif location_hint == "SOUTH": + return mathutils.Matrix(((-1, 0, 0, x), (0, 0, 1, y), (0, 1, 0, z), (0, 0, 0, 1))) + elif location_hint == "EAST": + return mathutils.Matrix(((0, 0, -1, x), (-1, 0, 0, y), (0, 1, 0, z), (0, 0, 0, 1))) + elif location_hint == "WEST": + return mathutils.Matrix(((0, 0, 1, x), (1, 0, 0, y), (0, 1, 0, z), (0, 0, 0, 1))) return mathutils.Matrix() @classmethod diff --git a/src/blenderbim/test/tool/test_drawing.py b/src/blenderbim/test/tool/test_drawing.py index 9f10e3596e..b530473cd8 100644 --- a/src/blenderbim/test/tool/test_drawing.py +++ b/src/blenderbim/test/tool/test_drawing.py @@ -175,7 +175,7 @@ class TestGenerateDrawingMatrix(NewFile): def test_returning_the_origin_as_a_fallback(self): assert subject.generate_drawing_matrix("PLAN_VIEW", None) == mathutils.Matrix() - def test_using_the_matrix_from_the_cursor_and_a_preexisting_object(self): + def test_creating_a_plan_view_at_the_cursor_at_a_storey(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) obj = bpy.data.objects.new("Object", None) @@ -189,6 +189,72 @@ class TestGenerateDrawingMatrix(NewFile): assert round(m[1][3], 3) == 2 assert round(m[2][3], 3) == 4.6 + def test_creating_an_rcp_at_the_origin(self): + assert subject.generate_drawing_matrix("REFLECTED_PLAN_VIEW", None) == mathutils.Matrix( + ((-1, 0, 0, 0), (0, 1, 0, 0), (0, 0, -1, 0), (0, 0, 0, 1)) + ) + + def test_creating_an_rcp_at_the_cursor_at_a_storey(self): + ifc = ifcopenshell.file() + tool.Ifc.set(ifc) + obj = bpy.data.objects.new("Object", None) + element = ifc.createIfcBuildingStorey() + tool.Ifc.link(element, obj) + bpy.context.scene.collection.objects.link(obj) + obj.matrix_world[2][3] = 3 + bpy.context.scene.cursor.location = (1.0, 2.0, 0.0) + assert subject.generate_drawing_matrix("REFLECTED_PLAN_VIEW", element.id()) == mathutils.Matrix( + ((-1, 0, 0, 1), (0, 1, 0, 2), (0, 0, -1, 3 + 1.6), (0, 0, 0, 1)) + ) + + def test_creating_a_north_elevation_at_the_cursor(self): + bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) + assert subject.generate_drawing_matrix("ELEVATION_VIEW", "NORTH") == mathutils.Matrix( + ((-1, 0, 0, 1), (0, 0, 1, 2), (0, 1, 0, 3), (0, 0, 0, 1)) + ) + + def test_creating_a_south_elevation_at_the_cursor(self): + bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) + assert subject.generate_drawing_matrix("ELEVATION_VIEW", "SOUTH") == mathutils.Matrix( + ((1, 0, 0, 1), (0, 0, -1, 2), (0, 1, 0, 3), (0, 0, 0, 1)) + ) + + def test_creating_an_east_elevation_at_the_cursor(self): + bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) + assert subject.generate_drawing_matrix("ELEVATION_VIEW", "EAST") == mathutils.Matrix( + ((0, 0, 1, 1), (1, 0, 0, 2), (0, 1, 0, 3), (0, 0, 0, 1)) + ) + + def test_creating_a_west_elevation_at_the_cursor(self): + bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) + assert subject.generate_drawing_matrix("ELEVATION_VIEW", "WEST") == mathutils.Matrix( + ((0, 0, -1, 1), (-1, 0, 0, 2), (0, 1, 0, 3), (0, 0, 0, 1)) + ) + + def test_creating_a_north_section_at_the_cursor(self): + bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) + assert subject.generate_drawing_matrix("SECTION_VIEW", "NORTH") == mathutils.Matrix( + ((1, 0, 0, 1), (0, 0, -1, 2), (0, 1, 0, 3), (0, 0, 0, 1)) + ) + + def test_creating_a_south_section_at_the_cursor(self): + bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) + assert subject.generate_drawing_matrix("SECTION_VIEW", "SOUTH") == mathutils.Matrix( + ((-1, 0, 0, 1), (0, 0, 1, 2), (0, 1, 0, 3), (0, 0, 0, 1)) + ) + + def test_creating_an_east_section_at_the_cursor(self): + bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) + assert subject.generate_drawing_matrix("SECTION_VIEW", "EAST") == mathutils.Matrix( + ((0, 0, -1, 1), (-1, 0, 0, 2), (0, 1, 0, 3), (0, 0, 0, 1)) + ) + + def test_creating_a_west_section_at_the_cursor(self): + bpy.context.scene.cursor.location = (1.0, 2.0, 3.0) + assert subject.generate_drawing_matrix("SECTION_VIEW", "WEST") == mathutils.Matrix( + ((0, 0, 1, 1), (1, 0, 0, 2), (0, 1, 0, 3), (0, 0, 0, 1)) + ) + class TestGenerateSheetIdentification(NewFile): def test_run(self):