Elements.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2005 Imetric 3D GmbH                                    *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #ifndef MESH_ELEMENTS_H
00025 #define MESH_ELEMENTS_H
00026 
00027 #include <functional>
00028 #include <vector>
00029 #include <climits>
00030 #include <cstring>
00031 
00032 #include "Definitions.h"
00033 
00034 #include <Base/BoundBox.h>
00035 #include <Base/Vector3D.h>
00036 
00037 // Cannot use namespace Base in constructors of MeshPoint
00038 #ifdef _MSC_VER
00039 using Base::Vector3f;
00040 #endif
00041 
00042 namespace MeshCore {
00043 
00044 class MeshHelpEdge;
00045 class MeshPoint;
00046 
00052 class MeshExport MeshHelpEdge
00053 {
00054 public:
00055   inline bool operator == (const MeshHelpEdge &rclEdge) const;
00056   unsigned long   _ulIndex[2];  // point indices
00057 };
00058 
00063 class MeshExport MeshIndexEdge
00064 {
00065 public:
00066   unsigned long  _ulFacetIndex;  // Facet index
00067   unsigned short _ausCorner[2];  // corner point indices of the facet
00068 };
00069 
00071 typedef std::pair<unsigned long, unsigned long> MeshEdge;
00072 
00086 class MeshExport MeshPoint: public Base::Vector3f
00087 {
00088 public:
00089   enum TFlagType {INVALID=1, VISIT=2, SEGMENT=4, MARKED=8, SELECTED=16, REV=32, TMP0=64, TMP1=128};
00090 
00093   MeshPoint (void) : _ucFlag(0), _ulProp(0) { }
00094   inline MeshPoint (const Base::Vector3f &rclPt);
00095   inline MeshPoint (const MeshPoint &rclPt);
00096   ~MeshPoint (void) { }
00098 
00099 public:
00104   void SetFlag (TFlagType tF) const
00105   { const_cast<MeshPoint*>(this)->_ucFlag |= (unsigned char)(tF); }
00106   void ResetFlag (TFlagType tF) const
00107   { const_cast<MeshPoint*>(this)->_ucFlag &= ~(unsigned char)(tF); }
00108   bool IsFlag (TFlagType tF) const
00109   { return (_ucFlag & (unsigned char)(tF)) == (unsigned char)(tF);  }
00110   void ResetInvalid (void) const
00111   { ResetFlag(INVALID); }
00112   void  SetInvalid (void) const
00113   { SetFlag(INVALID); }
00114   bool IsValid (void) const
00115   { return !IsFlag(INVALID); }
00116   void SetProperty(unsigned long uP) const
00117   { const_cast<MeshPoint*>(this)->_ulProp = uP; }
00119 
00120   // Assignment
00121   inline MeshPoint& operator = (const MeshPoint &rclPt);
00122 
00123   // compare operator
00124   inline bool operator == (const MeshPoint &rclPt) const;
00125   inline bool operator == (const Base::Vector3f &rclV) const;
00126   inline bool operator < (const MeshPoint &rclPt) const;
00127 
00128 public:
00129   unsigned char _ucFlag; 
00130   unsigned long _ulProp; 
00131 };
00132 
00137 class MeshExport MeshGeomEdge
00138 {
00139 public:
00140   MeshGeomEdge (void) : _bBorder(false) {}
00141 
00143   bool ContainedByOrIntersectBoundingBox (const Base::BoundBox3f &rclBB ) const;
00145   Base::BoundBox3f GetBoundBox () const;
00147   bool IntersectBoundingBox (const Base::BoundBox3f &rclBB) const;
00148 
00149 public:
00150   Base::Vector3f _aclPoints[2];  
00151   bool     _bBorder;       
00152 };
00153 
00171 class MeshFacet
00172 {
00173 public:
00174   enum TFlagType {INVALID=1, VISIT=2, SEGMENT=4, MARKED=8, SELECTED=16, REV=32, TMP0=64, TMP1=128};
00175 
00176 public:
00179   inline MeshFacet (void);
00180   inline MeshFacet(const MeshFacet &rclF);
00181   inline MeshFacet(unsigned long p1,unsigned long p2,unsigned long p3,unsigned long n1=ULONG_MAX,unsigned long n2=ULONG_MAX,unsigned long n3=ULONG_MAX);
00182   ~MeshFacet (void) { }
00184 
00189   void SetFlag (TFlagType tF) const
00190   { const_cast<MeshFacet*>(this)->_ucFlag |= (unsigned char)(tF); }
00191   void ResetFlag (TFlagType tF) const
00192   { const_cast<MeshFacet*>(this)->_ucFlag &= ~(unsigned char)(tF); }
00193   bool IsFlag (TFlagType tF) const
00194   { return (_ucFlag & (unsigned char)(tF)) == (unsigned char)(tF); }
00195   void ResetInvalid (void) const
00196   { ResetFlag(INVALID); }
00197   void SetProperty(unsigned long uP) const
00198   { const_cast<MeshFacet*>(this)->_ulProp = uP; }
00204   void  SetInvalid (void) const
00205   { SetFlag(INVALID); }
00206   bool IsValid (void) const
00207   { return !IsFlag(INVALID); }
00209 
00210   // Assignment
00211   inline MeshFacet& operator = (const MeshFacet &rclF);
00212   inline void SetVertices(unsigned long,unsigned long,unsigned long);
00213   inline void SetNeighbours(unsigned long,unsigned long,unsigned long);
00214 
00218   inline void GetEdge (unsigned short usSide, MeshHelpEdge &rclEdge) const;
00222   inline std::pair<unsigned long, unsigned long> GetEdge (unsigned short usSide) const;
00227   inline unsigned short Side (unsigned long ulNIndex) const;
00232   inline unsigned short Side (unsigned long ulP0, unsigned long P1) const;
00237   inline unsigned short Side (const MeshFacet& rcFace) const;
00242   inline bool IsEqual (const MeshFacet& rcFace) const;
00248   inline void Transpose (unsigned long ulOrig, unsigned long ulNew);
00252   inline void Decrement (unsigned long ulIndex);
00258   inline void ReplaceNeighbour (unsigned long ulOrig, unsigned long ulNew);
00262   bool HasNeighbour (unsigned short usSide) const
00263   { return (_aulNeighbours[usSide] != ULONG_MAX); }
00265   inline unsigned short CountOpenEdges() const;
00267   inline bool HasOpenEdge() const;
00271   inline bool HasSameOrientation(const MeshFacet&) const;
00273   inline bool IsDegenerated() const;
00275   void FlipNormal (void)
00276   {
00277     std::swap(_aulPoints[1], _aulPoints[2]);
00278     std::swap(_aulNeighbours[0], _aulNeighbours[2]);
00279   }
00280 
00281 public:
00282   unsigned char _ucFlag; 
00283   unsigned long _ulProp; 
00284   unsigned long _aulPoints[3];     
00285   unsigned long _aulNeighbours[3]; 
00286 };
00287 
00292 class MeshExport MeshGeomFacet 
00293 {
00294 public:
00297 
00298   MeshGeomFacet (void); 
00300   MeshGeomFacet (const Base::Vector3f &v1,const Base::Vector3f &v2,const Base::Vector3f &v3);
00302   ~MeshGeomFacet (void) { }
00304 
00305 public:
00311   bool IsPointOf (const Base::Vector3f &rclPoint, float fDistance) const;
00317   bool IsPointOf (const Base::Vector3f &rclPoint) const;
00322   bool IsPointOfFace (const Base::Vector3f& rclP, float fDistance) const;
00332   bool Weights(const Base::Vector3f& rclP, float& w0, float& w1, float& w2) const;
00336   inline float DistancePlaneToPoint (const Base::Vector3f &rclPoint) const;
00340   void ProjectPointToPlane (Base::Vector3f &rclPoint) const;
00344   void ProjectFacetToPlane (MeshGeomFacet &rclFacet) const;
00349   bool IsDegenerated() const;
00356   bool IsDeformed() const;
00360   void Enlarge (float fDist);
00364   inline void CalcNormal (void);
00368   inline void ArrangeNormal (const Base::Vector3f &rclN);
00372   inline void AdjustCirculationDirection (void);
00374   void NormalInvalid (void) { _bNormalCalculated = false; }
00376   bool IsFlag (MeshFacet::TFlagType tF) const
00377   { return (_ucFlag & (unsigned char)(tF)) == (unsigned char)(tF); }
00379   void SetFlag (MeshFacet::TFlagType tF)
00380   { _ucFlag |= (unsigned char)(tF); }
00382   void ResetFlag (MeshFacet::TFlagType tF)
00383   { _ucFlag &= ~(unsigned char)(tF); }
00385   inline Base::Vector3f GetGravityPoint (void) const;
00387   inline Base::Vector3f GetNormal (void) const;
00389   inline void SetNormal (const Base::Vector3f &rclNormal);
00391   inline Base::BoundBox3f GetBoundBox (void) const;
00393   inline float Perimeter() const;
00395   inline float Area () const;
00397   float MaximumAngle () const;
00399   inline bool ContainedByOrIntersectBoundingBox (const Base::BoundBox3f &rcBB) const;
00401   bool IntersectBoundingBox ( const Base::BoundBox3f &rclBB ) const;
00404   bool IntersectWithFacet(const MeshGeomFacet &rclFacet) const;
00410   int IntersectWithFacet (const MeshGeomFacet& facet, Base::Vector3f& rclPt0, Base::Vector3f& rclPt1) const;
00414   float DistanceToLineSegment (const Base::Vector3f &rcP1, const Base::Vector3f &rcP2) const;
00416   float DistanceToPoint (const Base::Vector3f &rcPt) const
00417   { Base::Vector3f res; return DistanceToPoint(rcPt, res); }
00421   float DistanceToPoint  ( const Base::Vector3f &rclPt, Base::Vector3f& rclNt ) const;
00425   bool IntersectWithLine (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes) const;
00431   bool Foraminate (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes, float fMaxAngle = F_PI) const;
00435   bool IntersectWithPlane (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal, Base::Vector3f &rclP1, Base::Vector3f &rclP2) const;
00440   inline bool IntersectWithPlane (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal) const;
00444   bool IntersectPlaneWithLine (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal, Base::Vector3f &rclRes ) const;
00448   float VolumeOfPrism (const MeshGeomFacet& rclF) const;
00450   void SubSample (float fStep, std::vector<Base::Vector3f> &rclPoints) const;
00452   float CenterOfInscribedCircle(Base::Vector3f& rclCenter) const;
00454   float CenterOfCircumCircle(Base::Vector3f& rclCenter) const;
00456   unsigned short NearestEdgeToPoint(const Base::Vector3f& rclPt) const;
00458   void NearestEdgeToPoint(const Base::Vector3f& rclPt, float& fDistance, unsigned short& side) const;
00462   bool IsPointOfSphere(const Base::Vector3f& rP) const;
00466   bool IsPointOfSphere(const MeshGeomFacet& rFacet) const;
00467 
00468 protected:
00469   Base::Vector3f  _clNormal; 
00470   bool  _bNormalCalculated; 
00472 public:
00473   Base::Vector3f  _aclPoints[3]; 
00474   unsigned char _ucFlag; 
00475   unsigned long _ulProp; 
00476 };
00477 
00478 typedef  std::vector<MeshPoint>  TMeshPointArray;
00482 class MeshExport MeshPointArray: public TMeshPointArray
00483 {
00484 public:
00485   // Iterator interface
00486   typedef std::vector<MeshPoint>::iterator        _TIterator;
00487   typedef std::vector<MeshPoint>::const_iterator  _TConstIterator;
00488 
00491   // constructor
00492   MeshPointArray (void) { }
00493   // constructor
00494   MeshPointArray (unsigned long ulSize) : TMeshPointArray(ulSize) { }
00495   // Destructor
00496   ~MeshPointArray (void) { }
00498 
00503 
00504   void SetFlag (MeshPoint::TFlagType tF) const;
00506   void ResetFlag (MeshPoint::TFlagType tF) const;
00508   void ResetInvalid (void) const;
00510   void SetProperty (unsigned long ulVal) const;
00512 
00513   // Assignment
00514   MeshPointArray& operator = (const MeshPointArray &rclPAry);
00519   unsigned long Get (const MeshPoint &rclPoint);
00525   unsigned long GetOrAddIndex (const MeshPoint &rclPoint);
00526 };
00527 
00528 typedef std::vector<MeshFacet>  TMeshFacetArray;
00529 
00533 class MeshExport MeshFacetArray: public TMeshFacetArray
00534 {
00535 public:
00536     // Iterator interface
00537     typedef std::vector<MeshFacet>::iterator        _TIterator;
00538     typedef std::vector<MeshFacet>::const_iterator  _TConstIterator;
00539 
00542 
00543     MeshFacetArray (void) { }
00545     MeshFacetArray (unsigned long ulSize) : TMeshFacetArray(ulSize) { }
00547     ~MeshFacetArray (void) { }
00549 
00555 
00556     void SetFlag (MeshFacet::TFlagType tF) const;
00558     void ResetFlag (MeshFacet::TFlagType tF) const;
00560     void ResetInvalid (void) const;
00562     void SetProperty (unsigned long ulVal) const;
00564 
00565     // Assignment
00566     MeshFacetArray& operator = (const MeshFacetArray &rclFAry);
00567 
00572     void Erase (_TIterator pIter);
00576     void TransposeIndices (unsigned long ulOrig, unsigned long ulNew);
00580     void DecrementIndices (unsigned long ulIndex);
00581 };
00582 
00583 inline MeshPoint::MeshPoint (const Base::Vector3f &rclPt)
00584 #ifdef _MSC_VER
00585 : Vector3f(rclPt),
00586 #else
00587 : Base::Vector3f(rclPt),
00588 #endif
00589   _ucFlag(0),
00590   _ulProp(0)
00591 {
00592 }
00593 
00594 inline MeshPoint::MeshPoint (const MeshPoint &rclPt)
00595 #ifdef _MSC_VER
00596 : Vector3f(rclPt),
00597 #else
00598 : Base::Vector3f(rclPt),
00599 #endif
00600   _ucFlag(rclPt._ucFlag),
00601   _ulProp(rclPt._ulProp)
00602 {
00603 }
00604 
00605 inline MeshPoint& MeshPoint::operator = (const MeshPoint &rclPt)
00606 {
00607 #ifdef _MSC_VER
00608     Vector3f::operator=(rclPt);
00609 #else
00610     Base::Vector3f::operator=(rclPt);
00611 #endif
00612     _ucFlag = rclPt._ucFlag;
00613     _ulProp = rclPt._ulProp;
00614     return *this;
00615 }
00616 
00617 inline bool MeshPoint::operator == (const MeshPoint &rclPt) const
00618 {
00619     return Base::DistanceP2(*this, rclPt) < MeshDefinitions::_fMinPointDistanceP2;
00620 }
00621 
00622 inline bool MeshPoint::operator == (const Base::Vector3f &rclV) const
00623 {
00624     return Base::DistanceP2(*this, rclV) < MeshDefinitions::_fMinPointDistanceP2;
00625 }
00626 
00627 inline bool MeshPoint::operator < (const MeshPoint &rclPt) const
00628 {
00629     if (fabs ( this->x - rclPt.x ) >= MeshDefinitions::_fMinPointDistanceD1)
00630         return this->x < rclPt.x;
00631     if (fabs ( this->y - rclPt.y ) >= MeshDefinitions::_fMinPointDistanceD1)
00632         return this->y < rclPt.y;
00633     if (fabs ( this->z - rclPt.z ) >= MeshDefinitions::_fMinPointDistanceD1)
00634         return this->z < rclPt.z;
00635     return false; // points are considered to be equal
00636 }
00637 
00638 inline float MeshGeomFacet::DistancePlaneToPoint (const Base::Vector3f &rclPoint) const
00639 {
00640     // internal normal is forced to have length equal to 1
00641     return float(fabs(rclPoint.DistanceToPlane(_aclPoints[0], GetNormal())));
00642 }
00643 
00644 inline void MeshGeomFacet::CalcNormal (void)
00645 {
00646     _clNormal = (_aclPoints[1] - _aclPoints[0]) % (_aclPoints[2] - _aclPoints[0]);
00647     _clNormal.Normalize();
00648     _bNormalCalculated = true;
00649 }
00650 
00651 inline Base::Vector3f MeshGeomFacet::GetNormal (void) const
00652 {
00653     if (_bNormalCalculated == false)
00654         const_cast<MeshGeomFacet*>(this)->CalcNormal();
00655     return _clNormal;
00656 }
00657 
00658 inline void MeshGeomFacet::SetNormal (const Base::Vector3f &rclNormal)
00659 {
00660     if (rclNormal.Sqr() == 0.0f)
00661         return;
00662     _clNormal = rclNormal;
00663     _clNormal.Normalize();
00664     _bNormalCalculated = true;
00665 }
00666 
00667 inline void MeshGeomFacet::ArrangeNormal (const Base::Vector3f &rclN)
00668 {
00669     // force internal normal to be computed if not done yet
00670     if ((rclN * GetNormal()) < 0.0f)
00671         _clNormal = -_clNormal;
00672 }
00673 
00674 inline Base::Vector3f MeshGeomFacet::GetGravityPoint (void) const
00675 {
00676     return (1.0f / 3.0f) * (_aclPoints[0] + _aclPoints[1] + _aclPoints[2]);
00677 }
00678 
00679 inline void MeshGeomFacet::AdjustCirculationDirection (void)
00680 {
00681     Base::Vector3f clN = (_aclPoints[1] - _aclPoints[0]) % (_aclPoints[2] - _aclPoints[0]);
00682     if ((clN * _clNormal) < 0.0f)
00683         std::swap(_aclPoints[1], _aclPoints[2]);
00684 }
00685 
00686 inline Base::BoundBox3f MeshGeomFacet::GetBoundBox (void) const
00687 {
00688     return Base::BoundBox3f(_aclPoints, 3);
00689 }
00690 
00691 inline float MeshGeomFacet::Perimeter() const
00692 {
00693     float perimeter=0.0f;
00694     perimeter += Base::Distance(_aclPoints[0], _aclPoints[1]);
00695     perimeter += Base::Distance(_aclPoints[1], _aclPoints[2]);
00696     perimeter += Base::Distance(_aclPoints[2], _aclPoints[0]);
00697     return perimeter;
00698 }
00699 
00700 inline float MeshGeomFacet::Area () const
00701 {
00702     return ((_aclPoints[1] - _aclPoints[0]) % 
00703             (_aclPoints[2] - _aclPoints[0])).Length() / 2.0f;
00704 }
00705 
00706 inline bool MeshGeomFacet::ContainedByOrIntersectBoundingBox ( const Base::BoundBox3f &rclBB ) const
00707 {
00708      // Test, ob alle Eckpunkte des Facets sich auf einer der 6 Seiten der BB befinden
00709     if ((GetBoundBox() && rclBB) == false)
00710         return false;
00711 
00712     // Test, ob Facet-BB komplett in BB liegt
00713     if (rclBB.IsInBox(GetBoundBox()))
00714         return true;
00715 
00716     // Test, ob einer der Eckpunkte in BB liegt
00717     for (int i=0;i<3;i++) {
00718         if (rclBB.IsInBox(_aclPoints[i]))
00719             return true;
00720     }
00721 
00722     // "echter" Test auf Schnitt
00723     if (IntersectBoundingBox(rclBB))
00724         return true;
00725 
00726     return false;
00727 }
00728 
00729 inline bool MeshGeomFacet::IntersectWithPlane (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal) const
00730 {
00731     bool bD0 = (_aclPoints[0].DistanceToPlane(rclBase, rclNormal) > 0.0f); 
00732     return !((bD0 == (_aclPoints[1].DistanceToPlane(rclBase, rclNormal) > 0.0f)) &&
00733              (bD0 == (_aclPoints[2].DistanceToPlane(rclBase, rclNormal) > 0.0f)));
00734 }
00735 
00736 inline MeshFacet::MeshFacet (void)
00737 : _ucFlag(0),
00738   _ulProp(0)
00739 {
00740     memset(_aulNeighbours, 0xff, sizeof(ULONG_MAX) * 3);
00741     memset(_aulPoints, 0xff, sizeof(ULONG_MAX) * 3);
00742 }
00743 
00744 inline MeshFacet::MeshFacet(const MeshFacet &rclF)
00745 : _ucFlag(rclF._ucFlag),
00746   _ulProp(rclF._ulProp)
00747 {
00748     _aulPoints[0] = rclF._aulPoints[0];
00749     _aulPoints[1] = rclF._aulPoints[1];
00750     _aulPoints[2] = rclF._aulPoints[2];
00751 
00752     _aulNeighbours[0] = rclF._aulNeighbours[0];
00753     _aulNeighbours[1] = rclF._aulNeighbours[1];
00754     _aulNeighbours[2] = rclF._aulNeighbours[2];
00755 }
00756 
00757 inline MeshFacet::MeshFacet(unsigned long p1,unsigned long p2,unsigned long p3,
00758                             unsigned long n1,unsigned long n2,unsigned long n3)
00759 : _ucFlag(0),
00760   _ulProp(0)
00761 {
00762     _aulPoints[0] = p1;
00763     _aulPoints[1] = p2;
00764     _aulPoints[2] = p3;
00765 
00766     _aulNeighbours[0] = n1;
00767     _aulNeighbours[1] = n2;
00768     _aulNeighbours[2] = n3;
00769 }
00770 
00771 inline MeshFacet& MeshFacet::operator = (const MeshFacet &rclF)
00772 {
00773     _ucFlag          = rclF._ucFlag;
00774     _ulProp          = rclF._ulProp;
00775 
00776     _aulPoints[0]    = rclF._aulPoints[0];
00777     _aulPoints[1]    = rclF._aulPoints[1];
00778     _aulPoints[2]    = rclF._aulPoints[2];
00779 
00780     _aulNeighbours[0] = rclF._aulNeighbours[0];
00781     _aulNeighbours[1] = rclF._aulNeighbours[1];
00782     _aulNeighbours[2] = rclF._aulNeighbours[2];
00783 
00784     return *this;
00785 }
00786 
00787 void MeshFacet::SetVertices(unsigned long p1,unsigned long p2,unsigned long p3)
00788 {
00789     _aulPoints[0] = p1;
00790     _aulPoints[1] = p2;
00791     _aulPoints[2] = p3;
00792 }
00793 
00794 void MeshFacet::SetNeighbours(unsigned long n1,unsigned long n2,unsigned long n3)
00795 {
00796     _aulNeighbours[0] = n1;
00797     _aulNeighbours[1] = n2;
00798     _aulNeighbours[2] = n3;
00799 }
00800 
00801 inline void MeshFacet::GetEdge (unsigned short usSide, MeshHelpEdge &rclEdge) const
00802 {
00803     rclEdge._ulIndex[0] = _aulPoints[usSide];
00804     rclEdge._ulIndex[1] = _aulPoints[(usSide+1) % 3];
00805 }
00806 
00807 inline std::pair<unsigned long, unsigned long> MeshFacet::GetEdge (unsigned short usSide) const
00808 {
00809     return std::pair<unsigned long, unsigned long>(_aulPoints[usSide], _aulPoints[(usSide+1)%3]);
00810 }
00811 
00812 inline void MeshFacet::Transpose (unsigned long ulOrig, unsigned long ulNew)
00813 {
00814     if (_aulPoints[0] == ulOrig)
00815         _aulPoints[0] = ulNew;
00816     else if (_aulPoints[1] == ulOrig)
00817         _aulPoints[1] = ulNew;
00818     else if (_aulPoints[2] == ulOrig)
00819         _aulPoints[2] = ulNew;
00820 }
00821 
00822 inline void MeshFacet::Decrement (unsigned long ulIndex)
00823 {
00824     if (_aulPoints[0] > ulIndex) _aulPoints[0]--;
00825     if (_aulPoints[1] > ulIndex) _aulPoints[1]--;
00826     if (_aulPoints[2] > ulIndex) _aulPoints[2]--;
00827 }
00828 
00829 inline void MeshFacet::ReplaceNeighbour (unsigned long ulOrig, unsigned long ulNew)
00830 {
00831     if (_aulNeighbours[0] == ulOrig)
00832         _aulNeighbours[0] = ulNew;
00833     else if (_aulNeighbours[1] == ulOrig)
00834         _aulNeighbours[1] = ulNew;
00835     else if (_aulNeighbours[2] == ulOrig)
00836         _aulNeighbours[2] = ulNew;
00837 }
00838 
00839 inline unsigned short MeshFacet::CountOpenEdges() const
00840 {
00841     unsigned short ct=0;
00842     for (unsigned short i=0; i<3; i++)
00843     { if ( !HasNeighbour(i) ) ct++; }
00844     return ct;
00845 }
00846 
00847 inline bool MeshFacet::HasOpenEdge() const
00848 {
00849     return (CountOpenEdges() != 0);
00850 }
00851 
00852 inline bool MeshFacet::HasSameOrientation(const MeshFacet& f) const
00853 {
00854     for (int i = 0; i < 3; i++) {
00855         for (int j = 0; j < 3; j++) {
00856             if (_aulPoints[i] == f._aulPoints[j]) {
00857                 if ((_aulPoints[(i+1)%3] == f._aulPoints[(j+1)%3]) ||
00858                     (_aulPoints[(i+2)%3] == f._aulPoints[(j+2)%3])) {
00859                     return false;
00860                 }
00861             }
00862         }
00863     }
00864 
00865     return true;
00866 }
00867 
00868 inline bool MeshFacet::IsDegenerated() const
00869 {
00870     if (_aulPoints[0] == _aulPoints[1])
00871         return true;
00872     if (_aulPoints[1] == _aulPoints[2])
00873         return true;
00874     if (_aulPoints[2] == _aulPoints[0])
00875         return true;
00876     return false;
00877 }
00878 
00879 inline unsigned short MeshFacet::Side (unsigned long ulNIndex) const
00880 {
00881     if (_aulNeighbours[0] == ulNIndex)
00882         return 0;
00883     else if (_aulNeighbours[1] == ulNIndex)
00884         return 1;
00885     else if (_aulNeighbours[2] == ulNIndex)
00886         return 2;
00887     else
00888         return USHRT_MAX;
00889 }
00890 
00891 inline unsigned short MeshFacet::Side (unsigned long ulP0, unsigned long ulP1) const
00892 {
00893     if (_aulPoints[0] == ulP0) {
00894         if (_aulPoints[1] == ulP1)
00895             return 0;  // Kante 0-1 ==> 0
00896         else if (_aulPoints[2] == ulP1)
00897             return 2;  // Kante 0-2 ==> 2
00898     }
00899     else if (_aulPoints[1] == ulP0) {
00900         if (_aulPoints[0] == ulP1)
00901             return 0; // Kante 1-0 ==> 0
00902         else if (_aulPoints[2] == ulP1)
00903             return 1; // Kante 1-2 ==> 1
00904     }
00905     else if (_aulPoints[2] == ulP0) {
00906         if (_aulPoints[0] == ulP1)
00907             return 2; // Kante 2-0 ==> 2
00908         else if (_aulPoints[1] == ulP1)
00909             return 1; // Kante 2-1 ==> 1
00910     }
00911 
00912     return USHRT_MAX;
00913 }
00914 
00915 inline unsigned short MeshFacet::Side (const MeshFacet& rFace) const
00916 {
00917     unsigned short side;
00918     for (int i=0; i<3;i++){
00919         side = Side(rFace._aulPoints[i], rFace._aulPoints[(i+1)%3]);
00920         if (side != USHRT_MAX)
00921             return side;
00922     }
00923 
00924     return USHRT_MAX;
00925 }
00926 
00927 inline bool MeshFacet::IsEqual (const MeshFacet& rcFace) const
00928 {
00929     for (int i=0; i<3; i++) {
00930         if (this->_aulPoints[0] == rcFace._aulPoints[i]) {
00931             if (this->_aulPoints[1] == rcFace._aulPoints[(i+1)%3] &&
00932                 this->_aulPoints[2] == rcFace._aulPoints[(i+2)%3])
00933                 return true;
00934             else if (this->_aulPoints[1] == rcFace._aulPoints[(i+2)%3] &&
00935                      this->_aulPoints[2] == rcFace._aulPoints[(i+1)%3])
00936                 return true;
00937         }
00938     }
00939 
00940     return false;
00941 }
00942 
00946 template <class TCLASS>
00947 class MeshIsFlag : public std::binary_function<TCLASS, typename TCLASS::TFlagType, bool>
00948 {
00949 public:
00950     bool operator () (const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const
00951     { return rclElem.IsFlag(tFlag); }
00952 };
00953 
00957 template <class TCLASS>
00958 class MeshIsNotFlag : public std::binary_function<TCLASS, typename TCLASS::TFlagType, bool>
00959 {
00960 public:
00961     bool operator () (const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const
00962     { return !rclElem.IsFlag(tFlag); }
00963 };
00964 
00968 template <class TCLASS>
00969 class MeshSetFlag : public std::binary_function<TCLASS, typename TCLASS::TFlagType, bool>
00970 {
00971 public:
00972     bool operator () (const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const
00973     { rclElem.SetFlag(tFlag); return true; }
00974 };
00975 
00979 template <class TCLASS>
00980 class MeshResetFlag : public std::binary_function<TCLASS, typename TCLASS::TFlagType, bool>
00981 {
00982 public:
00983     bool operator () (const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const
00984     { rclElem.ResetFlag(tFlag); return true; }
00985 };
00986 
00987 } // namespace MeshCore
00988 
00989 #endif // MESH_ELEMENTS_H 

Generated on Wed Nov 23 19:00:10 2011 for FreeCAD by  doxygen 1.6.1