diff --git a/src/blenderbim/blenderbim/bim/module/drawing/annotation.py b/src/blenderbim/blenderbim/bim/module/drawing/annotation.py index 10e1e59e5a..9188291f40 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/annotation.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/annotation.py @@ -16,11 +16,13 @@ # You should have received a copy of the GNU General Public License # along with BlenderBIM Add-on. If not, see . -import bpy import os -import blenderbim.tool as tool -from mathutils import Vector +import bpy +import math import bmesh +import blenderbim.tool as tool +import ifcopenshell.util.element +from mathutils import Vector, Matrix class Annotator: @@ -111,7 +113,7 @@ class Annotator: def get_annotation_obj(drawing, object_type, data_type): camera = tool.Ifc.get_object(drawing) co1, _, _, _ = Annotator.get_placeholder_coords(camera) - matrix_world = camera.matrix_world.copy() + matrix_world = tool.Drawing.get_camera_matrix(camera) matrix_world.translation = co1 collection = camera.BIMObjectProperties.collection @@ -154,6 +156,13 @@ class Annotator: camera = bpy.context.scene.camera z_offset = camera.matrix_world.to_quaternion() @ Vector((0, 0, -1)) + + if ( + ifcopenshell.util.element.get_pset(tool.Ifc.get_entity(camera), "EPset_Drawing", "TargetView") + == "REFLECTED_PLAN_VIEW" + ): + z_offset *= -1 + y = camera.data.ortho_scale / 4 res_x = bpy.context.scene.render.resolution_x diff --git a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py index 13c66efa5f..6b21e95bee 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py @@ -520,7 +520,9 @@ class BaseDecorator: return matrix.inverted()[i].to_3d().normalized() text_dir_world_x_axis = get_basis_vector(obj.matrix_world) - camera_matrix = camera.matrix_world.normalized() + + camera_matrix = tool.Drawing.get_camera_matrix(camera) + 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) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py index 7021c9bfd2..a987157c63 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py @@ -805,7 +805,7 @@ class SvgWriter: text_dir_world_x_axis = get_basis_vector(text_obj.matrix_world) # RCP cameras may be scaled, so reset scales. - camera_matrix = self.camera.matrix_world.normalized() + camera_matrix = tool.Drawing.get_camera_matrix(self.camera) 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)))) diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index f78862baf9..bcf9c1ebae 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -1849,3 +1849,12 @@ class Drawing(blenderbim.core.tool.Drawing): sheet_references.append(reference) break return sheet_references + + def get_camera_matrix(self, camera): + matrix_world = camera.matrix_world.copy().normalized() + location, rotation, scale = matrix_world.decompose() + if scale.x < 0 or scale.y < 0 or scale.z < 0: + # RCPs may be inversely scaled. We discard the scale and rotate the Z to compensate. + rotate180z = mathutils.Matrix.Rotation(math.radians(180.0), 4, "Z") + return mathutils.Matrix.Translation(location) @ rotation.to_matrix().to_4x4() @ rotate180z + return mathutils.Matrix.Translation(location) @ rotation.to_matrix().to_4x4() diff --git a/src/blenderbim/blenderbim/tool/geometry.py b/src/blenderbim/blenderbim/tool/geometry.py index 3b78dfb8d4..0544c9d330 100644 --- a/src/blenderbim/blenderbim/tool/geometry.py +++ b/src/blenderbim/blenderbim/tool/geometry.py @@ -29,7 +29,7 @@ import blenderbim.core.spatial import blenderbim.tool as tool import blenderbim.bim.import_ifc from math import radians -from mathutils import Vector +from mathutils import Vector, Matrix from blenderbim.bim.ifc import IfcStore @@ -59,6 +59,8 @@ class Geometry(blenderbim.core.tool.Geometry): # Note that clearing scale has no impact on cameras. if (obj.scale - Vector((1.0, 1.0, 1.0))).length > 1e-4: if not obj.data: + location, rotation, _ = obj.matrix_world.decompose() + obj.matrix_world = Matrix.Translation(location) @ rotation.to_matrix().to_4x4() obj.matrix_world.normalize() elif obj.data.users == 1: context_override = {} diff --git a/src/blenderbim/docs/devs/writing_docs.rst b/src/blenderbim/docs/devs/writing_docs.rst index c5be24d5b2..0d14e89bee 100644 --- a/src/blenderbim/docs/devs/writing_docs.rst +++ b/src/blenderbim/docs/devs/writing_docs.rst @@ -60,3 +60,11 @@ download. See also blocks should be used to reference `further reading `__ links. + +Tables can be very annoying to format. You can use a CSV table instead. + +.. csv-table:: + :header: "Foo", "Bar", "Baz" + + "ABC", "01", "02" + "DEF", "03", "04" diff --git a/src/ifccsv/ifccsv.py b/src/ifccsv/ifccsv.py index d8e31a2183..1f72bf6c54 100755 --- a/src/ifccsv/ifccsv.py +++ b/src/ifccsv/ifccsv.py @@ -258,7 +258,7 @@ class IfcCsv: reverse = sort_data["order"] == "DESC" self.results = sorted(self.results, key=lambda x: natural_sort(x[i]), reverse=reverse) else: - if include_global_id and len(list(self.results[0])) > 1: + if include_global_id and len(list(self.results)[0]) > 1: self.results = sorted(self.results, key=lambda x: x[1]) elif not include_global_id: self.results = sorted(self.results, key=lambda x: x[0])