Fix #3644. Annotation matrixes properly calculated now for RCPs.

This commit is contained in:
Dion Moult
2023-08-30 18:15:10 +10:00
parent 0a69e3668e
commit b33131db44
7 changed files with 38 additions and 8 deletions
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
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
@@ -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)
@@ -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))))
@@ -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()
+3 -1
View File
@@ -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 = {}
@@ -60,3 +60,11 @@ download.
See also blocks should be used to reference `further reading
<https://blenderbim.org>`__ 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"
+1 -1
View File
@@ -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])