tions or components.
Participants will learn concepts of object oriented programming and essential syntax of C# to endeavour into personally extending cad toolsets. The workshop will focus on introducing the .NET language C# and the Software Development Kit (SDK) RhinoCommon.
Topics
- use of Script Component within Grasshopper
- explanation to the .NET Framework
- introduction to RhinoCommon SDK
- basics of imperative / object-oriented programming
- data types, operators, properties
- variables, arrays, lists, enumerations
- methods
- objects, classes
- control structures: conditional statements (if, else, switch)
- control structures: loops (for, foreach, while, do)
- walk-through iterative und recursive code-samples
- use of RhinoCommon Geometry class library: creation, sorting, editing of Geometry (Points, Vectors, Curves, Surfaces)
- adding (baking) geometry to the active Rhino 3DM Document, including attributes (Name, Layer, Colors etc.)
- introduction to the Integrated Development Environment MS Visual Studio Express Edition
- compiling code to dll/gha files (plug-ins) / making your own Grasshopper custom components
Grasshopper wird auf der .NET Softwareplattform entwickelt, und kann ebenso wie das CAD Programm Rhinoceros mit "RhinoCommon", einem Software Development Kit, erweitert werden.
Dieser Kurs richtet sich an Designer, Architekten, Ingenieure und Techniker, welche mit dem grafischen Algorithmus-Modellierer "Grasshopper3d" sowie dem CAD-Programm "Rhinoceros" bereits vertraut sind und einen Einstieg in die Programmierung von Geometrie erlernen möchten.
Der Kurs Grasshopper II folgende Grundlagen:
Kennenlernen der Script Componente
Erläuterung zum .NET Framework
Einführung in RhinoCommon SDK
Grundlagen d. imperativen / objektorientierten Programmierung
Datentypen, Operatoren, Eigenschaften
Variablen, Reihen, Listen, Aufzählungen
Methoden
Objekte und Klassen
Kontrollstrukturen: Bedingte Ausführung, Schleifen
praxisnahe iterative und rekursive Code-Beispiele für generatives Design unter Verwendung der RhinoCommon Geometrie Klassenbibiliothek - Punkt- und Vektorgeometrie erstellen, sortieren, bearbeiten, Flächen und Netze erstellen - Geometrie in das Rhino 3DM Dokument baken, einschließlich Attribute (Name, Layer, Color)
Einführung in die Entwicklungsumgebung MS Visual Studio Express Edition
Kompilieren von Programmerweiterungen (plug-ins) als Komponenten (custom components)
Details, Anmeldung:
www.vhs-stuttgart.de
Trainer Peter Mehrtens
Kursdauer: 3 Tage x 8 h
Freitag, 21.02.2014, 9:00-17:00 Uhr Samstag, 22.02.2014, 9:00-17:00 Uhr Sonntag, 23.02.2014, 9:00-17:00 Uhr Ort: VHS Stuttgart, Fritz-Elsas-Str. 46/48
Teilnahmegebühr 510,00 €…
and visualizing data for ENVI-Met 4 software. ENVI-met is a cutting edge software used to analyse microclimate interactions in urban environment. Tens of different analysis types can be performed on the chosen building context. From Mean radiant temperature and local Wind speed to CO2 concentration and Pollutant dispersion in the air. To generate the building context for Ladybug ENVI-met components, Antonello used Gismo:
An example similar to results in upper screenshots has been been attached below. To run it, Gismo, Ladybug and Human plugins need to be installed. To perform the ENVI-met analysis, download ENVI-met 4 Basic for free, and install it. Steps in the .gh example file have been labelled from 1 to 11. They mostly consist of just setting a boolean toggle to True. An exception to this are steps 6 (set the folder path of your ENVI-met application install folder), and 8 (running the ENVI-met simulation). Step 8 has been explained in detail in the photo attached below (step8.jpg). Special thanks to Antonello for developing and guidance on ENVI-met application and components! Post questions below if you have any issues!…
Added by djordje to Gismo at 11:30am on March 25, 2017
t file** - ply file with just x,y,z locations. I got it from a 3d scanner. Here is how first few lines of file looks like - ply format ascii 1.0 comment VCGLIB generated element vertex 6183 property float x property float y property float z end_header -32.3271 -43.9859 11.5124 -32.0631 -43.983 11.4945 12.9266 -44.4913 28.2031 13.1701 -44.4918 28.2568 13.4138 -44.4892 28.2531 13.6581 -44.4834 28.1941 13.9012 -44.4851 28.2684 ... ... ... In case you need the data - please email me on **nisha.m234@gmail.com**. **Algorithm:** I am trying to find principal curvatures for extracting the ridges and valleys. The steps I am following is: 1. Take a point x 2. Find its k nearest neighbors. I used k from 3 to 20. 3. average the k nearest neighbors => gives (_x, _y, _z) 4. compute covariance matrix 5. Now I take eigen values and eigen vectors of this covariance matrix 6. I get u, v and n here from eigen vectors. u is a vector corresponding to largest eigen value v corresponding to 2nd largest n is 3rd smallest vector corresponding to smallest eigen value 7. Then for transforming the point(x,y,z) I compute matrix T T = [ui ] [u ] [x - _x] [vi ] = [v ] x [y - _y] [ni ] [n ] [z - _z] 8. for each i of the k nearest neighbors:<br> [ n1 ] [u1*u1 u1*v1 v1*v1] [ a ]<br> [ n2 ] = [u2*u2 u2*v2 v2*v2] [ b ] <br> [... ] [ ... ... ... ] [ c ] <br> [ nk ] [uk*uk uk*vk vk*vk]<br> Solve this for a, b and c with least squares 9. this equations will give me a,b,c 10. now I compute eigen values of matrix [a b b a ] 11. This will give me 2 eigen values. one is Kmin and another Kmax. **My Problem:** The output is no where close to finding the correct Ridges and Valleys. I am totally Stuck and frustrated. I am not sure where exactly I am getting it wrong. I think the normal's are not computed correctly. But I am not sure. I am very new to graphics programming and so this maths, normals, shaders go way above my head. Any help will be appreciated. **PLEASE PLEASE HELP!!** **Resources:** I am using Visual Studio 2010 + Eigen Library + ANN Library. **Other Options used** I tried using MeshLab. I used ball pivoting triangles remeshing in MeshLab and then applied the polkadot3d shader. If correctly identifies the ridges and valleys. But I am not able to code it. **My Function:** //the function outputs to ply file void getEigen() { int nPts; // actual number of data points ANNpointArray dataPts; // data points ANNpoint queryPt; // query point ANNidxArray nnIdx;// near neighbor indices ANNdistArray dists; // near neighbor distances ANNkd_tree* kdTree; // search structure //for k = 25 and esp = 2, seems to got few ridges queryPt = annAllocPt(dim); // allocate query point dataPts = annAllocPts(maxPts, dim); // allocate data points nnIdx = new ANNidx[k]; // allocate near neigh indices dists = new ANNdist[k]; // allocate near neighbor dists nPts = 0; // read data points ifstream dataStream; dataStream.open(inputFile, ios::in);// open data file dataIn = &dataStream; ifstream queryStream; queryStream.open("input/query.
pts", ios::in);// open data file queryIn = &queryStream; while (nPts < maxPts && readPt(*dataIn, dataPts[nPts])) nPts++; kdTree = new ANNkd_tree( // build search structure dataPts, // the data points nPts, // number of points dim); // dimension of space while (readPt(*queryIn, queryPt)) // read query points { kdTree->annkSearch( // search queryPt, // query point k, // number of near neighbors nnIdx, // nearest neighbors (returned) dists, // distance (returned) eps); // error bound double x = queryPt[0]; double y = queryPt[1]; double z = queryPt[2]; double _x = 0.0; double _y = 0.0; double _z = 0.0; #pragma region Compute covariance matrix for (int i = 0; i < k; i++) { _x += dataPts[nnIdx[i]][0]; _y += dataPts[nnIdx[i]][1]; _z += dataPts[nnIdx[i]][2]; } _x = _x/k; _y = _y/k; _z = _z/k; double A[3][3] = {0,0,0,0,0,0,0,0,0}; for (int i = 0; i < k; i++) { double X = dataPts[nnIdx[i]][0]; double Y = dataPts[nnIdx[i]][1]; double Z = dataPts[nnIdx[i]][2]; A[0][0] += (X-_x) * (X-_x); A[0][1] += (X-_x) * (Y-_y); A[0][2] += (X-_x) * (Z-_z); A[1][0] += (Y-_y) * (X-_x); A[1][1] += (Y-_y) * (Y-_y); A[1][2] += (Y-_y) * (Z-_z); A[2][0] += (Z-_z) * (X-_x); A[2][1] += (Z-_z) * (Y-_y); A[2][2] += (Z-_z) * (Z-_z); } MatrixXd C(3,3); C <<A[0][0]/k, A[0][1]/k, A[0][2]/k, A[1][0]/k, A[1][1]/k, A[1][2]/k, A[2][0]/k, A[2][1]/k, A[2][2]/k; #pragma endregion EigenSolver<MatrixXd> es(C); MatrixXd Eval = es.eigenvalues().real().asDiagonal(); MatrixXd Evec = es.eigenvectors().real(); MatrixXd u,v,n; double a = Eval.row(0).col(0).value(); double b = Eval.row(1).col(1).value(); double c = Eval.row(2).col(2).value(); #pragma region SET U V N if(a>b && a>c) { u = Evec.row(0); if(b>c) { v = Eval.row(1); n = Eval.row(2);} else { v = Eval.row(2); n = Eval.row(1);} } else if(b>a && b>c) { u = Evec.row(1); if(a>c) { v = Eval.row(0); n = Eval.row(2);} else { v = Eval.row(2); n = Eval.row(0);} } else { u = Eval.row(2); if(a>b) { v = Eval.row(0); n = Eval.row(1);} else { v = Eval.row(1); n = Eval.row(0);} } #pragma endregion MatrixXd O(3,3); O <<u, v, n; MatrixXd UV(k,3); VectorXd N(k,1); for( int i=0; i<k; i++) { double x = dataPts[nnIdx[i]][0];; double y = dataPts[nnIdx[i]][1];; double z = dataPts[nnIdx[i]][2];; MatrixXd X(3,1); X << x-_x, y-_y, z-_z; MatrixXd T = O * X; double ui = T.row(0).col(0).value(); double vi = T.row(1).col(0).value(); double ni = T.row(2).col(0).value(); UV.row(i) << ui * ui, ui * vi, vi * vi; N.row(i) << ni; } Vector3d S = UV.colPivHouseholderQr().solve(N); MatrixXd II(2,2); II << S.row(0).value(), S.row(1).value(), S.row(1).value(), S.row(2).value(); EigenSolver<MatrixXd> es2(II); MatrixXd Eval2 = es2.eigenvalues().real().asDiagonal(); MatrixXd Evec2 = es2.eigenvectors().real(); double kmin, kmax; if(Eval2.row(0).col(0).value() < Eval2.row(1).col(1).value()) { kmin = Eval2.row(0).col(0).value(); kmax = Eval2.row(1).col(1).value(); } else { kmax = Eval2.row(0).col(0).value(); kmin = Eval2.row(1).col(1).value(); } double thresh = 0.0020078; if (kmin < thresh && kmax > thresh ) cout << x << " " << y << " " << z << " " << 255 << " " << 0 << " " << 0 << endl; else cout << x << " " << y << " " << z << " " << 255 << " " << 255 << " " << 255 << endl; } delete [] nnIdx; delete [] dists; delete kdTree; annClose(); } Thanks, NISHA…
TB of RAM. I think I'm going to start a GoFundMe campaign to buy one for myself :)
2- The server's cost is about $13 an hour. I get free access to supercomputer through my university and xsede.org because I earned an NSF Honorable mention last March, however, the supercomputers available through both resources are a little complicated for me to use, as opposed to the one available from amazon that has Microsoft server 2012 already installed.
3- I wanted to run 400 annual glare simulations for 400 different views.
4- I tried a to perform annual glare simulation for one view on my Dell XPS that has Intel Core i7-6700HQ processor and 16GB of system memory. The simulation took 2 hours to complete. Radiance parameter ab was set to 6.
5- I wanted to obtain the batch file for each view so I can run them on the server. So I used the fly component to run all 400 simulations and closed the cmd windows, that wasn't bad ( for me at least) because I asked my son to this job for me, he was just glad to help me :)
6- I created one batch file using this cmd command:
dir /s /b *.bat > runall.bat
This created a file with the path to each .bat file. I edited this file in Notepad++ to include the word "start" at the beginning of each line. This was done using the "find and replace" dialogue box.
7- I split my newly created batch file into 3 batch files, each one has about 130 file names and " start" before the file names.
8- installed radiance on my server
9- Ran the first batch file on the server, this started 130 cmd windows performing my simulations, CPU usage was anywhere between 90% to 100% and about 105 GB of RAMs were used.
10. It took about 5 hours to complete all 130 simulations, I expected to run all in 2 hours but can't complain because this would've taken about 260 hours to run on my laptop. After the simulations done I ran the second and then the third batch files ( total of about 15 hours).
11. I got 400 valid dgb files. Couldn't be happier!
…
une 7 at Madison Square Garden. Promoted by Miguel Cotto Promotions, Top Rank®, DiBella Entertainment and Sampson Boxing, in association with Maravilla Box, Tecate and Madison Square Garden.Fight Tickets and PPV InfoCotto vs Martinez tickets are now available for purchase online at Ticketnetwork. To charge by phone with a major credit card, call Buy Tickets Center at (855) 859-4045. The fight will be produced and distributed live by HBO Pay-Per-View®, beginning at 9:00 p.m. ET/6:00 p.m. PT.Hall of Fame trainer Freddie Roach is devising a cunning and effective strategy to, badger, outfox, and hound WBC middleweight champion Sergio “Maravilla” Martinez (51-2-2, 28KOs) into a brush with defeat, on June 7th at Madison Square Garden. Roach is training former three division world champion Miguel Cotto (38-4, 31KOs) for the match.“We have seen Martinez fights. I observed him closely when I was in Julio Cesar Chavez Jr’s corner, and he’s very fast. But…like all opponents he can be outboxed. If Miguel focuses on his body, Martinez will loose his speed and that’s when we will knock him out,” Roach mused.Cotto (38-4, 31 KO) and Martinez (51-2-2, 28 KO) will meet for Martinez’s WBC middleweight title and The Ring Magazine championship at Madison Square Garden, promoted by Top Rank, DiBella Entertainment, and Miguel Cotto Promotions.“Face Off” will premiere on Saturday, May 24 at Midnight EDT (so technically, the first minutes of Sunday, May 25, technically), after the May 24 HBO Boxing After Dark card, featuring Bryant Jennings vs Mike Perez, Daniel Geale vs Matthew Macklin, and Edwin Rodriguez vs Marcus Johnson.Other air times:HBO air times include: May 24 (12:00 a.m.), 25 (10:00 a.m.), 27 (3:15 p.m. & 2:30 a.m.), 28 (12:30 a.m.), 29 (5:30 p.m.), 30 (10:30 a.m.), 31 (7:00 p.m.) and June 3 (12:30 p.m. & 3:30 a.m.), 5 (1:15 a.m.), 6 (6:45 p.m.) and 7 (10:45 a.m.).HBO2 air times include: May 25 (5:30 p.m.), 26 (10:45 a.m. & 3:30 a.m.) 30 (4:00 p.m.) and 31 (11:30 p.m.).…
une 7 at Madison Square Garden. Promoted by Miguel Cotto Promotions, Top Rank®, DiBella Entertainment and Sampson Boxing, in association with Maravilla Box, Tecate and Madison Square Garden.Fight Tickets and PPV InfoCotto vs Martinez tickets are now available for purchase online at Ticketnetwork. To charge by phone with a major credit card, call Buy Tickets Center at (855) 859-4045. The fight will be produced and distributed live by HBO Pay-Per-View®, beginning at 9:00 p.m. ET/6:00 p.m. PT.Hall of Fame trainer Freddie Roach is devising a cunning and effective strategy to, badger, outfox, and hound WBC middleweight champion Sergio “Maravilla” Martinez (51-2-2, 28KOs) into a brush with defeat, on June 7th at Madison Square Garden. Roach is training former three division world champion Miguel Cotto (38-4, 31KOs) for the match.“We have seen Martinez fights. I observed him closely when I was in Julio Cesar Chavez Jr’s corner, and he’s very fast. But…like all opponents he can be outboxed. If Miguel focuses on his body, Martinez will loose his speed and that’s when we will knock him out,” Roach mused.Cotto (38-4, 31 KO) and Martinez (51-2-2, 28 KO) will meet for Martinez’s WBC middleweight title and The Ring Magazine championship at Madison Square Garden, promoted by Top Rank, DiBella Entertainment, and Miguel Cotto Promotions.“Face Off” will premiere on Saturday, May 24 at Midnight EDT (so technically, the first minutes of Sunday, May 25, technically), after the May 24 HBO Boxing After Dark card, featuring Bryant Jennings vs Mike Perez, Daniel Geale vs Matthew Macklin, and Edwin Rodriguez vs Marcus Johnson.Other air times:HBO air times include: May 24 (12:00 a.m.), 25 (10:00 a.m.), 27 (3:15 p.m. & 2:30 a.m.), 28 (12:30 a.m.), 29 (5:30 p.m.), 30 (10:30 a.m.), 31 (7:00 p.m.) and June 3 (12:30 p.m. & 3:30 a.m.), 5 (1:15 a.m.), 6 (6:45 p.m.) and 7 (10:45 a.m.).HBO2 air times include: May 25 (5:30 p.m.), 26 (10:45 a.m. & 3:30 a.m.) 30 (4:00 p.m.) and 31 (11:30 p.m.).…
une 7 at Madison Square Garden. Promoted by Miguel Cotto Promotions, Top Rank®, DiBella Entertainment and Sampson Boxing, in association with Maravilla Box, Tecate and Madison Square Garden.Fight Tickets and PPV InfoCotto vs Martinez tickets are now available for purchase online at Ticketnetwork. To charge by phone with a major credit card, call Buy Tickets Center at (855) 859-4045. The fight will be produced and distributed live by HBO Pay-Per-View®, beginning at 9:00 p.m. ET/6:00 p.m. PT.Hall of Fame trainer Freddie Roach is devising a cunning and effective strategy to, badger, outfox, and hound WBC middleweight champion Sergio “Maravilla” Martinez (51-2-2, 28KOs) into a brush with defeat, on June 7th at Madison Square Garden. Roach is training former three division world champion Miguel Cotto (38-4, 31KOs) for the match.“We have seen Martinez fights. I observed him closely when I was in Julio Cesar Chavez Jr’s corner, and he’s very fast. But…like all opponents he can be outboxed. If Miguel focuses on his body, Martinez will loose his speed and that’s when we will knock him out,” Roach mused.Cotto (38-4, 31 KO) and Martinez (51-2-2, 28 KO) will meet for Martinez’s WBC middleweight title and The Ring Magazine championship at Madison Square Garden, promoted by Top Rank, DiBella Entertainment, and Miguel Cotto Promotions.“Face Off” will premiere on Saturday, May 24 at Midnight EDT (so technically, the first minutes of Sunday, May 25, technically), after the May 24 HBO Boxing After Dark card, featuring Bryant Jennings vs Mike Perez, Daniel Geale vs Matthew Macklin, and Edwin Rodriguez vs Marcus Johnson.Other air times:HBO air times include: May 24 (12:00 a.m.), 25 (10:00 a.m.), 27 (3:15 p.m. & 2:30 a.m.), 28 (12:30 a.m.), 29 (5:30 p.m.), 30 (10:30 a.m.), 31 (7:00 p.m.) and June 3 (12:30 p.m. & 3:30 a.m.), 5 (1:15 a.m.), 6 (6:45 p.m.) and 7 (10:45 a.m.).HBO2 air times include: May 25 (5:30 p.m.), 26 (10:45 a.m. & 3:30 a.m.) 30 (4:00 p.m.) and 31 (11:30 p.m.).…
he default for Rhino, degree=5 gives you smoother curves, but each control point matters less, degree=11 is the highest degree Rhino allows. Apart from 2, degrees tend to be odd rather than even, though Rhino supports both.
In addition to the degree and the control points, Nurbs curves have knots. A single knot is just a number, and the list of all knots is called the knot-vector of a curve. The number of knots depends on both the degree and the control-point count, and the spacing of the knots affects the shape of the curve a little bit. If there are <degree> knots with the same value, then the curve is somewhat discontinuous at that location which could manifest itself as a kink or as a clamped end-point. However it is not possible by just looking at the shape of a curve to say where stacked knots might be, but you can use the Rhino _List command to inspect all details of a Nurbs curve.…
para poder parametrizarla - Entender cómo se gestionan los datos con Grasshopper - Asociar formulaciones matemáticas a modelos paramétricos - Panelizar y triangular superficies - Parametrizar estructuras sencillas - Saber deformar modelos tridimensionales paramétricamente - Elaboración de algoritmos simples y aplicarlos a modelos tridimensionales - Exportar e importar tablas de datos
El curso será impartido por dos Authorized Rhino Trainers.
También te informamos de que hemos renovado el temario del curso, preparado específica y exclusivamente por nosotros, y que es revisado y ampliado continuamente, gracias a la experiencia de cursos anteriores. El curso tiene un formato intensivo de 18 horas, cuyo horario es: - viernes, de 16 a 20; - sábado, de 10 a 14 y de 16 a 20; - domingo, de 11 a 14 y de 16 a 19.
Si estás interesado en apuntarte, contáctanos en: cursos@frikearq.com…
is set up to manipulate strings into an STL file that is quite different from how Grasshopper defines meshes, in that an STL seems to define each face by XYZ points, Grasshopper wants a single list of all vertex points and then has an allied lists of topological connectivity according to vertex number, so for now I just hacked it to spit out points minus so many duplicates it generates for STL:
Right now it has an internal 3D trigonometric function I added input sliders to control, that creates surfaces that look a lot like molecular orbitals.
So how do I make a mesh? I failed to make a single mesh face from each STL face since AddMesh seems to want a list, so I tried making a single list and matching it with a simple ((1,2,3),(4,5,6),(7,8,9)...) array of connectivity but it hasn't worked yet since the STL list of vertices has duplicates that won't work for Grasshopper and removing the duplicates scrambles the connectivity relation.
After some work on this and seeing the output, I figure I could just randomly populate the mathematical function with points instead, unless it really gives a better mesh result than other routines. I'm not sure what to do with it yet, even if I get the mesh figured out.
import rhinoscriptsyntaximport RhinoPOINTS_CONTAINER =[]POINTS = []class Vector: # struct XYZ def __init__(self,x,y,z): self.x=x self.y=y self.z=z def __str__(self): return str(self.x)+" "+str(self.y)+" "+str(self.z) class Gridcell: # struct GRIDCELL def __init__(self,p,n,val): self.p = p # p=[8] self.n = n # n=[8] self.val = val # val=[8] class Triangle: # struct TRIANGLE def __init__(self,p1,p2,p3): self.p = [p1, p2, p3] # vertices # HACK TO GRAB VERTICES FOR PYTHON OUTPUT POINTS_CONTAINER.append( (p1.x,p1.y,p1.z) ) POINTS_CONTAINER.append( (p2.x,p2.y,p2.z) ) POINTS_CONTAINER.append( (p3.x,p3.y,p3.z) )# return a 3d list of values def readdata(f=lambda x,y,z:x*x+y*y+z*z,size=5.0,steps=11): m=int(steps/2) ki = [] for i in range(steps): kj = [] for j in range(steps): kd=[] for k in range(steps): kd.append(f(size*(i-m)/m,size*(j-m)/m,size*(k-m)/m)) kj.append(kd) ki.append(kj) return ki from math import sin,cos,exp,atan2 def lobes(x,y,z): try: theta = atan2(x,y) # sin t = o except: theta = 0 try: phi = atan2(z,y) except: phi = 0 r = x*x+y*y+z*z ct=cos(PARAMETER_A * theta) cp=cos(PARAMETER_B * phi) return ct*ct*cp*cp*exp(-r/10) def main(): data = readdata(lobes,10,40) isolevel = 0.1 #print(data) triangles=[] for i in range(len(data)-1): for j in range(len(data[i])-1): for k in range(len(data[i][j])-1): p=[None]*8 val=[None]*8 #print(i,j,k) p[0]=Vector(i,j,k) val[0] = data[i][j][k] p[1]=Vector(i+1,j,k) val[1] = data[i+1][j][k] p[2]=Vector(i+1,j+1,k) val[2] = data[i+1][j+1][k] p[3]=Vector(i,j+1,k) val[3] = data[i][j+1][k] p[4]=Vector(i,j,k+1) val[4] = data[i][j][k+1] p[5]=Vector(i+1,j,k+1) val[5] = data[i+1][j][k+1] p[6]=Vector(i+1,j+1,k+1) val[6] = data[i+1][j+1][k+1] p[7]=Vector(i,j+1,k+1) val[7] = data[i][j+1][k+1] grid=Gridcell(p,[],val) triangles.extend(PolygoniseTri(grid,isolevel,0,2,3,7)) triangles.extend(PolygoniseTri(grid,isolevel,0,2,6,7)) triangles.extend(PolygoniseTri(grid,isolevel,0,4,6,7)) triangles.extend(PolygoniseTri(grid,isolevel,0,6,1,2)) triangles.extend(PolygoniseTri(grid,isolevel,0,6,1,4)) triangles.extend(PolygoniseTri(grid,isolevel,5,6,1,4)) def t000F(g, iso, v0, v1, v2, v3): return [] def t0E01(g, iso, v0, v1, v2, v3): return [Triangle( VertexInterp(iso,g.p[v0],g.p[v1],g.val[v0],g.val[v1]), VertexInterp(iso,g.p[v0],g.p[v2],g.val[v0],g.val[v2]), VertexInterp(iso,g.p[v0],g.p[v3],g.val[v0],g.val[v3])) ] def t0D02(g, iso, v0, v1, v2, v3): return [Triangle( VertexInterp(iso,g.p[v1],g.p[v0],g.val[v1],g.val[v0]), VertexInterp(iso,g.p[v1],g.p[v3],g.val[v1],g.val[v3]), VertexInterp(iso,g.p[v1],g.p[v2],g.val[v1],g.val[v2])) ] def t0C03(g, iso, v0, v1, v2, v3): tri=Triangle( VertexInterp(iso,g.p[v0],g.p[v3],g.val[v0],g.val[v3]), VertexInterp(iso,g.p[v0],g.p[v2],g.val[v0],g.val[v2]), VertexInterp(iso,g.p[v1],g.p[v3],g.val[v1],g.val[v3])) return [tri,Triangle( tri.p[2], VertexInterp(iso,g.p[v1],g.p[v2],g.val[v1],g.val[v2]), tri.p[1]) ] def t0B04(g, iso, v0, v1, v2, v3): return [Triangle( VertexInterp(iso,g.p[v2],g.p[v0],g.val[v2],g.val[v0]), VertexInterp(iso,g.p[v2],g.p[v1],g.val[v2],g.val[v1]), VertexInterp(iso,g.p[v2],g.p[v3],g.val[v2],g.val[v3])) ] def t0A05(g, iso, v0, v1, v2, v3): tri = Triangle( VertexInterp(iso,g.p[v0],g.p[v1],g.val[v0],g.val[v1]), VertexInterp(iso,g.p[v2],g.p[v3],g.val[v2],g.val[v3]), VertexInterp(iso,g.p[v0],g.p[v3],g.val[v0],g.val[v3])) return [tri,Triangle( tri.p[0], VertexInterp(iso,g.p[v1],g.p[v2],g.val[v1],g.val[v2]), tri.p[1]) ] def t0906(g, iso, v0, v1, v2, v3): tri=Triangle( VertexInterp(iso,g.p[v0],g.p[v1],g.val[v0],g.val[v1]), VertexInterp(iso,g.p[v1],g.p[v3],g.val[v1],g.val[v3]), VertexInterp(iso,g.p[v2],g.p[v3],g.val[v2],g.val[v3])) return [tri, Triangle( tri.p[0], VertexInterp(iso,g.p[v0],g.p[v2],g.val[v0],g.val[v2]), tri.p[2]) ] def t0708(g, iso, v0, v1, v2, v3): return [Triangle( VertexInterp(iso,g.p[v3],g.p[v0],g.val[v3],g.val[v0]), VertexInterp(iso,g.p[v3],g.p[v2],g.val[v3],g.val[v2]), VertexInterp(iso,g.p[v3],g.p[v1],g.val[v3],g.val[v1])) ] trianglefs = {7:t0708,8:t0708,9:t0906,6:t0906,10:t0A05,5:t0A05,11:t0B04,4:t0B04,12:t0C03,3:t0C03,13:t0D02,2:t0D02,14:t0E01,1:t0E01,0:t000F,15:t000F} def PolygoniseTri(g, iso, v0, v1, v2, v3): triangles = [] # Determine which of the 16 cases we have given which vertices # are above or below the isosurface triindex = 0; if g.val[v0] < iso: triindex |= 1 if g.val[v1] < iso: triindex |= 2 if g.val[v2] < iso: triindex |= 4 if g.val[v3] < iso: triindex |= 8 return trianglefs[triindex](g, iso, v0, v1, v2, v3) def VertexInterp(isolevel,p1,p2,valp1,valp2): if abs(isolevel-valp1) < 0.00001 : return(p1); if abs(isolevel-valp2) < 0.00001 : return(p2); if abs(valp1-valp2) < 0.00001 : return(p1); mu = (isolevel - valp1) / (valp2 - valp1) return Vector(p1.x + mu * (p2.x - p1.x), p1.y + mu * (p2.y - p1.y), p1.z + mu * (p2.z - p1.z)) if __name__ == "__main__": main() # GRASSHOPPER PYTHON OUTPUTPOINTS = rhinoscriptsyntax.AddPoints(POINTS_CONTAINER)POINTS = rhinoscriptsyntax.CullDuplicatePoints(POINTS)…