Alignment API update for station and positioning referents. Fixes bug with fallback position.

This commit is contained in:
Richard Brice
2026-07-09 14:10:33 -07:00
parent 9ae79b42dd
commit 206cd6bbe1
11 changed files with 366 additions and 45 deletions
@@ -16,35 +16,33 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import numpy as np
from typing import Optional
import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell.api.alignment.update_fallback_position import update_fallback_position
import ifcopenshell.api.pset
import ifcopenshell.geom
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.unit
from ifcopenshell import entity_instance, ifcopenshell_wrapper
from ifcopenshell import entity_instance
def add_stationing_referent(
file: ifcopenshell.file,
name: str,
alignment: entity_instance,
distance_along: float,
station: float,
name: str,
positioned_product: entity_instance,
incoming_station: Optional[float] = None,
) -> entity_instance:
"""
Adds an IfcReferent to the alignment with the Pset_Stationing property set.
Adds an IfcReferent to the alignment that defines the stationing system.
:param name: name to assign to IfcReferent.Name, typically a stringized version of the station value
:param alignment: the alignment to receive the referent
:param distance_along: distance along the alignment basis 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 incoming_station: station value of the incoming segment, only set to specify a station equation
:return: referent
Example:
@@ -52,7 +50,7 @@ def add_stationing_referent(
.. code:: python
alignment = model.by_type("IfcAlignment")[0]
ifcopenshell.api.alignment.add_stationing_referent(model,alignment=alignment,distance_along=0.0,station=100.0)
ifcopenshell.api.alignment.add_stationing_referent(model,name="1+00.0",alignment=alignment,distance_along=0.0,station=100.0)
"""
basis_curve = ifcopenshell.api.alignment.get_basis_curve(alignment)
@@ -100,8 +98,12 @@ def add_stationing_referent(
Representation=representation,
PredefinedType="STATION",
)
properties = {"Station": station}
if incoming_station is not None:
properties["IncomingStation"] = incoming_station
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=properties)
nest = ifcopenshell.api.alignment.get_referent_nest(file, alignment)
if nest is None:
@@ -115,15 +117,4 @@ def add_stationing_referent(
nest.RelatedObjects, key=lambda x: ifcopenshell.util.element.get_pset(x, name="Pset_Stationing", prop="Station")
)
if len(referent.Positions) == 0:
rel_positions = file.createIfcRelPositions(
GlobalId=ifcopenshell.guid.new(),
RelatingPositioningElement=referent,
RelatedProducts=[
positioned_product,
],
)
else:
referent.Positions[0].RelatedProducts += (positioned_product,)
return referent