[Closed] Select SImilar Geometry by (bbox, position, vertex count)
for some reason I can’t use it. If I tick both options I get:
but if I use only bbox option it work!
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