How we can zoom extents on specific group of objects (SDK)?
Zoom ob objects (SDK-C#)
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;
}
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
I guess you can call these methods on the nodes and then combine box3 together to get the bounds
SDK reference
Bounding BoxesAn 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.
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…
If you have a selection, you can directly use:
GetCOREInterface()->ViewportZoomExtents (BOOL doAll, BOOL skipPersp=FALSE)
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?
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 …
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.
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);