69 const point& pt = pts[i];
71 os <<
"v " << pt.
x() <<
' ' << pt.
y() <<
' ' << pt.
z() <<
endl;
80 Info<<
"Dumping borderPoints as Lightwave .obj file to " << fName
81 <<
"\nThis can be visualised with e.g. javaview (www.javaview.de)\n\n";
85 forAll(borderPoint, pointi)
87 if (borderPoint[pointi] != -1)
91 os <<
"v " << pt.
x() <<
' ' << pt.
y() <<
' ' << pt.
z() <<
endl;
101 Info<<
"Dumping borderEdges as Lightwave .obj file to " << fName
102 <<
"\nThis can be visualised with e.g. javaview (www.javaview.de)\n\n";
110 if (borderEdge[edgeI])
114 os <<
"l " <<
e.start()+1 <<
' ' <<
e.end()+1 <<
endl;
127 Info<<
"Dumping connectedFaces as Lightwave .obj file to " << fName
128 <<
"\nThis can be visualised with e.g. javaview (www.javaview.de)\n\n";
136 os <<
"v " << ctr.
x() <<
' ' << ctr.
y() <<
' ' << ctr.
z() <<
endl;
141 void testSortedEdgeFaces(
const triSurface& surf)
148 const labelList& myFaces = edgeFaces[edgeI];
149 const labelList& sortMyFaces = sortedEdgeFaces[edgeI];
153 if (
findIndex(sortMyFaces, myFaces[i]) == -1)
160 if (
findIndex(myFaces, sortMyFaces[i]) == -1)
170 label markBorderEdges
177 label nBorderEdges = 0;
183 if (edgeFaces[edgeI].size() == 4)
185 borderEdge[edgeI] =
true;
193 dumpEdges(surf, borderEdge);
202 label markBorderPoints
214 forAll(pointEdges, pointi)
216 const labelList& pEdges = pointEdges[pointi];
218 label nBorderEdges = 0;
222 if (borderEdge[pEdges[i]])
228 if (nBorderEdges == 2 && borderPoint[pointi] == -1)
230 borderPoint[pointi] =
nPoints++;
238 dumpPoints(surf, borderPoint);
241 return nBorderPoints;
253 scalar minLen = great;
257 label edgeI = pEdges[i];
281 label edgeI = edgeLabels[i];
303 <<
' ' << v1 <<
" in candidates " << edgeLabels
316 const label otherEdgeI,
324 label edgeI = fEdges[i];
343 <<
" connected to point " << pointi
360 const label startFacei,
361 const label startEdgeI,
362 const label startPointi,
368 label facei = startFacei;
369 label edgeI = startEdgeI;
370 label pointi = startPointi;
381 edgeI =
otherEdge(surf, facei, edgeI, pointi);
383 if (borderEdge[edgeI])
385 if (!faceToEdge.
insert(facei, edgeI))
405 if (eFaces.
size() != 2)
408 <<
"Can only handle edges with 2 or 4 edges for now."
412 if (eFaces[0] == facei)
416 else if (eFaces[1] == facei)
432 pointi = surf.
edges()[edgeI].otherVertex(pointi);
434 if (borderPoint[pointi] == -1)
449 const label firstFacei,
450 const label sharedEdgeI
462 bool edgeOrder = (
f[
f.
fcIndex(startIndex)] ==
e.end());
475 return eFaces[eFaces.
rcIndex(faceIndex)];
480 return eFaces[eFaces.
fcIndex(faceIndex)];
503 const label edgeI = iter();
505 if (!edgeDone[edgeI])
507 edgeDone[edgeI] =
true;
515 const labelList& eFaces = sortedEdgeFaces[edgeI];
519 label facei = eFaces[i];
521 if (faceToEdge.
found(facei))
527 else if (face1I == -1)
536 if (face0I == -1 && face1I == -1)
538 Info<<
"Writing surface to errorSurf.obj" <<
endl;
540 surf.write(
"errorSurf.obj");
543 <<
"Cannot find two faces using border edge " << edgeI
544 <<
" verts:" << edges[edgeI]
545 <<
" eFaces:" << eFaces <<
endl
546 <<
"face0I:" << face0I
547 <<
" face1I:" << face1I <<
nl
548 <<
"faceToEdge:" << faceToEdge <<
nl
550 <<
"Written surface to errorSurf.obj"
556 const edge&
e = edges[edgeI];
579 scalar magMidVec =
mag(midVec);
581 if (magMidVec > small)
586 borderPointVec[
e.start()] += midVec;
587 borderPointVec[
e.end()] += midVec;
606 const label facei = iter.key();
611 if (pointMap[
f[fp]] != -1)
613 newTris[facei][fp] = pointMap[
f[fp]];
622 bool splitBorderEdges
634 if (borderEdge[edgeI])
638 if (borderPoint[
e.start()] == -1 && borderPoint[
e.end()] == -1)
642 edgesToBeSplit[nSplit++] = edgeI;
646 edgesToBeSplit.
setSize(nSplit);
650 Info<<
"Splitting surface along " << nSplit <<
" borderEdges that don't"
651 <<
" neighbour other borderEdges" <<
nl <<
endl;
653 surf = triSurfaceTools::greenRefine(surf, edgesToBeSplit);
667 int main(
int argc,
char *argv[])
673 "split multiply connected surface edges by duplicating points"
680 "add debugging output"
689 Info<<
"Reading surface from " << inSurfName <<
endl;
694 testSortedEdgeFaces(surf);
698 markBorderEdges(debug, surf, borderEdge);
704 markBorderPoints(debug, surf, borderEdge, borderPoint);
707 splitBorderEdges(surf, borderEdge, borderPoint);
710 Info<<
"Writing split surface to " << outSurfName <<
nl <<
endl;
711 surf.write(outSurfName);
712 Info<<
"Finished writing surface to " << outSurfName <<
nl <<
endl;
716 label nOldBorderEdges = -1;
717 label nOldBorderPoints = -1;
726 label nBorderEdges = markBorderEdges(debug, surf, borderEdge);
728 if (nBorderEdges == 0)
730 Info<<
"Found no border edges. Exiting." <<
nl <<
nl;
738 label nBorderPoints =
747 if (nBorderPoints == 0)
749 Info<<
"Found no border points. Exiting." <<
nl <<
nl;
755 <<
" border edges :" << nBorderEdges <<
nl
756 <<
" border points:" << nBorderPoints <<
nl
761 nBorderPoints == nOldBorderPoints
762 && nBorderEdges == nOldBorderEdges
765 Info<<
"Stopping since number of border edges and point is same"
766 <<
" as in previous iteration" <<
nl <<
endl;
776 label startEdgeI = -1;
777 label startPointi = -1;
781 if (borderEdge[edgeI])
785 if ((borderPoint[
e[0]] != -1) && (borderPoint[
e[1]] == -1))
792 else if ((borderPoint[
e[0]] == -1) && (borderPoint[
e[1]] != -1))
802 if (startEdgeI == -1)
804 Info<<
"Cannot find starting point of splitLine\n" <<
endl;
812 label firstFacei = eFaces[0];
816 label secondFacei = sharedFace(surf, firstFacei, startEdgeI);
818 Info<<
"Starting local walk from:" <<
endl
819 <<
" edge :" << startEdgeI <<
endl
820 <<
" point:" << startPointi <<
endl
821 <<
" face0:" << firstFacei <<
endl
822 <<
" face1:" << secondFacei <<
endl
830 faceToEdge.
insert(firstFacei, startEdgeI);
846 faceToEdge.
insert(secondFacei, startEdgeI);
862 Info<<
"Finished local walk and visited" <<
nl
863 <<
" border edges :" << faceToEdge.
size() <<
nl
864 <<
" border points(but not edges):" <<
faceToPoint.size() <<
nl
869 dumpFaces(
"faceToEdge.obj", surf, faceToEdge);
882 calcPointVecs(surf, faceToEdge,
faceToPoint, borderPointVec);
887 newPoints.setSize(newPoints.size() + nBorderPoints);
889 forAll(borderPoint, pointi)
895 scalar minLen = minEdgeLen(surf, pointi);
897 vector n = borderPointVec[pointi];
900 newPoints[
newPointi] = newPoints[pointi] + 0.1 * minLen *
n;
915 newTris[facei].region() = surf[facei].region();
919 renumberFaces(surf, borderPoint, faceToEdge, newTris);
921 renumberFaces(surf, borderPoint,
faceToPoint, newTris);
931 const point& pt = newPoints[
f[fp]];
933 if (
mag(pt) >= great/2)
935 Info<<
"newTri:" << facei <<
" verts:" <<
f
936 <<
" vert:" <<
f[fp] <<
" point:" << pt <<
endl;
944 if (debug || (iteration != 0 && (iteration % 20) == 0))
946 Info<<
"Writing surface to " << outSurfName <<
nl <<
endl;
948 surf.write(outSurfName);
950 Info<<
"Finished writing surface to " << outSurfName <<
nl <<
endl;
954 nOldBorderEdges = nBorderEdges;
955 nOldBorderPoints = nBorderPoints;
961 Info<<
"Writing final surface to " << outSurfName <<
nl <<
endl;
963 surf.write(outSurfName);
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
label size() const
Return number of elements in table.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
bool found(const Key &) const
Return true if hashedEntry is found in table.
void size(const label)
Override size to be inconsistent with allocated storage.
void setSize(const label)
Reset size of List.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
label nEdges() const
Return number of edges in patch.
label nPoints() const
Return number of points supporting patch faces.
const labelListList & pointEdges() const
Return point-edge addressing.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
std::remove_reference< ::Foam::List< labelledTri > >::type::value_type FaceType
const labelListList & edgeFaces() const
Return edge-face addressing.
const labelListList & faceEdges() const
Return face-edge addressing.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
A List with indirect addressing.
label rcIndex(const label i) const
Return the reverse circular index, i.e. the previous index.
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Extract command arguments and options from the supplied argc and argv parameters.
static void addNote(const string &)
Add extra notes for the usage information.
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
bool optionFound(const word &opt) const
Return true if the named option is found.
static SLList< string > validArgs
A list of valid (mandatory) arguments.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
A topoSetSource to select points based on usage in faces.
A class for handling file names.
Triangulated surface description with patch information.
const geometricSurfacePatchList & patches() const
const labelListList & sortedEdgeFaces() const
Return edge-face addressing sorted (for edges with more than.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
int main(int argc, char *argv[])
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Ostream & endl(Ostream &os)
Add newline and flush stream.
errorManip< error > abort(error &err)
dimensioned< scalar > mag(const dimensioned< Type > &)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
Foam::argList args(argc, argv)