Notifications
Clear all

[Closed] how to make a box exactly wrap a object ?

hi :

if i select a object ,(or additionally select faces of a mesh etc . ), how to make a box wrap it ?
i can use a ffd_2x2x2 modifier and it do it very good, but i cant get the vertexes of the ffd modifier. so i cant make a box to align with the ffd modifier .

i want make a box , or just get the ffd_modifier gizmo `s height ,width , length , or the exact position of all control vertexes .

have checked the max reference box , havent found something useful .

thanks .

7 Replies

make a mesh as u wish , and modified it with faces and vertex … select it .


bb = $
addmodifier bb (ffd_2x2x2())
pmin = getModContextBBoxMin bb (bb.modifiers[1])
pmax = getModContextBBoxMax bb (bb.modifiers[1]) 
Bwidth = pmax.x - pmin.x -- x axis
Blength = pmax.y - pmin.y -- y axis
Bheight = pmax.z - pmin.z -- z axis
aa = box width:bwidth length:blength height:bheight
tm = $.transform 
aa.transform = tm

something not as i expected , the position of the new box is not align with the ffd gizmo,
why has these gaps ?

i think the getModContextTM and lattice_transform is useful , but i dont know how to use them . the result ot these is always a standard matrix3 . without any offset value . but now in the scene, it has the offset gaps . dont know why ?


i think it is useful when we select only some of faces and can caculate the size of it .

Hey man,

I just wrote a script that does this a couple of days ago actually!  I needed it to convert (generally square) buildings to straight "bounding" boxes on a huge set to cut down on polycounts.  Credit goes to Bobo for the script, there's a post from a few months back where he posted some code for it, here is my adaptation:

    fn boundingBox theObj =
   (
  	oldTransform = theObj.transform
  	theObj.transform *= inverse theObj.transform
  	theMin = theObj.min
  	theMax = theObj.max 
  	bb = box width:(theMax.x - theMin.x) length:(theMax.y - theMin.y) height:(theMax.z - theMin.z)
  	theObj.transform = oldTransform
  	bb.transform = theObj.transform
  	bb.center = theObj.center
  	bb.wirecolor = color 127 127 127
  	 --delete theObj
   )
    		
    	theSelection = for o in selection collect o
    	for o in theSelection do try(boundingBox o)catch()
    
For making a box around a vertex selection (if you want you can convert from other subobject modes down to vertex mode), I wrote this code to take all the "extreme" vertices in each dimension, then derived the box off of that.  Makes a perfectly sized box around a vertex selection:

     (
     	if selection.count == 1 and classof $ == Editable_Poly do
     	(
     		theObj = $
     		theVerts = polyop.getvertselection theObj as array
     		xVals = #()
     		yVals = #()
     		zVals = #()
     			   
     		for v in theVerts do
     		(
     			vertPos = polyop.getvert theObj v
     			append xVals vertPos.x
     			append yVals vertPos.y
     			append zVals vertPos.z
     		)
     		
     		theWidth = (amax xVals) - (amin xVals)
     		theLength = (amax yVals) - (amin yVals)
     		theHeight = (amax zVals) - (amin zVals)
     		
     		avgPos = [(((amax xVals) + (amin xVals)) / 2.),(((amax yVals) + (amin yVals)) / 2.),(((amax zVals) + (amin zVals)) / 2.)]
     		theBox = box length:theLength width:theWidth height:theHeight xray:true
     		theBox.pivot = theBox.center
     		theBox.pos = avgPos
     	)
     )
    

i love u man . cause u always appear at right time and right place these days ,makes me cant forget u . hahahh

haha Have a good night man

our thinknesses are in same way . i am doing it in this way ,just as u say . why i thinking about ffd 2x2x2 is i am afraid if use vertexes caculation , in big scene , maybe slower than use internal function of max like ffd 2x2x2. it looks more faster when in sub object mode ,and the axis of the gizmo is very good.

additional :
if u select many vertex , and u can make a helper or a sphere with 0 radius at each vertex position . then collapse them into one mesh . then u can use the first way to move it to zero position , use .max .min. add box cover …

this idea has been used in my other scripts about render in boxselection mode .

maybe u like .

I usually try to avoid adding modifiers and getting info off of them if I can get all the info I need on the current object, in-place. It just seems a little hacky to go through all the trouble of adding the modifier to get the info when you can just get it straight from the object itself (in our case vertex calculations). But the reason the FFD wasn’t working for you was because when you use the getModContextTM, its not giving you the true bounding box (the one you see around objects when you select them).

 To get the true bounding box you have to inverse the object's transform, THEN get the .min and .max values, then bring the object's transform back to normal, make your box with the extracted values, and make the box's transform into the original object's transform.  Its a silly workaround to get from local space to world space, so that if your object is rotated, you still get the correct bounding box, instead of with "offsets" like you mentioned.
 
 As far as speed goes... it seemed pretty fast to me!  But, what I always ask myself is this:
 
 "Will the time thinking about a better solution and writing it take less time than just running the code that already works efficiently?"  Usually the answer is no, and it takes longer to write a better script, which leads to more wasted time in the long run...
 
 But if the code is written poorly to begin with, then yes, it is worth it to re-write... especially if someone else is going to be working with it in the future.  I generally find that vertex positional calculation is pretty fast, especially when you leave vertex lists as bitarrays... as a matter of fact, in the first script I posted, you don't need the "as array" conversion after theVerts are assigned, I must have converted it out of habit :)  But generally looping over bitarrays is ridiculously faster than looping over arrays, and another thing that definitely helps is to pre-initialize your array size when the final size is known, instead of appending.
 
 So a more efficient version of the second script would look like:

     if selection.count == 1 and classof $ == Editable_Poly do
     (
   	theObj = $
   	theVerts = polyop.getvertselection theObj as array
   	vertCount = theVerts.count
   	xVals = #()
   	yVals = #()
   	zVals = #()
   	xVals[vertCount] = undefined
   	yVals[vertCount] = undefined
   	zVals[vertCount] = undefined
     	   
   	for x = 1 to theVerts.count do
   	(
   		vertPos = polyop.getvert theObj theVerts[x]
   		xVals[x] = vertPos.x
   		yVals[x] = vertPos.y
   		zVals[x] = vertPos.z
   	)
          		
   	theWidth = (amax xVals) - (amin xVals)
   	theLength = (amax yVals) - (amin yVals)
   	theHeight = (amax zVals) - (amin zVals)
     
   	avgPos = [(((amax xVals) + (amin xVals)) / 2.),(((amax yVals) + (amin yVals)) / 2.),(((amax zVals) + (amin zVals)) / 2.)]
   	theBox = box length:theLength width:theWidth height:theHeight xray:true
   	theBox.pivot = theBox.center
   	theBox.pos = avgPos
     )
    

I wouldn’t be afraid of using vertex calculations… unless we’re talking crazy huge numbers… but in that case the above code will work faster. In most everyday use though you would never notice the difference between “appends” and direct array assignment.

Very Much.