This commit is contained in:
Andrej730
2025-02-24 11:47:19 +05:00
parent 3854afb34d
commit 0783f8082e
8 changed files with 153 additions and 119 deletions
+16 -4
View File
@@ -464,7 +464,7 @@ def get_horizontal_profile_preview_data(context, relating_type):
# Rotates the profile face to the right direction # Rotates the profile face to the right direction
direction = polyline_verts[i + 1] - polyline_verts[i] direction = polyline_verts[i + 1] - polyline_verts[i]
position = polyline_verts[i] position = polyline_verts[i]
rotation_matrix = direction.to_track_quat('Z', 'Y').to_matrix().to_4x4() rotation_matrix = direction.to_track_quat("Z", "Y").to_matrix().to_4x4()
bmesh.ops.transform(bm, verts=bm.verts, matrix=rotation_matrix) bmesh.ops.transform(bm, verts=bm.verts, matrix=rotation_matrix)
bmesh.ops.translate(bm, verts=bm.verts, vec=position) bmesh.ops.translate(bm, verts=bm.verts, vec=position)
bmesh.ops.translate(bm, verts=bm.verts, vec=-direction) bmesh.ops.translate(bm, verts=bm.verts, vec=-direction)
@@ -474,10 +474,22 @@ def get_horizontal_profile_preview_data(context, relating_type):
new_verts = [e for e in last_face["geom"] if isinstance(e, bmesh.types.BMVert)] new_verts = [e for e in last_face["geom"] if isinstance(e, bmesh.types.BMVert)]
bmesh.ops.translate(bm, verts=new_verts, vec=direction * 3) bmesh.ops.translate(bm, verts=new_verts, vec=direction * 3)
# Apply the cutting planes # Apply the cutting planes
cut = bmesh.ops.bisect_plane(bm, geom=bm.verts[:] + bm.edges[:] + bm.faces[:], plane_co=polyline_verts[i], plane_no=clip_start, clear_inner=True) cut = bmesh.ops.bisect_plane(
bm,
geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
plane_co=polyline_verts[i],
plane_no=clip_start,
clear_inner=True,
)
bm.verts.index_update() bm.verts.index_update()
bm.edges.index_update() bm.edges.index_update()
cut = bmesh.ops.bisect_plane(bm, geom=bm.verts[:] + bm.edges[:] + bm.faces[:], plane_co=polyline_verts[i+1], plane_no=clip_end, clear_outer=True) cut = bmesh.ops.bisect_plane(
bm,
geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
plane_co=polyline_verts[i + 1],
plane_no=clip_end,
clear_outer=True,
)
bm.to_mesh(mesh) bm.to_mesh(mesh)
bm.free() bm.free()
@@ -489,7 +501,7 @@ def get_horizontal_profile_preview_data(context, relating_type):
mesh = bpy.data.meshes.new("TempMesh2") mesh = bpy.data.meshes.new("TempMesh2")
all_bm.to_mesh(mesh) all_bm.to_mesh(mesh)
all_bm.free() all_bm.free()
obj = bpy.data.objects.new('TempObj', mesh) obj = bpy.data.objects.new("TempObj", mesh)
bm = bmesh.new() bm = bmesh.new()
bm.from_mesh(obj.data) bm.from_mesh(obj.data)
bpy.data.meshes.remove(bpy.data.meshes["TempMesh2"]) bpy.data.meshes.remove(bpy.data.meshes["TempMesh2"])
@@ -112,10 +112,9 @@ class DumbProfileGenerator:
matrix_world = Matrix.Rotation(pi / 2, 4, "Z") @ Matrix.Rotation(pi / 2, 4, "X") @ matrix_world matrix_world = Matrix.Rotation(pi / 2, 4, "Z") @ Matrix.Rotation(pi / 2, 4, "X") @ matrix_world
matrix_world = Matrix.Rotation(self.rotation, 4, "Z") @ matrix_world matrix_world = Matrix.Rotation(self.rotation, 4, "Z") @ matrix_world
else: else:
rotation_matrix = self.direction.to_track_quat('Z', 'Y') rotation_matrix = self.direction.to_track_quat("Z", "Y")
matrix_world = rotation_matrix.to_matrix().to_4x4() @ matrix_world matrix_world = rotation_matrix.to_matrix().to_4x4() @ matrix_world
matrix_world.translation = self.location matrix_world.translation = self.location
if self.insertion_type not in {"POLYLINE"} and self.container_obj: if self.insertion_type not in {"POLYLINE"} and self.container_obj:
matrix_world.translation.z = self.container_obj.location.z matrix_world.translation.z = self.container_obj.location.z
+1 -2
View File
@@ -526,8 +526,7 @@ class Polyline(bonsai.core.tool.Polyline):
v1 = Vector((x, y, z)) v1 = Vector((x, y, z))
v2 = Vector((polyline_points[-1].x, polyline_points[-1].y, polyline_points[-1].z)) v2 = Vector((polyline_points[-1].x, polyline_points[-1].y, polyline_points[-1].z))
v3 = Vector((polyline_points[-2].x, polyline_points[-2].y, polyline_points[-2].z)) v3 = Vector((polyline_points[-2].x, polyline_points[-2].y, polyline_points[-2].z))
angle = tool.Cad.angle_3_vectors(v1, v2, v3, new_angle=None, degrees=True angle = tool.Cad.angle_3_vectors(v1, v2, v3, new_angle=None, degrees=True)
)
if tool.Cad.is_x(angle, 0): if tool.Cad.is_x(angle, 0):
return return
# TODO move this limitation to be Wall tool specific. Right now it also affects Measure tool # TODO move this limitation to be Wall tool specific. Right now it also affects Measure tool
-1
View File
@@ -227,7 +227,6 @@ class Foo:
else: else:
ifcopenshell.api.geometry.assign_representation(self.file, product=wall, representation=rep) ifcopenshell.api.geometry.assign_representation(self.file, product=wall, representation=rep)
def join(self, wall1, wall2, layers1, layers2, connection1, connection2): def join(self, wall1, wall2, layers1, layers2, connection1, connection2):
if connection1 == "NOTDEFINED" or connection2 == "NOTDEFINED": if connection1 == "NOTDEFINED" or connection2 == "NOTDEFINED":
return return
@@ -213,10 +213,18 @@ class IfcAlignmentHelper:
case "CONSTANTGRADIENT": case "CONSTANTGRADIENT":
parent_curve = self._file.create_entity( parent_curve = self._file.create_entity(
type="IfcLine", type="IfcLine",
Pnt=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(0.0,0.0),), Pnt=self._file.create_entity(
Dir=self._file.create_entity(type="IfcVector", type="IfcCartesianPoint",
Orientation=self._file.create_entity(type="IfcDirection",DirectionRatios=(1.0,0.0),), Coordinates=(0.0, 0.0),
Magnitude=1.0,), ),
Dir=self._file.create_entity(
type="IfcVector",
Orientation=self._file.create_entity(
type="IfcDirection",
DirectionRatios=(1.0, 0.0),
),
Magnitude=1.0,
),
) )
dx = math.cos(math.atan(start_gradient)) dx = math.cos(math.atan(start_gradient))
@@ -228,7 +236,9 @@ class IfcAlignmentHelper:
Transition=transition, Transition=transition,
Placement=self._file.create_entity( Placement=self._file.create_entity(
type="IfcAxis2Placement2D", type="IfcAxis2Placement2D",
Location=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(start_distance_along,start_height)), Location=self._file.create_entity(
type="IfcCartesianPoint", Coordinates=(start_distance_along, start_height)
),
RefDirection=self._file.createIfcDirection((dx, dy)), RefDirection=self._file.createIfcDirection((dx, dy)),
), ),
SegmentStart=self._file.createIfcLengthMeasure(0.0), SegmentStart=self._file.createIfcLengthMeasure(0.0),
@@ -247,7 +257,9 @@ class IfcAlignmentHelper:
Position=self._file.create_entity( Position=self._file.create_entity(
type="IfcAxis2Placement2D", type="IfcAxis2Placement2D",
Location=self._file.create_entity(type="IfcCartesianPoint", Coordinates=(0.0, 0.0)), Location=self._file.create_entity(type="IfcCartesianPoint", Coordinates=(0.0, 0.0)),
RefDirection=self._file.createIfcDirection((1.0, 0.0),), RefDirection=self._file.createIfcDirection(
(1.0, 0.0),
),
), ),
CoefficientsX=(0.0, 1.0), CoefficientsX=(0.0, 1.0),
CoefficientsY=(A, B, C), CoefficientsY=(A, B, C),
@@ -262,7 +274,9 @@ class IfcAlignmentHelper:
Transition=transition, Transition=transition,
Placement=self._file.create_entity( Placement=self._file.create_entity(
type="IfcAxis2Placement2D", type="IfcAxis2Placement2D",
Location=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(start_distance_along,start_height)), Location=self._file.create_entity(
type="IfcCartesianPoint", Coordinates=(start_distance_along, start_height)
),
RefDirection=self._file.createIfcDirection((dx, dy)), RefDirection=self._file.createIfcDirection((dx, dy)),
), ),
SegmentStart=self._file.createIfcLengthMeasure(0.0), SegmentStart=self._file.createIfcLengthMeasure(0.0),
@@ -284,7 +298,9 @@ class IfcAlignmentHelper:
Position=self._file.create_entity( Position=self._file.create_entity(
type="IfcAxis2Placement2D", type="IfcAxis2Placement2D",
Location=self._file.create_entity(type="IfcCartesianPoint", Coordinates=(0.0, 0.0)), Location=self._file.create_entity(type="IfcCartesianPoint", Coordinates=(0.0, 0.0)),
RefDirection=self._file.createIfcDirection((1.0, 0.0),), RefDirection=self._file.createIfcDirection(
(1.0, 0.0),
),
), ),
Radius=radius, Radius=radius,
) )
@@ -296,8 +312,11 @@ class IfcAlignmentHelper:
Transition=transition, Transition=transition,
Placement=self._file.create_entity( Placement=self._file.create_entity(
type="IfcAxis2Placement2D", type="IfcAxis2Placement2D",
Location=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(start_distance_along,start_height)), Location=self._file.create_entity(
RefDirection=self._file.createIfcDirection((1.0,0.0), type="IfcCartesianPoint", Coordinates=(start_distance_along, start_height)
),
RefDirection=self._file.createIfcDirection(
(1.0, 0.0),
), ),
), ),
SegmentStart=self._file.createIfcLengthMeasure(0.0), SegmentStart=self._file.createIfcLengthMeasure(0.0),
@@ -676,7 +695,9 @@ class IfcAlignmentHelper:
alignment.Representation = product_definition_shape alignment.Representation = product_definition_shape
# create referent for start station # create referent for start station
start_station_name = "Start Station ({})".format(ifcopenshell.util.stationing.station_as_string(start_station)) start_station_name = "Start Station ({})".format(
ifcopenshell.util.stationing.station_as_string(start_station)
)
start_referent = self._file.createIfcReferent( start_referent = self._file.createIfcReferent(
GlobalId=ifcopenshell.guid.new(), GlobalId=ifcopenshell.guid.new(),
OwnerHistory=None, OwnerHistory=None,
@@ -772,7 +793,7 @@ class IfcAlignmentHelper:
StartGradient=start_slope, StartGradient=start_slope,
EndGradient=start_slope, EndGradient=start_slope,
RadiusOfCurvature=None, RadiusOfCurvature=None,
PredefinedType="CONSTANTGRADIENT" PredefinedType="CONSTANTGRADIENT",
) )
alignment_segment = self._file.create_entity( alignment_segment = self._file.create_entity(
type="IfcAlignmentSegment", type="IfcAlignmentSegment",
@@ -805,7 +826,7 @@ class IfcAlignmentHelper:
StartGradient=start_slope, StartGradient=start_slope,
EndGradient=end_slope, EndGradient=end_slope,
RadiusOfCurvature=1 / k, RadiusOfCurvature=1 / k,
PredefinedType="PARABOLICARC" PredefinedType="PARABOLICARC",
) )
alignment_segment = self._file.create_entity( alignment_segment = self._file.create_entity(
type="IfcAlignmentSegment", type="IfcAlignmentSegment",
@@ -829,7 +850,6 @@ class IfcAlignmentHelper:
xPVI = xPFG xPVI = xPFG
yPVI = yPFG yPVI = yPFG
# create last gradient run # create last gradient run
dx = xPVI - xPBG dx = xPVI - xPBG
dy = yPVI - yPBG dy = yPVI - yPBG
@@ -846,7 +866,7 @@ class IfcAlignmentHelper:
StartGradient=slope, StartGradient=slope,
EndGradient=slope, EndGradient=slope,
RadiusOfCurvature=None, RadiusOfCurvature=None,
PredefinedType="CONSTANTGRADIENT" PredefinedType="CONSTANTGRADIENT",
) )
alignment_segment = self._file.create_entity( alignment_segment = self._file.create_entity(
type="IfcAlignmentSegment", type="IfcAlignmentSegment",
@@ -875,7 +895,7 @@ class IfcAlignmentHelper:
StartGradient=slope, StartGradient=slope,
EndGradient=slope, EndGradient=slope,
RadiusOfCurvature=None, RadiusOfCurvature=None,
PredefinedType="CONSTANTGRADIENT" PredefinedType="CONSTANTGRADIENT",
) )
alignment_segment = self._file.create_entity( alignment_segment = self._file.create_entity(
type="IfcAlignmentSegment", type="IfcAlignmentSegment",
@@ -899,7 +919,7 @@ class IfcAlignmentHelper:
Segments=vertical_curve_segments, Segments=vertical_curve_segments,
SelfIntersect=False, SelfIntersect=False,
BaseCurve=composite_curve, BaseCurve=composite_curve,
EndPoint=None EndPoint=None,
) )
else: else:
gradient_curve = None gradient_curve = None
@@ -915,7 +935,7 @@ class IfcAlignmentHelper:
lengths: Sequence[float], lengths: Sequence[float],
alignment_description: str = None, alignment_description: str = None,
start_station: float = 1000.0, start_station: float = 1000.0,
include_geometry: bool = True include_geometry: bool = True,
): ):
""" """
Create an alignment using the PI layout method for both horizontal and vertical alignments. Create an alignment using the PI layout method for both horizontal and vertical alignments.
@@ -930,8 +950,12 @@ class IfcAlignmentHelper:
@param include_geometry: optionally create the alignment geometric representation as well as the semantic business logic @param include_geometry: optionally create the alignment geometric representation as well as the semantic business logic
""" """
horizontal_segments, horizontal_curve_segments, composite_curve = self._create_horizontal_alignment(alignment_name,alignment_description,points,radii,include_geometry) horizontal_segments, horizontal_curve_segments, composite_curve = self._create_horizontal_alignment(
vertical_segments, vertical_curve_segments, gradient_curve = self._create_vertical_alignment(composite_curve,vpoints,lengths) alignment_name, alignment_description, points, radii, include_geometry
)
vertical_segments, vertical_curve_segments, gradient_curve = self._create_vertical_alignment(
composite_curve, vpoints, lengths
)
name_segments(prefix="H", segments=horizontal_segments) name_segments(prefix="H", segments=horizontal_segments)
name_segments(prefix="V", segments=vertical_segments) name_segments(prefix="V", segments=vertical_segments)
@@ -1069,7 +1093,10 @@ class IfcAlignmentHelper:
type="IfcProductDefinitionShape", type="IfcProductDefinitionShape",
Name="Alignment Product Definition Shape", Name="Alignment Product Definition Shape",
Description=None, Description=None,
Representations=(footprint_shape_representation,axis3d_shape_representation,), Representations=(
footprint_shape_representation,
axis3d_shape_representation,
),
) )
# create representations for each segment # create representations for each segment
@@ -1081,7 +1108,6 @@ class IfcAlignmentHelper:
return alignment return alignment
def create_horizontal_alignment_by_pi_method( def create_horizontal_alignment_by_pi_method(
self, self,
name: str, name: str,
@@ -1115,13 +1141,11 @@ if __name__ == "__main__":
project = f.create_entity(type="IfcProject", GlobalId=ifcopenshell.guid.new()) project = f.create_entity(type="IfcProject", GlobalId=ifcopenshell.guid.new())
context = f.create_entity(type="IfcGeometricRepresentationContext") context = f.create_entity(type="IfcGeometricRepresentationContext")
points=[(0.,0.),(100.,0.),(200.,150.)] points = [(0.0, 0.0), (100.0, 0.0), (200.0, 150.0)]
radii=[(50.)] radii = [50.0]
helper = IfcAlignmentHelper(f) helper = IfcAlignmentHelper(f)
helper.create_horizontal_alignment_by_pi_method( helper.create_horizontal_alignment_by_pi_method(name="MyAlignment", hpoints=points, radii=radii)
name="MyAlignment",hpoints = points,radii = radii
)
# f = ifcopenshell.open(sys.argv[1]) # f = ifcopenshell.open(sys.argv[1])
print_structure(f.by_type("IfcAlignment")[0]) print_structure(f.by_type("IfcAlignment")[0])
@@ -18,6 +18,7 @@
import math import math
def station_as_string(station: float, plus_seperator=3, accuracy=3): def station_as_string(station: float, plus_seperator=3, accuracy=3):
""" """
Returns a stringized version of a station. Example 100.0 is 1+00.00 as a stationing string Returns a stringized version of a station. Example 100.0 is 1+00.00 as a stationing string
@@ -47,5 +48,3 @@ def station_as_string(station:float,plus_seperator=3,accuracy=3):
station_string = "-" + station_string station_string = "-" + station_string
return station_string return station_string
@@ -84,6 +84,7 @@ ENDSEC;
END-ISO-10303-21; END-ISO-10303-21;
""" """
def test_original_edges(): def test_original_edges():
ifc_file = ifcopenshell.file.from_string(contents) ifc_file = ifcopenshell.file.from_string(contents)
element = ifc_file.by_id(95) element = ifc_file.by_id(95)
@@ -92,6 +93,6 @@ def test_original_edges():
assert (len(shape.edges) // 2) == 20 assert (len(shape.edges) // 2) == 20
shape = ifcopenshell.geom.create_shape(settings, element, geometry_library="cgal") shape = ifcopenshell.geom.create_shape(settings, element, geometry_library="cgal")
assert (len(shape.edges) // 2) == 16 assert (len(shape.edges) // 2) == 16
settings.set('cgal-original-edges', True) settings.set("cgal-original-edges", True)
shape = ifcopenshell.geom.create_shape(settings, element, geometry_library="cgal") shape = ifcopenshell.geom.create_shape(settings, element, geometry_library="cgal")
assert (len(shape.edges) // 2) == 20 assert (len(shape.edges) // 2) == 20
@@ -18,28 +18,29 @@
import ifcopenshell.util.stationing as sta import ifcopenshell.util.stationing as sta
def test_station_as_string(): def test_station_as_string():
# test with a bunch of "random" station values # test with a bunch of "random" station values
s = sta.station_as_string(0.0) s = sta.station_as_string(0.0)
assert(s == "0+000.000") assert s == "0+000.000"
s = sta.station_as_string(0.0, 2, 2) s = sta.station_as_string(0.0, 2, 2)
assert(s == "0+00.00") assert s == "0+00.00"
s = sta.station_as_string(0.0, 2) s = sta.station_as_string(0.0, 2)
assert(s == "0+00.000") assert s == "0+00.000"
s = sta.station_as_string(100.00) s = sta.station_as_string(100.00)
assert(s == "0+100.000") assert s == "0+100.000"
s = sta.station_as_string(-100.00) s = sta.station_as_string(-100.00)
assert(s == "-0+100.000") assert s == "-0+100.000"
s = sta.station_as_string(123456.789, 2, 2) s = sta.station_as_string(123456.789, 2, 2)
assert(s == "1234+56.79") assert s == "1234+56.79"
s = sta.station_as_string(-123456.789, 2, 2) s = sta.station_as_string(-123456.789, 2, 2)
assert(s == "-1234+56.79") assert s == "-1234+56.79"
s = sta.station_as_string(123456.789, 3, 4) s = sta.station_as_string(123456.789, 3, 4)
assert(s == "123+456.7890") assert s == "123+456.7890"