Commit eaebb8ee authored by Mark OLESEN's avatar Mark OLESEN
Browse files

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

Feature surface scaling

See merge request !139
parents aad962a0 c59c3af1
......@@ -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;
......
Test-surfaceMeshConvert.C
EXE = $(FOAM_APPBIN)/Test-surfaceMeshConvert
......@@ -22,17 +22,16 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
surfaceMeshConvertTesting
Test-surfaceMeshConvert
Group
grpSurfaceUtilities
Description
Converts from one surface mesh format to another, but primarily
used for testing functionality.
Test conversions from one surface mesh format to another.
Usage
\b surfaceMeshConvertTesting inputFile outputFile [OPTION]
\b Test-surfaceMeshConvert inputFile outputFile [OPTION]
Options:
- \par -clean
......
......@@ -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))
{
......
......@@ -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
......
......@@ -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();
......
......@@ -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);
{
......
......@@ -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)
{
......
......@@ -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]];
}
......
<
......@@ -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
(