从 Rhino3d 导出图层为 obj
Export layers as obj from Rhino3d
任务
从 Rhino 导出图层为 obj 文件。
问题
使用 Python 脚本时,我 运行 导出命令。界面中会显示一个对话框,而不是导出模型。如果我点击导出界面,它工作正常。然而,它会为每一层弹出对话框。虽然我有很多层,但我想自动化整个导出过程。
最终目标是通过three.js在webGL中显示obj文件。
我是 Python 和 Rhino 的新手,但知道 PHP 和 JavaScript,所以我对这些概念有足够的了解并且看过一些关于 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)
备注
我在考虑使用python本地文件保存(打开("layername.json","a")。想法是以某种方式从每一层的对象中获取网格,转换到 three.js json 并改用它。但我不知道如何从图层中获取网格。我已导入 Rhino.Geometry 以查看它是否有帮助。我不知道如何找到要转换的网格,或者如果我可以以某种方式以自动方式使用本机导出命令并仅使用 obj 文件。
事实证明这很简单。您需要提供完整的文件路径、名称和扩展名。对话框可以使用多个 _Enter 命令自动执行。在此脚本中,使用默认的 obj 选项。选项可以附加到 _-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")
在我的笔记中,我提到使用网格对象并通过 Python 编写我自己的文件。这仍然是一个可行的选择,但该方法尚未在 Mac for Rhino 上实现。我现在要使用递归函数来查找嵌套层。完成后我将 post 解决 Gist。
这是导出 dae、obj 和 stl 的最终脚本。适当的设置是相当积极的多边形减少。调整角度和密度来改变它。
我发现您需要先将密度设置为零,然后再将其设置为另一个值,这解决了网格转换中的多边形计数问题。
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/////////////"
任务
从 Rhino 导出图层为 obj 文件。
问题
使用 Python 脚本时,我 运行 导出命令。界面中会显示一个对话框,而不是导出模型。如果我点击导出界面,它工作正常。然而,它会为每一层弹出对话框。虽然我有很多层,但我想自动化整个导出过程。
最终目标是通过three.js在webGL中显示obj文件。
我是 Python 和 Rhino 的新手,但知道 PHP 和 JavaScript,所以我对这些概念有足够的了解并且看过一些关于 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)
备注
我在考虑使用python本地文件保存(打开("layername.json","a")。想法是以某种方式从每一层的对象中获取网格,转换到 three.js json 并改用它。但我不知道如何从图层中获取网格。我已导入 Rhino.Geometry 以查看它是否有帮助。我不知道如何找到要转换的网格,或者如果我可以以某种方式以自动方式使用本机导出命令并仅使用 obj 文件。
事实证明这很简单。您需要提供完整的文件路径、名称和扩展名。对话框可以使用多个 _Enter 命令自动执行。在此脚本中,使用默认的 obj 选项。选项可以附加到 _-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")
在我的笔记中,我提到使用网格对象并通过 Python 编写我自己的文件。这仍然是一个可行的选择,但该方法尚未在 Mac for Rhino 上实现。我现在要使用递归函数来查找嵌套层。完成后我将 post 解决 Gist。
这是导出 dae、obj 和 stl 的最终脚本。适当的设置是相当积极的多边形减少。调整角度和密度来改变它。
我发现您需要先将密度设置为零,然后再将其设置为另一个值,这解决了网格转换中的多边形计数问题。
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/////////////"