Blog

August 12, 2019

Parametric Wall for Cement 3D Printing

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
Gh Definition!
You can download the file here and drag it to you Grasshopper canvas directly!
Architecture, CAD/CAM, Coding, Digital Fabrication, Generative Design, Integrated Design, OpenSource, Research & Development, Technical Design , , , ,
0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments