úterý 29. listopadu 2016

DYNAMO PLAYER: podlahová plocha místnosti; UPDATE 03.01.2017

V dnešním článku se zaměříme opět na vizuální programovací nástroj Dynamo a pokusíme se pomocí tohoto nástroje vyřešit problém spojený s vykazováním podlahové plochy místnosti. Pokročilí uživatelé Revitu pravděpodobně tuší o čem bude řeč - jde o to, že objekt místnosti je systémově naprogramován tak, aby po osazení do půdorysu generoval užitnou plochu daného prostoru, tzn., že nezapočítává výklenky jako niky vzniklé zapuštěním oken a dveří atd. Viz obrázek:


Na obrázku je patrné, že objekt místnosti skutečně generuje plochu podle hrany stěn, které ohraničují prostor místnosti, ale nezapočítává plochy vzniklé zapuštěním dveří do stěny, tedy tam, kde ve skutečnosti bude zrealizována podlahová krytina. Viz červené otazníky na obrázku. A právě zde je důležité si uvědomit, že plocha, se kterou počítám v tabulce místností, je právě užitná plocha a ne podlahová plocha, se kterou pracují rozpočtáři. V počátečních fázích projektu, jako DUR nebo DSP, to takový problém nejspíš nebude, ale v pozdějších fázích projektu, kdy se již generují výkazy a data přecházejí např. na realizační firmy, je nutné tento problém konstruktivně vyřešit.



Revit standardně nabízí řešení této problematiky přes nástroje Plocha, kdy tento nástroj vytvoří duplikát z daného půdorysu a umožní uživateli si pomocí náčrtu objet prostor místnosti podle potřeby a zahrnout i výklenky a niky. Toto řešení je samozřejmě funkční, ale tak nějak napůl. Jde o to, že nástroj Místnost a Plocha sdílí stejný systémový parametr, který nemůže figurovat v jednom výkazu, např. v tabulce místností. Tento pracovní postup se zdá být značně těžkopádný, jelikož nutí uživatele si vytvořit duplikát daného půdorysu a pracovat se dvěma výkazy zvlášť.

Daný problém řeší až vizuální programovací nástroj Dynamo, který pro generování podlahové plochy může využít komponentu Podlaha. Tato komponenta se vytváří přes náčrt stejně jako nástroj plocha, s tím rozdílem, že není nutné vytvářet duplikát daného půdorysu a vygenerovanou plochu podlahy lze jednoduše zaimplementovat do objektu místnosti a následně zahrnout do výkazu.

Než si nastartujeme Dynamo, je nutné si připravit testovací půdorys o libovolném počtu místností, ve kterých budou figurovat výklenky, niky atd. Do vzniklé dispozice si vložíme místnosti v náhodném pořadí a následně si pomocí náčrtu vytvoříme podlahy, které budou zohledňovat i výklenky, niky a zapuštěné dveře či okna.

V další fázi si vytvoříme sdílený parametr, který nazveme Podlahová plocha, a typ parametru musí být Plocha, jelikož do tohoto parametru budeme zapisovat hodnotu v metrech čtverečních. Následně daný parametr musíme zaimplementovat do projektu respektive do kategorie místností přes nástroj Parametry projektu. Daný parametr vytvoříme jako parametr Instance a zařadíme ho do skupiny Rozměry. Po označení libovolné místnosti by se měl parametr zobrazovat ve vlastnostech dané místnosti, Viz obrázek. Tento sdílený parametr také zaimplementujeme do popisky místností.

Další sdílený parametr, který je nutné vytvořit, je parametr Číslo místnosti. Tento parametr vytvoříme jako parametr Text a stejně jako v předchozím případě ho musíme zaimplementovat do projektu přes nástroj Parametry projektu. Parametr musí figurovat v projektu jako parametr Instance a zařadíme ho do skupiny Vazby. Po označení libovolné podlahy by se měl parametr zobrazovat ve vlastnostech dané podlahy, viz obrázek. Tento parametr nám pomůže seřadit podlahy, respektive jejich podlahové plochy k odpovídajícím místnostem.

Nyní už máme vše připravené a můžeme si nastartovat programovací nástroj Dynamo. Pro sestavení algoritmu je nutné si stáhnout nejaktuálnější verzi Dynama 1.2.1 ze stránek vývojového týmu.

V minulých článcích jsme si k jednotlivým uzlům uváděli přesnou cestu, dnes bychom si popsali rychlejší způsob vkládání uzlů do grafu. Při kliknutí pravého tlačítka myši do plochy grafu se zpřístupní vyhledávací konzole, do které lze zadat přesný název hledaného uzlu. První část algoritmu sestavíme z následujících uzlů:

1.)  Categories: Tento uzel umožňuje vybrat danou kategorii, kterou chceme načíst do prostředí Dynama. V našem případě si vybereme kategorii Místnosti.
2.)  All Elements of Category: Tento uzel načte všechny elementy zvolené kategorie.
3.)  SortByFuncion: Tento uzel umožní seřadit položky v seznamu podle nadefinované funkce.
4.)  Element.GetParameterValueByName: Tento parametr umožní získat hodnotu parametru z daného prvku, v našem případě poslouží jako funkce pro uzel SortByFuncion.
5.)  Code Block: Do grafu si ještě zaneseme uzel Code Block, který vyvoláme pro změnu dvojklikem levého tlačítka myši do plochy grafu. Do daného uzlu zapíšeme název parametru, podle kterého budeme řadit jednotlivé místnosti a tím je parametr „Číslo“. Pokud používáte uzel Code Block a zapisujete do něj textovou hodnotu, je nutné, aby tato hodnota byla v „uvozovkách“.

Výše zmíněné uzly spolu propojíme a přes zkratku ctrl+g uložíme do jedné skupiny, kterou nazveme Načtení všech místností z projektu a seřazení dle čísla místnosti. 


Následně si vytvoříme další skupinu, kterou si nazveme Načtení všech podlah z projektu a seřazení dle čísla místnosti, tuto skupinu budou tvořit stejné uzly jako v předchozí skupině, jen s tím rozdílem, že v uzlu Categories vybereme kategorii Podlahy a do uzlu Code Block zapíšeme hodnotu „Číslo místnosti“.












V další části si vytvoříme algoritmus, který nám pomůže vyfiltrovat podlahy, které nereprezentují skladby podlah v místnostech jako např. stropní desky, střešní plášť apod. Daný algoritmus obsahuje následující uzly:

6.)  Element.GetParameterValueByName: Tento parametr umožní získat hodnotu parametru z daného prvku, v našem případě budeme získávat hodnotu z parametru Číslo místnosti.
7.)  Code Block: Do daného uzlu zapíšeme název parametru Číslo místnosti a propojíme s uzlem Element.GetParameterValueByName.
8.)  List.UniqueItems: Tento uzel vytvoří nový seznam obsahující jedinečné položky ze seznamu, který generuje uzel Element.GetParameterValueByName. Podlahy, které nemají vyplněný parametr Číslo místnosti jako základové či stropní desky budou jednoduše vyfiltrovány daným uzlem. V novém seznamu se vždy na prvním indexu vytvoří prázdná hodnota, kterou je potřeba odstranit, proto si do grafu zaneseme následující uzel:
9.)  List.RestOfItems: Daný uzel odebere první položky z daného seznamu.
10.)  Count: Do grafu si zaneseme dva uzly Count, kdy jeden propojíme na přímo s uzlem SortByFunction ze skupiny Načtení všech podlah z projektu a seřazení dle čísla místnosti a druhy uzel propojíme s uzlem List.RestOfItems. Tuto operaci provádíme proto, abychom si vytvořili masku filtru, pomocí které vyfiltrujeme elementy podlah, které nereprezentují skladby podlah.
11.)  Operator - : Daný uzel vypočítá rozdíl mezi dvěma hodnotami. Tento uzel propojíme s uzly Count.
12.)  List.Cycle: Tento uzel vytvoří nový seznam zřetězením vstupní hodnoty.
13.)  Code Block: Do daného uzlu zapíšeme hodnotu „“, která reprezentuje prázdný index. Tento uzel propojíme s uzlem List.Cycle.
14.)  Code Block: Do daného uzlu zapíšeme např. hodnotu „!“, v tomto případě lze použít jakýkoliv symbol, u kterého je nepravděpodobné, že se bude vyskytovat v názvu místnosti.
15.)  String.Contains: Do grafu si zaneseme dva uzly String.Contains. Tento uzel určuje, zdali zadaný řetězec obsahuje daný dílčí řetězec. Jeden uzel propojíme s uzly z bodů 6.) a 12.) a druhy uzel propojíme s uzly z bodů 9.) a 14.). Výstupem daných uzlů je hodnota boolean (true, false).
16.)  List.Join: Tento uzel zřetězí všechny dané seznamy do jednoho seznamu, v našem případě chceme zřetězit hodnoty z uzlů String.Contains.
17.)  List.FilterByBoolMask: Tento uzel umožní vyfiltrovat elementy, které definuje maska filtru. V našem případě je maska filtru definována uzlem List.Join a seznam elementu definuje uzel SortByFunction ze skupiny Načtení všech podlah z projektu a seřazení dle čísla místnosti.
Propojené uzly sloučíme do skupiny, kterou si nazveme Vyfiltrování podlah, které nereprezentují skladby podlah. Algoritmus by měl mít tuto podobu:










V dalším kroku si vytvoříme algoritmus, který nám bude filtrovat místnosti podle počtu podlah, které mají nadefinovaný parametr Číslo místnosti. Pro správnou funkčnost algoritmu je nutné, aby počet místností vždy seděl s počtem přiřazených podlah. Pokud uživatel nadefinuje pouze tři podlahy z pěti, je nutné, aby počet místností v seznamu také klesl z pěti na tři.

18.)  Element.GetParameterValueByName: Tento parametr umožní získat hodnotu parametru z daného prvku, v našem případě budeme získávat hodnotu z parametru „Číslo místnosti“. Daný uzel propojíme s uzlem List.FilterByBoolMask ze skupiny Vyfiltrování podlah, které nereprezentují skladby podlah.
19.)  Code Block: Do daného uzlu zapíšeme název parametru „Číslo místnosti“ a propojíme s uzlem Element.GetParameterValueByName.
20.)  Element.GetParameterValueByName: Tento parametr umožní získat hodnotu parametru z daného prvku, v našem případě budeme získávat hodnotu z parametru „Číslo“. Daný uzel propojíme s uzlem SortByFunction ze skupiny Načtení všech místností z projektu a seřazení dle čísla místnosti.
21.)  Code Block: Do daného uzlu zapíšeme název parametru „Číslo“ a propojíme s uzlem z bodu 20.).
22.)  List.ContainsItem: Tento uzel určuje, zdali daný seznam obsahuje danou položku. Do vstupu List propojíme uzel z bodu 18.) a do vstupu Item propojíme uzel z bodu 20.).
23.)  List.FilterByBoolMask: Tento uzel umožní vyfiltrovat elementy, které definuje maska filtru. V našem případě je maska filtru definována uzlem List.ContainsItem a seznam elementu definuje uzel SortByFunction ze skupiny Načtení všech místností z projektu a seřazení dle čísla místnosti.
Propojené uzly sloučíme do skupiny, kterou si nazveme Vyfiltrování místností. Algoritmus by měl mít tuto podobu:





Dalším algoritmem, který potřebujeme zasadit do našeho grafu, je algoritmus, který nám vyselektuje jednotlivé podlahové plochy, které nám generují komponenty podlahy.

22.)  Element.GetParameterValueByName: Tento uzel získá hodnoty z nadefinovaného parametru. V našem případě se bude jednat o parametr Plocha. Do vstupu parameterName je nutné připojit uzel, do kterého můžeme vepsat název parametru.
23.)  Code Block: Do uzlu vepíšeme textovou hodnotu Plocha, která musí být v uvozovkách a daný uzel propojíme se vstupem parameterName uzlu Element.GetParameterValueByName.
24.)  Math.Round: Tento uzel zaokrouhluje hodnoty směrem nahoru. U vstupu digits, lze nastavit, nakolik desetinných míst se bude zaokrouhlovat, proto do grafu vložíme ještě jeden uzel:
25.)  Code Block: Do uzlu vepíšeme hodnotu 2, tato hodnota nám bude definovat počet desetinných míst u zaokrouhlování.

Tento algoritmus si uložíme do skupiny, kterou si nazveme Získání podlahové plochy a její následné zaokrouhlení. Algoritmu má tuto podobu:










Poslední algoritmus, který musíme vytvořit je založený pouze na dvou uzlech, a jsou to tyto dva:

26.)  Element.SetParameterByName: Tento uzel umožní zapsat plochu, kterou jsme získali z komponent podlah do námi vytvořeného sdíleného parametru Podlahová plocha, který jsme zaimplementovali v projektu do kategorie místnosti.
27.)  Code Block: Do uzlu zapíšeme textovou hodnotu, respektive název sdíleného parametru, tedy Podlahová plocha. Hodnota musí být v uvozovkách.

Oba uzly si sloučíme do skupiny a nezveme si ji Zápis hodnot do parametru „Podlahová plocha“. Algoritmu by měl mít tuto podobu:












Propojený algoritmus by měl mít tuto podobu:










Algoritmus funguje automaticky, tzn., lze spouštět napřímo z funkce Dynamo Player. Tato funkce se Vám zpřístupní až po instalaci nejnovějšího updatu na Revit 2017.1















Videoukázka:



DYN soubor ke stažení na www.cadstudio.cz/freeware

8 komentářů:

  1. Dobrá práce, jen praxe je trochu jiná. Pro niky to funguje dobře, u dveří je ve většině případů podlaha (finiš) zatažena pod dveře, na ní práh apod, takže nejde použít plochu podlahové krytiny jako to co chce klient vykázat jako podlažní plochu místnosti. Ale je to velké přiblížení.

    OdpovědětVymazat
  2. Neviem, kde robím chybu, ale mne daný algoritmus po spustení vykazuje zlé plochy. Napr. plocha 45m2 po spustení 8,5m2. Nevie co robím zle. Dakujem

    OdpovědětVymazat
    Odpovědi
    1. Podle toho jaký rozptyl mají obě plochy bych usoudil, že máte chybu někde mezi body 9. - 21., to je část, kdy ořezový kvádr detekuje vytvořené body z těžiště podlah a následně seřadí podlahy podle čísla místností, tím dojde ke správnému spárování. Zaměřte se na body 18. a 19., tedy na správné propojení uzlů List.Map, to je nejnáročnější pasáž na pochopení z celého algoritmu.

      Vymazat
    2. Dobrý deň, opäť mám problém po spustení daného algoritmu v rozpracovanom projekte. Podlahy mám vymodelované správne, no po spustení opäť vyčísľuje nezmyselné plochy. V bode BoundingBox bool - to List.Map f(x) vypíše list False (370). Viete mi poradiť? Ďakujem

      Vymazat
    3. Dobrý den, daný model bych potřeboval vidět, myslíte, že byste mi ho mohl zaslat k otestování? Pokud ano, tak na emailovou adresu: lukas.tunka@cadstudio.cz

      Vymazat
    4. Do algoritmu je nutné přidat filtr, který vyselektuje pouze podlahy, které reprezentují skladby podlah. Dále tam z nějakého nepochopitelného důvodu Dynamo detekuje více místností, než tam skutečně je a to způsobuje špatné párování místností s podlahami. Zítra zkusím daný problém vyladit.

      Vymazat
  3. Ďakujem. Už viem,kde som spravil chybu. Pri výbere jednej plochy som vybral (obtiahol) dve miestnosti. Na základe daného si vieme upraviť podlahovú plochu aj pod dverný prah.(dôležitá je plocha - objem materiálov pod prahom). Finálna podlaha sa aj tak počíta so stratným (rezervou). Ešte raz ďakujem.

    OdpovědětVymazat
  4. Dobrý den, byla provedena aktualizace článku.

    OdpovědětVymazat