bool FilterPerceptualMetric::applyFilter(QAction *action, MeshDocument &md, FilterParameterSet & par, vcg::CallBackPos *cb)
{
	switch(ID(action))
	{

		case FP_ROUGHNESS_MULTISCALE :  
		{
			MeshModel* mesh0 = par.getMesh("ReferenceMesh");  // reference mesh 
			MeshModel* mesh1 = par.getMesh("InputMesh");      // the processed mesh
			
			double globalimpact = PerceptualMetrics<CMeshO>::roughnessMultiscale(mesh0->cm, mesh1->cm);

			Log(0,"This metric is not implemented yet!!");
		}
		break;

		case FP_ROUGHNESS_SMOOTHING :  
		{
			MeshModel* mesh0 = par.getMesh("ReferenceMesh");  // reference mesh 
			MeshModel* mesh1 = par.getMesh("InputMesh");      // the processed mesh

			double globalimpact = PerceptualMetrics<CMeshO>::roughnessSmoothing(mesh0->cm, mesh1->cm);
			
			Log(0,"This metric is not implemented yet!!");
		}
		break;

		case FP_STRAIN_ENERGY : 
		{
			MeshModel* mesh0 = par.getMesh("ReferenceMesh");  // reference mesh 
			MeshModel* mesh1 = par.getMesh("InputMesh");      // the processed mesh

			double globalimpact = PerceptualMetrics<CMeshO>::strainEnergy(mesh0->cm, mesh1->cm);
			
			Log(0,"Perceptual Distance: %f",globalimpact);
		}
		break;

		default : assert(0);
	}
	return true;
}
bool FilterFeatureAlignment::applyFilter(QAction *filter, MeshDocument &md, FilterParameterSet & par, vcg::CallBackPos * cb)
{
    glLog=log;  //assign log to a global variable. needed to write the log from everywhere in the code

    //define needed typedef MeshType
    typedef CMeshO MeshType;

    //declare variables for parameters
    int featureType, from, to, step, trials;
    MeshModel *mFix, *mMov, *currMesh;
    //read parameters
    currMesh = md.mm(); //get current mesh from document
    if(par.hasParameter("mFix")) mFix = par.getMesh("mFix"); else mFix = currMesh;
    if(par.hasParameter("mMov")) mMov = par.getMesh("mMov"); else mMov = currMesh;
    if(par.hasParameter("featureType")) featureType = par.getEnum("featureType"); else featureType = -1;
    if(par.hasParameter("trials")) trials = par.getInt("trials"); else trials = 100;
    if(par.hasParameter("from")) from = par.getInt("from"); else from = 1000;
    if(par.hasParameter("to")) to = par.getInt("to"); else to = 5000;
    if(par.hasParameter("step")) step = par.getInt("step"); else step = 1000;

    switch(ID(filter))
    {
        case AF_COMPUTE_FEATURE:
        {            
            switch(featureType){
                case 0:{
                    typedef SmoothCurvatureFeature<MeshType, 6> FeatureType; //define needed typedef FeatureType
                    FeatureType::Parameters param;
                    FeatureType::SetupParameters(param);
                    return ComputeFeatureOperation<MeshType,FeatureType>(*currMesh, param, cb);
                }
                case 1:{
                    typedef APSSCurvatureFeature<MeshType, 3> FeatureType; //define needed typedef FeatureType
                    FeatureType::Parameters param;
                    FeatureType::SetupParameters(param);
                    return ComputeFeatureOperation<MeshType,FeatureType>(*currMesh, param, cb);
                }
                case 2:{
                    typedef FeatureRGB<MeshType, 3> FeatureType; //define needed typedef FeatureType
                    FeatureType::Parameters param;
                    FeatureType::SetupParameters(param);
                    return ComputeFeatureOperation<MeshType,FeatureType>(*currMesh, param, cb);
                }                
                default: assert(0);
            }   //end switch(ftype)
            assert(0);
        }   //end case AF_COMPUTE_FEATURE
        case AF_EXTRACTION:
        {
            switch(featureType){
                case 0:{
                    typedef SmoothCurvatureFeature<MeshType, 6> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    bool ok = ExtractionOperation<AlignerType>(*currMesh, alignerParam, cb);
                    return ok;
                }
                case 1:{
                    typedef FeatureRGB<MeshType, 3> FeatureType; //define needed typedef FeatureType                    
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);                    
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    bool ok = ExtractionOperation<AlignerType>(*currMesh, alignerParam, cb);
                    return ok;
                }                
                default: assert(0);
            }   //end switch(ftype)
            assert(0);
        }   //end case AF_EXTRACTION
        case AF_MATCHING :
        {            
            switch(featureType)
            {                
                case 0:{
                    typedef SmoothCurvatureFeature<MeshType, 6> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = MatchingOperation<AlignerType>(*mFix, *mMov, alignerParam, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }
                case 1:{
                    typedef FeatureRGB<MeshType, 3> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = MatchingOperation<AlignerType>(*mFix, *mMov, alignerParam, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }                
                default: assert(0);
            }  //end switch(ftype)
            assert(0);
        }  //end case AF_MATCHING
        case AF_RIGID_TRANSFORMATION :
        {                      
            switch(featureType)
            {                
                case 0:{
                    typedef SmoothCurvatureFeature<MeshType, 6> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = RigidTransformationOperation<AlignerType>(*mFix, *mMov, alignerParam, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }
                case 1:{
                    typedef FeatureRGB<MeshType, 3> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = RigidTransformationOperation<AlignerType>(*mFix, *mMov, alignerParam, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }               
                default: assert(0);
            }  //end switch(ftype)
            assert(0);
        }  //end case AF_RIGID_TRANSFORMATION
        case AF_CONSENSUS :
        {                        
            typedef OverlapEstimation<CMeshO> ConsensusType;
            ConsensusType::Parameters consParam;
            //set up params for consensus
            consParam.samples = math::Clamp(par.getInt("fullConsensusSamples"),1,mMov->cm.VertexNumber());
            consParam.consensusDist=math::Clamp<float>(par.getFloat("consensusDist"),0.0f,100.0f);
            consParam.paint = par.getBool("paint");
            consParam.normalEqualization = par.getBool("normEq");
            consParam.threshold = 0.0f;
            consParam.bestScore = 0;
            float result = ConsensusOperation<ConsensusType>(*mFix, *mMov, consParam, cb);
            if(result<0){
                errorMessage = "Consensus Initialization fails.";
                return false; }

            Log("Consensus of %.2f%%", 100*result);
            return true;
        }
        case AF_RANSAC:
        {                                
            switch(featureType){
                case 0:{
                    typedef SmoothCurvatureFeature<MeshType, 6> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);                    
                    ResultType res = RansacOperation<AlignerType>(*mFix, *mMov, alignerParam, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }
                case 1:{
                    typedef APSSCurvatureFeature<MeshType, 3> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = RansacOperation<AlignerType>(*mFix, *mMov, alignerParam, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }
                case 2:{
                    typedef FeatureRGB<MeshType, 3> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = RansacOperation<AlignerType>(*mFix, *mMov, alignerParam, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }                
                default: assert(0);
            }  // end switch(ftype)            
            assert(0);
        }  //end case AF_RANSAC
        case AF_RANSAC_DIAGRAM:
        {                                                
            switch(featureType){
                case 0:{
                    typedef SmoothCurvatureFeature<MeshType, 6> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = RansacDiagramOperation<AlignerType>(*mFix, *mMov, alignerParam, trials, from, to, step, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }
                case 1:{
                    typedef APSSCurvatureFeature<MeshType, 3> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = RansacDiagramOperation<AlignerType>(*mFix, *mMov, alignerParam, trials, from, to, step, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }
                case 2:{
                    typedef FeatureRGB<MeshType, 3> FeatureType; //define needed typedef FeatureType
                    typedef FeatureAlignment<MeshType, FeatureType> AlignerType;  //define the Aligner class
                    typedef AlignerType::Result ResultType;
                    AlignerType::Parameters alignerParam(mFix->cm, mMov->cm);
                    setAlignmentParameters<AlignerType>(mFix->cm, mMov->cm, par, alignerParam);
                    ResultType res = RansacDiagramOperation<AlignerType>(*mFix, *mMov, alignerParam, trials, from, to, step, cb);
                    return logResult<AlignerType>(ID(filter), res, errorMessage);
                }                
                default: assert(0);
            }  // end switch(ftype)
            assert(0);
        }  //end case AF_RANSAC_DIAGRAM                                         
        default: assert(0);
    } // end switch(ID(filter))
    return false;
}