symmetry.h
Go to the documentation of this file.
00001 #ifndef VCG_SYMMETRY_H
00002 #define VCG_SYMMETRY_H
00003 
00004 #include <vcg/space/plane3.h>
00005 #include <vcg/space/index/grid_static_ptr.h>
00006 #include <vcg/complex/algorithms/closest.h>
00007 #include <vcg/complex/algorithms/create/platonic.h>
00008 #include <vcg/complex/algorithms/point_sampling.h>
00009 
00010 namespace vcg {
00011 namespace tri {
00012 
00013 //class SphereEdge;
00014 //class SphereFace;
00015 //class SphereVertex;
00016 
00017 template <class TriMeshType>
00018 class ExtrinsicPlaneSymmetry
00019 {
00020     typedef typename TriMeshType::VertexType VertexType;
00021     typedef typename TriMeshType::FaceType FaceType;
00022     typedef typename TriMeshType::CoordType CoordType;
00023     typedef typename TriMeshType::ScalarType ScalarType;
00024 
00025 //    struct SphereUsedTypes : public vcg::UsedTypes<   vcg::Use<SphereVertex>::AsVertexType,
00026 //                                                    vcg::Use<SphereFace>::AsFaceType>{};
00027 
00028 //    class SphereVertex  : public vcg::Vertex< SphereUsedTypes,
00029 //                                             vcg::vertex::Coord<CoordType,ScalarType>,
00030 //                                             vcg::vertex::Normal<CoordType,ScalarType>,
00031 //                                            vcg::vertex::BitFlags>{};
00032 
00033 //    class SphereFace    : public vcg::Face< SphereUsedTypes, vcg::face::VertexRef,
00034 //                                            vcg::vertex::Normal<vcg::Point3<ScalarType>,ScalarType>,
00035 //                                            vcg::face::Mark,
00036 //                                            vcg::face::BitFlags,vcg::face::FFAdj> {};
00037 
00038 //    class SphereMesh : public vcg::tri::TriMesh< std::vector<SphereVertex>, std::vector<SphereFace> > {};
00039 
00040 
00041 
00042     TriMeshType &tri_mesh;
00043 
00044     CoordType AlignZeroTr;
00045 
00046     std::vector<std::vector< ScalarType > > Weight;
00047     //std::vector<std::vector<std::pair<VertexType*,VertexType*> > > VotingVertx;
00048     std::vector<std::vector<std::pair<CoordType,CoordType>  > > VotingPos;
00049 
00050     std::vector<ScalarType> Votes;
00051 
00052 
00053 
00054     TriMeshType *sphere;
00055 
00056     typename vcg::GridStaticPtr<FaceType,ScalarType> GridSph;
00057 
00058     ScalarType RadiusInterval;
00059     ScalarType MaxRadius;
00060     int radiusSph;
00061 
00062     std::vector<std::pair<ScalarType,int> > SortedPlanes;
00063     std::vector<vcg::Plane3<ScalarType> > SymmetricPlanes;
00064 
00065     int Bucket(const vcg::Plane3<ScalarType> &Pl)
00066     {
00067         ScalarType Offset=Pl.Offset();
00068         CoordType Direction=Pl.Direction();
00069         Direction.Normalize();
00071         int OffsetI=floor((Offset/RadiusInterval)+0.5);
00072         assert(OffsetI<radiusSph);
00074         ScalarType MaxD=sphere->bbox.Diag();
00075         ScalarType MinD;
00076         CoordType ClosePt;
00077         FaceType *choosen=NULL;
00078         choosen=vcg::tri::GetClosestFaceBase(*sphere,GridSph,Direction,MaxD,MinD,ClosePt);
00079         assert(choosen!=NULL);
00080         int IndexF=choosen-&(sphere->face[0]);
00082         int OffsetRadius=OffsetI * (sphere->face.size());
00083         return(OffsetRadius+IndexF);
00084     }
00085 
00086     void Elect(CoordType p0,CoordType p1)
00087     {
00088         CoordType AvP=(p0+p1)/2.0;
00089         AvP-=AlignZeroTr;
00090         CoordType Direction=p0-p1;
00091         Direction.Normalize();
00092         vcg::Plane3<ScalarType> Pl;
00093         Pl.Init(AvP,Direction);
00094         //invert if needed
00095         if (Pl.Offset()<0)
00096         {
00097             ScalarType Off=Pl.Offset();
00098             CoordType Dir=Pl.Direction();
00099             Pl.Set(-Dir,-Off);
00100         }
00101         int index=Bucket(Pl);
00102         assert(index>=0);
00103         assert(index<(int)Votes.size());
00104         ScalarType VoteValue=1;
00105         Votes[index]+=VoteValue;
00106         Weight[index].push_back(VoteValue);
00107         VotingPos[index].push_back(std::pair<CoordType,CoordType> (p0,p1));
00108     }
00109 
00110     vcg::Plane3<ScalarType> GetInterpolatedPlane(int &Index)
00111     {
00113         CoordType AvDir=CoordType(0,0,0);
00114         ScalarType WSum=0;
00115         ScalarType AvOffset=0;
00116         for (size_t i=0;i<VotingPos[Index].size();i++)
00117         {
00118             CoordType p0=VotingPos[Index][i].first;
00119             CoordType p1=VotingPos[Index][i].second;
00120             ScalarType W=Weight[Index][i];
00121             CoordType Dir=(p0-p1);
00122             Dir.Normalize();
00123 
00124             CoordType AvP=(p0+p1)/2.0;
00125             ScalarType Offset=AvP*Dir;
00126 
00127             //invert if needed
00128             if (Offset<0)
00129             {
00130                 Offset=-Offset;
00131                 Dir=-Dir;
00132             }
00133 
00134             AvDir+=(Dir*W);
00135             AvOffset+=(Offset*W);
00136             WSum+=W;
00137         }
00138         AvDir.Normalize();
00139         AvOffset/=WSum;
00140         vcg::Plane3<ScalarType> Pl;
00141         Pl.Set(AvDir,AvOffset);
00142         return Pl;
00143     }
00144 
00145     vcg::Plane3<ScalarType> GetBasePlane(int &Index)
00146     {
00148         int OffsetIndex=Index/sphere->face.size();
00149         ScalarType OffsetVal=OffsetIndex*RadiusInterval;
00150         int DirectionIndex=Index % sphere->face.size();
00151         CoordType PlaneDirection=(sphere->face[DirectionIndex].P(0)+
00152                                   sphere->face[DirectionIndex].P(1)+
00153                                   sphere->face[DirectionIndex].P(2))/3.0;
00154         PlaneDirection.Normalize();
00155         CoordType CenterPl=PlaneDirection*OffsetVal;
00156         CenterPl+=AlignZeroTr;
00157         vcg::Plane3<ScalarType> RetPl;
00158         RetPl.Init(CenterPl,PlaneDirection);
00159         return RetPl;
00160     }
00161 
00162     void InitSymmetricPlanes(const int SubN=4)
00163     {
00164         assert(SortedPlanes.size()>0);
00165         SymmetricPlanes.clear();
00166         int BestN=pow((ScalarType)2,(ScalarType)SubN);
00167         if (BestN>=(int)SortedPlanes.size())BestN=SortedPlanes.size()-1;
00168         for (size_t j=SortedPlanes.size()-1;j>SortedPlanes.size()-1-SubN;j--)
00169         {
00170             int Index=SortedPlanes[j].second;
00171             SymmetricPlanes.push_back(GetInterpolatedPlane(Index));
00172         }
00173     }
00174 
00175 
00176 public:
00177 
00178     void GetPlanes(std::vector<vcg::Plane3<ScalarType> > &Planes,int Num)
00179     {
00180         if (SymmetricPlanes.size()==0)return;
00181 
00182         for (int i=0;i<Num;i++)
00183             Planes.push_back(SymmetricPlanes[i]);
00184     }
00185 
00186     void Init(bool OnlyBorder=false,
00187               int SubDirections=4,
00188               int NumberBestPlanes=16)
00189     {
00190         if (OnlyBorder)
00191         {
00192             vcg::tri::UpdateTopology<TriMeshType>::FaceFace(tri_mesh);
00193             vcg::tri::UpdateFlags<TriMeshType>::FaceBorderFromFF(tri_mesh);
00194             vcg::tri::UpdateFlags<TriMeshType>::VertexBorderFromFaceBorder(tri_mesh);
00195         }
00196         AlignZeroTr=tri_mesh.bbox.Center();
00197 
00199         if (sphere!=NULL)
00200             sphere->Clear();
00201         else
00202             sphere=new TriMeshType();
00203 
00204         //create the sphere
00205         vcg::tri::Sphere<TriMeshType>(*sphere,SubDirections);
00206         vcg::tri::UpdateBounding<TriMeshType>::Box(*sphere);
00207 
00209         GridSph.Set(sphere->face.begin(),sphere->face.end());
00210 
00212         ScalarType MaxRadius=tri_mesh.bbox.Diag()/2;
00213         int AreaSph=sphere->fn;
00214         radiusSph=ceil(sqrt((ScalarType)AreaSph/4.0*M_PI));
00215         RadiusInterval=MaxRadius/(ScalarType)radiusSph;
00216 
00218         Votes.resize(radiusSph*sphere->fn,0);
00219 
00220         Weight.resize(radiusSph*sphere->fn);
00221         VotingPos.resize(radiusSph*sphere->fn);
00222 
00224         for (size_t i=0;i<tri_mesh.vert.size();i++)
00225             for (size_t j=i+1;j<tri_mesh.vert.size();j++)
00226             {
00227                 VertexType *v0=&tri_mesh.vert[i];
00228                 VertexType *v1=&tri_mesh.vert[j];
00229                 if ((OnlyBorder)&&(!((v0->IsB())&&(v1->IsB()))))continue;
00230                 Elect(v0->P(),v1->P());
00231             }
00232 
00233         SortedPlanes.resize(Votes.size());
00234         for (size_t i=0;i<Votes.size();i++)
00235             SortedPlanes[i]=std::pair<ScalarType,int>(Votes[i],i);
00236 
00237         std::sort(SortedPlanes.begin(),SortedPlanes.end());
00238 
00239         InitSymmetricPlanes(NumberBestPlanes);
00240 
00241     }
00242 
00243     ExtrinsicPlaneSymmetry(TriMeshType &_tri_mesh):tri_mesh(_tri_mesh)
00244     {
00245         sphere=NULL;
00246         RadiusInterval=-1;
00247         radiusSph=-1;
00248     }
00249 
00250 };
00251 
00252 }
00253 }
00254 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:36:59