mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improved handling of 'unresolved' surface intersections (issue #450)
- the heuristic for matching unresolved intersections is a relatively simple matching scheme that seems to be more robust than attempting to walk the geometry or the cuts. - avoid false positives for self intersection
This commit is contained in:
@ -1,9 +1,7 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
|
||||||
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/triSurface/lnInclude
|
-I$(LIB_SRC)/triSurface/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
-lfiniteVolume \
|
-lmeshTools
|
||||||
-lmeshTools -ledgeMesh
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@ Description
|
|||||||
#include "triSurface.H"
|
#include "triSurface.H"
|
||||||
#include "triSurfaceMesh.H"
|
#include "triSurfaceMesh.H"
|
||||||
#include "surfaceIntersection.H"
|
#include "surfaceIntersection.H"
|
||||||
#include "OFstream.H"
|
#include "OBJstream.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
Info<< "surf1-cuts: " << cuts.surf1EdgeCuts() << nl
|
Info<< "surf1-cuts: " << cuts.surf1EdgeCuts() << nl
|
||||||
<< "surf2-cuts: " << cuts.surf2EdgeCuts() << nl
|
<< "surf2-cuts: " << cuts.surf2EdgeCuts() << nl
|
||||||
<< "face-pairs: " << cuts.facePairToEdge() << nl
|
<< "face-pairs: " << cuts.facePairToEdgeId() << nl
|
||||||
<< "edges: " << cuts.cutEdges() << nl;
|
<< "edges: " << cuts.cutEdges() << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
Info<< "surf1-cuts: " << cuts.surf1EdgeCuts() << nl
|
Info<< "surf1-cuts: " << cuts.surf1EdgeCuts() << nl
|
||||||
<< "surf2-cuts: " << cuts.surf2EdgeCuts() << nl
|
<< "surf2-cuts: " << cuts.surf2EdgeCuts() << nl
|
||||||
<< "face-pairs: " << cuts.facePairToEdge() << nl
|
<< "face-pairs: " << cuts.facePairToEdgeId() << nl
|
||||||
<< "edges: " << cuts.cutEdges() << nl;
|
<< "edges: " << cuts.cutEdges() << nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,20 +209,7 @@ int main(int argc, char *argv[])
|
|||||||
if (points.size() || edges.size())
|
if (points.size() || edges.size())
|
||||||
{
|
{
|
||||||
Info<<"write to " << outputFile << nl;
|
Info<<"write to " << outputFile << nl;
|
||||||
|
OBJstream(outputFile).write(edges, points);
|
||||||
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;
|
Info<< "End\n" << endl;
|
||||||
|
|||||||
@ -99,7 +99,7 @@ typedef CGAL::AABB_face_graph_triangle_primitive
|
|||||||
typedef CGAL::AABB_traits<K, Primitive> Traits;
|
typedef CGAL::AABB_traits<K, Primitive> Traits;
|
||||||
typedef CGAL::AABB_tree<Traits> Tree;
|
typedef CGAL::AABB_tree<Traits> Tree;
|
||||||
|
|
||||||
typedef boost::optional<Tree::Intersection_and_primitive_id<Segment>::Type >
|
typedef boost::optional<Tree::Intersection_and_primitive_id<Segment>::Type>
|
||||||
Segment_intersection;
|
Segment_intersection;
|
||||||
|
|
||||||
#endif // NO_CGAL
|
#endif // NO_CGAL
|
||||||
@ -477,7 +477,6 @@ label dupNonManifoldPoints(triSurface& s, labelList& pointMap)
|
|||||||
List<labelledTri> newFaces(s);
|
List<labelledTri> newFaces(s);
|
||||||
label nNonManifold = 0;
|
label nNonManifold = 0;
|
||||||
|
|
||||||
|
|
||||||
forAll(pf, pointI)
|
forAll(pf, pointI)
|
||||||
{
|
{
|
||||||
const labelList& pFaces = pf[pointI];
|
const labelList& pFaces = pf[pointI];
|
||||||
@ -1257,10 +1256,10 @@ autoPtr<extendedFeatureEdgeMesh> createEdgeMesh
|
|||||||
const triSurface& s1 = surf1;
|
const triSurface& s1 = surf1;
|
||||||
const triSurface& s2 = surf2;
|
const triSurface& s2 = surf2;
|
||||||
|
|
||||||
forAllConstIter(labelPairLookup, inter.facePairToEdge(), iter)
|
forAllConstIters(inter.facePairToEdgeId(), iter)
|
||||||
{
|
{
|
||||||
const label& cutEdgeI = iter();
|
|
||||||
const labelPair& facePair = iter.key();
|
const labelPair& facePair = iter.key();
|
||||||
|
const label cutEdgeI = iter.object();
|
||||||
|
|
||||||
const edge& fE = inter.cutEdges()[cutEdgeI];
|
const edge& fE = inter.cutEdges()[cutEdgeI];
|
||||||
|
|
||||||
|
|||||||
@ -73,7 +73,7 @@ Foam::surfaceFeaturesExtraction::method::New
|
|||||||
dictionaryConstructorTable::iterator cstrIter =
|
dictionaryConstructorTable::iterator cstrIter =
|
||||||
dictionaryConstructorTablePtr_->find(methodName);
|
dictionaryConstructorTablePtr_->find(methodName);
|
||||||
|
|
||||||
if (cstrIter == dictionaryConstructorTablePtr_->end())
|
if (!cstrIter.found())
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction
|
FatalIOErrorInFunction
|
||||||
(
|
(
|
||||||
|
|||||||
@ -84,6 +84,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
forAllConstIter(dictionary, dict, iter)
|
forAllConstIter(dictionary, dict, iter)
|
||||||
{
|
{
|
||||||
|
const word& dictName = iter().keyword();
|
||||||
|
|
||||||
if (!iter().isDict())
|
if (!iter().isDict())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -106,7 +108,7 @@ int main(int argc, char *argv[])
|
|||||||
const word outputName =
|
const word outputName =
|
||||||
fileName
|
fileName
|
||||||
(
|
(
|
||||||
surfaceDict.lookupOrDefault<word>("output", iter().keyword())
|
surfaceDict.lookupOrDefault<word>("output", dictName)
|
||||||
).lessExt();
|
).lessExt();
|
||||||
|
|
||||||
// The "surfaces" entry is normally optional, but if the sub-dictionary
|
// The "surfaces" entry is normally optional, but if the sub-dictionary
|
||||||
@ -115,7 +117,7 @@ int main(int argc, char *argv[])
|
|||||||
// additional switch.
|
// additional switch.
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
iter().keyword() == "surfaces" // mandatory
|
dictName == "surfaces" // mandatory
|
||||||
|| surfaceDict.found("surfaces") // or optional
|
|| surfaceDict.found("surfaces") // or optional
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -123,14 +125,14 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loader.select(iter().keyword());
|
loader.select(dictName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loader.selected().empty())
|
if (loader.selected().empty())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "No surfaces specified/found for entry: "
|
<< "No surfaces specified/found for entry: "
|
||||||
<< iter().keyword() << exit(FatalError);
|
<< dictName << exit(FatalError);
|
||||||
}
|
}
|
||||||
// DebugVar(loader.available());
|
// DebugVar(loader.available());
|
||||||
// DebugVar(outputName);
|
// DebugVar(outputName);
|
||||||
@ -153,7 +155,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Problem loading surface(s) for entry: "
|
<< "Problem loading surface(s) for entry: "
|
||||||
<< iter().keyword() << exit(FatalError);
|
<< dictName << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
triSurface surf = surfPtr();
|
triSurface surf = surfPtr();
|
||||||
|
|||||||
@ -134,7 +134,7 @@ surface2.nas
|
|||||||
// - If other dictionaries contain a 'surfaces' entry,
|
// - If other dictionaries contain a 'surfaces' entry,
|
||||||
// it will be taken for the input.
|
// it will be taken for the input.
|
||||||
//
|
//
|
||||||
surfaces
|
dummyName
|
||||||
{
|
{
|
||||||
extractionMethod extractFromSurface;
|
extractionMethod extractFromSurface;
|
||||||
|
|
||||||
@ -169,4 +169,39 @@ surfaces
|
|||||||
writeObj yes;
|
writeObj yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Handle single or multiple surfaces
|
||||||
|
//
|
||||||
|
// - If the dictionary is named 'surfaces', it must also contain a 'surfaces'
|
||||||
|
// entry (wordRe list).
|
||||||
|
//
|
||||||
|
// - If other dictionaries contain a 'surfaces' entry,
|
||||||
|
// it will be taken for the input.
|
||||||
|
//
|
||||||
|
surfaces
|
||||||
|
{
|
||||||
|
extractionMethod extractFromNone;
|
||||||
|
|
||||||
|
surfaces (surface1.stl surface2.nas);
|
||||||
|
|
||||||
|
// Base output name (optional)
|
||||||
|
// output surfaces;
|
||||||
|
|
||||||
|
// Generate additional features from self-intersect
|
||||||
|
selfIntersection true;
|
||||||
|
|
||||||
|
// Tolerance for surface intersections
|
||||||
|
tolerance 1e-3;
|
||||||
|
|
||||||
|
extractFromNoneCoeffs
|
||||||
|
{
|
||||||
|
includedAngle 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write options
|
||||||
|
|
||||||
|
// Write features to obj format for postprocessing
|
||||||
|
writeObj yes;
|
||||||
|
}
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -129,8 +129,7 @@ void dumpFaces
|
|||||||
const Map<label>& connectedFaces
|
const Map<label>& connectedFaces
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Info<< "Dumping connectedFaces as Lightwave .obj file to " << fName
|
Info<< "Dumping connectedFaces as .obj file to " << fName << nl;
|
||||||
<< "\nThis can be visualized with e.g. javaview (www.javaview.de)\n\n";
|
|
||||||
|
|
||||||
OFstream os(fName);
|
OFstream os(fName);
|
||||||
|
|
||||||
|
|||||||
@ -27,56 +27,37 @@ License
|
|||||||
#include "triSurface.H"
|
#include "triSurface.H"
|
||||||
#include "surfaceIntersection.H"
|
#include "surfaceIntersection.H"
|
||||||
#include "meshTools.H"
|
#include "meshTools.H"
|
||||||
#include "OFstream.H"
|
#include "OBJstream.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
defineTypeNameAndDebug(edgeSurface, 0);
|
defineTypeNameAndDebug(edgeSurface, 0);
|
||||||
}
|
|
||||||
|
|
||||||
|
// file-scope
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// Write points in obj format
|
||||||
|
static void writeObjPoints(const UList<point>& pts, Ostream& os)
|
||||||
// Write whole pointField and edges to stream
|
|
||||||
void Foam::edgeSurface::writeOBJ
|
|
||||||
(
|
|
||||||
const pointField& points,
|
|
||||||
const edgeList& edges,
|
|
||||||
Ostream& os
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
forAll(points, pointi)
|
forAll(pts, i)
|
||||||
{
|
{
|
||||||
const point& pt = points[pointi];
|
const point& pt = pts[i];
|
||||||
|
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
|
||||||
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
|
|
||||||
}
|
|
||||||
forAll(edges, edgeI)
|
|
||||||
{
|
|
||||||
const edge& e = edges[edgeI];
|
|
||||||
|
|
||||||
os << "l " << e.start()+1 << ' ' << e.end()+1 << endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Write whole pointField and selected edges to stream
|
// Write whole pointField and selected edges to stream
|
||||||
void Foam::edgeSurface::writeOBJ
|
void writeObjEdges
|
||||||
(
|
(
|
||||||
const pointField& points,
|
const UList<point>& points,
|
||||||
const edgeList& edges,
|
const edgeList& edges,
|
||||||
const labelList& edgeLabels,
|
const labelList& edgeLabels,
|
||||||
Ostream& os
|
Ostream& os
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
forAll(points, pointi)
|
writeObjPoints(points, os);
|
||||||
{
|
|
||||||
const point& pt = points[pointi];
|
|
||||||
|
|
||||||
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
|
|
||||||
}
|
|
||||||
forAll(edgeLabels, i)
|
forAll(edgeLabels, i)
|
||||||
{
|
{
|
||||||
const edge& e = edges[edgeLabels[i]];
|
const edge& e = edges[edgeLabels[i]];
|
||||||
@ -85,6 +66,10 @@ void Foam::edgeSurface::writeOBJ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
// Pointedges in edgeSurface indices only.
|
// Pointedges in edgeSurface indices only.
|
||||||
void Foam::edgeSurface::calcPointEdges()
|
void Foam::edgeSurface::calcPointEdges()
|
||||||
@ -253,29 +238,16 @@ Foam::edgeSurface::edgeSurface
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Add intersection edges to faceEdges
|
// Add intersection edges to faceEdges
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
forAllConstIter(labelPairLookup, inter.facePairToEdge(), iter)
|
forAllConstIters(inter.facePairToEdgeId(), iter)
|
||||||
{
|
{
|
||||||
|
// The faceId from the correct surface
|
||||||
|
const label facei = iter.key()[isFirstSurface ? 0 : 1];
|
||||||
|
|
||||||
// Edge label in intersection
|
// Edge label in intersection
|
||||||
const label edgeI = iter();
|
const label edgeI = iter.object();
|
||||||
|
|
||||||
// Get the face from the correct surface
|
|
||||||
const FixedList<label, 2>& twoFaces = iter.key();
|
|
||||||
|
|
||||||
label facei;
|
|
||||||
|
|
||||||
if (isFirstSurface)
|
|
||||||
{
|
|
||||||
facei = twoFaces[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
facei = twoFaces[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store on face-edge addressing. (note: offset edge)
|
// Store on face-edge addressing. (note: offset edge)
|
||||||
allFaceEdges[facei].append(edgeI + nSurfaceEdges_);
|
allFaceEdges[facei].append(edgeI + nSurfaceEdges_);
|
||||||
@ -312,18 +284,17 @@ Foam::edgeSurface::edgeSurface
|
|||||||
<< " to " << faceFName << endl;
|
<< " to " << faceFName << endl;
|
||||||
|
|
||||||
OFstream fStream(faceFName);
|
OFstream fStream(faceFName);
|
||||||
writeOBJ(points_, edges_, fEdges, fStream);
|
writeObjEdges(points_, edges_, fEdges, fStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pout<< "edgeSurface : Dumping edges to edges.obj" << endl;
|
Pout<< "edgeSurface : Dumping edges to edges.obj" << endl;
|
||||||
OFstream eStream("edges.obj");
|
OBJstream("edges.obj").write(edges_, points_);
|
||||||
writeOBJ(points_, edges_, eStream);
|
|
||||||
|
|
||||||
Pout<< "edgeSurface : Dumping intersectionEdges to"
|
Pout<< "edgeSurface : Dumping intersectionEdges to"
|
||||||
<< " intersectionEdges.obj" << endl;
|
<< " intersectionEdges.obj" << endl;
|
||||||
OFstream intEdgesStream("intersectionEdges.obj");
|
|
||||||
|
|
||||||
|
OFstream intEdgesStream("intersectionEdges.obj");
|
||||||
labelList edgeLabels(edges_.size() - nSurfaceEdges_);
|
labelList edgeLabels(edges_.size() - nSurfaceEdges_);
|
||||||
|
|
||||||
label i = 0;
|
label i = 0;
|
||||||
@ -332,7 +303,7 @@ Foam::edgeSurface::edgeSurface
|
|||||||
edgeLabels[i++] = edgeI;
|
edgeLabels[i++] = edgeI;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOBJ(points_, edges_, edgeLabels, intEdgesStream);
|
writeObjEdges(points_, edges_, edgeLabels, intEdgesStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -93,25 +93,12 @@ private:
|
|||||||
//- From face to our edges_
|
//- From face to our edges_
|
||||||
labelListList faceEdges_;
|
labelListList faceEdges_;
|
||||||
|
|
||||||
|
|
||||||
//- Constructed from above: pointEdges
|
//- Constructed from above: pointEdges
|
||||||
labelListList pointEdges_;
|
labelListList pointEdges_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Dump edges in obj format
|
|
||||||
static void writeOBJ(const pointField&, const edgeList&, Ostream&);
|
|
||||||
|
|
||||||
//- Dump selected edges in obj format
|
|
||||||
static void writeOBJ
|
|
||||||
(
|
|
||||||
const pointField&,
|
|
||||||
const edgeList&,
|
|
||||||
const labelList&,
|
|
||||||
Ostream&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Calculate pointEdges
|
//- Calculate pointEdges
|
||||||
void calcPointEdges();
|
void calcPointEdges();
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ License
|
|||||||
|
|
||||||
#include "surfaceIntersection.H"
|
#include "surfaceIntersection.H"
|
||||||
#include "triSurfaceSearch.H"
|
#include "triSurfaceSearch.H"
|
||||||
#include "OFstream.H"
|
#include "OBJstream.H"
|
||||||
#include "labelPairHashes.H"
|
#include "labelPairHashes.H"
|
||||||
#include "triSurface.H"
|
#include "triSurface.H"
|
||||||
#include "pointIndexHit.H"
|
#include "pointIndexHit.H"
|
||||||
@ -47,7 +47,7 @@ void Foam::surfaceIntersection::setOptions(const dictionary& dict)
|
|||||||
{
|
{
|
||||||
dict.readIfPresent("tolerance", tolerance_);
|
dict.readIfPresent("tolerance", tolerance_);
|
||||||
dict.readIfPresent("allowEdgeHits", allowEdgeHits_);
|
dict.readIfPresent("allowEdgeHits", allowEdgeHits_);
|
||||||
dict.readIfPresent("avoidDuplicates", avoidDuplicates_);
|
dict.readIfPresent("snap", snapToEnd_);
|
||||||
dict.readIfPresent("warnDegenerate", warnDegenerate_);
|
dict.readIfPresent("warnDegenerate", warnDegenerate_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,42 +101,64 @@ void Foam::surfaceIntersection::storeIntersection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
labelPairLookup::const_iterator iter = facePairToVertex_.find(twoFaces);
|
|
||||||
|
|
||||||
if (iter == facePairToVertex_.end())
|
// Get existing edge, or create a null edge (with -1)
|
||||||
|
edge& thisEdge = facePairToEdge_(twoFaces);
|
||||||
|
const label pointCount = thisEdge.count();
|
||||||
|
|
||||||
|
if (pointCount == 0)
|
||||||
{
|
{
|
||||||
// New intersection. Store face-face intersection.
|
// First intersection of the faces - record it.
|
||||||
|
thisEdge.insert(cutPointId);
|
||||||
|
|
||||||
if (debug & 4)
|
if (debug & 4)
|
||||||
{
|
{
|
||||||
Pout<< "intersect faces " << twoFaces
|
Pout<< "intersect faces " << twoFaces
|
||||||
<< " point-1: " << cutPointId << " = "
|
<< " point-1: " << cutPointId << " = "
|
||||||
<< allCutPoints[cutPointId] << endl;
|
<< allCutPoints[cutPointId] << endl;
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
facePairToVertex_.insert(twoFaces, cutPointId);
|
|
||||||
}
|
}
|
||||||
else if (*iter == cutPointId)
|
else if (pointCount == 2)
|
||||||
{
|
{
|
||||||
// Avoid creating an edge if cutPointId had already been used
|
// This occurs for ugly surfaces with shards that result in multiple
|
||||||
|
// cuts very near a snapped end point.
|
||||||
if (debug & 4)
|
if (debug & 4)
|
||||||
{
|
{
|
||||||
Pout<< "intersect faces " << twoFaces
|
Pout<< "suppressed double intersection " << twoFaces
|
||||||
<< " dup-point: " << cutPointId << endl;
|
<< thisEdge << endl;
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (thisEdge.insert(cutPointId))
|
||||||
{
|
{
|
||||||
const label nextEdgeId = allCutEdges.size();
|
// Second intersection of the faces - this is an edge,
|
||||||
const edge nextEdge(*iter, cutPointId, true);
|
// with special treatment:
|
||||||
|
// - avoid duplicate points: addressed by the insert() above
|
||||||
|
// - avoid degenerate lengths
|
||||||
|
// - avoid duplicate edges - can occur with really dirty geometry
|
||||||
|
|
||||||
// Second occurrence of surf1-surf2 intersection.
|
if (edgeToId_.found(thisEdge))
|
||||||
// Or rather the face on surf1 intersects a face on
|
|
||||||
// surface2 twice -> we found edge.
|
|
||||||
|
|
||||||
// Check whether perhaps degenerate
|
|
||||||
if (nextEdge.mag(allCutPoints) < SMALL)
|
|
||||||
{
|
{
|
||||||
|
// Already have this edgeId, but not for this intersection.
|
||||||
|
thisEdge.sort();
|
||||||
|
if (facePairToEdge_.insert(twoFaces, thisEdge))
|
||||||
|
{
|
||||||
|
if (debug & 4)
|
||||||
|
{
|
||||||
|
Pout<< "reuse edge - faces " << twoFaces << " edge#"
|
||||||
|
<< edgeToId_[thisEdge] << " edge " << thisEdge
|
||||||
|
<< " = " << thisEdge.line(allCutPoints)
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (thisEdge.mag(allCutPoints) < SMALL)
|
||||||
|
{
|
||||||
|
// Degenerate length
|
||||||
|
// - eg, end snapping was disabled or somehow failed.
|
||||||
|
|
||||||
// Don't normally emit warnings, since these also arise for
|
// Don't normally emit warnings, since these also arise for
|
||||||
// manifold connections. For example,
|
// manifold connections. For example,
|
||||||
//
|
//
|
||||||
@ -147,10 +169,6 @@ void Foam::surfaceIntersection::storeIntersection
|
|||||||
//
|
//
|
||||||
// The plane is correctly pierced at the '.' by both edge-1
|
// The plane is correctly pierced at the '.' by both edge-1
|
||||||
// and edge-2, which belong to the same originating face.
|
// and edge-2, which belong to the same originating face.
|
||||||
//
|
|
||||||
// Unfortunately cannot suppress the second hit either, since
|
|
||||||
// it might already have been used for another face-pair
|
|
||||||
// intersection.
|
|
||||||
|
|
||||||
// Filter/merge away the extraneous points later.
|
// Filter/merge away the extraneous points later.
|
||||||
if (warnDegenerate_ > 0)
|
if (warnDegenerate_ > 0)
|
||||||
@ -159,31 +177,55 @@ void Foam::surfaceIntersection::storeIntersection
|
|||||||
WarningInFunction
|
WarningInFunction
|
||||||
<< "Degenerate edge between faces " << twoFaces
|
<< "Degenerate edge between faces " << twoFaces
|
||||||
<< " on 1st/2nd surface with points "
|
<< " on 1st/2nd surface with points "
|
||||||
<< nextEdge.line(allCutPoints)
|
<< thisEdge.line(allCutPoints)
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
else if (debug & 4)
|
else if (debug & 4)
|
||||||
{
|
{
|
||||||
Pout<< "degenerate edge face-pair " << twoFaces << " "
|
Pout<< "degenerate edge face-pair " << twoFaces << " "
|
||||||
<< *iter << " point " << allCutPoints[*iter]
|
<< thisEdge[0] << " point " << allCutPoints[thisEdge[0]]
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a failed edge - undo this second interaction
|
||||||
|
thisEdge.erase(cutPointId);
|
||||||
}
|
}
|
||||||
else if (facePairToEdge_.insert(twoFaces, nextEdgeId))
|
else
|
||||||
{
|
{
|
||||||
// Record complete (line) intersection of two faces
|
// This is a new edge.
|
||||||
|
const label edgeId = allCutEdges.size();
|
||||||
|
|
||||||
allCutEdges.append(nextEdge);
|
if (facePairToEdgeId_.insert(twoFaces, edgeId))
|
||||||
|
|
||||||
if (debug & 4)
|
|
||||||
{
|
{
|
||||||
Pout<< "create edge - faces " << twoFaces << " edge#"
|
// Record complete (line) intersection of two faces
|
||||||
<< nextEdgeId << " edge " << nextEdge
|
thisEdge.sort();
|
||||||
<< " = " << nextEdge.line(allCutPoints)
|
edgeToId_.insert(thisEdge, edgeId);
|
||||||
<< endl;
|
allCutEdges.append(thisEdge);
|
||||||
|
|
||||||
|
if (debug & 4)
|
||||||
|
{
|
||||||
|
Pout<< "create edge - faces " << twoFaces << " edge#"
|
||||||
|
<< edgeId << " edge " << thisEdge
|
||||||
|
<< " = " << thisEdge.line(allCutPoints)
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Faces already had an intersection
|
||||||
|
// This should not fail, but for safety.
|
||||||
|
Info<<"WARN " << twoFaces
|
||||||
|
<< " already intersected= " << thisEdge << endl;
|
||||||
|
thisEdge.erase(cutPointId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Duplicate point - usually zero-length edge from snapping
|
||||||
|
// - can discard this face/face interaction entirely
|
||||||
|
facePairToEdge_.erase(twoFaces);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +254,7 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
List<DynamicList<label>>& surfEdgeCuts
|
List<DynamicList<label>>& surfEdgeCuts
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const edge& e = surf1.edges()[edgeI];
|
const edge& e1 = surf1.edges()[edgeI];
|
||||||
|
|
||||||
const labelList& facesA = surf1.edgeFaces()[edgeI];
|
const labelList& facesA = surf1.edgeFaces()[edgeI];
|
||||||
|
|
||||||
@ -233,10 +275,10 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
const label edgeEnd =
|
const label edgeEnd =
|
||||||
classify
|
classify
|
||||||
(
|
(
|
||||||
surf1PointTol[e.start()],
|
surf1PointTol[e1.start()],
|
||||||
surf1PointTol[e.end()],
|
surf1PointTol[e1.end()],
|
||||||
pHit.hitPoint(),
|
pHit.hitPoint(),
|
||||||
e,
|
e1,
|
||||||
surf1Pts
|
surf1Pts
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -248,8 +290,8 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< "hit-type[1] " << pHit.hitPoint() << " is surf1:"
|
Pout<< "hit-type[1] " << pHit.hitPoint() << " is surf1:"
|
||||||
<< " end point of edge[" << edgeI << "] " << e
|
<< " end point of edge[" << edgeI << "] " << e1
|
||||||
<< "==" << e.line(surf1Pts)
|
<< "==" << e1.line(surf1Pts)
|
||||||
<< " surf2: vertex " << f2[nearLabel]
|
<< " surf2: vertex " << f2[nearLabel]
|
||||||
<< " coord:" << surf2Pts[f2[nearLabel]]
|
<< " coord:" << surf2Pts[f2[nearLabel]]
|
||||||
<< " - suppressed" << endl;
|
<< " - suppressed" << endl;
|
||||||
@ -258,7 +300,6 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 2. Edge hits point. Cut edge with new point.
|
// 2. Edge hits point. Cut edge with new point.
|
||||||
bool cached = false;
|
|
||||||
label cutPointId = -1;
|
label cutPointId = -1;
|
||||||
const label nearVert = f2[nearLabel];
|
const label nearVert = f2[nearLabel];
|
||||||
|
|
||||||
@ -269,22 +310,25 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
{
|
{
|
||||||
const point& nearPt = surf1Pts[nearVert];
|
const point& nearPt = surf1Pts[nearVert];
|
||||||
|
|
||||||
if (mag(pHit.hitPoint() - nearPt) < surf1PointTol[nearVert])
|
if
|
||||||
|
(
|
||||||
|
mag(pHit.hitPoint() - nearPt)
|
||||||
|
< surf1PointTol[nearVert]
|
||||||
|
)
|
||||||
{
|
{
|
||||||
cutPointId = allCutPoints.size();
|
cutPointId = allCutPoints.size();
|
||||||
|
|
||||||
if (avoidDuplicates_)
|
if (snapToEnd_)
|
||||||
{
|
{
|
||||||
if (edgeEndAsCut_.insert(nearVert, cutPointId))
|
if (snappedEnds_.insert(nearVert, cutPointId))
|
||||||
{
|
{
|
||||||
// First time with this end-point
|
// Initial snap
|
||||||
allCutPoints.append(nearPt);
|
allCutPoints.append(nearPt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Already seen this end point
|
// Already snapped this point.
|
||||||
cutPointId = edgeEndAsCut_[nearVert];
|
cutPointId = snappedEnds_[nearVert];
|
||||||
cached = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -297,11 +341,11 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< "hit-type[2] " << pHit.hitPoint() << " is surf1:"
|
Pout<< "hit-type[2] " << pHit.hitPoint() << " is surf1:"
|
||||||
<< " from edge[" << edgeI << "] " << e
|
<< " from edge[" << edgeI << "] " << e1
|
||||||
<< " surf2: vertex " << f2[nearLabel]
|
<< " surf2: vertex " << f2[nearLabel]
|
||||||
<< " coord:" << surf2Pts[f2[nearLabel]]
|
<< " coord:" << surf2Pts[f2[nearLabel]]
|
||||||
<< " - "
|
<< " - "
|
||||||
<< (cached ? "cached" : "stored") << endl;
|
<< (cutPointId >= 0 ? "snapped" : "stored") << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cutPointId == -1)
|
if (cutPointId == -1)
|
||||||
@ -339,7 +383,7 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
|
|
||||||
const label edge2I = getEdge(surf2, surf2Facei, nearLabel);
|
const label edge2I = getEdge(surf2, surf2Facei, nearLabel);
|
||||||
const edge& e2 = surf2.edges()[edge2I];
|
const edge& e2 = surf2.edges()[edge2I];
|
||||||
const label nearVert = (edgeEnd == 0 ? e.start() : e.end());
|
const label nearVert = e1[edgeEnd];
|
||||||
|
|
||||||
label cutPointId = -1;
|
label cutPointId = -1;
|
||||||
|
|
||||||
@ -367,22 +411,23 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
mag(pHit.hitPoint() - nearPt) < surf1PointTol[nearVert]
|
mag(pHit.hitPoint() - nearPt)
|
||||||
|
< surf1PointTol[nearVert]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cutPointId = allCutPoints.size();
|
cutPointId = allCutPoints.size();
|
||||||
|
|
||||||
if (avoidDuplicates_)
|
if (snapToEnd_)
|
||||||
{
|
{
|
||||||
if (edgeEndAsCut_.insert(nearVert, cutPointId))
|
if (snappedEnds_.insert(nearVert, cutPointId))
|
||||||
{
|
{
|
||||||
// First time with this end-point
|
// Initial snap
|
||||||
allCutPoints.append(nearPt);
|
allCutPoints.append(nearPt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Already seen this end point
|
// Already snapped this point.
|
||||||
cutPointId = edgeEndAsCut_[nearVert];
|
cutPointId = snappedEnds_[nearVert];
|
||||||
handling = 2; // cached
|
handling = 2; // cached
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -401,8 +446,8 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< "hit-type[3] " << pHit.hitPoint() << " is surf1:"
|
Pout<< "hit-type[3] " << pHit.hitPoint() << " is surf1:"
|
||||||
<< " end point of edge[" << edgeI << "] " << e
|
<< " end point of edge[" << edgeI << "] " << e1
|
||||||
<< "==" << e.line(surf1Pts)
|
<< "==" << e1.line(surf1Pts)
|
||||||
<< " surf2: edge[" << edge2I << "] " << e2
|
<< " surf2: edge[" << edge2I << "] " << e2
|
||||||
<< " coords:" << e2.line(surf2Pts)
|
<< " coords:" << e2.line(surf2Pts)
|
||||||
<< " - "
|
<< " - "
|
||||||
@ -482,9 +527,9 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
if (edgeEdgeIntersection_.insert(intersect))
|
if (edgeEdgeIntersection_.insert(intersect))
|
||||||
{
|
{
|
||||||
handling = 1;
|
handling = 1;
|
||||||
forAll(e, edgepti)
|
forAll(e1, edgepti)
|
||||||
{
|
{
|
||||||
const label endId = e[edgepti];
|
const label endId = e1[edgepti];
|
||||||
const point& nearPt = surf1Pts[endId];
|
const point& nearPt = surf1Pts[endId];
|
||||||
|
|
||||||
if
|
if
|
||||||
@ -495,9 +540,9 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
{
|
{
|
||||||
cutPointId = allCutPoints.size();
|
cutPointId = allCutPoints.size();
|
||||||
|
|
||||||
if (avoidDuplicates_)
|
if (snapToEnd_)
|
||||||
{
|
{
|
||||||
if (edgeEndAsCut_.insert(endId, cutPointId))
|
if (snappedEnds_.insert(endId, cutPointId))
|
||||||
{
|
{
|
||||||
// First time with this end-point
|
// First time with this end-point
|
||||||
allCutPoints.append(nearPt);
|
allCutPoints.append(nearPt);
|
||||||
@ -505,7 +550,7 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Already seen this end point
|
// Already seen this end point
|
||||||
cutPointId = edgeEndAsCut_[endId];
|
cutPointId = snappedEnds_[endId];
|
||||||
handling = 2; // cached
|
handling = 2; // cached
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -524,8 +569,8 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< "hit-type[4] " << pHit.hitPoint() << " is surf1:"
|
Pout<< "hit-type[4] " << pHit.hitPoint() << " is surf1:"
|
||||||
<< " from edge[" << edgeI << "] " << e
|
<< " from edge[" << edgeI << "] " << e1
|
||||||
<< "==" << e.line(surf1Pts)
|
<< "==" << e1.line(surf1Pts)
|
||||||
<< " surf2: edge[" << edge2I << "] " << e2
|
<< " surf2: edge[" << edge2I << "] " << e2
|
||||||
<< " coords:" << e2.line(surf2Pts)
|
<< " coords:" << e2.line(surf2Pts)
|
||||||
<< " - "
|
<< " - "
|
||||||
@ -549,18 +594,28 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
|
|
||||||
if (handling)
|
if (handling)
|
||||||
{
|
{
|
||||||
|
const vector eVec = e1.unitVec(surf1Pts);
|
||||||
|
|
||||||
const labelList& facesB = surf2.edgeFaces()[edge2I];
|
const labelList& facesB = surf2.edgeFaces()[edge2I];
|
||||||
forAll(facesB, faceBI)
|
forAll(facesB, faceBI)
|
||||||
{
|
{
|
||||||
storeIntersection
|
// Intersecting edge should be non-coplanar with face
|
||||||
|
if
|
||||||
(
|
(
|
||||||
cutFrom,
|
mag((surf2.faceNormals()[facesB[faceBI]] & eVec))
|
||||||
facesA,
|
> 0.01
|
||||||
facesB[faceBI],
|
)
|
||||||
allCutPoints,
|
{
|
||||||
cutPointId,
|
storeIntersection
|
||||||
allCutEdges
|
(
|
||||||
);
|
cutFrom,
|
||||||
|
facesA,
|
||||||
|
facesB[faceBI],
|
||||||
|
allCutPoints,
|
||||||
|
cutPointId,
|
||||||
|
allCutEdges
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -577,8 +632,8 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
|
|
||||||
// Vertex on/near surf2; vertex away from surf2
|
// Vertex on/near surf2; vertex away from surf2
|
||||||
// otherVert on outside of surf2
|
// otherVert on outside of surf2
|
||||||
const label nearVert = (edgeEnd == 0 ? e.start() : e.end());
|
const label nearVert = (edgeEnd == 0 ? e1.start() : e1.end());
|
||||||
const label otherVert = (edgeEnd == 0 ? e.end() : e.start());
|
const label otherVert = (edgeEnd == 0 ? e1.end() : e1.start());
|
||||||
|
|
||||||
const point& nearPt = surf1Pts[nearVert];
|
const point& nearPt = surf1Pts[nearVert];
|
||||||
const point& otherPt = surf1Pts[otherVert];
|
const point& otherPt = surf1Pts[otherVert];
|
||||||
@ -592,9 +647,9 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
bool cached = false;
|
bool cached = false;
|
||||||
|
|
||||||
label cutPointId = allCutPoints.size();
|
label cutPointId = allCutPoints.size();
|
||||||
if (avoidDuplicates_)
|
if (snapToEnd_)
|
||||||
{
|
{
|
||||||
if (edgeEndAsCut_.insert(nearVert, cutPointId))
|
if (snappedEnds_.insert(nearVert, cutPointId))
|
||||||
{
|
{
|
||||||
// First time with this end-point
|
// First time with this end-point
|
||||||
allCutPoints.append(nearPt);
|
allCutPoints.append(nearPt);
|
||||||
@ -602,7 +657,7 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Already seen this end point
|
// Already seen this end point
|
||||||
cutPointId = edgeEndAsCut_[nearVert];
|
cutPointId = snappedEnds_[nearVert];
|
||||||
cached = true;
|
cached = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,8 +672,8 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
{
|
{
|
||||||
Pout<< "hit-type[5] " << pHit.hitPoint()
|
Pout<< "hit-type[5] " << pHit.hitPoint()
|
||||||
<< " shifted to " << nearPt
|
<< " shifted to " << nearPt
|
||||||
<< " from edge[" << edgeI << "] " << e
|
<< " from edge[" << edgeI << "] " << e1
|
||||||
<< "==" << e.line(surf1Pts)
|
<< "==" << e1.line(surf1Pts)
|
||||||
<< " hits surf2 face[" << surf2Facei << "]"
|
<< " hits surf2 face[" << surf2Facei << "]"
|
||||||
<< " - "
|
<< " - "
|
||||||
<< (cached ? "cached" : "stored") << endl;
|
<< (cached ? "cached" : "stored") << endl;
|
||||||
@ -640,7 +695,7 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< "hit-type[5] " << pHit.hitPoint()
|
Pout<< "hit-type[5] " << pHit.hitPoint()
|
||||||
<< " from edge[" << edgeI << "] " << e
|
<< " from edge[" << edgeI << "] " << e1
|
||||||
<< " hits inside of surf2 face[" << surf2Facei << "]"
|
<< " hits inside of surf2 face[" << surf2Facei << "]"
|
||||||
<< " - discarded" << endl;
|
<< " - discarded" << endl;
|
||||||
}
|
}
|
||||||
@ -652,8 +707,8 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< "hit-type[6] " << pHit.hitPoint()
|
Pout<< "hit-type[6] " << pHit.hitPoint()
|
||||||
<< " from edge[" << edgeI << "] " << e
|
<< " from edge[" << edgeI << "] " << e1
|
||||||
<< "==" << e.line(surf1Pts)
|
<< "==" << e1.line(surf1Pts)
|
||||||
<< " hits surf2 face[" << surf2Facei << "]"
|
<< " hits surf2 face[" << surf2Facei << "]"
|
||||||
<< " - stored" << endl;
|
<< " - stored" << endl;
|
||||||
}
|
}
|
||||||
@ -680,8 +735,8 @@ void Foam::surfaceIntersection::classifyHit
|
|||||||
// Cut all edges of surf1 with surf2. Sets
|
// Cut all edges of surf1 with surf2. Sets
|
||||||
// - cutPoints : coordinates of cutPoints
|
// - cutPoints : coordinates of cutPoints
|
||||||
// - cutEdges : newly created edges between cutPoints
|
// - cutEdges : newly created edges between cutPoints
|
||||||
// - facePairToVertex : hash from face1I and face2I to (first) cutPoint
|
// - facePairToVertex : hash from face1I and face2I to edge
|
||||||
// - facePairToEdge : hash from face1I and face2I to cutEdge
|
// - facePairToEdgeId : hash from face1I and face2I to index in cutEdge
|
||||||
// - surfEdgeCuts : gives for each edge the cutPoints
|
// - surfEdgeCuts : gives for each edge the cutPoints
|
||||||
// (in order from start to end)
|
// (in order from start to end)
|
||||||
//
|
//
|
||||||
@ -716,7 +771,7 @@ void Foam::surfaceIntersection::doCutEdges
|
|||||||
// An edge may intersect multiple faces
|
// An edge may intersect multiple faces
|
||||||
// - mask out faces that have already been hit before trying again
|
// - mask out faces that have already been hit before trying again
|
||||||
// - never intersect with faces attached to the edge itself
|
// - never intersect with faces attached to the edge itself
|
||||||
DynamicList<label> maskFaces(8);
|
DynamicList<label> maskFaces(32);
|
||||||
|
|
||||||
treeDataTriSurface::findAllIntersectOp
|
treeDataTriSurface::findAllIntersectOp
|
||||||
allIntersectOp(searchTree, maskFaces);
|
allIntersectOp(searchTree, maskFaces);
|
||||||
@ -732,8 +787,12 @@ void Foam::surfaceIntersection::doCutEdges
|
|||||||
const point ptEnd =
|
const point ptEnd =
|
||||||
surf1Pts[e.end()] + 0.5*surf1PointTol[e.end()]*edgeVec;
|
surf1Pts[e.end()] + 0.5*surf1PointTol[e.end()]*edgeVec;
|
||||||
|
|
||||||
// Never intersect with faces attached to the edge itself
|
// Never intersect with faces attached directly to the edge itself,
|
||||||
maskFaces = surf1.edgeFaces()[edgeI];
|
// nor with faces attached to its end points. This mask contains
|
||||||
|
// some duplicates, but filtering them out is less efficient.
|
||||||
|
maskFaces = surf1.pointFaces()[e.start()];
|
||||||
|
maskFaces.append(surf1.pointFaces()[e.end()]);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
pointIndexHit pHit = searchTree.findLine
|
pointIndexHit pHit = searchTree.findLine
|
||||||
@ -833,24 +892,110 @@ void Foam::surfaceIntersection::doCutEdges
|
|||||||
|
|
||||||
// These temporaries are now unneeded:
|
// These temporaries are now unneeded:
|
||||||
edgeEdgeIntersection_.clear();
|
edgeEdgeIntersection_.clear();
|
||||||
edgeEndAsCut_.clear();
|
snappedEnds_.clear();
|
||||||
|
|
||||||
intersection::setPlanarTol(oldTol);
|
intersection::setPlanarTol(oldTol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::surfaceIntersection::joinDisconnected
|
||||||
|
(
|
||||||
|
DynamicList<edge>& allCutEdges
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// This simple heuristic seems to work just as well (or better) than
|
||||||
|
// more complicated schemes
|
||||||
|
//
|
||||||
|
// For any face/face intersection that only appears once,
|
||||||
|
// consider which other faces/points are involved and connect between
|
||||||
|
// those points.
|
||||||
|
// Just do a simple connect-the-dots?
|
||||||
|
|
||||||
|
Pair<Map<labelPairHashSet>> missedFacePoint;
|
||||||
|
|
||||||
|
// Stage 1:
|
||||||
|
// - Extract "faceId -> (faceId, pointId)"
|
||||||
|
// for all face/face pairs that only have one interaction
|
||||||
|
forAllConstIters(facePairToEdge_, iter)
|
||||||
|
{
|
||||||
|
const labelPair& twoFaces = iter.key();
|
||||||
|
const edge& e = iter.object();
|
||||||
|
|
||||||
|
if (e.count() == 1)
|
||||||
|
{
|
||||||
|
// minVertex = -1 (unused), maxVertex = pointId
|
||||||
|
const label pointId = e.maxVertex();
|
||||||
|
|
||||||
|
missedFacePoint[0](twoFaces[0]).insert
|
||||||
|
(
|
||||||
|
labelPair(twoFaces[1], pointId)
|
||||||
|
);
|
||||||
|
|
||||||
|
missedFacePoint[1](twoFaces[1]).insert
|
||||||
|
(
|
||||||
|
labelPair(twoFaces[0], pointId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Stage 2:
|
||||||
|
// - anything with two cross-interactions could cause a new edge:
|
||||||
|
|
||||||
|
edgeHashSet newEdges;
|
||||||
|
forAll(missedFacePoint, sidei)
|
||||||
|
{
|
||||||
|
const auto& mapping = missedFacePoint[sidei];
|
||||||
|
|
||||||
|
forAllConstIters(mapping, iter)
|
||||||
|
{
|
||||||
|
const auto& connect = iter.object();
|
||||||
|
|
||||||
|
if (connect.size() == 2)
|
||||||
|
{
|
||||||
|
// exactly two face/face cross-interactions
|
||||||
|
|
||||||
|
edge e;
|
||||||
|
for (const auto& facePoint : connect)
|
||||||
|
{
|
||||||
|
e.insert(facePoint.second());
|
||||||
|
}
|
||||||
|
e.sort();
|
||||||
|
|
||||||
|
// Only consider edges with two unique ends,
|
||||||
|
// and do not introduce duplicates
|
||||||
|
if (e.count() == 2 && !edgeToId_.found(e))
|
||||||
|
{
|
||||||
|
newEdges.insert(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label edgeId = allCutEdges.size();
|
||||||
|
edgeList newEdgesLst = newEdges.sortedToc();
|
||||||
|
for (const auto& e : newEdgesLst)
|
||||||
|
{
|
||||||
|
// Record complete (line) intersection of two faces
|
||||||
|
allCutEdges.append(e);
|
||||||
|
edgeToId_.insert(e, edgeId);
|
||||||
|
++edgeId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::surfaceIntersection::surfaceIntersection()
|
Foam::surfaceIntersection::surfaceIntersection()
|
||||||
:
|
:
|
||||||
tolerance_(1e-3),
|
tolerance_(1e-3),
|
||||||
allowEdgeHits_(true),
|
allowEdgeHits_(true),
|
||||||
avoidDuplicates_(true),
|
snapToEnd_(true),
|
||||||
warnDegenerate_(0),
|
warnDegenerate_(0),
|
||||||
cutPoints_(0),
|
cutPoints_(0),
|
||||||
cutEdges_(0),
|
cutEdges_(0),
|
||||||
facePairToVertex_(0),
|
|
||||||
facePairToEdge_(0),
|
facePairToEdge_(0),
|
||||||
|
facePairToEdgeId_(0),
|
||||||
surf1EdgeCuts_(0),
|
surf1EdgeCuts_(0),
|
||||||
surf2EdgeCuts_(0)
|
surf2EdgeCuts_(0)
|
||||||
{}
|
{}
|
||||||
@ -865,12 +1010,12 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
:
|
:
|
||||||
tolerance_(1e-3),
|
tolerance_(1e-3),
|
||||||
allowEdgeHits_(true),
|
allowEdgeHits_(true),
|
||||||
avoidDuplicates_(true),
|
snapToEnd_(true),
|
||||||
warnDegenerate_(0),
|
warnDegenerate_(0),
|
||||||
cutPoints_(0),
|
cutPoints_(0),
|
||||||
cutEdges_(0),
|
cutEdges_(0),
|
||||||
facePairToVertex_(2*max(query1.surface().size(), query2.surface().size())),
|
|
||||||
facePairToEdge_(2*max(query1.surface().size(), query2.surface().size())),
|
facePairToEdge_(2*max(query1.surface().size(), query2.surface().size())),
|
||||||
|
facePairToEdgeId_(2*max(query1.surface().size(), query2.surface().size())),
|
||||||
surf1EdgeCuts_(0),
|
surf1EdgeCuts_(0),
|
||||||
surf2EdgeCuts_(0)
|
surf2EdgeCuts_(0)
|
||||||
{
|
{
|
||||||
@ -931,6 +1076,9 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
edgeCuts2
|
edgeCuts2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// join disconnected intersection points
|
||||||
|
joinDisconnected(allCutEdges);
|
||||||
|
|
||||||
// Transfer to straight label(List)List
|
// Transfer to straight label(List)List
|
||||||
transfer(edgeCuts2, surf2EdgeCuts_);
|
transfer(edgeCuts2, surf2EdgeCuts_);
|
||||||
cutEdges_.transfer(allCutEdges);
|
cutEdges_.transfer(allCutEdges);
|
||||||
@ -946,8 +1094,7 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
Pout<< "surfaceIntersection : Writing intersection to intEdges.obj"
|
Pout<< "surfaceIntersection : Writing intersection to intEdges.obj"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
OFstream intStream("intEdges.obj");
|
OBJstream("intEdges.obj").write(cutEdges_, cutPoints_);
|
||||||
writeOBJ(cutPoints_, cutEdges_, intStream);
|
|
||||||
|
|
||||||
// Dump all cut edges to files
|
// Dump all cut edges to files
|
||||||
Pout<< "Dumping cut edges of surface1 to surf1EdgeCuts.obj" << endl;
|
Pout<< "Dumping cut edges of surface1 to surf1EdgeCuts.obj" << endl;
|
||||||
@ -960,9 +1107,9 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Temporaries
|
// Temporaries
|
||||||
facePairToVertex_.clear();
|
facePairToEdge_.clear();
|
||||||
|
|
||||||
// // Cleanup any duplicate cuts?
|
// Cleanup any duplicate cuts?
|
||||||
// mergeEdges();
|
// mergeEdges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -975,12 +1122,12 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
:
|
:
|
||||||
tolerance_(1e-3),
|
tolerance_(1e-3),
|
||||||
allowEdgeHits_(true),
|
allowEdgeHits_(true),
|
||||||
avoidDuplicates_(true),
|
snapToEnd_(true),
|
||||||
warnDegenerate_(0),
|
warnDegenerate_(0),
|
||||||
cutPoints_(0),
|
cutPoints_(0),
|
||||||
cutEdges_(0),
|
cutEdges_(0),
|
||||||
facePairToVertex_(2*query1.surface().size()),
|
|
||||||
facePairToEdge_(2*query1.surface().size()),
|
facePairToEdge_(2*query1.surface().size()),
|
||||||
|
facePairToEdgeId_(2*query1.surface().size()),
|
||||||
surf1EdgeCuts_(0),
|
surf1EdgeCuts_(0),
|
||||||
surf2EdgeCuts_(0)
|
surf2EdgeCuts_(0)
|
||||||
{
|
{
|
||||||
@ -1013,6 +1160,9 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
edgeCuts1
|
edgeCuts1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// join disconnected intersection points
|
||||||
|
joinDisconnected(allCutEdges);
|
||||||
|
|
||||||
// Transfer to straight label(List)List
|
// Transfer to straight label(List)List
|
||||||
transfer(edgeCuts1, surf1EdgeCuts_);
|
transfer(edgeCuts1, surf1EdgeCuts_);
|
||||||
cutEdges_.transfer(allCutEdges);
|
cutEdges_.transfer(allCutEdges);
|
||||||
@ -1039,8 +1189,7 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
Pout<< "surfaceIntersection : Writing intersection to intEdges.obj"
|
Pout<< "surfaceIntersection : Writing intersection to intEdges.obj"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
OFstream intStream("intEdges.obj");
|
OBJstream("intEdges.obj").write(cutEdges_, cutPoints_);
|
||||||
writeOBJ(cutPoints_, cutEdges_, intStream);
|
|
||||||
|
|
||||||
// Dump all cut edges to files
|
// Dump all cut edges to files
|
||||||
Pout<< "Dumping cut edges of surface1 to surf1EdgeCuts.obj" << endl;
|
Pout<< "Dumping cut edges of surface1 to surf1EdgeCuts.obj" << endl;
|
||||||
@ -1049,7 +1198,7 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Temporaries
|
// Temporaries
|
||||||
facePairToVertex_.clear();
|
facePairToEdge_.clear();
|
||||||
|
|
||||||
// // Cleanup any duplicate cuts?
|
// // Cleanup any duplicate cuts?
|
||||||
// mergeEdges();
|
// mergeEdges();
|
||||||
@ -1066,12 +1215,12 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
:
|
:
|
||||||
tolerance_(1e-3),
|
tolerance_(1e-3),
|
||||||
allowEdgeHits_(true),
|
allowEdgeHits_(true),
|
||||||
avoidDuplicates_(true),
|
snapToEnd_(true),
|
||||||
warnDegenerate_(0),
|
warnDegenerate_(0),
|
||||||
cutPoints_(0),
|
cutPoints_(0),
|
||||||
cutEdges_(0),
|
cutEdges_(0),
|
||||||
facePairToVertex_(2*max(surf1.size(), surf2.size())),
|
|
||||||
facePairToEdge_(2*max(surf1.size(), surf2.size())),
|
facePairToEdge_(2*max(surf1.size(), surf2.size())),
|
||||||
|
facePairToEdgeId_(2*max(surf1.size(), surf2.size())),
|
||||||
surf1EdgeCuts_(0),
|
surf1EdgeCuts_(0),
|
||||||
surf2EdgeCuts_(0)
|
surf2EdgeCuts_(0)
|
||||||
{
|
{
|
||||||
@ -1180,8 +1329,7 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
Pout<< "surfaceIntersection : Writing intersection to intEdges.obj"
|
Pout<< "surfaceIntersection : Writing intersection to intEdges.obj"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
OFstream intStream("intEdges.obj");
|
OBJstream("intEdges.obj").write(cutEdges_, cutPoints_);
|
||||||
writeOBJ(cutPoints_, cutEdges_, intStream);
|
|
||||||
|
|
||||||
// Dump all cut edges to files
|
// Dump all cut edges to files
|
||||||
Pout<< "Dumping cut edges of surface1 to surf1EdgeCuts.obj" << endl;
|
Pout<< "Dumping cut edges of surface1 to surf1EdgeCuts.obj" << endl;
|
||||||
@ -1193,37 +1341,8 @@ Foam::surfaceIntersection::surfaceIntersection
|
|||||||
writeIntersectedEdges(surf2, surf2EdgeCuts_, edge2Stream);
|
writeIntersectedEdges(surf2, surf2EdgeCuts_, edge2Stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Debugging stuff
|
|
||||||
{
|
|
||||||
// Check all facePairToVertex is used.
|
|
||||||
labelHashSet usedPoints;
|
|
||||||
|
|
||||||
forAllConstIter(labelPairLookup, facePairToEdge_, iter)
|
|
||||||
{
|
|
||||||
const label edgeI = iter();
|
|
||||||
const edge& e = cutEdges_[edgeI];
|
|
||||||
|
|
||||||
usedPoints.insert(e[0]);
|
|
||||||
usedPoints.insert(e[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
forAllConstIter(labelPairLookup, facePairToVertex_, iter)
|
|
||||||
{
|
|
||||||
const label pointi = iter();
|
|
||||||
|
|
||||||
if (!usedPoints.found(pointi))
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "Problem: cut point:" << pointi
|
|
||||||
<< " coord:" << cutPoints_[pointi]
|
|
||||||
<< " not used by any edge" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temporaries
|
// Temporaries
|
||||||
facePairToVertex_.clear();
|
facePairToEdge_.clear();
|
||||||
|
|
||||||
// // Cleanup any duplicate cuts?
|
// // Cleanup any duplicate cuts?
|
||||||
// mergeEdges();
|
// mergeEdges();
|
||||||
@ -1244,9 +1363,9 @@ const Foam::edgeList& Foam::surfaceIntersection::cutEdges() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Foam::labelPairLookup& Foam::surfaceIntersection::facePairToEdge() const
|
const Foam::labelPairLookup& Foam::surfaceIntersection::facePairToEdgeId() const
|
||||||
{
|
{
|
||||||
return facePairToEdge_;
|
return facePairToEdgeId_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1349,9 +1468,9 @@ void Foam::surfaceIntersection::mergeEdges()
|
|||||||
// if (nUniqEdges < cutEdges_.size())
|
// if (nUniqEdges < cutEdges_.size())
|
||||||
// {
|
// {
|
||||||
// // Additional safety, in case the edge was replaced?
|
// // Additional safety, in case the edge was replaced?
|
||||||
// forAllIter(labelPairLookup, facePairToEdge_, iter)
|
// forAllIters(facePairToEdge_, iter)
|
||||||
// {
|
// {
|
||||||
// iter() = edgeNumbering[iter()];
|
// iter.object() = edgeNumbering[iter.object()];
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ Description
|
|||||||
Property | Description | Type | Default value
|
Property | Description | Type | Default value
|
||||||
tolerance | Edge-length tolerance | scalar | 1e-3
|
tolerance | Edge-length tolerance | scalar | 1e-3
|
||||||
allowEdgeHits | Edge-end cuts another edge | bool | true
|
allowEdgeHits | Edge-end cuts another edge | bool | true
|
||||||
avoidDuplicates | Reduce the number of duplicate points | bool | true
|
snap | Snap near end-points | bool | true
|
||||||
warnDegenerate | Number of warnings about degenerate edges | label | 0
|
warnDegenerate | Number of warnings about degenerate edges | label | 0
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
@ -66,11 +66,11 @@ SourceFiles
|
|||||||
|
|
||||||
#include "DynamicList.H"
|
#include "DynamicList.H"
|
||||||
#include "point.H"
|
#include "point.H"
|
||||||
#include "edge.H"
|
#include "edgeHashes.H"
|
||||||
#include "labelPairHashes.H"
|
|
||||||
#include "typeInfo.H"
|
|
||||||
#include "edgeList.H"
|
#include "edgeList.H"
|
||||||
|
#include "labelPairHashes.H"
|
||||||
#include "pointIndexHit.H"
|
#include "pointIndexHit.H"
|
||||||
|
#include "typeInfo.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -82,6 +82,14 @@ class triSurfaceSearch;
|
|||||||
class triSurface;
|
class triSurface;
|
||||||
class edgeIntersections;
|
class edgeIntersections;
|
||||||
|
|
||||||
|
|
||||||
|
//- Key is non-commutative pair of labels. Value is commutative pair of labels
|
||||||
|
typedef LabelPairMap<edge> labelPairEdgeLookup;
|
||||||
|
|
||||||
|
//- Map from edge back to all parents (pairs of faces)
|
||||||
|
typedef EdgeMap<labelPairHashSet> edgelabelPairHashLookup;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class surfaceIntersection Declaration
|
Class surfaceIntersection Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -104,8 +112,8 @@ class surfaceIntersection
|
|||||||
//- Allow edge-ends to cut another edge.
|
//- Allow edge-ends to cut another edge.
|
||||||
bool allowEdgeHits_;
|
bool allowEdgeHits_;
|
||||||
|
|
||||||
//- Avoid creating duplicate cuts near edge ends
|
//- Snap cut points near edge ends (default: true)
|
||||||
bool avoidDuplicates_;
|
bool snapToEnd_;
|
||||||
|
|
||||||
//- Maximum number of warnings about degenerate edges
|
//- Maximum number of warnings about degenerate edges
|
||||||
label warnDegenerate_;
|
label warnDegenerate_;
|
||||||
@ -117,27 +125,29 @@ class surfaceIntersection
|
|||||||
// Reference into cutPoints.
|
// Reference into cutPoints.
|
||||||
edgeList cutEdges_;
|
edgeList cutEdges_;
|
||||||
|
|
||||||
//- From face on surf1 and face on surf2 to intersection point
|
|
||||||
// (label in cutPoints)
|
|
||||||
labelPairLookup facePairToVertex_;
|
|
||||||
|
|
||||||
//- From face on surf1 and face on surf2 to intersection edge
|
//- From face on surf1 and face on surf2 to intersection edge
|
||||||
// (label in cutEdges)
|
labelPairEdgeLookup facePairToEdge_;
|
||||||
labelPairLookup facePairToEdge_;
|
|
||||||
|
|
||||||
//- Edges on surf1 that are cut. From edge on surf1 to label in cutPoint
|
//- From face on surf1 and face on surf2 to intersection edgeId
|
||||||
// If multiple cuts:sorted from edge.start to edge.end
|
// (label in cutEdges)
|
||||||
|
labelPairLookup facePairToEdgeId_;
|
||||||
|
|
||||||
|
//- Edges on surf1 that are cut.
|
||||||
|
// From edgeId on surf1 to location in cutPoint
|
||||||
labelListList surf1EdgeCuts_;
|
labelListList surf1EdgeCuts_;
|
||||||
|
|
||||||
//- Edges on surf2 that are cut. From edge on surf2 to label in cutPoint
|
//- Edges on surf2 that are cut.
|
||||||
// If multiple cuts:sorted from edge.start to edge.end
|
// From edgeId on surf2 to location in cutPoint
|
||||||
labelListList surf2EdgeCuts_;
|
labelListList surf2EdgeCuts_;
|
||||||
|
|
||||||
//- Temporary storage to manage edge-edge self-intersections.
|
//- Temporary storage to manage edge-edge self-intersections.
|
||||||
HashSet<edge, Hash<edge>> edgeEdgeIntersection_;
|
edgeHashSet edgeEdgeIntersection_;
|
||||||
|
|
||||||
//- Temporary storage to manage cuts/intersections from the edge ends
|
//- Temporary storage to manage cuts/intersections from the edge ends
|
||||||
Map<label> edgeEndAsCut_;
|
Map<label> snappedEnds_;
|
||||||
|
|
||||||
|
//- Temporary storage
|
||||||
|
EdgeMap<label> edgeToId_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
@ -145,17 +155,6 @@ class surfaceIntersection
|
|||||||
//- Adjust intersection options according to the dictionary entries
|
//- Adjust intersection options according to the dictionary entries
|
||||||
void setOptions(const dictionary& dict);
|
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
|
|
||||||
static void writeOBJ
|
|
||||||
(
|
|
||||||
const List<point>& pts,
|
|
||||||
const List<edge>& edges,
|
|
||||||
Ostream& os
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Transfer contents of List<DynamicList<..>> to List<List<..>>
|
//- Transfer contents of List<DynamicList<..>> to List<List<..>>
|
||||||
template<class T>
|
template<class T>
|
||||||
static void transfer(List<DynamicList<T>>&, List<List<T>>&);
|
static void transfer(List<DynamicList<T>>&, List<List<T>>&);
|
||||||
@ -201,8 +200,8 @@ class surfaceIntersection
|
|||||||
const UList<point>& points
|
const UList<point>& points
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Update reference between faceA and faceB. Updates facePairToVertex_
|
//- Update reference between faceA and faceB.
|
||||||
// (first occurrence of face pair) and facePairToEdge_ (second occ.)
|
// Updates facePairToEdge_ and facePairToEdgeId_ (on the second hit)
|
||||||
void storeIntersection
|
void storeIntersection
|
||||||
(
|
(
|
||||||
const enum originatingType cutFrom,
|
const enum originatingType cutFrom,
|
||||||
@ -241,6 +240,9 @@ class surfaceIntersection
|
|||||||
List<DynamicList<label>>& surfEdgeCuts
|
List<DynamicList<label>>& surfEdgeCuts
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Join disconnected intersection points
|
||||||
|
void joinDisconnected(DynamicList<edge>& allCutEdges);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -292,7 +294,7 @@ public:
|
|||||||
const edgeList& cutEdges() const;
|
const edgeList& cutEdges() const;
|
||||||
|
|
||||||
//- Lookup of pairs of faces to created edges
|
//- Lookup of pairs of faces to created edges
|
||||||
const labelPairLookup& facePairToEdge() const;
|
const labelPairLookup& facePairToEdgeId() const;
|
||||||
|
|
||||||
//- Access either surf1EdgeCuts (isFirstSurface = true) or
|
//- Access either surf1EdgeCuts (isFirstSurface = true) or
|
||||||
// surf2EdgeCuts
|
// surf2EdgeCuts
|
||||||
|
|||||||
@ -29,13 +29,14 @@ License
|
|||||||
#include "labelPairHashes.H"
|
#include "labelPairHashes.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::surfaceIntersection::writeOBJ
|
namespace Foam
|
||||||
(
|
{
|
||||||
const List<point>& pts,
|
|
||||||
Ostream& os
|
// file-scope
|
||||||
)
|
// Write points in obj format
|
||||||
|
static void writeObjPoints(const UList<point>& pts, Ostream& os)
|
||||||
{
|
{
|
||||||
forAll(pts, i)
|
forAll(pts, i)
|
||||||
{
|
{
|
||||||
@ -44,23 +45,10 @@ void Foam::surfaceIntersection::writeOBJ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
void Foam::surfaceIntersection::writeOBJ
|
|
||||||
(
|
|
||||||
const List<point>& pts,
|
|
||||||
const List<edge>& edges,
|
|
||||||
Ostream& os
|
|
||||||
)
|
|
||||||
{
|
|
||||||
writeOBJ(pts, os);
|
|
||||||
|
|
||||||
forAll(edges, i)
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
{
|
|
||||||
const edge& e = edges[i];
|
|
||||||
|
|
||||||
os << "l " << e.start()+1 << ' ' << e.end()+1 << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get minimum length of all edges connected to point
|
// Get minimum length of all edges connected to point
|
||||||
@ -254,8 +242,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();
|
||||||
|
|
||||||
writeOBJ(pts, os);
|
writeObjPoints(pts, os);
|
||||||
writeOBJ(cutPoints(), os);
|
writeObjPoints(cutPoints(), os);
|
||||||
|
|
||||||
forAll(edgeCutVerts, edgeI)
|
forAll(edgeCutVerts, edgeI)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user