Warming up by training through RhinoCommon Namespaces
From openNurbs (founded by Robert McNeel and Associates) and C++ Rhino Core to C++ SDK then C and .NET by the left hand and RhinoScript by right, we get to the platforms where they provide us developing our add-ons whether with Grasshopper either Scripts by different programming languages like Python. This is the way we have access to Grasshopper and Python Scripts. By a step towards getting to know more about RhinoCommon, I direct one of our projects needed to be OpenSource for developing abilities.
To have an adapted model to the issue or system we look for, we need to have everything parametric. The project has been presented by Prof. Navid Ranjbar from DTU. To have a component in Grasshopper3D for generating different models of a wall according to the printer specifications, this code has been written in Python within the GHPython component. I tried to define something with a comprehensive variety of options through using RhinoCommon, GHPython, and Data Structures. It helps designers to match the Meshing process related to what they need to print and bake it in a layer just with a few clicks. This is where I teach how to work with Namespaces and deal with the RhinoCommon loaded by different approaches and different types of data.
RhinoCommon: Classes
"""Provides a scripting component. Inputs: ModelName: The typology undergoing Name to save as the file FilePath: Give it the path you want for *.stl SaveTheModel: Just Click once to save an stl file of the Mesh Length: Lenght of the Wall (mm) Partition: The same Length used for Chunk! Height: Height of the Wall (mm) Volumetrical: If it needs thickness (True/False) Thickness: The amount of thickness (mm) WaveC: Sin Coefficient Scalar_Fixed: If the waves are fixed or it might be scalar (True/False) Output: Mesh: The a output Mesh Model""" ###-------------Modules---------------### import rhinoscriptsyntax as rs import Rhino.Geometry as rg from math import sin ###------------Lists & Variables to be defined for the Model---------### MovedOdds = [] MovedEvens = [] PlanesO = [] PlanesE = [] Height = Heights + 1 ###----------Definitions-----------### ###----------The Wall Based for Developable Surface-----------### #General Plane Definition _Point = rg.Point3d(0,0,0) _Vec = rg.Vector3d(0,0,1) _Plane = rg.Plane(_Point, _Vec) #Ground Rules on Plane (0,0,0) for i in range(0, Length): L_PointsPlus = [rg.Point3d(i, hyper*sin(WaveC*Length), 0)] L_PointsMinus = [rg.Point3d(i, hyper*sin(-WaveC*Length), 0)] #Even planes and Points Definition for j in range(0, Height, 2): _Vec = rg.Vector3d(0,0,1) _Point = rg.Point3d(0,0,H_Coefficient*j) PlaneEven = rg.Plane(_Point, _Vec) x_form_e = rg.Transform.PlaneToPlane(_Plane, PlaneEven) Moved_E = rg.Transform.TransformList(x_form_e, L_PointsPlus) #Moved_e = rs.TransformObject(L_PointsPlus, x_form_e, True) PlanesE.append(PlaneEven) MovedEvens.append(Moved_E[0]) j += 1 #Odd planes and Points Definition for k in range(1, Height, 2): _Vec = rg.Vector3d(0,0,1) _Point = rg.Point3d(0,0,H_Coefficient*k) PlaneOdd = rg.Plane(_Point, _Vec) x_form_o = rg.Transform.PlaneToPlane(_Plane, PlaneOdd) Moved_O = rg.Transform.TransformList(x_form_o, L_PointsMinus) #Moved_o = rs.TransformObject(L_PointsMinus, x_form_o, True) PlanesO.append(PlaneOdd) MovedOdds.append(Moved_O[0]) k += 1 Length += 1
RhinoCommon: Classes’s elements, Properties, Events, Enumerations
###-----------------Working with data as lists------------### ##---------------------------------------------------------## #Height Counter if Heights % 2 == 1: nEvens = (Heights + 1)/2 nOdds = (Heights)/2 elif Heights % 2 == 0: nEvens = (Heights)/2 nOdds = (Heights)/2 print int(nEvens), "|", int(nOdds) ###--------------------MovedEvens Data Structure----------### ##---------------------------------------------------------## MovedEvens_n = [] nE = 0 while nE < nEvens: for i in range(nE, int(len(MovedEvens)), int(nEvens)): MovedEvens_n.append(MovedEvens[i]) nE = nE + 1 #Index Ranging Selection for Even --->>> nEvensList = [] for i in range(0,int(nEvens), 1): nEvensList.append(i) print nEvensList #Indexes Generator EvenIndexes = [i for i in range(0, Partition*int(nEvens))] #print EvenIndexes #Indexes Categorizing GeneralEvenList = [] for j in range(int(nEvens)): GeneralEvenList.append(EvenIndexes[j*Partition : (j + 1)*Partition]) print GeneralEvenList #Data Tree Structure MovedEvensTree = DataTree[object]() #Data Trees Definitions for Evens for i in range(0, int(nEvens)): for j in range(len(GeneralEvenList[i])): EvenPoints = MovedEvens_n[GeneralEvenList[i][j]] pathEven = ghpath(i) MovedEvensTree.Add(EvenPoints, pathEven) j += 1 i += 1 ###----------------MovedOdds data structure---------------### ##---------------------------------------------------------## MovedOdds_n = [] nO = 0 while nO < nOdds: for j in range(nO, int(len(MovedOdds)), int(nOdds)): MovedOdds_n.append(MovedOdds[j]) nO = nO + 1 #Index Ranging Selection for Odds --->>> nOddsList = [] for i in range(0,int(nOdds), 1): nOddsList.append(i) print nOddsList #Indexes Generator OddIndexes = [i for i in range(0, Partition*int(nOdds))] #print OddIndexes #Indexes Categorizing GeneralOddList = [] for j in range(int(nOdds)): GeneralOddList.append(OddIndexes[j*Partition : (j + 1)*Partition]) print GeneralOddList #print nOddsList #Data Tree Structure MovedOddsTree = DataTree[object]() #Data Trees Definitions for Odds for i in range(0, int(nOdds)): for j in range(len(GeneralOddList[i])): OddPoints = MovedOdds_n[GeneralOddList[i][j]] pathOdd = ghpath(i) MovedOddsTree.Add(OddPoints, pathOdd) j += 1 i += 1 SlicedOdds = MovedOddsTree SlicedEvens = MovedEvensTree ###----------PolyLinear Surface based on Data Trees-------### ##---------------------------------------------------------## #EvenTrees Polylines EvenPolies = [] for i in range(int(nEvens)): EvenPs = MovedEvensTree.Branch(i) PoliesEven = rg.Curve.CreateInterpolatedCurve(EvenPs, 3, 0) EvenPolies.append(PoliesEven) i += 1 DataE = EvenPolies #for i in range(len(MovedEvensTree)) OddPolies = [] for i in range(int(nOdds)): OddPs = MovedOddsTree.Branch(i) PoliesOdd = rg.Curve.CreateInterpolatedCurve(OddPs, 3, 0) OddPolies.append(PoliesOdd) i += 1 DataO = OddPolies
RhinoCommon: Scriptcontext
###----------------------Volumetrisism and Meshing-------------------------### ###------------------------------------------------------------------------### ###------------------------------------------------------------------------### #2D >>> 3D Shaping The Mode #Sorting PolyLines SortPolies = [] if Height % 2 == 0: for i , j in zip(EvenPolies, OddPolies): SortPolies.append(i) SortPolies.append(j) #SortPolies.append(OddPolies[-1]) else: for i , j in zip(EvenPolies, OddPolies): SortPolies.append(i) SortPolies.append(j) SortPolies.append(EvenPolies[-1]) #Surface Generation 2D & 3D MainSurface = rg.Brep.CreateFromLoft(SortPolies, rg.Point3d.Unset, rg.Point3d.Unset, rg.LoftType.Loose, False) ExtrudeVec = rg.Vector3d(0, Thickness, 0) MidPointSrf = rg.Surface.PointAt(MainSurface[0].Faces[0], 0.5, 0.5) print MidPointSrf _3dSrf = ghcomp.Extrude(MainSurface, ExtrudeVec) #Meshing Process MeshModel = rg.Mesh.CreateFromBrep(_3dSrf, rg.MeshingParameters(MeshDens, MinEdgeL)) FinalMesh = rg.Mesh() for mesh in MeshModel: FinalMesh.Append(mesh) ###----------------------Baking and Layer Substitution---------### sc.doc = r.RhinoDoc.ActiveDoc #Layer Names LayerName = "Meshi-Mesh" #Baking if SaveTheModel: MeshA = rd.ObjectAttributes() MeshA.ColorSource = rd.ObjectColorSource.ColorFromObject MeshA.ObjectColor = MeshColor AimedLayer = sc.doc.Layers.Find(LayerName, True) if AimedLayer < 0: Layer = rd.Layer() Layer.Name = LayerName AimedLayer = sc.doc.Layers.Add(Layer) MeshA.LayerIndex = AimedLayer sc.doc.Objects.AddMesh(FinalMesh, MeshA) sc.doc = ghdoc ###--------------Checking DATA needed for analysis------------### #Mesh Volume MeshVol = "The Mesh Volume is: {} mm3 nwhich Equals to: {} cc".format(rg.Mesh.Volume(FinalMesh), 0.001*rg.Mesh.Volume(FinalMesh)) print type(MainPoints) print MovedOddsTree print MovedEvensTree