Notifications
Clear all

[Closed] Newbie needs help with simple clone scripted plugin

Hi,
I was trying to do a simple object for making arrays of objects.
I share with you what I have so far but is very messy because is based on copying the source object and then attaching it to a container trimesh, I don’t know much about this but sounds to me like I’m doing so much garbage and when I do enough copies it becomes very unstable.

I’ll really appreciate any help or tip to make this code a little more efficient.

plugin simpleObject ArrayEr
name:"ArrayEr"
category:"Test Scripts"
classID:#(1430903902,1479981115)
(
	local baseMesh
	parameters main rollout:params 
	(
		NodePTR type:#node ui:nodePicker
		copiesX type:#integer ui:sp_copiesX
		copiesY type:#integer ui:sp_copiesY
		copiesZ type:#integer ui:sp_copiesZ
		posX type:#float ui:sp_posX
		posY type:#float ui:sp_posY
		posZ type:#float ui:sp_posZ
	)
	
	rollout params "ArrayEr"
	(
		pickbutton nodePicker "None" width:150 autodisplay:true
		spinner sp_copiesX "X Copies" type:#integer range:[0,100,0]
		spinner sp_copiesY "Y Copies" type:#integer range:[0,100,0]
		spinner sp_copiesZ "Z Copies" type:#integer range:[0,100,0]
		
		spinner sp_posX "X Distance" type:#WorldUnits range:[0,1000,0]
		spinner sp_posY "Y Distance" type:#WorldUnits range:[0,1000,0]
		spinner sp_posZ "Z Distance" type:#WorldUnits range:[0,1000,0]
		
	) 
	
	on buildMesh do
	(
		if NodePTR == undefined then
		(
			bObject = createInstance box length:10 width:10 height:10
			baseMesh = copy bObject.mesh
			mesh = baseMesh
		)else
		(
			baseMesh = TriMesh()
				for incX = 0 to copiesX do
				(
					for incY=0 to copiesY do
					(
						for incZ = 0 to copiesZ do
						(
							tmpMesh = copy NodePTR
							tmpMesh.Position = [posX*incX,posY*incY,posZ*incZ]
							meshop.attach baseMesh tmpMesh
						)
					)
				)
			
			mesh = baseMesh
		)
	)
	
	tool create
	(
		on mousePoint click do
		case click of
		(
			1: coordSys grid (nodeTM.translation = gridPoint)
			2: #stop
		)
		on mouseMove click do
		case click of
		(
			2: coordSys grid (nodeTM.translation = gridPoint)
		)
	)
)

Thanks a lot!

2 Replies

The options you have when working with Object Plugins are a little limited. Basically all you should use are the basic Mesh/Trimesh functions, such as getVert(), getFace(), getEdgeVis(), and so on.

Although you can use the functions in the meshop structure, most of them will have a big impact in performance.

Performing other operations such as node creation or manipulation, adding/removing modifiers are not recommended and will most probably lead to a crash.

Considering this, below is an incomplete modified version of your script. I will perform reasonably well with low polygon models and a few copies, but performance degrades quite fast with large amount of data.

Please note that it is not fully tested or optimized.

plugin simpleObject ArrayEr
 name:"ArrayEr"
 category:"Test Scripts"
 classID:#(1430903902,1479981115)
 (
 	parameters main rollout:params 
 	(
 		pNodePTR type:#node ui:pb_nodePicker
 		pCopiesX type:#integer ui:sp_copiesX
 		pCopiesY type:#integer ui:sp_copiesY
 		pCopiesZ type:#integer ui:sp_copiesZ
 		pPosX type:#float ui:sp_posX
 		pPosY type:#float ui:sp_posY
 		pPosZ type:#float ui:sp_posZ
 		pEdgeVis type:#boolean ui:cb_edgeVis
 		pSmoothGroups type:#boolean ui:cb_smoothGroups
 		pMatIDs type:#boolean ui:cb_matIDs
 		pUVW type:#boolean ui:cb_UVW
 	)
 	
 	rollout params "ArrayEr"
 	(
 		pickbutton pb_nodePicker "None" width:150 autodisplay:true
 		spinner sp_copiesX "X Copies" type:#integer range:[0,100,0]
 		spinner sp_copiesY "Y Copies" type:#integer range:[0,100,0]
 		spinner sp_copiesZ "Z Copies" type:#integer range:[0,100,0]
 		
 		spinner sp_posX "X Distance" type:#WorldUnits range:[0,1000,0]
 		spinner sp_posY "Y Distance" type:#WorldUnits range:[0,1000,0]
 		spinner sp_posZ "Z Distance" type:#WorldUnits range:[0,1000,0]
 		
 		checkbox cb_edgeVis "Set Invisible Edges" checked:true
 		checkbox cb_smoothGroups "Set Smoothing Groups"
 		checkbox cb_matIDs "Set Material IDs"
 		checkbox cb_UVW "Set UVWs" enabled:false -- NOT IMPLEMENTED
 	) 
 	
 	on buildMesh do
 	(
 		if pNodePTR == undefined then
 		(
 			bObject = createInstance box length:10 width:10 height:10
 			mesh = copy bObject.mesh
 		)else
 		(
 			baseMesh = copy pNodePTR.mesh
 			
 			numverts = baseMesh.numverts
 			numfaces = baseMesh.numfaces
 			
 			baseVerts = for v = 1 to numverts collect getvert baseMesh v
 			baseFaces = for f = 1 to numfaces collect getface baseMesh f
 			
 			finalVerts = #()
 			finalFaces = #()
 			lastVert = 0
 			
 			for incX = 0 to pCopiesX do
 			(
 				for incY = 0 to pCopiesY do
 				(
 					for incZ = 0 to pCopiesZ do
 					(
 						verts = for v in baseVerts collect [v.x+pPosX*incX, v.y+pPosY*incY, v.z+pPosZ*incZ]
 						faces = for f in baseFaces collect [f.x+lastVert, f.y+lastVert, f.z+lastVert]
 						join finalVerts verts
 						join finalFaces faces
 						lastVert += numverts
 					)
 				)
 			)
 			
 			setmesh mesh verts:finalVerts faces:finalFaces
 			
 			numCopies = (pCopiesX+1)*(pCopiesY+1)*(pCopiesZ+1)
 			
 			if pEdgeVis do
 			(
 				edgeVis = for f = 1 to numfaces collect #(getedgevis baseMesh f 1, getedgevis baseMesh f 2, getedgevis baseMesh f 3)
 				lastface = 0
 				for j = 0 to numCopies-1 do
 				(
 					for f = 1 to baseMesh.numfaces do
 					(
 						setedgevis mesh (f+lastface) 1 (edgeVis[f][1])
 						setedgevis mesh (f+lastface) 2 (edgeVis[f][2])
 						setedgevis mesh (f+lastface) 3 (edgeVis[f][3])
 					)
 					lastface += numfaces
 				)
 			)
 			
 			if pSmoothGroups do
 			(
 				smoothingGroups = for f = 1 to numfaces collect getfacesmoothgroup baseMesh f
 				lastface = 0
 				for j = 0 to numCopies-1 do
 				(
 					for f = 1 to baseMesh.numfaces do
 					(
 						setfacesmoothgroup mesh (f+lastface) smoothingGroups[f]
 					)
 					lastface += numfaces
 				)
 			)
 			
 			if pMatIDs do
 			(
 				matIDs = for f = 1 to numfaces collect getfacematid baseMesh f
 				lastface = 0
 				for j = 0 to numCopies-1 do
 				(
 					for f = 1 to baseMesh.numfaces do
 					(
 						setfacematid mesh (f+lastface) matIDs[f]
 					)
 					lastface += numfaces
 				)
 			)
 			
 			free baseMesh
 			
 		)
 	)
 	
 	tool create
 	(
 		on mousePoint click do
 		(
 			case click of
 			(
 				1: coordSys grid (nodeTM.translation = gridPoint)
 				2: #stop
 			)
 		)
 		on mouseMove click do
 		(
 			case click of
 			(
 				2: coordSys grid (nodeTM.translation = gridPoint)
 			)
 		)
 	)
 	
 )

Thanks a lot for your help!
I’ll try to work on it width the concepts you just gave to me.
If this kind of plugins are limited I think I’ll try to do a version without constant auto update, maybe in that way the plugin would save some resources not having to watch all the time to the picked node. I would try to find a way to partially rebuild the mesh based on a previous state too
Thanks!