Reputation: 121
I am attempting to convert a rhino mesh in Grasshopper python to a BufferGeometry that will be read in Three.js/WebGL. Three.js does have converters available to go from .obj to three.js, but for my workflow, I need these files to be outputted from GH as a JSON without saving it as a .obj first.
I had an old converter that would input a rhino mesh then output a Geometry, but since Three.js r.99 that JSON format is now deprecated. I have created a script that inputs a mesh and creates a data structure like JSON Geometry Format 4. The geometry is being successfully loaded using OBJLoader, but I am getting the following error.
glDrawArrays: attempt to access out of range vertices in attribute 1
Thanks in Advance!
from System import Guid
import rhinoscriptsyntax as rs
import json
# initiate lists to fill
geometryList = []
childrenList = []
# loop through input meshes
for i, mesh in enumerate(meshes):
# get UUID
geometry_guid = str(Guid.NewGuid())
# JSON BufferGeometry Structure
geometryDict = {
"uuid": geometry_guid,
"type": "BufferGeometry",
"data": {
"attributes":{
"position":{
"itemSize": 3,
"type": "Float32Array",
"array":[],
"normalized": False
},
"normal":{
"itemSize": 3,
"type": "Float32Array",
"array":[],
"normalized": False
}
}
}
}
# children Dict
# values such as name, visible are input values from GH
childrenDict = {
"uuid": str(Guid.NewGuid()),
"type": "Mesh",
"name": name,
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
"geometry": geometry_guid,
"material": material.d['uuid'],
"visible":visible,
"castShadow": cast_shadow,
"receiveShadow": receive_shadow,
"userData": {}
}
# start index
vertexIndex = 0
# vertex array creation
vertexArray = [None] * (len(rs.MeshVertices(mesh)) *3)
# loop through vertices and append to vertex array
for vertex in rs.MeshVertices(mesh):
vertexArray[vertexIndex*3] = vertex[0]
vertexArray[vertexIndex*3+1] = vertex[1]
vertexArray[vertexIndex*3+2] = vertex[2]
vertexIndex+=1
# add to geometry dictionary
geometryDict['data']['attributes']['position']['array'] = vertexArray
# loop through faces
faceVertices = []
for face in rs.MeshFaceVertices(mesh):
faceVertices.append(face[0])
faceVertices.append(face[1])
faceVertices.append(face[2])
if face[2] != face[3]:
faceVertices.append(face[2])
faceVertices.append(face[3])
faceVertices.append(face[0])
# normal index
normalIndex = 0
# normal array creation
normalArray = [None] * (len(rs.MeshFaceNormals(mesh)) *3)
for normal in rs.MeshFaceNormals(mesh):
normalArray[normalIndex*3] = normal[0]
normalArray[normalIndex*3+1] = normal[1]
normalArray[normalIndex*3+2] = normal[2]
normalIndex+=1
# add normal array to geometry dictionary
geometryDict['data']['attributes']['normal']['array'] = normalArray
geometryList.append(geometryDict)
childrenList.append(childrenDict)
# these meshes are later added to the parent JSON Structure
class GhPythonDictionary(object):
def __init__(self, pythonDict=None):
if pythonDict:
self.d = pythonDict
else:
self.d = {
"material": material.d,
"geometries": geometryList,
"children": childrenList
}
def ToString(self):
return 'GhPythonDictionary object'
mesh_object = GhPythonDictionary()
# master dictionary. all scene data goes in here
featureDict = {
"metadata": {
"version": 4.5,
"type": "Object",
"generator": "Object3D.toJSON",
},
"geometries":[],
"materials":[],
"object":{
"uuid": "378FAA8D-0888-4249-8701-92D1C1F37C51",
"type": "Group",
"name": file_name,
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
"children": []
}
}
for i in range(len(mesh_objects)):
for j in range(len(mesh_objects[i].d['geometries'])):
featureDict['geometries'].append(mesh_objects[i].d['geometries'][j])
featureDict['materials'].append(mesh_objects[i].d['material'])
for j in range(len(mesh_objects[i].d['children'])):
featureDict['object']['children'].append(mesh_objects[i].d['children'][j])
# file path as a string input from GH
file_path = path + '\\' + file_name + '.json'
# write file to folder path
with open(file_path, 'wb') as outfile:
json.dump(featureDict, outfile)
// example of a mesh object created
{"uuid":"77589f14-6476-4517-b371-846920b9464b","type":"BufferGeometry","data":{"attributes":{"position":{"array":[-99.910560607910156,7.6936740875244141,211,-99.910560607910156,7.6936740875244141,207.021728515625,-100.83158111572266,7.6936740875244141,211,-100.83158111572266,7.6936740875244141,210.00543212890625,-100.83158111572266,7.6936740875244141,209.0108642578125,-100.83158111572266,7.6936740875244141,208.01629638671875,-101.75260925292969,7.6936740875244141,211,-101.75260925292969,7.6936740875244141,210.00543212890625,-101.75260925292969,7.6936740875244141,209.0108642578125,-101.75260925292969,7.6936740875244141,208.01629638671875,-102.67362976074219,7.6936740875244141,211,-102.67362976074219,7.6936740875244141,210.00543212890625,-102.67362976074219,7.6936740875244141,209.0108642578125,-102.67362976074219,7.6936740875244141,208.01629638671875,-103.59465026855469,7.6936740875244141,211,-103.59465026855469,7.6936740875244141,207.021728515625,-99.910560607910156,7.6936740875244141,207.68478393554687,-99.910560607910156,7.6936740875244141,208.34782409667969,-99.910560607910156,7.6936740875244141,209.0108642578125,-99.910560607910156,7.6936740875244141,209.67390441894531,-99.910560607910156,7.6936740875244141,210.33694458007813,-103.59465026855469,7.6936740875244141,210.33694458007813,-103.59465026855469,7.6936740875244141,209.67390441894531,-103.59465026855469,7.6936740875244141,209.0108642578125,-103.59465026855469,7.6936740875244141,208.34782409667969,-103.59465026855469,7.6936740875244141,207.68478393554687,-102.85783386230469,7.6936740875244141,207.021728515625,-102.12101745605469,7.6936740875244141,207.021728515625,-101.38420104980469,7.6936740875244141,207.021728515625,-100.64737701416016,7.6936740875244141,207.021728515625],"normalized":false,"itemSize":3,"type":"Float32Array"},"normal":{"array":[0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1,0,-1,-1],"normalized":false,"itemSize":3,"type":"Float32Array"}}}}
Upvotes: 0
Views: 737
Reputation: 11
As you mentioned threejs JSON format 4 is deprecated and the ObjectLoader is not included with the most recent builds of threejs. One reason it's no longer supported is because glTF format has become the preferred option for web. To my knowledge, there is no glTF exporter for Rhino/GH available as of the time of this post.
You have a number of options:
Upvotes: 1