ntrol points in Rhino.
Also, I forgot to mention in part 1 that when doing the directional subdivision, depending on how you drew your input mesh, there is a chance that it gets divided in the wrong direction, and you end up with something like this:
Which is not what we want.
The simple way to fix this is with the MeshTurn component, which rotates the direction of each face by one side:
Now we can use physical relaxation to smooth our mesh. In this example I show a simple tensile relaxation, so it will be negatively curved, but the same principles can be applied to all sorts of surfaces by using different combinations of forces.
The definition for the relaxation is attached below.
There are 3 main groups of forces used:
Planarization
For the mesh to be able to unroll properly into flat strips, we want each of the thin rectangles to be flat.
Springs
I already showed how the WarpWeft splitting can be used to assign different strengths to control the shape of a mesh here. Now because of the uneven subdivision we have very different numbers of edges in each direction, so the strengths have to account for this. Depending on the level of subdivision used and the shape you want to achieve, you may need to set the Weft stiffness to be 10 to 100 times that of the Warp.
Edge Smoothing
Because our subdivided mesh has square ends, we might not want to simply anchor the boundary, so I've shown how we can force them to become more circular, while still staying in place. Each boundary curve gets pulled onto its best fit plane, while also applying bending to round it out, and springs to keep it from shrinking.
(This part could also be achieved in other ways, such as pulling the boundary vertices to a curve)
When we run this relaxation, the shape should smooth out to something like this:
Play with the tensions and boundaries until you are happy with the result, wait for it to stop moving, then stop the timer. (Remember it is very important to always stop the timer once the relaxation has finished, before continuing working with the output, as otherwise Grasshopper becomes very slow, because Kangaroo is constantly resolving, even if no movement is visible).
If you want to try other shapes than tensile surfaces, you could also use forces such as bending, laplacian smoothing, or pulling to some target surface to control the form.
Next - Part 3 splitting and unrolling
…
t of data it has to operate on. So only those aspects of the algorithm that differ in these cases are relevant.
For example if your algorithm always does exactly the same thing (let's say all it does is measure the size of an array and display it on screen) will be O(1), because it doesn't matter if you run it on an array containing 10 or 1000000 items. Measuring the size of an array is a constant-time operation:
Print(string.Format("Array contains: {0} element(s)", data.Length);
However if your algorithm works on not on arrays but on linked-lists, then it becomes an O(N) operation because counting all the elements in a linked list means you have to iterate over all of them. And the longer the list, the more iterations you need. In fact the number of iterations is exactly the same as the number of items. (ps. if you'd be using the System.Collections.Generic.LinkedList<T> class then it's still O(1), because apparently that particular implementation of linked lists caches the count and keeps it up to date.)
If you have a loop that runs for each item, and then inside that loop there is another loop that also runs for each item, then your complexity becomes O(N²). Or, in a similar case if your algorithm consumes two collections (N and M) and iterates over all items in N, and then inside that loop it iterates over all items in M, the complexity is O(N×M).
The case can be made that only the most severe complexity is relevant enough to report. For example if you have an algorithm that comprises of three steps, the first of which is O(log(N)), the second is O(N²) and the third is O(3ⁿ), then technically the total complexity would be O(log(N) + N² + 3ⁿ), however the first two parts are utterly insignificant compared to the third and therefore can be omitted entirely. Consider for example increasing the input size from 10 to 20 elements:
log(10) + 10² + 3¹⁰ = 1 + 100 + 59049 = 59150
log(20) + 20² + 3²⁰ ≈ 1 + 400 + 3486784401 ≈ 3486784802
As you can see the increase of the complexity is almost entirely due to the O(3ⁿ) portion, so much so that there's almost no point in mentioning the other two.
Now, your specific questions:
Constructors/declarations and method invokes are not necessarily O(1). In this particular case they are, but it is possible that some constructor you call may have a higher complexity. For example if instead of an empty List<T> you're constructing a SortedList<T> based on your inputs, then it definitely may be the most significant complexity in your entire algorithm and it needs to be taken into account.
Correct. A loop like this has complexity O(N), ignore stuff that only happens once like the declaration of the iteration variable.
I don't understand that line of code. cP is already a list. Why are you calling ToList() on it? In general making copies of memory-contiguous collections (like arrays or lists) can be done in O(1), depending on implementation, because blocks of memory can simply be duplicated or moved at one go using the correct hardware ops. However other times it will require a loop in which the complexity goes up.
It's very cheap to add items to lists, provided the list has enough space to add new items. By default a list is big enough to contain only 4 items. If you try and add a fifth one, the list will need to allocate more memory elsewhere, copy the 4 existing items into the newly allocated space and only then add a new item. So, if you know ahead of time how many items you'll be adding to a list (or even if you only know a theoretical upper bound), you should construct the list using that known capacity. This will speed up the process of adding many items to a single list.
Don't know how crypto providers work, but since this part of your algorithm does not depend on cp.Count or the magnitude of populationCount, it doesn't matter for the big-O complexity metric.
…
an run. GH2 still uses the Rhino SDK for the geometry functionality, so curve offsets, meshing, brep intersections etc. will run exactly as fast as they do now.
However even in the absence of a working version of GH2 which can be profiled, we can still discuss some of the major aspects of performance:
Preview display. Each GH solution involves a redraw of all the Rhino viewports at the end (unless is preview is switched off, which I imagine is exceedingly rare). For simple GH files, the viewport redraw takes far more time than the solution. Rhino6 has a completely rewritten display pipeline using more modern APIs so we should see a speed-up here in the future, be it GH1 or GH2 or GHx.
Canvas display. Each GH solution involves a redraw of the Grasshopper canvas. If the canvas shows a lot of bitmaps or intricate geometry (lots or text, dense graphs, etc.) this can take a significant amount of time. GH2 will use Eto instead of GDI+ as a UI platform. Eto can be both faster and slower than GDI, depending on what's being drawn. It is particularly fast when drawing images, not so much when drawing lots of lines. There is a little room for improvement here and I intend to take full advantage of that.
Preview meshing. Grasshopper uses standard Rhino mesher to generate preview meshes. If a GH file generates lots of breps, a large amount of time will be required to create the preview meshes. The new display improvements in Rhino6 will allow us to get away with previewing some types of geometry without the need to mesh them first, and I imagine some effort will be spend in the near future to improve the Rhino mesher as well.
Data casting. Most component code operates on standard framework and RhinoCommon types (bool, int, string, Point3d, Curve, Brep, ...), however Grasshopper stores and transfers data wrapped up in IGH_Goo derived types. This means that every time a component 'does it's thing', data needs to be converted from one type into another, and then back again. This involves type-checking and often type instantiation. This stuff is fast, but it's overhead nonetheless and can take significant amount of processor cycles when there's lots of data. GH2 no longer does this, it stores and transfers the types directly as they are. There will still be some overhead left, but hopefully a lot less.
Computation. GH1 is a single-threaded application. When a component operates on a large collection of data, each iteration waits for the next. GH2 will be parallel, meaning components will be invoked on multiple threads, each thread focusing only on part of the data. Then all the results need to be merged back into a single data tree. On my 8-core machine (4 physical cores, each with 2 logical cores) I've been getting performance speed-ups of 4~6 times when using my multi-threading code. I wish it was 8, but clearly there is some overhead involved here as well.This will not help to speed up a single very complicated solid boolean operation, but if you're offsetting 800 curves, then each thread can be assigned 100 curves and the time it takes will set by whatever thread takes the longest.
Algorithms. If a specific component is slow, there may be things we can do to speed it up. Either improve the Rhino SDK, or improve the GH code. Depends on the component in question.
When all's said and done, I'd love to see a 10x speed increase for GH2 over GH1 for simplish stuff, and I shall get very cross if it's anything less than 5x.…
etric/parəˈmɛtrɪk/adjectiverelating to or expressed in terms of a parameter or parameters.art/ɑːt/nounthe expression or application of human creative skill and imagination, typically in a visual form such as painting or sculpture, producing works to be appreciated primarily for their beauty or emotional power.// Summer School 2017 3 day intensive workshop for design students & professionals will delve into computational & parametric methods (using Rhino3D & Grasshopper3D) to create data-driven art installations, physically manifested into a space through hands-on fabrication & assembly.The experimental studio will run across 2 cities in India (New Delhi & Mumbai) and investigate the agenda of ‘filling the void’ at art installation scale, through the use of computation and parametric methods. Studio is designed as a 3-day event in both cities comprising of technical tutorials, teaching sessions, prototyping & presentations culminating in a symposium / round-table conference / open discussion with leading / emerging professionals that demonstrate computation, parametric design or alternative techniques in their work / practice / academia. // Cities & Dates*New Delhi – 30th June to 2nd July 2017 (Friday to Sunday)Mumbai – 7th July to 9th July 2017 (Friday to Sunday)//VENUE: DELHI: Startup Tunnel, Vihara Innovation CampusD-57, 100 Feet Rd, Pocket D, Dr Ambedkar Colony, Chhattarpur, New Delhi - 110074MUMBAI: Raffles Design International, MumbaiHi Life, 2nd Floor, Phirozshah Mehta Road,Santacruz (W). Mumbai – 400054// Registration DatesAll Registrations End 4 days prior to workshop start date (Or till seats last)// About rat[LAB] EDUCATIONrat[LAB] EDUCATION is an initiative by rat[LAB]-Research in Architecture & Technology (www.rat-lab.org) to start a new discourse in architecture & parallel design disciplines with the use of ‘computational design’ & it’s various subsets. Spread across various cities / countries, we are establishing a global dialogue in the domain of computational design by actively organizing and participating in workshops, lectures, presentations & symposia. While rat[LAB] has taken a top-down approach of exploring computational design through industry, a parallel, bottom-up approach is also in-line to involve students of all levels, from design & related backgrounds.…
ding is not for the faint of heart and is quite a significant understanding. However, I don't know what your dealing with, so that may be the way to go about it.
Your component if its "finished" has to supply some sort of results that are then used downstream. AFAIK there isn't a way to "prevent" down stream components from calculating until your finished. They have to get some sort of information or else they'll just be waiting. Considering how the results of those components are likely to be invalid until the information gets calculated, it may be better off supplying them with nulls until you have some actual information to give them.
Anyway, I think that you should think very closely about the structure of your routine, and specifically how it will interact and update itself. The way I'm thinking about it now is that there really isn't anything that's done in the "solve instance" function if you will. Essentially the "solve instance" function would either A) start the reading of the file if no data is found, or B) output some data if it is found. This is an extreme undersimplification, but the simpler you keep this the more likely this will work. Here are a few more "details", i guess, of how I could see this potentially working...
Thread A - Initial call to Solve Instance function
+ Check and see if there are any results that exist from reading your file - at this point there shouldn't be. These results should be stored in some sort of class variable that is accessible to both threads. It might also be a good idea to have some boolean flag that will also be accessible that represents whether your reading/writing those variables.
+ Fire a function in another thread that begins the read process. Note that you'll likely have to do this through a delegate and an invoke call, but I'm not 100% sure
+ Fill in some null values for the variables you must supply
+ Output the nulls, thus finishing the Solve Instance function
Thread B - File Read Function running in separate thread
+ Open up the file. Note that its probably a good idea just to pass the file path (as a string) between the different threads. Leave the creation of the file/text stream to the one thread that's using it.
+ Perform all the necessary reading from the file
+ Copy all your data to the variables that are accessible to both threads.
+ Expire either the solution on either the component in question or (at last resort) the whole canvas. I know expiring the whole canvas is defenitely possible, but it should be possible to just expire the one component that's doing the reading.
Thread A - "Second" call to Solve Instance after being manually expired
+ Check and see if there are any results that exist from reading your file, which there now should be.
+ Output those shared results
+ Clear the last results (or cache them in some way) so that the next time the Solve Instance function is fired, you don't find any results and reread the file.
I think there are a few variations to this that could happen too, including having a separate function for reading and writing through the data that's called using its own delegate/invoke call to make sure that its extra safe.
If you haven't already, you should really look into event driven programming, delegates, and asyncronous messaging. These are going to be the 3 things that you'll need to have a decent hold on to make sure this things works. Just to let you know, debugging these things can be a bitch.…
metric/parəˈmɛtrɪk/adjectiverelating to or expressed in terms of a parameter or parameters.art/ɑːt/nounthe expression or application of human creative skill and imagination, typically in a visual form such as painting or sculpture, producing works to be appreciated primarily for their beauty or emotional power.// Summer School 2017 3 day intensive workshop for design students & professionals will delve into computational & parametric methods (using Rhino3D & Grasshopper3D) to create data-driven art installations, physically manifested into a space through hands-on fabrication & assembly.The experimental studio will run across 2 cities in India (New Delhi & Mumbai) and investigate the agenda of ‘filling the void’ at art installation scale, through the use of computation and parametric methods. Studio is designed as a 3-day event in both cities comprising of technical tutorials, teaching sessions, prototyping & presentations culminating in a symposium / round-table conference / open discussion with leading / emerging professionals that demonstrate computation, parametric design or alternative techniques in their work / practice / academia. // Cities & Dates*New Delhi – 30th June to 2nd July 2017 (Friday to Sunday)Mumbai – 7th July to 9th July 2017 (Friday to Sunday)//VENUE: DELHI: Startup Tunnel, Vihara Innovation CampusD-57, 100 Feet Rd, Pocket D, Dr Ambedkar Colony, Chhattarpur, New Delhi - 110074MUMBAI: Raffles Design International, MumbaiHi Life, 2nd Floor, Phirozshah Mehta Road,Santacruz (W). Mumbai – 400054// Registration DatesAll Registrations End 4 days prior to workshop start date (Or till seats last)// About rat[LAB] EDUCATIONrat[LAB] EDUCATION is an initiative by rat[LAB]-Research in Architecture & Technology (www.rat-lab.org) to start a new discourse in architecture & parallel design disciplines with the use of ‘computational design’ & it’s various subsets. Spread across various cities / countries, we are establishing a global dialogue in the domain of computational design by actively organizing and participating in workshops, lectures, presentations & symposia. While rat[LAB] has taken a top-down approach of exploring computational design through industry, a parallel, bottom-up approach is also in-line to involve students of all levels, from design & related backgrounds.…
phere with the maximum number of triangles but not much than a defined threshold.
I scaled that mesh just to fit Rhino grid, but it is not mandatory. What is useful, is to scale not uniformly the mesh (Scale NU). It could be done after cellular modifier applied or before or before and after. The 3 options are possible in the script. If you don’t need them just put 1 in scale sliders.
Ellipsoid mesh is the populated with points, I put 2 independents populations to randomize a bit further. For each vertices of the mesh the closest distance from the populated points is calculated.
Here is an illustration in color of this distance.
This distance is then used to calculate a bump. If domain for bump is beginning with negatives values to 0, it carves the mesh. Instead it bumps/inflates it.
Some images to illustrate the difference with populating 100 points with one or two populations.
Here some images to illustrate the application of scale before carving or after.
Next phase apply noise. At the moment I don't find it good.…
Introduction to Grasshopper Videos by David Rutten.
Wondering how to get started with Grasshopper? Look no further. Spend an some time with the creator of Grasshopper, David Rutten, to learn the
n fact) according a vast variety of "modes" PLUS the required clash detection (ALWAYS via trigonometry). In plain English: outline any collection of Breps and "apply" a truss that is topologically sound (planarization in case of quads etc is an added constrain). PLUS outline/solve what comes "next" after that truss (like the planar glazing "add-on" brackets of yours [ the ones that need redesign, he he], or some roofing/facade skin system [secondary supports, corrugated sheet metal, insulation, final cladding, dogs and cats])
2. Imaging doing this in real life (nothing to do with "abstract" formations of "lines" or "shapes" or whatever). This means primarily adopting a BIM umbrella: in plain English AECOSim, Revit or Allplan (I'm a Bentley man so I use AECOSim + Generative Components). This also means using "in-parallel" a top MCAD app for 1:1 details, FEA/FIM and the vast paraphernalia required for real-life studies destined for real-life projects (made with real-life money by real-life people). My choice: CATIA/Siemens NX.
3. What to send to Microstation (if not using Generative Components, that is) and/or CATIA? In what "state"? To do what exactly? For instance even if you could design this feature driven tensile membrane anchor custom node in Rhino (you can't) it could be 100% useless in CATIA:
4. Imaging masterminding ways to send them nested instance definitions of ... er ... a coordinate system (all what you need). In plain English: since is utterly pointless to send them nested blocks that can't been parametrically controlled (variations/modifications/PLM management/BOM/specs etc etc)... send them simply the "instructions" to place coordinate systems of components that ARE parametrically designed within Microstation and/or CATIA (classic feature driven design approach blah blah). So GH solves topology et all (working on data imported via, say, Excel sheets related with sizes of components etc etc) and sends to Microstation simply this (a myriad of "this" actually):
I do hope that the gist of the "method" (the ONLY way to invite GH to the party) is clear.
best, Peter…