79 os <<
"v " << pt.x() <<
' ' << pt.y() <<
' ' << pt.z() <<
endl;
88 Info<<
"Dumping borderPoints as obj file: " << fName <<
endl;
92 forAll(borderPoint, pointi)
94 if (borderPoint[pointi] != -1)
98 os <<
"v " << pt.x() <<
' ' << pt.y() <<
' ' << pt.z() <<
endl;
108 Info<<
"Dumping borderEdges as obj file: " << fName <<
endl;
116 if (borderEdge[edgeI])
120 os <<
"l " <<
e.start()+1 <<
' ' <<
e.end()+1 <<
endl;
133 Info<<
"Dumping connectedFaces as obj file: " << fName <<
endl;
141 os <<
"v " << ctr.x() <<
' ' << ctr.y() <<
' ' << ctr.z() <<
endl;
146 void testSortedEdgeFaces(
const triSurface& surf)
153 const labelList& myFaces = edgeFaces[edgeI];
154 const labelList& sortMyFaces = sortedEdgeFaces[edgeI];
158 if (!sortMyFaces.
found(myFaces[i]))
165 if (!myFaces.
found(sortMyFaces[i]))
175 label markBorderEdges
182 label nBorderEdges = 0;
188 if (edgeFaces[edgeI].size() == 4)
190 borderEdge[edgeI] =
true;
198 dumpEdges(surf, borderEdge);
207 label markBorderPoints
219 forAll(pointEdges, pointi)
221 const labelList& pEdges = pointEdges[pointi];
223 label nBorderEdges = 0;
227 if (borderEdge[pEdges[i]])
233 if (nBorderEdges == 2 && borderPoint[pointi] == -1)
235 borderPoint[pointi] =
nPoints++;
243 dumpPoints(surf, borderPoint);
246 return nBorderPoints;
252 scalar minEdgeLen(
const triSurface& surf,
const label pointi)
258 scalar minLen = GREAT;
262 label edgeI = pEdges[i];
286 label edgeI = edgeLabels[i];
308 <<
' ' << v1 <<
" in candidates " << edgeLabels
321 const label otherEdgeI,
329 label edgeI = fEdges[i];
348 <<
" connected to point " << pointi
365 const label startFacei,
366 const label startEdgeI,
367 const label startPointi,
373 label facei = startFacei;
374 label edgeI = startEdgeI;
375 label pointi = startPointi;
386 edgeI =
otherEdge(surf, facei, edgeI, pointi);
388 if (borderEdge[edgeI])
390 if (!faceToEdge.
insert(facei, edgeI))
410 if (eFaces.
size() != 2)
413 <<
"Can only handle edges with 2 or 4 edges for now." 417 if (eFaces[0] == facei)
421 else if (eFaces[1] == facei)
437 pointi = surf.
edges()[edgeI].otherVertex(pointi);
439 if (borderPoint[pointi] == -1)
454 const label firstFacei,
455 const label sharedEdgeI
464 label startIndex =
f.
find(
e.start());
467 const bool edgeOrder = (
f[
f.
fcIndex(startIndex)] ==
e.end());
475 const label faceIndex = eFaces.
find(firstFacei);
480 return eFaces[eFaces.
rcIndex(faceIndex)];
485 return eFaces[eFaces.
fcIndex(faceIndex)];
508 const label edgeI = iter.val();
510 if (!edgeDone[edgeI])
512 edgeDone[edgeI] =
true;
520 const labelList& eFaces = sortedEdgeFaces[edgeI];
524 label facei = eFaces[i];
526 if (faceToEdge.
found(facei))
532 else if (face1I == -1)
541 if (face0I == -1 && face1I == -1)
543 Info<<
"Writing surface to errorSurf.obj" <<
endl;
545 surf.
write(
"errorSurf.obj");
548 <<
"Cannot find two faces using border edge " << edgeI
549 <<
" verts:" << edges[edgeI]
550 <<
" eFaces:" << eFaces <<
endl 551 <<
"face0I:" << face0I
552 <<
" face1I:" << face1I <<
nl 553 <<
"faceToEdge:" << faceToEdge <<
nl 555 <<
"Written surface to errorSurf.obj" 561 const edge&
e = edges[edgeI];
592 scalar magMidVec =
mag(midVec);
594 if (magMidVec > SMALL)
599 borderPointVec[
e.start()] += midVec;
600 borderPointVec[
e.end()] += midVec;
619 const label facei = iter.key();
624 if (pointMap[
f[fp]] != -1)
626 newTris[facei][fp] = pointMap[
f[fp]];
635 bool splitBorderEdges
647 if (borderEdge[edgeI])
651 if (borderPoint[
e.start()] == -1 && borderPoint[
e.end()] == -1)
655 edgesToBeSplit[nSplit++] = edgeI;
659 edgesToBeSplit.
setSize(nSplit);
663 Info<<
"Splitting surface along " << nSplit <<
" borderEdges that don't" 664 <<
" neighbour other borderEdges" <<
nl <<
endl;
666 surf = triSurfaceTools::greenRefine(surf, edgesToBeSplit);
677 int main(
int argc,
char *argv[])
681 "Split multiply connected surface edges by duplicating points" 689 "Add debugging output" 698 Info<<
"Reading surface from " << inSurfName <<
endl;
703 testSortedEdgeFaces(surf);
707 markBorderEdges(
debug, surf, borderEdge);
713 markBorderPoints(
debug, surf, borderEdge, borderPoint);
716 splitBorderEdges(surf, borderEdge, borderPoint);
719 Info<<
"Writing split surface to " << outSurfName <<
nl <<
endl;
720 surf.
write(outSurfName);
721 Info<<
"Finished writing surface to " << outSurfName <<
nl <<
endl;
725 label nOldBorderEdges = -1;
726 label nOldBorderPoints = -1;
735 label nBorderEdges = markBorderEdges(
debug, surf, borderEdge);
737 if (nBorderEdges == 0)
739 Info<<
"Found no border edges. Exiting." <<
nl <<
nl;
747 label nBorderPoints =
756 if (nBorderPoints == 0)
758 Info<<
"Found no border points. Exiting." <<
nl <<
nl;
764 <<
" border edges :" << nBorderEdges <<
nl 765 <<
" border points:" << nBorderPoints <<
nl 770 nBorderPoints == nOldBorderPoints
771 && nBorderEdges == nOldBorderEdges
774 Info<<
"Stopping since number of border edges and point is same" 775 <<
" as in previous iteration" <<
nl <<
endl;
785 label startEdgeI = -1;
786 label startPointi = -1;
790 if (borderEdge[edgeI])
794 if ((borderPoint[
e[0]] != -1) && (borderPoint[
e[1]] == -1))
801 else if ((borderPoint[
e[0]] == -1) && (borderPoint[
e[1]] != -1))
811 if (startEdgeI == -1)
813 Info<<
"Cannot find starting point of splitLine\n" <<
endl;
821 label firstFacei = eFaces[0];
825 label secondFacei = sharedFace(surf, firstFacei, startEdgeI);
827 Info<<
"Starting local walk from:" <<
endl 828 <<
" edge :" << startEdgeI <<
endl 829 <<
" point:" << startPointi <<
endl 830 <<
" face0:" << firstFacei <<
endl 831 <<
" face1:" << secondFacei <<
endl 839 faceToEdge.
insert(firstFacei, startEdgeI);
855 faceToEdge.
insert(secondFacei, startEdgeI);
871 Info<<
"Finished local walk and visited" <<
nl 872 <<
" border edges :" << faceToEdge.
size() <<
nl 873 <<
" border points(but not edges):" <<
faceToPoint.size() <<
nl 878 dumpFaces(
"faceToEdge.obj", surf, faceToEdge);
891 calcPointVecs(surf, faceToEdge,
faceToPoint, borderPointVec);
896 newPoints.
setSize(newPoints.size() + nBorderPoints);
898 forAll(borderPoint, pointi)
904 scalar minLen = minEdgeLen(surf, pointi);
908 newPoints[
newPointi] = newPoints[pointi] + 0.1 * minLen *
n;
923 newTris[facei].region() = surf[facei].region();
927 renumberFaces(surf, borderPoint, faceToEdge, newTris);
929 renumberFaces(surf, borderPoint,
faceToPoint, newTris);
939 const point& pt = newPoints[
f[fp]];
941 if (
mag(pt) >= GREAT/2)
943 Info<<
"newTri:" << facei <<
" verts:" <<
f 944 <<
" vert:" <<
f[fp] <<
" point:" << pt <<
endl;
952 if (
debug || (iteration != 0 && (iteration % 20) == 0))
954 Info<<
"Writing surface to " << outSurfName <<
nl <<
endl;
956 surf.
write(outSurfName);
958 Info<<
"Finished writing surface to " << outSurfName <<
nl <<
endl;
962 nOldBorderEdges = nBorderEdges;
963 nOldBorderPoints = nBorderPoints;
969 Info<<
"Writing final surface to " << outSurfName <<
nl <<
endl;
971 surf.
write(outSurfName);
const labelListList & pointEdges() const
Return point-edge addressing.
label nPoints() const
Number of points supporting patch faces.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
static void addNote(const string ¬e)
Add extra notes for the usage information.
void size(const label n)
Older name for setAddressableSize.
A class for handling file names.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const Field< point_type > & localPoints() const
Return pointField of points in patch.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
bool found(const Key &key) const
Same as contains()
Output to file stream as an OSstream, normally using std::ofstream for the actual output...
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool found(const T &val, label pos=0) const
Same as contains()
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
static void noParallel()
Remove the parallel options.
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
void write(Ostream &os) const
Write to Ostream in simple OpenFOAM format.
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
label size() const noexcept
The number of elements in table.
const geometricSurfacePatchList & patches() const noexcept
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
const labelListList & sortedEdgeFaces() const
Return edge-face addressing sorted (for edges with more than.
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
Extract command arguments and options from the supplied argc and argv parameters. ...
const labelListList & edgeFaces() const
Return edge-face addressing.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
A triFace with additional (region) index.
errorManip< error > abort(error &err)
label find(const T &val) const
Find index of the first occurrence of the value.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
label nEdges() const
Number of edges in patch.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
T get(const label index) const
Get a value from the argument at index.
A List with indirect addressing. Like IndirectList but does not store addressing. ...
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
messageStream Info
Information stream (stdout output on master, null elsewhere)
const labelListList & faceEdges() const
Return face-edge addressing.
Triangulated surface description with patch information.
label rcIndex(const label i) const noexcept
The reverse circular index. The previous index in the list which returns to the last at the beginning...
Foam::argList args(argc, argv)
bool found(const word &optName) const
Return true if the named option is found.
forAllConstIters(mixture.phases(), phase)
A topoSetPointSource to select all points based on usage in given faceSet(s).
static constexpr const zero Zero
Global zero (0)