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
00025
00026 #include "cuttingPlane.H"
00027 #include <OpenFOAM/primitiveMesh.H>
00028 #include <OpenFOAM/linePointRef.H>
00029 #include <meshTools/meshTools.H>
00030
00031
00032
00033
00034
00036 const Foam::scalar zeroish = Foam::SMALL;
00037 const Foam::scalar positive = Foam::SMALL * 1E3;
00039
00040
00041
00042
00043 void Foam::cuttingPlane::calcCutCells
00044 (
00045 const primitiveMesh& mesh,
00046 const scalarField& dotProducts,
00047 const UList<label>& cellIdLabels
00048 )
00049 {
00050 const labelListList& cellEdges = mesh.cellEdges();
00051 const edgeList& edges = mesh.edges();
00052
00053 label listSize = cellEdges.size();
00054 if (&cellIdLabels)
00055 {
00056 listSize = cellIdLabels.size();
00057 }
00058
00059 cutCells_.setSize(listSize);
00060 label cutcellI(0);
00061
00062
00063
00064 for (label listI = 0; listI < listSize; ++listI)
00065 {
00066 label cellI = listI;
00067 if (&cellIdLabels)
00068 {
00069 cellI = cellIdLabels[listI];
00070 }
00071
00072 const labelList& cEdges = cellEdges[cellI];
00073
00074 label nCutEdges = 0;
00075
00076 forAll(cEdges, i)
00077 {
00078 const edge& e = edges[cEdges[i]];
00079
00080 if
00081 (
00082 (dotProducts[e[0]] < zeroish && dotProducts[e[1]] > positive)
00083 || (dotProducts[e[1]] < zeroish && dotProducts[e[0]] > positive)
00084 )
00085 {
00086 nCutEdges++;
00087
00088 if (nCutEdges > 2)
00089 {
00090 cutCells_[cutcellI++] = cellI;
00091
00092 break;
00093 }
00094 }
00095 }
00096 }
00097
00098
00099 cutCells_.setSize(cutcellI);
00100 }
00101
00102
00103
00104
00105
00106 void Foam::cuttingPlane::intersectEdges
00107 (
00108 const primitiveMesh& mesh,
00109 const scalarField& dotProducts,
00110 List<label>& edgePoint
00111 )
00112 {
00113
00114 const edgeList& edges = mesh.edges();
00115 const pointField& points = mesh.points();
00116
00117
00118 edgePoint.setSize(edges.size());
00119
00120 DynamicList<point> dynCuttingPoints(4*cutCells_.size());
00121
00122 forAll(edges, edgeI)
00123 {
00124 const edge& e = edges[edgeI];
00125
00126 if
00127 (
00128 (dotProducts[e[0]] < zeroish && dotProducts[e[1]] > positive)
00129 || (dotProducts[e[1]] < zeroish && dotProducts[e[0]] > positive)
00130 )
00131 {
00132
00133 edgePoint[edgeI] = dynCuttingPoints.size();
00134
00135 const point& p0 = points[e[0]];
00136 const point& p1 = points[e[1]];
00137
00138 scalar alpha = lineIntersect(linePointRef(p0, p1));
00139
00140 if (alpha < zeroish)
00141 {
00142 dynCuttingPoints.append(p0);
00143 }
00144 else if (alpha >= 1.0)
00145 {
00146 dynCuttingPoints.append(p1);
00147 }
00148 else
00149 {
00150 dynCuttingPoints.append((1-alpha)*p0 + alpha*p1);
00151 }
00152 }
00153 else
00154 {
00155 edgePoint[edgeI] = -1;
00156 }
00157 }
00158
00159 this->storedPoints().transfer(dynCuttingPoints);
00160 }
00161
00162
00163
00164
00165 bool Foam::cuttingPlane::walkCell
00166 (
00167 const primitiveMesh& mesh,
00168 const UList<label>& edgePoint,
00169 const label cellI,
00170 const label startEdgeI,
00171 DynamicList<label>& faceVerts
00172 )
00173 {
00174 label faceI = -1;
00175 label edgeI = startEdgeI;
00176
00177 label nIter = 0;
00178
00179 faceVerts.clear();
00180 do
00181 {
00182 faceVerts.append(edgePoint[edgeI]);
00183
00184
00185 faceI = meshTools::otherFace(mesh, cellI, faceI, edgeI);
00186
00187
00188 const labelList& fEdges = mesh.faceEdges()[faceI];
00189
00190 label nextEdgeI = -1;
00191
00192
00193
00194
00195
00196
00197 forAll(fEdges, i)
00198 {
00199 label edge2I = fEdges[i];
00200
00201 if (edge2I != edgeI && edgePoint[edge2I] != -1)
00202 {
00203 nextEdgeI = edge2I;
00204 break;
00205 }
00206 }
00207
00208 if (nextEdgeI == -1)
00209 {
00210
00211 WarningIn("Foam::cuttingPlane::walkCell")
00212 << "Did not find closed walk along surface of cell " << cellI
00213 << " starting from edge " << startEdgeI
00214 << " in " << nIter << " iterations." << nl
00215 << "Collected cutPoints so far:" << faceVerts
00216 << endl;
00217
00218 return false;
00219 }
00220
00221 edgeI = nextEdgeI;
00222
00223 nIter++;
00224
00225 if (nIter > 1000)
00226 {
00227 WarningIn("Foam::cuttingPlane::walkCell")
00228 << "Did not find closed walk along surface of cell " << cellI
00229 << " starting from edge " << startEdgeI
00230 << " in " << nIter << " iterations." << nl
00231 << "Collected cutPoints so far:" << faceVerts
00232 << endl;
00233 return false;
00234 }
00235
00236 } while (edgeI != startEdgeI);
00237
00238
00239 if (faceVerts.size() >= 3)
00240 {
00241 return true;
00242 }
00243 else
00244 {
00245 WarningIn("Foam::cuttingPlane::walkCell")
00246 << "Did not find closed walk along surface of cell " << cellI
00247 << " starting from edge " << startEdgeI << nl
00248 << "Collected cutPoints so far:" << faceVerts
00249 << endl;
00250
00251 return false;
00252 }
00253 }
00254
00255
00256
00257 void Foam::cuttingPlane::walkCellCuts
00258 (
00259 const primitiveMesh& mesh,
00260 const UList<label>& edgePoint
00261 )
00262 {
00263 const pointField& cutPoints = this->points();
00264
00265
00266 DynamicList<face> dynCutFaces(cutCells_.size());
00267 DynamicList<label> dynCutCells(cutCells_.size());
00268
00269
00270 DynamicList<label> faceVerts(10);
00271
00272 forAll(cutCells_, i)
00273 {
00274 label cellI = cutCells_[i];
00275
00276
00277 const labelList& cEdges = mesh.cellEdges()[cellI];
00278
00279 label startEdgeI = -1;
00280
00281 forAll(cEdges, cEdgeI)
00282 {
00283 label edgeI = cEdges[cEdgeI];
00284
00285 if (edgePoint[edgeI] != -1)
00286 {
00287 startEdgeI = edgeI;
00288 break;
00289 }
00290 }
00291
00292
00293 if (startEdgeI == -1)
00294 {
00295 FatalErrorIn("Foam::cuttingPlane::walkCellCuts")
00296 << "Cannot find cut edge for cut cell " << cellI
00297 << abort(FatalError);
00298 }
00299
00300
00301 bool okCut = walkCell
00302 (
00303 mesh,
00304 edgePoint,
00305 cellI,
00306 startEdgeI,
00307 faceVerts
00308 );
00309
00310 if (okCut)
00311 {
00312 face f(faceVerts);
00313
00314
00315 if ((f.normal(cutPoints) & normal()) < 0)
00316 {
00317 f = f.reverseFace();
00318 }
00319
00320
00321 label nTri = f.triangles(cutPoints, dynCutFaces);
00322 while (nTri--)
00323 {
00324 dynCutCells.append(cellI);
00325 }
00326 }
00327 }
00328
00329 this->storedFaces().transfer(dynCutFaces);
00330 cutCells_.transfer(dynCutCells);
00331 }
00332
00333
00334
00335
00336
00337 Foam::cuttingPlane::cuttingPlane(const plane& pln)
00338 :
00339 plane(pln)
00340 {}
00341
00342
00343
00344 Foam::cuttingPlane::cuttingPlane
00345 (
00346 const plane& pln,
00347 const primitiveMesh& mesh,
00348 const UList<label>& cellIdLabels
00349 )
00350 :
00351 plane(pln)
00352 {
00353 reCut(mesh, cellIdLabels);
00354 }
00355
00356
00357
00358
00359
00360
00361 void Foam::cuttingPlane::reCut
00362 (
00363 const primitiveMesh& mesh,
00364 const UList<label>& cellIdLabels
00365 )
00366 {
00367 MeshStorage::clear();
00368 cutCells_.clear();
00369
00370 scalarField dotProducts = (mesh.points() - refPoint()) & normal();
00371
00372
00373 calcCutCells(mesh, dotProducts, cellIdLabels);
00374
00375
00376
00377 labelList edgePoint;
00378 intersectEdges(mesh, dotProducts, edgePoint);
00379
00380
00381 walkCellCuts(mesh, edgePoint);
00382 }
00383
00384
00385
00386 void Foam::cuttingPlane::remapFaces
00387 (
00388 const UList<label>& faceMap
00389 )
00390 {
00391
00392 if (&faceMap && faceMap.size())
00393 {
00394 MeshStorage::remapFaces(faceMap);
00395
00396 List<label> newCutCells(faceMap.size());
00397 forAll(faceMap, faceI)
00398 {
00399 newCutCells[faceI] = cutCells_[faceMap[faceI]];
00400 }
00401 cutCells_.transfer(newCutCells);
00402 }
00403 }
00404
00405
00406
00407 void Foam::cuttingPlane::operator=(const cuttingPlane& rhs)
00408 {
00409
00410 if (this == &rhs)
00411 {
00412 FatalErrorIn ("Foam::cuttingPlane::operator=(const cuttingPlane&)")
00413 << "Attempted assignment to self"
00414 << abort(FatalError);
00415 }
00416
00417 static_cast<MeshStorage&>(*this) = rhs;
00418 static_cast<plane&>(*this) = rhs;
00419 cutCells_ = rhs.cutCells();
00420 }
00421
00422
00423