ScriptSpot

Forum topic · Scripts Wanted

Bounding box of selected faces

By jsrocha · 2013-09-03

Description

Hi guys, how´s going?
i know there´s some scripts of "create bounding box" objetcs, that creates a box over the selected objects (like this one - http://www.scriptspot.com/3ds-max/scripts/translated-bounding-box). I need a script that makes the same thing, but only in the selected faces (or any sub-object, but mostly faces). I found this one - http://www.scriptspot.com/3ds-max/scripts/bounding-boxer - and it does what i want, but it too "complicated", i need something quicker. Does anyone can help me? I tried to do it using max listener, detaching the faces as a copy and then creating a bounding box using the new object, but for some reason it doesn´t work all the times.
Thanks in advance,

Jsrocha

Comments (13)

.

miauu · 2013-09-12

Now I saw(in Brakno's image) that my solution not works with rotated objects.
Here the fixed code. It works with rotated object, but if the objet is rotated ad sub-object level it will not work.
There is one very ugly line of code, but with it all matrix/math operations are skipped. :)




(	
	if selection.count == 1 and classOf (curO = selection[1]) == Editable_Poly do
	(
		if (selFacesBA = polyop.getFaceSelection curO).numberset != 0 do
		(
			faceVertsBA = polyop.getVertsUsingFace curO selFacesBA
			curOtransform = curO.transform
			curO.rotation = quat 0 0 0 1
			with redraw off 
			(
				tMesh = mesh mesh:curO.mesh
				tMesh.pos = curO.pos
				tMesh.objectOffsetPos = curO.objectOffsetPos
				if faceVertsBA.count > 0 do 
				(
					delete tMesh.verts[((tMesh.verts as BitArray) - (faceVertsBA))]
				)
				c = snapshot tMesh
				c.transform = matrix3 1
-- 				d = dummy boxsize:(c.max - c.min)
				size = (c.max - c.min)
				d = Box lengthsegs:1 widthsegs:1 heightsegs:1 length:size[2] width:size[1] height:size[3]
				centerPivot d
				delete c
				d.transform = tMesh.transform
				d.pos = tMesh.center
				d.name = tMesh.name + "_box"
				--	very ugly, but skip all math operations
				d.parent = curO
				delete tMesh
				curO.transform = curOtransform
				d.parent = undefined
			)
		)
	)
)

barigazy · 2013-09-12

Definitely we have to go back to elementary school to learn matrix.
Life is easier with knowledge of the matrix, no more mambo-jambo-pseudo codes.
:)

barigazy · 2013-09-12

You last code works fine. Now try to rotate object and resetXForm and then try code. Again matrix problem :)

miauu · 2013-09-12

Ii will not works in this case. The sama as when the object is rotated at sub-object level.
But it is better than nothing. :)
You can continue to fight with the matrix. I give up.:)

barigazy · 2013-09-12

I give Up before U (after I posted my concept). I tried with matrix there but without of luck.
:)

.

miauu · 2013-09-12

The corrected code:




(	
	if selection.count == 1 and classOf (curO = selection[1]) == Editable_Poly do
	(
		if (selFacesBA = polyop.getFaceSelection curO).numberset != 0 do
		(
			faceVertsBA = polyop.getVertsUsingFace curO selFacesBA
			with redraw off 
			(
				tMesh = mesh mesh:curO.mesh
				tMesh.pos = curO.pos
				tMesh.objectOffsetPos = curO.objectOffsetPos
				if faceVertsBA.count > 0 do 
				(
					delete tMesh.verts[((tMesh.verts as BitArray) - (faceVertsBA))]
				)
				c = snapshot tMesh
				c.transform = matrix3 1
				size = (c.max - c.min)
				d = Box lengthsegs:1 widthsegs:1 heightsegs:1 length:size[2] width:size[1] height:size[3]
				centerPivot d
				delete c
				d.transform = tMesh.transform
				d.pos = tMesh.center
				d.name = tMesh.name + "_box"
				delete tMesh
			)
		)
	)
)

Branko is right. Matrix in all 3dCAD sfoftware is for people who knows much about math. I am not one of them.
That's why I use Anubis code - no Matrix and Mat operations at all.
:)

.

miauu · 2013-09-11

This is combination of two scripts, written by Anubis.
You have to optimize the code.


(	
	if selection.count == 1 and classOf (curO = selection[1]) == Editable_Poly do
	(
		if (selFacesBA = polyop.getFaceSelection curO).numberset != 0 do
		(
			faceVertsBA = polyop.getVertsUsingFace curO selFacesBA
			with redraw off 
			(
				tMesh = mesh mesh:curO.mesh
				tMesh.pos = curO.pos
				tMesh.objectOffsetPos = curO.objectOffsetPos
				if faceVertsBA.count > 0 do 
				(
					delete tMesh.verts[((tMesh.verts as BitArray) - (faceVertsBA))]
				)
				c = snapshot tMesh
				c.transform = matrix3 1
				d = dummy boxsize:(c.max - c.min)
				delete c
				d.transform = tMesh.transform
				d.pos = tMesh.center
				d.name = tMesh.name + "_box"
				delete tMesh
			)
		)
	)
)

jsrocha · 2013-09-11

Hey Miauu, thanks for your help. This script works, but it creates a dummy instead of a box. I tried to tweak the code, but it doesn´t work (i´m a bad coder). Do you know how to make it create a box?
thanks man,

Jsrocha

barigazy · 2013-09-12

I have different concept but still not good


(
	local obj = selection[1], faces = #{}
	local dp = datapair #() #()
	local getNorm = polyop.getFaceNormal
	local faceC = polyop.getFaceCenter
	local xV,yV,zV,cnt = [0,0,0] 
	if not (faces = obj.selectedfaces as bitarray).isEmpty do
	(
		for i in faces do
		(
			if dp.v1.count == 0 then append dp.v1 i
			else if (distance (getNorm obj dp.v1[1]) (getNorm obj i)) < 0.01 then append dp.v1 i else append dp.v2 i
		)
	)
	case of
	(
		(dp.v1.count < dp.v2.count): 
		(
			xV = getNorm obj dp.v1[1] ; zV = getNorm obj dp.v2[1] ; yV = normalize (cross xV zV)
			for i = 1 to dp.v2.count do cnt += faceC obj dp.v2[i] ; cnt /= dp.v2.count
		)
		(dp.v1.count > dp.v2.count): 
		(
			xV = getNorm obj dp.v2[1] ; zV = getNorm obj dp.v1[1] ; yV = normalize (cross xV zV)
			for i = 1 to dp.v1.count do cnt += faceC obj dp.v1[i] ; cnt /= dp.v1.count
		)
		default: 
		(
			xV = getNorm obj dp.v1[1] ; zV = getNorm obj dp.v2[1] ; yV = normalize (cross xV zV)
			for i = 1 to dp.v2.count do cnt += faceC obj dp.v2[i] ; cnt /= dp.v2.count
		)
	)
	local tm = matrix3 xV yV zV cnt
	polyop.detachFaces obj faces delete:off asNode:on name:"tempObj"
	CenterPivot $tempObj ; ResetXForm $tempObj ; convertToMesh $tempObj
	w = in coordsys tm abs($tempObj.max.x - $tempObj.min.x)
	l = in coordsys tm abs($tempObj.max.y - $tempObj.min.y)
	h = in coordsys tm abs($tempObj.max.z - $tempObj.min.z)
	delete $tempObj
	Box lengthsegs:1 widthsegs:1 heightsegs:1 length:l width:w height:h transform:tm name:"BoxFromFaces" isSelected:on
)

This is the result of theses two examples

barigazy · 2013-09-12

My method is wrong. Try to rotate object and you'll see.
I love Matrix movie but matrix in max is pain in the ... :)
Only few people know how to deal with it. Bobo and DenisT.
Kostadin are you here to confirm this :)

jsrocha · 2013-09-11

Hey Barigazi, thanks for your reply, and excuse my late reply, i was in a big rush here ;)
here´s a screenshot showing what i want -
http://prntscr.com/1qq5jv
Basicaly, is to make a bounding box using the selected faces as size reference. As i said, i made a code that does what i want, but this code have two problems: first, is slow. Two, sometimes it doesn´t work (i don´t know why). In fact, is not a code, is a tweaked macro recorder, i'm pasting it here (pretty embarassing):

( --the code starts with the faces already selected in the object
macros.run "Tools" "Isolate_Selection"
actionMan.executeAction 369982487 "40086" --this hides the unselected faces of the object
$.EditablePoly.Hide #Face
macros.run "BlurScripts" "BBoxMaker" --this is the blur script BBoxMaker, which makes a boundig box using the selected object as reference size
macros.run "Editable Polygon Object" "EPoly_UnHide" --this unhides all the hiden faces of the object
subobjectLevel = 0 --exit sub-object mode
modPanel.setCurrentObject $.baseObject
d = for hwnd in UIAccessor.GetPopupDialogs() where UIAccessor.GetWindowText hwnd == "Warning: Isolated Selection" do exit with hwnd
if d != ok do UIAccessor.PressButtonByName d "Exit Isolation Mode" --these three lines of code i got from the internet, it exits the isolation
)

ok man, that´s it. If you can get a better code, i´ll appreciate (pretty easy i guess ;)
thanks,
Jsrocha

barigazy · 2013-09-03

Post your code and some screenshots to see exactly what you want to achieve