Dynamo is een fantastische tool en je kunt er op eenvoudige wijze tientallen objecten aanpassen of maken. Veel nodes werken met lijsten als invoer, en zolang je lijsten met evenveel elementen invoert, gaat het altijd goed. Een lijst met honderd lagen aanpassen met een lijst met honderd kleuren, geen probleem. En Dynamo is zelf ook slim genoeg om honderd lagen met één kleur te verwerken, in dat geval wordt die enkele kleur toegepast op alle elementen in de lagen-lijst. Maar als je honderd lagen aan wilt passen met tien kleuren, dan worden normaal gesproken alleen de eerste tien lagen aangepast. Dit kun je manipuleren door te werken met List Lacing, als je dat wilt natuurlijk.
Maar wat als je lijsten binnen lijsten hebt? Bijvoorbeeld een lijst met daarin drie lijsten met elk een handvol lagen? En die wil je combineren met een lijst met drie kleuren? Het niveau van beide collecties is niet gelijk, de kleuren-lijst is maar twee niveaus diep en de lagen-lijst is drie niveaus diep. Je zult hier moeten gaan werken met Levels.
Levels, of niveaus
Stel dat je wat waarden bij elkaar op wilt tellen, een eenvoudig voorbeeld dus. Je hebt drie verzamelingen van numerieke waarden en alledrie moeten opgehoogd worden met een bepaald getal. Verzin hier zelf maar een real-world situatie bij. In Dynamo gaat het nu even om de theorie.
Een lijst met drie waarden maak je eenvoudig met een Code Block, of met drie Number nodes en een List.Create. Ik geef de voorkeur aan een Code Block. Als je die eenmaal gebruikt hebt dan moet je oppassen dat je niet je hele graph in één Code Block schrijft, zo verslavend is het.
Aan de linkerkant zie je hoe je met de beschikbare nodes een lijst genereert, aan de rechterkant hetzelfde maar dan in één simpel Code Block. De syntax van een lijst is het gebruiken van blokhaken en elke waarde gescheiden met een komma. Voor de leesbaarheid mag alles op een eigen regel maar het staat je ook vrij om het op één regel te typen:
[7.5,4.3,9.1];
Dit levert hetzelfde resultaat maar is wat lastiger te lezen.
Hetzelfde geldt voor drie lijsten met een serie nummers. Je kunt Ranges bouwen en combineren, maar ook alles in één Code Block uitwerken. Dan is elke waarde in de lijst weer een nieuwe lijst (of een Range, die een lijst oplevert).
Beide methodes leveren hetzelfde resultaat.
Kijk je nu naar de niveaus, of levels, van het resultaat, dan zie je onderaan bij de drie enkele nummers:
@2 @1
En bij de ranges zie je dit:
@3 @2 @1
Dat wil zeggen dat de ene lijst 2 levels diep is en de ander 3 levels. Vaak kun je zulke lijsten niet met elkaar combineren, maar soms gaat het op magische wijze wel goed. Als je de + node gebruikt om de waarden bij elkaar op te tellen, dan zal Dynamo de eerste waarde uit de lijst combineren met de eerste range uit de andere lijst.
Dynamo is slim genoeg om te zien dat je drie losse waarden wilt combineren met drie lijsten met getallen. Maar als je lijsten evenlang zijn met evenveel levels, maar niet evenveel waarden bevatten, dan gaat het niet zomaar goed.
Beide lijsten zijn evenlang, bevatten allebei drie lijsten met waarden. Je zou verwachten dat de lijst met de waarde 7.5 wordt toegepast op de lijst met waarden van de range 1 t/m 10. Feitelijk gebeurt het ook, maar anders dan je verwacht.
Als je een enkele waarde combineert met een lijst, dan wordt die enkele waarde toegepast op alle waarden uit de lijst. Maar in dit geval gebruik je niet een enkele waarde, maar een lijst met één waarde.
En een lijst met één waarde combineren met een lijst met tien waarden, zorgt ervoor dat alleen het eerste element wordt aangepast. Kan dit anders?
Hier kun je het probleem verhelpen door naar een level van de lijst te verwijzen. Normaal gesproken werkt Dynamo de lijst van links naar rechts af. In dit geval bestaan beide lijsten uit 3 levels, dus vanaf level 3 worden de lijsten vergeleken en verwerkt.
Klik eerst op het pijltje, en vink vervolgens aan dat je Levels wilt toepassen. Vervolgens kun je met de up en down pijltjes het niveau instellen. Stel deze in op level 2, om aan te geven dat Dynamo voor die invoerpoort moet beginnen op level 2 in plaats van level 3. De andere poort laat je voor wat het is. Zo (slim bedacht) reduceer je de lijst met drie getallen weer tot 2 levels, wat in het vorige voorbeeld ook goed ging.
Nu krijg je keurig drie lijsten met elk 10 waarden en zo op het oog netjes opgehoogd met de drie losse waarden. Maar gaat het goed? Uiteraard check je alles want Dynamo doet precies wat je hem vertelt en niet meer dan dat. Bij een check zie je dat de drie losse waarden allemaal zijn toegepast op alleen de eerste range. En dat was niet de bedoeling, waarde 1 hoort bij range 1, waarde 2 bij range 2, enzovoort. Door de kortste lijst te reduceren, heb je een denkfout gemaakt. Het reduceren gaat namelijk vanaf de linkerkant, terwijl in dit geval aan de rechterkant de drie getallen waren omgezet naar drie lijsten met één waarde.
Met wat nadenken kom je erachter dat je eigenlijk de enkele waarden op level 1 wilt combineren met de drie lijsten op level 2. En als je dat doet, dan gaat het goed.
Het lijkt wat hocuspocus, maar het werkt in principe precies zoals je het wilt instellen. Het is alleen best complex om zo abstract te moeten kijken naar lijsten, voorals als zoals in dit geval beide lijsten evenlang zijn.
Alternatieven
Er zijn ook alternatieven die eenvoudiger zijn, of in ieder geval de level instelling niet nodig hebben. Zo kun je lijsten genereren die op alle niveaus evenlang zijn, voordat je ze combineert. Bijvoorbeeld een lijst genereren met exact dezelfde waarden, evenlang als de lijst waarmee je het wilt combineren:
Je kunt de lijst met 3 waarden ook plat slaan, zodat je niet drie lijsten met 1 waarde krijgt maar 1 lijst met 3 waarden. Zo reduceer je de lijsten vanaf de rechterkant, en krijg je weer het resultaat wat het in het begin was.
Of je haalt de enkele waarde uit de eerste lijst door te verwijzen naar de index. Dit wordt al wat complexer:
Je verwerkt hier overigens alleen de eerste items in beide lijsten (index 0 is de eerste, index 1, de tweede, enzovoort). En van het eerste item de korte lijst gebruik je vervolgens het eerste item (de waarde 7.5). Je ziet hier juist goed dat de korte lijst dieper wordt bevraagd dan de lange lijst.
Werken met levels is erg complex, en vooral een kwestie van veel proberen (en checken!). Je kunt je er al snel in verliezen, dus zodra je het overzicht kwijt bent dan kun je beter even een stapje terug doen. Denk vooral na over alternatieven. Vooral de node List.OfRepeatedItem is een zeer goed alternatief om lijsten evenlang te maken.
Wil je complexe of repetitieve taken automatiseren in Civil 3D? Dit boek helpt je alles te leren over de design automating tool Dynamo voor Civil 3D. Je wordt een professional in visueel programmeren, en binnenkort zijn al je saaie of complexe taken geautomatiseerd!
This book is only available in English.