We distinguish between two types of conditions:
Function MT_IsGood must be specialized if the condition requires some property on the MT (e.g., tiles and/or embedding space of a certain dimension).
Function MT_EvalCond, called within the extractor, has an MT_MultiTesselation among its arguments. The condition cannot access the functions of class WithYYYClass (accessing the attribute) through such argument, even if it points to m (which is actually of a subclass of WithYYYClass).
Therefore, the condition contains inside it a pointer to an object of the abstract class WithYYYClass. We call the constructor of the condition with an MT m of any subclass of WithYYYClass, which will be stored inside the condition into the above pointer.
The condition must be used only in an extractor created on the same MT m. MT m is accessed in this way:
A resolution filter condition will be a subclass of MT_CondClass that:
If the tile feature must be provided by the MT, the resolution filter needs to contain internally a pointer to the abstract class defining the interface of the feature, and its constructor will also accept an object of (a subclass of) that class.
typedef class TileErrFilterClass * TileErrFilter; class TileErrFilterClass : public MT_CondClass { protected: /* Explicit reference to the MT in order to access tile errors. */ WithTileError my_mt; /* The threshold imposed on tile errors. */ Threshold my_thr; public: /* Return 1 if the error of the tile is <= the threshold value for that tile. Return 0 otherwise. */ int MT_EvalCond(MT_MultiTesselation m, MT_INDEX t, int flag) { return ( my_mt->TileError(t) < my_thr->ThresholdValue(m,t) ); } /* Create a condition given the reference MT m and the threshold tr to be imposed on its tiles. */ TileErrFilterClass(WithTileErrorClass * m, Threshold tr) { my_mt = m; my_thr = tr; } };
We suggest to define focus conditions according to the following guidelines:
The strict evaluation mode of MT_EvalCond discriminates between case 1 (tile considered as active) and cases 2,3 (tile considered as not active). It is used when evaluating the condition on the tiles of the extracted tesselation. Such tiles are already at the resolution desired by the application program.
The loose evaluation mode discriminates between cases 1,2 (tile considered as active) and case 3 (tile considered as not active). It is used for evaluating the condition inside the extraction algorithms. Such algorithms traverse also tiles which are not at the resolution desired by the application, thus it is reasonable to temporarily report a possible intersection; the final decision between intersection or no intersection will be taken when the algorithm arrives at a sufficient resolution.
The following remarks are important:
We first define a general class for a box in d-dimensions, called BoxClass.
typedef class BoxClass * Box; class BoxClass { protected: /* Min and max coordinates of the box on each axis. Only the first d positions of the arrays will be used if box is in d-dimensions. */ float minF[MT_MAX_DIM]; float maxF[MT_MAX_DIM]; /* Number of coordinated of the embedding space. */ int b_dim; public: /* Return the number of coordinates of this box */ int BoxDim(void) { return (b_dim); } /* Set the box position and dimensions. */ void SetBox (float * min_coord, float * max_coord); /* Specialized versions for 2- and 3-dimensional boxes */ void SetBox (float x1, float y1, float x2, float y2); void SetBox (float x1, float y1, float z1, float x2, float y2, float z2); /* Return the box geometry. */ void TheBox (float ** min_coord, float ** max_coord); /* Specialized versions for 2- and 3-dimensional boxes */ void TheBox (float *x1, float *y1, float *x2, float *y2); void TheBox (float *x1, float *y1, float *z1, float *x2, float *y2, float *z2); /* Create a d-dimensional box with the given min and max coordinates. */ BoxClass(int d, float * min_coord, float * max_coord); /* Create a d-dimensional box of null size where both max and min coordinates are all zeroes. */ BoxClass(int d); };Then, we define a focus condition using a 3-dimensional box (i.e., a cuboid) on 2-dimensional MTs embedded in a space of at least three dimensions. If the embedding space is more than 3-dimensional, only the first three vertex coordinates are considered (i.e., the tiles are projected into the x-y-z subspace).
A tile is active either if the interior of the tile intersects the box, or if the boundary of the tile touches the box.
This focus set must be applied to MTs that are subclasses of MT_WithTileErrorClass and implement the function MT_TileError.
The focus condition, called Box3FocusOnTrianglesClass, is a subclass of BoxClass and MT_CondClass. It creates itself as a box with three dimensions, and its constructor needs an argument of type MT_WithTileError.
The loose evaluation mode of MT_EvalCond is implemented by testing the intersection of the given tile with a box enlarged of an amount equal to the tile error.
typedef class Box3FocusOnTrianglesClass * Box3FocusOnTriangles; class Box3FocusOnTrianglesClass : public BoxClass, public MT_CondClass { protected: /* Explicit reference to the MT in order to access tile errors. */ WithTileError my_mt; public: /* Constructors. Parameter m is the reference MT. */ Box3FocusOnTrianglesClass(WithTileError m, float * min_coord, float * max_coord) : BoxClass(3, min_coord, max_coord) { my_mt = m; } Box3FocusOnTrianglesClass(WithTileError m, float x1, float y1, float z1, float x2, float y2, float z2) : BoxClass(3) { SetBox(x1,y1,z1, x2,y2,z2); my_mt = m; } /* Implementation of abstract function from superclass MT_CondClass. */ int MT_EvalCond(MT_MultiTesselation m, MT_INDEX t, int flag) { if (flag==MT_LOOSE) { ... expand the box of an amount equal to my_mt->TileError(t) ... } if (... triangle t intersects the box ...) return 1; return 0; } /* This condition requires 2-dimensional MTs embedded in at least 3D */ int MT_IsGood(MT_MultiTesselation m) { if ( (m->MT_TileDim() != 2) || (m->MT_VertexDim() < 3) ) return 0; return 1; } };