我正在尝试将 Grasshopper python 中的犀牛网格转换为将在 Three.js/WebGL 中读取的 BufferGeometry。Three.js 确实有可用于从 .obj 到 three.js 的转换器,但对于我的工作流程,我需要将这些文件作为 JSON 从 GH 输出,而不先将其保存为 .obj。
我有一个旧转换器,它可以输入一个犀牛网格然后输出一个几何图形,但是从 Three.js r.99 开始,现在不推荐使用 JSON 格式。我创建了一个脚本,它输入一个网格并创建一个像JSON Geometry Format 4这样的数据结构。几何正在使用OBJLoader成功加载,但我收到以下错误。
glDrawArrays:尝试访问属性 1 中超出范围的顶点
提前致谢!
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"}}}}