Mod/Mesh/App/Core/Tools.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 #ifndef _PreComp_
00027 # include <algorithm>
00028 #endif
00029 
00030 #include "Tools.h"
00031 #include "Iterator.h"
00032 
00033 
00034 using namespace MeshCore;
00035 
00036 MeshSearchNeighbours::MeshSearchNeighbours (const MeshKernel &rclM, float fSampleDistance)
00037 : _rclMesh(rclM),
00038   _rclFAry(rclM.GetFacets()),
00039   _rclPAry(rclM.GetPoints()),
00040   _clPt2Fa(rclM),
00041   _fSampleDistance(fSampleDistance)
00042 {
00043     MeshAlgorithm(_rclMesh).ResetFacetFlag(MeshFacet::MARKED);
00044     MeshAlgorithm(_rclMesh).ResetPointFlag(MeshPoint::MARKED);
00045 }
00046 
00047 void MeshSearchNeighbours::Reinit (float fSampleDistance)
00048 {
00049     _fSampleDistance = fSampleDistance;
00050     MeshAlgorithm(_rclMesh).ResetFacetFlag(MeshFacet::MARKED);
00051     MeshAlgorithm(_rclMesh).ResetPointFlag(MeshPoint::MARKED);
00052 }
00053 
00054 unsigned long MeshSearchNeighbours::NeighboursFromFacet (unsigned long ulFacetIdx, float fDistance, unsigned long ulMinPoints, std::vector<Base::Vector3f> &raclResultPoints)
00055 {
00056     bool bAddPoints = false;
00057 
00058     _fMaxDistanceP2 = fDistance * fDistance;
00059     _clCenter       = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint();
00060 
00061     unsigned long ulVisited = 1;
00062     std::vector<MeshFacetArray::_TConstIterator>  aclTestedFacet;
00063 
00064     _aclResult.clear();
00065     _aclOuter.clear();
00066 
00067     // add start facet
00068     bool bFound = CheckDistToFacet(_rclFAry[ulFacetIdx]);
00069     _rclFAry[ulFacetIdx].SetFlag(MeshFacet::MARKED);
00070     aclTestedFacet.push_back(_rclFAry.begin() + ulFacetIdx);
00071 
00072     if ((bFound == false) && (_aclResult.size() < ulMinPoints)) {
00073         bAddPoints = true;
00074         bFound = ExpandRadius(ulMinPoints);
00075     }
00076 
00077     int nCtExpandRadius = 0; 
00078     // search neighbours, add not marked facets, test distance, add outer points
00079     MeshFacetArray::_TConstIterator f_beg = _rclFAry.begin();
00080     while ((bFound == true) && (nCtExpandRadius < 10)) {
00081         bFound = false;
00082 
00083         std::set<unsigned long> aclTmp;
00084         aclTmp.swap(_aclOuter);
00085         for (std::set<unsigned long>::iterator pI = aclTmp.begin(); pI != aclTmp.end(); pI++) {
00086             const std::set<unsigned long> &rclISet = _clPt2Fa[*pI]; 
00087             // search all facets hanging on this point
00088             for (std::set<unsigned long>::const_iterator pJ = rclISet.begin(); pJ != rclISet.end(); pJ++) {
00089                 const MeshFacet &rclF = f_beg[*pJ];
00090 
00091                 if (rclF.IsFlag(MeshFacet::MARKED) == false) {
00092                     bool bLF = CheckDistToFacet(rclF);
00093                     bFound = bFound || bLF;
00094                     rclF.SetFlag(MeshFacet::MARKED);
00095                     aclTestedFacet.push_back(f_beg+*pJ);
00096                 }
00097             }
00098             ulVisited += rclISet.size();
00099         }
00100 
00101         // too few points inside radius found -> expand radius
00102         if ((bFound == false) && (_aclResult.size() < ulMinPoints)) {
00103             nCtExpandRadius++;
00104             bAddPoints = true;
00105             bFound = ExpandRadius(ulMinPoints);
00106         }
00107         else
00108             nCtExpandRadius = 0;
00109     }
00110 
00111     // reset marked facets, points
00112     for (std::vector<MeshFacetArray::_TConstIterator>::iterator pF = aclTestedFacet.begin();
00113         pF != aclTestedFacet.end(); ++pF)
00114         (*pF)->ResetFlag(MeshFacet::MARKED);
00115     for (std::set<unsigned long>::iterator pR = _aclResult.begin(); pR != _aclResult.end(); ++pR)
00116         _rclPAry[*pR].ResetFlag(MeshPoint::MARKED);
00117 
00118 
00119     // copy points in result container
00120     raclResultPoints.resize(_aclResult.size());
00121     int i = 0;
00122     for (std::set<unsigned long>::iterator pI = _aclResult.begin(); pI != _aclResult.end(); pI++, i++)
00123         raclResultPoints[i] = _rclPAry[*pI];
00124 
00125     if (bAddPoints == true) {
00126         // sort points, remove points lying furthest from center
00127         std::sort(raclResultPoints.begin(), raclResultPoints.end(), CDistRad(_clCenter));
00128         raclResultPoints.erase(raclResultPoints.begin() + ulMinPoints, raclResultPoints.end());
00129     }
00130 
00131     return ulVisited;
00132 }
00133 
00134 void MeshSearchNeighbours::SampleAllFacets (void)
00135 {
00136     if (_aclSampledFacets.size() == _rclMesh.CountFacets())
00137         return; // already sampled, do nothing
00138 
00139     _aclSampledFacets.resize(_rclMesh.CountFacets());
00140     MeshFacetIterator clFIter(_rclMesh);
00141     int i = 0;
00142     for (clFIter.Init(); clFIter.More(); clFIter.Next(), i++) {
00143         std::vector<Base::Vector3f> clPoints;
00144         clFIter->SubSample(_fSampleDistance, clPoints);
00145         _aclSampledFacets[i].resize(clPoints.size());
00146         std::copy(clPoints.begin(), clPoints.end(), _aclSampledFacets[i].begin());
00147     }
00148 }
00149 
00150 unsigned long MeshSearchNeighbours::NeighboursFromSampledFacets (unsigned long ulFacetIdx, float fDistance, std::vector<Base::Vector3f> &raclResultPoints)
00151 {
00152     SampleAllFacets();
00153 
00154     _fMaxDistanceP2 = fDistance * fDistance;
00155     _clCenter       = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint();
00156 
00157     _akSphere.Center = Wm4::Vector3<float>(_clCenter.x, _clCenter.y, _clCenter.z);
00158     _akSphere.Radius = fDistance;
00159 
00160     unsigned long ulVisited = 1;
00161     std::vector<MeshFacetArray::_TConstIterator>  aclTestedFacet;
00162 
00163     _aclResult.clear();
00164     _aclOuter.clear();
00165     _aclPointsResult.clear();
00166 
00167     // add start facet
00168     bool bFound = AccumulateNeighbours(_rclFAry[ulFacetIdx], ulFacetIdx);
00169     _rclFAry[ulFacetIdx].SetFlag(MeshFacet::MARKED);
00170 
00171     // search neighbours, add not marked facets, test distance, add outer points
00172     MeshFacetArray::_TConstIterator f_beg = _rclFAry.begin();
00173     while (bFound == true) {
00174         bFound = false;
00175 
00176         std::set<unsigned long> aclTmp;
00177         aclTmp.swap(_aclOuter);
00178         for (std::set<unsigned long>::iterator pI = aclTmp.begin(); pI != aclTmp.end(); pI++) {
00179             const std::set<unsigned long> &rclISet = _clPt2Fa[*pI]; 
00180             // search all facets hanging on this point
00181             for (std::set<unsigned long>::const_iterator pJ = rclISet.begin(); pJ != rclISet.end(); pJ++) {
00182                 const MeshFacet &rclF = f_beg[*pJ];
00183 
00184                 if (rclF.IsFlag(MeshFacet::MARKED) == false) {
00185                     bool bLF = AccumulateNeighbours(rclF, *pJ);
00186                     bFound = bFound || bLF;
00187                     rclF.SetFlag(MeshFacet::MARKED);
00188                     aclTestedFacet.push_back(f_beg+*pJ);
00189                 }
00190             }
00191             ulVisited += rclISet.size();
00192         }
00193     }
00194 
00195     // reset marked facets
00196     for (std::vector<MeshFacetArray::_TConstIterator>::iterator pF = aclTestedFacet.begin(); pF != aclTestedFacet.end(); pF++)
00197         (*pF)->ResetFlag(MeshFacet::MARKED);
00198 
00199     // copy points in result container
00200     raclResultPoints.resize(_aclPointsResult.size());
00201     std::copy(_aclPointsResult.begin(), _aclPointsResult.end(), raclResultPoints.begin());
00202 
00203     // facet points
00204     for (std::set<unsigned long>::iterator pI = _aclResult.begin(); pI != _aclResult.end(); pI++) {
00205         if (InnerPoint(_rclPAry[*pI]) == true)
00206             raclResultPoints.push_back(_rclPAry[*pI]);
00207     }
00208 
00209     return ulVisited;
00210 }
00211 
00212 bool MeshSearchNeighbours::AccumulateNeighbours (const MeshFacet &rclF, unsigned long ulFIdx)
00213 {
00214     int  k = 0;
00215 
00216     for (int i = 0; i < 3; i++) {
00217         unsigned long ulPIdx = rclF._aulPoints[i];
00218         _aclOuter.insert(ulPIdx);
00219         _aclResult.insert(ulPIdx);
00220 
00221         if (Base::DistanceP2(_clCenter, _rclPAry[ulPIdx]) < _fMaxDistanceP2)
00222             k++;
00223     }
00224 
00225     bool bFound = false;
00226     if (k == 3) {  // add all sample points
00227         _aclPointsResult.insert(_aclPointsResult.end(), _aclSampledFacets[ulFIdx].begin(), _aclSampledFacets[ulFIdx].end());
00228         bFound = true;
00229     }
00230     else {  // add points inner radius
00231         bFound = TriangleCutsSphere(rclF);
00232 
00233         if (bFound == true) {
00234             std::vector<Base::Vector3f> &rclT = _aclSampledFacets[ulFIdx];
00235             std::vector<Base::Vector3f> clTmp;
00236             clTmp.reserve(rclT.size());
00237             for (std::vector<Base::Vector3f>::iterator pI = rclT.begin(); pI != rclT.end(); pI++) {
00238                 if (InnerPoint(*pI) == true)
00239                     clTmp.push_back(*pI);
00240             }
00241             _aclPointsResult.insert(_aclPointsResult.end(), clTmp.begin(), clTmp.end());
00242         }
00243     }
00244 
00245     return bFound;
00246 }
00247 
00248 bool MeshSearchNeighbours::ExpandRadius (unsigned long ulMinPoints)
00249 {
00250     // add facets from current level
00251     _aclResult.insert(_aclOuter.begin(), _aclOuter.end());
00252     for (std::set<unsigned long>::iterator pI = _aclOuter.begin(); pI != _aclOuter.end(); pI++)
00253         _rclPAry[*pI].SetFlag(MeshPoint::MARKED);
00254 
00255     if (_aclResult.size() < ulMinPoints) {
00256         _fMaxDistanceP2 *= float(ulMinPoints) / float(_aclResult.size());
00257         return true;
00258     }
00259     else
00260         return false;
00261 }
00262 
00263 unsigned long MeshSearchNeighbours::NeighboursFacetFromFacet (unsigned long ulFacetIdx, float fDistance, std::vector<Base::Vector3f> &raclResultPoints, std::vector<unsigned long> &raclResultFacets)
00264 {
00265     std::set<unsigned long> aulFacetSet;
00266 
00267     _fMaxDistanceP2 = fDistance * fDistance;
00268     _clCenter       = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint();
00269 
00270     unsigned long            ulVisited = 1;
00271     std::vector<MeshFacetArray::_TConstIterator>  aclTestedFacet;
00272 
00273     _aclResult.clear();
00274     _aclOuter.clear();
00275 
00276     // add start facet
00277     bool bFound = CheckDistToFacet(_rclFAry[ulFacetIdx]);
00278     _rclFAry[ulFacetIdx].SetFlag(MeshFacet::MARKED);
00279     aclTestedFacet.push_back(_rclFAry.begin() + ulFacetIdx);
00280 
00281     aulFacetSet.insert(ulFacetIdx);
00282 
00283     // search neighbours, add not marked facets, test distance, add outer points
00284     MeshFacetArray::_TConstIterator f_beg = _rclFAry.begin();
00285     while (bFound == true) {
00286         bFound = false;
00287 
00288         std::set<unsigned long> aclTmp;
00289         aclTmp.swap(_aclOuter);
00290         for (std::set<unsigned long>::iterator pI = aclTmp.begin(); pI != aclTmp.end(); pI++) {
00291             const std::set<unsigned long> &rclISet = _clPt2Fa[*pI]; 
00292             // search all facets hanging on this point
00293             for (std::set<unsigned long>::const_iterator pJ = rclISet.begin(); pJ != rclISet.end(); pJ++) {
00294                 const MeshFacet &rclF = f_beg[*pJ];
00295 
00296                 for (int i = 0; i < 3; i++) {
00297                     if (Base::DistanceP2(_clCenter, _rclPAry[rclF._aulPoints[i]]) < _fMaxDistanceP2) {
00298                         aulFacetSet.insert(*pJ);
00299                         break;
00300                     }
00301                 }
00302 
00303                 if (rclF.IsFlag(MeshFacet::MARKED) == false) {
00304                     bool bLF = CheckDistToFacet(rclF);
00305 
00306                     bFound = bFound || bLF;
00307                     rclF.SetFlag(MeshFacet::MARKED);
00308                     aclTestedFacet.push_back(f_beg+*pJ);
00309                 }
00310             }
00311             ulVisited += rclISet.size();
00312         }
00313     }
00314 
00315     // reset marked facets, points
00316     for (std::vector<MeshFacetArray::_TConstIterator>::iterator pF = aclTestedFacet.begin(); pF != aclTestedFacet.end(); pF++)
00317         (*pF)->ResetFlag(MeshFacet::MARKED);
00318     for (std::set<unsigned long>::iterator pR = _aclResult.begin(); pR != _aclResult.end(); pR++)
00319         _rclPAry[*pR].ResetFlag(MeshPoint::MARKED);
00320 
00321     // copy points in result container
00322     raclResultPoints.resize(_aclResult.size());
00323     int i = 0;
00324     for (std::set<unsigned long>::iterator pI = _aclResult.begin(); pI != _aclResult.end(); pI++, i++)
00325         raclResultPoints[i] = _rclPAry[*pI];
00326 
00327     // copy facets in result container
00328     raclResultFacets.insert(raclResultFacets.begin(), aulFacetSet.begin(), aulFacetSet.end());
00329 
00330     return ulVisited;
00331 }

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