mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-11 22:31:55 +00:00
Fixes problems with referents
This commit is contained in:
@@ -89,7 +89,8 @@ def _add_segment_to_layout(file: ifcopenshell.file, layout: entity_instance, seg
|
|||||||
# update the zero length layout segment
|
# update the zero length layout segment
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
|
||||||
|
|
||||||
zero_length_segment = layout.IsNestedBy[0].RelatedObjects[-1]
|
segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(layout)
|
||||||
|
zero_length_segment = segment_nest.RelatedObjects[-1]
|
||||||
# DesignParameters.StartPoint for IfcAlignmentHorizontalSegment is automatically updated when the
|
# DesignParameters.StartPoint for IfcAlignmentHorizontalSegment is automatically updated when the
|
||||||
# geometric representation is updated because the semantic and geometric data use the same IfcPoint.
|
# geometric representation is updated because the semantic and geometric data use the same IfcPoint.
|
||||||
# This is not the case of IfcAlignmentVerticalSegment and IfcAlignmentCantSegment. For these
|
# This is not the case of IfcAlignmentVerticalSegment and IfcAlignmentCantSegment. For these
|
||||||
@@ -136,7 +137,8 @@ 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
|
||||||
|
|
||||||
end_referent = zero_length_segment.IsNestedBy[0].RelatedObjects[0]
|
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)})"
|
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)})"
|
||||||
|
|
||||||
# update the referent's geometric representation's location
|
# update the referent's geometric representation's location
|
||||||
@@ -173,12 +175,12 @@ def _add_segment_to_layout(file: ifcopenshell.file, layout: entity_instance, seg
|
|||||||
|
|
||||||
# get the previous segment. Working from the end of the basis curve, -1 is zero length segment
|
# get the previous segment. Working from the end of the basis curve, -1 is zero length segment
|
||||||
# -2 is the newly added segment, so -3 is the segment occuring just before the newly added segment
|
# -2 is the newly added segment, so -3 is the segment occuring just before the newly added segment
|
||||||
segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(layout)
|
|
||||||
prev_segment = segment_nest.RelatedObjects[-3] if 2 < len(segment_nest.RelatedObjects) else None
|
prev_segment = segment_nest.RelatedObjects[-3] if 2 < len(segment_nest.RelatedObjects) else None
|
||||||
name = f"{_get_segment_start_point_label(prev_segment,segment)} ({ifcopenshell.util.alignment.station_as_string(file,station)})"
|
name = f"{_get_segment_start_point_label(prev_segment,segment)} ({ifcopenshell.util.alignment.station_as_string(file,station)})"
|
||||||
referent = ifcopenshell.api.alignment.add_stationing_referent(
|
referent = ifcopenshell.api.alignment.add_stationing_referent(
|
||||||
file, segment, distance_along=dist_along, station=station, name=name
|
file, layout, distance_along=dist_along, station=station, name=name, positioned_product=segment
|
||||||
)
|
)
|
||||||
|
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
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ def _add_zero_length_segment(file: ifcopenshell.file, layout: entity_instance) -
|
|||||||
if curve:
|
if curve:
|
||||||
ifcopenshell.api.alignment.add_zero_length_segment(file, curve)
|
ifcopenshell.api.alignment.add_zero_length_segment(file, curve)
|
||||||
|
|
||||||
segment = layout.IsNestedBy[0].RelatedObjects[-1]
|
segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(layout)
|
||||||
|
segment = segment_nest.RelatedObjects[-1]
|
||||||
alignment = ifcopenshell.api.alignment.get_alignment(layout)
|
alignment = ifcopenshell.api.alignment.get_alignment(layout)
|
||||||
station = ifcopenshell.api.alignment.get_alignment_station(file, alignment)
|
station = ifcopenshell.api.alignment.get_alignment_station(file, alignment)
|
||||||
name = f"{_get_segment_start_point_label(segment,None)} ({ifcopenshell.util.alignment.station_as_string(file,station)})"
|
name = f"{_get_segment_start_point_label(segment,None)} ({ifcopenshell.util.alignment.station_as_string(file,station)})"
|
||||||
ifcopenshell.api.alignment.add_stationing_referent(file, segment, 0.0, station, name=name)
|
ifcopenshell.api.alignment.add_stationing_referent(file, layout, 0.0, station, name, segment)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ def add_stationing_referent(
|
|||||||
distance_along: float,
|
distance_along: float,
|
||||||
station: float,
|
station: float,
|
||||||
name: str,
|
name: str,
|
||||||
|
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.
|
||||||
@@ -43,6 +44,7 @@ def add_stationing_referent(
|
|||||||
:param distance_along: distance along the alignment curve
|
:param distance_along: distance along the alignment curve
|
||||||
:param station: station value
|
:param station: station value
|
||||||
:param name: name to assign to IfcReferent.Name, typically a stringized version of the 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
|
||||||
:return: referent
|
:return: referent
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@@ -54,9 +56,17 @@ def add_stationing_referent(
|
|||||||
"""
|
"""
|
||||||
alignment = element
|
alignment = element
|
||||||
|
|
||||||
|
layout_types = [
|
||||||
|
"IfcAlignmentHorizontal",
|
||||||
|
"IfcAlignmentVertical",
|
||||||
|
"IfcAlignmentCant",
|
||||||
|
]
|
||||||
|
|
||||||
if element.is_a("IfcAlignmentSegment"):
|
if element.is_a("IfcAlignmentSegment"):
|
||||||
layout = element.Nests[0].RelatingObject
|
layout = element.Nests[0].RelatingObject
|
||||||
alignment = ifcopenshell.api.alignment.get_alignment(layout)
|
alignment = ifcopenshell.api.alignment.get_alignment(layout)
|
||||||
|
elif element.is_a() in layout_types:
|
||||||
|
alignment = ifcopenshell.api.alignment.get_alignment(element)
|
||||||
|
|
||||||
basis_curve = ifcopenshell.api.alignment.get_basis_curve(alignment)
|
basis_curve = ifcopenshell.api.alignment.get_basis_curve(alignment)
|
||||||
|
|
||||||
@@ -137,15 +147,15 @@ def add_stationing_referent(
|
|||||||
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(alignment.Positions) == 0:
|
if len(referent.Positions) == 0:
|
||||||
rel_positions = file.createIfcRelPositions(
|
rel_positions = file.createIfcRelPositions(
|
||||||
GlobalId=ifcopenshell.guid.new(),
|
GlobalId=ifcopenshell.guid.new(),
|
||||||
RelatingPositioningElement=alignment,
|
RelatingPositioningElement=referent,
|
||||||
RelatedProducts=[
|
RelatedProducts=[
|
||||||
referent,
|
positioned_product,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
alignment.Positions[0].RelatedProducts += (referent,)
|
referent.Positions[0].RelatedProducts += (positioned_product,)
|
||||||
|
|
||||||
return referent
|
return referent
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ 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)
|
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
|
||||||
|
|||||||
@@ -137,13 +137,11 @@ def create_as_polyline(
|
|||||||
Name=name,
|
Name=name,
|
||||||
)
|
)
|
||||||
|
|
||||||
# _create_layout(file,alignment,points)
|
|
||||||
|
|
||||||
_create_polyline_representation(file, alignment, points)
|
_create_polyline_representation(file, alignment, points)
|
||||||
|
|
||||||
# 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)
|
referent = ifcopenshell.api.alignment.add_stationing_referent(file, alignment, 0.0, start_station, name, alignment)
|
||||||
ifcopenshell.api.nest.reorder_nesting(file, referent, -1, 0)
|
ifcopenshell.api.nest.reorder_nesting(file, referent, -1, 0)
|
||||||
|
|
||||||
# IFC 4.1.4.1.1 Alignment Aggregation To Project
|
# IFC 4.1.4.1.1 Alignment Aggregation To Project
|
||||||
|
|||||||
@@ -162,3 +162,11 @@ def print_composite_curve_deep(curve):
|
|||||||
print(" " * 4, segment.Placement)
|
print(" " * 4, segment.Placement)
|
||||||
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):
|
||||||
|
referents = file.by_type("IfcReferent")
|
||||||
|
for referent in referents:
|
||||||
|
print(referent)
|
||||||
|
for rel in referent.Positions:
|
||||||
|
for product in rel.RelatedProducts:
|
||||||
|
print(" " * 2,product)
|
||||||
@@ -67,14 +67,11 @@ 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) == 1
|
assert len(horizontal_alignment.IsNestedBy) == 2
|
||||||
assert (
|
referent_nest = ifcopenshell.api.alignment.get_referent_nest(file,horizontal_alignment)
|
||||||
len(horizontal_alignment.IsNestedBy[0].RelatedObjects) == 2
|
segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(horizontal_alignment)
|
||||||
) # The the segment we added and the automatically created zero length segment
|
assert (len(segment_nest.RelatedObjects) == 2)
|
||||||
assert horizontal_alignment.IsNestedBy[0].RelatedObjects[0] == alignment_segment
|
assert (len(referent_nest.RelatedObjects) == 2)
|
||||||
assert (
|
|
||||||
alignment_segment.IsNestedBy[0].RelatedObjects[0].is_a("IfcReferent")
|
|
||||||
) # a referent is automatically added at the start of the segment
|
|
||||||
|
|
||||||
|
|
||||||
test_add_segment_to_layout()
|
test_add_segment_to_layout()
|
||||||
|
|||||||
@@ -46,15 +46,22 @@ def test_create_by_pi_method():
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert len(alignment.IsDecomposedBy) == 0 # no child alignments
|
assert len(alignment.IsDecomposedBy) == 0 # no child alignments
|
||||||
assert len(alignment.IsNestedBy) == 2 # one nest
|
assert len(alignment.IsNestedBy) == 2
|
||||||
assert (len(alignment.IsNestedBy[0].RelatedObjects) == 2)
|
|
||||||
assert ifcopenshell.api.alignment.get_referent_nest(file,alignment).RelatedObjects[0].is_a("IfcReferent")
|
|
||||||
layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment)
|
layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment)
|
||||||
assert layout_nest.RelatedObjects[0].is_a("IfcAlignmentHorizontal")
|
assert (len(layout_nest.RelatedObjects) == 2)
|
||||||
assert layout_nest.RelatedObjects[1].is_a("IfcAlignmentVertical")
|
|
||||||
assert (len(layout_nest.RelatedObjects[0].IsNestedBy) == 1) # nesting of segments beneath IfcAlignmentHorizontal
|
horizontal_layout = ifcopenshell.api.alignment.get_horizontal_layout(alignment)
|
||||||
assert (len(layout_nest.RelatedObjects[0].IsNestedBy[0].RelatedObjects) == 8) # segments in horizontal layout
|
horizontal_segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(horizontal_layout)
|
||||||
assert (len(layout_nest.RelatedObjects[1].IsNestedBy[0].RelatedObjects) == 10) # segments in vertical 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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
test_create_by_pi_method()
|
test_create_by_pi_method()
|
||||||
|
|||||||
@@ -45,12 +45,14 @@ def test_name_segments():
|
|||||||
file, "TestAlignment", coordinates, radii, vpoints, lengths
|
file, "TestAlignment", coordinates, radii, vpoints, lengths
|
||||||
)
|
)
|
||||||
|
|
||||||
for rel in alignment.IsNestedBy:
|
layout_nest = ifcopenshell.api.alignment.get_alignment_layout_nest(alignment)
|
||||||
for a in rel.RelatedObjects:
|
for layout in layout_nest.RelatedObjects:
|
||||||
if a.is_a("IfcLinearElement"):
|
assert layout.is_a("IfcLinearElement")
|
||||||
ifcopenshell.api.alignment.name_segments("Q", a)
|
ifcopenshell.api.alignment.name_segments("Q", layout)
|
||||||
i = 1
|
segment_nest = ifcopenshell.api.alignment.get_alignment_segment_nest(layout)
|
||||||
for sr in a.IsNestedBy:
|
i = 1
|
||||||
for s in sr.RelatedObjects:
|
for segment in segment_nest.RelatedObjects:
|
||||||
assert f"Q{i}" == s.Name
|
assert f"Q{i}" == segment.Name
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
test_name_segments()
|
||||||
@@ -98,31 +98,36 @@ 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)
|
||||||
|
|
||||||
assert "P.O.B." in hlayout.IsNestedBy[0].RelatedObjects[0].IsNestedBy[0].RelatedObjects[0].Name
|
assert "P.O.B." in referent_nest.RelatedObjects[0].Name
|
||||||
assert "P.C." in hlayout.IsNestedBy[0].RelatedObjects[1].IsNestedBy[0].RelatedObjects[0].Name
|
assert "P.C." in referent_nest.RelatedObjects[1].Name
|
||||||
assert "P.T." in hlayout.IsNestedBy[0].RelatedObjects[2].IsNestedBy[0].RelatedObjects[0].Name
|
assert "P.T." in referent_nest.RelatedObjects[2].Name
|
||||||
assert "P.O.E." in hlayout.IsNestedBy[0].RelatedObjects[-1].IsNestedBy[0].RelatedObjects[0].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)
|
||||||
|
|
||||||
assert "V.P.O.B." in vlayout.IsNestedBy[0].RelatedObjects[0].IsNestedBy[0].RelatedObjects[0].Name
|
assert "V.P.O.B." in referent_nest.RelatedObjects[0].Name
|
||||||
assert "P.V.C." in vlayout.IsNestedBy[0].RelatedObjects[1].IsNestedBy[0].RelatedObjects[0].Name
|
assert "P.V.C." in referent_nest.RelatedObjects[1].Name
|
||||||
assert "P.V.T." in vlayout.IsNestedBy[0].RelatedObjects[2].IsNestedBy[0].RelatedObjects[0].Name
|
assert "P.V.T." in referent_nest.RelatedObjects[2].Name
|
||||||
assert "V.P.O.E." in vlayout.IsNestedBy[0].RelatedObjects[-1].IsNestedBy[0].RelatedObjects[0].Name
|
assert "V.P.O.E." in referent_nest.RelatedObjects[-1].Name
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
assert "A" in hlayout.IsNestedBy[0].RelatedObjects[0].IsNestedBy[0].RelatedObjects[0].Name
|
assert "A" in referent_nest.RelatedObjects[0].Name
|
||||||
assert "Q" in hlayout.IsNestedBy[0].RelatedObjects[1].IsNestedBy[0].RelatedObjects[0].Name
|
assert "Q" in referent_nest.RelatedObjects[1].Name
|
||||||
assert "Q" in hlayout.IsNestedBy[0].RelatedObjects[2].IsNestedBy[0].RelatedObjects[0].Name
|
assert "Q" in referent_nest.RelatedObjects[2].Name
|
||||||
assert "Z" in hlayout.IsNestedBy[0].RelatedObjects[-1].IsNestedBy[0].RelatedObjects[0].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)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
assert "a" in vlayout.IsNestedBy[0].RelatedObjects[0].IsNestedBy[0].RelatedObjects[0].Name
|
|
||||||
assert "q" in vlayout.IsNestedBy[0].RelatedObjects[1].IsNestedBy[0].RelatedObjects[0].Name
|
|
||||||
assert "q" in vlayout.IsNestedBy[0].RelatedObjects[2].IsNestedBy[0].RelatedObjects[0].Name
|
|
||||||
assert "z" in vlayout.IsNestedBy[0].RelatedObjects[-1].IsNestedBy[0].RelatedObjects[0].Name
|
|
||||||
|
|||||||
Reference in New Issue
Block a user