Acoustamo Released!

You can download it from the package manager…


…or from this page (with tutorial):

How it works (version 0.0.1 – raytrace)

First you need to select your source as Point. This represents the points where the rays are generated. Each ray is a Vector type. So you can generate any vector list, or use the following nodes:



which generates random rays on a portion of a spherical surface. We can control the horizontal and vertical opening angles.

rs - direction



which generates a list of Vectors targeting a Surface. It is useful for evaluating acoustic panels. The source is the source Point, Number U and V are ne numbers of subdivision of the surface, surface is the targeting surface and tolerance is a offset parameter from the edge.

dr - direction

Once the starting rays direction are generated and the geometry is modelled / imported from revit as list of surfaces, we can run the simulation:



The solver inputs all the bouce surfaces as list of Surfaces, a single source as Point, the starting rays direction as Vectors and the max number of bounces. It outputs a list of PolyCurve, each one starting from the source, following the starting rays direction and all the bounces on the model.


Have fun!


Acustamo “Designed by the Sound” AU Dynamo Hackathon Competition 1st place

Project Entry

DynamoBIM blog:

Project Intent

We set out to design an acoustic performance space that can self-adapt to a certain sound requirements.

Traditionally, during the conceptual design stage, the designer has to make assumptions about what the shape needs to be to satisfy a defined performance. The initial design can change drastically after this stage, and this approach is described as top-down. Using Dynamo and Optimo, it is possible to reverse this and create a bottom-up process. Once the constraints and the performance requirements are defined, the machine evolves the solution. The designer can then accept or refuse the results, which could range from fairly obvious to innovative.

Raytrace and Visual Programming

The missing link in our project was the simulation algorithm. Acoustics are complicated and, in order to be assessed, they need complicated analysis and validation tests. However, the raytrace algorithm is appropriate for concept design purposes. Because we are concentrating on the geometry and in particular on reflectors design, the material property is not included.

Dynamo has its own raytrace, but it is limited because it is performed inside Revit and communication takes more time than it would in Dynamo, and it cannot be part of a loop. Due to those constraints we decided to implement a simple raytrace algorithm in Dynamo. Our first step was visual programming. Dynamo is makes it exceptionally easy to prototype algorithms. The main algorithm is:

  • For each ray:
    • start from a point source with a starting direction vector
    • draw a line which intersects all the surfaces
    • select the closest surface intersected
    • calculate the normal at this point
    • rotate the direction vector 180° around the normal direction
    • reverse the vector
    • update the start point which is now the new intersection
    • repeat

In the video the first two iterations are shown for a single ray, copying and pasting part of the script. This needs improvement but the prototype of a ray bounce is the actual code that can be translated in python, allowing multiple loops.

In order to implement the algorithm, we need a loop where we can generate the ray objects and update them for certain input geometry. For reflectors design we also need a target surface and a node that generates vectors pointing at this surface. This can be done with a little script that uses the u and v coordinates of the surface to get a point, then a vector by 2 points to generate the starting array of vectors.

The python analysis code is implemented with two classes: Ray and Raytrace.





Ray class has a constructor that initializes the ray from an initial point and a starting vector. The update method performs the loop previously described. Until the maximum number of bounces is reached, it performs the intersections, reflections of the ray, and it stores the intersection points. The methods intersectionPoint and closestPointIndex are internal, which means they are functions called during the update method, in order to make it smaller and easier to debug. The method getPolycurve returns a polycurve passing throughout the points after the bounces are done.




Raytrace class is easier in a way. It is initialized with the starting parameters, and an array of rays is initialized. The run method loops through the starting vectors and creates a new ray, updates the ray and adds it to the array field. The method getRaysAsPolycurve returns an array of polycurves, each one with the rays.

Main script:



The main script is really concise: generate the simulation object, run the simulation, and output the result.

In the Dynamo definition, the node pointAtDistance is useful to visualize the particle at a given time. As we know, the speed of the sound is about 343 m/s. So fixing a time in a slider we know the distance of the sound from the source, which corresponds to the pointAtDistance of the polyline, oriented in the sound generation direction.

Having defined those classes, our next step was to create a library, Acoustamo, using ZeroTouch library implementation.



The c# code is actually the python code translated, with some correction necessary to adapt the variables plus an improvement. As the rays acts independently are the most demanding calculation, why not using parallel computing? So we did, changing the for loop inside the run method in the raytrace class. The result was amazing: in a i7 16GB ram, in order to perform the same analysis, a raytrace with 100 vectors and 20 bounces took 20 seconds in Python and 4 seconds in c# using multithread. Speed is important if we want to optimize the design and generate and evaluate many options quickly. Sometimes a sophisticated algorithm can be more precise as an analysis tool but not as optimization tool because the sophisticated calculation demands lots of memory and time, allowing less iteration for the same design problem within time constraints.

Optimo Optimization

Once we hacked and improved the simulation algorithm, we were ready for optimization! In order to do this we used Optimo, a Dynamo plugin from Mohammad Rahmani Asl which performs a Multicriteria Optimization with a genetic algorithm.

First, the project question: How would an optimized reflector be if we gave a sound source point and a target area that needs to be hit by the rays? So we modelled the elements in Dynamo: source point, curved canopy and an elliptic target area. Then we modelled the simulation inputs: initial directions, two bounces, two surfaces. The genotype, or, the parameters which controls the shape, is the z value of the point that is interpolated by NURBS generating the reflector. By changing the value of the points, we change the shape and the direction of the rays. Obviously we could move them manually and find a solution, but how long would it take? We’d prefer to just want to setup the machine, let the machine work and go to the bar.




But now a question arises. How can we measure the performance of the algorithm? As we said previously, we want the rays to bounce into the target area, so we want to maximize the number of intersections into the target surface. Is this enough? No, we want them cover the maximum area of the target (which we can measure by calculating the convex hull of the intersection points and its area with the shoelace algorithm). So we have the performance indicator (2 fitness function in GA terms), and now we can evolve the design.

In order to make Optimo work, we had to pack our model and the simulation in a node that we call acousticProblem. We needed to leave out only the array of z parameters, our genotype. This node is then instantiated with the Optimo’s initial population node (NSGA_II.InitialSolutionList).

What the node does is essentially randomize the genotype (the z parameters) for the number of individuals within the population. Then the array includes the fitness functions at the end, which are initialized with 0.0 value for each individual (Of course! No analysis done yet!). The output is a 2D array of parameters:

index 0 [Individual 0] [genotype]
index 1 [Individual 1] [genotype]
index (pop.size) [Fitness 1] [values for each individual]
index (pop.size+1) [Fitness 2] [values for each individual]

After this we needed to instantiate each individual and run the analysis, removing the fitness row from the array and use the acousticProblem node without input, plugged into the List.Map node.



Initial population generated! Now we had to extract the fitness value from the outputs. A little notation about Optimo: The algorithm is a minimization algorithm, so as we want to maximize area and number of intersection, we have to reverse in some way the fitness. In this scenario, we decided to use the formula 1 / (x + 0.001) to reverse the algorithm into a maximization algorithm. The 0.001 value is added to avoid division by zero. Once the analysis node was added, we needed to assign the fitness value with the node NSGA_II.AssignFitnessFuncResults to the initial population, filling the part of the array which stores the fitness functions.

Now that we had a population instantiated, we then created the function that needs to be run to evolve it. We needed to duplicate the definition, pack this node and change the NSGA_II.InitialSolutionList node into NSGA_II.GenerationAlgorithm. After the fitness assignation node we needed to sort the population with the NSGA_II.Sorting node and add the result to the output. We also added a value to the output value to store the number of iteration that needs to be ingremented.

After some tests adjusting the population size and the number of iteration, we reached the convergence. This was particularly evident when we filtered the information in order to rebuild the best individual; looping trough the solution they all look similar. The shapes tend to be symmetrical (even if no symmetry constraint was added) and concave. This may be caused by the fact that the more angled rays tend to bounce outside the target area and they need to be directed to the spot. The Pareto front, plotted in 2D as we have two fitness functions, proves that the first two solutions were the best under both fitness examination. This may be due to the fact that the number of intersections and the area of the points are not directly related.



image10 image11


Conclusion and Further Work

With this little project for the Hackathon competition, hacking Dynamo, Optimo and a Raytrace algorithm, we designed a workflow to implement a simple simulation algorithm that can be used to optimize design projects at concept level. Our results showed a convergence of the algorithm, evident from the similarity of the optimized shapes and from the Pareto front diagram. Some attributes of the shapes (concavity, symmetry) may have been anticipated by an expert acoustician as design constraints, but in this case are a result of a bottom-up design where the machine, which has no experience of acoustics, decides which shapes works best and evolve the solution.

This is all good, but more work needs to be done. Time constraints did not allow us to run a large problem with a big population and multiple iterations. But that is a test worth doing. Other work may be done on the algorithm, such as including the material properties, enabling more analysis such as statistical reverberation of the acoustic space, or constraining the simulation for a defined frequency input band. This will extend Acoustamo to analyse and, thanks to Optimo, optimize, concept design for acoustics.

We really enjoyed this competition and we hope that this work can be useful and hacked soon.


Nureci – Fuoco Generativo / Generative Fire

“Maimone, keret aba su sikkau” – Competition 2nd place

In June 2011, the opportunity arose for me and Paolo (ArtificioLab) to take part in a competition to design an artwork for a square, Piazza Ungheria, in Nureci (Sardinia). The idea was to replicate the “fire ritual” as a unifying element. The image of the fire was made dynamic by overlapping views of the same object from different angles. This was rationalized by using squared terracotta elements, coloured with melt glass, the PIX. Moreover, in order to make the composition more plastic, the height of each cube varied from a range depending on the colour parameter.

While we were designing the artwork we also posed ourselves the question of whether there would be a location in the square able to maximize its visibility from infinite points of view. We solved this problem simulating the visual point of a number of agents (in white) walking inside the square. The visual of each agent during the time is traced in order to get a diagram with the frequency of the times a particular area is looked at. The behaviour of the agent is based on an algorithm which considers simple rules. In fact, simple rules in a complex environment generate a complex behaviour, like birds, which follow simple rules to generate suggestive shapes when they fly together.
In this case each agent is generated next to the entry of the square and it starts to move with a constant velocity in an initially random direction. The agent is capable of changing the direction in order to avoid obstacles and other agents. A random change in direction is provided with a probability of 5%. At each step the agents throw a particle (in red) which traces the visual for the position. The overlaps of the large number of trails generate a diagram which shows the most viewed part of the wall, which was chosen for the position of the artwork. It was interesting to note how different simulations showed similar results, clearly demonstrating that was the ideal location for the artwork.


Nel mese di giugno 2011 Paolo (ArtificioLab) ed io dedidiamo di collaborare in un concorso per la realizzazione di un’opera d’arte a Nureci, in Piazza Ungheria. L’idea è quella di replicare l’atmosfera del “Rituale del fuoco” intesa come elemento unificante. L’immagine viene resa dinamica tramite la tecnica della sovraimpressione di fotogrammi da diverse angolazioni, razionalizzata e realizzata con elementi in terracotta e vetro fuso di opportuni colori, i PIX. La plasticità viene data mappando il canale del colore ad una specifica altezza dei cubetti, all’interno di un range appropriato.

Inoltre, durante la progettazione ci siamo posti la domanda se esistesse una collocazione ideale che ne avrebbe massimizzato la visibilità dagli infiniti punti della piazza. Per risolvere questo problema abbiamo deciso di utilizzare una simulazione con agenti all’interno della piazza, tracciando le visuali della loro passeggiata. L’algoritmo scelto per simulare l’insieme di agenti che si muovono nella piazza si basa sul principio che ogni agente si muove nello spazio secondo semplici regole. Semplici regole in un ambiente complesso generano un comportamento complesso. L’esempio tipico è lo stormo di uccelli in cui semplici regole senza organizzazione generano un sistema estremamente complesso e suggestivo. Nel caso in esame ogni agente (in bianco) viene generato in prossimità delle entrate della piazza. Esso mantiene una direzione e velocità definite in maniera random all’inizio della simulazione; queste vengono modificate evitando opportunamente gli ostacoli e cambiando direzione se in prossimità di elementi di collisione. Per rendere più vario il comportamento, un cambiamento di direzione può avvenire con probabilità del 5% ad ogni step della simulazione. Inoltre ad ogni step ogni agente lancia una particella (in rosso) che movendosi a velocità elevata, simula la visuale dell’agente. La particella, entrando nell’area sensibile in prossimità del muro, traccia il suo percorso. La sovrapposizione dell’elevato numero di visuali fa emergere la porzione di muro con più probabilità di essere percepita. E’ interessante notare che effettuando diverse simulazioni l’algoritmo converge verso la stessa soluzione, dimostrando chiaramente che si tratta di una collocazione ideale.

Resources / Risorse

Fuoco-LRpix-LD Piazza-w

Braitemberg Agents:


Learning Structural Patterns in the Voronoi Diagram

MSc AAC2011 Thesis


Intuition has a fundamental role in conceiving new structural systems. Considering the
emergent structures generated from the computational geometry algorithm, such as the
Voronoi diagram, it appears almost impossible to judge their feasibility without performing
complex simulations. The hypothesis is that the learning machine algorithm can embody the structural evaluation in the parametric model, so to provide a structural evaluation during the first design stage.
In order to test this hypothesis a neural network was trained to perform the task for an
increasing number of inputs and to analyze different situations. The response showed a
reduction in learning as the complexity increased. Moreover, it was tested whether the
response of a system with a large number of inputs could be approximated to that of subsystems with low dimensions. The latter seemed to have a better approximation and
suggested the need for further investigation, performed by using a design situation. The
properties were examined in a case of structural optimization, in which different methods
were compared. The results showed an improvement in the optimization with the
neural networks in some experiments, but it largely depended on how well the training of
the network was performed. Moreover, the optimization, made by using the neural network, and the bottom-up generation were faster than the Finite Element Analysis. It therefore advised for large dimensional problems.


L’intuizione ha un ruolo fondamentale nella concezione di nuovi sistemi strutturali. Analizzando strutture generate con algoritmi di geometria computazionale, come il idagramma di Voronoi, è impossibile giundicarne la fattibilità senza effettuare analisi complesse. Si può ipotizzare che un algoritmo basato sull’apprendimento possa incorporare la conoscienza della capacità portante all’interno del modello parametrico, così da fornirne una valutazione sin dalle prime fasi di progetto.
Per testare questa ipotesi, un algoritmo basato sulle reti neurali è stato implementato per un diverso numero di input, analizzando situazioni differenti. La risposta ha mostrato una riduzione nell’apprendimento proporzionale al numero di inputs. In un secondo test è stato sviluppato il problema testando la rete neurale su un gran numero di input per sottesistemi con dimensione inferiore. L’esito è stato migliore in termini di approssimazione e vengono suggeriti ulteriori approfondimenti, come ad esempio in un caso di design concreto. Nello specifico un terzo test è stato eseguito in relazione al precedente risultato, esaminando il caso di ottimizzazione strutturale, effettuato con diversi metodi. Il risultato ha mostrato un miglioramento nell’ottimizzazione utilizzando la rete neurale in alcuni esperimenti, dipendente dal livello di apprendimento della rete. In termini computazionali, l’ottimizzazione effettuata dalla rete è più veloce di una simulazione con elementi finiti, e consigliata per problemi di grande dimensione.

Evolving Roof

MSc AAC 2011 Computational Synthesis – Generative Techniques and Creative Design

This work reproduces the structural optimization of the roof of the Piazza Garibaldi Underground Station in Naples. Compared to the the original study, different implementation of the genetic algorithm have been tested, improving the performance of the project (max displacement = 9.6 cm VS 12.6 cm).

The FEM solver and the GA have been implemented in Processing.

CSynt_1_optimizationOptimized shape



Questo lavoro riproduce l’ottimizzazione strutturale della copertura della stazione metropolitana di Piazza Garibaldi a Napoli. In relazione allo studio originale è stata effettuata una differente implementazione dell’algoritmo genetico, riuscendo ad ottenere una maggiore performance della struttura (spostamento massimo 9.6 cm VS 12.6 cm dello studio originario).