Merge branch 'feature-surface-scaling' into 'develop'

Feature surface scaling

See merge request !139
This commit is contained in:
Mark Olesen
2017-09-12 08:36:12 +01:00
32 changed files with 328 additions and 181 deletions

View File

@ -41,10 +41,15 @@ using namespace Foam;
autoPtr<triSurface> loadSurface autoPtr<triSurface> loadSurface
( (
const Foam::Time& runTime, 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 = const fileName fallback =
runTime.constantPath()/triSurfaceMesh::meshSubDir/surfName; runTime.constantPath()/triSurfaceMesh::meshSubDir/surfName;
@ -52,11 +57,11 @@ autoPtr<triSurface> loadSurface
autoPtr<triSurface> surfPtr; autoPtr<triSurface> surfPtr;
if (isFile(surfName)) if (isFile(surfName))
{ {
surfPtr.set(new triSurface(surfName)); surfPtr.set(new triSurface(surfName, scaleFactor));
} }
else if (isFile(fallback)) else if (isFile(fallback))
{ {
surfPtr.set(new triSurface(fallback)); surfPtr.set(new triSurface(fallback, scaleFactor));
} }
else else
{ {
@ -102,6 +107,12 @@ int main(int argc, char *argv[])
"mergeTol", "mergeTol",
"merge points (and edges) using the specified tolerance" "merge points (and edges) using the specified tolerance"
); );
argList::addOption
(
"scale",
"factor",
"geometry scaling factor"
);
#include "addDictOption.H" #include "addDictOption.H"
@ -117,16 +128,18 @@ int main(int argc, char *argv[])
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
const scalar scaleFactor = args.optionLookupOrDefault<scalar>("scale", -1);
const word outputFile(args.executable() + ".obj"); const word outputFile(args.executable() + ".obj");
const fileName surf1Name(args[1]); const fileName surf1Name(args[1]);
triSurface surf1 = loadSurface(runTime, surf1Name)(); triSurface surf1 = loadSurface(runTime, surf1Name, scaleFactor)();
Info<< surf1Name << " statistics:" << endl; Info<< surf1Name << " statistics:" << endl;
surf1.writeStats(Info); surf1.writeStats(Info);
Info<< endl; Info<< endl;
const fileName surf2Name(args[2]); const fileName surf2Name(args[2]);
triSurface surf2 = loadSurface(runTime, surf2Name)(); triSurface surf2 = loadSurface(runTime, surf2Name, scaleFactor)();
Info<< surf2Name << " statistics:" << endl; Info<< surf2Name << " statistics:" << endl;
surf2.writeStats(Info); surf2.writeStats(Info);
Info<< endl; Info<< endl;

View File

@ -0,0 +1,3 @@
Test-surfaceMeshConvert.C
EXE = $(FOAM_APPBIN)/Test-surfaceMeshConvert

View File

@ -22,17 +22,16 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application Application
surfaceMeshConvertTesting Test-surfaceMeshConvert
Group Group
grpSurfaceUtilities grpSurfaceUtilities
Description Description
Converts from one surface mesh format to another, but primarily Test conversions from one surface mesh format to another.
used for testing functionality.
Usage Usage
\b surfaceMeshConvertTesting inputFile outputFile [OPTION] \b Test-surfaceMeshConvert inputFile outputFile [OPTION]
Options: Options:
- \par -clean - \par -clean

View File

@ -91,7 +91,7 @@ int main(int argc, char *argv[])
// ~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~
fileFormats::FIREMeshWriter::binary = !args.optionFound("ascii"); fileFormats::FIREMeshWriter::binary = !args.optionFound("ascii");
// default: rescale from [m] to [mm] // Default: no rescaling
scalar scaleFactor = 1; scalar scaleFactor = 1;
if (args.optionReadIfPresent("scale", scaleFactor)) if (args.optionReadIfPresent("scale", scaleFactor))
{ {

View File

@ -43,8 +43,8 @@ Usage
or -yawPitchRoll (yawdegrees pitchdegrees rolldegrees) or -yawPitchRoll (yawdegrees pitchdegrees rolldegrees)
or -rollPitchYaw (rolldegrees pitchdegrees yawdegrees) or -rollPitchYaw (rolldegrees pitchdegrees yawdegrees)
-scale vector -scale scalar|vector
Scales the points by the given vector. Scales the points by the given scalar or vector.
The any or all of the three options may be specified and are processed The any or all of the three options may be specified and are processed
in the above order. in the above order.
@ -182,9 +182,9 @@ int main(int argc, char *argv[])
argList::addOption argList::addOption
( (
"scale", "scale",
"vector", "scalar | vector",
"scale by the specified amount - eg, '(0.001 0.001 0.001)' for a " "scale by the specified amount - eg, for a uniform [mm] to [m] scaling "
"uniform [mm] to [m] scaling" "use either (0.001 0.001 0.001)' or simply '0.001'"
); );
#include "addRegionOption.H" #include "addRegionOption.H"
@ -262,10 +262,10 @@ int main(int argc, char *argv[])
<< " pitch " << v.y() << nl << " pitch " << v.y() << nl
<< " yaw " << v.z() << nl; << " yaw " << v.z() << nl;
// Convert to radians // degToRad
v *= pi/180.0; v *= pi/180.0;
quaternion R(quaternion::rotationSequence::XYZ, v); const quaternion R(quaternion::rotationSequence::XYZ, v);
Info<< "Rotating points by quaternion " << R << endl; Info<< "Rotating points by quaternion " << R << endl;
points = transform(R, points); points = transform(R, points);
@ -282,16 +282,10 @@ int main(int argc, char *argv[])
<< " pitch " << v.y() << nl << " pitch " << v.y() << nl
<< " roll " << v.z() << nl; << " roll " << v.z() << nl;
// Convert to radians // degToRad
v *= pi/180.0; v *= pi/180.0;
scalar yaw = v.x(); const quaternion R(quaternion::rotationSequence::ZYX, v);
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);
Info<< "Rotating points by quaternion " << R << endl; Info<< "Rotating points by quaternion " << R << endl;
points = transform(R, points); 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)); if (scaling.size() == 1)
points.replace(vector::Y, v.y()*points.component(vector::Y)); {
points.replace(vector::Z, v.z()*points.component(vector::Z)); 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 // Set the precision of the points data to 10

View File

@ -71,6 +71,12 @@ int main(int argc, char *argv[])
"mergeRegions", "mergeRegions",
"combine regions from both surfaces" "combine regions from both surfaces"
); );
argList::addOption
(
"scale",
"factor",
"geometry scaling factor on input surfaces"
);
argList args(argc, argv); argList args(argc, argv);
@ -81,6 +87,8 @@ int main(int argc, char *argv[])
const bool addPoint = args.optionFound("points"); const bool addPoint = args.optionFound("points");
const bool mergeRegions = args.optionFound("mergeRegions"); const bool mergeRegions = args.optionFound("mergeRegions");
const scalar scaleFactor = args.optionLookupOrDefault<scalar>("scale", -1);
if (addPoint) if (addPoint)
{ {
Info<< "Reading a surface and adding points from a file" Info<< "Reading a surface and adding points from a file"
@ -117,8 +125,12 @@ int main(int argc, char *argv[])
<< "Writing : " << outFileName << nl << endl; << "Writing : " << outFileName << nl << endl;
} }
const triSurface surface1(inFileName1); if (scaleFactor > 0)
{
Info<< "Scaling : " << scaleFactor << nl;
}
const triSurface surface1(inFileName1, scaleFactor);
Info<< "Surface1:" << endl; Info<< "Surface1:" << endl;
surface1.writeStats(Info); surface1.writeStats(Info);
Info<< endl; Info<< endl;
@ -131,7 +143,7 @@ int main(int argc, char *argv[])
if (addPoint) if (addPoint)
{ {
IFstream pointsFile(args["points"]); IFstream pointsFile(args["points"]);
pointField extraPoints(pointsFile); const pointField extraPoints(pointsFile);
Info<< "Additional Points:" << extraPoints.size() << endl; Info<< "Additional Points:" << extraPoints.size() << endl;
@ -139,17 +151,16 @@ int main(int argc, char *argv[])
label pointi = pointsAll.size(); label pointi = pointsAll.size();
pointsAll.setSize(pointsAll.size() + extraPoints.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); combinedSurf = triSurface(surface1, surface1.patches(), pointsAll);
} }
else else
{ {
const triSurface surface2(inFileName2); const triSurface surface2(inFileName2, scaleFactor);
Info<< "Surface2:" << endl; Info<< "Surface2:" << endl;
surface2.writeStats(Info); surface2.writeStats(Info);
Info<< endl; Info<< endl;
@ -165,21 +176,19 @@ int main(int argc, char *argv[])
label pointi = 0; label pointi = 0;
// Copy points1 into pointsAll // Copy points1 into pointsAll
forAll(points1, point1i) for (const auto& pt : points1)
{ {
pointsAll[pointi++] = points1[point1i]; pointsAll[pointi++] = pt;
} }
// Add surface2 points // Add surface2 points
forAll(points2, point2i) for (const auto& pt : points2)
{ {
pointsAll[pointi++] = points2[point2i]; pointsAll[pointi++] = pt;
} }
label trianglei = 0; label trianglei = 0;
// Determine map for both regions // Determine map for both regions
label nNewPatches = 0; label nNewPatches = 0;
labelList patch1Map(surface1.patches().size()); labelList patch1Map(surface1.patches().size());
@ -192,17 +201,17 @@ int main(int argc, char *argv[])
forAll(surface1.patches(), i) forAll(surface1.patches(), i)
{ {
const word& name = surface1.patches()[i].name(); const word& name = surface1.patches()[i].name();
HashTable<label>::iterator iter = nameToPatch.find(name); auto iter = nameToPatch.find(name);
label combinedi; label combinedi;
if (iter == nameToPatch.end()) if (iter.found())
{ {
combinedi = nameToPatch.size(); combinedi = iter.object();
nameToPatch.insert(name, combinedi);
} }
else else
{ {
combinedi = iter(); combinedi = nameToPatch.size();
nameToPatch.insert(name, combinedi);
} }
patch1Map[i] = combinedi; patch1Map[i] = combinedi;
} }
@ -212,17 +221,17 @@ int main(int argc, char *argv[])
forAll(surface2.patches(), i) forAll(surface2.patches(), i)
{ {
const word& name = surface2.patches()[i].name(); const word& name = surface2.patches()[i].name();
HashTable<label>::iterator iter = nameToPatch.find(name); auto iter = nameToPatch.find(name);
label combinedi; label combinedi;
if (iter == nameToPatch.end()) if (iter.found())
{ {
combinedi = nameToPatch.size(); combinedi = iter.object();
nameToPatch.insert(name, combinedi);
} }
else else
{ {
combinedi = iter(); combinedi = nameToPatch.size();
nameToPatch.insert(name, combinedi);
} }
patch2Map[i] = combinedi; patch2Map[i] = combinedi;
} }
@ -245,11 +254,9 @@ int main(int argc, char *argv[])
} }
// Copy triangles1 into trianglesAll // Copy triangles1 into trianglesAll
forAll(surface1, facei) for (const labelledTri& tri : surface1)
{ {
const labelledTri& tri = surface1[facei];
labelledTri& destTri = facesAll[trianglei++]; labelledTri& destTri = facesAll[trianglei++];
destTri.triFace::operator=(tri); destTri.triFace::operator=(tri);
@ -257,10 +264,8 @@ int main(int argc, char *argv[])
} }
// Add (renumbered) surface2 triangles // Add (renumbered) surface2 triangles
forAll(surface2, facei) for (const labelledTri& tri : surface2)
{ {
const labelledTri& tri = surface2[facei];
labelledTri& destTri = facesAll[trianglei++]; labelledTri& destTri = facesAll[trianglei++];
destTri[0] = tri[0] + points1.size(); destTri[0] = tri[0] + points1.size();
destTri[1] = tri[1] + points1.size(); destTri[1] = tri[1] + points1.size();

View File

@ -1517,6 +1517,12 @@ int main(int argc, char *argv[])
argList::validArgs.append("surfaceFile1"); argList::validArgs.append("surfaceFile1");
argList::validArgs.append("surfaceFile2"); argList::validArgs.append("surfaceFile2");
argList::addOption
(
"scale",
"factor",
"Geometry scaling factor (both surfaces)"
);
argList::addBoolOption argList::addBoolOption
( (
"surf1Baffle", "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]); const word surf1Name(args[2]);
Info<< "Reading surface " << surf1Name << endl; Info<< "Reading surface " << surf1Name << endl;
triSurfaceMesh surf1 triSurfaceMesh surf1
@ -1599,6 +1609,11 @@ int main(int argc, char *argv[])
runTime runTime
) )
); );
if (scaleFactor > 0)
{
Info<< "Scaling : " << scaleFactor << nl;
surf1.scalePoints(scaleFactor);
}
Info<< surf1Name << " statistics:" << endl; Info<< surf1Name << " statistics:" << endl;
surf1.writeStats(Info); surf1.writeStats(Info);
@ -1616,6 +1631,11 @@ int main(int argc, char *argv[])
runTime runTime
) )
); );
if (scaleFactor > 0)
{
Info<< "Scaling : " << scaleFactor << nl;
surf2.scalePoints(scaleFactor);
}
Info<< surf2Name << " statistics:" << endl; Info<< surf2Name << " statistics:" << endl;
surf2.writeStats(Info); surf2.writeStats(Info);
@ -1627,7 +1647,7 @@ int main(int argc, char *argv[])
edgeIntersections edgeCuts1; edgeIntersections edgeCuts1;
edgeIntersections edgeCuts2; edgeIntersections edgeCuts2;
bool invertedSpace = args.optionFound("invertedSpace"); const bool invertedSpace = args.optionFound("invertedSpace");
if (invertedSpace && validActions[action] == booleanSurface::DIFFERENCE) if (invertedSpace && validActions[action] == booleanSurface::DIFFERENCE)
{ {
@ -1736,9 +1756,7 @@ int main(int argc, char *argv[])
const extendedFeatureEdgeMesh& feMesh = feMeshPtr(); const extendedFeatureEdgeMesh& feMesh = feMeshPtr();
feMesh.writeStats(Info); feMesh.writeStats(Info);
feMesh.write(); feMesh.write();
feMesh.writeObj(feMesh.path()/sFeatFileName); feMesh.writeObj(feMesh.path()/sFeatFileName);
{ {

View File

@ -60,7 +60,13 @@ int main(int argc, char *argv[])
argList::addBoolOption argList::addBoolOption
( (
"noClean", "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); argList args(argc, argv);
@ -77,7 +83,12 @@ int main(int argc, char *argv[])
Info<< "Reading surface from " << inFileName << " ..." << nl << endl; Info<< "Reading surface from " << inFileName << " ..." << nl << endl;
triSurface surf(inFileName);
triSurface surf
(
inFileName,
args.optionLookupOrDefault<scalar>("scale", -1)
);
surf.writeStats(Info); surf.writeStats(Info);
if (!args.optionFound("noClean")) if (!args.optionFound("noClean"))
@ -90,7 +101,7 @@ int main(int argc, char *argv[])
while (true) while (true)
{ {
label nEdgeCollapse = collapseEdge(surf, minLen); const label nEdgeCollapse = collapseEdge(surf, minLen);
if (nEdgeCollapse == 0) if (nEdgeCollapse == 0)
{ {
@ -99,7 +110,7 @@ int main(int argc, char *argv[])
} }
while (true) while (true)
{ {
label nSplitEdge = collapseBase(surf, minLen, minQuality); const label nSplitEdge = collapseBase(surf, minLen, minQuality);
if (nSplitEdge == 0) if (nSplitEdge == 0)
{ {

View File

@ -28,7 +28,7 @@ Group
grpSurfaceUtilities grpSurfaceUtilities
Description Description
Surface coarsening using `bunnylod' Surface coarsening using 'bunnylod'
Reference: Reference:
\verbatim \verbatim
@ -75,6 +75,13 @@ int main(int argc, char *argv[])
argList::validArgs.append("surfaceFile"); argList::validArgs.append("surfaceFile");
argList::validArgs.append("reductionFactor"); argList::validArgs.append("reductionFactor");
argList::validArgs.append("output surfaceFile"); argList::validArgs.append("output surfaceFile");
argList::addOption
(
"scale",
"factor",
"input geometry scaling factor"
);
argList args(argc, argv); argList args(argc, argv);
const fileName inFileName = args[1]; const fileName inFileName = args[1];
@ -90,40 +97,39 @@ int main(int argc, char *argv[])
<< exit(FatalError); << exit(FatalError);
} }
Info<< "Input surface :" << inFileName << endl const scalar scaleFactor = args.optionLookupOrDefault<scalar>("scale", -1);
<< "Reduction factor:" << reduction << endl
<< "Output surface :" << outFileName << endl << endl;
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; Info<< "Surface:" << endl;
surf.writeStats(Info); surf.writeStats(Info);
Info<< endl; Info<< endl;
::List<::Vector> vert; // global list of vertices
::List< ::Vector> vert; // global list of vertices ::List<::tridata> tri; // global list of triangles
::List< ::tridata> tri; // global list of triangles
// Convert triSurface to progmesh format. Note: can use global point // Convert triSurface to progmesh format. Note: can use global point
// numbering since surface read in from file. // numbering since surface read in from file.
const pointField& pts = surf.points(); 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; tridata td;
td.v[0]=f[0]; td.v[0] = f[0];
td.v[1]=f[1]; td.v[1] = f[1];
td.v[2]=f[2]; td.v[2] = f[2];
tri.Add(td); tri.Add(td);
} }
@ -133,20 +139,20 @@ int main(int argc, char *argv[])
::ProgressiveMesh(vert,tri,collapse_map,permutation); ::ProgressiveMesh(vert,tri,collapse_map,permutation);
// rearrange the vertex list // rearrange the vertex list
::List< ::Vector> temp_list; ::List<::Vector> temp_list;
for (int i=0;i<vert.num;i++) for (int i=0; i<vert.num; i++)
{ {
temp_list.Add(vert[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 // 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]]; tri[i].v[j] = permutation[tri[i].v[j]];
} }

View File

@ -74,24 +74,24 @@ int main(int argc, char *argv[])
argList::addBoolOption argList::addBoolOption
( (
"clean", "clean",
"perform some surface checking/cleanup on the input surface" "Perform some surface checking/cleanup on the input surface"
); );
argList::addBoolOption argList::addBoolOption
( (
"group", "group",
"reorder faces into groups; one per region" "Reorder faces into groups; one per region"
); );
argList::addOption argList::addOption
( (
"scale", "scale",
"factor", "factor",
"geometry scaling factor - default is 1" "Input geometry scaling factor"
); );
argList::addOption argList::addOption
( (
"writePrecision", "writePrecision",
"label", "label",
"write to output with the specified precision" "Write to output with the specified precision"
); );
argList args(argc, argv); argList args(argc, argv);
@ -116,8 +116,10 @@ int main(int argc, char *argv[])
<< exit(FatalError); << exit(FatalError);
} }
const scalar scaleFactor = args.optionLookupOrDefault<scalar>("scale", -1);
Info<< "Reading : " << importName << endl; Info<< "Reading : " << importName << endl;
triSurface surf(importName); triSurface surf(importName, scaleFactor);
Info<< "Read surface:" << endl; Info<< "Read surface:" << endl;
surf.writeStats(Info); surf.writeStats(Info);
@ -144,13 +146,6 @@ int main(int argc, char *argv[])
} }
Info<< "writing " << exportName; Info<< "writing " << exportName;
scalar scaleFactor = 0;
if (args.optionReadIfPresent("scale", scaleFactor) && scaleFactor > 0)
{
Info<< " with scaling " << scaleFactor;
surf.scalePoints(scaleFactor);
}
Info<< endl; Info<< endl;
surf.write(exportName, sortByRegion); surf.write(exportName, sortByRegion);

View File

@ -339,8 +339,15 @@ int main(int argc, char *argv[])
<< " writeObj=" << writeObj << " writeObj=" << writeObj
<< " writeVTK=" << writeVTK << nl; << " 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 // 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()) if (!surfPtr.valid() || surfPtr().empty())
{ {
FatalErrorInFunction FatalErrorInFunction

View File

@ -50,6 +50,9 @@ outputName1
surfaces (surface1.stl surface2.nas); surfaces (surface1.stl surface2.nas);
// mm -> m scaling
// scale 0.001;
// Generate additional intersection features (none | self | region) // Generate additional intersection features (none | self | region)
intersectionMethod self; intersectionMethod self;

View File

@ -123,9 +123,8 @@ int main(int argc, char *argv[])
Info<< " " << points[f[fp]] << "\n"; Info<< " " << points[f[fp]] << "\n";
} }
Info<< endl; Info<< nl
<< "End\n" << endl;
Info<< "End\n" << endl;
return 0; return 0;
} }

View File

@ -90,7 +90,7 @@ int main(int argc, char *argv[])
vector refPt = Zero; vector refPt = Zero;
bool calcAroundRefPt = args.optionReadIfPresent("referencePoint", refPt); bool calcAroundRefPt = args.optionReadIfPresent("referencePoint", refPt);
triSurface surf(surfFileName); const triSurface surf(surfFileName);
scalar m = 0.0; scalar m = 0.0;
vector cM = Zero; vector cM = Zero;

View File

@ -44,7 +44,7 @@ Usage
Specify a feature angle 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 surfaceInflate DTC-scaled.obj 0.02 1.5 -featureAngle 45 -nSmooth 2
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/

View File

@ -1,3 +0,0 @@
surfaceMeshConvertTesting.C
EXE = $(FOAM_APPBIN)/surfaceMeshConvertTesting

View File

@ -87,7 +87,7 @@ int main(int argc, char *argv[])
( (
"scale", "scale",
"factor", "factor",
"geometry scaling factor - default is 1" "input geometry scaling factor"
); );
argList::addBoolOption argList::addBoolOption
( (
@ -119,10 +119,10 @@ int main(int argc, char *argv[])
// use UnsortedMeshedSurface, not MeshedSurface to maintain ordering // use UnsortedMeshedSurface, not MeshedSurface to maintain ordering
UnsortedMeshedSurface<face> surf(importName); UnsortedMeshedSurface<face> surf(importName);
scalar scaling = 0; const scalar scaling = args.optionLookupOrDefault<scalar>("scale", -1);
if (args.optionReadIfPresent("scale", scaling) && scaling > 0) if (scaling > 0)
{ {
Info<< " -scale " << scaling << endl; Info<< " -scale " << scaling << nl;
surf.scalePoints(scaling); surf.scalePoints(scaling);
} }

View File

@ -63,6 +63,12 @@ int main(int argc, char *argv[])
"usePierceTest", "usePierceTest",
"determine orientation by counting number of intersections" "determine orientation by counting number of intersections"
); );
argList::addOption
(
"scale",
"factor",
"input geometry scaling factor"
);
argList args(argc, argv); argList args(argc, argv);
@ -86,11 +92,14 @@ int main(int argc, char *argv[])
Info<< "outside" << endl; Info<< "outside" << endl;
} }
const scalar scaling = args.optionLookupOrDefault<scalar>("scale", -1);
if (scaling > 0)
{
Info<< "Input scaling: " << scaling << nl;
}
// Load surface // Load surface
triSurface surf(surfFileName); triSurface surf(surfFileName, scaling);
bool anyFlipped = false; bool anyFlipped = false;
@ -118,11 +127,11 @@ int main(int argc, char *argv[])
if (anyFlipped) if (anyFlipped)
{ {
Info<< "Flipped orientation of (part of) surface." << endl; Info<< "Flipped orientation of (part of) surface." << nl;
} }
else 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; Info<< "Writing new surface to " << outFileName << endl;

View File

@ -46,31 +46,47 @@ using namespace Foam;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
argList::addNote
(
"Merge points on surface if they are within absolute distance [m]."
);
argList::noParallel(); argList::noParallel();
argList::validArgs.append("surfaceFile"); argList::validArgs.append("surfaceFile");
argList::validArgs.append("merge distance"); argList::validArgs.append("merge distance");
argList::validArgs.append("output surfaceFile"); argList::validArgs.append("output surfaceFile");
argList::addOption
(
"scale",
"factor",
"input geometry scaling factor"
);
argList args(argc, argv); argList args(argc, argv);
const fileName surfFileName = args[1]; const fileName surfFileName = args[1];
const scalar mergeTol = args.argRead<scalar>(2); const scalar mergeTol = args.argRead<scalar>(2);
const fileName outFileName = args[3]; const fileName outFileName = args[3];
Info<< "Reading surface from " << surfFileName << " ..." << endl; const scalar scaling = args.optionLookupOrDefault<scalar>("scale", -1);
Info<< "Merging points within " << mergeTol << " metre." << endl;
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); surf1.writeStats(Info);
triSurface cleanSurf(surf1); triSurface cleanSurf(surf1);
while (true) while (true)
{ {
label nOldVert = cleanSurf.nPoints(); const label nOldVert = cleanSurf.nPoints();
cleanSurf = triSurfaceTools::mergePoints(cleanSurf, mergeTol); cleanSurf = triSurfaceTools::mergePoints(cleanSurf, mergeTol);

View File

@ -105,7 +105,8 @@ int main(int argc, char *argv[])
argList::addNote argList::addNote
( (
"Redistribute a triSurface. " "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"); argList::validArgs.append("triSurfaceMesh");

View File

@ -85,9 +85,9 @@ int main(int argc, char *argv[])
argList::addOption argList::addOption
( (
"scale", "scale",
"vector", "scalar | vector",
"scale by the specified amount - eg, '(0.001 0.001 0.001)' for a " "scale by the specified amount - eg, for a uniform [mm] to [m] scaling "
"uniform [mm] to [m] scaling" "use either (0.001 0.001 0.001)' or simply '0.001'"
); );
argList::addOption argList::addOption
( (
@ -138,7 +138,7 @@ int main(int argc, char *argv[])
n1n2[0] /= mag(n1n2[0]); n1n2[0] /= mag(n1n2[0]);
n1n2[1] /= mag(n1n2[1]); 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; Info<< "Rotating points by " << T << endl;
@ -151,10 +151,10 @@ int main(int argc, char *argv[])
<< " pitch " << v.y() << nl << " pitch " << v.y() << nl
<< " yaw " << v.z() << nl; << " yaw " << v.z() << nl;
// Convert to radians // degToRad
v *= pi/180.0; v *= pi/180.0;
quaternion R(quaternion::rotationSequence::XYZ, v); const quaternion R(quaternion::rotationSequence::XYZ, v);
Info<< "Rotating points by quaternion " << R << endl; Info<< "Rotating points by quaternion " << R << endl;
points = transform(R, points); points = transform(R, points);
@ -166,29 +166,43 @@ int main(int argc, char *argv[])
<< " pitch " << v.y() << nl << " pitch " << v.y() << nl
<< " roll " << v.z() << nl; << " roll " << v.z() << nl;
// degToRad
// Convert to radians
v *= pi/180.0; v *= pi/180.0;
scalar yaw = v.x(); const quaternion R(quaternion::rotationSequence::ZYX, v);
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);
Info<< "Rotating points by quaternion " << R << endl; Info<< "Rotating points by quaternion " << R << endl;
points = transform(R, points); points = transform(R, points);
} }
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)); if (scaling.size() == 1)
points.replace(vector::Y, v.y()*points.component(vector::Y)); {
points.replace(vector::Z, v.z()*points.component(vector::Z)); 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); surf1.movePoints(points);

View File

@ -224,7 +224,6 @@ _of_complete_cache_[surfaceInertia]="-case -density -referencePoint | -noFunctio
_of_complete_cache_[surfaceInflate]="-case -featureAngle -nSmooth | -checkSelfIntersection -debug -noFunctionObjects -srcDoc -doc -help" _of_complete_cache_[surfaceInflate]="-case -featureAngle -nSmooth | -checkSelfIntersection -debug -noFunctionObjects -srcDoc -doc -help"
_of_complete_cache_[surfaceLambdaMuSmooth]="-featureFile | -srcDoc -doc -help" _of_complete_cache_[surfaceLambdaMuSmooth]="-featureFile | -srcDoc -doc -help"
_of_complete_cache_[surfaceMeshConvert]="-case -dict -from -scaleIn -scaleOut -to | -clean -noFunctionObjects -tri -srcDoc -doc -help" _of_complete_cache_[surfaceMeshConvert]="-case -dict -from -scaleIn -scaleOut -to | -clean -noFunctionObjects -tri -srcDoc -doc -help"
_of_complete_cache_[surfaceMeshConvertTesting]="-case -scale | -clean -noFunctionObjects -orient -stdout -surfMesh -testModify -triFace -triSurface -unsorted -srcDoc -doc -help"
_of_complete_cache_[surfaceMeshExport]="-case -dict -from -name -scaleIn -scaleOut -to | -clean -noFunctionObjects -srcDoc -doc -help" _of_complete_cache_[surfaceMeshExport]="-case -dict -from -name -scaleIn -scaleOut -to | -clean -noFunctionObjects -srcDoc -doc -help"
_of_complete_cache_[surfaceMeshImport]="-case -dict -from -name -scaleIn -scaleOut -to | -clean -noFunctionObjects -srcDoc -doc -help" _of_complete_cache_[surfaceMeshImport]="-case -dict -from -name -scaleIn -scaleOut -to | -clean -noFunctionObjects -srcDoc -doc -help"
_of_complete_cache_[surfaceMeshInfo]="-case -scale | -areas -noFunctionObjects -xml -srcDoc -doc -help" _of_complete_cache_[surfaceMeshInfo]="-case -scale | -areas -noFunctionObjects -xml -srcDoc -doc -help"

View File

@ -125,7 +125,8 @@ public:
// Constructors // 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 meshWriter
( (
const polyMesh&, const polyMesh&,

View File

@ -97,7 +97,8 @@ public:
// Constructors // 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); FIREMeshWriter(const polyMesh&, const scalar scaleFactor = 1.0);

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -435,7 +435,14 @@ Foam::surfaceToCell::surfaceToCell
), ),
nearDist_(readScalar(dict.lookup("nearDistance"))), nearDist_(readScalar(dict.lookup("nearDistance"))),
curvature_(readScalar(dict.lookup("curvature"))), curvature_(readScalar(dict.lookup("curvature"))),
surfPtr_(new triSurface(surfName_)), surfPtr_
(
new triSurface
(
surfName_,
dict.lookupOrDefault<scalar>("scale", -1)
)
),
querySurfPtr_(new triSurfaceSearch(*surfPtr_)), querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
IOwnPtrs_(true) IOwnPtrs_(true)
{ {

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -59,7 +59,7 @@ void Foam::surfaceToPoint::combine(topoSet& set, const bool add) const
{ {
cpuTime timer; cpuTime timer;
triSurface surf(surfName_); triSurface surf(surfName_, scale_);
Info<< " Read surface from " << surfName_ Info<< " Read surface from " << surfName_
<< " in = "<< timer.cpuTimeIncrement() << " s" << endl << endl; << " in = "<< timer.cpuTimeIncrement() << " s" << endl << endl;
@ -131,6 +131,7 @@ Foam::surfaceToPoint::surfaceToPoint
: :
topoSetSource(mesh), topoSetSource(mesh),
surfName_(surfName), surfName_(surfName),
scale_(1.0),
nearDist_(nearDist), nearDist_(nearDist),
includeInside_(includeInside), includeInside_(includeInside),
includeOutside_(includeOutside) includeOutside_(includeOutside)
@ -147,6 +148,7 @@ Foam::surfaceToPoint::surfaceToPoint
: :
topoSetSource(mesh), topoSetSource(mesh),
surfName_(fileName(dict.lookup("file")).expand()), surfName_(fileName(dict.lookup("file")).expand()),
scale_(dict.lookupOrDefault<scalar>("scale", 1.0)),
nearDist_(readScalar(dict.lookup("nearDistance"))), nearDist_(readScalar(dict.lookup("nearDistance"))),
includeInside_(readBool(dict.lookup("includeInside"))), includeInside_(readBool(dict.lookup("includeInside"))),
includeOutside_(readBool(dict.lookup("includeOutside"))) includeOutside_(readBool(dict.lookup("includeOutside")))
@ -163,6 +165,7 @@ Foam::surfaceToPoint::surfaceToPoint
: :
topoSetSource(mesh), topoSetSource(mesh),
surfName_(checkIs(is)), surfName_(checkIs(is)),
scale_(1.0),
nearDist_(readScalar(checkIs(is))), nearDist_(readScalar(checkIs(is))),
includeInside_(readBool(checkIs(is))), includeInside_(readBool(checkIs(is))),
includeOutside_(readBool(checkIs(is))) includeOutside_(readBool(checkIs(is)))

View File

@ -67,6 +67,9 @@ class surfaceToPoint
//- Name of surface file //- Name of surface file
const fileName surfName_; const fileName surfName_;
//- Optional scaling for surface
const scalar scale_;
//- If > 0 : include points with distance to surface less than nearDist. //- If > 0 : include points with distance to surface less than nearDist.
const scalar nearDist_; const scalar nearDist_;

View File

@ -218,7 +218,8 @@ Foam::label Foam::triSurfaceLoader::select(const wordReList& matcher)
Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load
( (
const enum loadingOption opt const enum loadingOption opt,
const scalar scaleFactor
) const ) const
{ {
autoPtr<triSurface> output; autoPtr<triSurface> output;
@ -229,7 +230,8 @@ Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load
} }
else if (selected_.size() == 1) 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(); 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)); output.set(new triSurface(faces, patches, points, true));
return output; return output;

View File

@ -154,9 +154,12 @@ public:
label select(const wordReList& matcher); label select(const wordReList& matcher);
//- Load a single file, or load and combine multiple selected files //- 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 autoPtr<triSurface> load
( (
const enum loadingOption opt = loadingOption::OFFSET_REGION const enum loadingOption opt = loadingOption::OFFSET_REGION,
const scalar scaleFactor = -1
) const; ) const;
}; };

View File

@ -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()), ParentType(List<Face>(), pointField()),
patches_(), patches_(),
sortedEdgeFacesPtr_(nullptr), sortedEdgeFacesPtr_(nullptr),
edgeOwnerPtr_(nullptr) edgeOwnerPtr_(nullptr)
{ {
word ext = name.ext(); const word ext = name.ext();
read(name, ext); read(name, ext);
scalePoints(scaleFactor);
setDefaultPatches(); setDefaultPatches();
} }
@ -886,8 +888,8 @@ void Foam::triSurface::movePoints(const pointField& newPoints)
void Foam::triSurface::scalePoints(const scalar scaleFactor) void Foam::triSurface::scalePoints(const scalar scaleFactor)
{ {
// avoid bad scaling // Avoid bad scaling
if (scaleFactor > 0 && scaleFactor != 1.0) if (scaleFactor > VSMALL && scaleFactor != 1.0)
{ {
// Remove all geometry dependent data // Remove all geometry dependent data
clearTopology(); clearTopology();

View File

@ -264,46 +264,55 @@ public:
//- Construct from triangles, patches, points. //- Construct from triangles, patches, points.
triSurface triSurface
( (
const List<labelledTri>&, const List<labelledTri>& triangles,
const geometricSurfacePatchList&, const geometricSurfacePatchList& patches,
const pointField& const pointField& points
); );
//- Construct from triangles, patches, points. Reuse storage. //- Construct from triangles, patches, points. Reuse storage.
triSurface triSurface
( (
List<labelledTri>&, List<labelledTri>& triangles,
const geometricSurfacePatchList&, const geometricSurfacePatchList& patches,
pointField&, pointField& points,
const bool reuse const bool reuse
); );
//- Construct by transferring (triangles, points) components. //- Construct by transferring (triangles, points) components.
triSurface triSurface
( (
const Xfer<List<labelledTri>>&, const Xfer<List<labelledTri>>& triangles,
const geometricSurfacePatchList&, const geometricSurfacePatchList& patches,
const Xfer<List<point>>& const Xfer<List<point>>& points
); );
//- Construct from triangles, points. Set patch names to default. //- 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 //- Construct from triangles, points. Set region to 0 and default
// patchName. // patchName.
triSurface(const triFaceList&, const pointField&); triSurface
(
const triFaceList& triangles,
const pointField& points
);
//- Construct from file name (uses extension to determine type) //- Construct from file name (uses extension to determine type).
triSurface(const fileName&); // Optional (positive, non-zero) point scaling is possible.
triSurface(const fileName& name, const scalar scaleFactor = -1);
//- Construct from Istream //- Construct from Istream
triSurface(Istream&); triSurface(Istream& is);
//- Construct from objectRegistry //- Construct from objectRegistry
triSurface(const Time& d); triSurface(const Time& d);
//- Construct as copy //- Construct as copy
triSurface(const triSurface&); triSurface(const triSurface& ts);
//- Destructor //- Destructor
@ -382,10 +391,10 @@ public:
// Edit // Edit
//- Move points //- Move points
virtual void movePoints(const pointField&); virtual void movePoints(const pointField& newPoints);
//- Scale points. A non-positive factor is ignored //- Scale points. A non-positive factor is ignored.
virtual void scalePoints(const scalar); virtual void scalePoints(const scalar scaleFactor);
//- Check/remove duplicate/degenerate triangles //- Check/remove duplicate/degenerate triangles
void checkTriangles(const bool verbose); void checkTriangles(const bool verbose);
@ -447,13 +456,13 @@ public:
// Write // Write
//- Write to Ostream in simple FOAM format //- Write to Ostream in simple FOAM format
void write(Ostream&) const; void write(Ostream& os) const;
//- Generic write routine. Chooses writer based on extension. //- Generic write routine. Chooses writer based on extension.
void write(const fileName&, const bool sortByRegion = false) const; void write(const fileName&, const bool sortByRegion = false) const;
//- Write to database //- Write to database
void write(const Time&) const; void write(const Time& d) const;
//- Write some statistics //- Write some statistics
void writeStats(Ostream& os) const; void writeStats(Ostream& os) const;