将Rhino Mesh转换为BufferGeometry JSON

我正在尝试将Grasshopper python中的犀牛网格转换为BufferGeometry,将在Three.js / WebGL中读取。 Three.js确实具有从.obj到Three.js的转换器,但是对于我的工作流程,我需要将这些文件作为JSON从GH输出,而不是先将其保存为.obj。

我有一个旧的转换器,该转换器会输入一个犀牛网格然后输出一个Geometry,但是由于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,"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,1,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,"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,207.021728515625,-100.83158111572266,210.00543212890625,209.0108642578125,208.01629638671875,-101.75260925292969,-102.67362976074219,-103.59465026855469,207.68478393554687,208.34782409667969,209.67390441894531,210.33694458007813,-102.85783386230469,-102.12101745605469,-101.38420104980469,-100.64737701416016,207.021728515625],"normalized":false,"itemSize":3,"type":"Float32Array"},"normal":{"array":[0,-1,-1],"type":"Float32Array"}}}}
kangzhai77 回答:将Rhino Mesh转换为BufferGeometry JSON

正如您所提到的,Threejs JSON格式4已过时,并且ObjectLoader不包含在最新版本的threejs中。不再支持的原因之一是因为glTF格式已成为Web的首选选项。据我所知,截至本文发布之时,没有针对Rhino / GH的glTF导出器。

您有很多选择:

  1. 将此legacy JSON loader添加到您的网站
  2. 选择一种文件类型,该文件类型既可以从Rhino / Grasshopper导出,又可以为Threejs(即OBJ,FBX)加载器
  3. 从Rhino中导出为OBJ,FBX或其他文件类型,然后使用其他软件或进程将其转换为glTF。
  4. 从Rhino / GH创建glTF导出器
  5. 还原为支持threejs JSON格式4的Threejs(r99之前)的旧版本
本文链接:https://www.f2er.com/3144015.html

大家都在问