Zoom ob objects (SDK-C#)


#1

How we can zoom extents on specific group of objects (SDK)?


#2

there’s ZoomToBounds method for this, but you’ll have to make box3 bounds yourself


#3

So, how we can get the bounds of some objects?


#4

see Viewport Functionality in sdk reference


#5

the mxs source for zoomtobounds is

Value* 
VP_ZoomToBounds_cf(Value **arg_list, int count)
{
	check_arg_count(ZoomToBounds, 3, count);
	BOOL all = arg_list[0]->to_bool();
	Point3 a = arg_list[1]->to_point3();
	Point3 b = arg_list[2]->to_point3();
	Box3 box(a,b);
	MAXScript_interface->ZoomToBounds(all,box);

	return &ok;
}

#6

I couldn’t find the method to find the bounding box.


#7

How we can find those points?


#8

in c++…

           Box3 bbox;
           bbox.Init();

        // then for each node....

            Object* obj = node->EvalWorldState(t).obj;
            Matrix3 tm = node->GetObjectTM(t);
            bbox += obj->GetDeformBBox(t, bbox, &tm);

// ......

           GetCOREInterface()->ZoomToBounds(FALSE, bbox );

not tested btw :slight_smile:


#9

I guess you can call these methods on the nodes and then combine box3 together to get the bounds

SDK reference
Bounding Boxes

An object or modifier plug-in is expected to implement two methods that return bounding boxes. Bounding boxes are used primarily for fast rejection during hit testing and for computing the extent of an object or modifier gizmos.

The BaseObject::GetLocalBoundBox() method returns the object space bounding box. The system expects that requesting the object space bounding box will be fast, so in most cases an object should cache its bounding box. The object should not, for instance, traverse a long list of vertices calculating minimums and maximums. In the Ripple sample, the cached mesh is used for these bounding box computations.

The BaseObject::GetWorldBoundBox() method returns the world space bounding box. The bounding box returned by this method does not need to be precise. It should, however, be calculated rapidly. The object can handle this by transforming the 8 points of its local bounding box into world space and take the minimums and maximums of the result. Although this isn’t necessarily the tightest bounding box of the object’s points in world space, it is close enough. This box is mainly used for trivial rejection during hit testing and rendering.


#10

About Bounding Box…
ZoomToBounds needs a bounding box in world coordinates. We can use
GetCOREInterface()->GetSelectionWorldBox(…)

Yes, it needs node selection, but selection can be temporary done without view redraw and scene notification…


#11

If you have a selection, you can directly use:

GetCOREInterface()->ViewportZoomExtents (BOOL doAll, BOOL skipPersp=FALSE)

#12

Thank you guys, It seems first method is not mapped and other two functions needs selection (which I do’nt undrstand why).
Maybe we could create another function based on BaseObject::GetWorldBoundBox() to iterate over all objects and then calculate the min and max, right?


#13
 Object* obj = node->EvalWorldState(t).obj;
 Matrix3 tm = node->GetObjectTM(t);
 nodes_bbox += obj->GetDeformBBox(t, bbox, &tm);

Klvnk showed exactly what I would do …


#14

This should work, but I’m using c#, and += operand doesn’t work for IBox3.


#15

This is my c# code:

                    IBox3 bbox = global_interface.Box3.Create();
                    bbox.Init();
                    for (int i = 0; i < nodes.Count; i++) 
                    {
                        IINode node = nodes[i];
                        IObject obj = node.EvalWorldState(time,true).Obj;
                        IMatrix3 tm = node.GetObjectTM(time,null);
                        obj.GetDeformBBox(time, bbox, tm,false);
                        bbox = bbox.IncreaseBy(bbox);
                    }
                    core_interface.ZoomToBounds(false,bbox);

But it will zoom on only single node.


#16

you’re reseting bbox every loop you need a temp box3

IBox3 bbox = global_interface.Box3.Create();
   IBox3 temp = global_interface.Box3.Create();
bbox.Init();
for (int i = 0; i < nodes.Count; i++) 
{
    IINode node = nodes[i];
    IObject obj = node.EvalWorldState(time,true).Obj;
    IMatrix3 tm = node.GetObjectTM(time,null);
    obj.GetDeformBBox(time, temp, tm,false);
   bbox.IncreaseBy(temp);
}
core_interface.ZoomToBounds(false,bbox);

#17

Thank You!, yes now this works perfectly. is that nessecary to do bbox.Init();?


#18

probably not