diff --git a/applications/utilities/surface/surfaceCheck/surfaceCheck.C b/applications/utilities/surface/surfaceCheck/surfaceCheck.C index 1b76d0a8ad..0b3acc607e 100644 --- a/applications/utilities/surface/surfaceCheck/surfaceCheck.C +++ b/applications/utilities/surface/surfaceCheck/surfaceCheck.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -64,6 +64,9 @@ Usage #include "SortableList.H" #include "PatchTools.H" #include "vtkSurfaceWriter.H" +#include "functionObject.H" +#include "DynamicField.H" +#include "edgeMesh.H" using namespace Foam; @@ -123,6 +126,7 @@ labelList countBins void writeZoning ( + const surfaceWriter& writer, const triSurface& surf, const labelList& faceZone, const word& fieldName, @@ -138,9 +142,9 @@ void writeZoning + '_' + surfFileNameBase + '.' - + vtkSurfaceWriter::typeName + + writer.type() ) - << "..." << endl << endl; + << " ..." << endl << endl; // Convert data scalarField scalarFaceZone(faceZone.size()); @@ -154,7 +158,7 @@ void writeZoning faces[i] = surf[i]; } - vtkSurfaceWriter().write + writer.write ( surfFilePath, surfFileNameBase, @@ -275,6 +279,40 @@ void syncEdges(const triSurface& p, boolList& isMarkedEdge) } +void writeEdgeSet +( + const word& setName, + const triSurface& surf, + const labelUList& edgeSet +) +{ + // Get compact edge mesh + labelList pointToCompact(surf.nPoints(), -1); + DynamicField compactPoints(edgeSet.size()); + DynamicList compactEdges(edgeSet.size()); + for (label edgei : edgeSet) + { + const edge& e = surf.edges()[edgei]; + edge compactEdge(-1, -1); + forAll(e, ep) + { + label& compacti = pointToCompact[e[ep]]; + if (compacti == -1) + { + compacti = compactPoints.size(); + label pointi = surf.meshPoints()[e[ep]]; + compactPoints.append(surf.points()[pointi]); + } + compactEdge[ep] = compacti; + } + compactEdges.append(compactEdge); + } + + edgeMesh eMesh(std::move(compactPoints), std::move(compactEdges)); + eMesh.write(setName); +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) @@ -309,6 +347,13 @@ int main(int argc, char *argv[]) "upper limit on the number of files written." " Default is 10, using 0 suppresses file writing." ); + argList::addOption + ( + "writeSets", + "surfaceFormat", + "reconstruct and write problem triangles/edges in selected format" + ); + argList args(argc, argv); @@ -317,6 +362,25 @@ int main(int argc, char *argv[]) const bool splitNonManifold = args.found("splitNonManifold"); const label outputThreshold = args.lookupOrDefault("outputThreshold", 10); + word surfaceFormat; + const bool writeSets = args.optionReadIfPresent("writeSets", surfaceFormat); + + autoPtr surfWriter; + word edgeFormat; + if (writeSets) + { + surfWriter = surfaceWriter::New(surfaceFormat); + // Option1: hard-coded format + edgeFormat = "obj"; + //// Option2: same type as surface format. Problem is e.g. .obj format + //// is not a surfaceWriter format. + //edgeFormat = surfaceFormat; + //if (!edgeMesh::canWriteType(edgeFormat)) + //{ + // edgeFormat = "obj"; + //} + } + Info<< "Reading surface from " << surfFileName << " ..." << nl << endl; @@ -414,7 +478,8 @@ int main(int argc, char *argv[]) forAll(surf, facei) { - if (!triSurfaceTools::validTri(surf, facei)) + // Check silently + if (!triSurfaceTools::validTri(surf, facei, false)) { illegalFaces.append(facei); } @@ -425,8 +490,71 @@ int main(int argc, char *argv[]) Info<< "Surface has " << illegalFaces.size() << " illegal triangles." << endl; - if (outputThreshold > 0) + if (surfWriter.valid()) { + boolList isIllegalFace(surf.size(), false); + UIndirectList(isIllegalFace, illegalFaces) = true; + + labelList pointMap; + labelList faceMap; + triSurface subSurf + ( + surf.subsetMesh + ( + isIllegalFace, + pointMap, + faceMap + ) + ); + + const fileName qualityName + ( + surfFilePath + / "illegal" + + '_' + + surfFileNameBase + + '.' + + surfWriter().type() + ); + Info<< "Writing illegal triangles to " + << qualityName << " ..." << endl << endl; + + // Convert data + faceList faces(subSurf.size()); + forAll(subSurf, i) + { + faces[i] = subSurf[i]; + } + + surfWriter().write + ( + surfFilePath, + surfFileNameBase, + meshedSurfRef + ( + subSurf.points(), + faces + ), + "illegal", + scalarField(subSurf.size(), 0.0), + false // face based data + ); + } + else if (outputThreshold > 0) + { + forAll(illegalFaces, i) + { + // Force warning message + triSurfaceTools::validTri(surf, illegalFaces[i], true); + if (i >= outputThreshold) + { + Info<< "Suppressing further warning messages." + << " Use -outputThreshold to increase number" + << " of warnings." << endl; + break; + } + } + OFstream str("illegalFaces"); Info<< "Dumping conflicting face labels to " << str.name() << endl @@ -502,12 +630,48 @@ int main(int argc, char *argv[]) if (triQ[minIndex] < SMALL) { WarningInFunction + << "Minimum triangle quality is " << triQ[minIndex] << ". This might give problems in" << " self-intersection testing later on." << endl; } // Dump for subsetting - if (outputThreshold > 0) + if (surfWriter.valid()) + { + const fileName qualityName + ( + surfFilePath + / "quality" + + '_' + + surfFileNameBase + + '.' + + surfWriter().type() + ); + Info<< "Writing triangle-quality to " + << qualityName << " ..." << endl << endl; + + // Convert data + faceList faces(surf.size()); + forAll(surf, i) + { + faces[i] = surf[i]; + } + + surfWriter().write + ( + surfFilePath, + surfFileNameBase, + meshedSurfRef + ( + surf.points(), + faces + ), + "quality", + triQ, + false // face based data + ); + } + else if (outputThreshold > 0) { DynamicList