small matrix math refactor

more readable and allows avoiding jumping between 3d/4d vectors
This commit is contained in:
Andrej730
2023-07-20 18:58:52 +05:00
parent 0dee353b8e
commit c61854c7aa
13 changed files with 79 additions and 112 deletions
@@ -103,10 +103,8 @@ class Loader:
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
matrix = mathutils.Matrix(
ifcopenshell.util.placement.get_axis2placement(surface.BasisSurface.Position).tolist()
)
matrix[0][3] *= unit_scale
matrix[1][3] *= unit_scale
matrix[2][3] *= unit_scale
)
matrix.translation *= unit_scale
mesh.transform(matrix)
return mesh
@@ -691,7 +689,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
mat.col[0][:3] = x_axis
mat.col[1][:3] = y_axis
mat.col[2][:3] = z_axis
mat.col[3][:3] = p1
mat.translation = p1
return mat
@@ -725,7 +723,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
def export_surface(self, polygon, target_face_matrix):
x_axis = target_face_matrix.col[0][:3]
z_axis = target_face_matrix.col[2][:3]
p1 = target_face_matrix.col[3][:3]
p1 = target_face_matrix.translation
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
tool.Model.unit_scale = self.unit_scale
@@ -354,7 +354,7 @@ class UglyDotGizmo(OffsetHandle, types.Gizmo):
def refresh(self):
offset = self.target_get_value("offset") / self.scale_value
self.matrix_offset.col[3][2] = offset # z-shift
self.matrix_offset.translation.z = offset # z-shift
def draw(self, ctx):
self.refresh()
@@ -385,7 +385,7 @@ class DotGizmo(CustomGizmo, OffsetHandle, types.Gizmo):
def refresh(self):
offset = self.target_get_value("offset") / self.scale_value
self.matrix_offset.col[3][2] = offset # z-shifted
self.matrix_offset.translation.z = offset # z-shifted
def draw(self, ctx):
self.refresh()
@@ -443,7 +443,7 @@ class DimensionLabelGizmo(types.Gizmo):
def refresh(self, ctx):
value = self.target_get_value("value")
self.matrix_offset.col[3][2] = value * 0.5
self.matrix_offset.translation.z = value * 0.5
unit_system = ctx.scene.unit_settings.system
self.text_label = bpy.utils.units.to_string(unit_system, "LENGTH", value, 3, split_unit=False)
@@ -238,7 +238,7 @@ class Input3DCursorXArray(bpy.types.Operator):
props = obj.BIMArrayProperties
cursor = context.scene.cursor
if props.use_local_space:
props.x = (Matrix.inverted(obj.matrix_world) @ cursor.matrix.col[3]).x
props.x = (Matrix.inverted(obj.matrix_world) @ cursor.matrix.translation).x
else:
props.x = cursor.location.x - obj.location.x
return {"FINISHED"}
@@ -254,7 +254,7 @@ class Input3DCursorYArray(bpy.types.Operator):
props = obj.BIMArrayProperties
cursor = context.scene.cursor
if props.use_local_space:
props.y = (Matrix.inverted(obj.matrix_world) @ cursor.matrix.col[3]).y
props.y = (Matrix.inverted(obj.matrix_world) @ cursor.matrix.translation).y
else:
props.y = cursor.location.y - obj.location.y
return {"FINISHED"}
@@ -270,7 +270,7 @@ class Input3DCursorZArray(bpy.types.Operator):
props = obj.BIMArrayProperties
cursor = context.scene.cursor
if props.use_local_space:
props.z = (Matrix.inverted(obj.matrix_world) @ cursor.matrix.col[3]).z
props.z = (Matrix.inverted(obj.matrix_world) @ cursor.matrix.translation).z
else:
props.z = cursor.location.z - obj.location.z
return {"FINISHED"}
@@ -257,7 +257,7 @@ class ProfileDecorator:
circle_centroids.append(tuple(centroid))
segments = self.create_circle_segments(360, 20, radius)
matrix = obj.matrix_world.copy()
matrix.col[3] = centroid.to_4d()
matrix.translation = centroid
segments = [[list(matrix @ Vector(v)) for v in segments[0]], segments[1]]
circle_segments.append(segments)
@@ -76,7 +76,7 @@ class FilledOpeningGenerator:
if voided_obj.data:
raycast = voided_obj.closest_point_on_mesh(voided_obj.matrix_world.inverted() @ target, distance=0.01)
if not raycast[0]:
target = filling_obj.matrix_world.col[3].to_3d().copy()
target = filling_obj.matrix_world.translation.copy()
raycast = voided_obj.closest_point_on_mesh(voided_obj.matrix_world.inverted() @ target, distance=0.5)
if not raycast[0]:
return
@@ -86,12 +86,12 @@ class FilledOpeningGenerator:
axis = tool.Model.get_wall_axis(voided_obj, layers=layers)["base"]
new_matrix = voided_obj.matrix_world.copy()
new_matrix.col[3] = tool.Cad.point_on_edge(target, axis).to_4d()
new_matrix.translation = tool.Cad.point_on_edge(target, axis)
if filling.is_a("IfcDoor"):
new_matrix[2][3] = voided_obj.matrix_world[2][3]
new_matrix.translation.z = voided_obj.matrix_world.translation.z
else:
new_matrix[2][3] = voided_obj.matrix_world[2][3] + (props.rl2 * unit_scale)
new_matrix.translation.z = voided_obj.matrix_world.translation.z + (props.rl2 * unit_scale)
filling_obj.matrix_world = new_matrix
bpy.context.view_layer.update()
@@ -392,13 +392,12 @@ class FlipFill(bpy.types.Operator, tool.Ifc.Operator):
bottom_left = obj.matrix_world @ Vector(obj.bound_box[0])
top_right = obj.matrix_world @ Vector(obj.bound_box[6])
center = obj.matrix_world.col[3].to_3d().copy()
center = obj.matrix_world.translation.copy()
center_offset = center - bottom_left
flipped_center = top_right - center_offset
obj.matrix_world = obj.matrix_world @ flip_matrix
obj.matrix_world.col[3][0] = flipped_center[0]
obj.matrix_world.col[3][1] = flipped_center[1]
obj.matrix_world.translation.xy = flipped_center.xy
bpy.context.view_layer.update()
return {"FINISHED"}
@@ -425,7 +424,7 @@ class AddPotentialOpening(Operator, AddObjectHelper):
new_matrix = None
if context.selected_objects and context.active_object:
new_matrix = context.active_object.matrix_world.copy()
new_matrix.col[3] = context.scene.cursor.location.to_4d()
new_matrix.translation = context.scene.cursor.location
x = self.x / 2
y = self.y / 2
@@ -578,9 +577,7 @@ class ShowBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
boolean_obj = self.create_half_space_solid()
position = boolean.BaseSurface.Position
position = Matrix(ifcopenshell.util.placement.get_axis2placement(position).tolist())
position[0][3] *= unit_scale
position[1][3] *= unit_scale
position[2][3] *= unit_scale
position.translation *= unit_scale
boolean_obj.matrix_world = obj.matrix_world @ position
else:
settings = ifcopenshell.geom.settings()
@@ -390,7 +390,7 @@ class MirrorElements(bpy.types.Operator, tool.Ifc.Operator):
newc = mirror.matrix_world @ (c @ reflection)
newmat = Matrix((newx.to_4d(), newy.to_4d(), newz.to_4d(), newc.to_4d())).transposed()
newmat.col[3][0:3] = Vector(newmat.col[3][0:3]) - (newmat.to_quaternion() @ centroid)
newmat.translation = Vector(newmat.translation) - (newmat.to_quaternion() @ centroid)
obj.matrix_world = newmat
@@ -79,9 +79,9 @@ class DumbProfileGenerator:
"IfcFlowSegmentType"
):
matrix_world = Matrix.Rotation(pi / 2, 4, "Z") @ Matrix.Rotation(pi / 2, 4, "X") @ matrix_world
matrix_world.col[3] = self.location.to_4d()
matrix_world.translation = self.location
if self.collection_obj and self.collection_obj.BIMObjectProperties.ifc_definition_id:
matrix_world[2][3] = self.collection_obj.location[2]
matrix_world.translation.z = self.collection_obj.location.z
self.collection.objects.link(obj)
element = blenderbim.core.root.assign_class(
@@ -413,7 +413,7 @@ class DumbProfileJoiner:
)
new_matrix = copy.deepcopy(obj.matrix_world)
new_matrix.col[3] = self.body[0].to_4d().copy()
new_matrix.translation = self.body[0].copy()
new_matrix.invert()
for clipping in self.clippings:
@@ -563,13 +563,13 @@ class DumbProfileJoiner:
if tool.Cad.is_x(abs(xy_angle), (0, 90, 180), tolerance=0.001) and is_orthogonal:
plane = self.get_profile_plane(profile2, furthest_plane)
intersect = mathutils.geometry.intersect_line_plane(
*axis1, plane.col[3].to_3d(), plane.col[2].to_3d()
*axis1, plane.translation, plane.col[2].to_3d()
)
self.body[1] = intersect
else:
plane = self.get_profile_plane(profile2, furthest_plane, z_inwards=False)
intersect = mathutils.geometry.intersect_line_plane(
*axis1, plane.col[3].to_3d(), plane.col[2].to_3d()
*axis1, plane.translation, plane.col[2].to_3d()
)
max_dim = self.get_max_bound_box_dimension(profile1)
self.body[1] = intersect + profile1.matrix_world.to_quaternion() @ Vector((0, 0, max_dim))
@@ -579,25 +579,25 @@ class DumbProfileJoiner:
plane1 = self.get_profile_plane(profile1, furthest_plane2)
plane2 = self.get_profile_plane(profile2, furthest_plane)
clip1, direction1 = mathutils.geometry.intersect_plane_plane(
plane1.col[3].to_3d(), plane1.col[2].to_3d(), plane2.col[3].to_3d(), plane2.col[2].to_3d()
plane1.translation, plane1.col[2].to_3d(), plane2.translation, plane2.col[2].to_3d()
)
plane1 = self.get_profile_plane(profile1, closest_plane2)
plane2 = self.get_profile_plane(profile2, closest_plane)
clip2, direction2 = mathutils.geometry.intersect_plane_plane(
plane1.col[3].to_3d(), plane1.col[2].to_3d(), plane2.col[3].to_3d(), plane2.col[2].to_3d()
plane1.translation, plane1.col[2].to_3d(), plane2.translation, plane2.col[2].to_3d()
)
else:
plane1 = self.get_profile_plane(profile1, furthest_plane2)
plane2 = self.get_profile_plane(profile2, furthest_plane)
clip1, direction1 = mathutils.geometry.intersect_plane_plane(
plane1.col[3].to_3d(), plane1.col[2].to_3d(), plane2.col[3].to_3d(), plane2.col[2].to_3d()
plane1.translation, plane1.col[2].to_3d(), plane2.translation, plane2.col[2].to_3d()
)
plane1 = self.get_profile_plane(profile1, closest_plane2)
plane2 = self.get_profile_plane(profile2, closest_plane)
clip2, direction2 = mathutils.geometry.intersect_plane_plane(
plane1.col[3].to_3d(), plane1.col[2].to_3d(), plane2.col[3].to_3d(), plane2.col[2].to_3d()
plane1.translation, plane1.col[2].to_3d(), plane2.translation, plane2.col[2].to_3d()
)
y_axis = direction2
@@ -614,13 +614,13 @@ class DumbProfileJoiner:
if tool.Cad.is_x(abs(xy_angle), (0, 90, 180), tolerance=0.001) and is_orthogonal:
plane = self.get_profile_plane(profile2, furthest_plane)
intersect = mathutils.geometry.intersect_line_plane(
*axis1, plane.col[3].to_3d(), plane.col[2].to_3d()
*axis1, plane.translation, plane.col[2].to_3d()
)
self.body[0] = intersect
else:
plane = self.get_profile_plane(profile2, furthest_plane, z_inwards=False)
intersect = mathutils.geometry.intersect_line_plane(
*axis1, plane.col[3].to_3d(), plane.col[2].to_3d()
*axis1, plane.translation, plane.col[2].to_3d()
)
max_dim = self.get_max_bound_box_dimension(profile1)
self.body[0] = intersect - profile1.matrix_world.to_quaternion() @ Vector((0, 0, max_dim))
@@ -629,25 +629,25 @@ class DumbProfileJoiner:
plane1 = self.get_profile_plane(profile1, furthest_plane2)
plane2 = self.get_profile_plane(profile2, furthest_plane)
clip1, direction1 = mathutils.geometry.intersect_plane_plane(
plane1.col[3].to_3d(), plane1.col[2].to_3d(), plane2.col[3].to_3d(), plane2.col[2].to_3d()
plane1.translation, plane1.col[2].to_3d(), plane2.translation, plane2.col[2].to_3d()
)
plane1 = self.get_profile_plane(profile1, closest_plane2)
plane2 = self.get_profile_plane(profile2, closest_plane)
clip2, direction2 = mathutils.geometry.intersect_plane_plane(
plane1.col[3].to_3d(), plane1.col[2].to_3d(), plane2.col[3].to_3d(), plane2.col[2].to_3d()
plane1.translation, plane1.col[2].to_3d(), plane2.translation, plane2.col[2].to_3d()
)
else:
plane1 = self.get_profile_plane(profile1, furthest_plane2)
plane2 = self.get_profile_plane(profile2, furthest_plane)
clip1, direction1 = mathutils.geometry.intersect_plane_plane(
plane1.col[3].to_3d(), plane1.col[2].to_3d(), plane2.col[3].to_3d(), plane2.col[2].to_3d()
plane1.translation, plane1.col[2].to_3d(), plane2.translation, plane2.col[2].to_3d()
)
plane1 = self.get_profile_plane(profile1, closest_plane2)
plane2 = self.get_profile_plane(profile2, closest_plane)
clip2, direction2 = mathutils.geometry.intersect_plane_plane(
plane1.col[3].to_3d(), plane1.col[2].to_3d(), plane2.col[3].to_3d(), plane2.col[2].to_3d()
plane1.translation, plane1.col[2].to_3d(), plane2.translation, plane2.col[2].to_3d()
)
y_axis = direction2
@@ -666,7 +666,7 @@ class DumbProfileJoiner:
if tool.Cad.is_x(abs(xy_angle), (0, 90, 180), tolerance=0.001) and is_orthogonal:
plane = self.get_profile_plane(profile2, furthest_plane if is_relating else closest_plane)
intersect = mathutils.geometry.intersect_line_plane(
*axis1, plane.col[3].to_3d(), plane.col[2].to_3d()
*axis1, plane.translation, plane.col[2].to_3d()
)
self.body[1] = intersect
else:
@@ -676,7 +676,7 @@ class DumbProfileJoiner:
z_inwards=False if is_relating else True,
)
intersect = mathutils.geometry.intersect_line_plane(
*axis1, plane.col[3].to_3d(), plane.col[2].to_3d()
*axis1, plane.translation, plane.col[2].to_3d()
)
max_dim = self.get_max_bound_box_dimension(profile1)
self.body[1] = intersect + profile1.matrix_world.to_quaternion() @ Vector((0, 0, max_dim))
@@ -691,7 +691,7 @@ class DumbProfileJoiner:
if tool.Cad.is_x(abs(xy_angle), (0, 90, 180), tolerance=0.001) and is_orthogonal:
plane = self.get_profile_plane(profile2, furthest_plane if is_relating else closest_plane)
intersect = mathutils.geometry.intersect_line_plane(
*axis1, plane.col[3].to_3d(), plane.col[2].to_3d()
*axis1, plane.translation, plane.col[2].to_3d()
)
self.body[0] = intersect
else:
@@ -701,7 +701,7 @@ class DumbProfileJoiner:
z_inwards=False if is_relating else True,
)
intersect = mathutils.geometry.intersect_line_plane(
*axis1, plane.col[3].to_3d(), plane.col[2].to_3d()
*axis1, plane.translation, plane.col[2].to_3d()
)
max_dim = self.get_max_bound_box_dimension(profile1)
self.body[0] = intersect - profile1.matrix_world.to_quaternion() @ Vector((0, 0, max_dim))
@@ -937,9 +937,7 @@ class EnableEditingExtrusionAxis(bpy.types.Operator, tool.Ifc.Operator):
if extrusion.Position:
position = Matrix(ifcopenshell.util.placement.get_axis2placement(extrusion.Position).tolist())
position[0][3] *= self.unit_scale
position[1][3] *= self.unit_scale
position[2][3] *= self.unit_scale
position.translation *= self.unit_scale
else:
position = Matrix()
@@ -155,11 +155,11 @@ class DumbSlabGenerator:
obj = bpy.data.objects.new(tool.Model.generate_occurrence_name(self.relating_type, ifc_class), mesh)
matrix_world = Matrix()
matrix_world.col[3] = self.location.to_4d()
matrix_world.translation = self.location
if self.collection_obj and self.collection_obj.BIMObjectProperties.ifc_definition_id:
matrix_world[2][3] = self.collection_obj.location[2] - self.depth
matrix_world.translation.z = self.collection_obj.location.z - self.depth
else:
matrix_world[2][3] -= self.depth
matrix_world.translation.z -= self.depth
obj.matrix_world = Matrix.Rotation(self.x_angle, 4, "X") @ matrix_world
bpy.context.view_layer.update()
self.collection.objects.link(obj)
@@ -359,9 +359,7 @@ class EnableEditingSketchExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator)
profile = extrusion.SweptArea
if extrusion.Position:
position = Matrix(ifcopenshell.util.placement.get_axis2placement(extrusion.Position).tolist())
position[0][3] *= self.unit_scale
position[1][3] *= self.unit_scale
position[2][3] *= self.unit_scale
position.matrix_world.translation *= self.unit_scale
else:
position = Matrix()
@@ -447,7 +445,7 @@ class EnableEditingSketchExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator)
self.edges[-1] = (len(self.vertices) - 1, offset) # Close the loop
elif curve.is_a("IfcCircle"):
center = self.convert_unit_to_si(
Matrix(ifcopenshell.util.placement.get_axis2placement(curve.Position).tolist()).col[3].to_3d()
Matrix(ifcopenshell.util.placement.get_axis2placement(curve.Position).tolist()).translation
)
radius = self.convert_unit_to_si(curve.Radius)
self.vertices.extend(
@@ -617,9 +615,7 @@ class EnableEditingExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
if extrusion.Position:
position = Matrix(ifcopenshell.util.placement.get_axis2placement(extrusion.Position).tolist())
position[0][3] *= self.unit_scale
position[1][3] *= self.unit_scale
position[2][3] *= self.unit_scale
position.translation *= self.unit_scale
else:
position = Matrix()
@@ -650,9 +646,7 @@ class EditExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
extrusion = tool.Model.get_extrusion(body)
if extrusion.Position:
position = Matrix(ifcopenshell.util.placement.get_axis2placement(extrusion.Position).tolist())
position[0][3] *= self.unit_scale
position[1][3] *= self.unit_scale
position[2][3] *= self.unit_scale
position.translation *= self.unit_scale
else:
position = Matrix()
@@ -85,7 +85,7 @@ class GenerateSpace(bpy.types.Operator, tool.Ifc.Operator):
x, y = context.scene.cursor.location.xy
z = collection_obj.matrix_world.translation.z
mat = Matrix()
mat[0][3], mat[1][3], mat[2][3] = x, y, z
mat.translation = (x, y, z)
h = 3
boundary_elements = []
@@ -295,7 +295,7 @@ class ChangeExtrusionXAngle(bpy.types.Operator, tool.Ifc.Operator):
euler = obj.matrix_world.to_euler()
euler.x = x_angle
new_matrix = euler.to_matrix().to_4x4()
new_matrix.col[3] = obj.matrix_world.col[3]
new_matrix.translation = obj.matrix_world.translation
obj.matrix_world = new_matrix
if layer2_objs:
DumbWallRecalculator().recalculate(layer2_objs)
@@ -587,9 +587,9 @@ class DumbWallGenerator:
obj = bpy.data.objects.new(tool.Model.generate_occurrence_name(self.relating_type, ifc_class), mesh)
matrix_world = Matrix.Rotation(self.rotation, 4, "Z")
matrix_world.col[3] = self.location.to_4d()
matrix_world.translation = self.location
if self.collection_obj and self.collection_obj.BIMObjectProperties.ifc_definition_id:
matrix_world[2][3] = self.collection_obj.location[2] + (props.rl1 * self.unit_scale)
matrix_world.location.z = self.collection_obj.location.z + (props.rl1 * self.unit_scale)
obj.matrix_world = matrix_world
bpy.context.view_layer.update()
self.collection.objects.link(obj)
@@ -786,7 +786,7 @@ class DumbWallJoiner:
r.RelatedOpeningElement for r in element1.HasOpenings if not r.RelatedOpeningElement.HasFillings
]:
opening_matrix = Matrix(ifcopenshell.util.placement.get_local_placement(opening.ObjectPlacement).tolist())
opening_location = opening_matrix.col[3].to_3d()
opening_location = opening_matrix.translation
_, opening_position = mathutils.geometry.intersect_point_line(opening_location.to_2d(), *axis1["reference"])
if opening_position > cut_percentage:
# The opening should be removed from element1.
@@ -797,7 +797,7 @@ class DumbWallJoiner:
r.RelatedOpeningElement for r in element2.HasOpenings if not r.RelatedOpeningElement.HasFillings
]:
opening_matrix = Matrix(ifcopenshell.util.placement.get_local_placement(opening.ObjectPlacement).tolist())
opening_location = opening_matrix.col[3].to_3d()
opening_location = opening_matrix.translation
_, opening_position = mathutils.geometry.intersect_point_line(opening_location.to_2d(), *axis1["reference"])
if opening_position < cut_percentage:
# The opening should be removed from element2.
@@ -847,34 +847,34 @@ class DumbWallJoiner:
filling_matrixes = {}
for opening in [r.RelatedOpeningElement for r in element1.HasOpenings]:
opening_matrix = Matrix(ifcopenshell.util.placement.get_local_placement(opening.ObjectPlacement).tolist())
location = opening_matrix.col[3].to_3d()
location = opening_matrix.translation
location_on_base = tool.Cad.point_on_edge(location, axis1["base"])
location_on_side = tool.Cad.point_on_edge(location, axis1["side"])
if (location_on_base - location).length < (location_on_side - location).length:
axis_offset = location_on_side - location_on_base
offset_from_axis = location_on_base - location
opening_matrix.col[3] = (location_on_base - axis_offset - offset_from_axis).to_4d()
opening_matrix.translation = (location_on_base - axis_offset - offset_from_axis)
else:
axis_offset = location_on_side - location_on_base
offset_from_axis = location_on_side - location
opening_matrix.col[3] = (location_on_side - axis_offset - offset_from_axis).to_4d()
opening_matrix.translation = (location_on_side - axis_offset - offset_from_axis)
opening_matrixes[opening] = opening_matrix
for filling in [r.RelatedBuildingElement for r in opening.HasFillings]:
filling_obj = tool.Ifc.get_object(filling)
filling_matrix = filling_obj.matrix_world.copy()
location = filling_matrix.col[3].to_3d()
location = filling_matrix.translation
location_on_base = tool.Cad.point_on_edge(location, axis1["base"])
location_on_side = tool.Cad.point_on_edge(location, axis1["side"])
if (location_on_base - location).length < (location_on_side - location).length:
axis_offset = location_on_side - location_on_base
offset_from_axis = location_on_base - location
filling_matrix.col[3] = (location_on_base - axis_offset - offset_from_axis).to_4d()
filling_matrix.translation = (location_on_base - axis_offset - offset_from_axis)
else:
axis_offset = location_on_side - location_on_base
offset_from_axis = location_on_side - location
filling_matrix.col[3] = (location_on_side - axis_offset - offset_from_axis).to_4d()
filling_matrix.translation = (location_on_side - axis_offset - offset_from_axis)
filling_matrixes[filling] = filling_matrix
self.recreate_wall(element1, wall1, axis1["reference"], axis1["reference"])
@@ -1136,8 +1136,8 @@ class DumbWallJoiner:
)
previous_matrix = obj.matrix_world.copy()
previous_origin = previous_matrix.col[3].to_2d()
obj.matrix_world.col[3].xy = self.body[0]
previous_origin = previous_matrix.translation.xy
obj.matrix_world.translation.xy = self.body[0]
bpy.context.view_layer.update()
for rel in element.ConnectedFrom:
@@ -231,7 +231,7 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator):
bm.to_mesh(mesh)
bm.free()
obj = bpy.data.objects.new(name, mesh)
obj.matrix_world.col[3] = location.to_4d()
obj.matrix_world.translation = location
blenderbim.core.root.assign_class(
tool.Ifc,
tool.Collector,
@@ -327,7 +327,7 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator):
)
elif template == "DISTRIBUTION_SEGMENT_CIRCULAR_HOLLOW":
default_diameter = 0.15 / unit_scale
default_thickness = 0.005 / unit_scale # TODO: double check
default_thickness = 0.005 / unit_scale
profile_name = f"{ifc_class}-{default_diameter*1000}x{default_thickness*1000}"
profile = ifc_file.create_entity(
"IfcCircleHollowProfileDef",
+10 -26
View File
@@ -441,16 +441,14 @@ 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]
x, y, z = (0, 0, 0) if location_hint == 0 else bpy.context.scene.cursor.matrix.translation
if target_view == "PLAN_VIEW":
if location_hint:
z = tool.Ifc.get_object(tool.Ifc.get().by_id(location_hint)).matrix_world[2][3]
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)))
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]
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)))
return mathutils.Matrix(((-1, 0, 0, 0), (0, 1, 0, 0), (0, 0, -1, 0), (0, 0, 0, 1)))
elif target_view == "ELEVATION_VIEW":
@@ -1025,14 +1023,10 @@ class Drawing(blenderbim.core.tool.Drawing):
xyz = camera.matrix_world.inverted() @ reference_obj.matrix_world.translation
xyz[2] = 0
xyz = camera.matrix_world @ xyz
mat[0][3] = xyz[0]
mat[1][3] = xyz[1]
mat[2][3] = xyz[2]
mat.translation = xyz
annotation_offset = mathutils.Vector((0, 0, -camera.data.clip_start - 0.05))
annotation_offset = camera.matrix_world.to_quaternion() @ annotation_offset
mat[0][3] += annotation_offset[0]
mat[1][3] += annotation_offset[1]
mat[2][3] += annotation_offset[2]
mat.translation += annotation_offset
return mat
def project_point_onto_camera(point, camera):
@@ -1090,14 +1084,10 @@ class Drawing(blenderbim.core.tool.Drawing):
xyz = camera.matrix_world.inverted() @ reference_obj.matrix_world.translation
xyz[2] = 0
xyz = camera.matrix_world @ xyz
mat[0][3] = xyz[0]
mat[1][3] = xyz[1]
mat[2][3] = xyz[2]
mat.translation = xyz
annotation_offset = mathutils.Vector((0, 0, -camera.data.clip_start - 0.05))
annotation_offset = camera.matrix_world.to_quaternion() @ annotation_offset
mat[0][3] += annotation_offset[0]
mat[1][3] += annotation_offset[1]
mat[2][3] += annotation_offset[2]
mat.translation += annotation_offset
return mat
def clip_to_camera_boundary(mesh, bounds):
@@ -1171,14 +1161,10 @@ class Drawing(blenderbim.core.tool.Drawing):
xyz = camera.matrix_world.inverted() @ reference_obj.matrix_world.translation
xyz[2] = 0
xyz = camera.matrix_world @ xyz
mat[0][3] = xyz[0]
mat[1][3] = xyz[1]
mat[2][3] = xyz[2]
mat.translation = xyz
annotation_offset = mathutils.Vector((0, 0, -camera.data.clip_start - 0.05))
annotation_offset = camera.matrix_world.to_quaternion() @ annotation_offset
mat[0][3] += annotation_offset[0]
mat[1][3] += annotation_offset[1]
mat[2][3] += annotation_offset[2]
mat.translation += xyz
return mat
if cls.is_perpendicular(camera, reference_obj) and cls.is_intersecting(camera, reference_obj):
@@ -1230,9 +1216,7 @@ class Drawing(blenderbim.core.tool.Drawing):
obj.matrix_world = camera.matrix_world
annotation_offset = mathutils.Vector((0, 0, -camera.data.clip_start - 0.05))
annotation_offset = camera.matrix_world.to_quaternion() @ annotation_offset
obj.matrix_world[0][3] += annotation_offset[0]
obj.matrix_world[1][3] += annotation_offset[1]
obj.matrix_world[2][3] += annotation_offset[2]
obj.matrix_world.translation += annotation_offset
return obj, mesh
def clip_to_camera_boundary(mesh):
+6 -10
View File
@@ -160,7 +160,7 @@ class Model(blenderbim.core.tool.Model):
position.col[0][:3] = x_axis
position.col[1][:3] = y_axis
position.col[2][:3] = z_axis
position.col[3][:3] = p1
position.translation = p1
cls.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
@@ -310,9 +310,7 @@ class Model(blenderbim.core.tool.Model):
if surface.is_a("IfcCurveBoundedPlane"):
position = Matrix(ifcopenshell.util.placement.get_axis2placement(surface.BasisSurface.Position).tolist())
position[0][3] *= cls.unit_scale
position[1][3] *= cls.unit_scale
position[2][3] *= cls.unit_scale
position.translation *= cls.unit_scale
cls.import_curve(obj, position, surface.OuterBoundary)
for inner_boundary in surface.InnerBoundaries:
@@ -393,7 +391,7 @@ class Model(blenderbim.core.tool.Model):
cls.edges.append([len(cls.vertices) - 1, offset]) # Close the loop
elif curve.is_a("IfcCircle"):
center = cls.convert_unit_to_si(
Matrix(ifcopenshell.util.placement.get_axis2placement(curve.Position).tolist()).col[3].to_3d()
Matrix(ifcopenshell.util.placement.get_axis2placement(curve.Position).tolist()).translation
)
radius = cls.convert_unit_to_si(curve.Radius)
cls.vertices.extend(
@@ -409,9 +407,7 @@ class Model(blenderbim.core.tool.Model):
def import_rectangle(cls, obj, position, profile):
if profile.Position:
p_position = Matrix(ifcopenshell.util.placement.get_axis2placement(profile.Position).tolist())
p_position[0][3] *= cls.unit_scale
p_position[1][3] *= cls.unit_scale
p_position[2][3] *= cls.unit_scale
p_position.translation *= cls.unit_scale
else:
p_position = Matrix()
@@ -588,8 +584,8 @@ class Model(blenderbim.core.tool.Model):
if array["use_local_space"]:
current_obj_translation = obj.matrix_world @ offset
else:
current_obj_translation = obj.matrix_world.col[3].to_3d() + offset
new_matrix.col[3] = current_obj_translation.to_4d()
current_obj_translation = obj.matrix_world.translation + offset
new_matrix.translation = current_obj_translation
child_obj.matrix_world = new_matrix
children_objs.append(child_obj)
children_elements.append(child_element)