I continued the research of the fastest algorithm and I tried to apply a simple recursion instead of an iterative approach; I introduced also another constrain, I wanted to preserve the original vertex normals (each new vertex is obtained by pushing/pulling the original vertex along its surface normal).
The output is a flat panel made out of 4 vertices when it is possible, otherwise there is a compensation made of triangles, still flat of course so it is a combination of quad and tri shapes.
This 9x9 grid, took a little less than 10 seconds to complete.
These days I've been giving a Dynamo workshop to Jan, a former Grasshopper user with a big passion for optimization problems and automation.
He showed me a couple of examples were GH is used to solve panels optimization, in particular something that would produce flat panels over an organic surface.
I liked the challenge and we started to discuss possible algorithms to find a Dynamo solution to the same problem.
Firstly the subdivision of the surface only using Dynamo Out Of The Box nodes as opposed to the possibility of using LunchBox (I'd say just for academic purposes), so to have set of points to place adaptive components.
In Revit is relatively easy to get flat adaptive components out of 4 points and Zach Krone showed how to do that in his blog, what you have in return though is a set of panels that are discontinuous, in other words you have gaps along the sides of the panels and usually when I show this example I use a report parameter to measure how much the panels are deviating from the original surface.
The optimization problem is different, basically you accept to have points that are not sitting on the original surface but that are derived from it and that put together will generate a set of flat panels with no gaps, so that the outcome will look like a continuous quad mesh.
I started to think at this problem having in mind the iterative approach that I've seen in the videos that Jan showed me, I came up with a couple of different solutions, each vertex can be further adjusted at each iteration based on a variable number of "target" optimized positions (from 0 to 4) depending on where it is in the grid. If you set an high enough number of iterations you eventually get what you are looking for, but I guess that the optimization should be also after the minimum number of iterations required to get all the panels to be flat.
In the first attempt I've used an iterative approach that took in consideration all the vertices at each cycle, so it was running on a new set of points at each iteration.
In the second attempt I decided to introduce a maximum deviation from the flat condition for groups of 4 points. Basically if 4 points satisfy the maximum deviation condition they are not going to change in the following iterations.
In the image above, on the left you see an output for 5000 iterations over a 9x9 grid generated from the free form surface in Revit on the right.
The grey panels are flat, the colored panels didn't meet the maximum deviation condition (in this particular case it means that the red corners for each panel are more than 0.00001 mm away from the plane that best fit the 4 corners).
In the output I have a value that tells me the number of iterations required and the time elapsed to find the optimized vertices, if the number of iterations reaches the maximum values it means that not all the panels meet the maximum deviation condition.
This kind of processes can bring down the fabrication costs quite sensibly, once again Dynamo saved the day.
Yesterday I've been playing with Dynamo to calculate the minimum travel distance and the egress path length for each room of a level in Revit, it is still a work in progress and there is much to do in terms of handling exceptions, avoiding obstacles, but the core is there and it hasn't been that difficult to achieve after all.
I can say that having the possibility to choose among several tools to solve this kind of problems is a very good sensation, I can see several applications for that, in the design phase of course but also in the O&M of a facility, especially when there is valuable equipment that has been moved from one room to another.
I'd like to hear some feedbacks on this so feel free to leave a comment.
I wouldn't do this if it wasn't for a good cause...
Please, everyone who is interested in computational design and model based workflows, help to make this project reach the next stage: follow the link at the end of this page, subscribe and follow that project, propose 5 questions you would like to see on that stack exchange (look at mine for example, those are not platform related, I kindly ask you to do the same) and vote for questions proposed by others.
The goal now is to hit a minimum of 60 followers and 40 questions with 10 votes each so please don't waste your votes and thank you!
Recently I have been asked to demonstrate how Dynamo can help in the manufacturing market, especially in pattern generation, so I came up with this little example that can show all core Dynamo features at once: the Visual Scripting side by side with some Dynamo Script as well as some Python Nodes, Complex Geometry controlled by Parameters, Pattern generation, Lists handling, the Connection with External Resources (in this case Images) that can be used to generate information, the Export to SAT format to bring the idea in the physical world through other platforms such as Fusion 360.
If you were looking for a tool that does right that, you've found it, but Dynamo is much more!
Behold everyone, there is a brand new blog around BIM and cool stuff like Dynamo and React Structures that you might want to keep an eye on, so please subscribe and add it to your favorite readings, let's see what's in the box!
A while back when I was working for and architectural firm based in Milan Italy I was actively contributing to this blog at a crazy rate, even two posts a day sometimes, and I was answering questions around Revit and BIM in forums, sharing what I know as much as possible.
Knowledge is power, and the simple act of sharing knowledge can make a big difference.
One of my dreams was to be able to start a group of professionals to share ideas, around BIM in Italy and how this is going to change how we see the world and how the world looks on us, as a Country, to aknowledge the value in what we do, because we are passionate about it, because we take proud from being intellectually challenged, pursuing a never ending improvement.
What I felt was missing those days had become a necessity now, and thank to the efforts of Chiara Rizzarda, Claudio Vittori Antisari and Luigi Santapaga, it finally happend.
On March the 15th I was invited to the very first meeting of professionals around BIM in Milan, I saw old and new friends coming from all over Italy there, in a very warm and welcoming atmosphere, each and every one with a different story behind but eager to contribute and grow, together.
We talked about expectations and opportunities, we drew sketches and took notes, I can only speak for myself but I felt really good, I felt free to express my ideas and I was thrilled by the interaction in the room that night.
I was honered to be there, I sincerely hope that these meetings will grow in number of partecipants not only professionals but also owners, managers, contractors, all the people that will have to face the change of approach to their businesses and start a new path on the right foot, being supported by those who get their hands dirty with BIM every day.
Early adopters, with concrete solutions to concrete problems, getting together to work better, and the best part is that is not a dream anymore.
He is a brilliant man and he has done an astonishing work in the past with Revit, and most of all he shared his work and discoveries in multiple occasions and he became one of the most respected opinion leader in the world wide community through blog threads, Autodesk University Classes, RUGs and so on. So he's one of my superheroes and he knows it.
It's been a while now that he is on Dynamo, he has a course on CAD Learning and here's the latest class at AU named "More Practical Dynamo: Practical Uses for Dynamo Within Revit" that you should check out, it's been recorded and it's available for free.
I watched it on streaming and I was hoping to see some of his magic tricks in action but I was disappointed, very much, partially for the content of the class itself (I get that most of the people who attended the class hadn't the slightest idea of what Dynamo is and how it works but 20 minutes to change texts to upper case, seriously?), and mainly for a few false concepts here and there that will make people go "Marcello said it, so it must be true" because of who he is for the community.
I just couldn't turn a blind eye on it, for the sake of those who will approach to Dynamo and Revit API in general because they were inspired by Marcello's work, he's a good story teller, and I get that sometimes he needs to simplify concepts, like in this case, but too much simplification can lead to misunderstanding and unnecessary confusion, especially when it's going to be out there for a very long time.
Just a couple of examples:
1) [0:08:25] Element Types ARE NOT System families, they are the Base classes for all Types within Autodesk Revit (System or non-System family types), they simply are different animals.
2) [1:21:12] With this version of the Revit API it is not possible to create a "free standing" Railing but only hosted by a stair object and there are no exposed method to change the path of a Railing object. So NO, you can't create the fence example using an actual Railing object directly from Dynamo, something that you might want to change type later on per say, but you can use generic models, adaptive components, you could model the whole thing in Dynamo and import it in Revit using DirectShape...
Here's a question on the Revit API forum on the same topic.
What I'm saying is to keep up the good work, the creativity and the inspiration as a community, but in order to do that we should never take for granted what people tells us to be true (not even me, not even our heroes) and wrap our own head around problems, so if we look at the same problem from different point of views we might find a truly better solution.
I've tried to follow a very wise and simple ABC rule I've read somewhere, I think it's worth sharing:
Believe in yourself
Here is a brand new initiative by my good buddy Cesare Caoduro from his LinkedIn page: unleash all of your creative power and test your skills with the collaboration tools provided by the A360 platform!
You get to to pick your favourite Autodesk tools and create your own city for free!
So get an Autodesk Account if you don't have one already and be prepared to submit your models!
Like Cesare said on his page:
"...Imagine and design your personal city because the imagination is the only barrier for game designer, think like a game desiger or like a baby constructor..." Read more here
I'll be there, and you?
the latest stable release of Dynamo is out and ready for everyone to test, you can find it here in the DynamoBim official page.
Among other really awesome things that you can find in the release notes, one in particular caught my attention: the "Node to Code", which helps you to learn DesignScript converting (where it is possible) the graph into a very well organized CodeBlock.
This is a fantastic feature that adds clarity to a graph and opens the path for a Dynamo code compiler, that's one of the things I've been dreaming on for a robust firm-wide Dynamo implementation.
Plus from what I could see the development did a really good job in resolving clashing issues in geometry representation in the Dynamo environment.
Today I stumbled upon this notation in codeblocks and I tried to figure out how it works because I couldn't remember any documentations on this particular aspect but I think is pretty useful because it helps having compact clean graphs.
I've used a range from 0 to 5 (I prefer to use the codeblocks for this purpose) and built some points, on the Point.ByCoordinates node there is the lacing strategy to apply but on codeblocks there is not (to be fair now you can assign the lacing strategy to a selection of node via right click, also the codeblocks but it doesn't seemed to work in my case) .
With this syntax though you gain control over the range and how to use it applying transposition directly.
b=Point.ByCoordinates(a< i >,a < j >,a < k >)
Now i,j, and k have to be non negative integers, which means zero is allowed, what this does is to let you control how to combine the numbers in the range.
If i,j and k have the same values then the result will be a list of 6 points where for each point x=y=z.
When these indices are equal to 0 they return the first value of the range (in this case 0), otherwise the indices express the order in which the values in the range are going to be combined: the higher index is the one that goes through all the values of the range first.
When two indices are equals and bigger than 0, for instance 1,1,2 or 2,2,1, the geometric outcomes are going to look the same but the points will be listed differently just like using the transpose node.
When the indices are all different and greater than zero you a have a cross product lacing behavior.
Without further ado, here are some images that can explain better the results of the different combinations.
Finally this stable release is out for every Dynamo user, I've been waiting for such new feature for so long, and finally they are here!
Many thanks to the team for the amazing work once again.
Now I want to talk in particular about the grouping feature, this is the first step towards a robust, well organized, easy to read and edit Code/Graph.
A group is a collection of nodes, this is the closest thing that we have in standard coding with private functions or subroutines or whatever they are called in other coding languages.
To create a group is easy: select the nodes and CTRL+G (yes, I know... too bad that it is the same shortcut to toggle between the graph and the geometry view until 0.8.0, get over it!).
To be honset there are a couple of ways more to do that via the menu, right clicking... so stop complaining, you have been given a LOT more than just that.
If you select the group with a right click you can assign the color, and make the title really, REALLY visible with a huge font size.
Now the user can better understand what a set of nodes is meant for, so it becomes easier to orient inside a graph saving a huge amount of time. Love it.
If you want to remove a node from a group, right click on it and remove it from group, viceversa if you want to add a node to a group you need to select the node AND the group at once, right click and Add to group, that easy.
Anyway I wish it were as simple as "drag-and-drop" items over a group but hey, Rome wasn't build in a day.
Nodes inside a group move all together, so it is fairly easy to organize nicely your graph in a few clicks. A couple of issues are still there though: if you try to align two groups, what you are really doing is aligning the nodes inside the groups all together... so for now you don't wanna do that, maybe in the next releases such behaviour will be improved.
A nice thing to have would be the ability to "lock" a group, so no user is allowed to mess with it
We have colors, let's use them to organize our graph! Yes but how? We have 16 colors for now, let's say we start distinguishing main functions in our graphs:
I know it is even too much simplified, but what can be wrong with simple?
So, please, let's keep it this way.
It would be AWESOME to standardize the color meanings inside a firm, to provide consistency, so one can pick four different colors from the bottom row and assign each one of them to functions above.
It would be nice to follow an order too... from left to right, like when you are reading a book, so for instance:
Purple -> Input
Orange -> Data manipulation
Green -> Output
Light Blue -> Debugging
I feel that this approach can be really useful if we want a serious Dynamo implementation in our everyday processes, plus this would increase the possibility to make circulate these graphs between firms and open up to a more productive environment with multiple benefits for every one involved.
One of the issues that designers are most concerned about is the protection of their intellectual property within a model.
In an environment where the exchange of informations is vital to the process, one can not refuse to cooperate and share his model with other stakeholders involved, plain and simple.
There are different ways to protect the intellectual property without affecting the data exchange, such as using a different file format (e.g. DWF, IFC, etc..) but there's nothing we can do when it comes to native file format for authoring platforms like Revit.
Or maybe not.
I've been looking to the new functionality shown by Jeremy Tammik in his blog, the DirectShape, intended to allow the users to import geometry created in other softwares through other formats like OBJ for instance.
What I was trying to accomplish instead was to create a DirectShape from the actual model, retrieving a solid and fill the voids left by the rooms for 3D printing optimization, I'm still struggling on this particular issue since rooms appear to end up as solids with negative volumes.
Then came to mind a possibile application, the model freezing: one can select a portion of the model that wants to lock and eventually use it as a component. in other projects.
In theory it is possible to freeze the entire model, obtain a generic model, copy and paste it into a blank project, and deliver that to a third party.
The odd thing is that the family created through this process has no Type and it is not even listed in the family browser, so it can't be edited and saved in anyway.
The generic model is not editable and won't even export to CAD for what it matters, the only workaround I found was to export it to IFC.
In this case all of the data is retained except for the 3D geometry and some material information (just the appereance because tagging won't work).
Since October the 1st 2014 I'm part of the Autodesk Consulting AEC EMEA team, and I'm really happy! I'm sorrounded by very talented people and I'm learning everyday something new. Unfortunately I wasn't able to blog for a long time.
But anyway I'm here now and I want to share with you what I couldn.t over a year ago. During the first session in the very first RTC Europe in Delft, David Conant showed us a very interesting application of the new feature in Revit 2014, the highly customizable schedules!
Back at the time I had little knowledge of coding since I had just started the course by Harry Mattison of Boost Your BIM on Udemy, which by the way you should totally check out if you haven't yet.
I had time these days to test my understanding of how Revit API can work for me and made a little experiment to mimic what I saw at RTC, it's still a work in progress but I think it's been one of the highlights of that a RTC and shows pretty well what can be ddone if you just think out of the box, so my big thank you goes to David and Harry.
When working with consultants or clients it's fairly common to ship PDFs and DWGs of the sheet sets along with the Revit model, however DWGs are the weakest part of the overall process.
Revit is not able, natively, to export DWG in shared coordiantes from a sheet view, but from a regular model view it does although it will never be a native DWG file. So I wrote a macro (see a previous post) that collects the views on a sheet and exports them in a separate folder to have them organized and in shared coordinates.
What was missing was the ability to include the title block, which was ok for consultants but not for the client.
So here's a video that shows how this issue can be solved using both Revit and AutoCAD.
DWGs are still X-Refs and they are not clipped like in the previous version, each view is then rotated accordingly to the Revit file. Each viewport only shows the layers of the corresponding x-ref. For further enhancements the views could be locked automatically, there could be a batch file that will open AutoCAD and do the job for each sheet file, etc... I'm still working on and testing it. I hope to find a way to run the whole thing from Revit with the press of a button. Suggestions and critiques are appreciated as long as they are constructive.
In this examples I'm trying to retrieve the parameters of a generic model representing a person (a generic model smile shaped) in a room with all the equipment that belongs to his/her such as the workstation or the phone (each family has its own parameters).
In the previous example parameters were just listed in a certain order hard-coded in the Updater, this time the order needs to change slightly so that the parameters referring to a spefic person are all consequential.
In order to do this an additional step must be included in the process.
The best way I could think of is to group the families involved (the person, the workstation and the phone), retrieve the parameters for grouped objects first and then the remaining outside of groups.
I've been wrapping my head around dynamic model update in order to push my code further to be more "Revit-ish", so it updates instantly and has no longer a "fire and forget" sort of behaviour.
I've implemented an IUpdater interface that loops through the family instances, reads their parameters in a certain order and then pushes them into the comments of the room.
It's not perfectly Revit since it's not bi-directional at the moment, anyway it gets the job done nicely.
Technically the oddest part in developing this idea was to realize that an IUpdater doesn't need a transaction to work.
Applications are endless, this one I called "Super Tag", it would give the ability to the users to push calculated values into tags (finally!), embedding a piece of code in the template file assuring that everyone on the team has the same tools available.
There are considerations to make on performances, but it sure is a great thing we have to suit our design.
In addition to Marcello's post on confusing node names for selection in Dynamo, I'd like to point out what I've just discovered about the Document nodes.
In the API the document that is shown to the user is called Active UIDocument (for brevity uidoc), this element has a property called "Document" that refers to the data base level document (for brevity doc). Any time we want to edit a file in Revit we need to open a transaction that points to a specific doc, while the user interacts with the current uidoc.
In a Revit session there could be multiple docs opened at the same time at a database level (think for instance to a host and links scenario, linked files are documents somehow opened at a database level but not directly editable by the user in the current session; similarly, with multiple editable docs opened, the user is allowed to edit just one at a time, the active document, the uidoc), they could be project or family documents.
The API allows access to those docs without the user interaction and for this reason it's important to have clear in mind the differences between the two: for example, object selections belong to the uidoc (because they require the user intervention), walltypes belong to the doc (because their definition doesn't depend on variables such as the active view), etc.
In the picture above you can see that Document.Current is referring to the UIDocument since I got the active view name, while the Element.Document is referring to the Document since I got the title.
Hope this is gonna be fixed or cleared up in releases to come.
This is a further development of previous Dynamo definition, now it can apply the color scheme for any parameter, there's a little bit of coding in there because I couldn't figure out why a cross product lacing over a List.FilterByBoolMask returned a null list for the In and Out output ports.
Anyway I did it myself using a very simple script in Python.
I'm trying to avoid them as much as I can, really, but when I'm tight on the dead line and I need the get the job done, coding is always my best option, even if I don't feel particularly comfortable with Python, but I guess it's how my brain works, I know for a fact that amazing things are achievable just using the OutOfTheBox set of nodes, so I hope to have enough time to obtain the same thing using a "pure nodes" approach instead.
I guess that the beauty of Dynamo is that everybody can play with it and make his own tools, no doubt about that.
Here's the code I've used to collect rooms in the project:
Here's the code I've used to retrieve indexes evaluating the elements of ListA against the elements of a ListB, the output is a list of integers, as long as ListA.
In this example ListA contains Department values for each room in the project (11 rooms gives 11 items) while ListB contains the same values but derived from the Color Scheme file (5 department entries gives 5 items).
The outcome of this python script is used to determine which color has to be used to override each one of the solids derived from rooms.
Solid extraction and ListA:
Color override and ListB:
Here's a .Zip file containing the .Dyn, .Rvt and .Csv used in this example.
I've been asked today by a collegue how to replicate an axonometric view of AutoCAD spaces into Revit for a preliminary design.
In the past I've tried to do something using IFC but the result wasn't that good after all for many reasons.
This time I tried a Dynamo approach to the problem since it allows access to data and particulary to the solid representation of elements.
What I needed was a little bit of code to select rooms in the project but I still suck in Python, I happend by chance in a package by Nathan Miller called LunchBox and one of the custom nodes inside this package retrieves a lot of room data. What I did in this case was to copy the import statements from this node and write a few lines of Python code on my own to filter objects belonging to the Room Category.
After that it was fairly simple extract the solid representation for each room, I created a list to keep the geometries distinct because I wanted to be able to control the color of each room to match the color scheme in 2D views.
Here comes the sloppy part: unfortunately the API (Revit 2014 as far as I know) still doesn't give access to the color scheme parameters, so not even in Dynamo it shouldn't be possible to retrieve those parameters.
To keep it simple I decided to write a CSV file containing the paramter value and the components for the colors in the color scheme (this one was based on the name of the room, but it could be done for every parameter availible, just keep in mind that room solids have to be grouped as one big object for each value of the color scheme (I know it's not very handy but I couldn't figure out another way to do it, suggestions appreaciated).
Here's the definition for those who want to have a closer look to it.
Using acronyms is not really in my culture since I'm not an english mother tongue, it's fairly common though in the rest of the world and I happend to get used to it. I had to be explained what "RAF" stood for in a project based in London, since for me it was Royal Air Force, but the other BIM Manager on the phone told me it was Raised Access Floor, just to name a funny episode that happend to me not too long ago.
Right now the usage of these "magic words" is spreading also in the AEC industry (here's another one).
If everybody understands these acronyms, such as BIM, BEP, VCD and so on, and everybody knows precisely what they refer to there's absolutely no problem with using them.
Unfortunately this is not the case for the subtle LOD (Level of Development), which is sad to note that still too many people tend to confuse with level of detail, which is a completely different concept.
I'd say to shift the attention from the model to the results of the analysis that can be performed on a model at the certain stage of its development.
LOR Level Of Reliability would measure the reliability of those analysis (in a general kind of way), less people would confuse the terminology and the key concepts behind it.
This is the latest version of this macro that moves objects from one workset to another and let the user check the results via a report button.
The user can copy and paste the Id's in the report for further editing using the Select by Id tool in the ribbon.
There's a check box that allows to move also hidden objects that don't belong to any categories visible to the end user.
Here's the solution to copy in here:
This macro opens a little form with two drop down menus listing the worksets in the project and then try to move all the possible object from the source to the target workset.
There's a Log button that opens a read only dialog listing the Id's of the elements and the types divided by workset and the number of objects in parenthesis.
I've used two different techniques to list the worksets in the project, the FilteredWorksetCollector and another one using the WorksetPreviews.
Right now I'm thinking about adding a check list for the categories to move between worksets, so the the form would be something more like the one in this other video:
Implementing the category check list produced some undesirable side effects: Analytical Surfaces and Structural Trusses return an error when selected, categories such as "Other" and "Legend components" are no longer taken into account when performing the macro.
I guess it's best to keep the possibility to control each and every object in the model for the next version.
At a first look it seems pretty much the same old Design Script Manual, but it's still crucial in understanding how code blocks work.
Thanks to the team that put this documentation together, you guys are amazing!!!
Today I've found an interesting Topo add-in by Mustafa Khalil and here's a video demonstrating how it works.
So I decided to understand how it could be done and I tried to mimic the core of the add-in.
My attempt here is really basic, there are no parameters exposed to the user to set for instance.
This exercise gave me the opportunity to understand better some of the topography features in the API, for example the implementation of an interface to manage preprocess failures since it is needed to commit the transaction group necessary to edit a topographic surface.
Another interesting aspect is that Revit won't allow you to process points with the same XY values for topo surfaces, that's why I' decided to add a point at a time while editing the surface.
It would be fun to do the opposite: having a topo and edit the floor secondary element back... oh wait, Marcello Sgambelluri already did it :)
Anyway here you can find the code I've used if you want to have a look at it, if you are happy with it please show me some gratitude paying what you want via PayPal to:
When I tried to update the previous definition to the 0.7.1 release something went wrong and Dynamo was stuck.
I took the opportunity to rethink the definition and I found a slightly different approach to the problem: this time I keep the curves as distinct elements almost to the end, this way it's easier to check the orientation of the curves and get rid of the special node for opposite direction of the curves.
After selecting the model lines in the Revit environment Dynamo automatically places the Adaptive component accordingly to the maximum width specified for the subdivision.
If the orientations of the lines are opposite, Dynamo reverses one of the two and perform the definition anyway.
There's always need to delete the panels manually once created like in previous version, it would be nice to have a "dispose" node for this particular goal.
Here's the custom node definition and here's the test definition I've used.
I was looking for some images for a presentation and I came across these pictures of some works I've done at the University prior than 2008, way long before adaptive components came along.
It was definitely fun! but really soon I realized that what I was doing was much, much more than just a 3D model, I saw the potential and what eventually the AEC industry was going to be in the closest future.
That's when I moved my focus from modeling and representation to BIM. Unfortunately most of the people that I know from the University still haven't even approached to BIM and they're just starting now to consider to move, for instance, to Revit because they're blinded by the 3D model and the rendering.
Using Revit to just make a 3d model is like having a Ferrari and use it in the backyard.
So please double check your willingness to learn something new (a BIM approach to design and not just how to use an instrument like Revit), both for productivity on a specific project and in the long run, keep in mind that it can be really painful if you're doing it while you're already working full time but it hasn't necessarely to be a blood bath if you ask for help to competent people.
Break problems into smaller ones, read forums and blogs to find answers to your questions, don't take "no" for an answer and never give up.