<commit_before>#include "MeanValueCoordinatesModel.hpp"
#include "FAST/Data/Image.hpp"
#include "FAST/Importers/VTKMeshFileImporter.hpp"

namespace fast {

MeanValueCoordinatesModel::MeanValueCoordinatesModel() {
	mInitializeShapeToImageCenter = false;
}

inline float sign(float v) {
    return v < 0.0f ? -1.0f : 1.0f;
}

std::vector<MeshVertex> MeanValueCoordinatesModel::getDeformedVertices(
        const std::vector<Vector3f>& displacements) {
    MeshAccess::pointer modelMeshAccess = mSurfaceMesh->getMeshAccess(ACCESS_READ);
    std::vector<MeshVertex> vertices = modelMeshAccess->getVertices();
    MeshAccess::pointer controlMeshAccess = mControlMesh->getMeshAccess(ACCESS_READ);
    std::vector<MeshVertex> nodes = controlMeshAccess->getVertices();

    if(displacements.size() != mControlMesh->getNrOfVertices()) {
        throw Exception("The number of displacements is not equal to the number of control nodes.");
    }
    // Get original vertices from the model mesh
    std::vector<MeshVertex> newVertices;

    // Deform these vertices using the weights and displacement vector
    Vector3f* controlNodes = new Vector3f[nodes.size()];
    // TODO this loop could be run in parallel
    for(int i = 0; i < nodes.size(); i++) {
        controlNodes[i] = (nodes[i].getPosition() + displacements[i]);
    }

    for(uint i = 0; i < vertices.size(); i++) {
        Vector3f newVertex(0,0,0);
        for(uint j = 0; j < nodes.size(); j++) {
            newVertex = newVertex + controlNodes[j]*getNormalizedWeight(i, j);
        }
        MeshVertex v(newVertex);
        newVertices.push_back(v);
    }
    delete[] controlNodes;

    // Calculate new normals
    // TODO this loop could be run in parallel
    for(int i = 0; i < vertices.size(); i++) {
        // Find the normal of all triangles
        std::vector<int> triangles = vertices[i].getConnections();
        Vector3f average = Vector3f::Constant(0);
        int counter = 0;
        for(int j = 0; j < triangles.size(); j++) {
            Vector3ui triangle = modelMeshAccess->getTriangle(triangles[j]);
            Vector3f a;
            Vector3f b;
            if(triangle.x() == i) {
                a = newVertices[triangle.y()].getPosition()-newVertices[i].getPosition();
                b = newVertices[triangle.z()].getPosition()-newVertices[i].getPosition();
            } else if(triangle.y() == i) {
                a = newVertices[triangle.x()].getPosition()-newVertices[i].getPosition();
                b = newVertices[triangle.z()].getPosition()-newVertices[i].getPosition();
            } else {
                a = newVertices[triangle.x()].getPosition()-newVertices[i].getPosition();
                b = newVertices[triangle.y()].getPosition()-newVertices[i].getPosition();
            }
            Vector3f faceNormal = a.cross(b);
            faceNormal.normalize();
            // Have to make sure that all the normals are pointing out of the object
            float direction = sign(faceNormal.dot(vertices[i].getNormal()));
            average = average + faceNormal*direction;
            counter++;
        }
        average = average / counter;
        average.normalize();
        newVertices[i].setNormal(average);
    }

    return newVertices;
}

void MeanValueCoordinatesModel::loadMeshes(std::string surfaceMeshFilename, std::string controlMeshFilename) {
	VTKMeshFileImporter::pointer importer = VTKMeshFileImporter::New();

	importer->setFilename(surfaceMeshFilename);
	importer->update();
	Mesh::pointer surfaceMesh = importer->getOutputData<Mesh>();

	VTKMeshFileImporter::pointer importer2 = VTKMeshFileImporter::New();
	importer2->setFilename(controlMeshFilename);
	importer2->update();
	Mesh::pointer controlMesh = importer2->getOutputData<Mesh>();

	loadMeshes(surfaceMesh, controlMesh);
}

void MeanValueCoordinatesModel::loadMeshes(Mesh::pointer surfaceMesh,
		Mesh::pointer controlMesh) {
	mSurfaceMesh = surfaceMesh;
	mControlMesh = controlMesh;
    const float epsilon = 0.00001f;

	MeshAccess::pointer access = mSurfaceMesh->getMeshAccess(ACCESS_READ);
    MeshAccess::pointer access2 = mControlMesh->getMeshAccess(ACCESS_READ);
    std::vector<MeshVertex> nodes = access2->getVertices();
    mStateSize = 9 + nodes.size()*3;

    // Create state transition matrices
    const float dampening = 0.5;

    mA1 = MatrixXf::Zero(mStateSize,mStateSize);
    mA1(0,0) = 1+dampening;
    mA1(1,1) = 1+dampening;
    mA1(2,2) = 1+dampening;
    mA1(3,3) = 1+dampening;
    mA1(4,4) = 1+dampening;
    mA1(5,5) = 1+dampening;
    mA1(6,6) = 0.5;//1+dampening;
    mA1(7,7) = 0.5;//1+dampening;
    mA1(8,8) = 0.5;//1+dampening;
    for(int i = 9; i < mStateSize; ++i)
        mA1(i,i) = 1+dampening;//0.5;

    mA2 = MatrixXf::Zero(mStateSize,mStateSize);
    mA2(0,0) = -dampening;
    mA2(1,1) = -dampening;
    mA2(2,2) = -dampening;
    mA2(3,3) = -dampening;
    mA2(4,4) = -dampening;
    mA2(5,5) = -dampening;
    mA2(6,6) = 0.5;//-dampening;
    mA2(7,7) = 0.5;//-dampening;
    mA2(8,8) = 0.5;//-dampening;
    for(int i = 9; i < mStateSize; ++i) {
        mA2(i,i) = -dampening;//0.5;
    }

    mA3 = MatrixXf::Zero(mStateSize, mStateSize);

    mProcessErrorMatrix = MatrixXf::Zero(mStateSize, mStateSize);
    for(int i = 0; i < mStateSize; ++i) {
    	if(i < 9) {
    		mProcessErrorMatrix(i, i) = 1.5f;
    	} else {
    		mProcessErrorMatrix(i, i) = 0.001f;<commit_msg>tuned some MVC parameters<commit_after>#include "MeanValueCoordinatesModel.hpp"
#include "FAST/Data/Image.hpp"
#include "FAST/Importers/VTKMeshFileImporter.hpp"

namespace fast {

MeanValueCoordinatesModel::MeanValueCoordinatesModel() {
	mInitializeShapeToImageCenter = false;
}

inline float sign(float v) {
    return v < 0.0f ? -1.0f : 1.0f;
}

std::vector<MeshVertex> MeanValueCoordinatesModel::getDeformedVertices(
        const std::vector<Vector3f>& displacements) {
    MeshAccess::pointer modelMeshAccess = mSurfaceMesh->getMeshAccess(ACCESS_READ);
    std::vector<MeshVertex> vertices = modelMeshAccess->getVertices();
    MeshAccess::pointer controlMeshAccess = mControlMesh->getMeshAccess(ACCESS_READ);
    std::vector<MeshVertex> nodes = controlMeshAccess->getVertices();

    if(displacements.size() != mControlMesh->getNrOfVertices()) {
        throw Exception("The number of displacements is not equal to the number of control nodes.");
    }
    // Get original vertices from the model mesh
    std::vector<MeshVertex> newVertices;

    // Deform these vertices using the weights and displacement vector
    Vector3f* controlNodes = new Vector3f[nodes.size()];
    // TODO this loop could be run in parallel
    for(int i = 0; i < nodes.size(); i++) {
        controlNodes[i] = (nodes[i].getPosition() + displacements[i]);
    }

    for(uint i = 0; i < vertices.size(); i++) {
        Vector3f newVertex(0,0,0);
        for(uint j = 0; j < nodes.size(); j++) {
            newVertex = newVertex + controlNodes[j]*getNormalizedWeight(i, j);
        }
        MeshVertex v(newVertex);
        newVertices.push_back(v);
    }
    delete[] controlNodes;

    // Calculate new normals
    // TODO this loop could be run in parallel
    for(int i = 0; i < vertices.size(); i++) {
        // Find the normal of all triangles
        std::vector<int> triangles = vertices[i].getConnections();
        Vector3f average = Vector3f::Constant(0);
        int counter = 0;
        for(int j = 0; j < triangles.size(); j++) {
            Vector3ui triangle = modelMeshAccess->getTriangle(triangles[j]);
            Vector3f a;
            Vector3f b;
            if(triangle.x() == i) {
                a = newVertices[triangle.y()].getPosition()-newVertices[i].getPosition();
                b = newVertices[triangle.z()].getPosition()-newVertices[i].getPosition();
            } else if(triangle.y() == i) {
                a = newVertices[triangle.x()].getPosition()-newVertices[i].getPosition();
                b = newVertices[triangle.z()].getPosition()-newVertices[i].getPosition();
            } else {
                a = newVertices[triangle.x()].getPosition()-newVertices[i].getPosition();
                b = newVertices[triangle.y()].getPosition()-newVertices[i].getPosition();
            }
            Vector3f faceNormal = a.cross(b);
            faceNormal.normalize();
            // Have to make sure that all the normals are pointing out of the object
            float direction = sign(faceNormal.dot(vertices[i].getNormal()));
            average = average + faceNormal*direction;
            counter++;
        }
        average = average / counter;
        average.normalize();
        newVertices[i].setNormal(average);
    }

    return newVertices;
}

void MeanValueCoordinatesModel::loadMeshes(std::string surfaceMeshFilename, std::string controlMeshFilename) {
	VTKMeshFileImporter::pointer importer = VTKMeshFileImporter::New();

	importer->setFilename(surfaceMeshFilename);
	importer->update();
	Mesh::pointer surfaceMesh = importer->getOutputData<Mesh>();

	VTKMeshFileImporter::pointer importer2 = VTKMeshFileImporter::New();
	importer2->setFilename(controlMeshFilename);
	importer2->update();
	Mesh::pointer controlMesh = importer2->getOutputData<Mesh>();

	loadMeshes(surfaceMesh, controlMesh);
}

void MeanValueCoordinatesModel::loadMeshes(Mesh::pointer surfaceMesh,
		Mesh::pointer controlMesh) {
	mSurfaceMesh = surfaceMesh;
	mControlMesh = controlMesh;
    const float epsilon = 0.00001f;

	MeshAccess::pointer access = mSurfaceMesh->getMeshAccess(ACCESS_READ);
    MeshAccess::pointer access2 = mControlMesh->getMeshAccess(ACCESS_READ);
    std::vector<MeshVertex> nodes = access2->getVertices();
    mStateSize = 9 + nodes.size()*3;

    // Create state transition matrices
    const float dampening = 0.5;

    mA1 = MatrixXf::Zero(mStateSize,mStateSize);
    mA1(0,0) = 1+dampening;
    mA1(1,1) = 1+dampening;
    mA1(2,2) = 1+dampening;
    mA1(3,3) = 1+dampening;
    mA1(4,4) = 1+dampening;
    mA1(5,5) = 1+dampening;
    mA1(6,6) = 0.5;//1+dampening;
    mA1(7,7) = 0.5;//1+dampening;
    mA1(8,8) = 0.5;//1+dampening;
    for(int i = 9; i < mStateSize; ++i)
        mA1(i,i) = 0.5;

    mA2 = MatrixXf::Zero(mStateSize,mStateSize);
    mA2(0,0) = -dampening;
    mA2(1,1) = -dampening;
    mA2(2,2) = -dampening;
    mA2(3,3) = -dampening;
    mA2(4,4) = -dampening;
    mA2(5,5) = -dampening;
    mA2(6,6) = 0.5;//-dampening;
    mA2(7,7) = 0.5;//-dampening;
    mA2(8,8) = 0.5;//-dampening;
    for(int i = 9; i < mStateSize; ++i) {
        mA2(i,i) = 0.5;
    }

    mA3 = MatrixXf::Zero(mStateSize, mStateSize);

    mProcessErrorMatrix = MatrixXf::Zero(mStateSize, mStateSize);
    for(int i = 0; i < mStateSize; ++i) {
    	if(i < 9) {
    		mProcessErrorMatrix(i, i) = 0.01f;
    	} else {
    		mProcessErrorMatrix(i, i) = 0.000001f;
{'fraction_non_alphanumeric': 0.1433200629571336, 'fraction_numerical': 0.025645773539487084, 'mean_word_length': 3.20147802411513, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3639642', 'n_tokens_mistral': 3801, 'n_tokens_neox': 3632, 'n_words': 688}