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
@@ -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
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.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(
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"):
# this is the first real segment in the horizontal alignment
# update the location of the alignment's stationing referent
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]
p = curve_evaluator.evaluate(
stationing_referent.ObjectPlacement.RelativePlacement.Location.DistanceAlong.wrappedValue
@@ -34,7 +34,7 @@ def add_stationing_referent(
distance_along: float,
station: float,
name: str,
positioned_product: entity_instance
positioned_product: entity_instance,
) -> entity_instance:
"""
Adds an IfcReferent to the element with the Pset_Stationing property set.
@@ -44,7 +44,7 @@ def add_stationing_referent(
:param distance_along: distance along the alignment curve
:param station: station value
:param name: name to assign to IfcReferent.Name, typically a stringized version of the station value
:param positioned_product: the product whose position is informed by the referent
:param positioned_product: the product whose position is informed by the referent
:return: referent
Example:
@@ -144,7 +144,7 @@ def add_stationing_referent(
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})
nest = ifcopenshell.api.alignment.get_referent_nest(file,element)
nest = ifcopenshell.api.alignment.get_referent_nest(file, element)
nest.RelatedObjects += (referent,)
if len(referent.Positions) == 0:
@@ -37,15 +37,15 @@ def create(
start_station: float = 0.0,
) -> entity_instance:
"""
Creates a new alignment with a horizontal layout. Optionally, vertical and cant layouts can be created as well.
The geometric representations are created as well, unless they are explicitly excluded.
Zero length segments are added at the end of the layouts and geometric representations.
Creates a new alignment with a horizontal layout. Optionally, vertical and cant layouts can be created as well.
The geometric representations are created as well, unless they are explicitly excluded.
Zero length segments are added at the end of the layouts and geometric representations.
The alignment is automatically aggreated to the project if it exists.
Use get_horizontal_layout(alignment), get_vertical_layout(alignment) and get_cant_layout(alignment) to get the
corresponding IfcAlignmentHorizontal, IfcAlignmentVertical, and IfcAlignmentCant layout entities.
If the alignment has Viennese Bend transition curves, create the segments in the cant layout before the horizontal layout using create_layout_segment().
If the alignment has Viennese Bend transition curves, create the segments in the cant layout before the horizontal layout using create_layout_segment().
The horizontal geometry in the Viennese Bend transition curves depends on the Viennese Bend cant parameters. create_layout_segment() automatically creates
the geometric representation from the semantic definition. The horizontal segment geometric representation will fail if the cant segment is not defined.
@@ -86,8 +86,9 @@ def create(
if include_geometry:
# define stationing
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
project = file.by_type("IfcProject")[0]
@@ -60,7 +60,7 @@ def create_layout_segment(
# returned and used when defining the next segment
alignment = ifcopenshell.api.alignment.get_alignment(layout)
curve = ifcopenshell.api.alignment.get_curve(alignment)
if curve:
if layout.is_a("IfcAlignmentHorizontal"):
if curve.is_a("IfcGradientCurve"):
@@ -18,6 +18,7 @@
from ifcopenshell import entity_instance
def get_alignment(layout: entity_instance) -> entity_instance:
"""
Returns the alignment that nests this layout
@@ -19,11 +19,12 @@
import ifcopenshell
from ifcopenshell import entity_instance
def get_alignment_layout_nest(alignment: entity_instance) -> entity_instance:
"""
Searches for the IfcRelNest that contains IfcAlignmentHorizontal, IfcAlignmentVertical, or IfcAlignmentCant
:param alignment: the alignment
:param alignment: the alignment
:return: Returns the IfcRelNests containing the alignment layout
"""
layout_types = ["IfcAlignmentHorizontal", "IfcAlignmentVertical", "IfcAlignmentCant"]
@@ -19,6 +19,7 @@
import ifcopenshell
from ifcopenshell import entity_instance
def get_alignment_segment_nest(layout: entity_instance) -> entity_instance:
"""
Searches for the IfcRelNest that contains IfcAlignmentSegment
@@ -21,6 +21,7 @@ import ifcopenshell.api.alignment
import ifcopenshell.util.element
from ifcopenshell import entity_instance
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
@@ -19,7 +19,8 @@
import ifcopenshell
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.
@@ -32,5 +33,5 @@ def get_referent_nest(file: ifcopenshell.file,entity: entity_instance) -> entity
if related_object.is_a("IfcReferent"):
return nest
nest = file.createIfcRelNests(GlobalId=ifcopenshell.guid.new(),RelatingObject=entity,RelatedObjects=[])
nest = file.createIfcRelNests(GlobalId=ifcopenshell.guid.new(), RelatingObject=entity, RelatedObjects=[])
return nest
@@ -163,10 +163,11 @@ def print_composite_curve_deep(curve):
print(" " * 4, segment.Placement.Location)
print(" " * 4, segment.Placement.RefDirection)
def print_positioned_products(file: ifcopenshell.file):
referents = file.by_type("IfcReferent")
for referent in referents:
print(referent)
for rel in referent.Positions:
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)
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)
assert (len(segment_nest.RelatedObjects) == 2)
assert (len(referent_nest.RelatedObjects) == 2)
assert len(segment_nest.RelatedObjects) == 2
assert len(referent_nest.RelatedObjects) == 2
test_add_segment_to_layout()
@@ -33,8 +33,8 @@ def test_add_vertical_alignment():
assert len(alignment.IsDecomposedBy) == 0 # no child alignments
assert len(alignment.IsNestedBy) == 2 # nests for layout and referents
assert len(alignment.IsNestedBy[0].RelatedObjects) == 1
assert ifcopenshell.api.alignment.get_referent_nest(file,alignment).RelatedObjects[0].is_a("IfcReferent")
assert len(alignment.IsNestedBy[0].RelatedObjects) == 1
assert ifcopenshell.api.alignment.get_referent_nest(file, alignment).RelatedObjects[0].is_a("IfcReferent")
assert alignment.IsNestedBy[0].RelatedObjects[0].is_a("IfcAlignmentHorizontal")
curve = ifcopenshell.api.alignment.get_curve(alignment)
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.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[1].is_a("IfcAlignmentVertical")
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)
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:
assert child_alignment.is_a("IfcAlignment")
@@ -49,19 +49,19 @@ def test_create_by_pi_method():
assert len(alignment.IsNestedBy) == 2
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_segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(horizontal_layout)
assert (len(horizontal_segment_nest.RelatedObjects) == 8)
horizontal_referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,horizontal_layout)
assert (len(horizontal_referent_nest.RelatedObjects) == 8)
assert len(horizontal_segment_nest.RelatedObjects) == 8
horizontal_referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, horizontal_layout)
assert len(horizontal_referent_nest.RelatedObjects) == 8
vertical_layout = ifcopenshell.api.alignment.get_vertical_layout(alignment)
vertical_segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(vertical_layout)
assert (len(vertical_segment_nest.RelatedObjects) == 10)
vertical_referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,vertical_layout)
assert (len(vertical_referent_nest.RelatedObjects) == 10)
assert len(vertical_segment_nest.RelatedObjects) == 10
vertical_referent_nest = ifcopenshell.api.alignment.get_referent_nest(file, vertical_layout)
assert len(vertical_referent_nest.RelatedObjects) == 10
test_create_by_pi_method()
@@ -29,7 +29,7 @@ def test_create_no_geometry():
ifcopenshell.api.unit.assign_unit(file, units=[length])
# 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
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.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)
assert referent_nest.RelatedObjects[0].is_a("IfcReferent")
assert layout_nest.RelatedObjects[0].is_a("IfcAlignmentHorizontal")
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()
@@ -55,4 +55,5 @@ def test_name_segments():
assert f"Q{i}" == segment.Name
i += 1
test_name_segments()
test_name_segments()
@@ -98,7 +98,7 @@ def callback_alignment():
def test_with_default_names(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.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
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 "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):
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 "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
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 "q" in referent_nest.RelatedObjects[1].Name
assert "q" in referent_nest.RelatedObjects[2].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.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)
assert(len(referent_nest.RelatedObjects) == 1)
assert(len(layout_nest.RelatedObjects) == 2)
assert len(referent_nest.RelatedObjects) == 1
assert len(layout_nest.RelatedObjects) == 2
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()