简体   繁体   English

从Rhino3d将图层导出为obj

[英]Export layers as obj from Rhino3d

The task 任务

Export layers as obj files from Rhino. 从Rhino将图层导出为obj文件。

The issue 问题

When using Python scripting, I run an export command. 使用Python脚本时,我运行导出命令。 Instead of exporting the model, a dialog is presented in the interface. 在界面中会显示一个对话框,而不是导出模型。 If I click the export interface, it works fine. 如果我单击导出界面,则可以正常工作。 However it brings up the dialog box for every layer. 但是,它会弹出每个图层的对话框。 I have many many layers though and I would like to automate the entire export process. 我有很多层,但我想使整个导出过程自动化。

The end goal is to display the obj files in webGL via three.js. 最终目标是通过three.js在webGL中显示obj文件。

I am new to Python and Rhino, but know PHP and JavaScript, so I understand the concepts well enough and have watched a few tutorials on Python so I can begin working on this script. 我是Python和Rhino的新手,但是了解PHP和JavaScript,所以我对这些概念已经足够了解,并且已经看过一些关于Python的教程,因此我可以开始使用此脚本。

What I have tried 我尝试过的

I am using Rhino, Atom/Python. 我正在使用Rhino,Atom / Python。

import scriptcontext
import rhinoscriptsyntax as rs
from Rhino.Geometry import Point3d

def layerNames(sort=False):
    rc = []
    for layer in scriptcontext.doc.Layers:
        if not layer.IsDeleted: rc.append(layer.FullPath)
    if sort: rc.sort()
    return rc


rs.EnableRedraw(False)

strPath = rs.DocumentPath()
strName = rs.DocumentName()

arrLayers = layerNames(False)
for layerName in arrLayers:
    objs = scriptcontext.doc.Objects.FindByLayer(layerName)
    rs.Command("_-Export "+layerName+".obj", False) 

Notes 笔记

I was thinking of using python native file saving (open("layername.json", "a"). The thought is to somehow get the mesh from the objects in each layer, convert that to three.js json and use that instead. But I don't know how to get a mesh from a layer. I have imported Rhino.Geometry to see if it was helpful. I don't know how to find a mesh to convert, or if I can somehow use the native export command in an automated fashion and just use obj files. 我当时正在考虑使用python本机文件保存(open(“ layername.json”,“ a”)。这种想法是要以某种方式从每一层的对象中获取网格,将其转换为three.js json并改用它。但是我不知道如何从图层中获取网格,我已经导入Rhino.Geometry以查看它是否有用,我不知道如何找到要转换的网格,或者我是否可以使用本机导出命令以一种自动化的方式,只使用obj文件。

Here is the final script which exports dae, obj and stl. 这是导出dae,obj和stl的最终脚本。 The settings in place are fairly aggressive polygon reductions. 适当的设置是相当激进的多边形缩小。 Adjust angle and density to change that. 调整角度和密度以改变它。

I discovered that you need to set the density to zero before setting it to another value which solved a polygon count issue in the mesh conversion. 我发现需要将密度设置为零,然后再将其设置为另一个值,从而解决了网格转换中的多边形计数问题。

Also available on gist. 也可在要旨上使用。

import os
import scriptcontext
import rhinoscriptsyntax as rs


print "//export run started/////////////"

# this function via mcneel/rhinoscriptsyntax
#https://github.com/mcneel/rhinoscriptsyntax/blob/master/Scripts/rhinoscript/layer.py
def layerNames(sort=False):
    rc = []
    for layer in scriptcontext.doc.Layers:
        if not layer.IsDeleted: rc.append(layer.FullPath)
    if sort: rc.sort()
    return rc

def GetDAESettings():
    e_str = ""
    return e_str

def GetOBJSettings():
    e_str = "_Geometry=_Mesh "
    e_str+= "_EndOfLine=CRLF "
    e_str+= "_ExportRhinoObjectNames=_ExportObjectsAsOBJGroups "
    e_str+= "_ExportMeshTextureCoordinates=_Yes "
    e_str+= "_ExportMeshVertexNormals=_No "
    e_str+= "_CreateNGons=_No "
    e_str+= "_ExportMaterialDefinitions=_No "
    e_str+= "_YUp=_No "
    e_str+= "_WrapLongLines=Yes "
    e_str+= "_VertexWelding=_Welded "
    e_str+= "_WritePrecision=4 "
    e_str+= "_Enter "

    e_str+= "_DetailedOptions "
    e_str+= "_JaggedSeams=_No "
    e_str+= "_PackTextures=_No "
    e_str+= "_Refine=_Yes "
    e_str+= "_SimplePlane=_No "

    e_str+= "_AdvancedOptions "
    e_str+= "_Angle=50 "
    e_str+= "_AspectRatio=0 "
    e_str+= "_Distance=0.0"
    e_str+= "_Density=0 "
    e_str+= "_Density=0.45 "
    e_str+= "_Grid=0 "
    e_str+= "_MaxEdgeLength=0 "
    e_str+= "_MinEdgeLength=0.0001 "

    e_str+= "_Enter _Enter"

    return e_str

def GetSTLSettings():
    eStr = "_ExportFileAs=_Binary "
    eStr+= "_ExportUnfinishedObjects=_Yes "
    eStr+= "_UseSimpleDialog=_No "
    eStr+= "_UseSimpleParameters=_No "
    eStr+= "_Enter _DetailedOptions "
    eStr+= "_JaggedSeams=_No "
    eStr+= "_PackTextures=_No "
    eStr+= "_Refine=_Yes "
    eStr+= "_SimplePlane=_No "
    eStr+= "_AdvancedOptions "
    eStr+= "_Angle=15 "
    eStr+= "_AspectRatio=0 "
    eStr+= "_Distance=0.01 "
    eStr+= "_Grid=16 "
    eStr+= "_MaxEdgeLength=0 "
    eStr+= "_MinEdgeLength=0.0001 "
    eStr+= "_Enter _Enter"
    return eStr

settingsList = {
    'GetDAESettings': GetDAESettings,
    'GetOBJSettings': GetOBJSettings,
    'GetSTLSettings': GetSTLSettings
}




fileName = rs.DocumentName()
filePath = rs.DocumentPath().rstrip(fileName)

arrLayers = layerNames(False)



def initExportByLayer(fileType="obj", visibleonly=False, byObject=False):
    for layerName in arrLayers:
        layer = scriptcontext.doc.Layers.FindByFullPath(layerName, True)
        if layer >= 0:
            layer = scriptcontext.doc.Layers[layer]
            save = True;
            if visibleonly:
                if not layer.IsVisible:
                    save = False
            if  rs.IsLayerEmpty(layerName):
                save = False
            if save:
                cutName = layerName.split("::")
                cutName = cutName[len(cutName)-1]
                objs = scriptcontext.doc.Objects.FindByLayer(cutName)
                if len(objs) > 0:
                    if byObject:
                        i=0
                        for obj in objs:
                            i= i+1
                            saveObjectsToFile(cutName+"_"+str(i), [obj], fileType)
                    else:
                        saveObjectsToFile(cutName, objs, fileType)



def saveObjectsToFile(name, objs, fileType):
    rs.EnableRedraw(False)
    if len(objs) > 0:
        settings = settingsList["Get"+fileType.upper()+"Settings"]()
        rs.UnselectAllObjects()
        for obj in objs:
            obj.Select(True)
        name = "".join(name.split(" "))
        command = '-_Export "{}{}{}" {}'.format(filePath, name, "."+fileType.lower(), settings)
        rs.Command(command, True)
        rs.EnableRedraw(True)


initExportByLayer("obj",True, False)
initExportByLayer("dae",True, False)
initExportByLayer("stl",True, False)

print "//export run ended/////////////"

This turned out to be simple. 事实证明这很简单。 You need to supply a complete file path, name, and extension. 您需要提供完整的文件路径,名称和扩展名。 The dialogs can be automated with multiple _Enter commands. 对话框可以使用多个_Enter命令自动执行。 In this script the default obj options are used. 在此脚本中,使用默认的obj选项。 options can be appended to the _-Export command however before their respective _Enter commands are called. 可以将选项附加到_-Export命令之后,然后再调用它们各自的_Enter命令。

import scriptcontext
import rhinoscriptsyntax as rs

def layerNames(sort=False):
    rc = []
    for layer in scriptcontext.doc.Layers:
        if not layer.IsDeleted: rc.append(layer.FullPath)
    if sort: rc.sort()
    return rc

fileName = rs.DocumentName()
filePath = rs.DocumentPath().rstrip(fileName)
extension = ".obj"

arrLayers = layerNames(False)

for layerName in arrLayers:
    objs = scriptcontext.doc.Objects.FindByLayer(layerName)
    if len(objs) > 0:
        rs.UnselectAllObjects()
        for obj in objs:
            obj.Select(True)
        scriptcontext.doc.Views.Redraw()
        rs.Command("_-Export "+filePath+layerName+extension+" _Enter _Enter")

In my notes I mentioned utilizing the mesh object and writing my own file via Python. 在我的笔记中,我提到了利用Mesh对象并通过Python编写自己的文件。 This is still a viable option, but the method is not yet implemented on Mac for Rhino. 这仍然是一个可行的选择,但是该方法尚未在Mac for Rhino上实现。 I am now going to work on a recursive function to look for nested layers. 我现在要使用递归函数来查找嵌套层。 I will post the solution to a Gist when complete. 完成后,我会将解决方案发布到Gist。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM