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:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-03-04 18:01:58 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-03-04 18:18:16 +0400
commit34c7fd1a1120aee8e367bfe7336ca78e2b3e5f8b (patch)
treea2ee4d4d60e79d21104563b99a872d96d36a3b2b /extern/carve/carve-capi.cc
parent58bd0e53f1172b21f674736276e9c22b0d63f3e6 (diff)
Fix T38918: Boolean modifier crashes when using specific topology
There were loads of issues in the code still which are mow likely fixed: - Hole resolver hook had memory leak -- it didn't free face with holes when triangulating it. - Original edge mapping didn't work correct. old code related on the fact that loop order is not changing when constructing the MeshSet class, but in fact it does change. Currently used edge map for this because it was easiest way to do it now, but after the release we're to change it. Main reason is that face mapping is not correct as well (and it was never correct actually). So we'll need to construct Mesh structures by our own to be sure we're using correct original index mapping. - Carve might produce faces with ears, which is forbidden in Blender. it wasn't an issue in old integration because triangulation will remove the ears. So for now simply added ears removing back as a hook. But actual reason of the ears is to be investigated really. This hook will only work for NGons, quads are assumed not be able to have ears. So this additional hook shouldn't slow down things much. - Carve's hole resolver produces duplicated faces in some cases. Still not sure what is the reason of this. Code here is not so much straightforward, this is to be investigated later. For now solved the issue as own hole resolver which checks for duplicated faces after the hole resolving. The additional checks here will only run if the mesh actually have hole and wouldn't introduce slowdown for faces which doesn't have holes. - Made it so if edge user triangulation gets a split (for example, in cases when this edge intersects with the second operand) it wouldn't be dissolved. This prevents cases of crappy topology after dissolving in several cases. - Edge dissolver didn't check for whether edge is a non-manifold. We couldn't really dissolve open manifold edges. The bad thing about this is that mesh triangulation might produce non-manifold edges and they wouldn't be dissolved. Not worst case in the world, but would be nice to have it solved somehow. - Exporting mesh form Carve to Blender might have produced duplicated edges in cases when several non-manifold faces shared the edge. This is also fixed now. - Mesh triangulation might have produced duplicated faces, which is really bad. Fixed by keeping a track on which faces we've created and skipping adding new triangle if we already have one. This all might introduce some slowdown, but we're too close to the release now, so would rather have it slower but robust. After the release we might look into ways to speed things up.
Diffstat (limited to 'extern/carve/carve-capi.cc')
-rw-r--r--extern/carve/carve-capi.cc440
1 files changed, 327 insertions, 113 deletions
diff --git a/extern/carve/carve-capi.cc b/extern/carve/carve-capi.cc
index 319a20129d1..ef7a95e578b 100644
--- a/extern/carve/carve-capi.cc
+++ b/extern/carve/carve-capi.cc
@@ -39,14 +39,14 @@ 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::FaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
-typedef carve::interpolate::FaceEdgeAttr<bool> FaceEdgeTriangulatedFlag;
+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::vector<int> orig_loop_index_map;
+ std::unordered_map<std::pair<int, int>, int> orig_loop_index_map;
// N-th element of the vector indicates index of an original mesh poly.
std::vector<int> orig_poly_index_map;
@@ -123,6 +123,24 @@ bool edgeIndexMap_get_if_exists(const std::unordered_map<std::pair<T1, T1>, T2>
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)
{
@@ -131,7 +149,7 @@ inline int indexOf(const T *element, const std::vector<T> &vector_from)
void initOrigIndexMeshFaceMapping(CarveMeshDescr *mesh,
int which_mesh,
- const std::vector<int> &orig_loop_index_map,
+ std::unordered_map<std::pair<int, int>, int> &orig_loop_index_map,
const std::vector<int> &orig_poly_index_map,
OrigVertMapping *orig_vert_mapping,
OrigFaceEdgeMapping *orig_face_edge_mapping,
@@ -166,7 +184,17 @@ void initOrigIndexMeshFaceMapping(CarveMeshDescr *mesh,
edge_iter != face->end();
++edge_iter, ++loop_map_index)
{
- int orig_loop_index = orig_loop_index_map[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,
@@ -175,7 +203,9 @@ void initOrigIndexMeshFaceMapping(CarveMeshDescr *mesh,
orig_loop_index));
}
else {
- face_edge_triangulated_flag->setAttribute(face, edge_iter.idx(), true);
+ face_edge_triangulated_flag->setAttribute(face,
+ edge_iter.idx(),
+ true);
}
}
}
@@ -215,11 +245,11 @@ void origEdgeMappingForFace(MeshSet<3>::face_t *face,
MeshSet<3>::edge_t *edge = face->edge;
for (int i = 0;
- i < face->n_edges;
+ i < face->nEdges();
++i, edge = edge->next)
{
- MeshSet<3>::vertex_t *v1 = edge->vert;
- MeshSet<3>::vertex_t *v2 = edge->next->vert;
+ 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);
@@ -229,27 +259,43 @@ void origEdgeMappingForFace(MeshSet<3>::face_t *face,
}
void dissolveTriangulatedEdges(MeshSet<3>::mesh_t *mesh,
- OrigFaceEdgeMapping *orig_face_edge_mapping,
- FaceEdgeTriangulatedFlag *face_edge_triangulated_flag)
+ 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++) {
+ 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->n_edges;
+ edge_index < face->nEdges();
++edge_index, edge = edge->next)
{
- 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);
- triangulated_face_edges.insert(e1);
+ 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);
+ }
+ }
}
}
}
@@ -284,11 +330,11 @@ void dissolveTriangulatedEdges(MeshSet<3>::mesh_t *mesh,
if (triangulated_faces.find(face) != triangulated_faces.end()) {
MeshSet<3>::edge_t *edge = face->edge;
for (int edge_index = 0;
- edge_index < face->n_edges;
+ edge_index < face->nEdges();
++edge_index, edge = edge->next)
{
- MeshSet<3>::vertex_t *v1 = edge->vert;
- MeshSet<3>::vertex_t *v2 = edge->next->vert;
+ MeshSet<3>::vertex_t *v1 = edge->v1();
+ MeshSet<3>::vertex_t *v2 = edge->v2();
OrigIndex orig_edge_index =
edgeIndexMap_get(edge_origindex_map,
@@ -308,14 +354,174 @@ void dissolveTriangulatedEdges(CarveMeshDescr *mesh_descr)
FaceEdgeTriangulatedFlag *face_edge_triangulated_flag =
&mesh_descr->face_edge_triangulated_flag;
- for (int i = 0; i < poly->meshes.size(); ++i) {
- MeshSet<3>::mesh_t *mesh = poly->meshes[i];
+ 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,
- &mesh_descr->orig_face_edge_mapping,
- face_edge_triangulated_flag);
+ 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);
+ }
+ }
+};
+
} // namespace
CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
@@ -348,8 +554,8 @@ CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
int num_tessellated_polys = 0;
std::vector<int> face_indices;
face_indices.reserve(num_loops);
- mesh_descr->orig_loop_index_map.reserve(num_polys);
mesh_descr->orig_poly_index_map.reserve(num_polys);
+ TrianglesStorage triangles_storage;
for (int i = 0; i < num_polys; i++) {
int verts_per_poly =
mesh_importer->getNumPolyVerts(import_data, i);
@@ -376,32 +582,35 @@ CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
verts_per_poly,
verts_of_poly,
&axis_matrix)) {
- int num_triangles;
-
- num_triangles = carve_triangulatePoly(import_data,
- mesh_importer,
- i,
- loop_index,
- vertices,
- verts_per_poly,
- verts_of_poly,
- axis_matrix,
- &face_indices,
- &mesh_descr->orig_loop_index_map,
- &mesh_descr->orig_poly_index_map);
+ int num_triangles = carve_triangulatePoly(import_data,
+ mesh_importer,
+ vertices,
+ verts_per_poly,
+ verts_of_poly,
+ axis_matrix,
+ &face_indices,
+ &triangles_storage);
+
+ for (int j = 0; j < num_triangles; ++j) {
+ mesh_descr->orig_poly_index_map.push_back(i);
+ }
num_tessellated_polys += num_triangles;
- loop_index += verts_per_poly;
}
else {
face_indices.push_back(verts_per_poly);
for (int j = 0; j < verts_per_poly; ++j) {
- mesh_descr->orig_loop_index_map.push_back(loop_index++);
face_indices.push_back(verts_of_poly[j]);
}
mesh_descr->orig_poly_index_map.push_back(i);
num_tessellated_polys++;
}
+
+ 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) {
@@ -471,7 +680,10 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
carve::csg::CSG csg;
- csg.hooks.registerHook(new carve::csg::CarveHoleResolver,
+ 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);
@@ -504,10 +716,11 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
op,
NULL,
carve::csg::CSG::CLASSIFY_EDGE);
+
if (output_descr->poly) {
output_descr->poly->transform(rev_r);
- dissolveTriangulatedEdges(output_descr);
+ //dissolveTriangulatedEdges(output_descr);
}
}
catch (carve::exception e) {
@@ -522,33 +735,32 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
return output_descr->poly != NULL;
}
-static void 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,
- const std::unordered_map<VertexPair, OrigIndex> &edge_origindex_map,
- std::unordered_map<VertexPair, int> *edge_map)
+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, ++edge_index)
+ ++i)
{
MeshSet<3>::edge_t *edge = edges.at(i);
- MeshSet<3>::vertex_t *v1 = edge->vert;
- MeshSet<3>::vertex_t *v2 = edge->next->vert;
+ MeshSet<3>::vertex_t *v1 = edge->v1();
+ MeshSet<3>::vertex_t *v2 = edge->v2();
- OrigIndex orig_edge_index;
-
- if (!edgeIndexMap_get_if_exists(edge_origindex_map,
- v1,
- v2,
- &orig_edge_index))
- {
- orig_edge_index.first = CARVE_MESH_NONE;
- orig_edge_index.second = -1;
+ 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),
@@ -557,7 +769,11 @@ static void exportMesh_handle_edges_list(MeshSet<3> *poly,
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,
@@ -569,28 +785,6 @@ void carve_exportMesh(CarveMeshDescr *mesh_descr,
int num_vertices = poly->vertex_storage.size();
int num_edges = 0, num_loops = 0, num_polys = 0;
- // Count edges from all manifolds.
- for (int i = 0; i < poly->meshes.size(); ++i) {
- carve::mesh::Mesh<3> *mesh = poly->meshes[i];
- num_edges += mesh->closed_edges.size() + mesh->open_edges.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->n_edges;
- }
-
- // Initialize arrays for geometry in exported mesh.
- mesh_exporter->initGeomArrays(export_data,
- num_vertices,
- num_edges,
- num_loops,
- num_polys);
-
// Get mapping from edge denoted by vertex pair to original edge index,
//
// This is needed because internally Carve interpolates data for per-face
@@ -613,23 +807,45 @@ void carve_exportMesh(CarveMeshDescr *mesh_descr,
edge_iter_index,
origindex_none);
- if (orig_loop_index.first != CARVE_MESH_NONE) {
- OrigIndex orig_edge_index;
+ 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.vert;
- MeshSet<3>::vertex_t *v2 = edge.next->vert;
+ MeshSet<3>::vertex_t *v1 = edge.v1();
+ MeshSet<3>::vertex_t *v2 = edge.v2();
- edgeIndexMap_put(&edge_origindex_map, v1, v2, orig_edge_index);
- }
+ 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) {
@@ -652,24 +868,22 @@ void carve_exportMesh(CarveMeshDescr *mesh_descr,
for (int i = 0, edge_index = 0; i < poly->meshes.size(); ++i) {
carve::mesh::Mesh<3> *mesh = poly->meshes[i];
// Export closed edges.
- exportMesh_handle_edges_list(poly,
- mesh->closed_edges,
- edge_index,
- mesh_exporter,
- export_data,
- edge_origindex_map,
- &edge_map);
- edge_index += mesh->closed_edges.size();
+ edge_index += exportMesh_handle_edges_list(poly,
+ mesh->closed_edges,
+ edge_index,
+ mesh_exporter,
+ export_data,
+ edge_origindex_map,
+ &edge_map);
// Export open edges.
- exportMesh_handle_edges_list(poly,
- mesh->open_edges,
- edge_index,
- mesh_exporter,
- export_data,
- edge_origindex_map,
- &edge_map);
- edge_index += mesh->open_edges.size();
+ 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.
@@ -694,15 +908,15 @@ void carve_exportMesh(CarveMeshDescr *mesh_descr,
origindex_none);
mesh_exporter->setLoop(export_data,
- loop_index,
- indexOf(edge.vert, poly->vertex_storage),
- edgeIndexMap_get(edge_map, edge.vert, edge.next->vert),
- orig_loop_index.first,
- orig_loop_index.second);
+ 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->n_edges,
+ poly_index, start_loop_index, face->nEdges(),
orig_face_index.first, orig_face_index.second);
}
}