Builder.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <algorithm>
00028 #endif
00029
00030 #include <Base/Sequencer.h>
00031 #include <Base/Exception.h>
00032
00033 #include "Builder.h"
00034 #include "MeshKernel.h"
00035
00036 using namespace MeshCore;
00037
00038
00039 MeshBuilder::MeshBuilder (MeshKernel& kernel) : _meshKernel(kernel), _seq(0)
00040 {
00041 _fSaveTolerance = MeshDefinitions::_fMinPointDistanceD1;
00042 }
00043
00044 MeshBuilder::~MeshBuilder (void)
00045 {
00046 MeshDefinitions::_fMinPointDistanceD1 = _fSaveTolerance;
00047 delete this->_seq;
00048 }
00049
00050 void MeshBuilder::SetTolerance(float fTol)
00051 {
00052 MeshDefinitions::_fMinPointDistanceD1 = fTol;
00053 }
00054
00055 void MeshBuilder::Initialize (unsigned long ctFacets, bool deletion)
00056 {
00057 if (deletion)
00058 {
00059
00060 _meshKernel.Clear();
00061
00062
00063
00064
00065
00066
00067 _meshKernel._aclFacetArray.reserve(ctFacets);
00068
00069
00070
00071
00072 unsigned long ctPoints = ctFacets / 2;
00073 _pointsIterator.reserve((unsigned long)(float(ctPoints)*1.10f));
00074 _ptIdx = 0;
00075 }
00076 else
00077 {
00078 for (MeshPointArray::_TConstIterator it1 = _meshKernel._aclPointArray.begin(); it1 != _meshKernel._aclPointArray.end(); it1++)
00079 {
00080 MeshPointIterator pit = _points.insert(*it1);
00081 _pointsIterator.push_back(pit);
00082 }
00083 _ptIdx = _points.size();
00084
00085
00086
00087 _meshKernel._aclPointArray.clear();
00088
00089 unsigned long newCtFacets = _meshKernel._aclFacetArray.size()+ctFacets;
00090 _meshKernel._aclFacetArray.reserve(newCtFacets);
00091 unsigned long ctPoints = newCtFacets / 2;
00092 _pointsIterator.reserve((unsigned long)(float(ctPoints)*1.10f));
00093 }
00094
00095 this->_seq = new Base::SequencerLauncher("create mesh structure...", ctFacets * 2);
00096 }
00097
00098 void MeshBuilder::AddFacet (const MeshGeomFacet& facet, bool takeFlag, bool takeProperty)
00099 {
00100 unsigned char flag = 0;
00101 unsigned long prop = 0;
00102 if (takeFlag)
00103 flag = facet._ucFlag;
00104 if (takeProperty)
00105 prop = facet._ulProp;
00106
00107 AddFacet(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], facet.GetNormal(), flag, prop);
00108 }
00109
00110 void MeshBuilder::AddFacet (const Base::Vector3f& pt1, const Base::Vector3f& pt2, const Base::Vector3f& pt3, const Base::Vector3f& normal, unsigned char flag, unsigned long prop)
00111 {
00112 Base::Vector3f facetPoints[4] = { pt1, pt2, pt3, normal };
00113 AddFacet(facetPoints, flag, prop);
00114 }
00115
00116 void MeshBuilder::AddFacet (Base::Vector3f* facetPoints, unsigned char flag, unsigned long prop)
00117 {
00118 this->_seq->next(true);
00119
00120
00121 if ((((facetPoints[1] - facetPoints[0]) % (facetPoints[2] - facetPoints[0])) * facetPoints[3]) < 0.0f)
00122 {
00123 std::swap(facetPoints[1], facetPoints[2]);
00124 }
00125
00126 MeshFacet mf;
00127 mf._ucFlag = flag;
00128 mf._ulProp = prop;
00129
00130 int i = 0;
00131 for (i = 0; i < 3; i++)
00132 {
00133 MeshPoint pt(facetPoints[i]);
00134 std::set<MeshPoint>::iterator p = _points.find(pt);
00135 if (p == _points.end())
00136 {
00137 mf._aulPoints[i] = _ptIdx;
00138 pt._ulProp = _ptIdx++;
00139
00140 MeshPointIterator it = _points.insert(pt);
00141 _pointsIterator.push_back(it);
00142 }
00143 else
00144 mf._aulPoints[i] = p->_ulProp;
00145 }
00146
00147
00148 if ((mf._aulPoints[0] == mf._aulPoints[1]) || (mf._aulPoints[0] == mf._aulPoints[2]) || (mf._aulPoints[1] == mf._aulPoints[2]))
00149 return;
00150
00151 _meshKernel._aclFacetArray.push_back(mf);
00152 }
00153
00154 void MeshBuilder::SetNeighbourhood ()
00155 {
00156 std::set<Edge> edges;
00157 int facetIdx = 0;
00158
00159 for (MeshFacetArray::_TIterator it = _meshKernel._aclFacetArray.begin(); it != _meshKernel._aclFacetArray.end(); it++)
00160 {
00161 this->_seq->next(true);
00162 MeshFacet& mf = *it;
00163
00164 for (int i = 0; i < 3; i++)
00165 {
00166 Edge edge(mf._aulPoints[i], mf._aulPoints[(i+1)%3], facetIdx);
00167 std::set<Edge>::iterator e = edges.find(edge);
00168 if (e != edges.end())
00169 {
00170 MeshFacet& mf1 = _meshKernel._aclFacetArray[e->facetIdx];
00171 if (mf1._aulPoints[0] == edge.pt1)
00172 {
00173 if (mf1._aulPoints[1] == edge.pt2)
00174 mf1._aulNeighbours[0] = facetIdx;
00175 else
00176 mf1._aulNeighbours[2] = facetIdx;
00177 }
00178 else if (mf1._aulPoints[0] == edge.pt2)
00179 {
00180 if (mf1._aulPoints[1] == edge.pt1)
00181 mf1._aulNeighbours[0] = facetIdx;
00182 else
00183 mf1._aulNeighbours[2] = facetIdx;
00184 }
00185 else
00186 mf1._aulNeighbours[1] = facetIdx;
00187
00188 mf._aulNeighbours[i] = e->facetIdx;
00189 }
00190 else
00191 {
00192 edges.insert(edge);
00193 }
00194 }
00195
00196 facetIdx++;
00197 }
00198 }
00199
00200 void MeshBuilder::RemoveUnreferencedPoints()
00201 {
00202 _meshKernel._aclPointArray.SetFlag(MeshPoint::INVALID);
00203 for ( MeshFacetArray::_TConstIterator it = _meshKernel._aclFacetArray.begin(); it != _meshKernel._aclFacetArray.end(); ++it )
00204 {
00205 for ( int i=0; i<3; i++ )
00206 _meshKernel._aclPointArray[it->_aulPoints[i]].ResetInvalid();
00207 }
00208
00209 unsigned long uValidPts = std::count_if(_meshKernel._aclPointArray.begin(), _meshKernel._aclPointArray.end(), std::mem_fun_ref(&MeshPoint::IsValid));
00210 if ( uValidPts < _meshKernel.CountPoints() )
00211 _meshKernel.RemoveInvalids();
00212 }
00213
00214 void MeshBuilder::Finish (bool freeMemory)
00215 {
00216
00217 unsigned long i=0;
00218 _meshKernel._aclPointArray.resize(_pointsIterator.size());
00219 for ( std::vector<MeshPointIterator>::iterator it = _pointsIterator.begin(); it != _pointsIterator.end(); ++it)
00220 _meshKernel._aclPointArray[i++] = *(it->first);
00221
00222
00223
00224 { std::vector<MeshPointIterator>().swap(_pointsIterator); }
00225 _points.clear();
00226
00227 SetNeighbourhood();
00228 RemoveUnreferencedPoints();
00229
00230
00231 if ( freeMemory )
00232 {
00233 unsigned long cap = _meshKernel._aclFacetArray.capacity();
00234 unsigned long siz = _meshKernel._aclFacetArray.size();
00235
00236 if ( cap > siz+siz/20 )
00237 {
00238 try {
00239 unsigned long i=0;
00240 MeshFacetArray faces(siz);
00241 for ( MeshFacetArray::_TIterator it = _meshKernel._aclFacetArray.begin(); it != _meshKernel._aclFacetArray.end(); ++it )
00242 faces[i++]=*it;
00243 _meshKernel._aclFacetArray.swap(faces);
00244 } catch ( const Base::MemoryException&) {
00245
00246 }
00247 }
00248 }
00249
00250 _meshKernel.RecalcBoundBox();
00251 }