Notifications
Clear all

[Closed] Select SImilar Geometry by (bbox, position, vertex count)

for some reason I can’t use it. If I tick both options I get:
image

but if I use only bbox option it work!

I have edited the tags in my previous post. Can you try again?

I did it but still no go

I use v2009 if it’s matters

I have tested it in Max 2009. The script works with no errors when the both checkboxes are not turned On at the same time. Please, see this video: https://drive.google.com/open?id=19ZrdOAFSw6TepeBHTVzeThlJPJ2KKpzD

I experienced the same behavior,
it’s impossible to check both at the same time?

This should works with both checkboxes turned ON

(
	global rol_selectSimilar
	try(destroyDialog rol_selectSimilar)catch()
	rollout rol_selectSimilar "Select Similar"
	(
		checkBox chkBox_selectByBBox "Size(Bounding Box)"
		checkBox chkBtn_vertsFaceCount "Verts/FAces count" 
		button btn_selectSimilar "Select Similar"
		
		function GetShapeMeshPolyCount obj = 
		(
			oldState = obj.render_renderable -- keep rend. state
			obj.render_renderable = true -- set to true for next operation
			res = (getPolygonCount obj) as string -- get Real mesh (v,f) !
			obj.render_renderable = oldState -- restore state
			res -- return result
		)
		
		
		on btn_selectSimilar pressed do
		(
			selObjsArr = selection as array
			if selObjsArr.count != 0 do
			(
				similarObjsArr = #()
				
				for i = 1 to selObjsArr.count where isValidNode selObjsArr[i] do
				(
					iObj = selObjsArr[i]
					iMeshData = #(0,0)
					if chkBtn_vertsFaceCount.checked do
					(
						iMeshData = if isShapeObject iObj then 
							(
								GetShapeMeshPolyCount iObj 
							)
							else
							(
								(getPolygonCount iObj) as string
							)
					)
					for j = selObjsArr.count to i + 1 by -1 where isValidNode selObjsArr[j] do
					(
						if chkBox_selectByBBox.checked do
						(
							if (nodeGetBoundingBox iObj iObj.transform) as string == (nodeGetBoundingBox selObjsArr[j] selObjsArr[j].transform) as string do
							(
								appendIfUnique similarObjsArr selObjsArr[j]
								deleteitem selObjsArr j
							)							
						)
						
						if chkBtn_vertsFaceCount.checked and isValidNode selObjsArr[j] do
						(
							if isShapeObject selObjsArr[j] then 
							(
								if (GetShapeMeshPolyCount selObjsArr[j]) == iMeshData do 
								(
									appendIfUnique similarObjsArr selObjsArr[j]
									deleteitem selObjsArr j
								)								
							)
							else 
							(
								if (getPolygonCount selObjsArr[j]) as string == iMeshData do
								(
									appendIfUnique similarObjsArr selObjsArr[j]
									deleteitem selObjsArr j	
								)
							)
					)
					)
				)
				if similarObjsArr.count != 0 do select similarObjsArr
			)
		)
		
	)
	createdialog rol_selectSimilar 	
)

here is how i would search geometrically same objects (i would use mesh vertex positions hash)…
as you can see transform of objects doesn’t matter in this case:

fn roundFloat d pre:0.001 =
(
	d = (d as float)/pre
	v = if (d - (v1 = floor d)) > ((v2 = ceil d) - d) then v2 else v1 
	v*pre
)

fn roundPoint3 p pre:0.001 =
(
	p.x = roundFloat p.x pre:pre
	p.y = roundFloat p.y pre:pre
	p.z = roundFloat p.z pre:pre

	p
)

fn getMeshHash obj round:0 = 
(
	hash = 0
	mesh = obj.mesh 
	for k=1 to mesh.numverts do 
	(
		p = getvert mesh k
		if round > 0 do roundPoint3 p pre:round
		hash = gethashvalue p hash
	)
	hash
)

/*
delete objects
for k=1 to 100 do 
(
	teapot segs:(random 4 6) pos:(random -[100,100,100] [100,100,100]) rotation:(eulerangles 0 0 (random 0 180)) scale:([0.2,0.2,0.2] * (random 1 3))
)

-- find all the same as one selected: 
(
	node = selection[1]
	hash = getMeshHash node
	same = for obj in geometry where (getMeshHash obj) == hash collect obj
)
*/

you can use “round” to have less accuracy but adding some tolerance

you can use the hashing method to find similar (same) bounding boxes as well.
it needs only one point (size) or four points (transform) for hashing

here is a snippet to play with:

try(destroydialog FindSameRol) catch()
rollout FindSameRol "Find Same with denisT" width:191
(
	fn roundFloat d pre:0.001 =
	(
		d = (d as float)/pre
		v = if (d - (v1 = floor d)) > ((v2 = ceil d) - d) then v2 else v1 
		v*pre
	)

	fn roundPoint3 p pre:0.001 =
	(
		p.x = roundFloat p.x pre:pre
		p.y = roundFloat p.y pre:pre
		p.z = roundFloat p.z pre:pre

		p
	)

	fn getBBoxHash obj round:0 hash:0 = 
	(
		--bb = nodeLocalBoundingBox obj
		tm = translate (rotate (scalematrix [1,1,1]) obj.transform.rotation) obj.transform.position
		bb = nodeGetBoundingBox obj tm
		size = bb[2] - bb[1]
		if round > 0 do roundPoint3 size pre:round
		gethashvalue size hash
	)
	fn getAnimHash obj round:0 hash:0 = 
	(
		tm = obj.transform
		for k=1 to 3 do 
		(
			p = tm[k]
			if round > 0 do roundPoint3 p pre:round
			hash = gethashvalue p hash
		)
		hash
	)
	fn getMeshHash obj round:0 hash:0 = 
	(
		mesh = obj.mesh 
		for k=1 to mesh.numverts do 
		(
			p = getvert mesh k
			if round > 0 do roundPoint3 p pre:round
			hash = gethashvalue p hash
		)
		hash
	)

	group "Search: "
	(
		checkbox check_bbox_ch "Check Bounding Box" checked:off offset:[0,0]
		checkbox check_anim_ch "Check Orientation" checked:off offset:[0,0]
		checkbox check_mesh_ch "Check Geometry" checked:on
		
		button find_same_bt "Find Same Objects" width:172 align:#left offset:[-4,4]
		progressbar pb width:172 height:8 color:orange align:#left offset:[-4,-2]
		label info_lb ">> " align:#left offset:[0,0]
	)
	group "Debug: "
	(
		button make_scene_bt "Make Test Scene" width:172 align:#left offset:[-4,0]
	)
	
	fn runCompare source targets compare_fn color: = 
	(
		pb.value = 0.0
		pb.color = color
		hash = compare_fn source

		found = #()
		for k=1 to targets.count do
		(
			pb.value = 100.0 * k / targets.count
			target = targets[k]
			if (compare_fn target) == hash do append found target
		)
		found
	)

	on find_same_bt pressed do undo "Find Same" on 
	(
		if iskindof (source = selection[1]) GeometryClass do
		(
			pb.value = 0.0
			targets = geometry as array

			if check_bbox_ch.state do
			(
				targets = runCompare source targets getBBoxHash color:green
			)
			if check_anim_ch.state do
			(
				targets = runCompare source targets getAnimHash color:blue
			)
			if check_mesh_ch.state do
			(
				targets = runCompare source targets getMeshHash color:orange
			)
			
			if targets.count > 0 do select targets
			info_lb.text = ">> " + targets.count as string + " objects found" 
		)
	)
	
	on make_scene_bt pressed do undo "Make Test Scene" on
	(
		delete objects
		for k=1 to 100 do 
		(
			teapot segs:(random 4 6) pos:(random -[100,100,100] [100,100,100]) rotation:(eulerangles 0 0 (90 *(random 0 3))) scale:([0.2,0.2,0.2] * (random 1 3))
		)
		select objects[random 1 objects.count]
	)
)
createdialog FindSameRol
Page 2 / 2