From 139edb246860860da5f8623e93fdc08cb2dc5c6b Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Mon, 14 Aug 2017 09:18:15 +0200 Subject: [PATCH] ENH: add input surface scaling (issue #514) - surfaceFeatureExtract * dictionary "scale" entry - triSurface - triSurfaceLoader * optional scaleFactor on reading - surfaceAdd - surfaceBooleanFeatures - surfaceClean - surfaceCoarsen * scale option - surfaceTransformPoints, transformPoints * scale option as scalar or vector quantity --- .../Test-surfaceIntersection.C | 25 ++++++-- .../foamToFireMesh/foamToFireMesh.C | 2 +- .../transformPoints/transformPoints.C | 55 +++++++++++------ .../utilities/surface/surfaceAdd/surfaceAdd.C | 61 ++++++++++--------- .../surfaceBooleanFeatures.C | 24 +++++++- .../surface/surfaceClean/surfaceClean.C | 19 ++++-- .../surface/surfaceCoarsen/surfaceCoarsen.C | 54 ++++++++-------- .../surface/surfaceConvert/surfaceConvert.C | 19 +++--- .../surfaceFeatureExtract.C | 9 ++- .../surfaceFeatureExtractDict | 3 + .../surface/surfaceFind/surfaceFind.C | 5 +- .../surface/surfaceInertia/surfaceInertia.C | 2 +- .../surface/surfaceInflate/surfaceInflate.C | 2 +- .../surface/surfaceMeshInfo/surfaceMeshInfo.C | 8 +-- .../surface/surfaceOrient/surfaceOrient.C | 19 ++++-- .../surfacePointMerge/surfacePointMerge.C | 28 +++++++-- .../surfaceRedistributePar.C | 3 +- .../surfaceTransformPoints.C | 56 ++++++++++------- src/conversion/common/writer/meshWriter.H | 3 +- src/conversion/fire/FIREMeshWriter.H | 3 +- .../triSurfaceLoader/triSurfaceLoader.C | 12 +++- .../triSurfaceLoader/triSurfaceLoader.H | 5 +- src/surfMesh/triSurface/triSurface.C | 10 +-- src/surfMesh/triSurface/triSurface.H | 49 +++++++++------ 24 files changed, 306 insertions(+), 170 deletions(-) diff --git a/applications/test/surfaceIntersection/Test-surfaceIntersection.C b/applications/test/surfaceIntersection/Test-surfaceIntersection.C index ddf122f60a9..b8416637900 100644 --- a/applications/test/surfaceIntersection/Test-surfaceIntersection.C +++ b/applications/test/surfaceIntersection/Test-surfaceIntersection.C @@ -41,10 +41,15 @@ using namespace Foam; autoPtr<triSurface> loadSurface ( const Foam::Time& runTime, - const fileName& surfName + const fileName& surfName, + const scalar scaleFactor ) { - Info<< "Reading surface " << surfName << endl; + Info<< "Reading surface " << surfName << nl; + if (scaleFactor > 0) + { + Info<<"Scaling : " << scaleFactor << nl; + } const fileName fallback = runTime.constantPath()/triSurfaceMesh::meshSubDir/surfName; @@ -52,11 +57,11 @@ autoPtr<triSurface> loadSurface autoPtr<triSurface> surfPtr; if (isFile(surfName)) { - surfPtr.set(new triSurface(surfName)); + surfPtr.set(new triSurface(surfName, scaleFactor)); } else if (isFile(fallback)) { - surfPtr.set(new triSurface(fallback)); + surfPtr.set(new triSurface(fallback, scaleFactor)); } else { @@ -102,6 +107,12 @@ int main(int argc, char *argv[]) "mergeTol", "merge points (and edges) using the specified tolerance" ); + argList::addOption + ( + "scale", + "factor", + "geometry scaling factor" + ); #include "addDictOption.H" @@ -117,16 +128,18 @@ int main(int argc, char *argv[]) #include "setRootCase.H" #include "createTime.H" + const scalar scaleFactor = args.optionLookupOrDefault<scalar>("scale", -1); + const word outputFile(args.executable() + ".obj"); const fileName surf1Name(args[1]); - triSurface surf1 = loadSurface(runTime, surf1Name)(); + triSurface surf1 = loadSurface(runTime, surf1Name, scaleFactor)(); Info<< surf1Name << " statistics:" << endl; surf1.writeStats(Info); Info<< endl; const fileName surf2Name(args[2]); - triSurface surf2 = loadSurface(runTime, surf2Name)(); + triSurface surf2 = loadSurface(runTime, surf2Name, scaleFactor)(); Info<< surf2Name << " statistics:" << endl; surf2.writeStats(Info); Info<< endl; diff --git a/applications/utilities/mesh/conversion/foamToFireMesh/foamToFireMesh.C b/applications/utilities/mesh/conversion/foamToFireMesh/foamToFireMesh.C index 87ddd4dff93..216f253d5f2 100644 --- a/applications/utilities/mesh/conversion/foamToFireMesh/foamToFireMesh.C +++ b/applications/utilities/mesh/conversion/foamToFireMesh/foamToFireMesh.C @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) // ~~~~~~~~~~~~~~~~~~~~~ fileFormats::FIREMeshWriter::binary = !args.optionFound("ascii"); - // default: rescale from [m] to [mm] + // Default: no rescaling scalar scaleFactor = 1; if (args.optionReadIfPresent("scale", scaleFactor)) { diff --git a/applications/utilities/mesh/manipulation/transformPoints/transformPoints.C b/applications/utilities/mesh/manipulation/transformPoints/transformPoints.C index db2f571043f..b082bf39c2b 100644 --- a/applications/utilities/mesh/manipulation/transformPoints/transformPoints.C +++ b/applications/utilities/mesh/manipulation/transformPoints/transformPoints.C @@ -43,8 +43,8 @@ Usage or -yawPitchRoll (yawdegrees pitchdegrees rolldegrees) or -rollPitchYaw (rolldegrees pitchdegrees yawdegrees) - -scale vector - Scales the points by the given vector. + -scale scalar|vector + Scales the points by the given scalar or vector. The any or all of the three options may be specified and are processed in the above order. @@ -182,9 +182,9 @@ int main(int argc, char *argv[]) argList::addOption ( "scale", - "vector", - "scale by the specified amount - eg, '(0.001 0.001 0.001)' for a " - "uniform [mm] to [m] scaling" + "scalar | vector", + "scale by the specified amount - eg, for a uniform [mm] to [m] scaling " + "use either (0.001 0.001 0.001)' or simply '0.001'" ); #include "addRegionOption.H" @@ -262,10 +262,10 @@ int main(int argc, char *argv[]) << " pitch " << v.y() << nl << " yaw " << v.z() << nl; - // Convert to radians + // degToRad v *= pi/180.0; - quaternion R(quaternion::rotationSequence::XYZ, v); + const quaternion R(quaternion::rotationSequence::XYZ, v); Info<< "Rotating points by quaternion " << R << endl; points = transform(R, points); @@ -282,16 +282,10 @@ int main(int argc, char *argv[]) << " pitch " << v.y() << nl << " roll " << v.z() << nl; - // Convert to radians + // degToRad v *= pi/180.0; - scalar yaw = v.x(); - scalar pitch = v.y(); - scalar roll = v.z(); - - quaternion R = quaternion(vector(0, 0, 1), yaw); - R *= quaternion(vector(0, 1, 0), pitch); - R *= quaternion(vector(1, 0, 0), roll); + const quaternion R(quaternion::rotationSequence::ZYX, v); Info<< "Rotating points by quaternion " << R << endl; points = transform(R, points); @@ -302,13 +296,34 @@ int main(int argc, char *argv[]) } } - if (args.optionReadIfPresent("scale", v)) + if (args.optionFound("scale")) { - Info<< "Scaling points by " << v << endl; + // Use readList to handle single or multiple values + const List<scalar> scaling = args.optionReadList<scalar>("scale"); - points.replace(vector::X, v.x()*points.component(vector::X)); - points.replace(vector::Y, v.y()*points.component(vector::Y)); - points.replace(vector::Z, v.z()*points.component(vector::Z)); + if (scaling.size() == 1) + { + Info<< "Scaling points uniformly by " << scaling[0] << nl; + points *= scaling[0]; + } + else if (scaling.size() == 3) + { + Info<< "Scaling points by (" + << scaling[0] << " " + << scaling[1] << " " + << scaling[2] << ")" << nl; + + points.replace(vector::X, scaling[0]*points.component(vector::X)); + points.replace(vector::Y, scaling[1]*points.component(vector::Y)); + points.replace(vector::Z, scaling[2]*points.component(vector::Z)); + } + else + { + FatalError + << "-scale with 1 or 3 components only" << nl + << "given: " << args["scale"] << endl + << exit(FatalError); + } } // Set the precision of the points data to 10 diff --git a/applications/utilities/surface/surfaceAdd/surfaceAdd.C b/applications/utilities/surface/surfaceAdd/surfaceAdd.C index 5caa3e07031..0be9024ebd9 100644 --- a/applications/utilities/surface/surfaceAdd/surfaceAdd.C +++ b/applications/utilities/surface/surfaceAdd/surfaceAdd.C @@ -71,6 +71,12 @@ int main(int argc, char *argv[]) "mergeRegions", "combine regions from both surfaces" ); + argList::addOption + ( + "scale", + "factor", + "geometry scaling factor on input surfaces" + ); argList args(argc, argv); @@ -81,6 +87,8 @@ int main(int argc, char *argv[]) const bool addPoint = args.optionFound("points"); const bool mergeRegions = args.optionFound("mergeRegions"); + const scalar scaleFactor = args.optionLookupOrDefault<scalar>("scale", -1); + if (addPoint) { Info<< "Reading a surface and adding points from a file" @@ -117,8 +125,12 @@ int main(int argc, char *argv[]) << "Writing : " << outFileName << nl << endl; } - const triSurface surface1(inFileName1); + if (scaleFactor > 0) + { + Info<< "Scaling : " << scaleFactor << nl; + } + const triSurface surface1(inFileName1, scaleFactor); Info<< "Surface1:" << endl; surface1.writeStats(Info); Info<< endl; @@ -131,7 +143,7 @@ int main(int argc, char *argv[]) if (addPoint) { IFstream pointsFile(args["points"]); - pointField extraPoints(pointsFile); + const pointField extraPoints(pointsFile); Info<< "Additional Points:" << extraPoints.size() << endl; @@ -139,17 +151,16 @@ int main(int argc, char *argv[]) label pointi = pointsAll.size(); pointsAll.setSize(pointsAll.size() + extraPoints.size()); - forAll(extraPoints, i) + for (const auto& pt : extraPoints) { - pointsAll[pointi++] = extraPoints[i]; + pointsAll[pointi++] = pt; } combinedSurf = triSurface(surface1, surface1.patches(), pointsAll); } else { - const triSurface surface2(inFileName2); - + const triSurface surface2(inFileName2, scaleFactor); Info<< "Surface2:" << endl; surface2.writeStats(Info); Info<< endl; @@ -165,21 +176,19 @@ int main(int argc, char *argv[]) label pointi = 0; // Copy points1 into pointsAll - forAll(points1, point1i) + for (const auto& pt : points1) { - pointsAll[pointi++] = points1[point1i]; + pointsAll[pointi++] = pt; } // Add surface2 points - forAll(points2, point2i) + for (const auto& pt : points2) { - pointsAll[pointi++] = points2[point2i]; + pointsAll[pointi++] = pt; } label trianglei = 0; - - // Determine map for both regions label nNewPatches = 0; labelList patch1Map(surface1.patches().size()); @@ -192,17 +201,17 @@ int main(int argc, char *argv[]) forAll(surface1.patches(), i) { const word& name = surface1.patches()[i].name(); - HashTable<label>::iterator iter = nameToPatch.find(name); + auto iter = nameToPatch.find(name); label combinedi; - if (iter == nameToPatch.end()) + if (iter.found()) { - combinedi = nameToPatch.size(); - nameToPatch.insert(name, combinedi); + combinedi = iter.object(); } else { - combinedi = iter(); + combinedi = nameToPatch.size(); + nameToPatch.insert(name, combinedi); } patch1Map[i] = combinedi; } @@ -212,17 +221,17 @@ int main(int argc, char *argv[]) forAll(surface2.patches(), i) { const word& name = surface2.patches()[i].name(); - HashTable<label>::iterator iter = nameToPatch.find(name); + auto iter = nameToPatch.find(name); label combinedi; - if (iter == nameToPatch.end()) + if (iter.found()) { - combinedi = nameToPatch.size(); - nameToPatch.insert(name, combinedi); + combinedi = iter.object(); } else { - combinedi = iter(); + combinedi = nameToPatch.size(); + nameToPatch.insert(name, combinedi); } patch2Map[i] = combinedi; } @@ -245,11 +254,9 @@ int main(int argc, char *argv[]) } - // Copy triangles1 into trianglesAll - forAll(surface1, facei) + for (const labelledTri& tri : surface1) { - const labelledTri& tri = surface1[facei]; labelledTri& destTri = facesAll[trianglei++]; destTri.triFace::operator=(tri); @@ -257,10 +264,8 @@ int main(int argc, char *argv[]) } // Add (renumbered) surface2 triangles - forAll(surface2, facei) + for (const labelledTri& tri : surface2) { - const labelledTri& tri = surface2[facei]; - labelledTri& destTri = facesAll[trianglei++]; destTri[0] = tri[0] + points1.size(); destTri[1] = tri[1] + points1.size(); diff --git a/applications/utilities/surface/surfaceBooleanFeatures/surfaceBooleanFeatures.C b/applications/utilities/surface/surfaceBooleanFeatures/surfaceBooleanFeatures.C index 52c5d9c0895..6dca6415bff 100644 --- a/applications/utilities/surface/surfaceBooleanFeatures/surfaceBooleanFeatures.C +++ b/applications/utilities/surface/surfaceBooleanFeatures/surfaceBooleanFeatures.C @@ -1517,6 +1517,12 @@ int main(int argc, char *argv[]) argList::validArgs.append("surfaceFile1"); argList::validArgs.append("surfaceFile2"); + argList::addOption + ( + "scale", + "factor", + "Geometry scaling factor (both surfaces)" + ); argList::addBoolOption ( "surf1Baffle", @@ -1587,6 +1593,10 @@ int main(int argc, char *argv[]) } + // Scale factor for both surfaces: + const scalar scaleFactor + = args.optionLookupOrDefault<scalar>("scale", -1); + const word surf1Name(args[2]); Info<< "Reading surface " << surf1Name << endl; triSurfaceMesh surf1 @@ -1599,6 +1609,11 @@ int main(int argc, char *argv[]) runTime ) ); + if (scaleFactor > 0) + { + Info<< "Scaling : " << scaleFactor << nl; + surf1.scalePoints(scaleFactor); + } Info<< surf1Name << " statistics:" << endl; surf1.writeStats(Info); @@ -1616,6 +1631,11 @@ int main(int argc, char *argv[]) runTime ) ); + if (scaleFactor > 0) + { + Info<< "Scaling : " << scaleFactor << nl; + surf2.scalePoints(scaleFactor); + } Info<< surf2Name << " statistics:" << endl; surf2.writeStats(Info); @@ -1627,7 +1647,7 @@ int main(int argc, char *argv[]) edgeIntersections edgeCuts1; edgeIntersections edgeCuts2; - bool invertedSpace = args.optionFound("invertedSpace"); + const bool invertedSpace = args.optionFound("invertedSpace"); if (invertedSpace && validActions[action] == booleanSurface::DIFFERENCE) { @@ -1736,9 +1756,7 @@ int main(int argc, char *argv[]) const extendedFeatureEdgeMesh& feMesh = feMeshPtr(); feMesh.writeStats(Info); - feMesh.write(); - feMesh.writeObj(feMesh.path()/sFeatFileName); { diff --git a/applications/utilities/surface/surfaceClean/surfaceClean.C b/applications/utilities/surface/surfaceClean/surfaceClean.C index b11845df044..ca806edf354 100644 --- a/applications/utilities/surface/surfaceClean/surfaceClean.C +++ b/applications/utilities/surface/surfaceClean/surfaceClean.C @@ -60,7 +60,13 @@ int main(int argc, char *argv[]) argList::addBoolOption ( "noClean", - "suppress surface checking/cleanup on the input surface" + "Suppress surface checking/cleanup on the input surface" + ); + argList::addOption + ( + "scale", + "factor", + "Input geometry scaling factor" ); argList args(argc, argv); @@ -77,7 +83,12 @@ int main(int argc, char *argv[]) Info<< "Reading surface from " << inFileName << " ..." << nl << endl; - triSurface surf(inFileName); + + triSurface surf + ( + inFileName, + args.optionLookupOrDefault<scalar>("scale", -1) + ); surf.writeStats(Info); if (!args.optionFound("noClean")) @@ -90,7 +101,7 @@ int main(int argc, char *argv[]) while (true) { - label nEdgeCollapse = collapseEdge(surf, minLen); + const label nEdgeCollapse = collapseEdge(surf, minLen); if (nEdgeCollapse == 0) { @@ -99,7 +110,7 @@ int main(int argc, char *argv[]) } while (true) { - label nSplitEdge = collapseBase(surf, minLen, minQuality); + const label nSplitEdge = collapseBase(surf, minLen, minQuality); if (nSplitEdge == 0) { diff --git a/applications/utilities/surface/surfaceCoarsen/surfaceCoarsen.C b/applications/utilities/surface/surfaceCoarsen/surfaceCoarsen.C index 5be802c3f9a..8adaef8d9d0 100644 --- a/applications/utilities/surface/surfaceCoarsen/surfaceCoarsen.C +++ b/applications/utilities/surface/surfaceCoarsen/surfaceCoarsen.C @@ -28,7 +28,7 @@ Group grpSurfaceUtilities Description - Surface coarsening using `bunnylod' + Surface coarsening using 'bunnylod' Reference: \verbatim @@ -75,6 +75,13 @@ int main(int argc, char *argv[]) argList::validArgs.append("surfaceFile"); argList::validArgs.append("reductionFactor"); argList::validArgs.append("output surfaceFile"); + argList::addOption + ( + "scale", + "factor", + "input geometry scaling factor" + ); + argList args(argc, argv); const fileName inFileName = args[1]; @@ -90,40 +97,39 @@ int main(int argc, char *argv[]) << exit(FatalError); } - Info<< "Input surface :" << inFileName << endl - << "Reduction factor:" << reduction << endl - << "Output surface :" << outFileName << endl << endl; + const scalar scaleFactor = args.optionLookupOrDefault<scalar>("scale", -1); - const triSurface surf(inFileName); + Info<< "Input surface :" << inFileName << nl + << "Scaling factor :" << scaleFactor << nl + << "Reduction factor:" << reduction << nl + << "Output surface :" << outFileName << nl + << endl; + + const triSurface surf(inFileName, scaleFactor); Info<< "Surface:" << endl; surf.writeStats(Info); Info<< endl; - - ::List< ::Vector> vert; // global list of vertices - ::List< ::tridata> tri; // global list of triangles + ::List<::Vector> vert; // global list of vertices + ::List<::tridata> tri; // global list of triangles // Convert triSurface to progmesh format. Note: can use global point // numbering since surface read in from file. const pointField& pts = surf.points(); - forAll(pts, ptI) + for (const point& pt : pts) { - const point& pt = pts[ptI]; - - vert.Add( ::Vector(pt.x(), pt.y(), pt.z())); + vert.Add(::Vector(pt.x(), pt.y(), pt.z())); } - forAll(surf, facei) + for (const labelledTri& f : surf) { - const labelledTri& f = surf[facei]; - tridata td; - td.v[0]=f[0]; - td.v[1]=f[1]; - td.v[2]=f[2]; + td.v[0] = f[0]; + td.v[1] = f[1]; + td.v[2] = f[2]; tri.Add(td); } @@ -133,20 +139,20 @@ int main(int argc, char *argv[]) ::ProgressiveMesh(vert,tri,collapse_map,permutation); // rearrange the vertex list - ::List< ::Vector> temp_list; - for (int i=0;i<vert.num;i++) + ::List<::Vector> temp_list; + for (int i=0; i<vert.num; i++) { temp_list.Add(vert[i]); } - for (int i=0;i<vert.num;i++) + for (int i=0; i<vert.num; i++) { - vert[permutation[i]]=temp_list[i]; + vert[permutation[i]] = temp_list[i]; } // update the changes in the entries in the triangle list - for (int i=0;i<tri.num;i++) + for (int i=0; i<tri.num; i++) { - for (int j=0;j<3;j++) + for (int j=0; j<3; j++) { tri[i].v[j] = permutation[tri[i].v[j]]; } diff --git a/applications/utilities/surface/surfaceConvert/surfaceConvert.C b/applications/utilities/surface/surfaceConvert/surfaceConvert.C index f19127cd5e8..9337770fd89 100644 --- a/applications/utilities/surface/surfaceConvert/surfaceConvert.C +++ b/applications/utilities/surface/surfaceConvert/surfaceConvert.C @@ -74,24 +74,24 @@ int main(int argc, char *argv[]) argList::addBoolOption ( "clean", - "perform some surface checking/cleanup on the input surface" + "Perform some surface checking/cleanup on the input surface" ); argList::addBoolOption ( "group", - "reorder faces into groups; one per region" + "Reorder faces into groups; one per region" ); argList::addOption ( "scale", "factor", - "geometry scaling factor - default is 1" + "Input geometry scaling factor" ); argList::addOption ( "writePrecision", "label", - "write to output with the specified precision" + "Write to output with the specified precision" ); argList args(argc, argv); @@ -116,8 +116,10 @@ int main(int argc, char *argv[]) << exit(FatalError); } + const scalar scaleFactor = args.optionLookupOrDefault<scalar>("scale", -1); + Info<< "Reading : " << importName << endl; - triSurface surf(importName); + triSurface surf(importName, scaleFactor); Info<< "Read surface:" << endl; surf.writeStats(Info); @@ -144,13 +146,6 @@ int main(int argc, char *argv[]) } Info<< "writing " << exportName; - - scalar scaleFactor = 0; - if (args.optionReadIfPresent("scale", scaleFactor) && scaleFactor > 0) - { - Info<< " with scaling " << scaleFactor; - surf.scalePoints(scaleFactor); - } Info<< endl; surf.write(exportName, sortByRegion); diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C index 2810e084c0b..ca7cba62cc6 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C +++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C @@ -339,8 +339,15 @@ int main(int argc, char *argv[]) << " writeObj=" << writeObj << " writeVTK=" << writeVTK << nl; + scalar scaleFactor = -1; + // Allow rescaling of the surface points (eg, mm -> m) + if (surfaceDict.readIfPresent("scale", scaleFactor) && scaleFactor > 0) + { + Info<<"Scaling : " << scaleFactor << nl; + } + // Load a single file, or load and combine multiple selected files - autoPtr<triSurface> surfPtr = loader.load(loadingOption); + autoPtr<triSurface> surfPtr = loader.load(loadingOption, scaleFactor); if (!surfPtr.valid() || surfPtr().empty()) { FatalErrorInFunction diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtractDict b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtractDict index 176a0e19384..c03e80ced6f 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtractDict +++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtractDict @@ -50,6 +50,9 @@ outputName1 surfaces (surface1.stl surface2.nas); + // mm -> m scaling + // scale 0.001; + // Generate additional intersection features (none | self | region) intersectionMethod self; diff --git a/applications/utilities/surface/surfaceFind/surfaceFind.C b/applications/utilities/surface/surfaceFind/surfaceFind.C index 165eb976a01..f0dd8c39a2a 100644 --- a/applications/utilities/surface/surfaceFind/surfaceFind.C +++ b/applications/utilities/surface/surfaceFind/surfaceFind.C @@ -123,9 +123,8 @@ int main(int argc, char *argv[]) Info<< " " << points[f[fp]] << "\n"; } - Info<< endl; - - Info<< "End\n" << endl; + Info<< nl + << "End\n" << endl; return 0; } diff --git a/applications/utilities/surface/surfaceInertia/surfaceInertia.C b/applications/utilities/surface/surfaceInertia/surfaceInertia.C index fb45390688f..ce53c2ae91e 100644 --- a/applications/utilities/surface/surfaceInertia/surfaceInertia.C +++ b/applications/utilities/surface/surfaceInertia/surfaceInertia.C @@ -90,7 +90,7 @@ int main(int argc, char *argv[]) vector refPt = Zero; bool calcAroundRefPt = args.optionReadIfPresent("referencePoint", refPt); - triSurface surf(surfFileName); + const triSurface surf(surfFileName); scalar m = 0.0; vector cM = Zero; diff --git a/applications/utilities/surface/surfaceInflate/surfaceInflate.C b/applications/utilities/surface/surfaceInflate/surfaceInflate.C index 145e2b3490d..3cfdb743bed 100644 --- a/applications/utilities/surface/surfaceInflate/surfaceInflate.C +++ b/applications/utilities/surface/surfaceInflate/surfaceInflate.C @@ -44,7 +44,7 @@ Usage Specify a feature angle - E.g. inflate surface by 2cm with 1.5 safety factor: + E.g. inflate surface by 20mm with 1.5 safety factor: surfaceInflate DTC-scaled.obj 0.02 1.5 -featureAngle 45 -nSmooth 2 \*---------------------------------------------------------------------------*/ diff --git a/applications/utilities/surface/surfaceMeshInfo/surfaceMeshInfo.C b/applications/utilities/surface/surfaceMeshInfo/surfaceMeshInfo.C index bf965eee0db..6f58fe5cc3e 100644 --- a/applications/utilities/surface/surfaceMeshInfo/surfaceMeshInfo.C +++ b/applications/utilities/surface/surfaceMeshInfo/surfaceMeshInfo.C @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) ( "scale", "factor", - "geometry scaling factor - default is 1" + "input geometry scaling factor" ); argList::addBoolOption ( @@ -119,10 +119,10 @@ int main(int argc, char *argv[]) // use UnsortedMeshedSurface, not MeshedSurface to maintain ordering UnsortedMeshedSurface<face> surf(importName); - scalar scaling = 0; - if (args.optionReadIfPresent("scale", scaling) && scaling > 0) + const scalar scaling = args.optionLookupOrDefault<scalar>("scale", -1); + if (scaling > 0) { - Info<< " -scale " << scaling << endl; + Info<< " -scale " << scaling << nl; surf.scalePoints(scaling); } diff --git a/applications/utilities/surface/surfaceOrient/surfaceOrient.C b/applications/utilities/surface/surfaceOrient/surfaceOrient.C index 4dad7dd5701..fe0944a69a3 100644 --- a/applications/utilities/surface/surfaceOrient/surfaceOrient.C +++ b/applications/utilities/surface/surfaceOrient/surfaceOrient.C @@ -63,6 +63,12 @@ int main(int argc, char *argv[]) "usePierceTest", "determine orientation by counting number of intersections" ); + argList::addOption + ( + "scale", + "factor", + "input geometry scaling factor" + ); argList args(argc, argv); @@ -86,11 +92,14 @@ int main(int argc, char *argv[]) Info<< "outside" << endl; } - + const scalar scaling = args.optionLookupOrDefault<scalar>("scale", -1); + if (scaling > 0) + { + Info<< "Input scaling: " << scaling << nl; + } // Load surface - triSurface surf(surfFileName); - + triSurface surf(surfFileName, scaling); bool anyFlipped = false; @@ -118,11 +127,11 @@ int main(int argc, char *argv[]) if (anyFlipped) { - Info<< "Flipped orientation of (part of) surface." << endl; + Info<< "Flipped orientation of (part of) surface." << nl; } else { - Info<< "Did not flip orientation of any triangle of surface." << endl; + Info<< "Did not flip orientation of any triangle of surface." << nl; } Info<< "Writing new surface to " << outFileName << endl; diff --git a/applications/utilities/surface/surfacePointMerge/surfacePointMerge.C b/applications/utilities/surface/surfacePointMerge/surfacePointMerge.C index 830e861654c..ec3fe22c4ab 100644 --- a/applications/utilities/surface/surfacePointMerge/surfacePointMerge.C +++ b/applications/utilities/surface/surfacePointMerge/surfacePointMerge.C @@ -46,31 +46,47 @@ using namespace Foam; int main(int argc, char *argv[]) { + argList::addNote + ( + "Merge points on surface if they are within absolute distance [m]." + ); argList::noParallel(); argList::validArgs.append("surfaceFile"); argList::validArgs.append("merge distance"); argList::validArgs.append("output surfaceFile"); + + argList::addOption + ( + "scale", + "factor", + "input geometry scaling factor" + ); + argList args(argc, argv); const fileName surfFileName = args[1]; const scalar mergeTol = args.argRead<scalar>(2); const fileName outFileName = args[3]; - Info<< "Reading surface from " << surfFileName << " ..." << endl; - Info<< "Merging points within " << mergeTol << " metre." << endl; + const scalar scaling = args.optionLookupOrDefault<scalar>("scale", -1); - triSurface surf1(surfFileName); + Info<< "Reading surface from " << surfFileName << " ..." << nl + << "Merging points within " << mergeTol << " metre." << nl; + if (scaling > 0) + { + Info<< "input scaling " << scaling << nl; + } - Info<< "Original surface:" << endl; + const triSurface surf1(surfFileName, scaling); + Info<< "Original surface:" << nl; surf1.writeStats(Info); - triSurface cleanSurf(surf1); while (true) { - label nOldVert = cleanSurf.nPoints(); + const label nOldVert = cleanSurf.nPoints(); cleanSurf = triSurfaceTools::mergePoints(cleanSurf, mergeTol); diff --git a/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C b/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C index 219a4552090..58483493133 100644 --- a/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C +++ b/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C @@ -105,7 +105,8 @@ int main(int argc, char *argv[]) argList::addNote ( "Redistribute a triSurface. " - "The specified surface must be located in the constant/triSurface directory" + "The specified surface must be located in the constant/triSurface " + "directory" ); argList::validArgs.append("triSurfaceMesh"); diff --git a/applications/utilities/surface/surfaceTransformPoints/surfaceTransformPoints.C b/applications/utilities/surface/surfaceTransformPoints/surfaceTransformPoints.C index dcfb66f61be..36ae2631c48 100644 --- a/applications/utilities/surface/surfaceTransformPoints/surfaceTransformPoints.C +++ b/applications/utilities/surface/surfaceTransformPoints/surfaceTransformPoints.C @@ -85,9 +85,9 @@ int main(int argc, char *argv[]) argList::addOption ( "scale", - "vector", - "scale by the specified amount - eg, '(0.001 0.001 0.001)' for a " - "uniform [mm] to [m] scaling" + "scalar | vector", + "scale by the specified amount - eg, for a uniform [mm] to [m] scaling " + "use either (0.001 0.001 0.001)' or simply '0.001'" ); argList::addOption ( @@ -138,7 +138,7 @@ int main(int argc, char *argv[]) n1n2[0] /= mag(n1n2[0]); n1n2[1] /= mag(n1n2[1]); - tensor T = rotationTensor(n1n2[0], n1n2[1]); + const tensor T = rotationTensor(n1n2[0], n1n2[1]); Info<< "Rotating points by " << T << endl; @@ -151,10 +151,10 @@ int main(int argc, char *argv[]) << " pitch " << v.y() << nl << " yaw " << v.z() << nl; - // Convert to radians + // degToRad v *= pi/180.0; - quaternion R(quaternion::rotationSequence::XYZ, v); + const quaternion R(quaternion::rotationSequence::XYZ, v); Info<< "Rotating points by quaternion " << R << endl; points = transform(R, points); @@ -166,29 +166,43 @@ int main(int argc, char *argv[]) << " pitch " << v.y() << nl << " roll " << v.z() << nl; - - // Convert to radians + // degToRad v *= pi/180.0; - scalar yaw = v.x(); - scalar pitch = v.y(); - scalar roll = v.z(); - - quaternion R = quaternion(vector(0, 0, 1), yaw); - R *= quaternion(vector(0, 1, 0), pitch); - R *= quaternion(vector(1, 0, 0), roll); + const quaternion R(quaternion::rotationSequence::ZYX, v); Info<< "Rotating points by quaternion " << R << endl; points = transform(R, points); } - if (args.optionReadIfPresent("scale", v)) + if (args.optionFound("scale")) { - Info<< "Scaling points by " << v << endl; - - points.replace(vector::X, v.x()*points.component(vector::X)); - points.replace(vector::Y, v.y()*points.component(vector::Y)); - points.replace(vector::Z, v.z()*points.component(vector::Z)); + // Use readList to handle single or multiple values + const List<scalar> scaling = args.optionReadList<scalar>("scale"); + + if (scaling.size() == 1) + { + Info<< "Scaling points uniformly by " << scaling[0] << nl; + points *= scaling[0]; + } + else if (scaling.size() == 3) + { + Info<< "Scaling points by (" + << scaling[0] << " " + << scaling[1] << " " + << scaling[2] << ")" << nl; + + points.replace(vector::X, scaling[0]*points.component(vector::X)); + points.replace(vector::Y, scaling[1]*points.component(vector::Y)); + points.replace(vector::Z, scaling[2]*points.component(vector::Z)); + } + else + { + FatalError + << "-scale with 1 or 3 components only" << nl + << "given: " << args["scale"] << endl + << exit(FatalError); + } } surf1.movePoints(points); diff --git a/src/conversion/common/writer/meshWriter.H b/src/conversion/common/writer/meshWriter.H index d17322fde07..5aedb05cdfb 100644 --- a/src/conversion/common/writer/meshWriter.H +++ b/src/conversion/common/writer/meshWriter.H @@ -125,7 +125,8 @@ public: // Constructors - //- Create a writer object with given output scaling + //- Create a writer object with given output scaling. + // Treats a zero or negative scale factor as unity scaling. meshWriter ( const polyMesh&, diff --git a/src/conversion/fire/FIREMeshWriter.H b/src/conversion/fire/FIREMeshWriter.H index 7d61a0461eb..66294b068c7 100644 --- a/src/conversion/fire/FIREMeshWriter.H +++ b/src/conversion/fire/FIREMeshWriter.H @@ -97,7 +97,8 @@ public: // Constructors - //- Prepare for writing, optionally with scaling + //- Prepare for writing, optionally with scaling. + // Treats a zero or negative scale factor as unity scaling. FIREMeshWriter(const polyMesh&, const scalar scaleFactor = 1.0); diff --git a/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.C b/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.C index a653f53bae0..8390c94c74c 100644 --- a/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.C +++ b/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.C @@ -218,7 +218,8 @@ Foam::label Foam::triSurfaceLoader::select(const wordReList& matcher) Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load ( - const enum loadingOption opt + const enum loadingOption opt, + const scalar scaleFactor ) const { autoPtr<triSurface> output; @@ -229,7 +230,8 @@ Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load } else if (selected_.size() == 1) { - output.set(new triSurface(directory_/selected_[0])); + // Use scaling (if any) + output.set(new triSurface(directory_/selected_[0], scaleFactor)); triSurface& surf = output(); @@ -392,6 +394,12 @@ Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load } } + // Apply scaling (if any) + if (scaleFactor > VSMALL) + { + points *= scaleFactor; + } + output.set(new triSurface(faces, patches, points, true)); return output; diff --git a/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.H b/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.H index 7332026f765..c8a0f62493f 100644 --- a/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.H +++ b/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.H @@ -154,9 +154,12 @@ public: label select(const wordReList& matcher); //- Load a single file, or load and combine multiple selected files + // Optionally scale the surface(s) on input, with a zero or negative + // scale factor treated as no scaling. autoPtr<triSurface> load ( - const enum loadingOption opt = loadingOption::OFFSET_REGION + const enum loadingOption opt = loadingOption::OFFSET_REGION, + const scalar scaleFactor = -1 ) const; }; diff --git a/src/surfMesh/triSurface/triSurface.C b/src/surfMesh/triSurface/triSurface.C index b9958febf44..921e410593e 100644 --- a/src/surfMesh/triSurface/triSurface.C +++ b/src/surfMesh/triSurface/triSurface.C @@ -760,17 +760,19 @@ Foam::triSurface::triSurface } -Foam::triSurface::triSurface(const fileName& name) +Foam::triSurface::triSurface(const fileName& name, const scalar scaleFactor) : ParentType(List<Face>(), pointField()), patches_(), sortedEdgeFacesPtr_(nullptr), edgeOwnerPtr_(nullptr) { - word ext = name.ext(); + const word ext = name.ext(); read(name, ext); + scalePoints(scaleFactor); + setDefaultPatches(); } @@ -886,8 +888,8 @@ void Foam::triSurface::movePoints(const pointField& newPoints) void Foam::triSurface::scalePoints(const scalar scaleFactor) { - // avoid bad scaling - if (scaleFactor > 0 && scaleFactor != 1.0) + // Avoid bad scaling + if (scaleFactor > VSMALL && scaleFactor != 1.0) { // Remove all geometry dependent data clearTopology(); diff --git a/src/surfMesh/triSurface/triSurface.H b/src/surfMesh/triSurface/triSurface.H index 24f8b518378..a9ac604d56a 100644 --- a/src/surfMesh/triSurface/triSurface.H +++ b/src/surfMesh/triSurface/triSurface.H @@ -264,46 +264,55 @@ public: //- Construct from triangles, patches, points. triSurface ( - const List<labelledTri>&, - const geometricSurfacePatchList&, - const pointField& + const List<labelledTri>& triangles, + const geometricSurfacePatchList& patches, + const pointField& points ); //- Construct from triangles, patches, points. Reuse storage. triSurface ( - List<labelledTri>&, - const geometricSurfacePatchList&, - pointField&, + List<labelledTri>& triangles, + const geometricSurfacePatchList& patches, + pointField& points, const bool reuse ); //- Construct by transferring (triangles, points) components. triSurface ( - const Xfer<List<labelledTri>>&, - const geometricSurfacePatchList&, - const Xfer<List<point>>& + const Xfer<List<labelledTri>>& triangles, + const geometricSurfacePatchList& patches, + const Xfer<List<point>>& points ); //- Construct from triangles, points. Set patch names to default. - triSurface(const List<labelledTri>&, const pointField&); + triSurface + ( + const List<labelledTri>& triangles, + const pointField& points + ); //- Construct from triangles, points. Set region to 0 and default // patchName. - triSurface(const triFaceList&, const pointField&); + triSurface + ( + const triFaceList& triangles, + const pointField& points + ); - //- Construct from file name (uses extension to determine type) - triSurface(const fileName&); + //- Construct from file name (uses extension to determine type). + // Optional (positive, non-zero) point scaling is possible. + triSurface(const fileName& name, const scalar scaleFactor = -1); //- Construct from Istream - triSurface(Istream&); + triSurface(Istream& is); //- Construct from objectRegistry triSurface(const Time& d); //- Construct as copy - triSurface(const triSurface&); + triSurface(const triSurface& ts); //- Destructor @@ -382,10 +391,10 @@ public: // Edit //- Move points - virtual void movePoints(const pointField&); + virtual void movePoints(const pointField& newPoints); - //- Scale points. A non-positive factor is ignored - virtual void scalePoints(const scalar); + //- Scale points. A non-positive factor is ignored. + virtual void scalePoints(const scalar scaleFactor); //- Check/remove duplicate/degenerate triangles void checkTriangles(const bool verbose); @@ -447,13 +456,13 @@ public: // Write //- Write to Ostream in simple FOAM format - void write(Ostream&) const; + void write(Ostream& os) const; //- Generic write routine. Chooses writer based on extension. void write(const fileName&, const bool sortByRegion = false) const; //- Write to database - void write(const Time&) const; + void write(const Time& d) const; //- Write some statistics void writeStats(Ostream& os) const; -- GitLab