diff --git a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C index 235c812bff251a04ddc085f1c9a3d4e27dfd5824..65d62f4b67fc5174cb02f720d5e1b39ce1f9ab9c 100644 --- a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C +++ b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C @@ -34,6 +34,9 @@ Usage @param -clean \n Perform some surface checking/cleanup on the input surface + @param -orient \n + Check face orientation on the input surface + @param -scale \<scale\> \n Specify a scaling factor for writing the files @@ -68,6 +71,7 @@ int main(int argc, char *argv[]) argList::validArgs.append("inputFile"); argList::validArgs.append("outputFile"); argList::validOptions.insert("clean", ""); + argList::validOptions.insert("orient", ""); argList::validOptions.insert("scale", "scale"); argList::validOptions.insert("triSurface", ""); argList::validOptions.insert("unsorted", ""); @@ -108,6 +112,13 @@ int main(int argc, char *argv[]) surf.writeStats(Info); Info<< endl; + if (args.options().found("orient")) + { + Info<< "Checking surface orientation" << endl; + surf.checkOrientation(true); + Info<< endl; + } + if (args.options().found("clean")) { Info<< "Cleaning up surface" << endl; @@ -140,6 +151,13 @@ int main(int argc, char *argv[]) surf.writeStats(Info); Info<< endl; + if (args.options().found("orient")) + { + Info<< "Checking surface orientation" << endl; + surf.checkOrientation(true); + Info<< endl; + } + if (args.options().found("clean")) { Info<< "Cleaning up surface" << endl; @@ -171,6 +189,13 @@ int main(int argc, char *argv[]) surf.writeStats(Info); Info<< endl; + if (args.options().found("orient")) + { + Info<< "Checking surface orientation" << endl; + surf.checkOrientation(true); + Info<< endl; + } + if (args.options().found("clean")) { Info<< "Cleaning up surface" << endl; @@ -202,6 +227,13 @@ int main(int argc, char *argv[]) surf.writeStats(Info); Info<< endl; + if (args.options().found("orient")) + { + Info<< "Checking surface orientation" << endl; + surf.checkOrientation(true); + Info<< endl; + } + if (args.options().found("clean")) { Info<< "Cleaning up surface" << endl; diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.C b/src/OpenFOAM/meshes/meshShapes/face/face.C index b6c8370f77f8344cb6977ef582eb377b0509b116..f371e697a1a9e4022c3d505ae26abef420785ec2 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/face.C +++ b/src/OpenFOAM/meshes/meshShapes/face/face.C @@ -713,41 +713,43 @@ Foam::edgeList Foam::face::edges() const int Foam::face::edgeDirection(const edge& e) const { - if (size() > 2) + forAll (*this, i) { - edge found(-1,-1); - - // find start/end points - this breaks down for degenerate faces - forAll (*this, i) + if (operator[](i) == e.start()) { - if (operator[](i) == e.start()) + if (operator[](rcIndex(i)) == e.end()) { - found.start() = i; + // reverse direction + return -1; } - else if (operator[](i) == e.end()) + else if (operator[](fcIndex(i)) == e.end()) { - found.end() = i; + // forward direction + return 1; } - } - label diff = found.end() - found.start(); - if (!diff || found.start() < 0 || found.end() < 0) - { + // no match return 0; } - - // forward direction - if (diff == 1 || diff == 1 - size()) - { - return 1; - } - // reverse direction - if (diff == -1 || diff == -1 + size()) + else if (operator[](i) == e.end()) { - return -1; + if (operator[](rcIndex(i)) == e.start()) + { + // forward direction + return 1; + } + else if (operator[](fcIndex(i)) == e.start()) + { + // reverse direction + return -1; + } + + // no match + return 0; } } + // not found return 0; } diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.H b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.H index 2a132d914c84c060da7e25f7effcd166a40f3944..3818fcbfb50cb77aec85e63aa8f73a346ff2fb01 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.H +++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.H @@ -125,11 +125,8 @@ public: // Topological data; no mesh required. - //- Return edge-face addressing sorted - // (for edges with more than 2 faces) according to the - // angle around the edge. - // Orientation is anticlockwise looking from - // edge.vec(localPoints()) + //- Return edge-face addressing sorted by angle around the edge. + // Orientation is anticlockwise looking from edge.vec(localPoints()) const labelListList& sortedEdgeFaces() const; //- If 2 face neighbours: label of face where ordering of edge diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraAddressing.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraAddressing.C index 8d33ad27628d803e4c6989af95433ccbed9dabd8..98782ea40bbc2e89bb839db0aec2c1cf965b5efd 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraAddressing.C +++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraAddressing.C @@ -171,26 +171,25 @@ calcEdgeOwner() const forAll(edgeLst, edgeI) { const edge& e = edgeLst[edgeI]; + const labelList& neighbouringFaces = eFaces[edgeI]; - const labelList& myFaces = eFaces[edgeI]; - - if (myFaces.size() == 1) + if (neighbouringFaces.size() == 1) { - edgeOwner[edgeI] = myFaces[0]; + edgeOwner[edgeI] = neighbouringFaces[0]; } else { // Find the first face whose vertices are aligned with the edge. - // (in case of multiply connected edge the best we can do) + // with multiply connected edges, this is the best we can do edgeOwner[edgeI] = -1; - forAll(myFaces, i) + forAll(neighbouringFaces, i) { - const Face& f = locFaceLst[myFaces[i]]; + const Face& f = locFaceLst[neighbouringFaces[i]]; - if (f.findEdge(e) > 0) + if (f.edgeDirection(e) > 0) { - edgeOwner[edgeI] = myFaces[i]; + edgeOwner[edgeI] = neighbouringFaces[i]; break; } } @@ -203,9 +202,9 @@ calcEdgeOwner() const "calcEdgeOwner()" ) << "Edge " << edgeI << " vertices:" << e - << " is used by faces " << myFaces + << " is used by faces " << neighbouringFaces << " vertices:" - << IndirectList<Face>(locFaceLst, myFaces)() + << IndirectList<Face>(locFaceLst, neighbouringFaces)() << " none of which use the edge vertices in the same order" << nl << "I give up" << abort(FatalError); } diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraCleanup.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraCleanup.C index e34b2a2a44ca4bc912095f55be9550b9db0b41ce..c825f44a0e10dd309b23ecaa53dc79cdbb1f8a09 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraCleanup.C +++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraCleanup.C @@ -99,6 +99,11 @@ checkOrientation const Field<PointType>& pointLst = this->points(); const vectorField& normLst = this->faceNormals(); + if (ParentType::debug) + { + Info<<"checkOrientation:::checkOrientation(bool)" << endl; + } + // Check edge normals, face normals, point normals. forAll(faceEs, faceI) { @@ -153,8 +158,8 @@ checkOrientation ( "PrimitivePatchExtra::checkOrientation(bool)" ) - << "Normal calculated from points not consistent with " - << "faceNormal" << nl + << "Normal calculated from points inconsistent with faceNormal" + << nl << "face: " << f << nl << "points: " << p0 << ' ' << p1 << ' ' << p2 << nl << "pointNormal:" << pointNormal << nl @@ -174,21 +179,18 @@ checkOrientation forAll(edgeLst, edgeI) { const edge& e = edgeLst[edgeI]; - const labelList& neighbours = eFaces[edgeI]; + const labelList& neighbouringFaces = eFaces[edgeI]; - if (neighbours.size() == 2) + if (neighbouringFaces.size() == 2) { - const Face& faceA = faceLst[neighbours[0]]; - const Face& faceB = faceLst[neighbours[1]]; - - // The edge cannot be going in the same direction if both faces - // are oriented counterclockwise. - // Thus the next face point *must* different between the faces. - if - ( - faceA[faceA.fcIndex(findIndex(faceA, e.start()))] - == faceB[faceB.fcIndex(findIndex(faceB, e.start()))] - ) + // we use localFaces() since edges() are LOCAL + // these are both already available + const Face& faceA = this->localFaces()[neighbouringFaces[0]]; + const Face& faceB = this->localFaces()[neighbouringFaces[1]]; + + // If the faces are correctly oriented, the edges must go in + // different directions on connected faces. + if (faceA.edgeDirection(e) == faceB.edgeDirection(e)) { borderEdge[edgeI] = true; if (verbose) @@ -198,14 +200,20 @@ checkOrientation "PrimitivePatchExtra::checkOrientation(bool)" ) << "face orientation incorrect." << nl - << "edge[" << edgeI << "] " << e - << " between faces " << neighbours << ":" << nl - << "face[" << neighbours[0] << "] " << faceA << nl - << "face[" << neighbours[1] << "] " << faceB << endl; + << "localEdge[" << edgeI << "] " << e + << " between faces:" << nl + << " face[" << neighbouringFaces[0] << "] " + << faceLst[neighbouringFaces[0]] + << " localFace: " << faceA + << nl + << " face[" << neighbouringFaces[1] << "] " + << faceLst[neighbouringFaces[1]] + << " localFace: " << faceB + << endl; } } } - else if (neighbours.size() != 1) + else if (neighbouringFaces.size() != 1) { if (verbose) { @@ -217,7 +225,7 @@ checkOrientation << "edge[" << edgeI << "] " << e << " with points:" << locPointsLst[e.start()] << ' ' << locPointsLst[e.end()] - << " has neighbours:" << neighbours << endl; + << " has neighbouringFaces:" << neighbouringFaces << endl; } borderEdge[edgeI] = true; }