23#ifndef __VCGLIB_CURVE_ON_SURF_H
24#define __VCGLIB_CURVE_ON_SURF_H
26#include<vcg/complex/complex.h>
27#include<vcg/simplex/face/topology.h>
28#include<vcg/complex/algorithms/update/topology.h>
29#include<vcg/complex/algorithms/update/color.h>
30#include<vcg/complex/algorithms/update/normal.h>
31#include<vcg/complex/algorithms/update/quality.h>
32#include<vcg/complex/algorithms/clean.h>
33#include<vcg/complex/algorithms/refine.h>
34#include<vcg/complex/algorithms/create/platonic.h>
35#include<vcg/complex/algorithms/point_sampling.h>
36#include <vcg/space/index/grid_static_ptr.h>
37#include <vcg/space/index/kdtree/kdtree.h>
38#include <vcg/math/histogram.h>
39#include<vcg/space/distance3.h>
40#include <vcg/complex/algorithms/attribute_seam.h>
41#include <wrap/io_trimesh/export_ply.h>
87template <
class MeshType>
91 typedef typename MeshType::ScalarType ScalarType;
92 typedef typename MeshType::CoordType CoordType;
93 typedef typename MeshType::VertexType VertexType;
94 typedef typename MeshType::VertexPointer VertexPointer;
95 typedef typename MeshType::VertexIterator VertexIterator;
96 typedef typename MeshType::EdgeIterator EdgeIterator;
97 typedef typename MeshType::EdgeType EdgeType;
98 typedef typename MeshType::FaceType FaceType;
99 typedef typename MeshType::FacePointer FacePointer;
100 typedef typename MeshType::FaceIterator FaceIterator;
102 typedef Segment3<ScalarType> Segment3Type;
103 typedef typename vcg::GridStaticPtr<FaceType, ScalarType> MeshGrid;
104 typedef typename vcg::GridStaticPtr<EdgeType, ScalarType> EdgeGrid;
105 typedef typename face::Pos<FaceType> PosType;
176 ScalarType closestDist;
189 ScalarType closestDist;
190 CoordType closestP,closestN;
203 ScalarType closestDist;
216 ScalarType closestDist;
241 assert(ip[0]+ip[1]+ip[2] == 1.0);
257 if(ip[i]>0.0 && ip[(i+1)%3]>0.0 && ip[(i+2)%3]==0.0 ) {
274 if(ip[i]==1.0 && ip[(i+1)%3]==0.0 && ip[(i+2)%3]==0.0 ) {
291 if(ip[i]==1.0 && ip[(i+1)%3]==0.0 && ip[(i+2)%3]==0.0 )
return fp->V(i);
328 for(EdgeIterator ei=poly.edge.begin(); ei!=poly.edge.end();++ei)
346 bool ret=face::FindSharedFaces<FaceType>(v0,v1,ff0,ff1,e0,e1);
350 assert(ff0->V(e0)==v0 || ff0->V(e0)==v1);
351 ff0->SetFaceEdgeS(e0);
352 ff1->SetFaceEdgeS(e1);
372 ScalarType
MinDistOnEdge(CoordType samplePnt, EdgeGrid &edgeGrid, MeshType &poly, CoordType &closestPoint)
375 EdgeType *cep = vcg::tri::GetClosestEdgeBase(poly,edgeGrid,samplePnt,
par.
gridBailout,polyDist,closestPoint);
390 static ScalarType
MinDistOnEdge(VertexType *v0,VertexType *v1, EdgeGrid &edgeGrid, MeshType &poly, CoordType &closestPoint)
392 ScalarType minPolyDist = std::numeric_limits<ScalarType>::max();
393 const ScalarType sampleNum = 50;
394 const ScalarType maxDist = poly.bbox.Diag()/10.0;
395 for(ScalarType k = 0;k<sampleNum+1;++k)
398 CoordType closestPPoly;
399 CoordType samplePnt = (v0->P()*k +v1->P()*(sampleNum-k))/sampleNum;
401 EdgeType *cep = vcg::tri::GetClosestEdgeBase(poly,edgeGrid,samplePnt,maxDist,polyDist,closestPPoly);
403 if(polyDist < minPolyDist)
405 minPolyDist = polyDist;
406 closestPoint = samplePnt;
430 static inline void ExtractVertex(
const MeshType & srcMesh,
const FaceType & f,
int whichWedge,
const MeshType & dstMesh, VertexType & v)
436 v.ImportData(*f.cV(whichWedge));
453 static inline bool CompareVertex(
const MeshType & m,
const VertexType & vA,
const VertexType & vB)
457 if(vA.C() ==
Color4b(Color4b::Red) && vB.C() ==
Color4b(Color4b::Blue) )
return false;
458 if(vA.C() ==
Color4b(Color4b::Blue) && vB.C() ==
Color4b(Color4b::Red) )
return false;
475 static CoordType
QLerp(VertexType *v0, VertexType *v1)
478 ScalarType qSum = fabs(v0->Q())+fabs(v1->Q());
479 ScalarType w0 = (qSum - fabs(v0->Q()))/qSum;
480 ScalarType w1 = (qSum - fabs(v1->Q()))/qSum;
481 return v0->P()*w0 + v1->P()*w1;
503 int borderCnt=0,midCnt=0,nonmanifCnt=0;
504 for(VertexIterator vi=poly.vert.begin(); vi!=poly.vert.end();++vi)
510 if(ip[0]>0 && ip[1]>0) { vi->P() = f->P(0)*ip[0]+f->P(1)*ip[1]; edgeSnapCnt++; assert(ip[2]==0); vi->C()=Color4b::White;}
511 if(ip[0]>0 && ip[2]>0) { vi->P() = f->P(0)*ip[0]+f->P(2)*ip[2]; edgeSnapCnt++; assert(ip[1]==0); vi->C()=Color4b::White;}
512 if(ip[1]>0 && ip[2]>0) { vi->P() = f->P(1)*ip[1]+f->P(2)*ip[2]; edgeSnapCnt++; assert(ip[0]==0); vi->C()=Color4b::White;}
514 if(ip[0]==1.0) { vi->P() = f->P(0); vertSnapCnt++; assert(ip[1]==0 && ip[2]==0); vi->C()=Color4b::Black; }
515 if(ip[1]==1.0) { vi->P() = f->P(1); vertSnapCnt++; assert(ip[0]==0 && ip[2]==0); vi->C()=Color4b::Black;}
516 if(ip[2]==1.0) { vi->P() = f->P(2); vertSnapCnt++; assert(ip[0]==0 && ip[1]==0); vi->C()=Color4b::Black;}
520 int deg = edge::VEDegree<EdgeType>(&*vi);
521 if (deg > 2) { nonmanifCnt++; vi->C()=Color4b::Magenta; }
522 if (deg < 2) { borderCnt++; vi->C()=Color4b::Green;}
523 if (deg== 2) { midCnt++; vi->C()=Color4b::Blue;}
526 printf(
"SnapPolyline %i vertices: snapped %i onto vert and %i onto edges %i nonmanif, %i border, %i mid\n",
527 poly.vn, vertSnapCnt, edgeSnapCnt, nonmanifCnt,borderCnt,midCnt); fflush(stdout);
530 if(dupCnt) printf(
"SnapPolyline: Removed %i Duplicated vertices\n",dupCnt);
532 return vertSnapCnt==0 && edgeSnapCnt==0 && dupCnt==0;
535 void SelectBoundaryVertex(MeshType &poly)
540 if(edge::VEDegree<EdgeType>(&v)==1) v.SetS();
544 void SelectUniformlyDistributed(MeshType &poly,
int k)
546 tri::TrivialPointerSampler<MeshType> tps;
547 ScalarType samplingRadius = tri::Stat<MeshType>::ComputeEdgeLengthSum(poly)/ScalarType(k);
548 tri::SurfaceSampling<MeshType, typename tri::TrivialPointerSampler<MeshType> >::EdgeMeshUniform(poly,tps,samplingRadius);
549 for(
int i=0;i<tps.sampleVec.size();++i)
550 tps.sampleVec[i]->SetS();
569 void DecomposeNonManifoldPolyline(MeshType &poly,
bool singSplitFlag =
true)
571 tri::Allocator<MeshType>::CompactEveryVector(poly);
572 std::vector<int> degreeVec(poly.vn, 0);
573 tri::UpdateTopology<MeshType>::VertexEdge(poly);
576 if(singSplitFlag) delta = 1;
579 for(VertexIterator vi=poly.vert.begin(); vi!=poly.vert.end();++vi)
581 std::vector<EdgeType *> starVec;
582 edge::VEStarVE(&*vi,starVec);
583 degreeVec[tri::Index(poly, *vi)] = starVec.size();
585 neededVert += starVec.size()-delta;
587 printf(
"DecomposeNonManifold Adding %i vert to a polyline of %i vert\n",neededVert,poly.vn);
590 for(
size_t i=0;i<degreeVec.size();++i)
594 std::vector<EdgeType *> edgeStarVec;
595 edge::VEStarVE(&(poly.vert[i]),edgeStarVec);
596 assert(edgeStarVec.size() == degreeVec[i]);
597 for(
size_t j=delta;j<edgeStarVec.size();++j)
599 EdgeType *ep = edgeStarVec[j];
601 if(tri::Index(poly,ep->V(0)) == i) ind = 0;
604 ep->V(ind) = &*firstVi;
605 ep->V(ind)->P() = poly.vert[i].P();
606 ep->V(ind)->N() = poly.vert[i].N();
611 assert(firstVi == poly.vert.end());
651 std::vector< std::pair<int,VertexPointer> > toSplitVec;
653 for(VertexIterator vi=poly.vert.begin(); vi!=poly.vert.end();++vi)
658 toSplitVec.push_back(std::make_pair(tri::Index(
base,f),&*vi));
661 printf(
"SplitMeshWithPolyline found %lu non snapped points\n",toSplitVec.size()); fflush(stdout);
667 for(
size_t i =0; i<toSplitVec.size();++i)
669 newVi->P() = toSplitVec[i].second->P();
670 newVi->C()=Color4b::Green;
679 std::map<std::pair<CoordType,CoordType>, VertexPointer> edgeToSplitMap;
682 edgeToSplitMap.clear();
683 for(VertexIterator vi=poly.vert.begin(); vi!=poly.vert.end();++vi)
690 if((ip[i ]>0 && ip[i ]<1.0) &&
691 (ip[(i+1)%3]>0 && ip[(i+1)%3]<1.0) &&
694 CoordType p0=f->P0(i);
695 CoordType p1=f->P1(i);
696 if (p0>p1) std::swap(p0,p1);
697 if(edgeToSplitMap[std::make_pair(p0,p1)])
698 printf(
"Found an already used Edge %lu - %lu vert %lu!!!\n", tri::Index(
base,f->V0(i)),tri::Index(
base,f->V1(i)),tri::Index(poly,&*vi));
699 edgeToSplitMap[std::make_pair(p0,p1)]=&*vi;
703 printf(
"SplitMeshWithPolyline: Created a map of %lu edges to be split\n",edgeToSplitMap.size());
707 tri::RefineE(
base,eSplit,ePred);
709 }
while(edgeToSplitMap.size()>0);
750 printf(
"SimplifyNullEdges: Removed %i Duplicated vertices\n",cnt);
753 void SimplifyMidEdge(MeshType &poly)
756 int midEdgeCollapseCnt=0;
761 for(
int ei =0; ei<poly.en; ++ei)
763 VertexType *v0=poly.edge[ei].V(0);
764 VertexType *v1=poly.edge[ei].V(1);
775 if( ( f0 == f1 && e0i == e1i) ||
776 ( f0 == f1->FFp(e1i) && e0i == f1->FFi(e1i)) ||
777 (f0->FFp(e0i) == f1 && f0->FFi(e0i) == e1i) ||
778 (f0->FFp(e0i) == f1->FFp(e1i) && f0->FFi(e0i) == f1->FFi(e1i)) )
780 CoordType newp = (v0->P()+v1->P())/2.0;
783 midEdgeCollapseCnt++;
787 tri::Allocator<MeshType>::CompactEveryVector(poly);
789 }
while(startVn>poly.vn);
802 int startVn= poly.vn;;
803 int midFaceCollapseCnt=0;
804 int vertexEdgeCollapseCnt=0;
811 for(
int i =0; i<poly.vn;++i)
813 std::vector<VertexPointer> starVecVp;
814 edge::VVStarVE(&(poly.vert[i]),starVecVp);
815 if( (starVecVp.size()==2) )
817 CoordType ipP, ipN, ipI;
825 VertexPointer vertexSnapP = 0;
826 VertexPointer vertexSnapN = 0;
827 VertexPointer vertexSnapI = 0;
830 if(ipP[j]==1.0) vertexSnapP=fpP->V(j);
831 if(ipN[j]==1.0) vertexSnapN=fpN->V(j);
832 if(ipI[j]==1.0) vertexSnapI=fpI->V(j);
835 bool collapseFlag=
false;
837 if((!snapI && snapP && snapN) ||
838 (!snapI && !snapP && fpI==fpP) ||
839 (!snapI && !snapN && fpI==fpN) )
842 midFaceCollapseCnt++;
846 if(snapI && snapP && snapN && vertexSnapI==0 && (vertexSnapP!=0 || vertexSnapN!=0) )
848 for(
int j=0;j<3;++j) {
849 if(ipI[j]!=0 && (fpI->V(j)==vertexSnapP || fpI->V(j)==vertexSnapN)) {
851 vertexEdgeCollapseCnt++;
857 edge::VEEdgeCollapse(poly,&(poly.vert[i]));
860 }
while(curVn>poly.vn);
861 printf(
"SimplifyMidFace %5i -> %5i %i mid %i ve \n",startVn,poly.vn,midFaceCollapseCnt,vertexEdgeCollapseCnt);
864 void Simplify(MeshType &poly)
866 int startEn = poly.en;
867 Distribution<ScalarType> hist;
868 for(
int i =0; i<poly.en;++i)
869 hist.Add(edge::Length(poly.edge[i]));
873 for(
int i =0; i<poly.vn;++i)
875 std::vector<VertexPointer> starVecVp;
876 edge::VVStarVE(&(poly.vert[i]),starVecVp);
877 if ((starVecVp.size()==2) && (!poly.vert[i].IsS()))
879 ScalarType newSegLen = Distance(starVecVp[0]->P(), starVecVp[1]->P());
880 Segment3Type seg(starVecVp[0]->P(),starVecVp[1]->P());
882 CoordType closestPSeg;
883 SegmentPointDistance(seg,poly.vert[i].cP(),closestPSeg,segDist);
885 ScalarType maxSurfDist = MaxSegDist(starVecVp[0], starVecVp[1],fp,fn);
889 edge::VEEdgeCollapse(poly,&(poly.vert[i]));
894 tri::Allocator<MeshType>::CompactEveryVector(poly);
899 void EvaluateHausdorffDistance(MeshType &poly, Distribution<ScalarType> &dist)
902 tri::UpdateTopology<MeshType>::VertexEdge(poly);
904 for(
int i =0; i<poly.edge.size();++i)
906 CoordType farthestP, farthestN;
907 ScalarType maxDist = MaxSegDist(poly.edge[i].V(0),poly.edge[i].V(1), farthestP, farthestN, &dist);
908 poly.edge[i].V(0)->Q()+= maxDist;
909 poly.edge[i].V(1)->Q()+= maxDist;
911 for(
int i=0;i<poly.vn;++i)
913 ScalarType deg = edge::VEDegree<EdgeType>(&poly.vert[i]);
914 poly.vert[i].Q()/=deg;
960 ScalarType sum = ip[0]+ip[1]+ip[2];
963 if(ip[i]!=1.0) ip[i]/=sum;
965 sum = ip[0]+ip[1]+ip[2];
969 if(ip[i]>0.0 && ip[i]<1.0)
970 ip[i]=1.0-(ip[(i+1)%3]+ip[(i+2)%3]);
973 sum = ip[0]+ip[1]+ip[2];
976 if(ip[0]==0 || ip[1]==0 || ip[2]==0)
return true;
1000 Segment3Type segPoly(v0->P(),v1->P());
1001 const ScalarType sampleNum = 40;
1006 if(f0==f1)
return false;
1008 bool snap0=
false,snap1=
false;
1012 VertexPointer vertexSnap0 = 0;
1013 VertexPointer vertexSnap1 = 0;
1016 for(
int i=0;i<3;++i) {
1017 if(ip0[i]==1.0) vertexSnap0=f0->V(i);
1018 if(ip0[i]==0.0) seg0=Segment3Type(f0->P1(i),f0->P2(i));
1023 for(
int i=0;i<3;++i){
1024 if(ip1[i]==1.0) vertexSnap1=f1->V(i);
1025 if(ip1[i]==0.0) seg1=Segment3Type(f1->P1(i),f1->P2(i));
1029 CoordType bestSplitPt(0,0,0);
1030 ScalarType bestDist = std::numeric_limits<ScalarType>::max();
1031 for(ScalarType k = 1;k<sampleNum;++k)
1033 CoordType samplePnt = segPoly.Lerp(k/sampleNum);
1039 VertexPointer vertexSnapI = 0;
1040 for(
int i=0;i<3;++i)
1041 if(ip[i]==1.0) vertexSnapI=f->V(i);
1042 CoordType closestPt = f->P(0)*ip[0]+f->P(1)*ip[1]+f->P(2)*ip[2];
1043 if(Distance(samplePnt,closestPt) < bestDist )
1045 ScalarType dist0=std::numeric_limits<ScalarType>::max();
1046 ScalarType dist1=std::numeric_limits<ScalarType>::max();
1047 CoordType closestSegPt;
1048 if(snap0) SegmentPointDistance(seg0,closestPt,closestSegPt,dist0);
1049 if(snap1) SegmentPointDistance(seg1,closestPt,closestSegPt,dist1);
1051 ( vertexSnapI!=vertexSnap0 && vertexSnapI!=vertexSnap1) )
1053 bestDist = Distance(samplePnt,closestPt);
1054 bestSplitPt = closestPt;
1061 splitPt = bestSplitPt;
1083 if(f0==f1)
return true;
1090 FacePointer f0p=0;
int e0p=-1;
1091 FacePointer f1p=0;
int e1p=-1;
1092 assert((e0Snap != v0Snap) && (e1Snap != v1Snap));
1095 f0p = f0->FFp(e0); e0p=f0->FFi(e0); assert(f0p->FFp(e0p)==f0);
1098 f1p = f1->FFp(e1); e1p=f1->FFi(e1); assert(f1p->FFp(e1p)==f1);
1101 if(e0Snap && e1Snap) {
1102 if(f0==f1p || f0p==f1p || f0p==f1 || f0==f1)
return true;
1105 if(e0Snap && v1Snap) {
1106 assert(v1>=0 && v1<3 && v0==-1 && e1==-1);
1107 if(f0->V2(e0) ==f1->V(v1))
return true;
1108 if(f0p->V2(e0p)==f1->V(v1))
return true;
1111 if(e1Snap && v0Snap) {
1112 assert(v0>=0 && v0<3 && v1==-1 && e0==-1);
1113 if(f1->V2(e1) ==f0->V(v0))
return true;
1114 if(f1p->V2(e1p)==f0->V(v0))
return true;
1117 if(v1Snap && v0Snap) {
1118 PosType startPos(f0,f0->V(v0));
1119 PosType curPos=startPos;
1122 assert(curPos.V()==f0->V(v0));
1123 if(curPos.VFlip()==f1->V(v1))
return true;
1127 while(curPos!=startPos);
1151 splitPt=(v0->P()+v1->P())/2.0;
1153 CoordType ip0,ip1,ipm;
1158 if(f0==f1)
return false;
1164 splitPt = fm->P(0)*ipm[0]+fm->P(1)*ipm[1]+fm->P(2)*ipm[2];
1166 if(!snap0 && !snap1) {
1179 if(f0->FFp(e0) == f1)
return false;
1182 for(
int i=0;i<3;++i)
1183 if(f1->V(i)==f0->V(v0))
return false;
1189 if(f1->FFp(e1) == f0)
return false;
1192 for(
int i=0;i<3;++i)
1193 if(f0->V(i)==f1->V(v1))
return false;
1201 bool TestSplitSegWithMeshAdaptOld(VertexType *v0, VertexType *v1, CoordType &splitPt)
1203 Segment3Type segPoly(v0->P(),v1->P());
1204 const ScalarType sampleNum = 40;
1208 if(f0==f1)
return false;
1213 if(!snap0 && !snap1) {
1215 splitPt=(v0->P()+v1->P())/2.0;
1227 if(f0->FFp(e0) == f1)
return false;
1230 for(
int i=0;i<3;++i)
1231 if(f1->V(i)==f0->V(v0))
return false;
1234 splitPt=(v0->P()+v1->P())/2.0;
1240 ScalarType MaxSegDist(VertexType *v0, VertexType *v1, CoordType &farthestPointOnSurf, CoordType &farthestN, Distribution<ScalarType> *distanceDistribution=0)
1242 ScalarType maxSurfDist = 0;
1243 const ScalarType sampleNum = 10;
1244 for(ScalarType k = 1;k<sampleNum;++k)
1246 ScalarType surfDist;
1247 CoordType closestPSurf;
1248 CoordType samplePnt = (v0->P()*k +v1->P()*(sampleNum-k))/sampleNum;
1250 if(distanceDistribution)
1251 distanceDistribution->Add(surfDist);
1253 if(surfDist > maxSurfDist)
1255 maxSurfDist = surfDist;
1256 farthestPointOnSurf = closestPSurf;
1278 int startEdgeSize = poly.en;
1279 for(
int i =0; i<startEdgeSize;++i)
1281 EdgeType &ei = poly.edge[i];
1284 CoordType farthestP, farthestN;
1285 ScalarType maxDist = MaxSegDist(ei.V(0),ei.V(1),farthestP, farthestN);
1288 edge::VEEdgeSplit(poly, &ei, farthestP, farthestN);
1304 std::vector<int> edgeToRefineVec;
1305 for(
int i=0; i<poly.en;++i)
1306 edgeToRefineVec.push_back(i);
1307 int startEn=poly.en;
1309 while (!edgeToRefineVec.empty() && iterCnt<100) {
1311 std::vector<int> edgeToRefineVecNext;
1312 for(
int i=0; i<edgeToRefineVec.size();++i)
1314 EdgeType &e = poly.edge[edgeToRefineVec[i]];
1318 edge::VEEdgeSplit(poly, &e, splitPt);
1319 edgeToRefineVecNext.push_back(edgeToRefineVec[i]);
1320 edgeToRefineVecNext.push_back(poly.en-1);
1324 swap(edgeToRefineVecNext,edgeToRefineVec);
1325 printf(
"RefineCurveByBaseMesh %i en -> %i en\n",startEn,poly.en); fflush(stdout);
1330 SimplifyMidEdge(poly);
1332 printf(
"RefineCurveByBaseMesh %i en -> %i en\n",startEn,poly.en); fflush(stdout);
1344 std::vector<CoordType> operator()(
const MeshType &poly)
const {
1345 std::vector<CoordType> posVec(poly.vn, CoordType(0,0,0));
1346 std::vector<int> cntVec(poly.vn, 0);
1347 for(
int i=0; i<poly.en; ++i)
1348 for(
int j=0; j<2; ++j) {
1349 int vi = tri::Index(poly, poly.edge[i].V0(j));
1350 posVec[vi] += poly.edge[i].V1(j)->P();
1353 for(
int i=0; i<poly.vn; ++i)
1354 posVec[i] = (poly.vert[i].P() + posVec[i]) / ScalarType(cntVec[i]+1);
1381 ScalarType smoothBlend = 0.5;
1384 std::vector<CoordType> operator()(
const MeshType &poly)
const
1387 std::vector<CoordType> smoothPosVec(poly.vn, CoordType(0, 0, 0));
1388 std::vector<int> cntVec(poly.vn, 0);
1389 for (
int i = 0; i < poly.en; ++i)
1390 for (
int j = 0; j < 2; ++j)
1392 int vi = tri::Index(poly, poly.edge[i].V0(j));
1393 smoothPosVec[vi] += poly.edge[i].V1(j)->P();
1396 for (
int i = 0; i < poly.vn; ++i)
1397 smoothPosVec[i] = (poly.vert[i].P() + smoothPosVec[i]) / ScalarType(cntVec[i] + 1);
1400 std::vector<CoordType> fieldPosVec(poly.vn, CoordType(0, 0, 0));
1401 for (
const VertexType &v : poly.vert)
1406 printf(
"Fail to get closest face for vertex at position (%f, %f, %f)\n", v.P().X(), v.P().Y(), v.P().Z()); fflush(stdout);
1409 ScalarType q = f->V(0)->Q() * ip[0] + f->V(1)->Q() * ip[1] + f->V(2)->Q() * ip[2];
1410 CoordType fieldDir = GradientScalarField(*f, f->V(0)->Q(),f->V(1)->Q(),f->V(2)->Q());
1412 fieldPosVec[tri::Index(poly, v)] = v.P() + fieldDir * scale * q;
1415 std::vector<CoordType> PosVec(poly.vn, CoordType(0, 0, 0));
1416 for (
int i = 0; i < poly.vn; ++i)
1417 PosVec[i] = (smoothPosVec[i] * smoothBlend + fieldPosVec[i] * (1.0 - smoothBlend));
1434 template<
typename PositionFunctor>
1435 void MoveAndProject(MeshType &poly,
int iterNum, ScalarType moveWeight, ScalarType projectWeight,
1436 PositionFunctor &desiredPos)
1438 tri::RequireCompactness(poly);
1440 assert(poly.en>0 &&
base.fn>0);
1441 for(
int k=0;k<iterNum;++k)
1443 if(k==iterNum-1) projectWeight=1;
1444 std::vector<CoordType> desired = desiredPos(poly);
1446 for(
int i=0; i<poly.vn; ++i)
1447 if(!poly.vert[i].IsS())
1450 CoordType delta = desired[i] - poly.vert[i].P();
1451 ScalarType deltaLen = delta.Norm();
1454 desired[i] = poly.vert[i].P() + delta;
1457 CoordType newP = poly.vert[i].P()*(1.0-moveWeight) + desired[i]*moveWeight;
1462 poly.vert[i].P() = newP*(1.0-projectWeight) +closestP*projectWeight;
1463 poly.vert[i].N() = f->N();
1479 void SmoothProject(MeshType &poly,
int iterNum, ScalarType smoothWeight, ScalarType projectWeight)
1481 LaplacianFunctor lapFunct;
1482 MoveAndProject(poly, iterNum, smoothWeight, projectWeight, lapFunct);
1489 std::map<std::pair<CoordType,CoordType>, VertexPointer> &edgeToPolyVertMap;
1491 EdgePointPred(std::map<std::pair<CoordType,CoordType>, VertexPointer> &_edgeToPolyVertMap):edgeToPolyVertMap(_edgeToPolyVertMap){};
1492 bool operator()(face::Pos<FaceType> ep)
const
1494 CoordType p0 = ep.V()->P();
1495 CoordType p1 = ep.VFlip()->P();
1496 if (p0>p1) std::swap(p0,p1);
1497 return edgeToPolyVertMap.find(std::make_pair(p0,p1)) != edgeToPolyVertMap.end();
1504 std::map<std::pair<CoordType,CoordType>, VertexPointer> &edgeToPolyVertMap;
1506 EdgePointSplit(std::map<std::pair<CoordType,CoordType>, VertexPointer> &_edgeToPolyVertMap):edgeToPolyVertMap(_edgeToPolyVertMap){};
1507 void operator()(VertexType &nv, face::Pos<FaceType> ep)
1509 CoordType p0 = ep.V()->P();
1510 CoordType p1 = ep.VFlip()->P();
1511 if (p0>p1) std::swap(p0,p1);
1512 VertexPointer vp=edgeToPolyVertMap[std::make_pair(p0,p1)];
1520 cc.lerp(c0,c1,0.5f);
1521 return Color4b::Red;
1523 TexCoord2f WedgeInterp(TexCoord2f &t0, TexCoord2f &t1)
1526 assert(t0.n()== t1.n());
1528 tmp.t()=(t0.t()+t1.t())/2.0;
Class to safely add and delete elements in a mesh.
Definition: allocate.h:97
static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater< VertexPointer > &pu)
Add n vertices to the mesh. Function to add n vertices to the mesh. The elements are added always to ...
Definition: allocate.h:189
static FaceIterator AddFaces(MeshType &m, size_t n)
Function to add n faces to the mesh. First wrapper, with no parameters.
Definition: allocate.h:615
static int RemoveDuplicateVertex(MeshType &m, bool RemoveDegenerateFlag=true)
Definition: clean.h:206
Definition: curve_on_manifold.h:1487
Parameter class controlling the behavior of CoM algorithms.
Definition: curve_on_manifold.h:116
ScalarType surfDistThr
Max distance between surface and curve; used in simplify and refine.
Definition: curve_on_manifold.h:119
ScalarType maxMoveDelta
The maximum movement admitted during MoveAndProject (before projection)
Definition: curve_on_manifold.h:122
ScalarType barycentricSnapThr
Threshold for snapping barycentric coords to 0 or 1 (controls vertex/edge snapping)
Definition: curve_on_manifold.h:125
ScalarType gridBailout
The maximum distance bailout used in grid-based spatial queries.
Definition: curve_on_manifold.h:124
ScalarType maxSimpEdgeLen
Maximal admitted edge length (used in simplify: never make edges longer than this)
Definition: curve_on_manifold.h:121
void SetDefault(MeshType &m)
Set all parameters to reasonable defaults based on the mesh bounding box.
Definition: curve_on_manifold.h:131
ScalarType minRefEdgeLen
Minimal admitted edge length (used in refine: never make edges shorter than this)
Definition: curve_on_manifold.h:120
ScalarType maxSnapThr
The maximum distance allowed when snapping a polyline vertex onto a mesh vertex (currently unused)
Definition: curve_on_manifold.h:123
void Dump() const
Print current parameter values to stdout.
Definition: curve_on_manifold.h:143
Param(MeshType &m)
Constructor with default parameter initialization based on mesh size.
Definition: curve_on_manifold.h:128
A class for managing curves on a 2-manifold (Curve on Manifold - CoM).
Definition: curve_on_manifold.h:89
ScalarType MinDistOnEdge(CoordType samplePnt, EdgeGrid &edgeGrid, MeshType &poly, CoordType &closestPoint)
Find the minimum distance from a sample point to the polyline.
Definition: curve_on_manifold.h:372
MeshType & base
Reference to the base triangulated surface mesh.
Definition: curve_on_manifold.h:158
void SimplifyNullEdges(MeshType &poly)
Remove duplicate/zero-length edges from a polyline.
Definition: curve_on_manifold.h:746
VertexPointer FindVertexSnap(FacePointer fp, CoordType &ip)
Find the vertex pointer for a vertex-snapped barycentric coordinate.
Definition: curve_on_manifold.h:288
FaceType * GetClosestFace(const CoordType &p)
Get the closest face to a query point.
Definition: curve_on_manifold.h:174
MeshGrid uniformGrid
Spatial acceleration structure for closest point queries.
Definition: curve_on_manifold.h:159
FaceType * GetClosestFaceIP(const CoordType &p, CoordType &ip)
Get the closest face and its barycentric coordinates.
Definition: curve_on_manifold.h:187
void RefineCurveByBaseMesh(MeshType &poly)
RefineCurveByBaseMesh.
Definition: curve_on_manifold.h:1301
Param par
Parameters controlling algorithm behavior.
Definition: curve_on_manifold.h:160
bool TagFaceEdgeSelWithPolyLine(MeshType &poly, bool markFlag=true)
Tag face edges of the base mesh that coincide with polyline edges.
Definition: curve_on_manifold.h:320
void SimplifyMidFace(MeshType &poly)
SimplifyMidFace remove all the vertices that in the mid of a face and between two of the points snapp...
Definition: curve_on_manifold.h:800
CoM(MeshType &_m)
Constructor: initializes the CoM with a base mesh.
Definition: curve_on_manifold.h:163
FaceType * GetClosestFacePoint(const CoordType &p, CoordType &closestP)
Get the closest face and the closest point on it.
Definition: curve_on_manifold.h:214
bool SnapPolyline(MeshType &poly)
SnapPolyline snaps the vertexes of a polyline onto the base mesh.
Definition: curve_on_manifold.h:497
static CoordType QLerp(VertexType *v0, VertexType *v1)
Compute quality-weighted linear interpolation between two vertices.
Definition: curve_on_manifold.h:475
bool IsWellSnapped(const CoordType &ip)
Test if a barycentric coordinate is well snapped.
Definition: curve_on_manifold.h:235
bool SnappedOnSameFace(FacePointer f0, CoordType i0, FacePointer f1, CoordType i1)
SnappedOnSameFace Return true if the two points are snapped to a common face;.
Definition: curve_on_manifold.h:1081
void MoveAndProject(MeshType &poly, int iterNum, ScalarType moveWeight, ScalarType projectWeight, PositionFunctor &desiredPos)
MoveAndProject.
Definition: curve_on_manifold.h:1435
bool TestSplitSegWithMeshAdapt(VertexType *v0, VertexType *v1, CoordType &splitPt)
TestSplitSegWithMesh Given a poly segment decide if it should be split along elements of base mesh.
Definition: curve_on_manifold.h:1149
FaceType * GetClosestFaceIP(const CoordType &p, CoordType &ip, CoordType &in)
Get the closest face, barycentric coordinates, and normal.
Definition: curve_on_manifold.h:201
void RefineCurveByDistance(MeshType &poly)
RefineCurve.
Definition: curve_on_manifold.h:1275
bool BarycentricSnap(CoordType &ip)
Snap barycentric coordinates to 0 or 1 if within threshold.
Definition: curve_on_manifold.h:953
void Init()
Initialize the CoM data structures for processing.
Definition: curve_on_manifold.h:728
bool TestSplitSegWithMesh(VertexType *v0, VertexType *v1, CoordType &splitPt)
TestSplitSegWithMesh Given a poly segment decide if it should be split along elements of base mesh.
Definition: curve_on_manifold.h:998
static bool CompareVertex(const MeshType &m, const VertexType &vA, const VertexType &vB)
Compare two vertices for seam compatibility.
Definition: curve_on_manifold.h:453
static void ExtractVertex(const MeshType &srcMesh, const FaceType &f, int whichWedge, const MeshType &dstMesh, VertexType &v)
Extract vertex attributes for seam processing.
Definition: curve_on_manifold.h:430
bool IsSnappedVertex(CoordType &ip, int &vi)
Check if a barycentric coordinate is snapped to a vertex.
Definition: curve_on_manifold.h:271
static ScalarType MinDistOnEdge(VertexType *v0, VertexType *v1, EdgeGrid &edgeGrid, MeshType &poly, CoordType &closestPoint)
Find the closest point on a mesh edge to the polyline (static version)
Definition: curve_on_manifold.h:390
bool IsSnappedEdge(CoordType &ip, int &ei)
Check if a barycentric coordinate is snapped to an edge.
Definition: curve_on_manifold.h:254
void SplitMeshWithPolyline(MeshType &poly)
Split the base mesh to make it conforming with the polyline.
Definition: curve_on_manifold.h:649
static int PerVertexConstant(MeshType &m, Color4b vs=Color4b::White, bool selected=false)
This function colors all (or the selected) the vertices of a mesh.
Definition: color.h:83
static void PerVertexQualityRamp(MeshType &m, ScalarType minq=0., ScalarType maxq=0., vcg::ColorMap cmap=vcg::ColorMap::RGB)
This function colores all the faces of a mesh with a hue color shade dependent on the quality.
Definition: color.h:222
Management, updating and computation of per-vertex and per-face flags (like border flags).
Definition: flag.h:44
static void PerFaceNormalized(ComputeMeshType &m)
Equivalent to PerFace() and NormalizePerFace()
Definition: normal.h:276
static void VertexConstant(MeshType &m, VertexQualityType q)
Definition: quality.h:67
static size_t VertexClear(MeshType &m)
This function clear the selection flag for all the vertices.
Definition: selection.h:237
Auxiliary data structure for computing face face adjacency information.
Definition: topology.h:149
Generation of per-vertex and per-face topological information.
Definition: topology.h:43
static void VertexFace(MeshType &m)
Update the Vertex-Face topological relation.
Definition: topology.h:467
static void FaceFace(MeshType &m)
Update the Face-Face topological relation by allowing to retrieve for each face what other faces shar...
Definition: topology.h:395
static void TestVertexEdge(MeshType &m)
Test correctness of VEtopology.
Definition: topology.h:584
void ForEachVertex(const MeshType &m, Callable action)
Definition: foreach.h:126
void TriSplit(FaceType *fToSplit, FaceType *newf0, FaceType *newf1, typename FaceType::VertexType *newVert)
Definition: topology.h:842
Definition: curve_on_manifold.h:1502
LaplacianFunctor basic Laplacian smoothing functor.
Definition: curve_on_manifold.h:1343
QualityDistanceFieldFunctor quality field based smoothing functor.
Definition: curve_on_manifold.h:1377