From 3345d7e08803e7c1bf677348083820214ff450fd Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 11 Aug 2023 22:40:46 +1000 Subject: [PATCH] Fix #2894. Implement reflected ceiling plans. Note that this requires new bot build. --- .../blenderbim/bim/module/drawing/decoration.py | 6 +++++- src/blenderbim/blenderbim/bim/module/drawing/operator.py | 6 ++++-- .../blenderbim/bim/module/drawing/svgwriter.py | 9 ++++++++- src/blenderbim/blenderbim/tool/drawing.py | 9 ++++++++- src/blenderbim/blenderbim/tool/geometry.py | 7 ++++++- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py index e392084f8d..9daf4ede50 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py @@ -520,7 +520,11 @@ class BaseDecorator: return matrix.inverted()[i].to_3d().normalized() text_dir_world_x_axis = get_basis_vector(obj.matrix_world) - text_dir = (camera.matrix_world.inverted().to_quaternion() @ text_dir_world_x_axis).to_2d().normalized() + camera_matrix = camera.matrix_world.copy() + camera_matrix[0][0] = 1 + camera_matrix[1][1] = 1 + camera_matrix[2][2] = 1 + text_dir = (camera_matrix.inverted().to_quaternion() @ text_dir_world_x_axis).to_2d().normalized() pos = location_3d_to_region_2d(region, region3d, text_world_position) props = obj.BIMTextProperties diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index 1cbbd8d838..3b16062315 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -485,7 +485,7 @@ class CreateDrawing(bpy.types.Operator): drawing_elements = tool.Drawing.get_drawing_elements(self.camera_element) - self.setup_serialiser(ifc) + self.setup_serialiser(ifc, target_view) cache = IfcStore.get_cache() [cache.remove(guid) for guid in invalidated_guids] tree = ifcopenshell.geom.tree() @@ -829,7 +829,7 @@ class CreateDrawing(bpy.types.Operator): return svg_path - def setup_serialiser(self, ifc): + def setup_serialiser(self, ifc, target_view): self.svg_settings = ifcopenshell.geom.settings( DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True, INCLUDE_CURVES=True ) @@ -853,6 +853,8 @@ class CreateDrawing(bpy.types.Operator): self.serialiser.setScale(self.scale) self.serialiser.setSubtractionSettings(ifcopenshell.ifcopenshell_wrapper.ALWAYS) self.serialiser.setUsePrefiltering(True) # See #3359 + if target_view == "REFLECTED_PLAN_VIEW": + self.serialiser.setMirrorY(True) # tree = ifcopenshell.geom.tree() # This instructs the tree to explode BReps into faces and return # the style of the face when running tree.select_ray() diff --git a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py index a0ed721fa5..9b3fad9ee8 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py @@ -791,7 +791,14 @@ class SvgWriter: return matrix.inverted()[i].to_3d().normalized() text_dir_world_x_axis = get_basis_vector(text_obj.matrix_world) - text_dir = (self.camera.matrix_world.inverted().to_quaternion() @ text_dir_world_x_axis).to_2d().normalized() + + # RCP cameras may be scaled, so reset scales. + camera_matrix = self.camera.matrix_world.copy() + camera_matrix[0][0] = 1 + camera_matrix[1][1] = 1 + camera_matrix[2][2] = 1 + + text_dir = (camera_matrix.inverted().to_quaternion() @ text_dir_world_x_axis).to_2d().normalized() angle = math.degrees(-text_dir.angle_signed(Vector((1, 0)))) classes = self.get_attribute_classes(text_obj) diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index 6ad4ba21a7..73e5157171 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -450,7 +450,10 @@ class Drawing(blenderbim.core.tool.Drawing): elif target_view == "REFLECTED_PLAN_VIEW": if location_hint: z = tool.Ifc.get_object(tool.Ifc.get().by_id(location_hint)).matrix_world.translation.z - return mathutils.Matrix(((-1, 0, 0, x), (0, 1, 0, y), (0, 0, -1, z + 1.6), (0, 0, 0, 1))) + m = mathutils.Matrix() + m[2][2] = -1 + m.translation = (x, y, z + 1.6) + return m 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": @@ -677,6 +680,10 @@ class Drawing(blenderbim.core.tool.Drawing): ([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1]) ) obj.matrix_world = mat + + if cls.get_drawing_target_view(drawing) == "REFLECTED_PLAN_VIEW": + obj.matrix_world[1][1] *= -1 + tool.Geometry.record_object_position(obj) tool.Collector.assign(obj) diff --git a/src/blenderbim/blenderbim/tool/geometry.py b/src/blenderbim/blenderbim/tool/geometry.py index 839f67ffb8..10f04a7f08 100644 --- a/src/blenderbim/blenderbim/tool/geometry.py +++ b/src/blenderbim/blenderbim/tool/geometry.py @@ -56,8 +56,13 @@ class Geometry(blenderbim.core.tool.Geometry): @classmethod def clear_scale(cls, obj): + # Note that clearing scale has no impact on cameras. if (obj.scale - Vector((1.0, 1.0, 1.0))).length > 1e-4: - if obj.data.users == 1: + if not obj.data: + obj.matrix_world[0][0] = 1 + obj.matrix_world[1][1] = 1 + obj.matrix_world[2][2] = 1 + elif obj.data.users == 1: context_override = {} context_override["object"] = context_override["active_object"] = obj context_override["selected_objects"] = context_override["selected_editable_objects"] = [obj]