vtf-logo

BRep.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #if !defined(__cpt_BRep_h__)
00004 #define __cpt_BRep_h__
00005 
00006 // Local
00007 #include "Grid.h"
00008 #include "Vertex.h"
00009 #include "Edge.h"
00010 #include "Face.h"
00011 #include "performance.h"
00012 
00013 // Algorithms and data structures.
00014 #include "../ads/array/FixedArray.h"
00015 #ifdef CPT_PERFORMANCE
00016 #include "../ads/timer.h"
00017 #endif
00018 
00019 // Geometry
00020 #include "../geom/mesh/iss/build.h"
00021 #include "../geom/mesh/iss/file_io.h"
00022 #include "../geom/mesh/iss/geometry.h"
00023 #include "../geom/mesh/iss/quality.h"
00024 #include "../geom/mesh/iss/set.h"
00025 #include "../geom/polytope/IndexedEdgePolyhedron.h"
00026 
00027 #include <fstream>
00028 #include <vector>
00029 #include <utility>
00030 #include <set>
00031 
00032 BEGIN_NAMESPACE_CPT
00033 
00039 template <int N, typename T = double>
00040 class BRep;
00041 
00042 
00043 //---------------------------------------------------------------------------
00044 //---------------------------------------------------------------------------
00045 // 1-D
00046 //---------------------------------------------------------------------------
00047 //---------------------------------------------------------------------------
00048 
00050 template <typename T>
00051 class BRep<1,T> {
00052 public:
00053 
00054   // 
00055   // Public types.
00056   //
00057 
00059   typedef T Number;
00061   typedef ads::FixedArray<1,Number> Point;
00063   typedef geom::BBox<1,Number> BBox;
00065   typedef Grid<1,Number> Grid;
00066 
00067   // CONTINUE: With the Intel compiler, private members are not accessible
00068   // in nested classes.
00069 #ifdef __INTEL_COMPILER
00070 public:
00071 #else
00072 private:
00073 #endif
00074 
00075   // The representation of a face.
00076   class FaceRep {
00077   private:
00078 
00080     Point _location;
00082     int _orientation;
00084     int _identifier;
00085 
00086   public:
00087 
00088     //------------------------------------------------------------------------
00090 
00091 
00093     FaceRep()
00094     {}
00095 
00097     FaceRep(const Point& location, const int orientation, 
00098             const int identifier) :
00099       _location(location),
00100       _orientation(orientation),
00101       _identifier(identifier)
00102     {}
00103 
00105     FaceRep(const FaceRep& other) :
00106       _location(other._location),
00107       _orientation(other._orientation),
00108       _identifier(other._identifier)
00109     {}
00110 
00112     FaceRep&
00113     operator=(const FaceRep& other) {
00114       if (&other != this) {
00115         _location = other._location;
00116         _orientation = other._orientation;
00117         _identifier = other._identifier;
00118       }
00119       return *this;
00120     }
00121 
00123     ~FaceRep()
00124     {}
00125 
00127     //------------------------------------------------------------------------
00129 
00130 
00132     const Point&
00133     getLocation() const {
00134       return _location;
00135     }
00136 
00138     int 
00139     getOrientation() const {
00140       return _orientation;
00141     }
00142 
00144     int 
00145     getIdentifier() const {
00146       return _identifier;
00147     }
00148 
00150   };
00151 
00152   // Functor for comparing faces by their location.
00153   class LocationCompare :
00154     public std::binary_function<FaceRep,FaceRep,bool> {
00155   private:
00156     typedef std::binary_function<FaceRep,FaceRep,bool> Base;
00157   public:
00158     typedef typename Base::first_argument_type first_argument_type;
00159     typedef typename Base::second_argument_type second_argument_type;
00160     typedef typename Base::result_type result_type;
00161 
00162     result_type
00163     operator()(const first_argument_type& x, const second_argument_type& y) {
00164       return x.getLocation() < y.getLocation();
00165     }
00166   };
00167 
00168 private:
00169 
00170   // CONTINUE REMOVE
00171   // This class needs access to private type inside BRep.
00172   //friend class LocationCompare;
00173 
00174   // Functor for comparing faces by their identifier.
00175   class IdentifierCompare :
00176     public std::binary_function<FaceRep,FaceRep,bool> {
00177   private:
00178     typedef std::binary_function<FaceRep,FaceRep,bool> Base;
00179   public:
00180     typedef typename Base::first_argument_type first_argument_type;
00181     typedef typename Base::second_argument_type second_argument_type;
00182     typedef typename Base::result_type result_type;
00183 
00184     result_type
00185     operator()(const first_argument_type& x, const second_argument_type& y) {
00186       return x.getIdentifier() < y.getIdentifier();
00187     }
00188   };
00189 
00190   // CONTINUE REMOVE
00191   // This class needs access to private type inside BRep.
00192   //friend class IdentifierCompare;
00193 
00194   //
00195   // Private types.
00196   //
00197 
00199   typedef Face<1,Number> Face;
00200 
00201   //
00202   // Member data.
00203   //
00204 
00205   // The faces.
00206   std::vector<FaceRep> _faces;
00207   // How far to compute the distance.
00208   mutable Number _maximumDistance;
00209 
00210 public:
00211 
00212   //--------------------------------------------------------------------------
00213   // \name Constructors, etc.
00215     
00217   BRep() : 
00218     _faces(),
00219     _maximumDistance(0)
00220   {}
00221 
00223 
00238   template <typename NumberInputIter, typename IntegerInputIter>
00239   BRep(NumberInputIter locationsBeginning, NumberInputIter locationsEnd,
00240        IntegerInputIter orientationsBeginning, 
00241        IntegerInputIter orientationsEnd,
00242        const BBox& cartesianDomain,
00243        const Number maximumDistance) {
00244     make(locationsBeginning, locationsEnd, 
00245          orientationsBeginning, orientationsEnd,
00246          cartesianDomain, maximumDistance);
00247   }
00248 
00250   BRep(const BRep& other) :
00251     _faces(other._faces),
00252     _maximumDistance(other._maximumDistance)
00253   {}
00254 
00256   BRep& 
00257   operator=(const BRep& other) {
00258     if (&other != this) {
00259       _faces = other._faces;
00260       _maximumDistance = other._maximumDistance;
00261     }
00262     return *this;
00263   }
00264   
00266   ~BRep()
00267   {}
00268     
00270 
00278   template <typename NumberInputIter, typename IntegerInputIter>
00279   void 
00280   make(NumberInputIter locationsBeginning, NumberInputIter locationsEnd,
00281        IntegerInputIter orientationsBeginning, 
00282        IntegerInputIter orientationsEnd) {
00283     // Add the faces.
00284     NumberInputIter location = locationsBeginning;
00285     IntegerInputIter orientation = orientationsBeginning;
00286     int identifier = 0;
00287     while (location != locationsEnd) {
00288       insertFace(*location, *orientation, identifier);
00289       ++location;
00290       ++orientation;
00291       ++identifier;
00292     }
00293 #ifdef DEBUG_cpt
00294     assert(orientation == orientationsEnd);
00295 #endif
00296 
00297     // Sort the faces.
00298     LocationCompare comp;
00299     std::sort(_faces.begin(), _faces.end(), comp);
00300   }
00301 
00303 
00316   template <typename NumberInputIter, typename IntegerInputIter>
00317   void 
00318   make(NumberInputIter locationsBeginning, NumberInputIter locationsEnd,
00319        IntegerInputIter orientationsBeginning, 
00320        IntegerInputIter orientationsEnd,
00321        const BBox& cartesianDomain,
00322        const Number maximumDistance) {
00323     _maximumDistance = maximumDistance;
00324     const BBox 
00325       interestDomain(cartesianDomain.getLowerCorner()[0] - maximumDistance,
00326                      cartesianDomain.getUpperCorner()[0] + maximumDistance);
00327 
00328     // Add the faces.
00329     NumberInputIter location = locationsBeginning;
00330     IntegerInputIter orientation = orientationsBeginning;
00331     int identifier = 0;
00332     ads::FixedArray<1,Number> loc;
00333     while (location != locationsEnd) {
00334       loc[0] = (*location)[0];
00335       if (interestDomain.isIn(loc)) {
00336         insertFace(loc, *orientation, identifier);
00337       }
00338       ++location;
00339       ++orientation;
00340       ++identifier;
00341     }
00342 #ifdef DEBUG_cpt
00343     assert(orientation == orientationsEnd);
00344 #endif
00345 
00346     // Sort the faces.
00347     LocationCompare comp;
00348     std::sort(_faces.begin(), _faces.end(), comp);
00349   }
00350 
00352   //--------------------------------------------------------------------------
00353   // \name Size accessors.
00355 
00357   bool
00358   isEmpty() const {
00359     return _faces.empty();
00360   }
00361 
00363   int
00364   getSimplicesSize() const {
00365     return _faces.size();
00366   }
00367 
00369   int 
00370   computeMaximumFaceIdentifier() const {
00371     if (isEmpty()) {
00372       return -1;
00373     }
00374     IdentifierCompare comp;
00375     return std::max_element(_faces.begin(), _faces.end(), 
00376                             comp)->getIdentifier();
00377   }
00378 
00380   //--------------------------------------------------------------------------
00381   // \name Mathematical Operations.
00383 
00385   std::pair<int,int>
00386   computeClosestPoint(std::vector<Grid>& grids, 
00387                       const Number maximumDistance) const {
00388     // CONTINUE: Make efficient.
00389     const int gridsSize = grids.size();
00390     assert(gridsSize > 0);
00391 
00392     _maximumDistance = maximumDistance;
00393     int i;
00394     int scanConversionCount = 0;
00395     int distanceCount = 0;
00396     std::pair<int,int> faceCount;
00397 
00398     // Find the closest points and distance for the faces.
00399     Face face;
00400     for (i = 0; i != getSimplicesSize(); ++i) {
00401       // Get the i_th face.
00402       getFace(i, &face);
00403       // For each grid.
00404       for (int n = 0; n != gridsSize; ++n) {
00405         // Scan convert the grid points and compute the distance etc.
00406         faceCount = grids[n].computeClosestPointTransform(face, 
00407                                                           maximumDistance);
00408         scanConversionCount += faceCount.first;
00409         distanceCount += faceCount.second;
00410       }
00411     }
00412 
00413     return std::pair<int,int>(scanConversionCount, distanceCount);
00414   }
00415 
00417   std::pair<int,int>
00418   computeClosestPointUnsigned(std::vector<Grid>& grids, 
00419                               const Number maximumDistance) const {
00420     // CONTINUE: Make efficient.
00421     const int gridsSize = grids.size();
00422     assert(gridsSize > 0);
00423 
00424     _maximumDistance = maximumDistance;
00425     int i;
00426     int scanConversionCount = 0;
00427     int distanceCount = 0;
00428     std::pair<int,int> faceCount;
00429 
00430     // Find the closest points and distance for the faces.
00431     Face face;
00432     for (i = 0; i != getSimplicesSize(); ++i) {
00433       // Get the i_th face.
00434       getFace(i, &face);
00435       // For each grid.
00436       for (int n = 0; n != gridsSize; ++n) {
00437         // Scan convert the grid points and compute the distance etc.
00438         faceCount = grids[n].computeClosestPointTransformUnsigned
00439           (face, maximumDistance);
00440         scanConversionCount += faceCount.first;
00441         distanceCount += faceCount.second;
00442       }
00443     }
00444 
00445     return std::pair<int,int>(scanConversionCount, distanceCount);
00446   }
00447 
00449   BBox
00450   computeBBox() const {
00451     if (getSimplicesSize() == 0) {
00452       return BBox(0, -1); 
00453     }
00454     BBox box(_faces[0].getLocation()[0], _faces[0].getLocation()[0]);
00455     for (int n = 1; n != getSimplicesSize(); ++n) {
00456       box.add(_faces[n].getLocation());
00457     }
00458     return box;
00459   }
00460 
00462   //--------------------------------------------------------------------------
00463   // \name File I/O.
00465 
00467 
00470   void 
00471   displayInformation(std::ostream& out) const {
00472     out << "Number of faces: " << getSimplicesSize() << '\n'
00473         << "Bounding box: " << computeBBox() << '\n';
00474   }
00475 
00477   void 
00478   display(std::ostream& out) const {
00479     out << "Number of faces: " << getSimplicesSize() << '\n';
00480     const int iEnd = _faces.size();
00481     for (int i = 0; i != iEnd; ++i) {
00482       out << _faces[i].getLocation() << " "
00483           << _faces[i].getOrientation() << " "
00484           << _faces[i].getIdentifier() << '\n';
00485     }
00486   }
00487 
00489 
00490 private:
00491 
00492   //
00493   // Accessors.
00494   //
00495 
00496   // Make the n_th face
00497   void 
00498   getFace(const int n, Face* face) const {
00499 #ifdef DEBUG_cpt
00500     assert(0 <= n && n < getSimplicesSize());
00501 #endif
00502     // Get locations for the left and right neighbors.
00503     // If there is no neighbor, give a far-away point.
00504     // I divide by 2 to avoid overflow problems in Face.
00505     Point left = - std::numeric_limits<Number>::max() / 2.0;
00506     if (n != 0) {
00507       left = _faces[n-1].getLocation();
00508     }
00509     Point right = std::numeric_limits<Number>::max() / 2.0;
00510     if (n != getSimplicesSize() - 1) {
00511       right = _faces[n+1].getLocation();
00512     }
00513     // Make the face.
00514     face->make(_faces[n].getLocation(), _faces[n].getOrientation(), 
00515                _faces[n].getIdentifier(), left, right, _maximumDistance);
00516   }
00517 
00518   int 
00519   getFaceIdentifier(const int n) const {
00520     return _faces[n].getIdentifier();
00521   }
00522 
00523   //
00524   // Manipulators.
00525   //
00526 
00527   // Add a face. 
00528   // a, b and c are indices of vertices in the positive orientation.
00529   void 
00530   insertFace(const Point& location, const int orientation, 
00531              const int faceIdentifier) {
00532     _faces.push_back(FaceRep(location, orientation, faceIdentifier));
00533   }
00534 
00535   // Clear all the member data.
00536   void 
00537   clear() {
00538     _faces.clear();
00539   }
00540 
00541 };
00542 
00543 
00544 //
00545 // File IO
00546 //
00547 
00549 
00553 template <int N, typename T>
00554 inline
00555 std::ostream& 
00556 operator<<(std::ostream& out, const BRep<N,T>& br) {
00557   br.display(out);
00558   return out;
00559 }
00560 
00561 END_NAMESPACE_CPT
00562 
00563 #define __cpt_BRep3_ipp__
00564 #include "BRep3.ipp"
00565 #undef __cpt_BRep3_ipp__
00566 
00567 #define __cpt_BRep2_ipp__
00568 #include "BRep2.ipp"
00569 #undef __cpt_BRep2_ipp__
00570 
00571 #endif

Generated on Fri Aug 24 12:55:43 2007 for Closest Point Transform by  doxygen 1.4.7