Piszemy model IFC 4x3 w notatniku. Poradnik krok-po-kroku do zrozumienia struktury IFC.

IFC4x3 jest już oficjalnym standardem (release note). Nowości tej wersji wiążą się zwłaszcza z infrastrukturą – kolejami, drogami, portami, czy mostami.

IFC4x3 zawiera nowe dedykowane klasy jak np. IfcFacility, IfcBridge, IfcRoad, a nawet jeszcze konkretniejsze IfcBearing, IfcPavement, czy IfcRail (nie wszystko związane z infrastrukturą musi więc być dalej modelowane z ogólnym IfcBuildingElementProxy). Mamy też reprezentujące niweletę IfcAlignment i nowe sposoby lokalizacji geometrii, właśnie w odniesieniu do niwelety.

A więc jak te nowości możemy wykorzystać w modelu IFC? W tym poście proponuję pewne ćwiczenie. Zbudujemy prosty model IFC, ale “ręcznie”, bez narzędzi do modelowania – używając jedynie notatnika. Myślę, że to dobry sposób na poznanie nowych możliwości IFC 4×3, ale też na ogólne zrozumienie struktury. Jak wygląda kod, który koniec końców jest wizualizowany w postaci modelu?

Otwieramy notatniki (lub inne oprogramowanie do tworzenia plików tekstowych), tworzymy nowy plik, zapisujemy go z rozszerzeniem “.ifc” i zaczynamy!

Nagłówek

Początek modelu to nagłówek (header). Nagłówek zawiera podstawowe informacje o pliku jak: nazwa, czas utworzenia, twórca i organizacja (np. firma), czy użyty do modelowania program. Zawiera też informację o użytej wersji IFC. W naszym przypadku używamy “IFC4X3_ADD2”, odnosząc się do aktualnie oficjalnej wersji IFC 4.3.2.0.

ISO-10303-21;  

HEADER;
FILE_DESCRIPTION ((”), ‘2;1’); FILE_NAME (‘Bridge model example’, ‘2024-10-14T17:42:13’, ‘Kamil Korus’, ‘AECO Evolution’, ‘Processor version’, ‘Software’, ”);
FILE_SCHEMA ((‘IFC4X3_ADD2’));
ENDSEC;

Projekt i jednostki

Dane w IFC opisywane są za pomocą klas, a właściwie instancji klas. (Po angielsku odnosimy się do “entity”, ale to słowo nie ma bezpośredniego dobrego tłumaczenia. “Instancje klas” wydają się być dobrym przybliżeniem, więc tak też często je nazywamy. Jaka jest różnica pomiędzy klasą a instancją klasy? Przykładowo, IfcColumn to “klasa”. A już konkretne wystąpienie IfcColumn w modelu to “instancja klasy” – jeden model może mięc więcej słupów, a więc więcej instancji tej jednej klasy.)

IfcProject to jedna z podstawowych klas, definiująca cały projekt. Klasy mogą mieć różne atrybuty. Pierwszy atrybut IfcProject (tak jak i w przypadku wielu innych klas) to unikalny globalny numer ID, GUID. Następne atrybuty to np. nazwa czy opis projektu. Wartości atrybutów mogą przybierać różne formy, jak np. tekst czy liczba (niektóre atrybuty są opcjonalne i mogą być pominięte poprzez wartość “$”). Wartości atrybutów mogą też odnosić się do innych instancji. W takim przypadku, wartość danego atrybutu to numer poprzedzony hasztagiem (np. #2). Numer ten wskazuje na instancję, do której się odnosimy. W naszym przykladzie, #2 (kolor dla lepszego odniesienia i “zrozumienia” w kodzie modelu) łączy IfcProject z zestawem jednostek zdefiniowanych dla tego modelu. Z kolei (#14, #17) łączy projekt z “geometric representation context”, który za chwilę utworzymy.

DATA; #1=IFCPROJECT(‘0vGCH5MKb7IxXhcP$Yz3$a’,$,’Bridge project’, ‘This project is a simple example of modeling a bridge’,$,$,$,(#14,#17),#2);

#2=IFCUNITASSIGNMENT((#3,#4,#5,#6,#7,#8,#9,#10,#11)); #3=IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#4=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#5=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.); #6=IFCSIUNIT(*,.SOLIDANGLEUNIT.,$,.STERADIAN.);
#7=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#8=IFCSIUNIT(*,.MASSUNIT.,$,.GRAM.); #9=IFCSIUNIT(*,.TIMEUNIT.,$,.SECOND.); #10=IFCSIUNIT(*,.THERMODYNAMICTEMPERATUREUNIT.,$,.DEGREE_CELSIUS.); #11=IFCSIUNIT(*,.LUMINOUSINTENSITYUNIT.,$,.LUMEN.);

Geometric representation contexts – “pojemniki” na obiekty modelu

Geometric representation contexts (określenie, które bardzo trudno, “niełamiąco” przetłumaczyć), to właściwie pojemniki na inne obiekty modelu. Jeden projekt może zawierać kilka kontekstów, np. 3D (“3” w #14) lub 2D (“2” w #17). Kontekst ma przyporządkowany układ współrzędnych (opisany za pomocą IfcAxis2Placement i odnoszący się do punktu w modelu) i deklarowaną dokładność (1.E-05).

#12=IFCCARTESIANPOINT((0.,0.,0.));
#13=IFCAXIS2PLACEMENT3D(#12,$,$);
#14=IFCGEOMETRICREPRESENTATIONCONTEXT($,’Model’,3,1.E-05,#13,$);

#15=IFCCARTESIANPOINT((0.,0.));
#16=IFCAXIS2PLACEMENT2D(#15,$);
#17=IFCGEOMETRICREPRESENTATIONCONTEXT($,’Plan’,2,1.E-05,#16,$);

“Umiejscowienie lokalne” i kierunki podstawowe

Następnie definiujemy instancje “umiejscowienia lokalnego”, do którego będziemy się odnosić podczas tworzenia elementów modelu. Zwróć uwagę, że IfcLocalPlacement odnosi się do uprzednio utworzonego IfcAxis2Placement3D (#13), który z kolei jest powiązany z punktem 0,0,0 (#12). Instancja IfcLocalPlacement jak i podstawowe kierunki (IfcDirection) są pomocne w późniejszym modelowaniu geometrii.

#18=IFCLOCALPLACEMENT($,#13);
#19=IFCDIRECTION((1.,0.,0.));
#20=IFCDIRECTION((0.,1.,0.));
#21=IFCDIRECTION((0.,0.,1.));

Hierarchia elementów przestrzennych

Następnie tworzymy hierarchię elementów przestrzennych. IfcFacility (#22) jest podstawowym elementem przestrzennym w naszym modelu. IfcRelAggregates iIfcRelContainedInSpatialStructure definiują zależności; pozwalają one na agregowanie jednych elementów w drugich. IfcRelAggregates o numerze #23 agreguje IfcFacility do IfcProject (#1) – można więc powiedzieć, że IfcProject zawiera IfcFacility. Następne elementy w przestrzennej hierarchii to IfcBridge (agregowany do IfcFacility) oraz IfcBridgePart (agregowany do IfcBridge).

Wiemy już, że klasy IFC mogą mieć różny typy atrybutów. Niektóre z atrybutów mogą przyjmować jedynie predefiniowane wartości. Są to tak zwane enumeratory. .GIRDER w IfcBridge czy .SUPERSTRUCTURE. (ustrój nośny) w IfcBridgePart są przykładami takich predefiniowanych wartości. Wartości te są częścią dokumentacji IFC (przykład: IfcBridgeTypePartEnum).

#22=IFCFACILITY(‘3eRo4UYs96VvgzHYlN5rwP’,$,’Facility’,$,$,$,$,$,$);
#23=IFCRELAGGREGATES(‘1zjaZZpoz2EwQTKxCE3dQj’,$,$,$,#1,(#22));
 
#24=IFCBRIDGE(‘2pyXrKuJX2hROBEU2KQ1rq’,$,’Bridge’,$,$,$,$,$,$,.GIRDER.);
#25=IFCRELCONTAINEDINSPATIALSTRUCTURE(‘2PeVAh2uH2phENraW6lvHj’,$,$,$,(#24),#22);
 
#26=IFCBRIDGEPART(‘2N8pyojwb4Bgw07KZBEF3O’,$,’Superstructure’,$,$,#36,#55,$,$,.USERDEFINED.,.SUPERSTRUCTURE.);
#27=IFCRELCONTAINEDINSPATIALSTRUCTURE(‘1LqnXVBdfEMwYGj9_UUshh’,$,$,$,(#26,#30),#24);

Materiał

Definiujemy materiał i łączymy go z ustrojemy nośnym za pomocą IfcRelAssociatesMaterial (odnosimy się do #26, czyli do IfcBridgePart reprezentującego ustrój nośny). Materiał to przykład obecnych w modelu danych semantycznych. Materiał, podobnie jak inne klasy, może mieć atrybuty (pominięte w tym przykładzie), co dodatkowo może zwiększyć nasycenie modelu danymi.

#28=IFCMATERIAL(‘Concrete’,$,$);
#29=IFCRELASSOCIATESMATERIAL(‘295_zxIQT9QBPS_FCpe59Y’,$,$,$,(#26),#28);

Niweleta

IfcAlignment, czyli jedna z kluczowych nowinek.

Umiejscowienie naszej niwelety odnosi się do punktu “0,0,0” (#18). Jej profil jest zdefiniowany poprzez IfcProductDefinitionShape (#35). Modelowanie profilu zaczynamy od IfcPolyline (#31) zawierającej dwa punkty (#32, #33). IfcShapeRepresentation (#34) wiąże IfcPolyline z IfcGeometricRepresentationContext (#14) i definiuje typ jej geometrii(“Curve3D”).

#30=IFCALIGNMENT(‘2eDu6iXCn6qfh2qIv8t0P2’,$,$,$,$,#18,#35,$);
#31=IFCPOLYLINE((#32,#33));
#32=IFCCARTESIANPOINT((0.,0.,0.));
#33=IFCCARTESIANPOINT((20000.,0.,400.));
#34=IFCSHAPEREPRESENTATION(#14,$,’Curve3D’,(#31));
#35=IFCPRODUCTDEFINITIONSHAPE(‘Alignment shape definition’,$,(#34));

Lokalizacja

Wcześniej utworzone IfcBridgePart (#26) zawiera odniesienie do lokalizacji (#36). Dokumentacja IFC daje kilka opcji na definiowanie lokalizacji elementów. Podstawowym jest lokalizacja w punkcie modelu (Opcja 1). Kolejne dwie możliwości również są oparte na punktach, ale w odniesieniu do niwelety. Opcja 2 wykorzystuje IfcPointOnCurve aby pobrać punkt na niwelecie. Opcja 3 wykorzystuje nową klasę, IfcPointByDistanceExpression, aby pobrać punkt w odniesieniu do niwelety z możliwością offsetu. Z kolei opcja 4 to nowy typ lokalizacji bazujących na krzywych (linear placement) – w tym przypadku, odnosząc się bezpośrednio do krzywej niwelety.

Co ważne – niestety, nie wszystkie przedstawione opcje są już zaimplementowane przez program do IFC, np. przeglądarki. Tak więc zdarza się, że pomimo prawidłowego zdefiniowania geometrii, przeglądarka może jej nie pokazać. Opcja 1, jako najstarsza, jest bezpieczną, szeroko obsługiwaną możliwością.

/* Opcja 1: Lokalizacja w punkcie modelu
#36=IFCLOCALPLACEMENT($,#37);
#37=IFCAXIS2PLACEMENT3D(#38,$,$);
#38=IFCCARTESIANPOINT((0.,0.,-80.));
 
/* Opcja 2: Lokalizacja w punkcie niwelety
#36=IFCLOCALPLACEMENT($,#37);
#37=IFCAXIS2PLACEMENT3D(#38,$,$);
#38=IFCPOINTONCURVE(#31,0.);
 
/* Opcja 3: Lokalizacja w punkcie w odniesieniu do niwelety
#36=IFCLOCALPLACEMENT($,#37);
#37=IFCAXIS2PLACEMENT3D(#38,$,$);
#38=IFCPOINTBYDISTANCEEXPRESSION(IFCNONNEGATIVELENGTHMEASURE(1000.),0.,-80.,0.,#31);
 
/* Opcja 4: Lokalizacja w odniesieniu do krzywej niwelety
#36=IFCLINEARPLACEMENT($,#37,$);
#37=IFCAXIS2PLACEMENTLINEAR(#38,$,$);

Przekrój poprzeczny ustroju nośnego

Przechodzimy do modelowania geometrii, zaczynając od przekroju poprzecznego ustroju nośnego. Przekroj poprzeczny (profil, #39) jest zdefiniowany poprzez zamkniętą polilinię (#40). Sama polilinia jest natomiast zdefiniowaną poprzez zbiór wierzchołków, czyli punktów (#41-#51)

#39=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#40);
#40=IFCPOLYLINE((#41,#42,#43,#44,#45,#46,#47,#48,#49,#50,#51,#41));
#41=IFCCARTESIANPOINT((0.,0.));
#42=IFCCARTESIANPOINT((-3800.,-76.));
#43=IFCCARTESIANPOINT((-6750.,-17.));
#44=IFCCARTESIANPOINT((-6750.,-237.));
#45=IFCCARTESIANPOINT((-4300.,-356.));
#46=IFCCARTESIANPOINT((-3900.,-1100.));
#47=IFCCARTESIANPOINT((3900.,-1100.));
#48=IFCCARTESIANPOINT((4300.,-356.));
#49=IFCCARTESIANPOINT((6750.,-237.));
#50=IFCCARTESIANPOINT((6750.,-17.));
#51=IFCCARTESIANPOINT((3800.,-76.));

Geometria ustroju nośnego

Ostatni krok do utworzenia geometrii.

IfcFixedReferenceSweptAreaSolid (#53) tworzy geometrię bryłową poprzez tzw. wyciąganie profilu wzdłuż krzywej; w naszym przykładzie, profil przekroju poprzecznego (#39) jest wyciągany wzdłuż krzywej niwelety (#31). Powstała bryła jest “opakowana” przez IfcShapeRepresentation (#54), która to jest “opakowana” przez IfcProductDefinitionShape. Te “opakowujące” klasy mogą być pomocne w agregowaniu większej ilości elementów do jednego – przykładowo, jeden element modelu (np. ustrój nośny) może być reprezentowany przez więcej geometrii. Utworzone wcześniej IfcBridgePart odnosi się do utworzonego na tym etapie IfcProductDefinitionShape w jednym ze swoich atrybutów, co wiąże ustrój nośny z jego geometrią.

#53=IFCFIXEDREFERENCESWEPTAREASOLID(#39,$,#31,$,$,$);
#54=IFCSHAPEREPRESENTATION(#14,’Body’,’SolidModel’,(#53));
#55=IFCPRODUCTDEFINITIONSHAPE(‘Superstructure shape definition’,$,(#54));

Bonus: zewnętrzne źródła danych

Utworzyliśmy klasy modelu IFC z hierarchią elementów oraz geometrią. Na obecnym etapie wdrażania IFC, są to zdecydowanie najczęściej używane funkcjonalności. Ale schemat IFC pozwala na zdecydowanie więcej. Na przykład na powiązanie modelu z zewnętrznymi źródłami danych.

Nasz przykład kończymy więc klasami wiążącymi nasz model z internetową bazą danych SHM za pomocą IfcPerformanceHistory, IfcLibraryInformation oraz klas “wiążących”, definiujących zależności.

#56=IFCPERFORMANCEHISTORY(‘2AKe$ZJ1bCxunXTKWapVSF’,$,
‘Superstructure performance history’,$,$,$,’OPERATION’,$);
#57=IFCRELAGGREGATES(‘0dSmTizeDBMREGS$lvAfsh’,$,$,$,#26,(#56));
#58=IFCLIBRARYINFORMATION(‘Superstructure performance database’,$,$,$,’
https://www.digitaltwin-database.com/0vGCH5MKb7IxXhcP$Yz3$a/2N8pyojwb4Bgw07KZBEF3O’,$);
#59=IFCRELASSOCIATESLIBRARY(’01mMvMoyvFJwH8aYXLKCjV’,$,$,$,(#56),#58);
 
ENDSEC;
END-ISO-10303-21;

Tak wygląda nasz prosty, ale kompletny, model IFC (wizualizacja w usBIM.viewer+):

Podsumowanie

Udało się – krok po kroku, utworzyliśmy “ręcznie” prosty, ale kompletny, model IFC.

Oczywiście, “ręczne pisanie” IFC na pierwszy rzut oka może być skomplikowane. Całkiem dobrze, że many do dyspozycji programy do modelowania, a nie tylko notatniki. Niemniej uważam, że warto wiedzieć co dzieje się “za kurtyną”. Dzięki temu jesteśmy bardziej świadomi. A IFC odgrywa coraz większa rolę.

#56=IFCPERFORMANCEHISTORY(‘2AKe$ZJ1bCxunXTKWapVSF’,$,
‘Superstructure performance history’,$,$,$,’OPERATION’,$);
#57=IFCRELAGGREGATES(‘0dSmTizeDBMREGS$lvAfsh’,$,$,$,#26,(#56));
#58=IFCLIBRARYINFORMATION(‘Superstructure performance database’,$,$,$,’
https://www.digitaltwin-database.com/0vGCH5MKb7IxXhcP$Yz3$a/2N8pyojwb4Bgw07KZBEF3O’,$);
#59=IFCRELASSOCIATESLIBRARY(’01mMvMoyvFJwH8aYXLKCjV’,$,$,$,(#56),#58);
 
ENDSEC;
END-ISO-10303-21;

Kompletny kod naszego modelu:

ISO-10303-21;  

HEADER;
FILE_DESCRIPTION ((”), ‘2;1’); FILE_NAME (‘Bridge model example’, ‘2024-10-14T17:42:13’, ‘Kamil Korus’, ‘AECO Evolution’, ‘Processor version’, ‘Software’, ”);
FILE_SCHEMA ((‘IFC4X3_ADD2’));
ENDSEC;
 
DATA;
#1=IFCPROJECT(‘0vGCH5MKb7IxXhcP$Yz3$a’,$,’Bridge project’,
‘This project is a simple example of modeling a bridge’,$,$,$,(#14,#17),#2);
 
#2=IFCUNITASSIGNMENT((#3,#4,#5,#6,#7,#8,#9,#10,#11));
#3=IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#4=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#5=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#6=IFCSIUNIT(*,.SOLIDANGLEUNIT.,$,.STERADIAN.);
#7=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#8=IFCSIUNIT(*,.MASSUNIT.,$,.GRAM.);
#9=IFCSIUNIT(*,.TIMEUNIT.,$,.SECOND.);
#10=IFCSIUNIT(*,.THERMODYNAMICTEMPERATUREUNIT.,$,.DEGREE_CELSIUS.);
#11=IFCSIUNIT(*,.LUMINOUSINTENSITYUNIT.,$,.LUMEN.);
 
#12=IFCCARTESIANPOINT((0.,0.,0.));
#13=IFCAXIS2PLACEMENT3D(#12,$,$);
#14=IFCGEOMETRICREPRESENTATIONCONTEXT($,’Model’,3,1.E-05,#13,$);
#15=IFCCARTESIANPOINT((0.,0.));
#16=IFCAXIS2PLACEMENT2D(#15,$);
#17=IFCGEOMETRICREPRESENTATIONCONTEXT($,’Plan’,2,1.E-05,#16,$);
 
#18=IFCLOCALPLACEMENT($,#13);
#19=IFCDIRECTION((1.,0.,0.));
#20=IFCDIRECTION((0.,1.,0.));
#21=IFCDIRECTION((0.,0.,1.));
 
#22=IFCFACILITY(‘3eRo4UYs96VvgzHYlN5rwP’,$,’Facility’,$,$,$,$,$,$);
#23=IFCRELAGGREGATES(‘1zjaZZpoz2EwQTKxCE3dQj’,$,$,$,#1,(#22));
 
#24=IFCBRIDGE(‘2pyXrKuJX2hROBEU2KQ1rq’,$,’Bridge’,$,$,$,$,$,$,.GIRDER.);
#25=IFCRELCONTAINEDINSPATIALSTRUCTURE(‘2PeVAh2uH2phENraW6lvHj’,$,$,$,(#24),#22);
 
#26=IFCBRIDGEPART(‘2N8pyojwb4Bgw07KZBEF3O’,$,’Superstructure’,$,$,#36,#55,$,$,.USERDEFINED.,
.SUPERSTRUCTURE.);
#27=IFCRELCONTAINEDINSPATIALSTRUCTURE(‘1LqnXVBdfEMwYGj9_UUshh’,$,$,$,(#26,#30),#24);
 
#28=IFCMATERIAL(‘Concrete’,$,$);
#29=IFCRELASSOCIATESMATERIAL(‘295_zxIQT9QBPS_FCpe59Y’,$,$,$,(#26),#28);
 
#30=IFCALIGNMENT(‘2eDu6iXCn6qfh2qIv8t0P2’,$,$,$,$,#18,#35,$);
#31=IFCPOLYLINE((#32,#33));
#32=IFCCARTESIANPOINT((0.,0.,0.));
#33=IFCCARTESIANPOINT((20000.,0.,400.));
#34=IFCSHAPEREPRESENTATION(#14,$,’Curve3D’,(#31));
#35=IFCPRODUCTDEFINITIONSHAPE(‘Alignment shape definition’,$,(#34));
 
#36=IFCLOCALPLACEMENT($,#37);
#37=IFCAXIS2PLACEMENT3D(#38,$,$);
#38=IFCCARTESIANPOINT((0.,0.,-80.));
 
#39=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#40);
#40=IFCPOLYLINE((#41,#42,#43,#44,#45,#46,#47,#48,#49,#50,#51,#41));
#41=IFCCARTESIANPOINT((0.,0.));
#42=IFCCARTESIANPOINT((-3800.,-76.));
#43=IFCCARTESIANPOINT((-6750.,-17.));
#44=IFCCARTESIANPOINT((-6750.,-237.));
#45=IFCCARTESIANPOINT((-4300.,-356.));
#46=IFCCARTESIANPOINT((-3900.,-1100.));
#47=IFCCARTESIANPOINT((3900.,-1100.));
#48=IFCCARTESIANPOINT((4300.,-356.));
#49=IFCCARTESIANPOINT((6750.,-237.));
#50=IFCCARTESIANPOINT((6750.,-17.));
#51=IFCCARTESIANPOINT((3800.,-76.));
 
#53=IFCFIXEDREFERENCESWEPTAREASOLID(#39,$,#31,$,$,$);
#54=IFCSHAPEREPRESENTATION(#14,’Body’,’SolidModel’,(#53));
#55=IFCPRODUCTDEFINITIONSHAPE(‘Superstructure shape definition’,$,(#54));
 
#56=IFCPERFORMANCEHISTORY(‘2AKe$ZJ1bCxunXTKWapVSF’,$,
‘Superstructure performance history’,$,$,$,’OPERATION’,$);
#57=IFCRELAGGREGATES(‘0dSmTizeDBMREGS$lvAfsh’,$,$,$,#26,(#56));
#58=IFCLIBRARYINFORMATION(‘Superstructure performance database’,$,$,$,
‘https://www.digitaltwin-database.com/0vGCH5MKb7IxXhcP$Yz3$a/2N8pyojwb4Bgw07KZBEF3O’,$);
#59=IFCRELASSOCIATESLIBRARY(’01mMvMoyvFJwH8aYXLKCjV’,$,$,$,(#56),#58);
 
ENDSEC;
END-ISO-10303-21;

Dziękuję za dołączenie do newslettera The AECO Evolution.

Thank you for joining The AECO Evolution Newsletter.

Chcesz być częścią cyfrowej transformacji branży AECO?

 

Dołącz do newslettera The AECO Evolution Newsletter by być na bieżąco.

Idee, koncepcje, wiadomości. Sztuczna inteligencja, cyfrowe bliźniaki, BIM, nowoczesne narzędzia.

Zawsze z myślą o praktyce.

 

pl_PL