diff --git a/modules/geom/pymod/export_composite3.cc b/modules/geom/pymod/export_composite3.cc index 47988768cc7baf28cb4560895ad43cbdddb8e544..4a37c79f70939446f4a131a1e219ce7e6dc73a21 100644 --- a/modules/geom/pymod/export_composite3.cc +++ b/modules/geom/pymod/export_composite3.cc @@ -33,6 +33,7 @@ void export_Composite3() .def("GetDirection",&Line3::GetDirection) .add_property("origin", &Line3::GetOrigin) .add_property("direction", &Line3::GetDirection) + .def(self_ns::str(self)) ; { // scope @@ -169,6 +170,7 @@ scope PlaneScope = return_value_policy<copy_const_reference>())) .add_property("center", &AlignedCuboid::GetCenter) .add_property("size", &AlignedCuboid::GetSize) + .def(self_ns::str(self)) ; } diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc index 45093dd9bb8927e213c5af627babd19fe9d8f9ce..5f9ad7d1a4ecfc29a4b1aadf18b42c4d4f81e6e0 100644 --- a/modules/gfx/pymod/export_gfx_obj.cc +++ b/modules/gfx/pymod/export_gfx_obj.cc @@ -65,17 +65,17 @@ using namespace ost::gfx; GfxObj(name) {} - virtual geom::AlignedCuboid GetBoundingBox() const + virtual geom::AlignedCuboid GetBoundingBox(bool return_global=true) const { if(override f = this->get_override("GetBoundingBox")) { - return f(); + return f(return_global); } else { - return GfxObj::GetBoundingBox(); + return GfxObj::GetBoundingBox(return_global); } } - geom::AlignedCuboid default_GetBoundingBox() const { - return GfxObj::GetBoundingBox(); + geom::AlignedCuboid default_GetBoundingBox(bool return_global) const { + return GfxObj::GetBoundingBox(return_global); } virtual void CustomRenderGL(RenderPass pass) { @@ -175,7 +175,7 @@ void export_GfxObj() .def("GetAALines",&GfxObj::GetAALines) .def("GetLineWidth",&GfxObj::GetLineWidth) .def("GetLineHalo",&GfxObj::GetLineHalo) - .def("GetBoundingBox",&GfxObj::GetBoundingBox, &GfxObjWrap::default_GetBoundingBox) + .def("GetBoundingBox",&GfxObj::GetBoundingBox,&GfxObjWrap::default_GetBoundingBox) .def("_CustomRenderGL",&GfxObj::CustomRenderGL, &GfxObjWrap::default_CustomRenderGL) .def("_CustomPreRenderGL",&GfxObj::CustomPreRenderGL, &GfxObjWrap::default_CustomPreRenderGL) .def("_InitGL",&GfxObj::InitGL, &GfxObjWrap::default_InitGL) diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index 8b73a3391ec8a0a8ac5f4e41357b17738320d1d2..adaa52e479b97355f5d4adb0c2a6aa269302ff54 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -29,11 +29,12 @@ namespace { BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(scene_add_overloads, Scene::Add, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(scene_autoslab_overloads, - Scene::Autoslab, 0, 2) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(scene_export_pov_overloads, Scene::ExportPov, 1,2) void (Scene::*apply)(const InputEvent&, bool)=&Scene::Apply; +void (Scene::*autoslab1)()=&Scene::Autoslab; +void (Scene::*autoslab2)(bool)=&Scene::Autoslab; +void (Scene::*autoslab3)(bool,bool)=&Scene::Autoslab; Scene* get_scene() { @@ -49,6 +50,21 @@ GfxObjP scene_getitem(Scene* scene, const String& item) return scene->operator[](item); } +geom::AlignedCuboid scene_get_bb1(Scene* scene) +{ + return scene->GetBoundingBox(); +} + +geom::AlignedCuboid scene_get_bb2(Scene* scene, bool use_tf) +{ + return scene->GetBoundingBox(use_tf); +} + +geom::AlignedCuboid scene_get_bb3(Scene* scene, const mol::Transform& tf) +{ + return scene->GetBoundingBox(tf); +} + } // anon ns @@ -80,11 +96,16 @@ void export_Scene() class_<Scene, boost::noncopyable>("SceneSingleton",no_init) .def("Add", &Scene::Add, scene_add_overloads()) - .def("Autoslab", &Scene::Autoslab, - scene_autoslab_overloads()) + .def("Autoslab", autoslab1) .def("AutoAutoslab",&Scene::AutoAutoslab) .def("GetAutoAutoslab",&Scene::GetAutoAutoslab) - .def("AutoslabMax",&Scene::AutoslabMax) + .add_property("auto_autoslab",&Scene::GetAutoAutoslab,&Scene::AutoAutoslab) + .def("SetAutoslabMode",&Scene::SetAutoslabMode) + .def("GetAutoslabMode",&Scene::GetAutoslabMode) + .add_property("autoslab_mode",&Scene::GetAutoslabMode,&Scene::SetAutoslabMode) + .def("Autoslab", autoslab2) // DEPRECATED + .def("Autoslab", autoslab3) // DEPRECATED + .def("AutoslabMax",&Scene::AutoslabMax) // DEPRECATED .def("Remove", remove1) .def("Remove", remove2) .add_property("viewport", &Scene::GetViewport) @@ -202,5 +223,9 @@ void export_Scene() .def("__getitem__",scene_getitem) .add_property("show_center",&Scene::GetShowCenter, &Scene::SetShowCenter) .add_property("fix_center",&Scene::GetFixCenter, &Scene::SetFixCenter) + .def("GetBoundingBox",scene_get_bb1) + .def("GetBoundingBox",scene_get_bb2) + .def("GetBoundingBox",scene_get_bb3) + .add_property("bounding_box",scene_get_bb1) ; } diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc index dff4bfa1fb8465036438a59ebdf8f72dc2a3277b..0154907216fc4940b726707307db806981cb7a2f 100644 --- a/modules/gfx/src/entity.cc +++ b/modules/gfx/src/entity.cc @@ -252,39 +252,11 @@ void Entity::UpdatePositions() -geom::AlignedCuboid Entity::GetBoundingBox() const +geom::AlignedCuboid Entity::GetBoundingBox(bool use_tf) const { this->UpdateIfNeeded(); - return bbox_; -} - -void Entity::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, - const Transform& tf) const -{ - try { - geom::AlignedCuboid coord_limits=this->GetBoundingBox(); - // update min/max by transforming all 8 corners of the bounding box and - // comparing it against the current min/max - geom::Vec3 mmin=coord_limits.GetMin(); - geom::Vec3 mmax=coord_limits.GetMax(); - geom::Vec3 t1=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmin[2])); - geom::Vec3 t2=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmin[2])); - geom::Vec3 t3=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmin[2])); - geom::Vec3 t4=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmin[2])); - geom::Vec3 t5=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmax[2])); - geom::Vec3 t6=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmax[2])); - geom::Vec3 t7=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmax[2])); - geom::Vec3 t8=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmax[2])); - minc = geom::Min(minc, geom::Min(t1, geom::Min(t2, geom::Min(t3, - geom::Min(t4, geom::Min(t5, geom::Min(t6, - geom::Min(t7, t8)))))))); - maxc = geom::Max(maxc, geom::Max(t1, geom::Max(t2, geom::Max(t3, - geom::Max(t4, geom::Max(t5, geom::Max(t6, - geom::Max(t7, t8)))))))); - } catch(Error& e) { - // in case the object is empty... - } -} + return use_tf ? transform_.Apply(bbox_) : bbox_; +} void Entity::SetColorForAtom(const Color& col, const AtomHandle& atom) diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh index 7663fe3782fe053df4eb7f0428d6401da26905c9..112a7ac4d8f5b5dbdd6db517a673b9ded7180a34 100644 --- a/modules/gfx/src/entity.hh +++ b/modules/gfx/src/entity.hh @@ -90,11 +90,10 @@ public: RenderMode::Type m, const mol::EntityView& ev); - virtual geom::AlignedCuboid GetBoundingBox() const; - - virtual void ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, - const mol::Transform& tf) const; + virtual geom::AlignedCuboid GetBoundingBox(bool use_global=false) const; + // ProcessLimits uses the default implementation of bounding box + /// internal routine virtual void CustomRenderGL(RenderPass pass); diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc index 1f0486017c6139adc74134f712d72409486744cd..d527ceffabf5b805535a0dc1c796cd74b82ab19b 100644 --- a/modules/gfx/src/gfx_object.cc +++ b/modules/gfx/src/gfx_object.cc @@ -394,7 +394,7 @@ void GfxObj::ColorBy(const img::MapHandle& mh, ////////////////////////////////////////////////// // and now for the rest of the GfxObj interface -geom::AlignedCuboid GfxObj::GetBoundingBox() const +geom::AlignedCuboid GfxObj::GetBoundingBox(bool use_tf) const { return geom::AlignedCuboid(geom::Vec3(),geom::Vec3()); } @@ -403,25 +403,11 @@ void GfxObj::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, const mol::Transform& tf) const { try { - geom::AlignedCuboid coord_limits=this->GetBoundingBox(); + geom::AlignedCuboid coord_limits=tf.Apply(this->GetBoundingBox(true)); // update min/max by transforming all 8 corners of the bounding box and // comparing it against the current min/max - geom::Vec3 mmin=coord_limits.GetMin(); - geom::Vec3 mmax=coord_limits.GetMax(); - geom::Vec3 t1=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmin[2])); - geom::Vec3 t2=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmin[2])); - geom::Vec3 t3=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmin[2])); - geom::Vec3 t4=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmin[2])); - geom::Vec3 t5=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmax[2])); - geom::Vec3 t6=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmax[2])); - geom::Vec3 t7=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmax[2])); - geom::Vec3 t8=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmax[2])); - minc = geom::Min(minc, geom::Min(t1, geom::Min(t2, geom::Min(t3, - geom::Min(t4, geom::Min(t5, geom::Min(t6, - geom::Min(t7, t8)))))))); - maxc = geom::Max(maxc, geom::Max(t1, geom::Max(t2, geom::Max(t3, - geom::Max(t4, geom::Max(t5, geom::Max(t6, - geom::Max(t7, t8)))))))); + minc=geom::Min(minc,coord_limits.GetMin()); + maxc=geom::Min(maxc,coord_limits.GetMax()); } catch(Error& e) { // in case the object is empty... } diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh index d241be75e19f15158d173554f01384b26cdab15f..8809e1046fe10d15c410bc51f86545cc1bc32cf1 100644 --- a/modules/gfx/src/gfx_object.hh +++ b/modules/gfx/src/gfx_object.hh @@ -101,15 +101,27 @@ public: // new gfx obj virtual interface starts here - /// \brief returns the left-bottom-front and the right-top-back corner - /// that encompasses all graphical elements in this object - /// - /// the bounding box is in local coordinates. to obtain the coordinates in - /// the scene, multiply the bounding box by the object's transformation - /// matrix. - virtual geom::AlignedCuboid GetBoundingBox() const; - - /// \brief adjust the given limits according to the represented data + /*! + \brief returns the bounding box of this object + + The bounding box, i.e. the left-bottom-front and the right-top-back corner + of the object, is obtained with this method. The single boolean parameter + denotes whether to return local coordinates or global scene coordinates; + global scene coordinates are local coordinates with the object's transformation + (if present) applied. The default is false, i.e. return local coordinates. + */ + virtual geom::AlignedCuboid GetBoundingBox(bool use_tf=false) const; + + /*! + \brief adjust minimum and maximum extent based on graphical object + + this routine will adjust the provided minimum and maximum points + based on the vertices of the underlying graphical representation, + combining the given Transform with the object transform. + + If derived classes do not implement this method then the limits + will be adjusted based on the Cuboid returned by GetBoundingBox(true) + */ virtual void ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, const mol::Transform& tf) const; diff --git a/modules/gfx/src/map_iso.cc b/modules/gfx/src/map_iso.cc index 8e685e524215dabd1ff12b2abe28965829c2d7b8..5dbd4d3907c57964a3b21c0d9183e3e1917ccf2e 100644 --- a/modules/gfx/src/map_iso.cc +++ b/modules/gfx/src/map_iso.cc @@ -93,13 +93,13 @@ MapIso::MapIso(const String& name, const img::MapHandle& mh, Rebuild(); } -geom::AlignedCuboid MapIso::GetBoundingBox() const +geom::AlignedCuboid MapIso::GetBoundingBox(bool use_tf) const { if(recalc_bb_) { bb_=va_.GetBoundingBox(); recalc_bb_=false; } - return bb_; + return use_tf ? transform_.Apply(bb_) : bb_; } geom::Vec3 MapIso::GetCenter() const diff --git a/modules/gfx/src/map_iso.hh b/modules/gfx/src/map_iso.hh index 814dfa756399c592ddf3df72d3173e5c958a73c6..bb47a129c1d0b04d223387dba693fc89031b12a0 100644 --- a/modules/gfx/src/map_iso.hh +++ b/modules/gfx/src/map_iso.hh @@ -54,7 +54,7 @@ public: MapIso(const String& name, const img::MapHandle& mh,float level, uint a=0); /// returns bounding box of iso-contour object, not overall map - virtual geom::AlignedCuboid GetBoundingBox() const; + virtual geom::AlignedCuboid GetBoundingBox(bool use_global=false) const; /// returns center of iso-contour object, not overall map virtual geom::Vec3 GetCenter() const; diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index 1bd5e460742f0a774bd7e7d46eba5974b4804dd7..a123d3a2dd8f3aba0169763fb723a27e721f7d2c 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -115,7 +115,7 @@ Scene::Scene(): fog_color_(0.0,0.0,0.0,0.0), auto_autoslab_(true), do_autoslab_(true), - do_autoslab_fast_(true), + autoslab_mode_(0), offscreen_flag_(false), main_offscreen_buffer_(0), old_vp_(), @@ -843,7 +843,9 @@ void Scene::Add(const GfxNodeP& n, bool redraw) if(root_node_->GetChildCount()==0) { SetCenter(go->GetCenter()); } - do_autoslab_=true; + if(auto_autoslab_) { + do_autoslab_=true; + } } root_node_->Add(n); @@ -1201,18 +1203,11 @@ public: } void VisitObject(GfxObj* obj, const Stack& st) { if(obj->IsVisible()) { - geom::AlignedCuboid bb=obj->GetBoundingBox(); + // use obj transform for BB calculation as well as provided global transform + geom::AlignedCuboid bb=tf.Apply(obj->GetBoundingBox(True)); if(bb.GetVolume()>0.0) { - Vec3 t1 = tf.Apply(Vec3(bb.GetMin()[0],bb.GetMin()[1],bb.GetMin()[2])); - Vec3 t2 = tf.Apply(Vec3(bb.GetMin()[0],bb.GetMax()[1],bb.GetMin()[2])); - Vec3 t3 = tf.Apply(Vec3(bb.GetMax()[0],bb.GetMax()[1],bb.GetMin()[2])); - Vec3 t4 = tf.Apply(Vec3(bb.GetMax()[0],bb.GetMin()[1],bb.GetMin()[2])); - Vec3 t5 = tf.Apply(Vec3(bb.GetMin()[0],bb.GetMin()[1],bb.GetMax()[2])); - Vec3 t6 = tf.Apply(Vec3(bb.GetMin()[0],bb.GetMax()[1],bb.GetMax()[2])); - Vec3 t7 = tf.Apply(Vec3(bb.GetMax()[0],bb.GetMax()[1],bb.GetMax()[2])); - Vec3 t8 = tf.Apply(Vec3(bb.GetMax()[0],bb.GetMin()[1],bb.GetMax()[2])); - minc = Min(minc,Min(t1,Min(t2,Min(t3,Min(t4,Min(t5,Min(t6,Min(t7,t8)))))))); - maxc = Max(maxc,Max(t1,Max(t2,Max(t3,Max(t4,Max(t5,Max(t6,Max(t7,t8)))))))); + minc = Min(minc,bb.GetMin()); + maxc = Max(maxc,bb.GetMax()); valid=true; } } @@ -1225,6 +1220,11 @@ public: } +geom::AlignedCuboid Scene::GetBoundingBox(bool use_tf) const +{ + return GetBoundingBox(use_tf ? transform_ : mol::Transform()); +} + geom::AlignedCuboid Scene::GetBoundingBox(const mol::Transform& tf) const { BBCalc bbcalc(Vec3(std::numeric_limits<float>::max(), @@ -1706,16 +1706,30 @@ public: } // anon ns +void Scene::Autoslab(bool fast) +{ + LOG_INFO("Autoslab(bool) is deprecated, use Autoslab() and SetAutoslabMode() instead"); + do_autoslab_=true; + autoslab_mode_= fast ? 0 : 1; + RequestRedraw(); +} + void Scene::Autoslab(bool fast, bool) +{ + LOG_INFO("Autoslab(bool,bool) is deprecated, use Autoslab() and SetAutoslabMode() instead"); + Autoslab(fast); +} + +void Scene::Autoslab() { do_autoslab_=true; - do_autoslab_fast_=fast; RequestRedraw(); } void Scene::AutoslabMax() { - geom::AlignedCuboid bb =this->GetBoundingBox(transform_); + LOG_INFO("AutoslabMax() is deprecated, use Autoslab() and SetAutoslabMode() instead"); + geom::AlignedCuboid bb =this->GetBoundingBox(); if(bb.GetVolume()==0.0) { znear_=1; @@ -2146,21 +2160,17 @@ void Scene::do_autoslab() { // skip autoslab if nothing to show yet if(root_node_->GetChildCount()==0) return; - if(do_autoslab_fast_) { - geom::AlignedCuboid bb =this->GetBoundingBox(transform_); - // necessary code duplication due to awkward slab limit impl - if(bb.GetVolume()==0.0) { - // skip if empty BB - return; - } else { - float mynear=-(bb.GetMax()[2])-1.0; - float myfar=-(bb.GetMin()[2])+1.0; - znear_=mynear; - zfar_=myfar; - set_near(mynear); - set_far(myfar); + float nnear=znear_; + float nfar=zfar_; + if(autoslab_mode_==0) { + // fast + geom::AlignedCuboid bb =this->GetBoundingBox(); + if(bb.GetVolume()>0.0) { + nnear=-(bb.GetMax()[2])-1.0; + nfar=-(bb.GetMin()[2])+1.0; } - } else { + } else if (autoslab_mode_==1) { + // precise LimCalc limcalc; limcalc.transform=transform_; limcalc.minc = Vec3(std::numeric_limits<float>::max(), @@ -2170,16 +2180,34 @@ void Scene::do_autoslab() -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max()); this->Apply(limcalc); - if(!limcalc.valid) { - return; + if(limcalc.valid) { + nnear=std::max(float(0.0), std::min(float(-limcalc.minc[2]),float(-limcalc.maxc[2])))-float(1.0); + nfar=std::max(float(-limcalc.minc[2]),float(-limcalc.maxc[2]))+float(1.0); + } + } else if(autoslab_mode_==2) { + // max + geom::AlignedCuboid bb =this->GetBoundingBox(); + + if(bb.GetVolume()>0.0) { + Vec3 cen = transform_.Apply(transform_.GetCenter()); + + float bmax = std::max(std::abs(cen[0]-bb.GetMin()[0]), + std::abs(cen[0]-bb.GetMax()[0])); + bmax = std::max(bmax,float(std::abs(cen[1]-bb.GetMin()[1]))); + bmax = std::max(bmax,float(std::abs(cen[1]-bb.GetMax()[1]))); + bmax = std::max(bmax,float(std::abs(cen[2]-bb.GetMin()[2]))); + bmax = std::max(bmax,float(std::abs(cen[2]-bb.GetMax()[2]))); + + nnear = -(cen[2]+bmax*1.5); + nfar = -(cen[2]-bmax*1.5); } - float mynear=std::max(float(0.0), std::min(float(-limcalc.minc[2]),float(-limcalc.maxc[2])))-float(1.0); - float myfar=std::max(float(-limcalc.minc[2]),float(-limcalc.maxc[2]))+float(1.0); - znear_=mynear; - zfar_=myfar; - set_near(mynear); - set_far(myfar); } + + // necessary code duplication due to awkward slab limit impl + znear_=nnear; + zfar_=nfar; + set_near(nnear); + set_far(nfar); ResetProjection(); RequestRedraw(); } diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index a5868d0606581bff66c84b32b5d53f071bc44751..6912bfbfffb4d26ac9c8974ddee8a63b8756a6d8 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -180,20 +180,48 @@ class DLLEXPORT_OST_GFX Scene { /// \brief convenciene function to set fog near and far offset void SetFogOffsets(float no, float fo); - /// \brief adjust near and far clipping plane to fit visible objects - // TODO: use mode aka fast, precise, max - void Autoslab(bool fast=false, bool redraw=true); + /// DEPRECATED, use Autoslab() and SetAutoslabMode(int) + void Autoslab(bool fast); - /// \brief adjust clipping planes to fix maximal extent of all objects - /// even under rotation - // TODO: merge with Autoslab + /// DEPRECATED, use Autoslab() and SetAutoslabMode(int) + void Autoslab(bool fast, bool); + + /// DEPRECATED, use SetAutoslabMode(2) void AutoslabMax(); - /// \brief turn on automatic auto-slabbing (using the fast bounding box alg) - // TODO: more sophisticated mode, aka fast, precise, max + /*! + \brief adjust near and far clipping plane to fit visible objects + + Use autoslab mode to calculate near and far clipping places; this + does not need to be called explicitely if AutoAutoslab is active. + Uses the mode set by \ref SetAutoslabMode + */ + void Autoslab(); + + /*! + \brief set autoslab mode + + 0: fast (default), using only the bounding box + 1: precise, using each graphical element (not implemented) + 2: max, using maximal extent upon rotation + */ + void SetAutoslabMode(int mode) { + autoslab_mode_=std::min(2,std::max(0,mode)); + } + + /// \brief return current autoslab mode + int GetAutoslabMode() const { + return autoslab_mode_; + } + + /*! + \brief turn automatic autoslab'bing on or off for each scene update + + the current autoslab mode is honored \ref SetAutoslabMode(int) + */ void AutoAutoslab(bool f); - /// \brief get current state of automatic auto-slabbing + /// \brief get current state of automatic autoslab'bing bool GetAutoAutoslab() const { return auto_autoslab_; } //@} @@ -319,7 +347,15 @@ class DLLEXPORT_OST_GFX Scene { /// \brief calculate unprojected point out of the scene geom::Vec3 UnProject(const geom::Vec3& v, bool ignore_vp=false) const; - /// \brief return bounding box of scene under given transform + /// \brief return bounding box of scene + /*! + the sole boolean parameter determines whether or not the scene + transformation is applied to calculate the bounding box. Since in + most cases it should be used, the default value is true. + */ + geom::AlignedCuboid GetBoundingBox(bool use_tf=true) const; + + /// \brief return bounding box of with a given transform geom::AlignedCuboid GetBoundingBox(const mol::Transform& tf) const; /// \brief get full underlying transformation @@ -496,8 +532,9 @@ private: bool fix_cor_flag_; bool fog_flag_; Color fog_color_; - bool auto_autoslab_; - bool do_autoslab_,do_autoslab_fast_; + bool auto_autoslab_; // run autoslab on each scene update + bool do_autoslab_; // run autoslab on next scene update + int autoslab_mode_; // 0: fast, 1:precise, 2: max bool offscreen_flag_; // a simple indicator whether in offscreen mode or not OffscreenBuffer* main_offscreen_buffer_; // not null if a main offscreen buffer is present diff --git a/modules/gfx/src/surface.cc b/modules/gfx/src/surface.cc index 488375cf5b46ba29ee9e37c4c28f5368d750ad2c..0500e72b1482ae2ea32b7cd80fd3ee794a96e5bd 100644 --- a/modules/gfx/src/surface.cc +++ b/modules/gfx/src/surface.cc @@ -140,29 +140,32 @@ void Surface::Rebuild() recalc_bb_=true; } -geom::AlignedCuboid Surface::GetBoundingBox() const +geom::AlignedCuboid Surface::GetBoundingBox(bool use_tf) const { - static Vec3 minc,maxc; + static geom::AlignedCuboid bb; if(recalc_bb_) { - minc=Vec3(std::numeric_limits<float>::max(), + geom::Vec3 minc(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max()); - maxc=Vec3(-std::numeric_limits<float>::max(), + geom::Vec3 maxc(-std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max()); std::vector<mol::SurfaceVertexID> svid_list = sh_.GetVertexIDList(); - for(std::vector<mol::SurfaceVertexID>::const_iterator it=svid_list.begin(); - it!=svid_list.end();++it) { - Vec3 pos = sh_.GetVertex(*it).position; - minc=Min(minc,pos); - maxc=Max(maxc,pos); + if(svid_list.size()>0) { + for(std::vector<mol::SurfaceVertexID>::const_iterator it=svid_list.begin(); + it!=svid_list.end();++it) { + geom::Vec3 pos = sh_.GetVertex(*it).position; + minc=geom::Min(minc,pos); + maxc=geom::Max(maxc,pos); + } + minc-=geom::Vec3(1.0,1.0,1.0); + maxc+=geom::Vec3(1.0,1.0,1.0); + recalc_bb_=false; + bb=geom::AlignedCuboid(minc,maxc); } - minc-=Vec3(1.0,1.0,1.0); - maxc+=Vec3(1.0,1.0,1.0); - recalc_bb_=false; } - return geom::AlignedCuboid(minc,maxc); + return use_tf ? transform_.Apply(bb) : bb; } void Surface::CustomPreRenderGL(bool flag) diff --git a/modules/gfx/src/surface.hh b/modules/gfx/src/surface.hh index 740ae787fcb4c5f0550201ae36856c9d2ee07f4e..ff3ea292c6940cce040d5600aa370250f2868105 100644 --- a/modules/gfx/src/surface.hh +++ b/modules/gfx/src/surface.hh @@ -56,7 +56,7 @@ public: virtual void CustomRenderGL(RenderPass pass); virtual void CustomRenderPov(PovState& pov); - virtual geom::AlignedCuboid GetBoundingBox() const; + virtual geom::AlignedCuboid GetBoundingBox(bool use_global=false) const; mol::SurfaceHandle GetHandle() const; diff --git a/modules/mol/base/src/transform.cc b/modules/mol/base/src/transform.cc index c1ffbff6b8a34bf6016d01fba72deeba8a2f4fdb..d035bf2b9a0b9887f172f492fe7ed185ead7ac1f 100644 --- a/modules/mol/base/src/transform.cc +++ b/modules/mol/base/src/transform.cc @@ -164,6 +164,23 @@ Vec4 Transform::Apply(const Vec4& v) const return nrvo; } +geom::AlignedCuboid Transform::Apply(const geom::AlignedCuboid& c) const +{ + geom::Vec3 cmin=c.GetMin(); + geom::Vec3 cmax=c.GetMax(); + Vec3 t1 = Apply(Vec3(cmin[0],cmin[1],cmin[2])); + Vec3 t2 = Apply(Vec3(cmin[0],cmax[1],cmin[2])); + Vec3 t3 = Apply(Vec3(cmax[0],cmax[1],cmin[2])); + Vec3 t4 = Apply(Vec3(cmax[0],cmin[1],cmin[2])); + Vec3 t5 = Apply(Vec3(cmin[0],cmin[1],cmax[2])); + Vec3 t6 = Apply(Vec3(cmin[0],cmax[1],cmax[2])); + Vec3 t7 = Apply(Vec3(cmax[0],cmax[1],cmax[2])); + Vec3 t8 = Apply(Vec3(cmax[0],cmin[1],cmax[2])); + geom::Vec3 minc = Min(t1,Min(t2,Min(t3,Min(t4,Min(t5,Min(t6,Min(t7,t8))))))); + geom::Vec3 maxc = Max(t1,Max(t2,Max(t3,Max(t4,Max(t5,Max(t6,Max(t7,t8))))))); + return geom::AlignedCuboid(minc,maxc); +} + /* The order of the transformations given herein is conceptually "backward" as they are applied to a vertex, because the left-right diff --git a/modules/mol/base/src/transform.hh b/modules/mol/base/src/transform.hh index 1ed33135e1ca1287f0e2c9debc151aeacca069cc..726b578a73f82ee27ab77c0303df8e31a41cc39d 100644 --- a/modules/mol/base/src/transform.hh +++ b/modules/mol/base/src/transform.hh @@ -73,6 +73,7 @@ public: geom::Vec3 Apply(const geom::Vec3& v) const; geom::Vec4 Apply(const geom::Vec4& v) const; + geom::AlignedCuboid Apply(const geom::AlignedCuboid& c) const; private: geom::Mat3 rot_; @@ -84,6 +85,8 @@ private: void update_tm(); }; + + #if(OST_INFO_ENABLED) /// \brief read transformation from info group /// \relates Transform