Notifications
Clear all

[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

Rhino layer tree:

Max Layer and Object Names

(
 	--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>

1 Reply

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)
	
)