Back to index

salome-med  6.5.0
TransformedTriangle.hxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #ifndef __TRANSFORMED_TRIANGLE_HXX__
00021 #define __TRANSFORMED_TRIANGLE_HXX__
00022 
00023 #include "INTERPKERNELDefines.hxx"
00024 
00025 #include <vector>
00026 
00027 // Levels : 
00028 // 1 - overview of algorithm + volume result
00029 // 2 - algorithm detail
00030 // 3 - intersection polygon results detail
00031 // 4 - intersection polygon search detail
00032 // higher -> misc. gory details of calculation
00033 
00034 #include "Log.hxx"
00035 
00036 #ifdef WNT
00037 #pragma warning(disable:4251)
00038 #endif
00039 
00040 namespace INTERP_TEST
00041 {
00042   class TransformedTriangleTest;
00043   class TransformedTriangleIntersectTest;
00044 }
00045 
00046 
00047 namespace INTERP_KERNEL
00048 {
00049   class TetraAffineTransform;
00050 
00101   class INTERPKERNEL_EXPORT TransformedTriangle
00102   {
00103  
00104 
00105   public:
00106 
00107     friend class INTERP_TEST::TransformedTriangleTest;
00108     friend class INTERP_TEST::TransformedTriangleIntersectTest;
00109     /*
00110      * Enumerations representing the different geometric elements of the unit tetrahedron
00111      * and the triangle. The end element, NO_* gives the number of elements in the enumeration
00112      * and can be used as end element in loops.
00113      */
00114 
00116     enum TetraCorner { O = 0, X, Y, Z, NO_TET_CORNER };
00117 
00119     enum TetraEdge { OX = 0, OY, OZ, XY, YZ, ZX, H01, H10, NO_TET_EDGE };
00120 
00122     enum TetraFacet { OYZ = 0, OZX, OXY, XYZ, NO_TET_FACET };
00123 
00125     enum TriCorner { P = 0, Q, R, NO_TRI_CORNER };
00126     
00128     enum TriSegment { PQ = 0, QR, RP, NO_TRI_SEGMENT };
00129     
00131     enum IntersectionPolygon{ A = 0, B, NO_INTERSECTION_POLYGONS };
00132 
00135     enum DoubleProduct { C_YZ = 0, C_ZX, C_XY, C_ZH, C_XH, C_YH, C_01, C_10, NO_DP };
00136 
00137     TransformedTriangle(double* p, double* q, double* r); 
00138     ~TransformedTriangle();
00139 
00140     double calculateIntersectionVolume(); 
00141     double calculateIntersectionSurface(TetraAffineTransform* tat);
00142 
00143     void dumpCoords() const;
00144 
00145     // Queries of member values used by UnitTetraIntersectionBary
00146 
00147     const double* getCorner(TriCorner corner) const { return _coords + 5*corner; }
00148 
00149     const std::vector<double*>& getPolygonA() const { return _polygonA; }
00150 
00151     double getVolume() const { return _volume; }
00152 
00153   protected:
00154 
00155     TransformedTriangle() { }
00156 
00157     // ----------------------------------------------------------------------------------
00158     //  High-level methods called directly by calculateIntersectionVolume()     
00159     // ----------------------------------------------------------------------------------
00160     void calculateIntersectionAndProjectionPolygons();
00161 
00162     void calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter); 
00163 
00164     void sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter); 
00165 
00166     double calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter); 
00167 
00168     // ----------------------------------------------------------------------------------
00169     //  High-level methods called directly by calculateIntersectionSurface()
00170     // ----------------------------------------------------------------------------------
00171     void calculateIntersectionPolygon();
00172 
00173     double calculateSurfacePolygon();
00174 
00175     // ----------------------------------------------------------------------------------
00176     //  Detection of degenerate triangles  
00177     // ----------------------------------------------------------------------------------
00178 
00179     bool isTriangleInPlaneOfFacet(const TetraFacet facet) const;
00180     
00181     bool isTriangleParallelToFacet(const TetraFacet facet) const;
00182 
00183     int isTriangleInclinedToFacet(const TetraFacet facet) const;
00184 
00185     bool isTriangleBelowTetraeder() const;
00186 
00187     // ----------------------------------------------------------------------------------
00188     //  Intersection test methods and intersection point calculations           
00189     // ----------------------------------------------------------------------------------
00190  
00191     inline bool testSurfaceEdgeIntersection(const TetraEdge edge) const; 
00192 
00193     void calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const;  
00194 
00195     inline bool testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const; 
00196 
00197     void calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const;  
00198 
00199     bool testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const; 
00200  
00201     void calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const ; 
00202 
00203     bool testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const ;
00204 
00205     inline bool testSurfaceRayIntersection(const TetraCorner corner) const;
00206 
00207     bool testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edg);
00208 
00209     void calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const;
00210     
00211     bool testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const;
00212 
00213     inline bool testCornerInTetrahedron(const TriCorner corner) const;
00214 
00215     inline bool testCornerOnXYZFacet(const TriCorner corner) const;
00216 
00217     inline bool testCornerAboveXYZFacet(const TriCorner corner) const;
00218 
00219     // ----------------------------------------------------------------------------------
00220     //  Utility methods used in intersection tests                       
00221     // ----------------------------------------------------------------------------------
00222     
00223     bool testTriangleSurroundsEdge(const TetraEdge edge) const;
00224 
00225     inline bool testEdgeIntersectsTriangle(const TetraEdge edge) const;
00226 
00227     inline bool testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const;
00228 
00229     inline bool testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const;
00230 
00231     bool testSegmentIntersectsHPlane(const TriSegment seg) const;
00232 
00233     bool testSurfaceAboveCorner(const TetraCorner corner) const;
00234     
00235     bool testTriangleSurroundsRay(const TetraCorner corner) const;
00236 
00237     // ----------------------------------------------------------------------------------
00238     //  Double and triple product calculations                           
00239     // ----------------------------------------------------------------------------------
00240     
00241     void resetNearZeroCoordinates();
00242 
00243     bool areDoubleProductsConsistent(const TriSegment seg) const;
00244 
00245     void preCalculateDoubleProducts(void);
00246 
00247     inline void resetDoubleProducts(const TriSegment seg, const TetraCorner corner);
00248 
00249     double calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const;
00250     
00251     void preCalculateTripleProducts(void);
00252 
00253     double calculateAngleEdgeTriangle(const TetraEdge edge) const;
00254 
00255     inline double calcStableC(const TriSegment seg, const DoubleProduct dp) const;
00256 
00257     inline double calcStableT(const TetraCorner corner) const;
00258 
00259     inline double calcUnstableC(const TriSegment seg, const DoubleProduct dp) const;
00260 
00261     double calcTByDevelopingRow(const TetraCorner corner, const int row = 1, const bool project = false) const;
00262 
00263     // ----------------------------------------------------------------------------------
00264     //  Member variables                                                 
00265     // ----------------------------------------------------------------------------------
00266   protected:
00267 
00271     double _coords[15];
00272     
00274     bool _is_double_products_calculated;
00275 
00277     bool _is_triple_products_calculated; 
00278 
00282     double _doubleProducts[24];
00283 
00286     double _tripleProducts[4];
00287 
00290     std::vector<double*> _polygonA;
00291     
00294     std::vector<double*> _polygonB;
00295     
00298     double _barycenterA[3];
00299 
00302     //double _barycenterB[3];
00303 
00306     bool _validTP[4];
00307 
00309     double _volume;
00310     
00316     void preCalculateTriangleSurroundsEdge();
00317 
00320     bool _triangleSurroundsEdgeCache[NO_TET_EDGE];
00321 
00322     // ----------------------------------------------------------------------------------
00323     //  Constants                                                    
00324     // ----------------------------------------------------------------------------------
00325 
00326     // offsets : 0 -> x, 1 -> y, 2 -> z, 3 -> h, 4 -> H
00327     // corresponds to order of double products in DoubleProduct
00328     // so that offset[C_*] gives the right coordinate
00329     static const int DP_OFFSET_1[8];
00330     static const int DP_OFFSET_2[8];
00331 
00332     // the coordinates used in the expansion of triple products by a given row
00333     // in constellation (corner, row-1)
00334     // (0,1,2,3) <=> (x,y,z,h)
00335     static const int COORDINATE_FOR_DETERMINANT_EXPANSION[12];
00336 
00337     // contains the edge of the double product used when 
00338     // expanding the triple product determinant associated with each corner
00339     // by a given row
00340     static const DoubleProduct DP_FOR_DETERMINANT_EXPANSION[12];
00341     
00342     // values used to decide how imprecise the double products 
00343     // should be to set them to 0.0
00344     static const long double MACH_EPS;    // machine epsilon
00345     static const long double MULT_PREC_F; // precision of multiplications (Grandy : f)
00346     static const long double THRESHOLD_F; // threshold for zeroing (Grandy : F/f)
00347 
00348     static const double TRIPLE_PRODUCT_ANGLE_THRESHOLD;
00349 
00350     // correspondance facet - double product
00351     // Grandy, table IV
00352     static const DoubleProduct DP_FOR_SEG_FACET_INTERSECTION[12];
00353 
00354     // signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION
00355     static const double SIGN_FOR_SEG_FACET_INTERSECTION[12];
00356     
00357     // coordinates of corners of tetrahedron
00358     static const double COORDS_TET_CORNER[12];
00359     
00360     // indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION
00361     // for the calculation of the coordinates (x,y,z) of the intersection points
00362     // for Segment-Facet and Segment-Edge intersections
00363     static const int DP_INDEX[12];
00364 
00365     // correspondance edge - corners
00366     static const TetraCorner CORNERS_FOR_EDGE[12];
00367 
00368     // correspondance edge - facets
00369     // facets shared by each edge
00370     static const TetraFacet FACET_FOR_EDGE[12];
00371 
00372     // correspondance edge - corners
00373     static const TetraEdge EDGES_FOR_CORNER[12];
00374    
00375     // double products used in segment-halfstrip test
00376     static const DoubleProduct DP_FOR_HALFSTRIP_INTERSECTION[12];
00377 
00378     // double products used in segment - ray test
00379     static const DoubleProduct DP_SEGMENT_RAY_INTERSECTION[21];
00380 
00381   };
00382 
00383   // include definitions of inline methods
00384 
00385 #include "TransformedTriangleInline.hxx"
00386 }
00387 
00388 
00389 #endif