This commit is contained in:
Andrej730
2025-08-28 10:57:26 +05:00
parent 39100b7c97
commit 43fbdf57c8
20 changed files with 57 additions and 47 deletions
+6 -2
View File
@@ -469,8 +469,12 @@ class ChangeExtrusionXAngle(bpy.types.Operator, tool.Ifc.Operator):
existing_x_angle = 0 if tool.Cad.is_x(existing_x_angle, pi, tolerance=0.001) else existing_x_angle existing_x_angle = 0 if tool.Cad.is_x(existing_x_angle, pi, tolerance=0.001) else existing_x_angle
coord_list = builder.get_polyline_coords(extrusion.SweptArea.OuterCurve) coord_list = builder.get_polyline_coords(extrusion.SweptArea.OuterCurve)
coord_list = [(p[0], p[1] * abs(cos(existing_x_angle))) for p in coord_list] # Reset the transformation and returns to the original points with 0 degrees coord_list = [
coord_list = [(p[0], p[1] * abs(1 / cos(x_angle))) for p in coord_list] # Apply the transformation for the new x_angle (p[0], p[1] * abs(cos(existing_x_angle))) for p in coord_list
] # Reset the transformation and returns to the original points with 0 degrees
coord_list = [
(p[0], p[1] * abs(1 / cos(x_angle))) for p in coord_list
] # Apply the transformation for the new x_angle
builder.set_polyline_coords(extrusion.SweptArea.OuterCurve, coord_list) builder.set_polyline_coords(extrusion.SweptArea.OuterCurve, coord_list)
# The extrusion direction calculated previously default to the positive direction # The extrusion direction calculated previously default to the positive direction
-1
View File
@@ -50,7 +50,6 @@ else:
raise RuntimeError("Unsupported platform") raise RuntimeError("Unsupported platform")
BONSAI_PATH_CANDIDATES = ( BONSAI_PATH_CANDIDATES = (
# Installed from Bonsai Unstalble Repo. # Installed from Bonsai Unstalble Repo.
BLENDER_PATH / r"extensions/raw_githubusercontent_com/bonsai", BLENDER_PATH / r"extensions/raw_githubusercontent_com/bonsai",
@@ -137,7 +137,7 @@ def _add_segment_to_layout(file: ifcopenshell.file, layout: entity_instance, seg
start_dist_along = segment.DesignParameters.StartDistAlong + segment.DesignParameters.HorizontalLength start_dist_along = segment.DesignParameters.StartDistAlong + segment.DesignParameters.HorizontalLength
zero_length_segment.DesignParameters.StartDistAlong = start_dist_along zero_length_segment.DesignParameters.StartDistAlong = start_dist_along
referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,layout) referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, layout)
end_referent = referent_nest.RelatedObjects[-1] end_referent = referent_nest.RelatedObjects[-1]
end_referent.Name = f"{_get_segment_start_point_label(zero_length_segment,None)} ({ifcopenshell.util.alignment.station_as_string(file,start_station+start_dist_along)})" end_referent.Name = f"{_get_segment_start_point_label(zero_length_segment,None)} ({ifcopenshell.util.alignment.station_as_string(file,start_station+start_dist_along)})"
@@ -180,13 +180,13 @@ def _add_segment_to_layout(file: ifcopenshell.file, layout: entity_instance, seg
referent = ifcopenshell.api.alignment.add_stationing_referent( referent = ifcopenshell.api.alignment.add_stationing_referent(
file, layout, distance_along=dist_along, station=station, name=name, positioned_product=segment file, layout, distance_along=dist_along, station=station, name=name, positioned_product=segment
) )
ifcopenshell.api.nest.reorder_nesting(file,referent,-1,-1) ifcopenshell.api.nest.reorder_nesting(file, referent, -1, -1)
if len(curve.Segments) == 2 and layout.is_a("IfcAlignmentHorizontal"): if len(curve.Segments) == 2 and layout.is_a("IfcAlignmentHorizontal"):
# this is the first real segment in the horizontal alignment # this is the first real segment in the horizontal alignment
# update the location of the alignment's stationing referent # update the location of the alignment's stationing referent
alignment = ifcopenshell.api.alignment.get_alignment(layout) alignment = ifcopenshell.api.alignment.get_alignment(layout)
ref_nest = ifcopenshell.api.alignment.get_referent_nest(file,alignment) ref_nest = ifcopenshell.api.alignment.get_referent_nest(file, alignment)
stationing_referent = ref_nest.RelatedObjects[0] stationing_referent = ref_nest.RelatedObjects[0]
p = curve_evaluator.evaluate( p = curve_evaluator.evaluate(
stationing_referent.ObjectPlacement.RelativePlacement.Location.DistanceAlong.wrappedValue stationing_referent.ObjectPlacement.RelativePlacement.Location.DistanceAlong.wrappedValue
@@ -34,7 +34,7 @@ def add_stationing_referent(
distance_along: float, distance_along: float,
station: float, station: float,
name: str, name: str,
positioned_product: entity_instance positioned_product: entity_instance,
) -> entity_instance: ) -> entity_instance:
""" """
Adds an IfcReferent to the element with the Pset_Stationing property set. Adds an IfcReferent to the element with the Pset_Stationing property set.
@@ -144,7 +144,7 @@ def add_stationing_referent(
pset_stationing = ifcopenshell.api.pset.add_pset(file, product=referent, name="Pset_Stationing") pset_stationing = ifcopenshell.api.pset.add_pset(file, product=referent, name="Pset_Stationing")
ifcopenshell.api.pset.edit_pset(file, pset=pset_stationing, properties={"Station": station}) ifcopenshell.api.pset.edit_pset(file, pset=pset_stationing, properties={"Station": station})
nest = ifcopenshell.api.alignment.get_referent_nest(file,element) nest = ifcopenshell.api.alignment.get_referent_nest(file, element)
nest.RelatedObjects += (referent,) nest.RelatedObjects += (referent,)
if len(referent.Positions) == 0: if len(referent.Positions) == 0:
@@ -86,8 +86,9 @@ def create(
if include_geometry: if include_geometry:
# define stationing # define stationing
name = ifcopenshell.util.alignment.station_as_string(file, start_station) name = ifcopenshell.util.alignment.station_as_string(file, start_station)
referent = ifcopenshell.api.alignment.add_stationing_referent(file, alignment, 0.0, start_station, name, alignment) referent = ifcopenshell.api.alignment.add_stationing_referent(
file, alignment, 0.0, start_station, name, alignment
)
# IFC 4.1.4.1.1 Alignment Aggregation To Project # IFC 4.1.4.1.1 Alignment Aggregation To Project
project = file.by_type("IfcProject")[0] project = file.by_type("IfcProject")[0]
@@ -18,6 +18,7 @@
from ifcopenshell import entity_instance from ifcopenshell import entity_instance
def get_alignment(layout: entity_instance) -> entity_instance: def get_alignment(layout: entity_instance) -> entity_instance:
""" """
Returns the alignment that nests this layout Returns the alignment that nests this layout
@@ -19,6 +19,7 @@
import ifcopenshell import ifcopenshell
from ifcopenshell import entity_instance from ifcopenshell import entity_instance
def get_alignment_layout_nest(alignment: entity_instance) -> entity_instance: def get_alignment_layout_nest(alignment: entity_instance) -> entity_instance:
""" """
Searches for the IfcRelNest that contains IfcAlignmentHorizontal, IfcAlignmentVertical, or IfcAlignmentCant Searches for the IfcRelNest that contains IfcAlignmentHorizontal, IfcAlignmentVertical, or IfcAlignmentCant
@@ -19,6 +19,7 @@
import ifcopenshell import ifcopenshell
from ifcopenshell import entity_instance from ifcopenshell import entity_instance
def get_alignment_segment_nest(layout: entity_instance) -> entity_instance: def get_alignment_segment_nest(layout: entity_instance) -> entity_instance:
""" """
Searches for the IfcRelNest that contains IfcAlignmentSegment Searches for the IfcRelNest that contains IfcAlignmentSegment
@@ -21,6 +21,7 @@ import ifcopenshell.api.alignment
import ifcopenshell.util.element import ifcopenshell.util.element
from ifcopenshell import entity_instance from ifcopenshell import entity_instance
def get_alignment_station(file: ifcopenshell.file, alignment: entity_instance) -> float: def get_alignment_station(file: ifcopenshell.file, alignment: entity_instance) -> float:
""" """
Returns the start station of the alignment. If the alignment is nested by an IfcReferent Returns the start station of the alignment. If the alignment is nested by an IfcReferent
@@ -19,7 +19,8 @@
import ifcopenshell import ifcopenshell
from ifcopenshell import entity_instance from ifcopenshell import entity_instance
def get_referent_nest(file: ifcopenshell.file,entity: entity_instance) -> entity_instance:
def get_referent_nest(file: ifcopenshell.file, entity: entity_instance) -> entity_instance:
""" """
Searches for the IfcRelNest that contains IfcReferent. If one is not found, a empty IfcRelNests is created. Searches for the IfcRelNest that contains IfcReferent. If one is not found, a empty IfcRelNests is created.
@@ -32,5 +33,5 @@ def get_referent_nest(file: ifcopenshell.file,entity: entity_instance) -> entity
if related_object.is_a("IfcReferent"): if related_object.is_a("IfcReferent"):
return nest return nest
nest = file.createIfcRelNests(GlobalId=ifcopenshell.guid.new(),RelatingObject=entity,RelatedObjects=[]) nest = file.createIfcRelNests(GlobalId=ifcopenshell.guid.new(), RelatingObject=entity, RelatedObjects=[])
return nest return nest
@@ -163,10 +163,11 @@ def print_composite_curve_deep(curve):
print(" " * 4, segment.Placement.Location) print(" " * 4, segment.Placement.Location)
print(" " * 4, segment.Placement.RefDirection) print(" " * 4, segment.Placement.RefDirection)
def print_positioned_products(file: ifcopenshell.file): def print_positioned_products(file: ifcopenshell.file):
referents = file.by_type("IfcReferent") referents = file.by_type("IfcReferent")
for referent in referents: for referent in referents:
print(referent) print(referent)
for rel in referent.Positions: for rel in referent.Positions:
for product in rel.RelatedProducts: for product in rel.RelatedProducts:
print(" " * 2,product) print(" " * 2, product)
@@ -68,10 +68,10 @@ def test_add_segment_to_layout():
_add_segment_to_layout(file, horizontal_alignment, alignment_segment) _add_segment_to_layout(file, horizontal_alignment, alignment_segment)
assert len(horizontal_alignment.IsNestedBy) == 2 assert len(horizontal_alignment.IsNestedBy) == 2
referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,horizontal_alignment) referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, horizontal_alignment)
segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(horizontal_alignment) segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(horizontal_alignment)
assert (len(segment_nest.RelatedObjects) == 2) assert len(segment_nest.RelatedObjects) == 2
assert (len(referent_nest.RelatedObjects) == 2) assert len(referent_nest.RelatedObjects) == 2
test_add_segment_to_layout() test_add_segment_to_layout()
@@ -34,7 +34,7 @@ def test_add_vertical_alignment():
assert len(alignment.IsDecomposedBy) == 0 # no child alignments assert len(alignment.IsDecomposedBy) == 0 # no child alignments
assert len(alignment.IsNestedBy) == 2 # nests for layout and referents assert len(alignment.IsNestedBy) == 2 # nests for layout and referents
assert len(alignment.IsNestedBy[0].RelatedObjects) == 1 assert len(alignment.IsNestedBy[0].RelatedObjects) == 1
assert ifcopenshell.api.alignment.get_referent_nest(file,alignment).RelatedObjects[0].is_a("IfcReferent") assert ifcopenshell.api.alignment.get_referent_nest(file, alignment).RelatedObjects[0].is_a("IfcReferent")
assert alignment.IsNestedBy[0].RelatedObjects[0].is_a("IfcAlignmentHorizontal") assert alignment.IsNestedBy[0].RelatedObjects[0].is_a("IfcAlignmentHorizontal")
curve = ifcopenshell.api.alignment.get_curve(alignment) curve = ifcopenshell.api.alignment.get_curve(alignment)
assert curve.is_a("IfcCompositeCurve") assert curve.is_a("IfcCompositeCurve")
@@ -43,7 +43,7 @@ def test_add_vertical_alignment():
assert len(alignment.IsDecomposedBy) == 0 # no child alignments assert len(alignment.IsDecomposedBy) == 0 # no child alignments
assert len(alignment.IsNestedBy) == 2 assert len(alignment.IsNestedBy) == 2
assert (len(alignment.IsNestedBy[0].RelatedObjects) == 2) assert len(alignment.IsNestedBy[0].RelatedObjects) == 2
assert alignment.IsNestedBy[0].RelatedObjects[0].is_a("IfcAlignmentHorizontal") assert alignment.IsNestedBy[0].RelatedObjects[0].is_a("IfcAlignmentHorizontal")
assert alignment.IsNestedBy[0].RelatedObjects[1].is_a("IfcAlignmentVertical") assert alignment.IsNestedBy[0].RelatedObjects[1].is_a("IfcAlignmentVertical")
curve = ifcopenshell.api.alignment.get_curve(alignment) curve = ifcopenshell.api.alignment.get_curve(alignment)
@@ -53,7 +53,7 @@ def test_add_vertical_alignment():
vertical_layout = ifcopenshell.api.alignment.add_vertical_layout(file, alignment) vertical_layout = ifcopenshell.api.alignment.add_vertical_layout(file, alignment)
assert len(alignment.IsDecomposedBy) == 1 # 1 IfcRelAggreates relationship for the child algiments assert len(alignment.IsDecomposedBy) == 1 # 1 IfcRelAggreates relationship for the child algiments
assert (len(alignment.IsDecomposedBy[0].RelatedObjects) == 2) assert len(alignment.IsDecomposedBy[0].RelatedObjects) == 2
for child_alignment in alignment.IsDecomposedBy[0].RelatedObjects: for child_alignment in alignment.IsDecomposedBy[0].RelatedObjects:
assert child_alignment.is_a("IfcAlignment") assert child_alignment.is_a("IfcAlignment")
@@ -49,19 +49,19 @@ def test_create_by_pi_method():
assert len(alignment.IsNestedBy) == 2 assert len(alignment.IsNestedBy) == 2
layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment) layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment)
assert (len(layout_nest.RelatedObjects) == 2) assert len(layout_nest.RelatedObjects) == 2
horizontal_layout = ifcopenshell.api.alignment.get_horizontal_layout(alignment) horizontal_layout = ifcopenshell.api.alignment.get_horizontal_layout(alignment)
horizontal_segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(horizontal_layout) horizontal_segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(horizontal_layout)
assert (len(horizontal_segment_nest.RelatedObjects) == 8) assert len(horizontal_segment_nest.RelatedObjects) == 8
horizontal_referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,horizontal_layout) horizontal_referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, horizontal_layout)
assert (len(horizontal_referent_nest.RelatedObjects) == 8) assert len(horizontal_referent_nest.RelatedObjects) == 8
vertical_layout = ifcopenshell.api.alignment.get_vertical_layout(alignment) vertical_layout = ifcopenshell.api.alignment.get_vertical_layout(alignment)
vertical_segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(vertical_layout) vertical_segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(vertical_layout)
assert (len(vertical_segment_nest.RelatedObjects) == 10) assert len(vertical_segment_nest.RelatedObjects) == 10
vertical_referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,vertical_layout) vertical_referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, vertical_layout)
assert (len(vertical_referent_nest.RelatedObjects) == 10) assert len(vertical_referent_nest.RelatedObjects) == 10
test_create_by_pi_method() test_create_by_pi_method()
@@ -29,7 +29,7 @@ def test_create_no_geometry():
ifcopenshell.api.unit.assign_unit(file, units=[length]) ifcopenshell.api.unit.assign_unit(file, units=[length])
# creates an IfcAlignment with an IfcAlignmentHorizontal layout containing only the zero length segment # creates an IfcAlignment with an IfcAlignmentHorizontal layout containing only the zero length segment
ali = ifcopenshell.api.alignment.create(file, "A1", include_vertical=True,include_geometry=False) ali = ifcopenshell.api.alignment.create(file, "A1", include_vertical=True, include_geometry=False)
# append a segment to the horizontal layout # append a segment to the horizontal layout
horizontal_alignment = ifcopenshell.api.alignment.get_horizontal_layout(ali) horizontal_alignment = ifcopenshell.api.alignment.get_horizontal_layout(ali)
@@ -46,12 +46,12 @@ def test_horizontal_layout_by_pi_method():
assert len(alignment.IsDecomposedBy) == 0 # no child alignments assert len(alignment.IsDecomposedBy) == 0 # no child alignments
assert len(alignment.IsNestedBy) == 2 assert len(alignment.IsNestedBy) == 2
referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,alignment) referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, alignment)
layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment) layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment)
assert referent_nest.RelatedObjects[0].is_a("IfcReferent") assert referent_nest.RelatedObjects[0].is_a("IfcReferent")
assert layout_nest.RelatedObjects[0].is_a("IfcAlignmentHorizontal") assert layout_nest.RelatedObjects[0].is_a("IfcAlignmentHorizontal")
segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(layout_nest.RelatedObjects[0]) segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(layout_nest.RelatedObjects[0])
assert (len(segment_nest.RelatedObjects) == 3) # segments in horizontal layout assert len(segment_nest.RelatedObjects) == 3 # segments in horizontal layout
test_horizontal_layout_by_pi_method() test_horizontal_layout_by_pi_method()
@@ -55,4 +55,5 @@ def test_name_segments():
assert f"Q{i}" == segment.Name assert f"Q{i}" == segment.Name
i += 1 i += 1
test_name_segments() test_name_segments()
@@ -98,7 +98,7 @@ def callback_alignment():
def test_with_default_names(default_names_alignment): def test_with_default_names(default_names_alignment):
hlayout = ifcopenshell.api.alignment.get_horizontal_layout(default_names_alignment) hlayout = ifcopenshell.api.alignment.get_horizontal_layout(default_names_alignment)
referent_nest = ifcopenshell.api.alignment.get_referent_nest(None,hlayout) referent_nest = ifcopenshell.api.alignment.get_referent_nest(None, hlayout)
assert "P.O.B." in referent_nest.RelatedObjects[0].Name assert "P.O.B." in referent_nest.RelatedObjects[0].Name
assert "P.C." in referent_nest.RelatedObjects[1].Name assert "P.C." in referent_nest.RelatedObjects[1].Name
@@ -106,7 +106,7 @@ def test_with_default_names(default_names_alignment):
assert "P.O.E." in referent_nest.RelatedObjects[-1].Name assert "P.O.E." in referent_nest.RelatedObjects[-1].Name
vlayout = ifcopenshell.api.alignment.get_vertical_layout(default_names_alignment) vlayout = ifcopenshell.api.alignment.get_vertical_layout(default_names_alignment)
referent_nest = ifcopenshell.api.alignment.get_referent_nest(None,vlayout) referent_nest = ifcopenshell.api.alignment.get_referent_nest(None, vlayout)
assert "V.P.O.B." in referent_nest.RelatedObjects[0].Name assert "V.P.O.B." in referent_nest.RelatedObjects[0].Name
assert "P.V.C." in referent_nest.RelatedObjects[1].Name assert "P.V.C." in referent_nest.RelatedObjects[1].Name
@@ -116,7 +116,7 @@ def test_with_default_names(default_names_alignment):
def test_with_callbacks(callback_alignment): def test_with_callbacks(callback_alignment):
hlayout = ifcopenshell.api.alignment.get_horizontal_layout(callback_alignment) hlayout = ifcopenshell.api.alignment.get_horizontal_layout(callback_alignment)
referent_nest = ifcopenshell.api.alignment.get_referent_nest(None,hlayout) referent_nest = ifcopenshell.api.alignment.get_referent_nest(None, hlayout)
assert "A" in referent_nest.RelatedObjects[0].Name assert "A" in referent_nest.RelatedObjects[0].Name
assert "Q" in referent_nest.RelatedObjects[1].Name assert "Q" in referent_nest.RelatedObjects[1].Name
@@ -124,10 +124,9 @@ def test_with_callbacks(callback_alignment):
assert "Z" in referent_nest.RelatedObjects[-1].Name assert "Z" in referent_nest.RelatedObjects[-1].Name
vlayout = ifcopenshell.api.alignment.get_vertical_layout(callback_alignment) vlayout = ifcopenshell.api.alignment.get_vertical_layout(callback_alignment)
referent_nest = ifcopenshell.api.alignment.get_referent_nest(None,vlayout) referent_nest = ifcopenshell.api.alignment.get_referent_nest(None, vlayout)
assert "a" in referent_nest.RelatedObjects[0].Name assert "a" in referent_nest.RelatedObjects[0].Name
assert "q" in referent_nest.RelatedObjects[1].Name assert "q" in referent_nest.RelatedObjects[1].Name
assert "q" in referent_nest.RelatedObjects[2].Name assert "q" in referent_nest.RelatedObjects[2].Name
assert "z" in referent_nest.RelatedObjects[-1].Name assert "z" in referent_nest.RelatedObjects[-1].Name
@@ -59,12 +59,12 @@ def test_vertical_layout_by_pi_method():
assert len(alignment.IsDecomposedBy) == 0 # no child alignments assert len(alignment.IsDecomposedBy) == 0 # no child alignments
assert len(alignment.IsNestedBy) == 2 assert len(alignment.IsNestedBy) == 2
referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,alignment) referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, alignment)
layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment) layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment)
assert(len(referent_nest.RelatedObjects) == 1) assert len(referent_nest.RelatedObjects) == 1
assert(len(layout_nest.RelatedObjects) == 2) assert len(layout_nest.RelatedObjects) == 2
segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(vlayout) segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(vlayout)
assert(len(segment_nest.RelatedObjects) == 3) assert len(segment_nest.RelatedObjects) == 3
test_vertical_layout_by_pi_method() test_vertical_layout_by_pi_method()