mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improvements for surfaceIntersection (issue #450)
- adjust for updates in 'develop'
- change surfaceIntersection constructor to take a dictionary of
options.
tolerance | Edge-length tolerance | scalar | 1e-3
allowEdgeHits | Edge-end cuts another edge | bool | true
avoidDuplicates | Reduce the number of duplicate points | bool | true
warnDegenerate | Number of warnings about degenerate edges | label | 0
This commit is contained in:
3
applications/test/surfaceIntersection/Make/files
Normal file
3
applications/test/surfaceIntersection/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Test-surfaceIntersection.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/Test-surfaceIntersection
|
||||||
9
applications/test/surfaceIntersection/Make/options
Normal file
9
applications/test/surfaceIntersection/Make/options
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
-I$(LIB_SRC)/triSurface/lnInclude
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-lfiniteVolume \
|
||||||
|
-lmeshTools -ledgeMesh
|
||||||
234
applications/test/surfaceIntersection/Test-surfaceIntersection.C
Normal file
234
applications/test/surfaceIntersection/Test-surfaceIntersection.C
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Application
|
||||||
|
Test-surfaceIntersection
|
||||||
|
|
||||||
|
Description
|
||||||
|
Test surface-surface intersection
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "argList.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "triSurface.H"
|
||||||
|
#include "triSurfaceMesh.H"
|
||||||
|
#include "surfaceIntersection.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
autoPtr<triSurface> loadSurface
|
||||||
|
(
|
||||||
|
const Foam::Time& runTime,
|
||||||
|
const fileName& surfName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Reading surface " << surfName << endl;
|
||||||
|
|
||||||
|
const fileName fallback =
|
||||||
|
runTime.constantPath()/triSurfaceMesh::meshSubDir/surfName;
|
||||||
|
|
||||||
|
autoPtr<triSurface> surfPtr;
|
||||||
|
if (isFile(surfName))
|
||||||
|
{
|
||||||
|
surfPtr.set(new triSurface(surfName));
|
||||||
|
}
|
||||||
|
else if (isFile(fallback))
|
||||||
|
{
|
||||||
|
surfPtr.set(new triSurface(fallback));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "No such file:" << surfName << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return surfPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
argList::addNote
|
||||||
|
(
|
||||||
|
"Intersection of two surfaces. Writes obj file"
|
||||||
|
);
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"debug2",
|
||||||
|
"set surfaceIntersection debug=2"
|
||||||
|
);
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"debug4",
|
||||||
|
"set surfaceIntersection debug=4"
|
||||||
|
);
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"print",
|
||||||
|
"print information about cuts, etc"
|
||||||
|
);
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"mergeEdges",
|
||||||
|
"merge duplicate edges"
|
||||||
|
);
|
||||||
|
argList::addOption
|
||||||
|
(
|
||||||
|
"mergePoints",
|
||||||
|
"mergeTol",
|
||||||
|
"merge points (and edges) using the specified tolerance"
|
||||||
|
);
|
||||||
|
|
||||||
|
#include "addDictOption.H"
|
||||||
|
|
||||||
|
argList::addNote
|
||||||
|
(
|
||||||
|
"test intersect of two surfaces. Writes obj file"
|
||||||
|
);
|
||||||
|
argList::noParallel();
|
||||||
|
argList::noFunctionObjects();
|
||||||
|
argList::validArgs.append("surface file");
|
||||||
|
argList::validArgs.append("surface file");
|
||||||
|
|
||||||
|
#include "setRootCase.H"
|
||||||
|
#include "createTime.H"
|
||||||
|
|
||||||
|
const word outputFile(args.executable() + ".obj");
|
||||||
|
|
||||||
|
const fileName surf1Name(args[1]);
|
||||||
|
triSurface surf1 = loadSurface(runTime, surf1Name)();
|
||||||
|
Info<< surf1Name << " statistics:" << endl;
|
||||||
|
surf1.writeStats(Info);
|
||||||
|
Info<< endl;
|
||||||
|
|
||||||
|
const fileName surf2Name(args[2]);
|
||||||
|
triSurface surf2 = loadSurface(runTime, surf2Name)();
|
||||||
|
Info<< surf2Name << " statistics:" << endl;
|
||||||
|
surf2.writeStats(Info);
|
||||||
|
Info<< endl;
|
||||||
|
|
||||||
|
|
||||||
|
if (args.optionFound("debug2"))
|
||||||
|
{
|
||||||
|
surfaceIntersection::debug |= 2;
|
||||||
|
}
|
||||||
|
if (args.optionFound("debug4"))
|
||||||
|
{
|
||||||
|
surfaceIntersection::debug |= 4;
|
||||||
|
}
|
||||||
|
const bool optPrint = args.optionFound("print");
|
||||||
|
|
||||||
|
dictionary intersectOptions;
|
||||||
|
if (args.optionFound("dict"))
|
||||||
|
{
|
||||||
|
intersectOptions = IOdictionary
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
args["dict"],
|
||||||
|
runTime,
|
||||||
|
IOobject::MUST_READ_IF_MODIFIED,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
intersectOptions.writeEntry("intersectOptions", Info);
|
||||||
|
Info<< endl;
|
||||||
|
|
||||||
|
triSurfaceSearch query1(surf1);
|
||||||
|
triSurfaceSearch query2(surf2);
|
||||||
|
surfaceIntersection cuts(query1, query2, intersectOptions);
|
||||||
|
|
||||||
|
Info<<"intersection "
|
||||||
|
<< cuts.cutPoints().size() << " points "
|
||||||
|
<< cuts.cutEdges().size() << " edges" << nl;
|
||||||
|
|
||||||
|
if (optPrint)
|
||||||
|
{
|
||||||
|
Info<< "surf1-cuts: " << cuts.surf1EdgeCuts() << nl
|
||||||
|
<< "surf2-cuts: " << cuts.surf2EdgeCuts() << nl
|
||||||
|
<< "face-pairs: " << cuts.facePairToEdge() << nl
|
||||||
|
<< "edges: " << cuts.cutEdges() << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
word mergeOp;
|
||||||
|
if (args.optionFound("mergePoints"))
|
||||||
|
{
|
||||||
|
cuts.mergePoints(args.optionRead<scalar>("mergePoints"));
|
||||||
|
mergeOp = "mergePoints";
|
||||||
|
}
|
||||||
|
else if (args.optionFound("mergeEdges"))
|
||||||
|
{
|
||||||
|
cuts.mergeEdges();
|
||||||
|
mergeOp = "mergeEdges";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mergeOp.empty())
|
||||||
|
{
|
||||||
|
Info<< mergeOp << ": "
|
||||||
|
<< cuts.cutPoints().size() << " points "
|
||||||
|
<< cuts.cutEdges().size() << " edges" << nl;
|
||||||
|
|
||||||
|
if (optPrint)
|
||||||
|
{
|
||||||
|
Info<< "surf1-cuts: " << cuts.surf1EdgeCuts() << nl
|
||||||
|
<< "surf2-cuts: " << cuts.surf2EdgeCuts() << nl
|
||||||
|
<< "face-pairs: " << cuts.facePairToEdge() << nl
|
||||||
|
<< "edges: " << cuts.cutEdges() << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pointField& points = cuts.cutPoints();
|
||||||
|
const edgeList& edges = cuts.cutEdges();
|
||||||
|
|
||||||
|
if (points.size() || edges.size())
|
||||||
|
{
|
||||||
|
Info<<"write to " << outputFile << nl;
|
||||||
|
|
||||||
|
OFstream os(outputFile);
|
||||||
|
|
||||||
|
forAll(points, pointi)
|
||||||
|
{
|
||||||
|
const point& pt = points[pointi];
|
||||||
|
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(edges, edgei)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgei];
|
||||||
|
os << "l " << e.start()+1 << ' ' << e.end()+1 << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
7
applications/utilities/surface/surfaceFeatureExtract/Allwclean
Executable file
7
applications/utilities/surface/surfaceFeatureExtract/Allwclean
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd ${0%/*} || exit 1 # Run from this directory
|
||||||
|
|
||||||
|
wclean libso extractionMethod
|
||||||
|
wclean .
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
9
applications/utilities/surface/surfaceFeatureExtract/Allwmake
Executable file
9
applications/utilities/surface/surfaceFeatureExtract/Allwmake
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd ${0%/*} || exit 1 # Run from this directory
|
||||||
|
|
||||||
|
# Parse arguments for library compilation
|
||||||
|
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
|
||||||
|
|
||||||
|
(wmake libso extractionMethod && wmake)
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
@ -1,6 +1,7 @@
|
|||||||
method = .
|
method = .
|
||||||
$(method)/surfaceFeaturesExtraction.C
|
$(method)/surfaceFeaturesExtraction.C
|
||||||
$(method)/extractFromSurface.C
|
|
||||||
$(method)/extractFromFile.C
|
$(method)/extractFromFile.C
|
||||||
|
$(method)/extractFromNone.C
|
||||||
|
$(method)/extractFromSurface.C
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libsurfaceFeatureExtract
|
LIB = $(FOAM_LIBBIN)/libsurfaceFeatureExtract
|
||||||
|
|||||||
@ -24,7 +24,6 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "extractFromFile.H"
|
#include "extractFromFile.H"
|
||||||
#include "ListOps.H"
|
|
||||||
#include "edgeMesh.H"
|
#include "edgeMesh.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,81 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "extractFromNone.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace surfaceFeaturesExtraction
|
||||||
|
{
|
||||||
|
addNamedToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
method,
|
||||||
|
extractFromNone,
|
||||||
|
dictionary,
|
||||||
|
none
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::surfaceFeaturesExtraction::extractFromNone::extractFromNone
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
method()
|
||||||
|
{
|
||||||
|
const dictionary& coeffDict = dict.subOrEmptyDict("extractFromNoneCoeffs");
|
||||||
|
|
||||||
|
coeffDict.readIfPresent("includedAngle", includedAngle_);
|
||||||
|
coeffDict.readIfPresent("geometricTestOnly", geometricTestOnly_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::surfaceFeaturesExtraction::extractFromNone::~extractFromNone()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::surfaceFeatures>
|
||||||
|
Foam::surfaceFeaturesExtraction::extractFromNone::features
|
||||||
|
(
|
||||||
|
const triSurface& surf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return autoPtr<surfaceFeatures>(new surfaceFeatures(surf));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::surfaceFeaturesExtraction::extractFromNone
|
||||||
|
|
||||||
|
Description
|
||||||
|
Run-time selectable surface feature extraction.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
extractionMethod.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef surfaceFeaturesExtraction_extractFromNone_H
|
||||||
|
#define surfaceFeaturesExtraction_extractFromNone_H
|
||||||
|
|
||||||
|
#include "surfaceFeaturesExtraction.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "Switch.H"
|
||||||
|
#include "triSurface.H"
|
||||||
|
#include "edgeIntersections.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace surfaceFeaturesExtraction
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class surfaceFeaturesExtraction::extractFromNone Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class extractFromNone
|
||||||
|
:
|
||||||
|
public method
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary
|
||||||
|
extractFromNone(const dictionary& dict);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~extractFromNone();
|
||||||
|
|
||||||
|
|
||||||
|
//- Extracted features from surface (no-op)
|
||||||
|
virtual autoPtr<surfaceFeatures> features
|
||||||
|
(
|
||||||
|
const triSurface& surf
|
||||||
|
) const override;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace surfaceFeaturesExtraction
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -26,12 +26,6 @@ License
|
|||||||
#include "extractFromSurface.H"
|
#include "extractFromSurface.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
#include "triSurface.H"
|
|
||||||
#include "triSurfaceSearch.H"
|
|
||||||
#include "scalarField.H"
|
|
||||||
#include "edgeIntersections.H"
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
|
|||||||
@ -56,10 +56,6 @@ class extractFromSurface
|
|||||||
:
|
:
|
||||||
public method
|
public method
|
||||||
{
|
{
|
||||||
|
|
||||||
bool selfIntersection_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|||||||
@ -29,12 +29,17 @@ Group
|
|||||||
|
|
||||||
Description
|
Description
|
||||||
Extracts and writes surface features to file. All but the basic feature
|
Extracts and writes surface features to file. All but the basic feature
|
||||||
extraction is WIP.
|
extraction is a work-in-progress.
|
||||||
|
|
||||||
Curvature calculation is an implementation of the algorithm from:
|
The curvature calculation is an implementation of the algorithm from:
|
||||||
|
\verbatim
|
||||||
"Estimating Curvatures and their Derivatives on Triangle Meshes"
|
"Estimating Curvatures and their Derivatives on Triangle Meshes"
|
||||||
by S. Rusinkiewicz
|
by S. Rusinkiewicz
|
||||||
|
3DPVT'04 Proceedings of the 3D Data Processing,
|
||||||
|
Visualization, and Transmission, 2nd International Symposium
|
||||||
|
Pages 486-493
|
||||||
|
http://gfx.cs.princeton.edu/pubs/_2004_ECA/curvpaper.pdf
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -60,6 +65,7 @@ Description
|
|||||||
#include "point.H"
|
#include "point.H"
|
||||||
#include "triadField.H"
|
#include "triadField.H"
|
||||||
#include "transform.H"
|
#include "transform.H"
|
||||||
|
#include "triSurfaceLoader.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -367,23 +373,6 @@ triSurfacePointScalarField calcCurvature
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool edgesConnected(const edge& e1, const edge& e2)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
e1.start() == e2.start()
|
|
||||||
|| e1.start() == e2.end()
|
|
||||||
|| e1.end() == e2.start()
|
|
||||||
|| e1.end() == e2.end()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
scalar calcProximityOfFeaturePoints
|
scalar calcProximityOfFeaturePoints
|
||||||
(
|
(
|
||||||
const List<pointIndexHit>& hitList,
|
const List<pointIndexHit>& hitList,
|
||||||
@ -462,7 +451,7 @@ scalar calcProximityOfFeatureEdges
|
|||||||
const edge& e2 = efem.edges()[pHit2.index()];
|
const edge& e2 = efem.edges()[pHit2.index()];
|
||||||
|
|
||||||
// Don't refine if the edges are connected to each other
|
// Don't refine if the edges are connected to each other
|
||||||
if (!edgesConnected(e1, e2))
|
if (!e1.connects(e2))
|
||||||
{
|
{
|
||||||
scalar curDist =
|
scalar curDist =
|
||||||
mag(pHit1.hitPoint() - pHit2.hitPoint());
|
mag(pHit1.hitPoint() - pHit2.hitPoint());
|
||||||
@ -480,25 +469,12 @@ scalar calcProximityOfFeatureEdges
|
|||||||
|
|
||||||
void dumpBox(const treeBoundBox& bb, const fileName& fName)
|
void dumpBox(const treeBoundBox& bb, const fileName& fName)
|
||||||
{
|
{
|
||||||
OFstream str(fName);
|
OFstream os(fName);
|
||||||
|
|
||||||
Info<< "Dumping bounding box " << bb << " as lines to obj file "
|
Info<< "Dumping bounding box " << bb << " as lines to obj file "
|
||||||
<< str.name() << endl;
|
<< os.name() << endl;
|
||||||
|
|
||||||
|
meshTools::writeOBJ(os, bb);
|
||||||
pointField boxPoints(bb.points());
|
|
||||||
|
|
||||||
forAll(boxPoints, i)
|
|
||||||
{
|
|
||||||
meshTools::writeOBJ(str, boxPoints[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(treeBoundBox::edges, i)
|
|
||||||
{
|
|
||||||
const edge& e = treeBoundBox::edges[i];
|
|
||||||
|
|
||||||
str<< "l " << e[0]+1 << ' ' << e[1]+1 << nl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -866,62 +842,6 @@ void writeStats(const extendedFeatureEdgeMesh& fem, Ostream& os)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read and combine all surfaces into a single one
|
|
||||||
|
|
||||||
autoPtr<triSurface> loadSurfaces(Time& runTime, const wordList& surfNames)
|
|
||||||
{
|
|
||||||
List<labelledTri> faces;
|
|
||||||
pointField points;
|
|
||||||
label regoff = 0; // region offset
|
|
||||||
|
|
||||||
forAll(surfNames, surfi)
|
|
||||||
{
|
|
||||||
const word& surfName = surfNames[surfi];
|
|
||||||
|
|
||||||
triSurface addsurf(runTime.constantPath()/"triSurface"/surfName);
|
|
||||||
|
|
||||||
List<labelledTri> addfaces(addsurf.xferFaces());
|
|
||||||
List<point> addpoints(addsurf.xferPoints());
|
|
||||||
|
|
||||||
if (surfi)
|
|
||||||
{
|
|
||||||
const label ptoff = points.size(); // point offset
|
|
||||||
|
|
||||||
forAll(addfaces, facei)
|
|
||||||
{
|
|
||||||
labelledTri& f = addfaces[facei];
|
|
||||||
forAll(f, fi)
|
|
||||||
{
|
|
||||||
f[fi] += ptoff;
|
|
||||||
}
|
|
||||||
f.region() += regoff;
|
|
||||||
}
|
|
||||||
|
|
||||||
faces.append(addfaces);
|
|
||||||
points.append(addpoints);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
faces.transfer(addfaces);
|
|
||||||
points.transfer(addpoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
regoff += addsurf.patches().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<triSurface>
|
|
||||||
(
|
|
||||||
new triSurface
|
|
||||||
(
|
|
||||||
faces,
|
|
||||||
geometricSurfacePatchList(),
|
|
||||||
points,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
argList::addNote
|
argList::addNote
|
||||||
@ -939,25 +859,15 @@ int main(int argc, char *argv[])
|
|||||||
const word dictName("surfaceFeatureExtractDict");
|
const word dictName("surfaceFeatureExtractDict");
|
||||||
#include "setSystemRunTimeDictionaryIO.H"
|
#include "setSystemRunTimeDictionaryIO.H"
|
||||||
|
|
||||||
// Will be using triSurface, so filter according to what is supported
|
|
||||||
fileNameList validSurfaceFiles = readDir
|
|
||||||
(
|
|
||||||
runTime.path()/runTime.constant()/"triSurface",
|
|
||||||
fileName::FILE
|
|
||||||
);
|
|
||||||
inplaceSubsetList
|
|
||||||
(
|
|
||||||
validSurfaceFiles,
|
|
||||||
[](const fileName& f){ return triSurface::canRead(f); }
|
|
||||||
);
|
|
||||||
|
|
||||||
// sort and eliminate duplicates (eg, files with/without .gz)
|
|
||||||
inplaceUniqueSort(validSurfaceFiles);
|
|
||||||
|
|
||||||
Info<< "Reading " << dictName << nl << endl;
|
Info<< "Reading " << dictName << nl << endl;
|
||||||
|
|
||||||
const IOdictionary dict(dictIO);
|
const IOdictionary dict(dictIO);
|
||||||
|
|
||||||
|
// Loader for available triSurface surface files
|
||||||
|
triSurfaceLoader loader(runTime);
|
||||||
|
|
||||||
|
// Where to write VTK output files
|
||||||
|
const fileName vtkOutputDir = runTime.constantPath()/"triSurface";
|
||||||
|
|
||||||
forAllConstIter(dictionary, dict, iter)
|
forAllConstIter(dictionary, dict, iter)
|
||||||
{
|
{
|
||||||
if (!iter().isDict())
|
if (!iter().isDict())
|
||||||
@ -972,115 +882,88 @@ int main(int argc, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
autoPtr<surfaceFeaturesExtraction::method> extractPtr =
|
autoPtr<surfaceFeaturesExtraction::method> extractor =
|
||||||
surfaceFeaturesExtraction::method::New
|
surfaceFeaturesExtraction::method::New
|
||||||
(
|
(
|
||||||
surfaceDict
|
surfaceDict
|
||||||
);
|
);
|
||||||
|
|
||||||
const surfaceFeaturesExtraction::method& extract = extractPtr();
|
// The output name, cleansed of extensions
|
||||||
|
// Optional "output" entry, or the dictionary name.
|
||||||
// Output name, cleansed of extensions
|
const word outputName =
|
||||||
const word sFeatFileName =
|
|
||||||
fileName
|
fileName
|
||||||
(
|
(
|
||||||
surfaceDict.lookupOrDefault<word>("output", iter().keyword())
|
surfaceDict.lookupOrDefault<word>("output", iter().keyword())
|
||||||
).lessExt();
|
).lessExt();
|
||||||
|
|
||||||
wordList surfFileNames;
|
// The "surfaces" entry is normally optional, but if the sub-dictionary
|
||||||
|
// is itself called "surfaces", then this becomes mandatory.
|
||||||
|
// This provides a simple means of handling both situations without an
|
||||||
|
// additional switch.
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
iter().keyword() == "surfaces" // mandatory
|
iter().keyword() == "surfaces" // mandatory
|
||||||
|| surfaceDict.found("surfaces") // or optional
|
|| surfaceDict.found("surfaces") // or optional
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
wordReList regexs(surfaceDict.lookup("surfaces"));
|
loader.select(wordReList(surfaceDict.lookup("surfaces")));
|
||||||
|
|
||||||
labelList selected = findStrings(regexs, validSurfaceFiles);
|
|
||||||
surfFileNames.setSize(selected.size());
|
|
||||||
forAll(selected, i)
|
|
||||||
{
|
|
||||||
surfFileNames[i] = validSurfaceFiles[selected[i]].name();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surfFileNames.empty())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "No surfaces specified/found for entry: "
|
|
||||||
<< iter().keyword()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
surfFileNames.setSize(1);
|
loader.select(iter().keyword());
|
||||||
surfFileNames[0] = iter().keyword();
|
|
||||||
|
|
||||||
const fileName file
|
|
||||||
(
|
|
||||||
runTime.constantPath()/"triSurface"/surfFileNames[0]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isFile(file))
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "No surface: " << file.name()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DebugVar(surfFileNames);
|
if (loader.selected().empty())
|
||||||
// DebugVar(sFeatFileName);
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "No surfaces specified/found for entry: "
|
||||||
|
<< iter().keyword() << exit(FatalError);
|
||||||
|
}
|
||||||
|
// DebugVar(loader.available());
|
||||||
|
// DebugVar(outputName);
|
||||||
|
|
||||||
|
|
||||||
Info<< "Surfaces : ";
|
Info<< "Surfaces : ";
|
||||||
if (surfFileNames.size() == 1)
|
if (loader.selected().size() == 1)
|
||||||
{
|
{
|
||||||
Info<< surfFileNames[0] << nl;
|
Info<< loader.selected()[0] << nl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Info<< flatOutput(surfFileNames) << nl;
|
Info<< flatOutput(loader.selected()) << nl;
|
||||||
|
}
|
||||||
|
Info<< "Output : " << outputName << nl;
|
||||||
|
|
||||||
|
// Load a single file, or load and combine multiple selected files
|
||||||
|
autoPtr<triSurface> surfPtr = loader.load();
|
||||||
|
if (!surfPtr.valid() || surfPtr().empty())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Problem loading surface(s) for entry: "
|
||||||
|
<< iter().keyword() << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Output : " << sFeatFileName << nl;
|
triSurface surf = surfPtr();
|
||||||
|
|
||||||
const Switch writeVTK = surfaceDict.lookupOrDefault<Switch>
|
const Switch writeVTK = surfaceDict.lookupOrDefault<Switch>
|
||||||
(
|
(
|
||||||
"writeVTK", Switch::OFF
|
"writeVTK",
|
||||||
|
Switch::OFF
|
||||||
);
|
);
|
||||||
const Switch writeObj = surfaceDict.lookupOrDefault<Switch>
|
const Switch writeObj = surfaceDict.lookupOrDefault<Switch>
|
||||||
(
|
(
|
||||||
"writeObj", Switch::OFF
|
"writeObj",
|
||||||
);
|
Switch::OFF
|
||||||
|
|
||||||
const Switch curvature = surfaceDict.lookupOrDefault<Switch>
|
|
||||||
(
|
|
||||||
"curvature", Switch::OFF
|
|
||||||
);
|
|
||||||
const Switch featureProximity = surfaceDict.lookupOrDefault<Switch>
|
|
||||||
(
|
|
||||||
"featureProximity", Switch::OFF
|
|
||||||
);
|
|
||||||
const Switch closeness = surfaceDict.lookupOrDefault<Switch>
|
|
||||||
(
|
|
||||||
"closeness", Switch::OFF
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "write VTK: " << writeVTK << nl;
|
Info<< "write VTK: " << writeVTK << nl;
|
||||||
|
|
||||||
Info<< nl << "Feature line extraction is only valid on closed manifold "
|
Info<< "Feature line extraction is only valid on closed manifold "
|
||||||
<< "surfaces." << endl;
|
<< "surfaces." << nl;
|
||||||
|
|
||||||
|
Info<< nl << "Statistics:" << nl;
|
||||||
// Read and combine all surfaces into a single one
|
|
||||||
|
|
||||||
autoPtr<triSurface> surfPtr = loadSurfaces(runTime, surfFileNames);
|
|
||||||
triSurface surf = surfPtr();
|
|
||||||
|
|
||||||
Info<< "Statistics:" << endl;
|
|
||||||
surf.writeStats(Info);
|
surf.writeStats(Info);
|
||||||
Info<< endl;
|
Info<< nl;
|
||||||
|
|
||||||
// need plain faces if outputting VTK format
|
// need plain faces if outputting VTK format
|
||||||
faceList faces;
|
faceList faces;
|
||||||
@ -1097,19 +980,19 @@ int main(int argc, char *argv[])
|
|||||||
// Either construct features from surface & featureAngle or read set.
|
// Either construct features from surface & featureAngle or read set.
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
autoPtr<surfaceFeatures> set = extract.features(surf);
|
autoPtr<surfaceFeatures> features = extractor().features(surf);
|
||||||
|
|
||||||
// Trim set
|
// Trim set
|
||||||
// ~~~~~~~~
|
// ~~~~~~~~
|
||||||
|
|
||||||
if (surfaceDict.isDict("trimFeatures"))
|
if (surfaceDict.isDict("trimFeatures"))
|
||||||
{
|
{
|
||||||
dictionary trimDict = surfaceDict.subDict("trimFeatures");
|
const dictionary& trimDict = surfaceDict.subDict("trimFeatures");
|
||||||
const scalar minLen =
|
|
||||||
trimDict.lookupOrAddDefault<scalar>("minLen", -GREAT);
|
|
||||||
|
|
||||||
|
const scalar minLen =
|
||||||
|
trimDict.lookupOrDefault<scalar>("minLen", 0);
|
||||||
const label minElem =
|
const label minElem =
|
||||||
trimDict.lookupOrAddDefault<label>("minElem", 0);
|
trimDict.lookupOrDefault<label>("minElem", 0);
|
||||||
|
|
||||||
// Trim away small groups of features
|
// Trim away small groups of features
|
||||||
if (minLen > 0 || minElem > 0)
|
if (minLen > 0 || minElem > 0)
|
||||||
@ -1125,7 +1008,10 @@ int main(int argc, char *argv[])
|
|||||||
<< minElem << endl;
|
<< minElem << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
set().trimFeatures(minLen, minElem, extract.includedAngle());
|
features().trimFeatures
|
||||||
|
(
|
||||||
|
minLen, minElem, extractor().includedAngle()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1134,8 +1020,9 @@ int main(int argc, char *argv[])
|
|||||||
// ~~~~~~
|
// ~~~~~~
|
||||||
|
|
||||||
// Convert to marked edges, points
|
// Convert to marked edges, points
|
||||||
List<surfaceFeatures::edgeStatus> edgeStat(set().toStatus());
|
List<surfaceFeatures::edgeStatus> edgeStat(features().toStatus());
|
||||||
|
|
||||||
|
// Option: "subsetFeatures" (dictionary)
|
||||||
if (surfaceDict.isDict("subsetFeatures"))
|
if (surfaceDict.isDict("subsetFeatures"))
|
||||||
{
|
{
|
||||||
const dictionary& subsetDict = surfaceDict.subDict
|
const dictionary& subsetDict = surfaceDict.subDict
|
||||||
@ -1143,6 +1030,7 @@ int main(int argc, char *argv[])
|
|||||||
"subsetFeatures"
|
"subsetFeatures"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Suboption: "insideBox"
|
||||||
if (subsetDict.found("insideBox"))
|
if (subsetDict.found("insideBox"))
|
||||||
{
|
{
|
||||||
treeBoundBox bb(subsetDict.lookup("insideBox")());
|
treeBoundBox bb(subsetDict.lookup("insideBox")());
|
||||||
@ -1152,6 +1040,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
deleteBox(surf, bb, false, edgeStat);
|
deleteBox(surf, bb, false, edgeStat);
|
||||||
}
|
}
|
||||||
|
// Suboption: "outsideBox"
|
||||||
else if (subsetDict.found("outsideBox"))
|
else if (subsetDict.found("outsideBox"))
|
||||||
{
|
{
|
||||||
treeBoundBox bb(subsetDict.lookup("outsideBox")());
|
treeBoundBox bb(subsetDict.lookup("outsideBox")());
|
||||||
@ -1186,17 +1075,15 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
surf,
|
surf,
|
||||||
1e-5, //tol,
|
1e-5, //tol,
|
||||||
extract.includedAngle(),
|
extractor().includedAngle(),
|
||||||
edgeI
|
edgeI
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Switch openEdges =
|
// Suboption: "openEdges" (false: remove open edges)
|
||||||
subsetDict.lookupOrDefault<Switch>("openEdges", "yes");
|
if (!subsetDict.lookupOrDefault<bool>("openEdges", true))
|
||||||
|
|
||||||
if (!openEdges)
|
|
||||||
{
|
{
|
||||||
Info<< "Removing all open edges"
|
Info<< "Removing all open edges"
|
||||||
<< " (edges with 1 connected face)" << endl;
|
<< " (edges with 1 connected face)" << endl;
|
||||||
@ -1210,6 +1097,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Suboption: "plane"
|
||||||
if (subsetDict.found("plane"))
|
if (subsetDict.found("plane"))
|
||||||
{
|
{
|
||||||
plane cutPlane(subsetDict.lookup("plane")());
|
plane cutPlane(subsetDict.lookup("plane")());
|
||||||
@ -1225,7 +1113,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
surfaceFeatures newSet(surf);
|
surfaceFeatures newSet(surf);
|
||||||
newSet.setFromStatus(edgeStat, extract.includedAngle());
|
newSet.setFromStatus(edgeStat, extractor().includedAngle());
|
||||||
|
|
||||||
Info<< nl
|
Info<< nl
|
||||||
<< "Initial feature set:" << nl
|
<< "Initial feature set:" << nl
|
||||||
@ -1263,7 +1151,7 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
newSet,
|
newSet,
|
||||||
runTime,
|
runTime,
|
||||||
sFeatFileName + ".extendedFeatureEdgeMesh",
|
outputName + ".extendedFeatureEdgeMesh",
|
||||||
surfBaffleRegions
|
surfBaffleRegions
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1292,40 +1180,41 @@ int main(int argc, char *argv[])
|
|||||||
feMesh.add(addFeMesh);
|
feMesh.add(addFeMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (surfaceDict.lookupOrDefault<bool>("selfIntersection", false))
|
if (surfaceDict.lookupOrDefault<bool>("selfIntersection", false))
|
||||||
{
|
{
|
||||||
// TODO: perturb tolerance
|
// TODO: perturbance tolerance?
|
||||||
|
|
||||||
triSurfaceSearch query(surf);
|
triSurfaceSearch query(surf);
|
||||||
surfaceIntersection intersect
|
surfaceIntersection intersect(query, surfaceDict);
|
||||||
|
|
||||||
|
intersect.mergePoints(5*SMALL);
|
||||||
|
|
||||||
|
labelPair sizeInfo
|
||||||
(
|
(
|
||||||
query,
|
intersect.cutPoints().size(),
|
||||||
surfaceDict.lookupOrDefault<scalar>
|
intersect.cutEdges().size()
|
||||||
(
|
|
||||||
"planarTolerance",
|
|
||||||
surfaceIntersection::defaultTolerance
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// surf.write("selfIntersection-input.obj");
|
|
||||||
|
|
||||||
Info<<"self-intersection "
|
|
||||||
<< intersect.cutEdges().size() << " edges "
|
|
||||||
<< intersect.cutPoints().size() << " points" << nl;
|
|
||||||
|
|
||||||
if (intersect.cutEdges().size())
|
if (intersect.cutEdges().size())
|
||||||
{
|
{
|
||||||
extendedEdgeMesh addMesh
|
extendedEdgeMesh addMesh
|
||||||
(
|
(
|
||||||
xferCopy<pointField>(intersect.cutPoints()),
|
intersect.cutPoints(),
|
||||||
xferCopy<edgeList>(intersect.cutEdges())
|
intersect.cutEdges()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
addMesh.mergePoints(5*SMALL);
|
||||||
feMesh.add(addMesh);
|
feMesh.add(addMesh);
|
||||||
|
|
||||||
|
sizeInfo[0] = addMesh.points().size();
|
||||||
|
sizeInfo[1] = addMesh.edges().size();
|
||||||
}
|
}
|
||||||
|
Info<< "Self intersection:" << nl
|
||||||
|
<< " points : " << sizeInfo[0] << nl
|
||||||
|
<< " edges : " << sizeInfo[1] << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Info<< nl
|
Info<< nl
|
||||||
<< "Final feature set:" << nl;
|
<< "Final feature set:" << nl;
|
||||||
writeStats(feMesh, Info);
|
writeStats(feMesh, Info);
|
||||||
@ -1337,111 +1226,47 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (writeObj)
|
if (writeObj)
|
||||||
{
|
{
|
||||||
feMesh.writeObj(feMesh.path()/sFeatFileName);
|
feMesh.writeObj(feMesh.path()/outputName);
|
||||||
}
|
}
|
||||||
|
|
||||||
feMesh.write();
|
feMesh.write();
|
||||||
|
|
||||||
// Write a featureEdgeMesh for backwards compatibility
|
// Write a featureEdgeMesh for backwards compatibility
|
||||||
featureEdgeMesh bfeMesh
|
if (true)
|
||||||
(
|
{
|
||||||
IOobject
|
featureEdgeMesh bfeMesh
|
||||||
(
|
(
|
||||||
sFeatFileName + ".eMesh", // name
|
IOobject
|
||||||
runTime.constant(), // instance
|
(
|
||||||
"triSurface",
|
outputName + ".eMesh", // name
|
||||||
runTime, // registry
|
runTime.constant(), // instance
|
||||||
IOobject::NO_READ,
|
"triSurface",
|
||||||
IOobject::AUTO_WRITE,
|
runTime, // registry
|
||||||
false
|
IOobject::NO_READ,
|
||||||
),
|
IOobject::AUTO_WRITE,
|
||||||
feMesh.points(),
|
false
|
||||||
feMesh.edges()
|
),
|
||||||
);
|
feMesh.points(),
|
||||||
|
feMesh.edges()
|
||||||
|
);
|
||||||
|
|
||||||
Info<< nl << "Writing featureEdgeMesh to "
|
Info<< nl << "Writing featureEdgeMesh to "
|
||||||
<< bfeMesh.objectPath() << endl;
|
<< bfeMesh.objectPath() << endl;
|
||||||
|
|
||||||
bfeMesh.regIOobject::write();
|
bfeMesh.regIOobject::write();
|
||||||
|
}
|
||||||
|
|
||||||
// Find close features
|
// Option: "closeness"
|
||||||
|
if (surfaceDict.lookupOrDefault<bool>("closeness", false))
|
||||||
// // Dummy trim operation to mark features
|
|
||||||
// labelList featureEdgeIndexing = newSet.trimFeatures(-GREAT, 0);
|
|
||||||
|
|
||||||
// scalarField surfacePtFeatureIndex(surf.points().size(), -1);
|
|
||||||
|
|
||||||
// forAll(newSet.featureEdges(), eI)
|
|
||||||
// {
|
|
||||||
// const edge& e = surf.edges()[newSet.featureEdges()[eI]];
|
|
||||||
|
|
||||||
// surfacePtFeatureIndex[surf.meshPoints()[e.start()]] =
|
|
||||||
// featureEdgeIndexing[newSet.featureEdges()[eI]];
|
|
||||||
|
|
||||||
// surfacePtFeatureIndex[surf.meshPoints()[e.end()]] =
|
|
||||||
// featureEdgeIndexing[newSet.featureEdges()[eI]];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (writeVTK)
|
|
||||||
// {
|
|
||||||
// vtkSurfaceWriter().write
|
|
||||||
// (
|
|
||||||
// runTime.constant()/"triSurface", // outputDir
|
|
||||||
// sFeatFileName, // surfaceName
|
|
||||||
// surf.points(),
|
|
||||||
// faces,
|
|
||||||
// "surfacePtFeatureIndex", // fieldName
|
|
||||||
// surfacePtFeatureIndex,
|
|
||||||
// true, // isNodeValues
|
|
||||||
// true // verbose
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Random rndGen(343267);
|
|
||||||
|
|
||||||
// treeBoundBox surfBB
|
|
||||||
// (
|
|
||||||
// treeBoundBox(searchSurf.bounds()).extend(rndGen, 1e-4)
|
|
||||||
// );
|
|
||||||
|
|
||||||
// surfBB.min() -= Foam::point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
|
|
||||||
// surfBB.max() += Foam::point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
|
|
||||||
|
|
||||||
// indexedOctree<treeDataEdge> ftEdTree
|
|
||||||
// (
|
|
||||||
// treeDataEdge
|
|
||||||
// (
|
|
||||||
// false,
|
|
||||||
// surf.edges(),
|
|
||||||
// surf.localPoints(),
|
|
||||||
// newSet.featureEdges()
|
|
||||||
// ),
|
|
||||||
// surfBB,
|
|
||||||
// 8, // maxLevel
|
|
||||||
// 10, // leafsize
|
|
||||||
// 3.0 // duplicity
|
|
||||||
// );
|
|
||||||
|
|
||||||
// labelList nearPoints = ftEdTree.findBox
|
|
||||||
// (
|
|
||||||
// treeBoundBox
|
|
||||||
// (
|
|
||||||
// sPt - featureSearchSpan*Foam::vector::one,
|
|
||||||
// sPt + featureSearchSpan*Foam::vector::one
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
|
|
||||||
if (closeness)
|
|
||||||
{
|
{
|
||||||
Info<< nl << "Extracting internal and external closeness of "
|
Info<< nl << "Extracting internal and external closeness of "
|
||||||
<< "surface." << endl;
|
<< "surface." << endl;
|
||||||
|
|
||||||
|
|
||||||
triSurfaceMesh searchSurf
|
triSurfaceMesh searchSurf
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
sFeatFileName + ".closeness",
|
outputName + ".closeness",
|
||||||
runTime.constant(),
|
runTime.constant(),
|
||||||
"triSurface",
|
"triSurface",
|
||||||
runTime,
|
runTime,
|
||||||
@ -1481,8 +1306,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Info<< "span " << span << endl;
|
// Info<< "span " << span << endl;
|
||||||
|
|
||||||
pointField start(searchSurf.faceCentres() - span*normals);
|
const pointField start(searchSurf.faceCentres() - span*normals);
|
||||||
pointField end(searchSurf.faceCentres() + span*normals);
|
const pointField end(searchSurf.faceCentres() + span*normals);
|
||||||
const pointField& faceCentres = searchSurf.faceCentres();
|
const pointField& faceCentres = searchSurf.faceCentres();
|
||||||
|
|
||||||
List<List<pointIndexHit>> allHitInfo;
|
List<List<pointIndexHit>> allHitInfo;
|
||||||
@ -1649,7 +1474,7 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
sFeatFileName + ".internalCloseness",
|
outputName + ".internalCloseness",
|
||||||
runTime.constant(),
|
runTime.constant(),
|
||||||
"triSurface",
|
"triSurface",
|
||||||
runTime,
|
runTime,
|
||||||
@ -1667,7 +1492,7 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
sFeatFileName + ".externalCloseness",
|
outputName + ".externalCloseness",
|
||||||
runTime.constant(),
|
runTime.constant(),
|
||||||
"triSurface",
|
"triSurface",
|
||||||
runTime,
|
runTime,
|
||||||
@ -1685,8 +1510,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
vtkSurfaceWriter().write
|
vtkSurfaceWriter().write
|
||||||
(
|
(
|
||||||
runTime.constantPath()/"triSurface",// outputDir
|
vtkOutputDir,
|
||||||
sFeatFileName, // surfaceName
|
outputName,
|
||||||
meshedSurfRef
|
meshedSurfRef
|
||||||
(
|
(
|
||||||
surf.points(),
|
surf.points(),
|
||||||
@ -1700,8 +1525,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
vtkSurfaceWriter().write
|
vtkSurfaceWriter().write
|
||||||
(
|
(
|
||||||
runTime.constantPath()/"triSurface",// outputDir
|
vtkOutputDir,
|
||||||
sFeatFileName, // surfaceName
|
outputName,
|
||||||
meshedSurfRef
|
meshedSurfRef
|
||||||
(
|
(
|
||||||
surf.points(),
|
surf.points(),
|
||||||
@ -1715,8 +1540,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option: "curvature"
|
||||||
if (curvature)
|
if (surfaceDict.lookupOrDefault<bool>("curvature", false))
|
||||||
{
|
{
|
||||||
Info<< nl << "Extracting curvature of surface at the points."
|
Info<< nl << "Extracting curvature of surface at the points."
|
||||||
<< endl;
|
<< endl;
|
||||||
@ -1726,7 +1551,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
triSurfacePointScalarField k = calcCurvature
|
triSurfacePointScalarField k = calcCurvature
|
||||||
(
|
(
|
||||||
sFeatFileName,
|
outputName,
|
||||||
runTime,
|
runTime,
|
||||||
surf,
|
surf,
|
||||||
pointNormals,
|
pointNormals,
|
||||||
@ -1739,8 +1564,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
vtkSurfaceWriter().write
|
vtkSurfaceWriter().write
|
||||||
(
|
(
|
||||||
runTime.constantPath()/"triSurface",// outputDir
|
vtkOutputDir,
|
||||||
sFeatFileName, // surfaceName
|
outputName,
|
||||||
meshedSurfRef
|
meshedSurfRef
|
||||||
(
|
(
|
||||||
surf.points(),
|
surf.points(),
|
||||||
@ -1754,8 +1579,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option: "featureProximity"
|
||||||
if (featureProximity)
|
if (surfaceDict.lookupOrDefault<bool>("featureProximity", false))
|
||||||
{
|
{
|
||||||
Info<< nl << "Extracting proximity of close feature points and "
|
Info<< nl << "Extracting proximity of close feature points and "
|
||||||
<< "edges to the surface" << endl;
|
<< "edges to the surface" << endl;
|
||||||
@ -1802,7 +1627,7 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
sFeatFileName + ".featureProximity",
|
outputName + ".featureProximity",
|
||||||
runTime.constant(),
|
runTime.constant(),
|
||||||
"triSurface",
|
"triSurface",
|
||||||
runTime,
|
runTime,
|
||||||
@ -1820,8 +1645,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
vtkSurfaceWriter().write
|
vtkSurfaceWriter().write
|
||||||
(
|
(
|
||||||
runTime.constantPath()/"triSurface",// outputDir
|
vtkOutputDir,
|
||||||
sFeatFileName, // surfaceName
|
outputName,
|
||||||
meshedSurfRef
|
meshedSurfRef
|
||||||
(
|
(
|
||||||
surf.points(),
|
surf.points(),
|
||||||
|
|||||||
@ -16,7 +16,7 @@ FoamFile
|
|||||||
|
|
||||||
surface1.stl
|
surface1.stl
|
||||||
{
|
{
|
||||||
// How to obtain raw features (extractFromFile || extractFromSurface)
|
// How to obtain raw features (extractFromFile | extractFromSurface | none)
|
||||||
extractionMethod extractFromSurface;
|
extractionMethod extractFromSurface;
|
||||||
|
|
||||||
extractFromSurfaceCoeffs
|
extractFromSurfaceCoeffs
|
||||||
@ -28,19 +28,25 @@ surface1.stl
|
|||||||
includedAngle 120;
|
includedAngle 120;
|
||||||
|
|
||||||
// Do not mark region edges
|
// Do not mark region edges
|
||||||
geometricTestOnly yes;
|
geometricTestOnly yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate additional features from self-intersect
|
||||||
|
selfIntersection false;
|
||||||
|
|
||||||
|
// Tolerance for surface intersections
|
||||||
|
tolerance 1e-3;
|
||||||
|
|
||||||
// Write options
|
// Write options
|
||||||
|
|
||||||
// Write features to obj format for postprocessing
|
// Write features to obj format for postprocessing
|
||||||
writeObj yes;
|
writeObj yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
surface2.nas
|
surface2.nas
|
||||||
{
|
{
|
||||||
// How to obtain raw features (extractFromFile || extractFromSurface)
|
// How to obtain raw features (extractFromFile | extractFromSurface | none)
|
||||||
extractionMethod extractFromFile;
|
extractionMethod extractFromFile;
|
||||||
|
|
||||||
extractFromFileCoeffs
|
extractFromFileCoeffs
|
||||||
@ -91,36 +97,42 @@ surface2.nas
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Output the curvature of the surface
|
// Output the curvature of the surface
|
||||||
curvature no;
|
curvature no;
|
||||||
|
|
||||||
// Output the proximity of feature points and edges to each other
|
// Output the proximity of feature points and edges to each other
|
||||||
featureProximity no;
|
featureProximity no;
|
||||||
|
|
||||||
// The maximum search distance to use when looking for other feature
|
// The maximum search distance to use when looking for other feature
|
||||||
// points and edges
|
// points and edges
|
||||||
maxFeatureProximity 1;
|
maxFeatureProximity 1;
|
||||||
|
|
||||||
// Out put the closeness of surface elements to other surface elements.
|
// Out put the closeness of surface elements to other surface elements.
|
||||||
closeness no;
|
closeness no;
|
||||||
|
|
||||||
|
// Generate additional features from self-intersect
|
||||||
|
selfIntersection false;
|
||||||
|
|
||||||
|
// Tolerance for surface intersections
|
||||||
|
tolerance 1e-3;
|
||||||
|
|
||||||
// Write options
|
// Write options
|
||||||
|
|
||||||
// Write features to obj format for postprocessing
|
// Write features to obj format for postprocessing
|
||||||
writeObj yes;
|
writeObj yes;
|
||||||
|
|
||||||
// Write surface proximity and curvature fields to vtk format
|
// Write surface proximity and curvature fields to vtk format
|
||||||
// for postprocessing
|
// for postprocessing
|
||||||
writeVTK no;
|
writeVTK no;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Handle multiple surfaces
|
// Handle single or multiple surfaces
|
||||||
//
|
//
|
||||||
// - If the dictionary is named 'surfaces', it must also contain a 'surfaces'
|
// - If the dictionary is named 'surfaces', it must also contain a 'surfaces'
|
||||||
// entry (wordRe list).
|
// entry (wordRe list).
|
||||||
//
|
//
|
||||||
// - If other dictionaries may contain a 'surfaces' entry, it will be taken
|
// - If other dictionaries contain a 'surfaces' entry,
|
||||||
// for the input.
|
// it will be taken for the input.
|
||||||
//
|
//
|
||||||
surfaces
|
surfaces
|
||||||
{
|
{
|
||||||
@ -131,24 +143,30 @@ surfaces
|
|||||||
// Base output name (optional)
|
// Base output name (optional)
|
||||||
// output surfaces;
|
// output surfaces;
|
||||||
|
|
||||||
// Generate features from self-intersect
|
// Generate additional features from self-intersect
|
||||||
selfIntersection true;
|
selfIntersection true;
|
||||||
|
|
||||||
// Tolerance for self-intersect
|
// Tolerance for surface intersections
|
||||||
planarTolerance 1e-3;
|
tolerance 1e-3;
|
||||||
|
|
||||||
extractFromSurfaceCoeffs
|
extractFromSurfaceCoeffs
|
||||||
{
|
{
|
||||||
includedAngle 120;
|
includedAngle 120;
|
||||||
|
|
||||||
// Do not mark region edges
|
// Do not mark region edges
|
||||||
geometricTestOnly yes;
|
geometricTestOnly yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
extractFromNoneCoeffs
|
||||||
|
{
|
||||||
|
includedAngle 120;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write options
|
// Write options
|
||||||
|
|
||||||
// Write features to obj format for postprocessing
|
// Write features to obj format for postprocessing
|
||||||
writeObj yes;
|
writeObj yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -41,11 +41,19 @@ Description
|
|||||||
hit of both faces and an edge is created between the retrieved vertex and
|
hit of both faces and an edge is created between the retrieved vertex and
|
||||||
the new one.
|
the new one.
|
||||||
|
|
||||||
Note: when doing intersecting itself uses intersection::planarTol() as a
|
Note: when doing intersecting itself uses 'tolerance' as a fraction of
|
||||||
fraction of
|
|
||||||
current edge length to determine if intersection is a point-touching one
|
current edge length to determine if intersection is a point-touching one
|
||||||
instead of an edge-piercing action.
|
instead of an edge-piercing action.
|
||||||
|
|
||||||
|
Some constructors allow a dictionary of intersection controls:
|
||||||
|
\table
|
||||||
|
Property | Description | Type | Default value
|
||||||
|
tolerance | Edge-length tolerance | scalar | 1e-3
|
||||||
|
allowEdgeHits | Edge-end cuts another edge | bool | true
|
||||||
|
avoidDuplicates | Reduce the number of duplicate points | bool | true
|
||||||
|
warnDegenerate | Number of warnings about degenerate edges | label | 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
surfaceIntersection.C
|
surfaceIntersection.C
|
||||||
surfaceIntersectionFuncs.C
|
surfaceIntersectionFuncs.C
|
||||||
@ -75,7 +83,7 @@ class triSurface;
|
|||||||
class edgeIntersections;
|
class edgeIntersections;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class surfaceIntersection Declaration
|
Class surfaceIntersection Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class surfaceIntersection
|
class surfaceIntersection
|
||||||
@ -91,13 +99,22 @@ class surfaceIntersection
|
|||||||
};
|
};
|
||||||
|
|
||||||
//- Tolerance for intersections
|
//- Tolerance for intersections
|
||||||
scalar planarTol_;
|
scalar tolerance_;
|
||||||
|
|
||||||
|
//- Allow edge-ends to cut another edge.
|
||||||
|
bool allowEdgeHits_;
|
||||||
|
|
||||||
|
//- Avoid creating duplicate cuts near edge ends
|
||||||
|
bool avoidDuplicates_;
|
||||||
|
|
||||||
|
//- Maximum number of warnings about degenerate edges
|
||||||
|
label warnDegenerate_;
|
||||||
|
|
||||||
//- Newly introduced points.
|
//- Newly introduced points.
|
||||||
pointField cutPoints_;
|
pointField cutPoints_;
|
||||||
|
|
||||||
//- Newly introduced edges (are on both surfaces). Reference into
|
//- Newly introduced edges (are on both surfaces).
|
||||||
// cutPoints.
|
// Reference into cutPoints.
|
||||||
edgeList cutEdges_;
|
edgeList cutEdges_;
|
||||||
|
|
||||||
//- From face on surf1 and face on surf2 to intersection point
|
//- From face on surf1 and face on surf2 to intersection point
|
||||||
@ -116,18 +133,27 @@ class surfaceIntersection
|
|||||||
// If multiple cuts:sorted from edge.start to edge.end
|
// If multiple cuts:sorted from edge.start to edge.end
|
||||||
labelListList surf2EdgeCuts_;
|
labelListList surf2EdgeCuts_;
|
||||||
|
|
||||||
|
//- Temporary storage to manage edge-edge self-intersections.
|
||||||
|
HashSet<edge, Hash<edge>> edgeEdgeIntersection_;
|
||||||
|
|
||||||
|
//- Temporary storage to manage cuts/intersections from the edge ends
|
||||||
|
Map<label> edgeEndAsCut_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Write point in obj format.
|
//- Adjust intersection options according to the dictionary entries
|
||||||
static void writeOBJ(const point& pt, Ostream& os);
|
void setOptions(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Write points in obj format
|
||||||
|
static void writeOBJ(const List<point>& pts, Ostream& os);
|
||||||
|
|
||||||
//- Write points and edges in obj format
|
//- Write points and edges in obj format
|
||||||
static void writeOBJ
|
static void writeOBJ
|
||||||
(
|
(
|
||||||
const List<point>&,
|
const List<point>& pts,
|
||||||
const List<edge>&,
|
const List<edge>& edges,
|
||||||
Ostream&
|
Ostream& os
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Transfer contents of List<DynamicList<..>> to List<List<..>>
|
//- Transfer contents of List<DynamicList<..>> to List<List<..>>
|
||||||
@ -149,9 +175,6 @@ class surfaceIntersection
|
|||||||
// to new (-1 if element removed)
|
// to new (-1 if element removed)
|
||||||
static void removeDuplicates(const labelList& map, labelList& labels);
|
static void removeDuplicates(const labelList& map, labelList& labels);
|
||||||
|
|
||||||
//- Apply map to elements of a labelList
|
|
||||||
static void inlineRemap(const labelList& map, labelList& elems);
|
|
||||||
|
|
||||||
// Remove all duplicate and degenerate elements. Return unique elements
|
// Remove all duplicate and degenerate elements. Return unique elements
|
||||||
// and map from old to new.
|
// and map from old to new.
|
||||||
static edgeList filterEdges(const edgeList&, labelList& map);
|
static edgeList filterEdges(const edgeList&, labelList& map);
|
||||||
@ -159,30 +182,6 @@ class surfaceIntersection
|
|||||||
//- Remove all duplicate elements.
|
//- Remove all duplicate elements.
|
||||||
static labelList filterLabels(const labelList& elems, labelList& map);
|
static labelList filterLabels(const labelList& elems, labelList& map);
|
||||||
|
|
||||||
//- Do some checks if edge and face (resulting from hit)
|
|
||||||
// should not be considered. Returns true if can be discarded.
|
|
||||||
static bool excludeEdgeHit
|
|
||||||
(
|
|
||||||
const triSurface& surf,
|
|
||||||
const label edgeI,
|
|
||||||
const label facei,
|
|
||||||
const scalar tol
|
|
||||||
);
|
|
||||||
|
|
||||||
////- Given edge (eStart - eEnd) and normal direction construct plane
|
|
||||||
//// and intersect all edges of hitFace with it.
|
|
||||||
//// Return the edge and coordinate of hit.
|
|
||||||
//static pointIndexHit faceEdgeIntersection
|
|
||||||
//(
|
|
||||||
// const triSurface&,
|
|
||||||
// const label hitFacei,
|
|
||||||
//
|
|
||||||
// const vector& n,
|
|
||||||
// const point& eStart,
|
|
||||||
// const point& eEnd
|
|
||||||
//);
|
|
||||||
|
|
||||||
|
|
||||||
//- Debugging: Dump intersected edges to stream
|
//- Debugging: Dump intersected edges to stream
|
||||||
void writeIntersectedEdges
|
void writeIntersectedEdges
|
||||||
(
|
(
|
||||||
@ -199,7 +198,7 @@ class surfaceIntersection
|
|||||||
const scalar endTol,
|
const scalar endTol,
|
||||||
const point& p,
|
const point& p,
|
||||||
const edge& e,
|
const edge& e,
|
||||||
const pointField& points
|
const UList<point>& points
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Update reference between faceA and faceB. Updates facePairToVertex_
|
//- Update reference between faceA and faceB. Updates facePairToVertex_
|
||||||
@ -209,8 +208,9 @@ class surfaceIntersection
|
|||||||
const enum originatingType cutFrom,
|
const enum originatingType cutFrom,
|
||||||
const labelList& facesA,
|
const labelList& facesA,
|
||||||
const label faceB,
|
const label faceB,
|
||||||
DynamicList<edge>&,
|
const UList<point>& allCutPoints,
|
||||||
DynamicList<point>&
|
const label cutPointId,
|
||||||
|
DynamicList<edge>& allCutEdges
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Investigate pHit to whether is case of point hits point,
|
//- Investigate pHit to whether is case of point hits point,
|
||||||
@ -224,8 +224,8 @@ class surfaceIntersection
|
|||||||
const label edgeI,
|
const label edgeI,
|
||||||
const pointIndexHit& pHit,
|
const pointIndexHit& pHit,
|
||||||
|
|
||||||
DynamicList<edge>& allCutEdges,
|
|
||||||
DynamicList<point>& allCutPoints,
|
DynamicList<point>& allCutPoints,
|
||||||
|
DynamicList<edge>& allCutEdges,
|
||||||
List<DynamicList<label>>& surfEdgeCuts
|
List<DynamicList<label>>& surfEdgeCuts
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -236,8 +236,8 @@ class surfaceIntersection
|
|||||||
const triSurfaceSearch& querySurf2,
|
const triSurfaceSearch& querySurf2,
|
||||||
const enum originatingType cutFrom,
|
const enum originatingType cutFrom,
|
||||||
|
|
||||||
DynamicList<edge>& allCutEdges,
|
|
||||||
DynamicList<point>& allCutPoints,
|
DynamicList<point>& allCutPoints,
|
||||||
|
DynamicList<edge>& allCutEdges,
|
||||||
List<DynamicList<label>>& surfEdgeCuts
|
List<DynamicList<label>>& surfEdgeCuts
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -246,9 +246,6 @@ public:
|
|||||||
|
|
||||||
// Public Data, Declarations
|
// Public Data, Declarations
|
||||||
|
|
||||||
//- The default planarTol for intersections.
|
|
||||||
static const scalar defaultTolerance;
|
|
||||||
|
|
||||||
ClassName("surfaceIntersection");
|
ClassName("surfaceIntersection");
|
||||||
|
|
||||||
|
|
||||||
@ -263,7 +260,7 @@ public:
|
|||||||
(
|
(
|
||||||
const triSurfaceSearch& querySurf1,
|
const triSurfaceSearch& querySurf1,
|
||||||
const triSurfaceSearch& querySurf2,
|
const triSurfaceSearch& querySurf2,
|
||||||
const scalar planarTol = surfaceIntersection::defaultTolerance
|
const dictionary& dict = dictionary::null
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from self-intersections.
|
//- Construct from self-intersections.
|
||||||
@ -271,7 +268,7 @@ public:
|
|||||||
surfaceIntersection
|
surfaceIntersection
|
||||||
(
|
(
|
||||||
const triSurfaceSearch& querySurf1,
|
const triSurfaceSearch& querySurf1,
|
||||||
const scalar planarTol = surfaceIntersection::defaultTolerance
|
const dictionary& dict = dictionary::null
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from precalculated intersection information.
|
//- Construct from precalculated intersection information.
|
||||||
@ -288,21 +285,33 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
//- The list of cut points
|
||||||
const pointField& cutPoints() const;
|
const pointField& cutPoints() const;
|
||||||
|
|
||||||
|
//- The list of created edges
|
||||||
const edgeList& cutEdges() const;
|
const edgeList& cutEdges() const;
|
||||||
|
|
||||||
const labelPairLookup& facePairToVertex() const;
|
//- Lookup of pairs of faces to created edges
|
||||||
|
|
||||||
const labelPairLookup& facePairToEdge() const;
|
const labelPairLookup& facePairToEdge() const;
|
||||||
|
|
||||||
//- Access either surf1EdgeCuts (isFirstSurface = true) or
|
//- Access either surf1EdgeCuts (isFirstSurface = true) or
|
||||||
// surf2EdgeCuts
|
// surf2EdgeCuts
|
||||||
const labelListList& edgeCuts(const bool isFirstSurf) const;
|
const labelListList& edgeCuts(const bool isFirstSurf) const;
|
||||||
|
|
||||||
|
//- List of cut points on edges of surface1
|
||||||
const labelListList& surf1EdgeCuts() const;
|
const labelListList& surf1EdgeCuts() const;
|
||||||
|
|
||||||
|
//- List of cut points on edges of surface2
|
||||||
const labelListList& surf2EdgeCuts() const;
|
const labelListList& surf2EdgeCuts() const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Geometric merge points (points within mergeDist) prior to
|
||||||
|
// automatically calling mergeEdges().
|
||||||
|
void mergePoints(const scalar mergeDist);
|
||||||
|
|
||||||
|
//- Merge duplicate edges
|
||||||
|
void mergeEdges();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -24,19 +24,24 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "surfaceIntersection.H"
|
#include "surfaceIntersection.H"
|
||||||
|
#include "triSurface.H"
|
||||||
#include "triSurfaceSearch.H"
|
#include "triSurfaceSearch.H"
|
||||||
#include "labelPairHashes.H"
|
#include "labelPairHashes.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "HashSet.H"
|
|
||||||
#include "triSurface.H"
|
|
||||||
#include "pointIndexHit.H"
|
|
||||||
#include "meshTools.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::surfaceIntersection::writeOBJ(const point& pt, Ostream& os)
|
void Foam::surfaceIntersection::writeOBJ
|
||||||
|
(
|
||||||
|
const List<point>& pts,
|
||||||
|
Ostream& os
|
||||||
|
)
|
||||||
{
|
{
|
||||||
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
|
forAll(pts, i)
|
||||||
|
{
|
||||||
|
const point& pt = pts[i];
|
||||||
|
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -47,15 +52,13 @@ void Foam::surfaceIntersection::writeOBJ
|
|||||||
Ostream& os
|
Ostream& os
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
forAll(pts, i)
|
writeOBJ(pts, os);
|
||||||
{
|
|
||||||
writeOBJ(pts[i], os);
|
|
||||||
}
|
|
||||||
forAll(edges, i)
|
forAll(edges, i)
|
||||||
{
|
{
|
||||||
const edge& e = edges[i];
|
const edge& e = edges[i];
|
||||||
|
|
||||||
os << "l " << e.start()+1 << ' ' << e.end()+1 << endl;
|
os << "l " << e.start()+1 << ' ' << e.end()+1 << nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,20 +165,6 @@ void Foam::surfaceIntersection::removeDuplicates
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Remap.
|
|
||||||
void Foam::surfaceIntersection::inlineRemap
|
|
||||||
(
|
|
||||||
const labelList& map,
|
|
||||||
labelList& elems
|
|
||||||
)
|
|
||||||
{
|
|
||||||
forAll(elems, elemI)
|
|
||||||
{
|
|
||||||
elems[elemI] = map[elems[elemI]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Remove all duplicate and degenerate elements. Return unique elements and
|
// Remove all duplicate and degenerate elements. Return unique elements and
|
||||||
// map from old to new.
|
// map from old to new.
|
||||||
Foam::edgeList Foam::surfaceIntersection::filterEdges
|
Foam::edgeList Foam::surfaceIntersection::filterEdges
|
||||||
@ -265,14 +254,8 @@ void Foam::surfaceIntersection::writeIntersectedEdges
|
|||||||
// Dump all points (surface followed by cutPoints)
|
// Dump all points (surface followed by cutPoints)
|
||||||
const pointField& pts = surf.localPoints();
|
const pointField& pts = surf.localPoints();
|
||||||
|
|
||||||
forAll(pts, pointi)
|
writeOBJ(pts, os);
|
||||||
{
|
writeOBJ(cutPoints(), os);
|
||||||
writeOBJ(pts[pointi], os);
|
|
||||||
}
|
|
||||||
forAll(cutPoints(), cutPointi)
|
|
||||||
{
|
|
||||||
writeOBJ(cutPoints()[cutPointi], os);
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(edgeCutVerts, edgeI)
|
forAll(edgeCutVerts, edgeI)
|
||||||
{
|
{
|
||||||
@ -284,16 +267,16 @@ void Foam::surfaceIntersection::writeIntersectedEdges
|
|||||||
|
|
||||||
// Start of original edge to first extra point
|
// Start of original edge to first extra point
|
||||||
os << "l " << e.start()+1 << ' '
|
os << "l " << e.start()+1 << ' '
|
||||||
<< extraVerts[0] + surf.nPoints() + 1 << endl;
|
<< extraVerts[0] + surf.nPoints() + 1 << nl;
|
||||||
|
|
||||||
for (label i = 1; i < extraVerts.size(); i++)
|
for (label i = 1; i < extraVerts.size(); i++)
|
||||||
{
|
{
|
||||||
os << "l " << extraVerts[i-1] + surf.nPoints() + 1 << ' '
|
os << "l " << extraVerts[i-1] + surf.nPoints() + 1 << ' '
|
||||||
<< extraVerts[i] + surf.nPoints() + 1 << endl;
|
<< extraVerts[i] + surf.nPoints() + 1 << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "l " << extraVerts.last() + surf.nPoints() + 1
|
os << "l " << extraVerts.last() + surf.nPoints() + 1
|
||||||
<< ' ' << e.end()+1 << endl;
|
<< ' ' << e.end()+1 << nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,7 +289,7 @@ Foam::label Foam::surfaceIntersection::classify
|
|||||||
const scalar endTol,
|
const scalar endTol,
|
||||||
const point& p,
|
const point& p,
|
||||||
const edge& e,
|
const edge& e,
|
||||||
const pointField& points
|
const UList<point>& points
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (mag(p - points[e.start()]) < startTol)
|
if (mag(p - points[e.start()]) < startTol)
|
||||||
|
|||||||
Reference in New Issue
Block a user