[Closed] Parsing layer names to replicate nested layers from rhino
We receive files from rhino where objects are created on a material by layer basis. i.e. all objects that are to be rendered with concrete are created on a layer named Concrete etc. I am simplifying quite a bit. see the attached images for an example of the nested layer tree in rhino. We export the rhino file to dwg, then import by layer, which combines all rhino geometry on each layer. This is preferred for our workflow as this is the way we work with other import formats; combine geometry by material.
As in the attached image and .max file, the nested hierarchy of the rhino layers is represented in the layer name, separating parent/siblings by a “$” token.
I am trying to recreate the layer tree just as it is in rhino and move all the objects to the newly created layers. I’m close, this creates the tree appropriately but does not move all of the objects to new layers… only some. I assume this is because layer names already exist or something… but i’m not getting errors.
Any help would be appreciated. Thanks.
Max file. I had to strip out all but a couple faces per object for privacy/security purposes.
https://drive.google.com/file/d/0B1riS0yhBakDNGpUREd6eHpkRDQ/view?usp=sharing
(
--convert object names
(
obs = selection as array
for o in obs do
(
nameArray = FilterString o.name "$"
if nameArray.count > 1 do
(
o.name = nameArray[nameArray.count]
o.wirecolor = o.layer.wirecolor
)
)
)
lm = LayerManager
originalLayers = (for k = 1 to lm.count collect lm.getLayer k)
for i = 1 to originalLayers.count do
(
lay = lm.getLayer i -- original layer
layName = lay.name
nameArray = FilterString layName "$" -- array of rhino layer names as separated by token $
layer = ILayerManager.getLayerObject i
layerNodes = refs.dependents layer
if nameArray.count > 1 do
(
for j = 1 to nameArray.count do
(
newLayer = LayerManager.newLayerFromName nameArray[j]
--print newLayer.name
if newLayer != undefined do
(
for n = 1 to layerNodes.count where superclassof layerNodes[n] == GeometryClass do
(
if (lm.getLayerFromName nameArray[nameArray.count]) != undefined and j == nameArray.count then
(
newLayer.addNode layerNodes[n]
)
)
if j >1 do newLayer.setParent (lm.getLayerFromName nameArray[j-1])
)
)
)
)
)
</a>
This seems to work with the sample file you’ve provided, but it may fail with other scenes.
(
struct layer (name, color, nodes)
fn GetLayersNamesFromNodes nodes =
(
done = #()
layers = #()
wrongNames = stringstream ""
wrongClasses = stringstream ""
format "Wrong Names:
" to:wrongNames
format "Wrong Classes:
" to:wrongClasses
for j in nodes do
(
if superClassof j == geometryClass then
(
layerName = filterString j.name "$"
if layerName.count > 1 then
(
layerName = layerName[layerName.count]
found = finditem done layerName
if found == 0 then
(
append done layerName
append layers (layer name:layerName color:(j.wirecolor) nodes:#(j))
)else(
append layers[found].nodes j
)
)else(
format " %
" j to:wrongNames
)
)else(
format " %
" j to:wrongClasses
)
)
print (wrongNames as string)
print (wrongClasses as string)
return layers
)
fn MoveNodesToLayers nodes deleteOldLayers:true =
(
local NewLayerFromName = LayerManager.newLayerFromName
local DeleteLayerByName = LayerManager.deleteLayerByName
local GetLayer = LayerManager.getLayer
local tmpName = "_____TMP_____"
LayerManager.closeDialog()
(LayerManager.getLayer 0).current = true
layers = GetLayersNamesFromNodes nodes
tmpLayer = NewLayerFromName tmpName
for j in layers do
(
for k in j.nodes do tmpLayer.addNode k
)
if deleteOldLayers==true do
(
for j = LayerManager.count-1 to 0 by -1 do
(
layerName = (GetLayer j).name
if layerName != tmpName do DeleteLayerByName layerName
)
)
for j in layers do
(
layer = NewLayerFromName j.name
layer.wirecolor = j.color
for k in j.nodes do layer.addNode k
)
DeleteLayerByName tmpName
)
gc()
st = timestamp(); sh = heapfree
MoveNodesToLayers selection --deleteOldLayers:false
format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
)