Draw a bounding box for a Grid object residing in the fiber bundle. Refinement representations and field fragments are supported (which constitutes AMR).
For each coordinate field, the bounding box is stored with the field and thus re-used if possible. Also, there might be an field in the same data represention be specified. The bounding box information of this field is then shown in addition. This field may consist of various fragments, such that multiple bounding boxes are shown. The bounding box information is cached at each field fragment.
If values in field coordinates are changed, this is not recognized. Code doing so would have to clear the field's BoundingBox interface.
//#include <ocean/GLvish/VRenderCategory.hpp> #include <bone/BundleInput.hpp> #include <bone/GridObject.hpp> #include <bone/FishField.hpp> #include <bone/FieldObject.hpp> #include <ocean/plankton/VCreator.hpp> #include <ocean/shrimp/VEnum.hpp> #include <ocean/shrimp/VObjectStatus.hpp> #include <ocean/shrimp/ColorTypes.hpp> #include <ocean/GLvish/BoundingBox.hpp> #include <fish/lakeview/eye/retina/VSkeletonRenderObject.hpp> #include <baseop/ExpandBBox.hpp> using namespace Wizt; using namespace Fiber; using namespace Eagle; namespace { class GridBoundingBox : virtual public VSkeletonRenderObject { public: TypedSlot<rgba_float_t> Color; TypedSlot<int> Thickness; GridBoundingBox(const string&name, int, const RefPtr<VCreationPreferences>&VP) : VGLRenderObject(name, DEFAULT_OBJECT, VP) , Fish<VObject>(this) , VSkeletonRenderObject(name, DEFAULT_OBJECT, VP) , Color(this,"color", rgba_float_t(0.6, 0.7, 0.9, 1.0), 1) , Thickness(this, "thickness", 20, 5) {} override bool update(VRequest&R, double precision); override void render(VGLRenderContext&Context) const; static string createChildname(const string&obj) { return "BBox(" + obj + ")"; } }; /* Update function: evaluates the current parameter settings and determines the bounding box information for the entire representation, plus the field fragments if a field is specified. */ bool GridBoundingBox::update(VRequest&R, double precision) { #if 0 if (0) { GridSelector GS; MyGrid << R >> GS; if (Fiber::BundlePtr BP = GS.theSourceBundle) { memsize_t Used = 0, Wanted = 0; int frags = BP->getMemoryUsage( Used, Wanted); printf("\n\n GridBoundingBox::update(): %lg bytes used out of %lg (loaded %d fragments)\n\n", Used/1024.0/1024, Wanted/1024.0/1024, frags); } } #endif int nLevel = getMaxRefinementLevel(R); Info<Skeleton> Level = getRefinementLevel(nLevel, R); if (!Level.getSkeleton() ) return setStatusError(R, "No level found"); RefPtr<Grid> G = Level.getGrid(); if (!G) return setStatusError(R, "No Grid found"); RefPtr<Representation> LevelRep = Level.getCartesianRepresentation(); RefPtr<Field> Coords = LevelRep->Positions(); if (!Coords) return setStatusError(R, "No Coordinates"); if (RefPtr<BoundingBox> BBox = getBoundingBox( Coords ) ) { // printf(" Fish::BoundingBox([%s]): SETTING BBOX for Context\n", Name().c_str() ); setBoundingBall(R, BBox); // R.GhostValues.speak("BoundingBox::GhostValues"); VBoundingBox B(BBox); return setStatusInfo(R, "Bounding box" + String( B ) ); } else return setStatusError(R, "No Bounding box"); } /* The OpenGL render routine. Retrieves the field state information, draws the global bounding box of the coordinate field, plus local bounding boxes for all fragments of the specified fields. */ void GridBoundingBox::render(VGLRenderContext&Context) const { RefPtr<BoundingBox> MyBBox = getBoundingBall( Context ); if (!MyBBox) return; if (MyBBox->empty() ) return; using namespace Eagle::PhysicalSpace; int width = 20; Thickness << Context >> width; glLineWidth(width/10.0); glEnable(GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); glPointSize(width/10.0); rgba_float_t color(0.6, 0.7, 0.9, 1.0); Color << Context >> color; glColor( color ); // glColor3f( 0.6, 0.7, 0.9); glDisable(GL_LIGHTING); glEnable( GL_DEPTH_TEST ); glDraw( *MyBBox ); } static Ref<VCreator<GridBoundingBox, AcceptList<Fiber::Grid> > > myCreator("Display/BoundingBox", ObjectQuality::RECOMMENDED); } // namespace