diff --git a/vcg/complex/algorithms/smooth_field.h b/vcg/complex/algorithms/smooth_field.h deleted file mode 100644 index 2c0147e9..00000000 --- a/vcg/complex/algorithms/smooth_field.h +++ /dev/null @@ -1,487 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2014 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ - -#ifndef SMOOTHER_FIELD_H -#define SMOOTHER_FIELD_H - -//eigen stuff -#include - -//vcg stuff -#include -#include -#include -#include - -//igl related stuff -#include -#include -#include -#include - -namespace vcg { -namespace tri { - -enum SmoothMethod{SMMiq,SMNPoly}; - -template -class FieldSmoother -{ - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::ScalarType ScalarType; - typedef typename MeshType::CoordType CoordType; - - - static void InitQualityByAnisotropyDir(MeshType &mesh) - { - std::vector QVal; - for (size_t i=0;i1)NMax=1; - if (NMax<-1)NMax=-1; - - if (NMin>1)NMin=1; - if (NMin<-1)NMin=-1; - - ScalarType CurvAni=(NMax-NMin)/2; - mesh.vert[i].Q()=CurvAni; - } - vcg::tri::UpdateQuality::FaceFromVertex(mesh); - } - - static void SetEdgeDirection(FaceType *f,int edge) - { - CoordType dir=f->P0(edge)-f->P1(edge); - dir.Normalize(); - ScalarType prod1=fabs(dir*f->PD1()); - ScalarType prod2=fabs(dir*f->PD2()); - if (prod1>prod2) - { - f->PD1()=dir; - f->PD2()=f->N()^dir; - }else - { - f->PD2()=dir; - f->PD1()=f->N()^dir; - } - } - - static void AddSharpEdgesConstraints(MeshType & mesh, - const ScalarType &thr=0.2) - { - for (size_t i=0;iFFp(j); - if (f0==f1)continue; - CoordType N0=f0->N(); - CoordType N1=f1->N(); - if ((N0*N1)>thr)continue; - SetEdgeDirection(f0,j); - f0->SetS(); - } - } - - static void AddBorderConstraints(MeshType & mesh) - { - for (size_t i=0;iFFp(j); - assert(f1!=NULL); - if (f0!=f1)continue; - SetEdgeDirection(f0,j); - f0->SetS(); - } - } - - static void AddCurvatureConstraints(MeshType & mesh,const ScalarType &thr=0.5) - { - for (size_t i=0;ithr)mesh.face[i].SetS(); - } - - //hard constraints have selected face - static void CollectHardConstraints( MeshType & mesh, - Eigen::VectorXi &HardI, - Eigen::MatrixXd &HardD, - SmoothMethod SMethod, - int Ndir) - { - //count number of hard constraints - int numS=vcg::tri::UpdateSelection::FaceCount(mesh); - HardI=Eigen::MatrixXi(numS,1); - if ((Ndir==2)||(SMethod==SMMiq)) - HardD=Eigen::MatrixXd(numS,3); - else - HardD=Eigen::MatrixXd(numS,6); - //then update them - int curr_index=0; - for (size_t i=0;i::FaceCount(mesh); - numS=mesh.fn-numS; - //allocate eigen matrix - SoftI=Eigen::MatrixXi(numS,1); - SoftD=Eigen::MatrixXd(numS,3); - SoftW=Eigen::MatrixXd(numS,1); - - //then update them - int curr_index=0; - for (size_t i=0;i::GetTriMeshData(mesh,F,V); - - Eigen::MatrixXd output_field; - Eigen::VectorXd output_sing; - - igl::nrosy(V,F,HardI,HardD,SoftI,SoftW,SoftD,Ndir,alpha_soft,output_field,output_sing); - - //finally update the principal directions - for (size_t i=0;i::GetTriMeshData(mesh,F,V); - - Eigen::MatrixXd output_field; - Eigen::VectorXd output_sing; - - igl::n_polyvector(V,F,HardI,HardD,output_field); - - //finally update the principal directions - for (size_t i=0;iN(); - dirN.Normalize(); - Dir=CoordType(1,0,0); - if (fabs(Dir*dirN)>0.9) - Dir=CoordType(0,1,0); - if (fabs(Dir*dirN)>0.9) - Dir=CoordType(0,0,1); - - Dir=dirN^Dir; - Dir.Normalize(); - } - -public: - - struct SmoothParam - { - //the 90° rotation independence while smoothing the direction field - int Ndir; - //the weight of curvature if doing the smoothing keeping the field close to the original one - ScalarType alpha_curv; - //align the field to border or not - bool align_borders; - //threshold to consider some edge as sharp feature and to use as hard constraint (0, not use) - ScalarType sharp_thr; - //threshold to consider some edge as high curvature anisotropyand to use as hard constraint (0, not use) - ScalarType curv_thr; - //the method used to smooth MIQ or "Designing N-PolyVector Fields with Complex Polynomials" - SmoothMethod SmoothM; - //the number of faces of the ring used ot esteem the curvature - int curvRing; - - SmoothParam() - { - Ndir=4; - curvRing=2; - alpha_curv=0.0; - - align_borders=false; - - SmoothM=SMMiq; - - sharp_thr=0.0; - curv_thr=0.4; - } - - }; - - static void SelectConstraints(MeshType &mesh,SmoothParam &SParam) - { - //clear all selected faces - vcg::tri::UpdateFlags::FaceClearS(mesh); - - //add curvature hard constraints - //ScalarType Ratio=mesh.bbox.Diag()*0.01; - - if (SParam.curv_thr>0) - AddCurvatureConstraints(mesh,SParam.curv_thr);///Ratio); - - //add alignment to sharp features - if (SParam.sharp_thr>0) - AddSharpEdgesConstraints(mesh,SParam.sharp_thr); - - //add border constraints - if (SParam.align_borders) - AddBorderConstraints(mesh); - } - - static void GloballyOrient(MeshType &mesh) - { - vcg::tri::CrossField::MakeDirectionFaceCoherent(mesh,true); - } - - static void InitByCurvature(MeshType & mesh,int Nring) - { - - tri::RequirePerVertexCurvatureDir(mesh); - - Eigen::MatrixXi F; - Eigen::MatrixXd V; - - Eigen::MatrixXd PD1,PD2,PV1,PV2; - MeshToMatrix::GetTriMeshData(mesh,F,V); - igl::principal_curvature(V,F,PD1,PD2,PV1,PV2,Nring); - - //then copy curvature per vertex - for (size_t i=0;i::SetFaceCrossVectorFromVert(mesh); - InitQualityByAnisotropyDir(mesh); - } - - static void SmoothDirections(MeshType &mesh, - int Ndir, - SmoothMethod SMethod=SMNPoly, - bool HardAsS=true, - ScalarType alphaSoft=0) - { - - Eigen::VectorXi HardI; //hard constraints - Eigen::MatrixXd HardD; //hard directions - Eigen::VectorXi SoftI; //soft constraints - Eigen::VectorXd SoftW; //weight of soft constraints - Eigen::MatrixXd SoftD; //soft directions - - if (HardAsS) - CollectHardConstraints(mesh,HardI,HardD,SMethod,Ndir); - - //collect soft constraints , miw only one that allows for soft constraints - if ((alphaSoft>0)&&(SMethod==SMMiq)) - CollectSoftConstraints(mesh,SoftI,SoftD,SoftW); - - //add some hard constraints if are not present - int numC=3; - if ((SoftI.rows()==0)&&(HardI.rows()==0)) - { - printf("Add Forced Constraints \n"); - fflush(stdout); - HardI=Eigen::MatrixXi(numC,1); - - if ((Ndir==4)&&(SMethod==SMNPoly)) - HardD=Eigen::MatrixXd(numC,6); - else - HardD=Eigen::MatrixXd(numC,3); - - for (int i=0;i0)|| - (SParam.sharp_thr>0)|| - (SParam.curv_thr>0)) - InitByCurvature(mesh,SParam.curvRing); - - SelectConstraints(mesh,SParam); - //then do the actual smooth - SmoothDirections(mesh,SParam.Ndir,SParam.SmoothM,true,SParam.alpha_curv); - } - -}; - -} // end namespace tri -} // end namespace vcg -#endif // SMOOTHER_FIELD_H