Skip to content

Commit ff0286e

Browse files
committed
update slab and slab with opening
1 parent 02204b6 commit ff0286e

File tree

2 files changed

+390
-103
lines changed

2 files changed

+390
-103
lines changed

src/ifcplus/api/built_element.py

Lines changed: 183 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -305,21 +305,6 @@ def create_2pt_wall(
305305
)
306306
length = float(np.linalg.norm(vector_from_start_point_to_end_point))
307307

308-
# arbitrary_closed_profile_def = (
309-
# ifcplus.api.profile.add_arbitrary_profile_with_or_without_voids(
310-
# file=ifc4_file,
311-
# outer_profile=[
312-
# (0.0, 0.0 - total_thickness / 2),
313-
# (0.0 + length, 0.0 - total_thickness / 2),
314-
# (0.0 + length, 0.0 + total_thickness - total_thickness / 2),
315-
# (0.0 + length - length, 0.0 + total_thickness - total_thickness / 2),
316-
# (0.0, 0.0 - total_thickness / 2),
317-
# ],
318-
# inner_profiles=[],
319-
# name=None,
320-
# )
321-
# )
322-
323308
arbitrary_closed_profile_def = ifcopenshell.api.profile.add_arbitrary_profile(
324309
file=ifc4_file,
325310
profile=[
@@ -621,125 +606,220 @@ def create_curved_wall(
621606
return wall
622607

623608

624-
def create_npt_slab(
625-
outer_profile: list[tuple[float, float]], # global XY
626-
elevation: float, # global Z
609+
# def create_npt_slab_old(
610+
# outer_profile: list[tuple[float, float]], # global XY
611+
# elevation: float, # global Z
612+
# materials: list[ifcopenshell.entity_instance],
613+
# thicknesses: list[float],
614+
# inner_openings: list[list[tuple[float, float]]] = [], # Local XY
615+
# slab: ifcopenshell.entity_instance | None = None,
616+
# name: str | None = None,
617+
# structure_contained_in: ifcopenshell.entity_instance | None = None,
618+
# should_transform_relative_to_parent: bool = False,
619+
# ) -> ifcopenshell.entity_instance:
620+
# """
621+
# Add a geometric representation for an IfcSlab represented by an IfcIndexedPolyCurve
622+
# composed of straight lines defined by 2D points, and then automatically assign the
623+
# reprsentation.
624+
# """
625+
626+
# # Get IFC4 File
627+
# ifc4_file = materials[0].file
628+
629+
# # Create Slab
630+
# if slab is None:
631+
# slab = ifcopenshell.api.root.create_entity(
632+
# file=ifc4_file,
633+
# ifc_class="IfcSlab",
634+
# name=name,
635+
# predefined_type=None,
636+
# )
637+
638+
# # Assign spatial container
639+
# if isinstance(structure_contained_in, ifcopenshell.entity_instance):
640+
# ifcopenshell.api.spatial.assign_container(
641+
# file=ifc4_file,
642+
# products=[slab],
643+
# relating_structure=structure_contained_in,
644+
# )
645+
# ifcplus.api.placement.edit_object_placement(
646+
# product=slab,
647+
# place_object_relative_to_parent=True,
648+
# )
649+
650+
# # Calculate thickness
651+
# thickness = sum(thicknesses)
652+
653+
# # Add and assign representation
654+
# representation_item = ifcplus.api.geometry.add_extruded_area_solid(
655+
# ifc4_file=ifc4_file,
656+
# profile=ifcplus.api.profile.add_arbitrary_profile_with_or_without_voids(
657+
# file=ifc4_file,
658+
# outer_profile=outer_profile,
659+
# inner_profiles=[],
660+
# name=None,
661+
# ),
662+
# repositioned_origin=(0.0, 0.0, -thickness / 2),
663+
# extrusion_depth=thickness,
664+
# )
665+
# shape_model = ifcplus.api.geometry.add_shape_model(
666+
# ifc4_file=ifc4_file,
667+
# shape_model_class="IfcShapeRepresentation",
668+
# representation_identifier="Body",
669+
# representation_type="SweptSolid",
670+
# context_type="Model",
671+
# target_view="MODEL_VIEW",
672+
# items=[representation_item],
673+
# )
674+
# ifcopenshell.api.geometry.assign_representation(
675+
# file=ifc4_file,
676+
# product=slab,
677+
# representation=shape_model,
678+
# )
679+
680+
# # Edit Placement
681+
# ifcplus.api.placement.edit_object_placement(
682+
# product=slab,
683+
# repositioned_origin=(0.0, 0.0, elevation),
684+
# place_object_relative_to_parent=should_transform_relative_to_parent,
685+
# )
686+
687+
# # Add and assign Type
688+
# slab_type = ifcplus.api.element_type.add_slab_or_wall_or_plate_element_type(
689+
# ifc_class="IfcSlabType",
690+
# materials=materials,
691+
# thicknesses=thicknesses,
692+
# check_for_duplicate=True,
693+
# )
694+
# ifcopenshell.api.type.assign_type(
695+
# file=ifc4_file,
696+
# related_objects=[slab],
697+
# relating_type=slab_type,
698+
# )
699+
700+
# # Declare Type on Project
701+
# project = ifc4_file.by_type(type="IfcProject", include_subtypes=False)[0]
702+
# ifcopenshell.api.project.assign_declaration(
703+
# file=ifc4_file,
704+
# definitions=[slab_type],
705+
# relating_context=project,
706+
# )
707+
708+
# # Assign MaterialProfileSetUsage (material deduced from assigned element type
709+
# # automatically)
710+
# rel_associates_material = ifcopenshell.api.material.assign_material(
711+
# file=ifc4_file,
712+
# products=[slab],
713+
# type="IfcMaterialLayerSetUsage",
714+
# )
715+
# assert isinstance(rel_associates_material, ifcopenshell.entity_instance)
716+
# material_layer_set_usage = rel_associates_material.RelatingMaterial
717+
# material_layer_set_usage.OffsetFromReferenceLine = -thickness / 2
718+
719+
# # Openings
720+
# for inner_opening_coordinates in inner_openings:
721+
# create_opening_element(
722+
# voided_element=slab,
723+
# profile_points=inner_opening_coordinates,
724+
# depth=thickness,
725+
# origin_relative_to_voided_element=(0.0, 0.0, -thickness / 2),
726+
# x_axis_relative_to_voided_element=(1.0, 0.0, 0.0),
727+
# z_axis_relative_to_voided_element=(0.0, 0.0, 1.0),
728+
# )
729+
730+
# return slab
731+
732+
733+
def create_slab(
734+
profile: ifcopenshell.entity_instance,
735+
point_at_placement_of_slab_profile: tuple[float, float, float],
627736
materials: list[ifcopenshell.entity_instance],
628737
thicknesses: list[float],
629-
inner_openings: list[list[tuple[float, float]]] = [], # Local XY
630738
slab: ifcopenshell.entity_instance | None = None,
631739
name: str | None = None,
632-
structure_contained_in: ifcopenshell.entity_instance | None = None,
633-
should_transform_relative_to_parent: bool = False,
634-
) -> ifcopenshell.entity_instance:
635-
"""
636-
Add a geometric representation for an IfcSlab represented by an IfcIndexedPolyCurve
637-
composed of straight lines defined by 2D points, and then automatically assign the
638-
reprsentation.
639-
"""
740+
parent: ifcopenshell.entity_instance | None = None,
741+
place_object_relative_to_parent: bool = False,
742+
):
640743

641-
# Get IFC4 File
642744
ifc4_file = materials[0].file
643745

644-
# Create Slab
746+
material_layer_set = ifcplus.api.material.add_material_layer_set(
747+
materials=materials,
748+
thicknesses=thicknesses,
749+
name=None,
750+
check_for_duplicate=True,
751+
)
752+
753+
slab_type = ifcplus.api.element_type.add_element_type_for_material_layer_set(
754+
ifc_class="IfcSlabType",
755+
material_layer_set=material_layer_set,
756+
name=material_layer_set.LayerSetName,
757+
check_for_duplicate=True,
758+
)
759+
645760
if slab is None:
646761
slab = ifcopenshell.api.root.create_entity(
647762
file=ifc4_file,
648763
ifc_class="IfcSlab",
649764
name=name,
650-
predefined_type=None,
765+
predefined_type="NOTDEFINED",
651766
)
652767

653-
# Assign spatial container
654-
if isinstance(structure_contained_in, ifcopenshell.entity_instance):
655-
ifcopenshell.api.spatial.assign_container(
656-
file=ifc4_file,
657-
products=[slab],
658-
relating_structure=structure_contained_in,
659-
)
660-
ifcplus.api.placement.edit_object_placement(
661-
product=slab,
662-
place_object_relative_to_parent=True,
663-
)
768+
ifcopenshell.api.type.assign_type(
769+
file=ifc4_file,
770+
related_objects=[slab],
771+
relating_type=slab_type,
772+
)
664773

665-
# Calculate thickness
666-
thickness = sum(thicknesses)
774+
total_thickness = 0.0
775+
for material_layer in material_layer_set.MaterialLayers:
776+
total_thickness += material_layer.LayerThickness
667777

668-
# Add and assign representation
669-
representation_item = ifcplus.api.geometry.add_extruded_area_solid(
778+
ifcopenshell.api.material.assign_material(
779+
file=ifc4_file,
780+
products=[slab],
781+
type="IfcMaterialLayerSetUsage",
782+
material=None, # inferred from assigned IfcElementType
783+
)
784+
785+
extruded_area_solid = ifcplus.api.geometry.add_extruded_area_solid(
670786
ifc4_file=ifc4_file,
671-
profile=ifcplus.api.profile.add_arbitrary_profile_with_or_without_voids(
672-
file=ifc4_file,
673-
outer_profile=outer_profile,
674-
inner_profiles=[],
675-
name=None,
676-
),
677-
repositioned_origin=(0.0, 0.0, -thickness / 2),
678-
extrusion_depth=thickness,
787+
profile=profile,
788+
extrusion_depth=total_thickness,
679789
)
680-
shape_model = ifcplus.api.geometry.add_shape_model(
790+
791+
shape_representation = ifcplus.api.geometry.add_shape_model(
681792
ifc4_file=ifc4_file,
682793
shape_model_class="IfcShapeRepresentation",
683794
representation_identifier="Body",
684-
representation_type="SweptSolid",
795+
representation_type=cast(
796+
str,
797+
ifcopenshell.util.representation.guess_type(items=[extruded_area_solid]),
798+
), # SweptSolid
685799
context_type="Model",
686800
target_view="MODEL_VIEW",
687-
items=[representation_item],
801+
items=[extruded_area_solid],
688802
)
803+
689804
ifcopenshell.api.geometry.assign_representation(
690805
file=ifc4_file,
691806
product=slab,
692-
representation=shape_model,
807+
representation=shape_representation,
693808
)
694809

695-
# Edit Placement
810+
if isinstance(parent, ifcopenshell.entity_instance):
811+
ifcopenshell.api.spatial.assign_container(
812+
file=ifc4_file,
813+
products=[slab],
814+
relating_structure=parent,
815+
)
816+
696817
ifcplus.api.placement.edit_object_placement(
697818
product=slab,
698-
repositioned_origin=(0.0, 0.0, elevation),
699-
place_object_relative_to_parent=should_transform_relative_to_parent,
700-
)
701-
702-
# Add and assign Type
703-
slab_type = ifcplus.api.element_type.add_slab_or_wall_or_plate_element_type(
704-
ifc_class="IfcSlabType",
705-
materials=materials,
706-
thicknesses=thicknesses,
707-
check_for_duplicate=True,
708-
)
709-
ifcopenshell.api.type.assign_type(
710-
file=ifc4_file,
711-
related_objects=[slab],
712-
relating_type=slab_type,
713-
)
714-
715-
# Declare Type on Project
716-
project = ifc4_file.by_type(type="IfcProject", include_subtypes=False)[0]
717-
ifcopenshell.api.project.assign_declaration(
718-
file=ifc4_file,
719-
definitions=[slab_type],
720-
relating_context=project,
721-
)
722-
723-
# Assign MaterialProfileSetUsage (material deduced from assigned element type
724-
# automatically)
725-
rel_associates_material = ifcopenshell.api.material.assign_material(
726-
file=ifc4_file,
727-
products=[slab],
728-
type="IfcMaterialLayerSetUsage",
819+
repositioned_origin=point_at_placement_of_slab_profile,
820+
repositioned_x_axis=(1.0, 0.0, 0.0),
821+
repositioned_z_axis=(0.0, 0.0, 1.0),
822+
place_object_relative_to_parent=place_object_relative_to_parent,
729823
)
730-
assert isinstance(rel_associates_material, ifcopenshell.entity_instance)
731-
material_layer_set_usage = rel_associates_material.RelatingMaterial
732-
material_layer_set_usage.OffsetFromReferenceLine = -thickness / 2
733-
734-
# Openings
735-
for inner_opening_coordinates in inner_openings:
736-
create_opening_element(
737-
voided_element=slab,
738-
profile_points=inner_opening_coordinates,
739-
depth=thickness,
740-
origin_relative_to_voided_element=(0.0, 0.0, -thickness / 2),
741-
x_axis_relative_to_voided_element=(1.0, 0.0, 0.0),
742-
z_axis_relative_to_voided_element=(0.0, 0.0, 1.0),
743-
)
744824

745825
return slab

0 commit comments

Comments
 (0)