1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
11 cfMesh is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
16 cfMesh is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
28 #include "triSurfAddressing.H"
29 #include "VRWGraphSMPModifier.H"
30 #include "demandDrivenData.H"
41 void triSurfAddressing::calculatePointFacets() const
43 pointFacetsPtr_ = new VRWGraph();
45 VRWGraphSMPModifier(*pointFacetsPtr_).reverseAddressing(facets_);
48 void triSurfAddressing::calculateEdges() const
50 edgesPtr_ = new edgeLongList();
52 const VRWGraph& pFacets = pointFacets();
55 label nThreads = 3 * omp_get_num_procs();
56 if( pFacets.size() < 1000 )
59 const label nThreads(1);
62 labelList nEdgesForThread(nThreads);
67 # pragma omp parallel num_threads(nThreads)
70 edgeLongList edgesHelper;
73 # pragma omp for schedule(static)
77 std::set<std::pair<label, label> > edgesAtPoint;
79 forAllRow(pFacets, pI, pfI)
81 const label triI = pFacets(pI, pfI);
82 const labelledTri& tri = facets_[triI];
92 if( tri[(pos+1)%3] >= pI )
95 std::make_pair(pI, tri[(pos+1)%3])
97 if( tri[(pos+2)%3] >= pI )
100 std::make_pair(pI, tri[(pos+2)%3])
108 std::set<std::pair<label, label> >::const_iterator it;
109 for(it=edgesAtPoint.begin();it!=edgesAtPoint.end();++it)
110 edgesHelper.append(edge(it->first, it->second));
113 //- this enables other threads to see the number of edges
114 //- generated by each thread
116 const label threadI = omp_get_thread_num();
118 const label threadI(0);
120 nEdgesForThread[threadI] = edgesHelper.size();
124 # pragma omp critical
126 edgeI += edgesHelper.size();
133 edgesPtr_->setSize(edgeI);
139 //- find the starting position of the edges generated by this thread
140 //- in the global list of edges
142 for(label i=0;i<threadI;++i)
143 localStart += nEdgesForThread[i];
145 //- store edges into the global list
146 forAll(edgesHelper, i)
147 edgesPtr_->operator[](localStart+i) = edgesHelper[i];
151 void triSurfAddressing::calculateFacetEdges() const
153 const edgeLongList& edges = this->edges();
154 const VRWGraph& pointFaces = this->pointFacets();
156 facetEdgesPtr_ = new VRWGraph(facets_.size(), 3, -1);
157 VRWGraph& faceEdges = *facetEdgesPtr_;
160 # pragma omp parallel for schedule(dynamic, 100)
164 const edge ee = edges[edgeI];
165 const label pI = ee.start();
167 forAllRow(pointFaces, pI, pfI)
169 const label fI = pointFaces(pI, pfI);
171 const labelledTri& tri = facets_[fI];
174 const edge e(tri[eI], tri[(eI+1)%3]);
178 faceEdges(fI, eI) = edgeI;
184 # ifdef DEBUGTriSurfAddressing
185 forAll(faceEdges, triI)
187 forAllRow(faceEdges, triI, feI)
189 if( facets_[triI][feI] < 0 || facets_[triI][feI] >= points_.size() )
192 "void triSurfAddressing::calculateFacetEdges() const"
193 ) << "Invalid entry in triangle " << triI
194 << " " << facets_[triI] << abort(FatalError);
196 const label edgeI = faceEdges(triI, feI);
198 if( edgeI < 0 || edgeI >= edges.size() )
201 "void triSurfAddressing::calculateFacetEdges() const"
202 ) << "Invalid entry in face " << triI << " "
203 << facets_[triI] << " edges "
204 << faceEdges[triI] << abort(FatalError);
210 void triSurfAddressing::calculateEdgeFacets() const
212 const edgeLongList& edges = this->edges();
213 const VRWGraph& faceEdges = this->facetEdges();
215 edgeFacetsPtr_ = new VRWGraph(edges.size());
217 VRWGraphSMPModifier(*edgeFacetsPtr_).reverseAddressing(faceEdges);
220 void triSurfAddressing::calculatePointEdges() const
222 const edgeLongList& edges = this->edges();
224 pointEdgesPtr_ = new VRWGraph(points_.size());
226 pointEdgesPtr_->reverseAddressing(edges);
229 void triSurfAddressing::calculateFacetFacetsEdges() const
231 facetFacetsEdgesPtr_ = new VRWGraph();
233 const VRWGraph& facetEdges = this->facetEdges();
234 const VRWGraph& edgeFacets = this->edgeFacets();
236 facetFacetsEdgesPtr_->setSize(facets_.size());
238 forAll(facetEdges, facetI)
240 labelHashSet fLabels;
242 forAllRow(facetEdges, facetI, feI)
244 const label edgeI = facetEdges(facetI, feI);
246 forAllRow(edgeFacets, edgeI, efI)
247 fLabels.insert(edgeFacets(edgeI, efI));
250 facetFacetsEdgesPtr_->setRowSize(facetI, fLabels.size());
253 forAllConstIter(labelHashSet, fLabels, iter)
254 facetFacetsEdgesPtr_->operator()(facetI, counter++) = iter.key();
258 void triSurfAddressing::calculatePointNormals() const
260 const VRWGraph& pFacets = pointFacets();
261 const vectorField& fNormals = facetNormals();
263 pointNormalsPtr_ = new vectorField(pFacets.size());
265 const label size = pFacets.size();
267 # pragma omp parallel for if( size > 1000 )
269 for(label pI=0;pI<size;++pI)
271 vector normal(vector::zero);
273 forAllRow(pFacets, pI, pfI)
274 normal += fNormals[pFacets(pI, pfI)];
276 const scalar d = mag(normal);
283 normal = vector::zero;
286 (*pointNormalsPtr_)[pI] = normal;
290 void triSurfAddressing::calculateFacetNormals() const
292 facetNormalsPtr_ = new vectorField(facets_.size());
295 # pragma omp parallel for schedule(dynamic, 40)
299 vector v = facets_[fI].normal(points_);
300 v /= (mag(v) + VSMALL);
301 (*facetNormalsPtr_)[fI] = v;
305 void triSurfAddressing::calculateFacetCentres() const
307 facetCentresPtr_ = new vectorField(facets_.size());
310 # pragma omp parallel for schedule(dynamic, 40)
313 (*facetCentresPtr_)[fI] = facets_[fI].centre(points_);
316 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
318 triSurfAddressing::triSurfAddressing
320 const pointField& points,
321 const LongList<labelledTri>& triangles)
325 pointFacetsPtr_(NULL),
327 facetEdgesPtr_(NULL),
328 edgeFacetsPtr_(NULL),
329 pointEdgesPtr_(NULL),
330 facetFacetsEdgesPtr_(NULL),
331 pointNormalsPtr_(NULL),
332 facetNormalsPtr_(NULL),
333 facetCentresPtr_(NULL)
337 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
339 triSurfAddressing::~triSurfAddressing()
345 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
347 void triSurfAddressing::clearAddressing()
349 deleteDemandDrivenData(pointFacetsPtr_);
350 deleteDemandDrivenData(edgesPtr_);
351 deleteDemandDrivenData(facetEdgesPtr_);
352 deleteDemandDrivenData(edgeFacetsPtr_);
353 deleteDemandDrivenData(pointEdgesPtr_);
354 deleteDemandDrivenData(facetFacetsEdgesPtr_);
357 void triSurfAddressing::clearGeometry()
359 deleteDemandDrivenData(pointNormalsPtr_);
360 deleteDemandDrivenData(facetNormalsPtr_);
361 deleteDemandDrivenData(facetCentresPtr_);
364 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
366 } // End namespace Foam
368 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //