50 { booleanOpType::UNION,
"union" },
51 { booleanOpType::INTERSECTION,
"intersection" },
52 { booleanOpType::DIFFERENCE,
"difference" },
53 { booleanOpType::ALL,
"all" },
61void Foam::booleanSurface::checkIncluded
63 const intersectedSurface& surf,
64 const labelList& faceZone,
65 const label includedFace
68 forAll(surf.intersectionEdges(), intEdgeI)
70 label edgeI = surf.intersectionEdges()[intEdgeI];
72 const labelList& myFaces = surf.edgeFaces()[edgeI];
74 bool usesIncluded =
false;
78 if (faceZone[myFaces[myFacei]] == faceZone[includedFace])
89 <<
"None of the faces reachable from face " << includedFace
90 <<
" connects to the intersection."
106 if (elems[elemI] == elem)
115Foam::label Foam::booleanSurface::findEdge
122 forAll(edgeLabels, edgeLabelI)
124 if (edges[edgeLabels[edgeLabelI]] ==
e)
126 return edgeLabels[edgeLabelI];
130 <<
"Cannot find edge " <<
e <<
" in edges " << edgeLabels
141 const triSurface& surf1,
142 const triSurface& surf2,
149 surf1.patches().size()
150 + surf2.patches().size()
154 label combinedPatchi = 0;
155 forAll(surf1.patches(), patchi)
157 combinedPatches[combinedPatchi++] = surf1.patches()[patchi];
161 patchMap2.setSize(surf2.patches().size());
163 forAll(surf2.patches(), patch2I)
167 forAll(surf1.patches(), patch1I)
169 if (surf1.patches()[patch1I] == surf2.patches()[patch2I])
179 combinedPatches[combinedPatchi] = surf2.patches()[patch2I];
180 patchMap2[patch2I] = combinedPatchi;
185 patchMap2[patch2I] = index;
189 combinedPatches.setSize(combinedPatchi);
191 return combinedPatches;
195void Foam::booleanSurface::propagateEdgeSide
197 const triSurface& surf,
198 const label prevVert0,
199 const label prevFacei,
200 const label prevState,
205 const labelList& eFaces = surf.sortedEdgeFaces()[edgeI];
208 if (eFaces.size() == 2)
223 if (((eFaces.size() % 2) == 1) && (eFaces.size() != 1))
226 <<
"Don't know how to handle edges with odd number of faces"
228 <<
"edge:" << edgeI <<
" vertices:" << surf.edges()[edgeI]
229 <<
" coming from face:" << prevFacei
235 label ind = index(eFaces, prevFacei);
239 const edge&
e = surf.edges()[edgeI];
245 if (
e.start() == prevVert0)
250 prevInd = eFaces.rcIndex(ind);
255 nextInd = eFaces.rcIndex(ind);
256 prevInd = eFaces.fcIndex(ind);
260 if (prevState == OUTSIDE)
270 if (eFacei == nextInd)
299 if (eFacei == prevInd)
322void Foam::booleanSurface::propagateSide
324 const triSurface& surf,
325 const label prevState,
330 if (side[facei] == UNVISITED)
332 side[facei] = prevState;
334 const labelledTri& tri = surf.localFaces()[facei];
343 const labelList& myEdges = surf.faceEdges()[facei];
345 label edgeAB =
findEdge(surf.edges(), myEdges, edge(a,
b));
357 label edgeBC =
findEdge(surf.edges(), myEdges, edge(
b, c));
369 label edgeCA =
findEdge(surf.edges(), myEdges, edge(c, a));
399 const label includeFace1,
400 const label includeFace2
408 Pout<<
"booleanSurface : Generating intersected surface for surf1"
418 Pout<<
"booleanSurface : Generated cutSurf1: " <<
endl;
421 Pout<<
"Writing to file cutSurf1.obj" <<
endl;
422 cutSurf1.
write(
"cutSurf1.obj");
427 Pout<<
"booleanSurface : Generating intersected surface for surf2"
436 Pout<<
"booleanSurface : Generated cutSurf2: " <<
endl;
439 Pout<<
"Writing to file cutSurf2.obj" <<
endl;
440 cutSurf2.
write(
"cutSurf2.obj");
445 label cutSurf1Facei = index(cutSurf1.
faceMap(), includeFace1);
449 Pout<<
"cutSurf1 : starting to fill from face:" << cutSurf1Facei
453 if (cutSurf1Facei == -1)
456 <<
"Did not find face with label " << includeFace1
457 <<
" in intersectedSurface."
462 label cutSurf2Facei = index(cutSurf2.
faceMap(), includeFace2);
466 Pout<<
"cutSurf2 : starting to fill from face:" << cutSurf2Facei
469 if (cutSurf2Facei == -1)
472 <<
"Did not find face with label " << includeFace2
473 <<
" in intersectedSurface."
487 forAll(int1Edges, intEdgeI)
489 label edgeI = int1Edges[intEdgeI];
490 isIntersectionEdge1[edgeI] =
true;
494 cutSurf1.
markZones(isIntersectionEdge1, faceZone1);
498 checkIncluded(cutSurf1, faceZone1, cutSurf1Facei);
505 if (faceZone1[facei] == faceZone1[cutSurf1Facei])
507 includedFaces1[facei] =
true;
535 forAll(int2Edges, intEdgeI)
537 label edgeI = int2Edges[intEdgeI];
538 isIntersectionEdge2[edgeI] =
true;
542 cutSurf2.
markZones(isIntersectionEdge2, faceZone2);
546 checkIncluded(cutSurf2, faceZone2, cutSurf2Facei);
553 if (faceZone2[facei] == faceZone2[cutSurf2Facei])
555 includedFaces2[facei] =
true;
600 label combinedPointi = 0;
605 label cutSurfPointi = pointMap1[pointi];
612 intersectionLabels[cutSurfPointi] = combinedPointi;
616 combinedPoints[combinedPointi++] = subSurf1.
points()[pointi];
626 label cutSurfPointi = pointMap2[pointi];
631 pointMap[pointi] = intersectionLabels[cutSurfPointi];
635 pointMap[pointi] = combinedPointi;
637 combinedPoints[combinedPointi++] = subSurf2.
points()[pointi];
668 label combinedFacei = 0;
671 faceMap_[combinedFacei] = faceMap1[facei];
672 combinedFaces[combinedFacei++] = subSurf1[facei];
680 faceMap_[combinedFacei] = -faceMap2[facei]-1;
682 combinedFaces[combinedFacei++] =
688 patchMap2[
f.region()]
710 const label booleanOp
718 Pout<<
"booleanSurface : Testing surf1 and surf2" <<
endl;
727 if (eFaces.
size() == 1)
730 <<
"surf1 is open surface at edge " << edgeI
731 <<
" verts:" << surf1.
edges()[edgeI]
732 <<
" connected to faces " << eFaces <<
endl;
743 if (eFaces.
size() == 1)
746 <<
"surf2 is open surface at edge " << edgeI
747 <<
" verts:" << surf2.
edges()[edgeI]
748 <<
" connected to faces " << eFaces <<
endl;
761 Pout<<
"booleanSurface : Generating intersected surface for surf1"
770 Pout<<
"booleanSurface : Generated cutSurf1: " <<
endl;
773 Pout<<
"Writing to file cutSurf1.obj" <<
endl;
774 cutSurf1.
write(
"cutSurf1.obj");
784 Pout<<
"booleanSurface : Generating intersected surface for surf2"
793 Pout<<
"booleanSurface : Generated cutSurf2: " <<
endl;
796 Pout<<
"Writing to file cutSurf2.obj" <<
endl;
797 cutSurf2.
write(
"cutSurf2.obj");
831 label combinedPointi = 0;
835 combinedPoints[combinedPointi++] = cutSurf1.
points()[pointi];
845 combinedPoints[combinedPointi++] = cutSurf2.
points()[pointi];
855 Pout<<
"booleanSurface : generated points:" <<
nl
857 <<
" : original surface1"
860 <<
" .. " << cutSurf1.
nPoints()-1
861 <<
" : intersection points"
863 <<
" " << cutSurf1.
nPoints() <<
" .. "
865 <<
" : surface2 points"
874 label combinedFacei = 0;
878 combinedFaces[combinedFacei++] = cutSurf1[facei];
883 labelledTri& combinedTri = combinedFaces[combinedFacei++];
892 combinedTri[fp] = tri[fp] + cutSurf1.
nPoints();
920 Pout<<
"booleanSurface : Generated combinedSurf: " <<
endl;
923 Pout<<
"Writing to file combinedSurf.obj" <<
endl;
924 combinedSurf.
write(
"combinedSurf.obj");
934 label combinedFacei = 0;
938 faceMap_[combinedFacei++] = cutSurf1.
faceMap()[facei];
942 faceMap_[combinedFacei++] = -cutSurf2.
faceMap()[facei] - 1;
963 forAll(combinedSurf, facei)
965 pointHit curHit = combinedSurf[facei].nearestPoint(outsidePoint, pts);
976 Pout<<
"booleanSurface : found for point:" << outsidePoint
977 <<
" nearest face:" << minFacei
978 <<
" nearest point:" << minHit.
rawPoint()
989 propagateSide(combinedSurf, OUTSIDE, minFacei, side);
1001 if (side[facei] == UNVISITED)
1004 <<
"Face " << facei <<
" has not been reached by walking from"
1005 <<
" nearest point " << minHit.
rawPoint()
1008 else if (side[facei] == OUTSIDE)
1012 include[facei] =
true;
1016 include[facei] =
false;
1020 include[facei] = (facei < cutSurf1.
size());
1027 include[facei] =
false;
1031 include[facei] =
true;
1035 include[facei] = (facei >= cutSurf1.
size());
1056 forAll(subToCombinedFace, facei)
1059 label combinedFacei = subToCombinedFace[facei];
1063 if (combinedFacei < cutSurf1.
size())
1065 label cutSurf1Face = combinedFacei;
1067 faceMap_[facei] = cutSurf1.
faceMap()[cutSurf1Face];
1071 label cutSurf2Face = combinedFacei - cutSurf1.
size();
1073 faceMap_[facei] = - cutSurf2.
faceMap()[cutSurf2Face] - 1;
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
void setSize(const label n)
Alias for resize()
Describes the interaction of a face and a point. It carries the info of a successful hit and (if succ...
const point_type & rawPoint() const noexcept
The point, no checks.
scalar distance() const noexcept
Return distance to hit.
label nEdges() const
Number of edges in patch.
label nPoints() const
Number of points supporting patch faces.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
const Field< point_type > & localPoints() const
Return pointField of points in patch.
const Field< point_type > & points() const noexcept
Return reference to global points.
const labelListList & edgeFaces() const
Return edge-face addressing.
void size(const label n)
Older name for setAddressableSize.
label fcIndex(const label i) const noexcept
Surface-surface intersection. Given two surfaces construct combined surface.
static const Enum< booleanOpType > booleanOpTypeNames
booleanSurface()
Construct null.
booleanOpType
Enumeration listing the possible volume operator types.
vector span() const
The bounding box span (from minimum to maximum)
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
Given triSurface and intersection creates the intersected (properly triangulated) surface....
const labelList & faceMap() const
New to old.
bool isSurfacePoint(const label pointi) const
Is point coming from original surface?
const labelList & intersectionEdges() const
Labels of edges in *this which originate from 'cuts'.
label nSurfacePoints() const
Number of points from original surface.
A triFace with additional (region) index.
label region() const noexcept
Return the region index.
Given point flip all faces such that normals point in same direction.
Basic surface-surface intersection description. Constructed from two surfaces it creates a descriptio...
Standard boundBox with extra functionality for use in octree.
Triangulated surface description with patch information.
triSurface()
Default construct.
label markZones(const boolList &borderEdge, labelList &faceZone) const
(size and) fills faceZone with zone of face. Zone is area
triSurface subsetMesh(const UList< bool > &include, labelList &pointMap, labelList &faceMap) const
Return a new surface subsetted on the selected faces.
void write(Ostream &os) const
Write to Ostream in simple OpenFOAM format.
void writeStats(Ostream &os) const
Write some statistics.
void operator=(const triSurface &surf)
Copy assignment.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
List< label > labelList
A List of labels.
List< geometricSurfacePatch > geometricSurfacePatchList
A List of geometricSurfacePatch.
Ostream & endl(Ostream &os)
Add newline and flush stream.
errorManip< error > abort(error &err)
static constexpr const zero Zero
Global zero (0)
List< edge > edgeList
A List of edges.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a)
#define forAll(list, i)
Loop across all elements in list.