From 245931d93d19be7e99a31457af793fd1c9dc8922 Mon Sep 17 00:00:00 2001 From: cignoni Date: Fri, 18 Apr 2014 06:04:18 +0000 Subject: [PATCH] Still refactoring. Now substituted montecarlo with poisson disk sampling --- vcg/complex/algorithms/autoalign_4pcs.h | 60 ++++++++++++------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/vcg/complex/algorithms/autoalign_4pcs.h b/vcg/complex/algorithms/autoalign_4pcs.h index ea76abd6..3cd55510 100644 --- a/vcg/complex/algorithms/autoalign_4pcs.h +++ b/vcg/complex/algorithms/autoalign_4pcs.h @@ -34,6 +34,7 @@ used in the paper pseudocode. #include #include #include +#include #include namespace vcg{ namespace tri{ @@ -55,6 +56,7 @@ public: typedef typename MeshType::ScalarType ScalarType; typedef typename MeshType::CoordType CoordType; typedef typename MeshType::VertexIterator VertexIterator; + typedef typename MeshType::VertexPointer VertexPointer; typedef typename MeshType::VertexType VertexType; typedef vcg::Point4< vcg::Point3 > FourPoints; typedef vcg::GridStaticPtr GridType; @@ -80,13 +82,13 @@ public: } }; - struct Couple: public std::pair + struct Couple: public std::pair { - Couple(const int & i, const int & j, float d):std::pair(i,j),dist(d){} - Couple(float d):std::pair(0,0),dist(d){} + Couple(VertexPointer i, VertexPointer j, float d) : std::pair(i,j),dist(d){} + Couple(float d):std::pair(0,0),dist(d){} float dist; const bool operator < (const Couple & o) const {return dist < o.dist;} - int & operator[](const int &i){return (i==0)? first : second;} + VertexPointer operator[](const int &i){return (i==0)? this->first : this->second;} }; struct Candidate @@ -105,7 +107,10 @@ public: MeshType *P; // mesh from which the coplanar base is selected MeshType *Q; // mesh where to find the correspondences - std::vector mapsub; // subset of index to the vertices in Q + + std::vector subsetQ; // subset of the vertices in Q + std::vector subsetP; // random selection on P + PMesh Invr; // invariants math::MarsenneTwisterRNG rnd; @@ -116,7 +121,6 @@ public: std::vector bases; // used bases ScalarType side; // side std::vector ExtB[4]; // selection of vertices "close" to the four point - std::vector subsetP; // random selection on P ScalarType radius; std::vector R1; @@ -185,16 +189,10 @@ void FourPCS:: Init(MeshType &_movP,MeshType &_fixQ) ugridQ.Set(Q->vert.begin(),Q->vert.end()); ugridP.Set(P->vert.begin(),P->vert.end()); + float radius=0; + tri::PoissonPruning(*Q,subsetQ,radius,par.n_samples_on_Q); + tri::PoissonPruning(*P,subsetP,radius,par.n_samples_on_Q); float ratio = std::min(Q->vert.size(),par.n_samples_on_Q) / (float) Q->vert.size(); - for(int vi = 0; vi < Q->vert.size(); ++vi) - if(rnd.generate01() < ratio) - mapsub.push_back(vi); - - - - for(int vi = 0; vi < P->vert.size(); ++vi) - if(rnd.generate01() < ratio) - subsetP.push_back(&P->vert[vi]); // estimate neigh distance float avD = 0.0; @@ -353,13 +351,14 @@ void FourPCS::ComputeR1() { R1.clear(); - for(int vi = 0; vi < mapsub.size(); ++vi) - for(int vj = vi; vj < mapsub.size(); ++vj){ - ScalarType d = ((Q->vert[mapsub[vi]]).P()-(Q->vert[mapsub[vj]]).P()).Norm(); + for(int vi = 0; vi < subsetQ.size(); ++vi) + for(int vj = vi; vj < subsetQ.size(); ++vj){ +// ScalarType d = ((Q->vert[subsetQ[vi]]).P()-(Q->vert[subsetQ[vj]]).P()).Norm(); + ScalarType d = (subsetQ[vi]->P()- subsetQ[vj]->P()).Norm(); if( (d < side+par.delta)) { - R1.push_back(Couple(mapsub[vi],mapsub[vj],d )); - R1.push_back(Couple(mapsub[vj],mapsub[vi],d)); + R1.push_back(Couple(subsetQ[vi],subsetQ[vj],d )); + R1.push_back(Couple(subsetQ[vj],subsetQ[vi],d)); } } @@ -376,9 +375,6 @@ bool FourPCS::FindCongruent() { // of base B, on Q, with approximation d1 = (B[1]-B[0]).Norm(); d2 = (B[3]-B[2]).Norm(); - int start = clock(); - //int vi,vj; - typename PMesh::VertexIterator vii; typename std::vector::iterator bR1,eR1,bR2,eR2,ite,cite; bR1 = std::lower_bound::iterator,Couple>(R1.begin(),R1.end(),Couple(d1-par.delta)); @@ -397,7 +393,8 @@ bool FourPCS::FindCongruent() { // of base B, on Q, with approximation int i = &(*bR1)-&(*R1.begin()); for(ite = bR1; ite != eR1;++ite){ vii = vcg::tri::Allocator::AddVertices(Invr,1); - (*vii).P() = Q->vert[R1[i][0]].P() + (Q->vert[R1[i][1]].P()-Q->vert[R1[i][0]].P()) * r1; +// (*vii).P() = Q->vert[R1[i][0]].P() + (Q->vert[R1[i][1]].P()-Q->vert[R1[i][0]].P()) * r1; + (*vii).P() = R1[i][0]->P() + ( R1[i][1]->P() - R1[i][0]->P()) * r1; ++i; } if(Invr.vert.empty() ) return false; @@ -416,7 +413,8 @@ bool FourPCS::FindCongruent() { // of base B, on Q, with approximation i = &(*bR2)-&(*R1.begin()); // R2inv contains all the points generated by the couples in R2 (with the reference to remap into R2) for(ite = bR2; ite != eR2;++ite){ - R2inv.push_back( EPoint( Q->vert[R1[i][0]].P() + (Q->vert[R1[i][1]].P()-Q->vert[R1[i][0]].P()) * r2,i)); +// R2inv.push_back( EPoint( Q->vert[R1[i][0]].P() + (Q->vert[R1[i][1]].P()-Q->vert[R1[i][0]].P()) * r2,i)); + R2inv.push_back( EPoint( R1[i][0]->P() + (R1[i][1]->P() - R1[i][0]->P()) * r2,i)); ++i; } @@ -441,10 +439,10 @@ bool FourPCS::FindCongruent() { // of base B, on Q, with approximation n_closests+=closests.size(); for(uint ip = 0; ip < closests.size(); ++ip){ FourPoints p; - p[0] = Q->vert[R1[id[closests[ip]]][0]].P(); - p[1] = Q->vert[R1[id[closests[ip]]][1]].P(); - p[2] = Q->vert[R1[ R2inv[i].pi][0]].P(); - p[3] = Q->vert[R1[ R2inv[i].pi][1]].P(); + p[0] = R1[id[closests[ip]]][0]->P(); + p[1] = R1[id[closests[ip]]][1]->P(); + p[2] = R1[ R2inv[i].pi][0]->P(); + p[3] = R1[ R2inv[i].pi][1]->P(); float trerr; n_base++; @@ -599,7 +597,7 @@ bool FourPCS:: Align( int L, vcg::Matrix44f & result, vcg::CallBa return false; } bases.push_back(B); - if(cb) cb(t*100/L,"trying bases"); + if(cb) cb(t*100/L,"Trying bases"); if(FindCongruent()) break; } @@ -607,7 +605,7 @@ bool FourPCS:: Align( int L, vcg::Matrix44f & result, vcg::CallBa if(U.empty()) return false; // std::sort(U.begin(),U.end()); - + if(cb) cb(90,"TestAlignment"); bestv = -std::numeric_limits::max(); iwinner = 0;