Visitor.cpp

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 #include "PreCompiled.h"
00025 
00026 #include "MeshKernel.h"
00027 #include "Visitor.h"
00028 #include "Algorithm.h"
00029 #include "Approximation.h"
00030 
00031 using namespace MeshCore;
00032 
00033 
00034 unsigned long MeshKernel::VisitNeighbourFacets (MeshFacetVisitor &rclFVisitor, unsigned long ulStartFacet) const
00035 {
00036     unsigned long ulVisited = 0, j, ulLevel = 0;
00037     unsigned long ulCount = _aclFacetArray.size();
00038     std::vector<unsigned long> clCurrentLevel, clNextLevel;
00039     std::vector<unsigned long>::iterator  clCurrIter;  
00040     MeshFacetArray::_TConstIterator clCurrFacet, clNBFacet;
00041 
00042     // pick up start point
00043     clCurrentLevel.push_back(ulStartFacet);
00044     _aclFacetArray[ulStartFacet].SetFlag(MeshFacet::VISIT);
00045 
00046     // as long as free neighbours
00047     while (clCurrentLevel.size() > 0) {
00048         // visit all neighbours of the current level
00049         for (clCurrIter = clCurrentLevel.begin(); clCurrIter < clCurrentLevel.end(); clCurrIter++) {
00050             clCurrFacet = _aclFacetArray.begin() + *clCurrIter;
00051 
00052             // visit all neighbours of the current level if not yet done
00053             for (unsigned short i = 0; i < 3; i++) {
00054                 j = clCurrFacet->_aulNeighbours[i]; // index to neighbour facet
00055                 if (j == ULONG_MAX) 
00056                     continue;      // no neighbour facet
00057 
00058                 if (j >= ulCount) 
00059                     continue;      // error in data structure
00060 
00061                 clNBFacet = _aclFacetArray.begin() + j;
00062 
00063                 if (!rclFVisitor.AllowVisit(*clNBFacet, *clCurrFacet, j, ulLevel, i))
00064                     continue;
00065                 if (clNBFacet->IsFlag(MeshFacet::VISIT) == true)
00066                     continue; // neighbour facet already visited
00067                 else {
00068                     // visit and mark
00069                     ulVisited++;
00070                     clNextLevel.push_back(j);
00071                     clNBFacet->SetFlag(MeshFacet::VISIT);
00072                     if (rclFVisitor.Visit(*clNBFacet, *clCurrFacet, j, ulLevel) == false)
00073                         return ulVisited;
00074                 }
00075             }
00076         }
00077 
00078         clCurrentLevel = clNextLevel;
00079         clNextLevel.clear();
00080         ulLevel++;
00081     }
00082 
00083     return ulVisited;
00084 }
00085 
00086 unsigned long MeshKernel::VisitNeighbourFacetsOverCorners (MeshFacetVisitor &rclFVisitor, unsigned long ulStartFacet) const
00087 {
00088     unsigned long ulVisited = 0, ulLevel = 0;
00089     MeshRefPointToFacets clRPF(*this);
00090     const MeshFacetArray& raclFAry = _aclFacetArray;
00091     MeshFacetArray::_TConstIterator pFBegin = raclFAry.begin();
00092     std::vector<unsigned long> aclCurrentLevel, aclNextLevel;
00093 
00094     aclCurrentLevel.push_back(ulStartFacet);
00095     raclFAry[ulStartFacet].SetFlag(MeshFacet::VISIT);
00096 
00097     while (aclCurrentLevel.size() > 0) {
00098         // visit all neighbours of the current level
00099         for (std::vector<unsigned long>::iterator pCurrFacet = aclCurrentLevel.begin(); pCurrFacet < aclCurrentLevel.end(); pCurrFacet++) {
00100             for (int i = 0; i < 3; i++) {
00101                 const MeshFacet &rclFacet = raclFAry[*pCurrFacet];
00102                 const std::set<unsigned long>& raclNB = clRPF[rclFacet._aulPoints[i]];
00103                 for (std::set<unsigned long>::const_iterator pINb = raclNB.begin(); pINb != raclNB.end(); pINb++) {
00104                     if (pFBegin[*pINb].IsFlag(MeshFacet::VISIT) == false) {
00105                         // only visit if VISIT Flag not set
00106                         ulVisited++;
00107                         unsigned long ulFInd = *pINb;
00108                         aclNextLevel.push_back(ulFInd);
00109                         pFBegin[*pINb].SetFlag(MeshFacet::VISIT);
00110                         if (rclFVisitor.Visit(pFBegin[*pINb], raclFAry[*pCurrFacet], ulFInd, ulLevel) == false)
00111                             return ulVisited;
00112                     }
00113                 }
00114             }
00115         }
00116         aclCurrentLevel = aclNextLevel;
00117         aclNextLevel.clear();
00118         ulLevel++;
00119     }
00120 
00121     return ulVisited;
00122 }
00123 
00124 unsigned long MeshKernel::VisitNeighbourPoints (MeshPointVisitor &rclPVisitor, unsigned long ulStartPoint) const
00125 {
00126     unsigned long ulVisited = 0, ulLevel = 0;
00127     std::vector<unsigned long> aclCurrentLevel, aclNextLevel;
00128     std::vector<unsigned long>::iterator  clCurrIter;  
00129     MeshPointArray::_TConstIterator pPBegin = _aclPointArray.begin();
00130     MeshRefPointToPoints clNPs(*this);
00131 
00132     aclCurrentLevel.push_back(ulStartPoint);
00133     (pPBegin + ulStartPoint)->SetFlag(MeshPoint::VISIT);
00134 
00135     while (aclCurrentLevel.size() > 0) {
00136         // visit all neighbours of the current level
00137         for (clCurrIter = aclCurrentLevel.begin(); clCurrIter < aclCurrentLevel.end(); ++clCurrIter) {
00138             const std::set<unsigned long>& raclNB = clNPs[*clCurrIter];
00139             for (std::set<unsigned long>::const_iterator pINb = raclNB.begin(); pINb != raclNB.end(); ++pINb) {
00140                 if (pPBegin[*pINb].IsFlag(MeshPoint::VISIT) == false) {
00141                     // only visit if VISIT Flag not set
00142                     ulVisited++;
00143                     unsigned long ulPInd = *pINb;
00144                     aclNextLevel.push_back(ulPInd);
00145                     pPBegin[*pINb].SetFlag(MeshPoint::VISIT);
00146                     if (rclPVisitor.Visit(pPBegin[*pINb], *(pPBegin + (*clCurrIter)), ulPInd, ulLevel) == false)
00147                         return ulVisited;
00148                 }
00149             }
00150         }
00151         aclCurrentLevel = aclNextLevel;
00152         aclNextLevel.clear();
00153         ulLevel++;
00154     }
00155 
00156     return ulVisited;
00157 }
00158 
00159 // -------------------------------------------------------------------------
00160 
00161 MeshSearchNeighbourFacetsVisitor::MeshSearchNeighbourFacetsVisitor (const MeshKernel &rclMesh,
00162                                                                     float fRadius,
00163                                                                     unsigned long ulStartFacetIdx)
00164   : _rclMeshBase(rclMesh),
00165     _clCenter(rclMesh.GetFacet(ulStartFacetIdx).GetGravityPoint()),
00166     _fRadius(fRadius),
00167     _ulCurrentLevel(0),
00168     _bFacetsFoundInCurrentLevel(false)
00169 {
00170 }
00171 
00172 std::vector<unsigned long> MeshSearchNeighbourFacetsVisitor::GetAndReset (void)
00173 {
00174     MeshAlgorithm(_rclMeshBase).ResetFacetsFlag(_vecFacets, MeshFacet::VISIT);
00175     return _vecFacets;
00176 }
00177 
00178 // -------------------------------------------------------------------------
00179 
00180 MeshPlaneVisitor::MeshPlaneVisitor (const MeshKernel& mesh, unsigned long index,
00181                                     float deviation, std::vector<unsigned long> &indices)
00182   : mesh(mesh), indices(indices), max_deviation(deviation), fitter(new PlaneFit)
00183 {
00184     MeshGeomFacet triangle = mesh.GetFacet(index);
00185     basepoint = triangle.GetGravityPoint();
00186     normal = triangle.GetNormal();
00187     fitter->AddPoint(triangle._aclPoints[0]);
00188     fitter->AddPoint(triangle._aclPoints[1]);
00189     fitter->AddPoint(triangle._aclPoints[2]);
00190 }
00191 
00192 MeshPlaneVisitor::~MeshPlaneVisitor ()
00193 {
00194     delete fitter;
00195 }
00196 
00197 bool MeshPlaneVisitor::AllowVisit (const MeshFacet& face, const MeshFacet&, 
00198                                    unsigned long, unsigned long, unsigned short neighbourIndex)
00199 {
00200     if (!fitter->Done())
00201         fitter->Fit();
00202     MeshGeomFacet triangle = mesh.GetFacet(face);
00203     for (int i=0; i<3; i++) {
00204         if (fabs(fitter->GetDistanceToPlane(triangle._aclPoints[i])) > max_deviation)
00205             return false;
00206     }
00207     return true;
00208 }
00209 
00210 bool MeshPlaneVisitor::Visit (const MeshFacet & face, const MeshFacet &,
00211                               unsigned long ulFInd, unsigned long)
00212 {
00213     MeshGeomFacet triangle = mesh.GetFacet(face);
00214     indices.push_back(ulFInd);
00215     fitter->AddPoint(triangle.GetGravityPoint());
00216     return true;
00217 }

Generated on Wed Nov 23 19:01:02 2011 for FreeCAD by  doxygen 1.6.1