FiberVISH 0.2
Fish - The Fiber Bundle API for the Vish Visualization Shell
FragmentBoxes.cpp

Draw a bounding box for a Grid object residing in the fiber bundle.

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 FragmentBoxes interface.

#include <bone/BundleInput.hpp>
#include <bone/GridObject.hpp>
#include <bone/FishField.hpp>
#include <bone/FieldObject.hpp>
#include <ocean/shrimp/Options.hpp>
#include <ocean/shrimp/VObjectStatus.hpp>
#include <ocean/GLvish/BoundingBox.hpp>
#include <ocean/GLvish/GLFonts.hpp>
#include <ocean/Anemonia/FloatOrigin.hpp>
#include <eagle/PhysicalSpace.hpp>
#include <eye/retina/VFieldRenderObject.hpp>
#include <baseop/ExpandBBox.hpp>
using namespace Wizt;
using namespace Fiber;
using namespace Eagle;
namespace
{
class VFragmentBoxes : public VFieldRenderObject
, public Fish<Fiber::Skeleton>
, public FloatOrigin
{
public:
enum { NumberOfInputFields = 1 };
struct FieldState : State, FieldFragmentIterator
{
RefPtr<Field> CurrentCoords;
double MinBBoxRadius, MaxBBoxRadius;
struct PerFragmentInfo
{
PerFragmentInfo(const RefPtr<BoundingBox>&theBBox,
: BBox(theBBox)
, fragID(theFragID)
, DataPtr(theDataPtr)
{}
};
void clear()
{
FieldBBox = new BoundingBox();
BBoxes.clear();
}
bool apply(const RefPtr<FragmentID>&f, const RefPtr<CreativeArrayBase>&CAB) override;
};
RefPtr<State> newState() const override
{
return new FieldState();
}
in<Options> inOptions;
inUnloadedColor,
inFontColor;
TypedSlot<double> Thickness,
inFontScale;
VFragmentBoxes(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
, inOptions(this, "options", Options("+autoscale +showtext"))
, inColor(this,"color", rgba_float_t(0.4, 0.12, 0.65, 1.0), 1)
, inUnloadedColor(this,"uncolor", rgba_float_t(0.3, 0.3, 0.3, 1.0), 2)
, inFontColor(this, "fontcolor", rgba_float_t(0.9, 0.9, 0.9, 1.0), 1)
, Thickness(this, "thickness", 20, 5.0)
, inFontScale(this, "fontscale", 1.0, 1)
{}
bool update(VRequest&R, double precision) override;
bool renderGL(VGLRenderContext&Context) const override;
};
/*
Bounding box field state iterator callback function:
Called for each fragment of an (optional) field.
Determines the bounding box for the respective field fragments
using the global coordinate information.
*/
bool VFragmentBoxes::FieldState::apply(const RefPtr<FragmentID>&fid, const RefPtr<CreativeArrayBase>&FragmentDataCreator)
{
using namespace Eagle::PhysicalSpace;
if (!CurrentCoords)
{
printf("bool VFragmentBoxes::FieldState::apply(const RefPtr<FragmentID>&, CreativeArrayBase&): NO COORDINATES!\n" );
return false;
}
if (RefPtr<BoundingBox> BBox = getFragmentBBox(fid, FragmentDataCreator, *CurrentCoords) )
{
double R = BBox->getRadius();
if (BBoxes.size()<1)
{
MinBBoxRadius = MaxBBoxRadius = R;
}
else
{
if (R<MinBBoxRadius) MinBBoxRadius = R;
if (R>MaxBBoxRadius) MaxBBoxRadius = R;
}
BBoxes.push_back( PerFragmentInfo(BBox,
fid,
);
assert( FieldBBox );
FieldBBox->insert( *BBox );
}
return true;
}
/*
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 VFragmentBoxes::update(VRequest&Context, double precision)
{
{
string Fieldname;
{}
bool apply(const Info<Skeleton>&iS,
int Level,
const RefPtr<ValuePool>&Context) override
{
RefPtr<Fiber::Representation> CartesianLevelRep = iS.getCartesianRepresentation();
// assert( CartesianLevelRep );
{
cout << "VFragmentBoxes::DataExtractor::apply() No CartesianLevelRep found!! Skipping fragment!" << endl;
return true;
}
RefPtr<Field> Coords = CartesianLevelRep->Positions();
S->CurrentCoords = Coords;
if (RefPtr<Field> DataField = (*CartesianLevelRep)(Fieldname) )
{
// printf("LEVEL %d\n", Level);
// CartesianLevelRep.speak("CartesianLevelRep");
DataField->iterate( *S );
}
return true;
}
}
DE;
DE.S = myState(Context);
DE.S->clear();
DE.Fieldname = getFieldname(Context);
IterateLevels(DE, Context);
if (DE.S->FieldBBox)
DE.S->FieldBBox->updateBall();
setBoundingBall(Context, DE.S->FieldBBox);
// printf(" ConnectionAge(): %d inFontScale->ValueAge(Context) %d\n",
// int(ConnectionAge().time_value()),
// int(inFontScale->ValueAge(Context).time_value()));
if (ConnectionAge().isYoungerThan( inFontScale->ValueAge(Context) ) )
{
double R = DE.S->FieldBBox->getRadius();
inFontScale.setProperty("max", R);
}
if (opt("autoscale"))
{
double ProposedFontScale = DE.S->MinBBoxRadius*0.1;
inFontScale << Context <<= ProposedFontScale;
}
if (DE.FieldInstancesFound)
{
return StatusIndicator::setStatusInfo( Context,
"Showing " + String( int(DE.S->BBoxes.size() ) ) + " fragment boxes for "
+ String( DE.FieldInstancesFound ) + " field instances. "
"Bounding box radii vary from " + String(DE.S->MinBBoxRadius) +
" to " + String(DE.S->MaxBBoxRadius) + " ."
);
}
else
{
return setStatusError( Context, "No instances of the given field \"" + DE.Fieldname + "\" found.");
}
}
bool VFragmentBoxes::renderGL(VGLRenderContext&Context) const
{
RefPtr<FieldState> myState = getState(Context);
if (!myState)
return false;
RefPtr<BoundingBox> MyBBox = myState->FieldBBox;
Eagle::tvector3 TranslationVector;
auto T = getCoordinateTranslation(Context, TranslationVector);
using namespace Eagle::PhysicalSpace;
double width = 20;
if (width<=0.0)
width = 1.0;
glLineWidth(width/10.0);
glPointSize(width/10.0);
#if 0
glColor3f( 0.6, 0.7, 0.9);
if (MyBBox && !MyBBox->empty() )
glDraw( *MyBBox );
#endif
rgba_float_t LoadedColor(0.6, 0.7, 0.9, 1.0);
rgba_float_t UnloadedColor(0.3, 0.3, 0.3, 1.0);
rgba_float_t FontColor(0.9, 0.9, 0.9, 1.0);
MyFont = Context.getFont();
if( MyFont) MyFont->setSize(1);
double FontScale = 0.5;
for(unsigned i=0; i<myState->BBoxes.size(); i++)
{
if (!myState->BBoxes[ i ].BBox )
continue;
BoundingBox&CurrentBBox = *myState->BBoxes[ i ].BBox;
if (myState->BBoxes[i].DataPtr &&
myState->BBoxes[i].DataPtr->hasData() )
{
}
else
glDrawBox( CurrentBBox.mincoord() - TranslationVector,
CurrentBBox.maxcoord() - TranslationVector );
if (opt("showtext") && FontScale>0.0 && MyFont && myState->BBoxes[i].fragID)
{
glTranslate( CurrentBBox.center() - TranslationVector );
glScaled(FontScale, FontScale, FontScale );
MyFont->render( myState->BBoxes[i].fragID->Name().c_str() );
}
}
return true;
}
using namespace Panthalassa;
Category("Display") /
VIdentifier("FragmentBoxes"),
ObjectQuality::EXPERIMENTAL );
} // namespace
_Expr< _ValFunClos< _ValArray, _Tp >, _Tp > apply(_Tp __func(_Tp)) const
basic_ostream< _CharT, _Traits > & endl(basic_ostream< _CharT, _Traits > &__os)
ostream cout
constexpr void clear() noexcept
An iterator with an optional DataCreator, which is just a class to intercept creation of data along a...
Definition CreativeIterator.hpp:34
Base class for iterators over the fragments of a field.
Definition FragmentID.hpp:249
Base class for objects rendering fields on a fiber bundle.
Definition VFieldRenderObject.hpp:23
FlagList Options
Given a fragmented field of curvilinear coordinates, (3D array of coordinates), build a uniform Grid ...
Definition FAQ.dox:2
note: cannot derive from FloatingSkeletonRenderer as long as independent base class TriangleRenderer ...
DEFAULT_OBJECT
Definition Lytica.hpp:7
Definition GridInspector.hpp:13