Niedawno na Poradniku Inżyniera poruszaliśmy temat dodawania parametru do pliku IFC. Podany przykład sprawdza się, jeżeli mamy do obróbki kilka elementów lub mały model. Co się stanie, gdy musimy dodać, zmienić lub odczytać parametry z modelu, który ma 200 tys. instancji? Prawdopodobnie strasznie się napracujemy. Oczywiście możemy zlecić tą pracę dla pracownika mniej doświadczonego w celu jego edukacji lub sięgnąć po bardziej wykwintne metody.
C# przybądź na ratunek
Na nasze szczęście mamy szanse na optymalizację pracy przy użyciu C#. Oczywiście nie będziemy parsowali pliku IFC w sposób jawny. Do tego celu posłużymy się zgodną z zasadami open xbimToolkit. Jest to bardzo potężne narzędzie, które możemy zastosować do wielu projektów, np.: łączenia plików, edycji parametrów, dodawania obiektów, parametrów, tworzenia zestawień, usuwania elementów z modelu lub podmianki elementów i wielu innych. Ogromną zaletą biblioteki jest ciągły jej rozwój oraz wieloplanowość.
Koniec gadania siadamy do programowania
Nie miałem zamiaru rymować i mam nadzieję, że nikogo tym nie zraziłem :). Masowe dodawanie parametru do IFC rozpoczynamy klasycznie od stworzenia projektu w Visual Studio Communit. Na początek wystarczy nam aplikacja konsolowa. Możesz zrobić jednak dowolny projekt Forms lub WPF, a nawet ASP – więc programuj tak, jak lubisz. Jeżeli ten etap mamy za sobą musimy załadować bibliotekę xbimToolkit. W tym celu posłużymy się narzędziem Nuget Packet Manager. Narzędzie dostępne jest z poziomu inspektora obiektów, wybieramy więc „Manage NuGet Package for Solution” tak, jak na obrazku poniżej.
Teraz przechodzimy na zakładkę „Browser”, a w wyszukiwarkę wpisujemy xbim.Essentials i klikamy enter. Instalację rozpoczynamy przez kliknięcie w pakiet (1), a następnie w przycisk Install (2).
Teraz nasze środowisko jest gotowe, możemy zapoznać się z manuałem do biblioteki. Polecam ze swojej strony Githuba projektu. Pamiętajmy jednak, że projekt mocno się rozwija, więc być może w roku 2021 lub 2022, to co czytasz będzie nieaktualne. Zachęcam do śledzenia strony projektu xBimToolkit.
Pierwsza funkcja
Wcale nie jest regułą, że pierwszym elementem kursu musi być popularne „Hello World”. Rozpoczynamy od dodania nowego parametru dla wszystkich instancji w naszym modelu – czyli z grubej rury! Zanim jednak ruszymy zamodelujmy jakiś budynek. Ja do testów posłużę się modelem z poprzedniego poradnika. Z czystego lenistwa wrzucę go do folderu kompilacji „.\bin\Debug”, dzięki temu będę miał łatwiejszy dostęp do mojego pliku „Sample.ifc”.
static void Main(string[] args) { //Ścieżka do pliku ifc const string fileName = "Sample.ifc"; //Otwieranie pliku using (var model = IfcStore.Open(fileName)) { //Pobieranie wszystkich elementów pliku ifc (parametry, kolory, obiekty 3d itp...) var allInstances = model.Instances; var errors = new List<string>(); // Tu wylistujemy błedy foreach (var item in allInstances) //Główna pętla iteracji { var myObject = item as IfcObject; //Próba rzutowania obiektu if (myObject == null) //Jeżeli nie da się rzutwoać na obiekt 3D to pomiń itereację. continue; using (var txn = model.BeginTransaction()) //Rozpoczęcie transakcji zmien { try // na wszelki wypadek { //Tworzenie parametru tekstowego var pSetRel1 = model.Instances.New<Xbim.Ifc2x3.Kernel.IfcRelDefinesByProperties>(r => { r.RelatingPropertyDefinition = model.Instances.New<Xbim.Ifc2x3.Kernel.IfcPropertySet>(pSet => { pSet.Name = "PORADNIK INŻYNIERA"; pSet.HasProperties.Add(model.Instances.New<IfcPropertySingleValue>(p => { p.Name = "OPIS ARTYKUŁU"; p.NominalValue = new IfcText("Artykuł o obiektach BIM."); })); }); }); //Tworzenie parametru tekstowego var pSetRel2 = model.Instances.New<Xbim.Ifc2x3.Kernel.IfcRelDefinesByProperties>(r => { r.RelatingPropertyDefinition = model.Instances.New<Xbim.Ifc2x3.Kernel.IfcPropertySet>(pSet => { pSet.Name = "PORADNIK INŻYNIERA"; pSet.HasProperties.Add(model.Instances.New<IfcPropertySingleValue>(p => { p.Name = "ARTYKUŁ"; p.NominalValue = new IfcText("https://poradnikinzyniera.pl/co-to-jest-obiekt-bim-i-czym-sie-charakteryzuje/"); })); }); }); pSetRel1.RelatedObjects.Add(myObject); //dodanie relacji obiekt--parametr 1 pSetRel2.RelatedObjects.Add(myObject); //dodanie relacji obiekt--parametr 2 } catch (Exception ex) { errors.Add(ex.Message); } txn.Commit(); //Zakończenie transakcji zmien } } if (errors.Any()) Console.WriteLine("Wystąpiły błedy! Możesz je wylistować jeśli chcesz."); model.SaveAs("Sample_NOWY.ifc"); //Nowy plik } }
Teraz testujemy aplikację, w tym celu przyciśnij „DEBUG”, jeżeli nie mamy błędów to jest to znak, że udało się nam dodać nowy parametr! Możemy więc wyświetlić efekty naszej pracy.
Podsumowanie
Wykorzystaliśmy ułamek możliwości biblioteki, a efekty są zdumiewające. Nie ma chyba nic lepszego niż automatyzacja pracy przy użyciu języków programowania, natomiast masowe dodawanie parametru IFC nie byłoby możliwe bez wykorzystania tej technologii. Zachęcam czytelników do wypróbowania biblioteki oraz wrzucania pomysłów na kolejny algorytm.