Exemple #1
0
    VectorF convert_voxel_attribute_to_vertex_attribute(
            Mesh& mesh, const VectorF& attribute) {
        const size_t num_vertices = mesh.get_num_vertices();
        const size_t vertex_per_voxel = mesh.get_vertex_per_voxel();
        const size_t num_voxels = mesh.get_num_voxels();
        const size_t attr_size = attribute.size();
        const size_t stride = attr_size / num_voxels;

        const VectorI& voxels = mesh.get_voxels();
        if (!mesh.has_attribute("voxel_volume")) {
            mesh.add_attribute("voxel_volume");
        }
        const VectorF& weights = mesh.get_attribute("voxel_volume");

        VectorF result = VectorF::Zero(num_vertices * stride);
        VectorF result_weights = VectorF::Zero(num_vertices);
        for (size_t i=0; i<num_voxels; i++) {
            const VectorI& voxel =
                voxels.segment(i*vertex_per_voxel, vertex_per_voxel);
            Float per_vertex_weight = weights[i] / vertex_per_voxel;
            for (size_t j=0; j<vertex_per_voxel; j++) {
                result_weights[voxel[j]] += per_vertex_weight;
                result.segment(voxel[j]*stride, stride) +=
                    per_vertex_weight * attribute.segment(i*stride, stride);
            }
        }

        for (size_t i=0; i<num_vertices; i++) {
            result.segment(i*stride, stride) /= result_weights[i];
        }
        return result;
    }
Exemple #2
0
    VectorF convert_face_attribute_to_vertex_attribute(
            Mesh& mesh, const VectorF& attribute) {
        const size_t num_vertices = mesh.get_num_vertices();
        const size_t vertex_per_face = mesh.get_vertex_per_face();
        const size_t num_faces = mesh.get_num_faces();
        const size_t attr_size = attribute.size();
        const size_t stride = attr_size / num_faces;

        const VectorI& faces = mesh.get_faces();
        const VectorF& weights = mesh.get_attribute("face_area");

        VectorF result = VectorF::Zero(num_vertices * stride);
        VectorF result_weights = VectorF::Zero(num_vertices);
        for (size_t i=0; i<num_faces; i++) {
            const VectorI& face =
                faces.segment(i*vertex_per_face, vertex_per_face);
            Float per_vertex_weight = weights[i] / vertex_per_face;
            for (size_t j=0; j<vertex_per_face; j++) {
                result_weights[face[j]] += per_vertex_weight;
                result.segment(face[j]*stride, stride) +=
                    per_vertex_weight * attribute.segment(i*stride, stride);
            }
        }

        for (size_t i=0; i<num_vertices; i++) {
            result.segment(i*stride, stride) /= result_weights[i];
        }
        return result;
    }
Exemple #3
0
 void correct_tet_orientation(const VectorF& vertices, VectorI& voxels) {
     const size_t num_voxels = voxels.size() / 4;
     for (size_t i=0; i<num_voxels; i++) {
         const VectorI tet = voxels.segment(i*4, 4);
         const Vector3F& v1 = vertices.segment(tet[0]*3, 3);
         const Vector3F& v2 = vertices.segment(tet[1]*3, 3);
         const Vector3F& v3 = vertices.segment(tet[2]*3, 3);
         const Vector3F& v4 = vertices.segment(tet[3]*3, 3);
         if (!positive_orientated(v1, v2, v3, v4)) {
             voxels[i*4]   = tet[1];
             voxels[i*4+1] = tet[0];
         }
     }
 }
void VertexIsotropicOffsetParameter::apply(VectorF& results,
        const PatternParameter::Variables& vars) {
    const size_t dim = m_wire_network->get_dim();
    const size_t num_vertices = m_wire_network->get_num_vertices();
    const size_t roi_size = m_roi.size();
    const VectorF center = m_wire_network->center();
    const VectorF bbox_max = m_wire_network->get_bbox_max();
    assert(results.size() == dim * num_vertices);
    assert(roi_size == m_transforms.size());

    if (m_formula != "") evaluate_formula(vars);

    const MatrixFr& vertices = m_wire_network->get_vertices();
    size_t seed_vertex_index = m_roi.minCoeff();
    VectorF seed_vertex = vertices.row(seed_vertex_index);
    VectorF seed_offset = VectorF::Zero(dim);
    seed_offset = (bbox_max - center).cwiseProduct(m_dof_dir) * m_value;

    for (size_t i=0; i<roi_size; i++) {
        size_t v_idx = m_roi[i];
        assert(v_idx < num_vertices);
        const MatrixF& trans = m_transforms[i];
        results.segment(v_idx*dim, dim) += trans * seed_offset;
    }
}
Exemple #5
0
    VectorF convert_vertex_attribute_to_voxel_attribute(Mesh& mesh,
            const VectorF& attribute) {
        const size_t num_vertices = mesh.get_num_vertices();
        const size_t num_voxels = mesh.get_num_voxels();
        const size_t vertex_per_voxel = mesh.get_vertex_per_voxel();
        const size_t attr_size = attribute.size();
        const size_t stride = attr_size / num_vertices;

        const VectorI& voxels = mesh.get_voxels();
        VectorF result = VectorF::Zero(num_voxels * stride);

        for (size_t i=0; i<num_voxels; i++) {
            const VectorI& voxel = voxels.segment(i*vertex_per_voxel,
                    vertex_per_voxel);
            for (size_t j=0; j<vertex_per_voxel; j++) {
                result.segment(i*stride, stride) +=
                    attribute.segment(voxel[j]*stride, stride);
            }
        }
        result /= vertex_per_voxel;
        return result;
    }
Exemple #6
0
    VectorF convert_vertex_attribute_to_face_attribute(Mesh& mesh,
            const VectorF& attribute) {
        const size_t num_vertices = mesh.get_num_vertices();
        const size_t num_faces = mesh.get_num_faces();
        const size_t vertex_per_face = mesh.get_vertex_per_face();
        const size_t attr_size = attribute.size();
        const size_t stride = attr_size / num_vertices;

        const VectorI& faces = mesh.get_faces();
        VectorF result = VectorF::Zero(num_faces * stride);

        for (size_t i=0; i<num_faces; i++) {
            const VectorI& face = faces.segment(i*vertex_per_face,
                    vertex_per_face);
            for (size_t j=0; j<vertex_per_face; j++) {
                result.segment(i*stride, stride) +=
                    attribute.segment(face[j]*stride, stride);
            }
        }
        result /= vertex_per_face;
        return result;
    }
Exemple #7
0
    VectorF convert_voxel_attribute_to_face_attribute(
            Mesh& mesh, const VectorF& attribute) {
        const size_t num_faces = mesh.get_num_faces();
        const size_t num_voxels = mesh.get_num_voxels();
        const size_t attr_size = attribute.size();
        const size_t stride = attr_size / num_voxels;
        const size_t vertex_per_voxel = mesh.get_vertex_per_voxel();
        const size_t vertex_per_face = mesh.get_vertex_per_face();

        if (vertex_per_voxel != 4)
            throw NotImplementedError("Voxel type is not yet supported");
        if (vertex_per_face != 3)
            throw NotImplementedError("Face type is not yet supported");

        const VectorI& faces = mesh.get_faces();
        const VectorI& voxels = mesh.get_voxels();

        std::map<Triplet, VectorF> per_face_values;
        for (size_t i=0; i<num_voxels; i++) {
            const VectorI& voxel = voxels.segment(
                    i*vertex_per_voxel, vertex_per_voxel);
            const VectorF& value = attribute.segment(
                    i*stride, stride);
            per_face_values[Triplet(voxel[0], voxel[1], voxel[2])] = value;
            per_face_values[Triplet(voxel[0], voxel[1], voxel[3])] = value;
            per_face_values[Triplet(voxel[0], voxel[2], voxel[3])] = value;
            per_face_values[Triplet(voxel[1], voxel[2], voxel[3])] = value;
        }

        VectorF result = VectorF::Zero(num_faces*stride);
        for (size_t i=0; i<num_faces; i++) {
            const VectorI& face = faces.segment(i*vertex_per_face, vertex_per_face);
            result.segment(i*stride, stride) = per_face_values[
                Triplet(face[0], face[1], face[2])];
        }

        return result;
    }
void VertexMeanCurvatureAttribute::compute_from_mesh(Mesh& mesh) {
    const size_t dim = mesh.get_dim();
    const size_t num_vertices = mesh.get_num_vertices();
    VectorF laplacian = compute_laplacian_vectors(mesh);
    VectorF normals = compute_vertex_normals(mesh);
    assert(laplacian.size() == dim*num_vertices);
    assert(normals.size() == dim*num_vertices);

    if (!mesh.has_attribute("vertex_voronoi_area")) {
        mesh.add_attribute("vertex_voronoi_area");
    }

    const auto& area = mesh.get_attribute("vertex_voronoi_area");
    VectorF& mean_curvature = m_values;
    mean_curvature = VectorF::Zero(num_vertices);
    for (size_t i=0; i<num_vertices; i++) {
        mean_curvature[i] = laplacian.segment(dim*i,dim).norm() * 0.5;
        Float sign = laplacian.segment(dim*i, dim).dot(normals.segment(dim*i,dim));
        if (sign < 0) {
            mean_curvature[i] *= -1;
        }
    }
    mean_curvature = mean_curvature.array() / area.array();
}
Exemple #9
0
 void write_vertices(std::ofstream& fout,
         const VectorF& vertices, const size_t dim) {
     if (dim != 2 && dim != 3) {
         throw IOError("Unsupported mesh dimension: " + std::to_string(dim));
     }
     fout.precision(16);
     size_t num_vertices = vertices.size() / dim;
     for (size_t i=0; i<num_vertices; i++) {
         const auto& v = vertices.segment(i*dim, dim);
         fout << "v";
         for (size_t j=0; j<dim; j++) {
             fout << " " << v[j];
         }
         fout << std::endl;
     }
 }
Exemple #10
0
void EigenSolver::compute_batch_symmetric_2x2(const VectorF& matrices) {
    const size_t dim = 2;
    const size_t flatten_size = 3;
    const size_t num_matrices = matrices.size() / flatten_size;
    m_eigen_values = VectorF(num_matrices * dim);
    m_eigen_vectors = MatrixF(num_matrices * dim, dim);
    for (size_t i=0; i<num_matrices; i++) {
        const VectorF& entries = matrices.segment(i*flatten_size, flatten_size);
        MatrixF M(dim, dim);
        size_t base_idx = i*flatten_size;
        M << matrices[base_idx  ], matrices[base_idx+2],
             matrices[base_idx+2], matrices[base_idx+1],
        m_solver.compute(M);
        m_eigen_values.segment(i*dim, dim) = m_solver.eigenvalues().real();
        m_eigen_vectors.block(i*dim, 0, dim, dim) =
            m_solver.eigenvectors().real();
    }
}