Zliczanie sumarycznego pola powierzchni wielu pomieszczeń

Przy zaznaczeniu pojedynczego pomieszczenia w projekcie, Revit wyświetla w jego właściwościach m.in. pole powierzchni. Niestety zaznaczając kilka pomieszczeń nie jesteśmy w stanie w prosty sposób zsumować pól wybranych obiektów. Przynajmniej bez stworzenia specjalnego zestawienia. Zadaniem poniższego skryptu będzie dodanie tej funkcjonalności.

Dla porządku zacznijmy od tego, że będziemy korzystać w naszym kodzie z definicji obiektów Revitowych i muszą one zostać zaimportowane na początku pliku. Przy tworzeniu nowego modułu makr część z nich dodawana jest automatycznie, ale np. w obecnej wersji Revita 2017 moduł Autodesk.Revit.DB.Architecture jest domyślnie nieobecny. Będziemy go potrzebować z uwagi na to, że zawiera definicję obiektu Room. Dlatego upewnijmy się, że nagłówek naszego skryptu zawiera wszystkie poniższe linijki:

using System;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;

Następnie możemy przejść już do właściwego kodu. Zakładam, że skrypt zostanie odpalony po wybraniu przez użytkownika pomieszczeń. Stąd też na początku makra pobieramy do zmiennej aktywny (aktualnie otwarty) dokument Revitowy. Z niego wydobywamy aktualnie zaznaczone elementy i zapamiętujemy je w obiekcie typu Selection.

Document doc = this.ActiveUIDocument.Document;
UIDocument uiDoc = new UIDocument(doc);
Selection sel = uiDoc.Selection;

Każdy obiekt w pliku Revita oznaczony jest unikalnym numerem id. Znając takie id jesteśmy w stanie z dokumentu Revitowego uzyskać dostęp do żądanego elementu. Dlatego ze zmiennej zawierającego aktualne zaznaczenie obiektów pobieram numery id każdego z nich.

ICollection<ElementId> ids = sel.GetElementIds();

Definiuję pomocniczą zmienną, którą użyję do sumowania pól powierzchni.

double totalArea = 0f;

W kolejnym kawałku kodu wpierw sprawdzam czy moja lista id zaznaczeń nie jest pusta. Następnie dla każdego z elementów listy zapisuję jego id do tymczasowej zmiennej. Mając „w ręku” id elementu pobieram go z aktualnego dokumentu Revita (do zmiennej e typu Element). Sprawdzam czy jest pomieszczeniem (a nie np. ścianą czy dachem).
Jako że obiekt typu Element może być dowolnym Revitowym obiektem, nie zawiera w swojej definicji takiej właściwości jak pole powierzchni. W przypadku gdyby był np. balustradą albo linią Revit nie byłby w stanie z oczywistych względów podać takiej wartości. Jest to możliwe tylko dla niektórych typów obiektów, w tym właśnie pomieszczeń.
Sprawdziwszy uprzednio, że dany Element jest pomieszczeniem przekazuję go do zmiennej typu Room. Klasa Room zawiera w swoich właściwościach parametr powierzchni i mogę dodać jego wartość do zdefiniowanej wcześniej zmiennej.

if(0<ids.Count){
    foreach(ElementId id in ids) {
        Element e = doc.GetElement(id);
        if (e is Room) {
            Room r = e as Room;
            totalArea += r.Area;
        }
    }
}

W ten sposób zmienna totalArea zawiera zsumowane pola powierzchni wszystkich obiektów z zaznaczenia będących pomieszczeniami. Dalej pozostaje nam już tylko przeliczenie jednostek na metry kwadratowe (Revit używa wewnętrznie stóp), zaokrąglenie wartości do dwóch miejsc po przecinku oraz wyświetlenie końcowej informacji.

double METERS_IN_FEET = 0.3048;           
totalArea = totalArea * Math.Pow(METERS_IN_FEET,2);
totalArea = Math.Round(totalArea,2);           
TaskDialog.Show("Suma powierzchni", "Sumaryczna powierzchnia : " + totalArea + "m²");

Całość kodu funkcji wygląda tak:

public void roomArea() {
           
    Document doc = this.ActiveUIDocument.Document;
    UIDocument uiDoc = new UIDocument(doc);
           
    Selection sel = uiDoc.Selection;
           
    ICollection<ElementId> ids = sel.GetElementIds();
           
    double totalArea = 0f;
           
    if(0<ids.Count){
        foreach(ElementId id in ids) {
            Element e = doc.GetElement(id);
            if (e is Room) {
                Room r = e as Room;
                totalArea += r.Area;
            }
        }
    }
           
    double METERS_IN_FEET = 0.3048;
           
    totalArea = totalArea * Math.Pow(METERS_IN_FEET,2);
    totalArea = Math.Round(totalArea,2);
           
    TaskDialog.Show("Suma powierzchni", "Sumaryczna powierzchnia : " + totalArea + "m²");
} 
Posts created 32

3 thoughts on “Zliczanie sumarycznego pola powierzchni wielu pomieszczeń

  1. Witam, brzmi to rewelacyjnie bardzo chciałabym zastosować to u siebie w programie , ale niestety nie wiem jak można to zaadoptować do projektu. proszę o pomoc

  2. Proszę spojrzeć na pierwszy post bloga, w którym pokazano jak dodawać własne makra w Revicie.
    https://bim-bb.blogspot.com/2016/10/tworzenie-makr.html

    W miejsce funkcji pierwszeMakro należy wstawić powyższy kod funkcji roomArea.
    Prawdopodobnie po wklejeniu trzeba jeszcze wcisnąć klawisz F8, aby "przekompilować" kod.

    Następnie po uprzednim zaznaczeniu Room'ów w projekice wybieramy z zakładki Manage polecenie Macro Manager.
    Tam odnajdujemy naszą funkcę roomArea i klikamy Run.

    Wtedy powinna zostać wyświetlona sumaryczna powierzchnia wybranych pomieszczeń.

Dodaj komentarz

Twój adres email nie zostanie opublikowany.

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top