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 visualized 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 visualized with e.g. javaview (www.javaview.de)\n\n";
110 if (borderEdge[edgeI])
127 Info<<
"Dumping connectedFaces as Lightwave .obj file to " << fName
128 <<
"\nThis can be visualized 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];
259 scalar len = surf.
edges()[edgeI].mag(points);
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))
396 else if (!faceToPoint.
insert(facei, pointi))
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
455 const edge& e = surf.
edges()[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 549 <<
"faceToPoint:" << faceToPoint
550 <<
"Written surface to errorSurf.obj" 556 const edge& e = edges[edgeI];
566 vector e0 = (points[v0] - points[e.
start()]) ^ eVec;
574 vector e1 = (points[e.
start()] - points[v1]) ^ eVec;
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[])
671 "split multiply connected surface edges by duplicating points" 679 "add debugging output" 688 Info<<
"Reading surface from " << inSurfName <<
endl;
693 testSortedEdgeFaces(surf);
697 markBorderEdges(debug, surf, borderEdge);
703 markBorderPoints(debug, surf, borderEdge, borderPoint);
706 splitBorderEdges(surf, borderEdge, borderPoint);
709 Info<<
"Writing split surface to " << outSurfName <<
nl <<
endl;
710 surf.write(outSurfName);
711 Info<<
"Finished writing surface to " << outSurfName <<
nl <<
endl;
715 label nOldBorderEdges = -1;
716 label nOldBorderPoints = -1;
725 label nBorderEdges = markBorderEdges(debug, surf, borderEdge);
727 if (nBorderEdges == 0)
729 Info<<
"Found no border edges. Exiting." <<
nl <<
nl;
737 label nBorderPoints =
746 if (nBorderPoints == 0)
748 Info<<
"Found no border points. Exiting." <<
nl <<
nl;
754 <<
" border edges :" << nBorderEdges <<
nl 755 <<
" border points:" << nBorderPoints <<
nl 760 nBorderPoints == nOldBorderPoints
761 && nBorderEdges == nOldBorderEdges
764 Info<<
"Stopping since number of border edges and point is same" 765 <<
" as in previous iteration" <<
nl <<
endl;
775 label startEdgeI = -1;
776 label startPointi = -1;
780 if (borderEdge[edgeI])
784 if ((borderPoint[e[0]] != -1) && (borderPoint[e[1]] == -1))
791 else if ((borderPoint[e[0]] == -1) && (borderPoint[e[1]] != -1))
801 if (startEdgeI == -1)
803 Info<<
"Cannot find starting point of splitLine\n" <<
endl;
811 label firstFacei = eFaces[0];
815 label secondFacei = sharedFace(surf, firstFacei, startEdgeI);
817 Info<<
"Starting local walk from:" << endl
818 <<
" edge :" << startEdgeI << endl
819 <<
" point:" << startPointi << endl
820 <<
" face0:" << firstFacei << endl
821 <<
" face1:" << secondFacei << endl
829 faceToEdge.
insert(firstFacei, startEdgeI);
845 faceToEdge.
insert(secondFacei, startEdgeI);
861 Info<<
"Finished local walk and visited" <<
nl 862 <<
" border edges :" << faceToEdge.
size() <<
nl 863 <<
" border points(but not edges):" << faceToPoint.
size() <<
nl 868 dumpFaces(
"faceToEdge.obj", surf, faceToEdge);
869 dumpFaces(
"faceToPoint.obj", surf, faceToPoint);
881 calcPointVecs(surf, faceToEdge, faceToPoint, borderPointVec);
886 newPoints.
setSize(newPoints.size() + nBorderPoints);
888 forAll(borderPoint, pointi)
890 label newPointi = borderPoint[pointi];
894 scalar minLen = minEdgeLen(surf, pointi);
896 vector n = borderPointVec[pointi];
899 newPoints[
newPointi] = newPoints[pointi] + 0.1 * minLen *
n;
914 newTris[facei].region() = surf[facei].region();
918 renumberFaces(surf, borderPoint, faceToEdge, newTris);
920 renumberFaces(surf, borderPoint, faceToPoint, newTris);
930 const point& pt = newPoints[f[fp]];
932 if (
mag(pt) >= GREAT/2)
934 Info<<
"newTri:" << facei <<
" verts:" << f
935 <<
" vert:" << f[fp] <<
" point:" << pt <<
endl;
943 if (debug || (iteration != 0 && (iteration % 20) == 0))
945 Info<<
"Writing surface to " << outSurfName <<
nl <<
endl;
947 surf.write(outSurfName);
949 Info<<
"Finished writing surface to " << outSurfName <<
nl <<
endl;
953 nOldBorderEdges = nBorderEdges;
954 nOldBorderPoints = nBorderPoints;
960 Info<<
"Writing final surface to " << outSurfName <<
nl <<
endl;
962 surf.write(outSurfName);
label end() const
Return end vertex label.
label nPoints() const
Return number of points supporting patch faces.
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
A class for handling file names.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
void size(const label)
Override size to be inconsistent with allocated storage.
Ostream & endl(Ostream &os)
Add newline and flush stream.
static void noParallel()
Remove the parallel options.
static SLList< string > validArgs
A list of valid (mandatory) arguments.
const labelListList & sortedEdgeFaces() const
Return edge-face addressing sorted (for edges with more than.
label size() const
Return number of elements in table.
Vector< scalar > vector
A scalar version of the templated Vector.
const labelListList & pointEdges() const
Return point-edge addressing.
Various functions to operate on Lists.
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
bool optionFound(const word &opt) const
Return true if the named option is found.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
const geometricSurfacePatchList & patches() const
const labelListList & faceEdges() const
Return face-edge addressing.
Extract command arguments and options from the supplied argc and argv parameters. ...
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
errorManip< error > abort(error &err)
bool found(const Key &) const
Return true if hashedEntry is found in table.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
label start() const
Return start vertex label.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
label rcIndex(const label i) const
Return the reverse circular index, i.e. the previous index.
label nEdges() const
Return number of edges in patch.
void setSize(const label)
Reset size of List.
A List with indirect addressing.
vector vec(const pointField &) const
Return the vector (end - start)
dimensioned< scalar > mag(const dimensioned< Type > &)
const labelListList & edgeFaces() const
Return edge-face addressing.
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
static void addNote(const string &)
Add extra notes for the usage information.
Triangulated surface description with patch information.
Foam::argList args(argc, argv)
const Field< PointType > & localPoints() const
Return pointField of points in patch.