Hello,
I am trying to apply this code to generate the pasta form, unfortunately I am getting an error : unable to add mesh
Here is the code :
import rhinoscriptsyntax as rs
import math
n_u = 128
n_v = 128
point_list =
polygon_list =
for i in range(0,n_v+1):
v = i / n_v
for j in range(0,n_u+1):
u = j / n_u #Agnolotti page 016
x = 10.0math.sqrt(math.sin(u/2.0math.pi)+u0.15math.sin(v30.0math.pi))math.cos(v0.95math.pi+0.03math.pi)
y = 10.0* math.sin(u/2.0math.pi)+u0.15math.cos(v30.0math.pi) math.sin(v0.95math.pi+0.03)
z = 5.0math.pow(math.cos(u/2.0math.pi),5)math.sin(vmath.pi)-5.0math.sin(vmath.pi)math.pow(math.cos(u/2.0math.pi),200)
point_list.append ([x,y,z])
for i in range(0,n_v):
for j in range(0,n_u):
p0 = i*(n_u+1)+j
p1 = i*(n_u+1)+j+1
p2 = (i+1)(n_u+1)+j+1
p3 = (i+1)(n_u+1)+j
polygon_list.append ([p0,p1,p2,p3])
rs.AddMesh(point_list,polygon_list)
Is this related to GHPython? If so, please attach your implementation in a Grasshopper definition and maybe a screenshot of the error you’re getting.
Note that the rhinoscriptsyntax methods operate on/return GUIDs (as this module is designed for targeting the Rhino document). However, when outputting to the canvas the PastaMesh variable is automatically cast to its underlying RhinoCommon Mesh object:
So you can use rhinoscriptsyntax, but I generally recommend sticking with straight up RhinoCommon for geometry generation and manipulation in GHPython (for numerous reasons that have been covered here and on the old Grasshopper forum). Though there might be an initially steeper learning curve (which I still don’t really subscribe to, from experience, but again everyone is different etc).
Might be a versioning thing, I’m still on Rhino 5. Perhaps one of the Rhino devs can have a look (or someone else with Rhino 6 installed, just to verify).
using rhinocommon, you can get a mesh out, but I’m not sure the final result is correct. As far as the inital error, the rhinocommon method IsValidWIthLog() indicates the following error: (False, 'ON_Mesh.m_F[0] has degenerate double precision vertex locations.\n')
Not sure if this is the correct interpretation of what you wanted, but here is the rhinocommon version that uses the IsValidWIthLog() to get the “raw” mesh status, then applies some cleanup operations that creates a “valid” mesh. (it still looks incorrect though…)
import rhinoscriptsyntax as rs
import math
import Rhino
n_u = 128
n_v = 128
point_list = []
polygon_list = []
newMesh = Rhino.Geometry.Mesh()
for i in range(0,n_v+1):
v = i / n_v
for j in range(0,n_u+1):
u = j / n_u
x = 10.0*math.sqrt(math.sin(u/2.0*math.pi)+u*0.15*math.sin(v*30.0*math.pi))*math.cos(v*0.95*math.pi+0.03*math.pi)
y = 10.0* math.sin(u/2.0*math.pi)+u*0.15*math.cos(v*30.0*math.pi) *math.sin(v*0.95*math.pi+0.03)
z = 5.0*math.pow(math.cos(u/2.0*math.pi),5)*math.sin(v*math.pi)-5.0*math.sin(v*math.pi)*math.pow(math.cos(u/2.0*math.pi),200)
#point_list.append ([x,y,z])
newMesh.Vertices.Add(x, y, z)
for i in range(0,n_v):
for j in range(0,n_u):
p0 = i*(n_u+1)+j
p1 = i*(n_u+1)+j+1
p2 = (i+1)*(n_u+1)+j+1
p3 = (i+1)*(n_u+1)+j
#polygon_list.append ([p0,p1,p2,p3])
newMesh.Faces.AddFace(p0,p1,p2,p3)
print newMesh.IsValidWithLog()
newMesh.Faces.CullDegenerateFaces()
newMesh.Vertices.CullUnused()
newMesh.Vertices.CombineIdentical(True, True)
newMesh.Weld(math.pi)
newMesh.Normals.ComputeNormals()
newMesh.FaceNormals.ComputeFaceNormals()
newMesh.Compact()
print newMesh.IsValidWithLog()
this is just Rhino 6 being more investigative than Rhino 5, where bad meshes could more easily end into the document. In particular, the first face is unfortunately wrong! And the reason is, that the script only adds QUADS (4-sides faces) but these are definitely not quadrangular faces:
These are triangles, and should be added as such!
We can also just keep your script the same, and rescue the position where the wrong quads (collapsed quads) would be added. Here is how:
import rhinoscriptsyntax as rs
import math
import Rhino
n_u = 128
n_v = 128
point_list = []
polygon_list = []
for i in range(0,n_v+1):
v = i / n_v
for j in range(0,n_u+1):
u = j / n_u
x = 10.0*math.sqrt(math.sin(u/2.0*math.pi)+u*0.15*math.sin(v*30.0*math.pi))*math.cos(v*0.95*math.pi+0.03*math.pi)
y = 10.0* math.sin(u/2.0*math.pi)+u*0.15*math.cos(v*30.0*math.pi) *math.sin(v*0.95*math.pi+0.03)
z = 5.0*math.pow(math.cos(u/2.0*math.pi),5)*math.sin(v*math.pi)-5.0*math.sin(v*math.pi)*math.pow(math.cos(u/2.0*math.pi),200)
point_list.append ([x,y,z])
for i in range(0,n_v):
for j in range(0,n_u):
p0 = i*(n_u+1)+j
p1 = i*(n_u+1)+j+1
p2 = (i+1)*(n_u+1)+j+1
p3 = (i+1)*(n_u+1)+j
curr = [p0,p1,p2,p3]
#rescue collapsed quads
if point_list[curr[3]] == point_list[curr[0]]: curr.remove(curr[3])
elif point_list[curr[2]] == point_list[curr[3]]: curr.remove(curr[3])
if point_list[curr[1]] == point_list[curr[2]]: curr.remove(curr[2])
if point_list[curr[0]] == point_list[curr[1]]: curr.remove(curr[1])
if len (curr) >= 3: polygon_list.append(curr)
PastaMesh = rs.AddMesh(point_list,polygon_list)
These collapsed quads will then interfere with normals calculation, booleans, etc, and just make everything inconsistent in Rhino 5. Rhino 6 goes in the right direction of pointing out the problem.
Thanks,
Giulio
–
Giulio Piacentino
for Robert McNeel & Associates giulio@mcneel.com