Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/carve/carve-capi.cc')
-rw-r--r--extern/carve/carve-capi.cc994
1 files changed, 0 insertions, 994 deletions
diff --git a/extern/carve/carve-capi.cc b/extern/carve/carve-capi.cc
deleted file mode 100644
index d6666a52c10..00000000000
--- a/extern/carve/carve-capi.cc
+++ /dev/null
@@ -1,994 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * 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 for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2014 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- * Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "carve-capi.h"
-#include "carve-util.h"
-
-#include <carve/interpolator.hpp>
-#include <carve/rescale.hpp>
-#include <carve/csg_triangulator.hpp>
-#include <carve/mesh_simplify.hpp>
-
-using carve::mesh::MeshSet;
-
-typedef std::pair<int, int> OrigIndex;
-typedef std::pair<MeshSet<3>::vertex_t *, MeshSet<3>::vertex_t *> VertexPair;
-typedef carve::interpolate::VertexAttr<OrigIndex> OrigVertMapping;
-typedef carve::interpolate::FaceAttr<OrigIndex> OrigFaceMapping;
-typedef carve::interpolate::SwapableFaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
-typedef carve::interpolate::SimpleFaceEdgeAttr<bool> FaceEdgeTriangulatedFlag;
-
-typedef struct CarveMeshDescr {
- // Stores mesh data itself.
- MeshSet<3> *poly;
-
- // N-th element of the vector indicates index of an original mesh loop.
- std::unordered_map<std::pair<int, int>, int> orig_loop_index_map;
-
- // Mapping from carve face to an original face index in DM.
- std::unordered_map<const MeshSet<3>::face_t *, int> orig_poly_index_map;
-
- // The folloving mapping is only filled in for output mesh.
-
- // Mapping from the face verts back to original vert index.
- OrigVertMapping orig_vert_mapping;
-
- // Mapping from the face edges back to (original edge index, original loop index).
- OrigFaceEdgeMapping orig_face_edge_mapping;
-
- FaceEdgeTriangulatedFlag face_edge_triangulated_flag;
-
- // Mapping from the faces back to original poly index.
- OrigFaceMapping orig_face_mapping;
-} CarveMeshDescr;
-
-namespace {
-
-template <typename T1, typename T2>
-void edgeIndexMap_put(std::unordered_map<std::pair<T1, T1>, T2> *edge_map,
- const T1 &v1,
- const T1 &v2,
- const T2 &index)
-{
- if (v1 < v2) {
- (*edge_map)[std::make_pair(v1, v2)] = index;
- }
- else {
- (*edge_map)[std::make_pair(v2, v1)] = index;
- }
-}
-
-template <typename T1, typename T2>
-const T2 &edgeIndexMap_get(const std::unordered_map<std::pair<T1, T1>, T2> &edge_map,
- const T1 &v1,
- const T1 &v2)
-{
- typedef std::unordered_map<std::pair<T1, T1>, T2> Map;
- typename Map::const_iterator found;
-
- if (v1 < v2) {
- found = edge_map.find(std::make_pair(v1, v2));
- }
- else {
- found = edge_map.find(std::make_pair(v2, v1));
- }
-
- assert(found != edge_map.end());
- return found->second;
-}
-
-template <typename T1, typename T2>
-bool edgeIndexMap_get_if_exists(const std::unordered_map<std::pair<T1, T1>, T2> &edge_map,
- const T1 &v1,
- const T1 &v2,
- T2 *out)
-{
- typedef std::unordered_map<std::pair<T1, T1>, T2> Map;
- typename Map::const_iterator found;
-
- if (v1 < v2) {
- found = edge_map.find(std::make_pair(v1, v2));
- }
- else {
- found = edge_map.find(std::make_pair(v2, v1));
- }
-
- if (found == edge_map.end()) {
- return false;
- }
- *out = found->second;
- return true;
-}
-
-template <typename T1, typename T2>
-bool edgeIndexMap_exists(const std::unordered_map<std::pair<T1, T1>, T2> &edge_map,
- const T1 &v1,
- const T1 &v2)
-{
- typedef std::unordered_map<std::pair<T1, T1>, T2> Map;
- typename Map::const_iterator found;
-
- if (v1 < v2) {
- found = edge_map.find(std::make_pair(v1, v2));
- }
- else {
- found = edge_map.find(std::make_pair(v2, v1));
- }
-
- return found != edge_map.end();
-}
-
-template <typename T>
-inline int indexOf(const T *element, const std::vector<T> &vector_from)
-{
- return element - &vector_from.at(0);
-}
-
-void initOrigIndexMeshFaceMapping(CarveMeshDescr *mesh,
- int which_mesh,
- std::unordered_map<std::pair<int, int>, int> &orig_loop_index_map,
- std::unordered_map<const MeshSet<3>::face_t*, int> &orig_poly_index_map,
- OrigVertMapping *orig_vert_mapping,
- OrigFaceEdgeMapping *orig_face_edge_mapping,
- FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
- OrigFaceMapping *orig_face_attr)
-{
- MeshSet<3> *poly = mesh->poly;
-
- std::vector<MeshSet<3>::vertex_t>::iterator vertex_iter =
- poly->vertex_storage.begin();
- for (int i = 0;
- vertex_iter != poly->vertex_storage.end();
- ++i, ++vertex_iter)
- {
- MeshSet<3>::vertex_t *vertex = &(*vertex_iter);
- orig_vert_mapping->setAttribute(vertex,
- std::make_pair(which_mesh, i));
- }
-
- MeshSet<3>::face_iter face_iter = poly->faceBegin();
- for (int i = 0, loop_map_index = 0;
- face_iter != poly->faceEnd();
- ++face_iter, ++i)
- {
- const MeshSet<3>::face_t *face = *face_iter;
-
- // Mapping from carve face back to original poly index.
- int orig_poly_index = orig_poly_index_map[face];
- orig_face_attr->setAttribute(face, std::make_pair(which_mesh, orig_poly_index));
-
- for (MeshSet<3>::face_t::const_edge_iter_t edge_iter = face->begin();
- edge_iter != face->end();
- ++edge_iter, ++loop_map_index)
- {
- int v1 = indexOf(edge_iter->v1(), poly->vertex_storage);
- int v2 = indexOf(edge_iter->v2(), poly->vertex_storage);
-
- int orig_loop_index;
- if (!edgeIndexMap_get_if_exists(orig_loop_index_map,
- v1, v2,
- &orig_loop_index))
- {
- orig_loop_index = -1;
- }
-
- if (orig_loop_index != -1) {
- // Mapping from carve face edge back to original loop index.
- orig_face_edge_mapping->setAttribute(face,
- edge_iter.idx(),
- std::make_pair(which_mesh,
- orig_loop_index));
- }
- else {
- face_edge_triangulated_flag->setAttribute(face,
- edge_iter.idx(),
- true);
- }
- }
- }
-}
-
-void initOrigIndexMapping(CarveMeshDescr *left_mesh,
- CarveMeshDescr *right_mesh,
- OrigVertMapping *orig_vert_mapping,
- OrigFaceEdgeMapping *orig_face_edge_mapping,
- FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
- OrigFaceMapping *orig_face_mapping)
-{
- initOrigIndexMeshFaceMapping(left_mesh,
- CARVE_MESH_LEFT,
- left_mesh->orig_loop_index_map,
- left_mesh->orig_poly_index_map,
- orig_vert_mapping,
- orig_face_edge_mapping,
- face_edge_triangulated_flag,
- orig_face_mapping);
-
- initOrigIndexMeshFaceMapping(right_mesh,
- CARVE_MESH_RIGHT,
- right_mesh->orig_loop_index_map,
- right_mesh->orig_poly_index_map,
- orig_vert_mapping,
- orig_face_edge_mapping,
- face_edge_triangulated_flag,
- orig_face_mapping);
-}
-
-void origEdgeMappingForFace(MeshSet<3>::face_t *face,
- OrigFaceEdgeMapping *orig_face_edge_mapping,
- std::unordered_map<VertexPair, OrigIndex> *edge_origindex_map)
-{
- OrigIndex origindex_none = std::make_pair((int)CARVE_MESH_NONE, -1);
-
- MeshSet<3>::edge_t *edge = face->edge;
- for (int i = 0;
- i < face->nEdges();
- ++i, edge = edge->next)
- {
- MeshSet<3>::vertex_t *v1 = edge->v1();
- MeshSet<3>::vertex_t *v2 = edge->v2();
-
- OrigIndex orig_edge_index =
- orig_face_edge_mapping->getAttribute(edge->face, i, origindex_none);
-
- edgeIndexMap_put(edge_origindex_map, v1, v2, orig_edge_index);
- }
-}
-
-void dissolveTriangulatedEdges(MeshSet<3>::mesh_t *mesh,
- const std::set< std::pair<int, int> > &open_edges,
- FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
- OrigFaceEdgeMapping *orig_face_edge_mapping)
-{
- typedef std::unordered_set<MeshSet<3>::edge_t *> edge_set_t;
- typedef std::unordered_set<MeshSet<3>::face_t *> face_set_t;
- edge_set_t triangulated_face_edges;
-
- for (int face_index = 0; face_index < mesh->faces.size(); ++face_index) {
- MeshSet<3>::face_t *face = mesh->faces[face_index];
- MeshSet<3>::edge_t *edge = face->edge;
- for (int edge_index = 0;
- edge_index < face->nEdges();
- ++edge_index, edge = edge->next)
- {
- if (edge->rev) {
- const bool is_triangulated_edge =
- face_edge_triangulated_flag->getAttribute(face,
- edge_index,
- false);
- if (is_triangulated_edge) {
- MeshSet<3>::edge_t *e1 = std::min(edge, edge->rev);
- int v1 = indexOf(e1->v1(), mesh->meshset->vertex_storage),
- v2 = indexOf(e1->v2(), mesh->meshset->vertex_storage);
-
- bool is_open = false;
- if (v1 < v2) {
- is_open = open_edges.find(std::make_pair(v1, v2)) != open_edges.end();
- }
- else {
- is_open = open_edges.find(std::make_pair(v2, v1)) != open_edges.end();
- }
-
- if (is_open == false) {
- triangulated_face_edges.insert(e1);
- }
- }
- }
- }
- }
-
- if (triangulated_face_edges.size()) {
- face_set_t triangulated_faces;
- std::unordered_map<VertexPair, OrigIndex> edge_origindex_map;
-
- for (edge_set_t::iterator it = triangulated_face_edges.begin();
- it != triangulated_face_edges.end();
- ++it)
- {
- MeshSet<3>::edge_t *edge = *it;
-
- origEdgeMappingForFace(edge->face,
- orig_face_edge_mapping,
- &edge_origindex_map);
- triangulated_faces.insert(edge->face);
-
- origEdgeMappingForFace(edge->rev->face,
- orig_face_edge_mapping,
- &edge_origindex_map);
- triangulated_faces.insert(edge->rev->face);
- }
-
- carve::mesh::MeshSimplifier simplifier;
- simplifier.dissolveMeshEdges(mesh, triangulated_face_edges);
-
- for (int face_index = 0; face_index < mesh->faces.size(); face_index++) {
- MeshSet<3>::face_t *face = mesh->faces[face_index];
-
- if (triangulated_faces.find(face) != triangulated_faces.end()) {
- MeshSet<3>::edge_t *edge = face->edge;
- for (int edge_index = 0;
- edge_index < face->nEdges();
- ++edge_index, edge = edge->next)
- {
- MeshSet<3>::vertex_t *v1 = edge->v1();
- MeshSet<3>::vertex_t *v2 = edge->v2();
-
- OrigIndex orig_edge_index =
- edgeIndexMap_get(edge_origindex_map,
- v1,
- v2);
-
- orig_face_edge_mapping->setAttribute(face, edge_index, orig_edge_index);
- }
- }
- }
- }
-}
-
-void dissolveTriangulatedEdges(CarveMeshDescr *mesh_descr)
-{
- MeshSet<3> *poly = mesh_descr->poly;
- FaceEdgeTriangulatedFlag *face_edge_triangulated_flag =
- &mesh_descr->face_edge_triangulated_flag;
-
- std::set< std::pair<int, int> > open_edges;
- for (int mesh_index = 0;
- mesh_index < poly->meshes.size();
- ++mesh_index)
- {
- const MeshSet<3>::mesh_t *mesh = poly->meshes[mesh_index];
- for (int edge_index = 0;
- edge_index < mesh->open_edges.size();
- ++edge_index)
- {
- const MeshSet<3>::edge_t *edge = mesh->open_edges[edge_index];
- int v1 = indexOf(edge->v1(), poly->vertex_storage),
- v2 = indexOf(edge->v2(), poly->vertex_storage);
- if (v1 < v2) {
- open_edges.insert(std::make_pair(v1, v2));
- }
- else {
- open_edges.insert(std::make_pair(v2, v1));
- }
- }
- }
-
- for (int mesh_index = 0; mesh_index < poly->meshes.size(); ++mesh_index) {
- MeshSet<3>::mesh_t *mesh = poly->meshes[mesh_index];
- dissolveTriangulatedEdges(mesh,
- open_edges,
- face_edge_triangulated_flag,
- &mesh_descr->orig_face_edge_mapping);
- }
-}
-
-void clipEar(MeshSet<3>::edge_t *ear)
-{
- MeshSet<3>::edge_t *p_edge = ear->prev;
- MeshSet<3>::edge_t *n_edge = ear->next;
-
- p_edge->next = n_edge;
- n_edge->prev = p_edge;
-
- if (ear->face->edge == ear) {
- ear->face->edge = n_edge;
- }
- ear->face->n_edges--;
-
- delete ear;
-}
-
-MeshSet<3>::edge_t *findDegenerateEar(MeshSet<3>::face_t *face)
-{
- for (MeshSet<3>::face_t::edge_iter_t edge_iter = face->begin();
- edge_iter != face->end();
- ++edge_iter)
- {
- MeshSet<3>::edge_t &edge = *edge_iter;
- if (edge.vert == edge.next->next->vert) {
- return edge.next->next;
- }
- }
- return NULL;
-}
-
-class EarClipper : public carve::csg::CSG::Hook {
-public:
- virtual ~EarClipper() {
- }
-
- virtual void processOutputFace(std::vector<MeshSet<3>::face_t *> &faces,
- const MeshSet<3>::face_t *orig,
- bool flipped) {
- for (size_t face_index = 0; face_index < faces.size(); ++face_index) {
- carve::mesh::MeshSet<3>::face_t *face = faces[face_index];
-
- // There's no ears in quads and tris.
- if (face->nVertices() <= 4) {
- continue;
- }
-
- MeshSet<3>::edge_t *ear;
- while ((ear = findDegenerateEar(face)) != NULL) {
- clipEar(ear);
- }
-
- }
- }
-};
-
-class HoleResolver : public carve::csg::CarveHoleResolver {
-
- void removeDuplicatedFaces(std::vector<MeshSet<3>::face_t *> &faces) {
- std::vector<MeshSet<3>::face_t *> out_faces;
- std::vector<MeshSet<3>::face_t *> duplicated_faces;
-
- for (size_t face_index = 0; face_index < faces.size(); ++face_index) {
- carve::mesh::MeshSet<3>::face_t *face = faces[face_index];
- face->canonicalize();
- }
-
- for (size_t i = 0; i < faces.size(); ++i) {
- carve::mesh::MeshSet<3>::face_t *face = faces[i];
-
- bool found = false;
- for (size_t j = i + 1; j < faces.size() && found == false; ++j) {
- MeshSet<3>::face_t *cur_face = faces[j];
- if (cur_face->nEdges() == face->nEdges() &&
- cur_face->edge->vert == face->edge->vert)
- {
-
- MeshSet<3>::edge_t *cur_edge = cur_face->edge,
- *forward_edge = face->edge,
- *backward_edge = face->edge;
- bool forward_matches = true, backward_matches = true;
-
- for (int a = 0; a < cur_face->nEdges(); ++a) {
- if (forward_edge->vert != cur_edge->vert) {
- forward_matches = false;
- if (backward_matches == false) {
- break;
- }
- }
-
- if (backward_edge->vert != cur_edge->vert) {
- backward_matches = false;
- if (forward_matches == false) {
- break;
- }
- }
-
- cur_edge = cur_edge->next;
- forward_edge = forward_edge->next;
- backward_edge = backward_edge->prev;
- }
-
- if (forward_matches || backward_matches) {
- found = true;
- break;
- }
- }
- }
-
- if (found) {
- duplicated_faces.push_back(face);
- }
- else {
- out_faces.push_back(face);
- }
- }
-
- for (int i = 0; i < duplicated_faces.size(); ++i) {
- delete duplicated_faces[i];
- }
-
- std::swap(faces, out_faces);
- }
-
-public:
- virtual ~HoleResolver() {
- }
-
- virtual void processOutputFace(std::vector<MeshSet<3>::face_t *> &faces,
- const MeshSet<3>::face_t *orig,
- bool flipped) {
- carve::csg::CarveHoleResolver::processOutputFace(faces, orig, flipped);
- if (faces.size() > 1) {
- removeDuplicatedFaces(faces);
- }
- }
-};
-
-template <typename Interpolator>
-void copyFaceEdgeAttrs(const MeshSet<3> *poly,
- Interpolator *old_interpolator,
- Interpolator *new_interpolator)
-{
- for (MeshSet<3>::const_face_iter face_iter = poly->faceBegin();
- face_iter != poly->faceEnd();
- ++face_iter)
- {
- const MeshSet<3>::face_t *face = *face_iter;
-
- for (int edge_index = 0;
- edge_index < face->nEdges();
- ++edge_index)
- {
- new_interpolator->copyAttribute(face,
- edge_index,
- old_interpolator);
- }
- }
-}
-
-template <typename Interpolator>
-void cleanupFaceEdgeAttrs(const MeshSet<3> *left,
- const MeshSet<3> *right,
- Interpolator *interpolator)
-{
- Interpolator new_interpolator;
- copyFaceEdgeAttrs(left, interpolator, &new_interpolator);
- copyFaceEdgeAttrs(right, interpolator, &new_interpolator);
- interpolator->swapAttributes(&new_interpolator);
-}
-
-void cleanupFaceEdgeAttrsCallback(const MeshSet<3> *left,
- const MeshSet<3> *right,
- void *descr_v)
-{
- CarveMeshDescr *descr = (CarveMeshDescr *) descr_v;
- cleanupFaceEdgeAttrs(left,
- right,
- &descr->face_edge_triangulated_flag);
- cleanupFaceEdgeAttrs(left,
- right,
- &descr->orig_face_edge_mapping);
-}
-
-void copyVertexAttrsCallback(const carve::mesh::MeshSet<3>::vertex_t *orig_vert,
- const carve::mesh::MeshSet<3>::vertex_t *new_vert,
- void *descr_v)
-{
- CarveMeshDescr *descr = (CarveMeshDescr *) descr_v;
- if (!descr->orig_vert_mapping.hasAttribute(orig_vert)) {
- return;
- }
- if (descr->orig_vert_mapping.hasAttribute(new_vert)) {
- return;
- }
- OrigIndex attr = descr->orig_vert_mapping.getAttribute(orig_vert);
- descr->orig_vert_mapping.setAttribute(new_vert, attr);
- descr->orig_vert_mapping.removeAttribute(orig_vert);
-}
-
-} // namespace
-
-CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
- CarveMeshImporter *mesh_importer)
-{
-#define MAX_STATIC_VERTS 64
-
- CarveMeshDescr *mesh_descr = new CarveMeshDescr;
-
- // Import verices from external mesh to Carve.
- int num_verts = mesh_importer->getNumVerts(import_data);
- std::vector<MeshSet<3>::vertex_t> vertex_storage;
- vertex_storage.reserve(num_verts);
- for (int i = 0; i < num_verts; i++) {
- float position[3];
- mesh_importer->getVertCoord(import_data, i, position);
- vertex_storage.push_back(carve::geom::VECTOR(position[0],
- position[1],
- position[2]));
- }
-
- // Import polys from external mesh to Carve.
- int verts_of_poly_static[MAX_STATIC_VERTS];
- int *verts_of_poly_dynamic = NULL;
- int verts_of_poly_dynamic_size = 0;
-
- int num_polys = mesh_importer->getNumPolys(import_data);
- int loop_index = 0;
- std::vector<int> face_indices;
- TrianglesStorage triangles_storage;
- std::vector<MeshSet<3>::face_t *> faces;
- std::vector<MeshSet<3>::vertex_t *> face_vertices;
- faces.reserve(num_polys);
- for (int i = 0; i < num_polys; i++) {
- int verts_per_poly =
- mesh_importer->getNumPolyVerts(import_data, i);
- int *verts_of_poly;
-
- if (verts_per_poly <= MAX_STATIC_VERTS) {
- verts_of_poly = verts_of_poly_static;
- }
- else {
- if (verts_of_poly_dynamic_size < verts_per_poly) {
- if (verts_of_poly_dynamic != NULL) {
- delete [] verts_of_poly_dynamic;
- }
- verts_of_poly_dynamic = new int[verts_per_poly];
- verts_of_poly_dynamic_size = verts_per_poly;
- }
- verts_of_poly = verts_of_poly_dynamic;
- }
-
- mesh_importer->getPolyVerts(import_data, i, verts_of_poly);
-
- carve::math::Matrix3 axis_matrix;
- if (!carve_checkPolyPlanarAndGetNormal(vertex_storage,
- verts_per_poly,
- verts_of_poly,
- &axis_matrix)) {
- face_indices.clear();
- int num_triangles = carve_triangulatePoly(import_data,
- mesh_importer,
- vertex_storage,
- verts_per_poly,
- verts_of_poly,
- axis_matrix,
- &face_indices,
- &triangles_storage);
- for (int j = 0; j < num_triangles; ++j) {
- MeshSet<3>::face_t *face = new MeshSet<3>::face_t(
- &vertex_storage[face_indices[j * 3]],
- &vertex_storage[face_indices[j * 3 + 1]],
- &vertex_storage[face_indices[j * 3 + 2]]);
- mesh_descr->orig_poly_index_map[face] = i;
- faces.push_back(face);
- }
- }
- else {
- face_vertices.clear();
- face_vertices.reserve(verts_per_poly);
- for (int j = 0; j < verts_per_poly; ++j) {
- face_vertices.push_back(&vertex_storage[verts_of_poly[j]]);
- }
- MeshSet<3>::face_t *face =
- new MeshSet<3>::face_t(face_vertices.begin(),
- face_vertices.end());
- mesh_descr->orig_poly_index_map[face] = i;
- faces.push_back(face);
- }
-
- for (int j = 0; j < verts_per_poly; ++j) {
- int v1 = verts_of_poly[j];
- int v2 = verts_of_poly[(j + 1) % verts_per_poly];
- edgeIndexMap_put(&mesh_descr->orig_loop_index_map, v1, v2, loop_index++);
- }
- }
-
- if (verts_of_poly_dynamic != NULL) {
- delete [] verts_of_poly_dynamic;
- }
-
- std::vector<MeshSet<3>::mesh_t *> meshes;
- MeshSet<3>::mesh_t::create(faces.begin(), faces.end(), meshes, carve::mesh::MeshOptions());
- mesh_descr->poly = new MeshSet<3> (vertex_storage, meshes);
-
- return mesh_descr;
-
-#undef MAX_STATIC_VERTS
-}
-
-void carve_deleteMesh(CarveMeshDescr *mesh_descr)
-{
- delete mesh_descr->poly;
- delete mesh_descr;
-}
-
-bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
- CarveMeshDescr *right_mesh,
- int operation,
- CarveMeshDescr **output_mesh)
-{
- *output_mesh = NULL;
-
- carve::csg::CSG::OP op;
- switch (operation) {
-#define OP_CONVERT(the_op) \
- case CARVE_OP_ ## the_op: \
- op = carve::csg::CSG::the_op; \
- break;
- OP_CONVERT(UNION)
- OP_CONVERT(INTERSECTION)
- OP_CONVERT(A_MINUS_B)
- default:
- return false;
-#undef OP_CONVERT
- }
-
- CarveMeshDescr *output_descr = new CarveMeshDescr;
- output_descr->poly = NULL;
- try {
- MeshSet<3> *left = left_mesh->poly, *right = right_mesh->poly;
- carve::geom3d::Vector min, max;
-
- // TODO(sergey): Make importer/exporter to care about re-scale
- // to save extra mesh iteration here.
- carve_getRescaleMinMax(left, right, &min, &max);
-
- carve::rescale::rescale scaler(min.x, min.y, min.z, max.x, max.y, max.z);
- carve::rescale::fwd fwd_r(scaler);
- carve::rescale::rev rev_r(scaler);
-
- left->transform(fwd_r);
- right->transform(fwd_r);
-
- // Initialize attributes for maping from boolean result mesh back to
- // original geometry indices.
- initOrigIndexMapping(left_mesh, right_mesh,
- &output_descr->orig_vert_mapping,
- &output_descr->orig_face_edge_mapping,
- &output_descr->face_edge_triangulated_flag,
- &output_descr->orig_face_mapping);
-
- carve::csg::CSG csg;
-
- csg.hooks.registerHook(new HoleResolver,
- carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
-
- csg.hooks.registerHook(new EarClipper,
- carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
-
- output_descr->orig_vert_mapping.installHooks(csg);
- output_descr->orig_face_edge_mapping.installHooks(csg);
- output_descr->face_edge_triangulated_flag.installHooks(csg);
- output_descr->orig_face_mapping.installHooks(csg);
-
- // Prepare operands for actual boolean operation.
- //
- // It's needed because operands might consist of several intersecting
- // meshes and in case of another operands intersect an edge loop of
- // intersecting that meshes tessellation of operation result can't be
- // done properly. The only way to make such situations working is to
- // union intersecting meshes of the same operand.
- carve_unionIntersections(&csg, &left, &right,
- copyVertexAttrsCallback,
- cleanupFaceEdgeAttrsCallback,
- (void *) output_descr);
-
- left_mesh->poly = left;
- right_mesh->poly = right;
-
- if (left->meshes.size() == 0 || right->meshes.size() == 0) {
- // Normally shouldn't happen (zero-faces objects are handled by
- // modifier itself), but unioning intersecting meshes which doesn't
- // have consistent normals might lead to empty result which
- // wouldn't work here.
-
- return false;
- }
-
- output_descr->poly = csg.compute(left,
- right,
- op,
- NULL,
- carve::csg::CSG::CLASSIFY_EDGE);
-
- if (output_descr->poly) {
- output_descr->poly->transform(rev_r);
-
- dissolveTriangulatedEdges(output_descr);
- }
- }
- catch (carve::exception e) {
- std::cerr << "CSG failed, exception " << e.str() << std::endl;
- }
- catch (...) {
- std::cerr << "Unknown error in Carve library" << std::endl;
- }
-
- *output_mesh = output_descr;
-
- return output_descr->poly != NULL;
-}
-
-static int exportMesh_handle_edges_list(MeshSet<3> *poly,
- const std::vector<MeshSet<3>::edge_t*> &edges,
- int start_edge_index,
- CarveMeshExporter *mesh_exporter,
- struct ExportMeshData *export_data,
- std::unordered_map<VertexPair, OrigIndex> &edge_origindex_map,
- std::unordered_map<VertexPair, int> *edge_map)
-{
- int num_exported_edges = 0;
-
- for (int i = 0, edge_index = start_edge_index;
- i < edges.size();
- ++i)
- {
- MeshSet<3>::edge_t *edge = edges.at(i);
- MeshSet<3>::vertex_t *v1 = edge->v1();
- MeshSet<3>::vertex_t *v2 = edge->v2();
-
- if (edgeIndexMap_exists(*edge_map, v1, v2)) {
- continue;
- }
-
- const OrigIndex &orig_edge_index = edgeIndexMap_get(edge_origindex_map,
- v1,
- v2);
-
- mesh_exporter->setEdge(export_data,
- edge_index,
- indexOf(v1, poly->vertex_storage),
- indexOf(v2, poly->vertex_storage),
- orig_edge_index.first,
- orig_edge_index.second);
-
- edgeIndexMap_put(edge_map, v1, v2, edge_index);
- ++edge_index;
- ++num_exported_edges;
- }
-
- return num_exported_edges;
-}
-
-void carve_exportMesh(CarveMeshDescr *mesh_descr,
- CarveMeshExporter *mesh_exporter,
- struct ExportMeshData *export_data)
-{
- OrigIndex origindex_none = std::make_pair((int)CARVE_MESH_NONE, -1);
- MeshSet<3> *poly = mesh_descr->poly;
- int num_vertices = poly->vertex_storage.size();
- int num_edges = 0, num_loops = 0, num_polys = 0;
-
- // Get mapping from edge denoted by vertex pair to original edge index,
- //
- // This is needed because internally Carve interpolates data for per-face
- // edges rather then having some global edge storage.
- std::unordered_map<VertexPair, OrigIndex> edge_origindex_map;
- for (MeshSet<3>::face_iter face_iter = poly->faceBegin();
- face_iter != poly->faceEnd();
- ++face_iter)
- {
- MeshSet<3>::face_t *face = *face_iter;
- for (MeshSet<3>::face_t::edge_iter_t edge_iter = face->begin();
- edge_iter != face->end();
- ++edge_iter)
- {
- MeshSet<3>::edge_t &edge = *edge_iter;
- int edge_iter_index = edge_iter.idx();
-
- const OrigIndex &orig_loop_index =
- mesh_descr->orig_face_edge_mapping.getAttribute(face,
- edge_iter_index,
- origindex_none);
-
- OrigIndex orig_edge_index;
-
- if (orig_loop_index.first != CARVE_MESH_NONE) {
- orig_edge_index.first = orig_loop_index.first;
- orig_edge_index.second =
- mesh_exporter->mapLoopToEdge(export_data,
- orig_loop_index.first,
- orig_loop_index.second);
- }
- else {
- orig_edge_index.first = CARVE_MESH_NONE;
- orig_edge_index.second = -1;
- }
-
- MeshSet<3>::vertex_t *v1 = edge.v1();
- MeshSet<3>::vertex_t *v2 = edge.v2();
-
- edgeIndexMap_put(&edge_origindex_map, v1, v2, orig_edge_index);
- }
- }
-
- num_edges = edge_origindex_map.size();
-
- // Count polys and loops from all manifolds.
- for (MeshSet<3>::face_iter face_iter = poly->faceBegin();
- face_iter != poly->faceEnd();
- ++face_iter, ++num_polys)
- {
- MeshSet<3>::face_t *face = *face_iter;
- num_loops += face->nEdges();
- }
-
- // Initialize arrays for geometry in exported mesh.
- mesh_exporter->initGeomArrays(export_data,
- num_vertices,
- num_edges,
- num_loops,
- num_polys);
-
- // Export all the vertices.
- std::vector<MeshSet<3>::vertex_t>::iterator vertex_iter = poly->vertex_storage.begin();
- for (int i = 0; vertex_iter != poly->vertex_storage.end(); ++i, ++vertex_iter) {
- MeshSet<3>::vertex_t *vertex = &(*vertex_iter);
-
- OrigIndex orig_vert_index =
- mesh_descr->orig_vert_mapping.getAttribute(vertex, origindex_none);
-
- float coord[3];
- coord[0] = vertex->v[0];
- coord[1] = vertex->v[1];
- coord[2] = vertex->v[2];
- mesh_exporter->setVert(export_data, i, coord,
- orig_vert_index.first,
- orig_vert_index.second);
- }
-
- // Export all the edges.
- std::unordered_map<VertexPair, int> edge_map;
- for (int i = 0, edge_index = 0; i < poly->meshes.size(); ++i) {
- carve::mesh::Mesh<3> *mesh = poly->meshes[i];
- // Export closed edges.
- edge_index += exportMesh_handle_edges_list(poly,
- mesh->closed_edges,
- edge_index,
- mesh_exporter,
- export_data,
- edge_origindex_map,
- &edge_map);
-
- // Export open edges.
- edge_index += exportMesh_handle_edges_list(poly,
- mesh->open_edges,
- edge_index,
- mesh_exporter,
- export_data,
- edge_origindex_map,
- &edge_map);
- }
-
- // Export all the loops and polys.
- MeshSet<3>::face_iter face_iter = poly->faceBegin();
- for (int loop_index = 0, poly_index = 0;
- face_iter != poly->faceEnd();
- ++face_iter, ++poly_index)
- {
- int start_loop_index = loop_index;
- MeshSet<3>::face_t *face = *face_iter;
- const OrigIndex &orig_face_index =
- mesh_descr->orig_face_mapping.getAttribute(face, origindex_none);
-
- for (MeshSet<3>::face_t::edge_iter_t edge_iter = face->begin();
- edge_iter != face->end();
- ++edge_iter, ++loop_index)
- {
- MeshSet<3>::edge_t &edge = *edge_iter;
- const OrigIndex &orig_loop_index =
- mesh_descr->orig_face_edge_mapping.getAttribute(face,
- edge_iter.idx(),
- origindex_none);
-
- mesh_exporter->setLoop(export_data,
- loop_index,
- indexOf(edge.vert, poly->vertex_storage),
- edgeIndexMap_get(edge_map, edge.v1(), edge.v2()),
- orig_loop_index.first,
- orig_loop_index.second);
- }
-
- mesh_exporter->setPoly(export_data,
- poly_index, start_loop_index, face->nEdges(),
- orig_face_index.first, orig_face_index.second);
- }
-}