From f48d6bd5f51cf6786d9e6157eca22efb485e7036 Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Thu, 29 Mar 2018 17:10:59 +0800 Subject: [PATCH] Seperate mesh union as single source file --- dust3d.pro | 3 + src/skeletoneditnodeitem.cpp | 2 +- src/skeletontomesh.cpp | 256 ++-------------------------------- src/unionmesh.cpp | 257 +++++++++++++++++++++++++++++++++++ src/unionmesh.h | 7 + 5 files changed, 281 insertions(+), 244 deletions(-) create mode 100644 src/unionmesh.cpp create mode 100644 src/unionmesh.h diff --git a/dust3d.pro b/dust3d.pro index af06296c..689d43c7 100644 --- a/dust3d.pro +++ b/dust3d.pro @@ -43,6 +43,9 @@ HEADERS += src/theme.h SOURCES += src/mesh.cpp HEADERS += src/mesh.h +SOURCES += src/unionmesh.cpp +HEADERS += src/unionmesh.h + SOURCES += src/main.cpp INCLUDEPATH += ../meshlite/include diff --git a/src/skeletoneditnodeitem.cpp b/src/skeletoneditnodeitem.cpp index a71ddb33..b5b0e74f 100644 --- a/src/skeletoneditnodeitem.cpp +++ b/src/skeletoneditnodeitem.cpp @@ -124,7 +124,7 @@ void SkeletonEditNodeItem::updateAppearance() QColor penColor = m_sideColor; penColor.setAlphaF(m_checked ? Theme::checkedAlpha : (m_isBranch ? Theme::branchAlpha : Theme::normalAlpha)); QPen pen(penColor); - pen.setWidth(m_isRoot ? Theme::skeletonNodeBorderSize : (Theme::skeletonNodeBorderSize * 2)); + pen.setWidth(m_isRoot ? (Theme::skeletonNodeBorderSize * 2) : Theme::skeletonNodeBorderSize); setPen(pen); QColor brushColor = m_sideColor; diff --git a/src/skeletontomesh.cpp b/src/skeletontomesh.cpp index adf075ae..e9d6bebc 100644 --- a/src/skeletontomesh.cpp +++ b/src/skeletontomesh.cpp @@ -3,205 +3,9 @@ #include "skeletoneditnodeitem.h" #include "skeletoneditedgeitem.h" #include "skeletonsnapshot.h" +#include "unionmesh.h" #include -#define USE_CARVE 0 -#define USE_CGAL 1 -#define USE_EXTERNAL (USE_CARVE == 1 || USE_CGAL == 1) - -#if USE_CARVE == 1 -#if defined(HAVE_CONFIG_H) -# include -#endif -#include -#include -#include -#endif - -#define MAX_VERTICES_PER_FACE 100 - -#if USE_CGAL == 1 -// Polygon_mesh_processing/corefinement_mesh_union.cpp -// https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2corefinement_mesh_union_8cpp-example.html#a2 -// https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2triangulate_faces_example_8cpp-example.html -// https://github.com/CGAL/cgal/issues/2875 -#include -#include -#include -#include -#include -#include - -typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; -typedef CGAL::Surface_mesh CgalMesh; -namespace PMP = CGAL::Polygon_mesh_processing; - -CgalMesh *makeCgalMeshFromMeshlite(void *meshlite, int meshId) -{ - CgalMesh *mesh = new CgalMesh; - int vertexCount = meshlite_get_vertex_count(meshlite, meshId); - float *vertexPositions = new float[vertexCount * 3]; - int vertexArrayLen = meshlite_get_vertex_position_array(meshlite, meshId, vertexPositions, vertexCount * 3); - int offset = 0; - assert(vertexArrayLen == vertexCount * 3); - std::vector vertices; - for (int i = 0; i < vertexCount; i++) { - vertices.push_back(mesh->add_vertex(Kernel::Point_3(vertexPositions[offset + 0], - vertexPositions[offset + 1], - vertexPositions[offset + 2]))); - offset += 3; - } - int faceCount = meshlite_get_face_count(meshlite, meshId); - int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE]; - int filledLength = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * MAX_VERTICES_PER_FACE); - int i = 0; - while (i < filledLength) { - int num = faceVertexNumAndIndices[i++]; - assert(num > 0 && num <= MAX_VERTICES_PER_FACE); - std::vector faceIndices; - for (int j = 0; j < num; j++) { - int index = faceVertexNumAndIndices[i++]; - assert(index >= 0 && index < vertexCount); - faceIndices.push_back(vertices[index]); - } - mesh->add_face(faceIndices); - } - delete[] faceVertexNumAndIndices; - delete[] vertexPositions; - return mesh; -} - -// https://doc.cgal.org/latest/Surface_mesh/index.html#circulators_example -// https://www.cgal.org/FAQ.html - -int makeMeshliteMeshFromCgal(void *meshlite, CgalMesh *mesh) -{ - CgalMesh::Vertex_range vertexRange = mesh->vertices(); - int vertexCount = vertexRange.size(); - float *vertexPositions = new float[vertexCount * 3]; - int offset = 0; - CgalMesh::Vertex_range::iterator vertexIt; - std::map vertexIndexMap; - int i = 0; - for (vertexIt = vertexRange.begin(); vertexIt != vertexRange.end(); vertexIt++) { - Kernel::Point_3 point = mesh->point(*vertexIt); - vertexPositions[offset++] = CGAL::to_double(point.x()); - vertexPositions[offset++] = CGAL::to_double(point.y()); - vertexPositions[offset++] = CGAL::to_double(point.z()); - vertexIndexMap[*vertexIt] = i; - i++; - } - CgalMesh::Face_range faceRage = mesh->faces(); - int faceCount = faceRage.size(); - int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE]; - CgalMesh::Face_range::iterator faceIt; - offset = 0; - for (faceIt = faceRage.begin(); faceIt != faceRage.end(); faceIt++) { - CGAL::Vertex_around_face_iterator vbegin, vend; - std::vector indices; - for (boost::tie(vbegin, vend) = CGAL::vertices_around_face(mesh->halfedge(*faceIt), *mesh); - vbegin != vend; - ++vbegin){ - indices.push_back(vertexIndexMap[*vbegin]); - } - faceVertexNumAndIndices[offset++] = indices.size(); - for (int j = 0; j < (int)indices.size(); j++) { - faceVertexNumAndIndices[offset++] = indices[j]; - } - } - int meshId = meshlite_build(meshlite, vertexPositions, vertexCount, faceVertexNumAndIndices, offset); - delete[] vertexPositions; - delete[] faceVertexNumAndIndices; - return meshId; -} - -CgalMesh *unionCgalMeshs(CgalMesh *first, CgalMesh *second) -{ - CgalMesh *mesh = new CgalMesh; - if (!PMP::corefine_and_compute_union(*first, *second, *mesh)) { - return NULL; - } - return mesh; -} - -#endif - -#if USE_CARVE == 1 - -carve::poly::Polyhedron *makeCarveMeshFromMeshlite(void *meshlite, int meshId) -{ - carve::input::PolyhedronData data; - int vertexCount = meshlite_get_vertex_count(meshlite, meshId); - float *vertexPositions = new float[vertexCount * 3]; - int vertexArrayLen = meshlite_get_vertex_position_array(meshlite, meshId, vertexPositions, vertexCount * 3); - int offset = 0; - assert(vertexArrayLen == vertexCount * 3); - for (int i = 0; i < vertexCount; i++) { - data.addVertex(carve::geom::VECTOR( - vertexPositions[offset + 0], - vertexPositions[offset + 1], - vertexPositions[offset + 2])); - offset += 3; - } - int faceCount = meshlite_get_face_count(meshlite, meshId); - int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE]; - int filledLength = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * MAX_VERTICES_PER_FACE); - int i = 0; - while (i < filledLength) { - int num = faceVertexNumAndIndices[i++]; - assert(num > 0 && num <= MAX_VERTICES_PER_FACE); - std::vector faceIndices; - for (int j = 0; j < num; j++) { - int index = faceVertexNumAndIndices[i++]; - assert(index >= 0 && index < vertexCount); - faceIndices.push_back(index); - } - data.addFace(faceIndices.begin(), faceIndices.end()); - } - delete[] faceVertexNumAndIndices; - delete[] vertexPositions; - return new carve::poly::Polyhedron(data.points, data.getFaceCount(), data.faceIndices); -} - -int makeMeshliteMeshFromCarve(void *meshlite, carve::poly::Polyhedron *polyhedron) -{ - int vertexCount = polyhedron->vertices.size(); - float *vertexPositions = new float[vertexCount * 3]; - int offset = 0; - std::map::vertex_t *, int> vertexIndexMap; - for (int i = 0; i < vertexCount; i++) { - auto vertex = &polyhedron->vertices[i]; - vertexPositions[offset++] = vertex->v.x; - vertexPositions[offset++] = vertex->v.y; - vertexPositions[offset++] = vertex->v.z; - vertexIndexMap[vertex] = i; - } - int faceCount = polyhedron->faces.size(); - int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE]; - offset = 0; - for (int i = 0; i < faceCount; i++) { - auto face = &polyhedron->faces[i]; - faceVertexNumAndIndices[offset++] = face->vertices.size(); - for (int j = 0; j < (int)face->vertices.size(); j++) { - faceVertexNumAndIndices[offset++] = vertexIndexMap[face->vertices[j]]; - } - } - int meshId = meshlite_build(meshlite, vertexPositions, vertexCount, faceVertexNumAndIndices, offset); - delete[] vertexPositions; - delete[] faceVertexNumAndIndices; - return meshId; -} - -carve::poly::Polyhedron *unionCarveMeshs(carve::poly::Polyhedron *first, - carve::poly::Polyhedron *second) -{ - carve::csg::CSG csg; - carve::poly::Polyhedron *result = csg.compute(first, second, carve::csg::CSG::UNION, NULL, carve::csg::CSG::CLASSIFY_EDGE); - return new carve::poly::Polyhedron(*result); -} - -#endif - struct NodeItemInfo { int index; @@ -256,10 +60,10 @@ void SkeletonToMesh::process() void *meshliteContext = meshlite_create_context(); for (size_t i = 0; i < groups.size(); i++) { SkeletonSnapshot *skeleton = &groups[i]; - QRectF front = skeleton->boundingBoxFront(); - QRectF side = skeleton->boundingBoxSide(); - float canvasWidth = skeleton->canvas["width"].toFloat(); - float canvasHeight = skeleton->canvas["height"].toFloat(); + //QRectF front = skeleton->boundingBoxFront(); + //QRectF side = skeleton->boundingBoxSide(); + //float canvasWidth = skeleton->canvas["width"].toFloat(); + //float canvasHeight = skeleton->canvas["height"].toFloat(); std::map bmeshNodeMap; @@ -271,11 +75,11 @@ void SkeletonToMesh::process() std::map>::iterator nextSidePair = skeleton->nodes.find(nodeIterator->second["nextSidePair"]); if (nextSidePair == skeleton->nodes.end()) continue; - float x = (nodeIterator->second["x"].toFloat() - frontMiddleX) / canvasHeight; - float y = (nodeIterator->second["y"].toFloat() - frontMiddleY) / canvasHeight; - float z = (nextSidePair->second["x"].toFloat() - sideMiddleX) / canvasHeight; - float r = nodeIterator->second["radius"].toFloat() / canvasHeight; - float t = nextSidePair->second["radius"].toFloat() / canvasHeight; + float x = (nodeIterator->second["x"].toFloat() - frontMiddleX) / globalFront.height(); + float y = (nodeIterator->second["y"].toFloat() - frontMiddleY) / globalFront.height(); + float z = (nextSidePair->second["x"].toFloat() - sideMiddleX) / globalFront.height(); + float r = nodeIterator->second["radius"].toFloat() / globalFront.height(); + float t = nextSidePair->second["radius"].toFloat() / globalFront.height(); int bmeshNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, r, t); printf("meshlite_bmesh_add_node x:%f y:%f z:%f r:%f t:%f nodeName:%s bmeshNodeId:%d\n", x, y, z, r, t, nodeIterator->first.toUtf8().constData(), bmeshNodeId); bmeshNodeMap[nodeIterator->first] = bmeshNodeId; @@ -302,44 +106,10 @@ void SkeletonToMesh::process() } if (meshIds.size() > 0) { -#if USE_EXTERNAL -# if USE_CGAL - CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); -# endif - std::vector externalMeshs; - for (size_t i = 0; i < meshIds.size(); i++) { - int triangledMeshId = meshlite_triangulate(meshliteContext, meshIds[i]); - if (meshlite_is_triangulated_manifold(meshliteContext, triangledMeshId)) - externalMeshs.push_back(makeExternalMeshFromMeshlite(meshliteContext, triangledMeshId)); + int mergedMeshId = unionMeshs(meshliteContext, meshIds); + if (mergedMeshId > 0) { + m_mesh = new Mesh(meshliteContext, mergedMeshId); } - if (externalMeshs.size() > 0) { - ExternalMesh *mergedExternalMesh = externalMeshs[0]; - for (size_t i = 1; i < externalMeshs.size(); i++) { - if (!mergedExternalMesh) - break; - ExternalMesh *unionedExternalMesh = NULL; - try { - unionedExternalMesh = unionExternalMeshs(mergedExternalMesh, externalMeshs[i]); - } catch (...) { - // ignore; - } - delete mergedExternalMesh; - delete externalMeshs[i]; - mergedExternalMesh = unionedExternalMesh; - } - if (mergedExternalMesh) { - int mergedMeshId = makeMeshliteMeshFromExternal(meshliteContext, mergedExternalMesh); - delete mergedExternalMesh; - m_mesh = new Mesh(meshliteContext, mergedMeshId); - } - } -#else - int mergedMeshId = meshIds[0]; - for (size_t i = 1; i < meshIds.size(); i++) { - mergedMeshId = meshlite_merge(meshliteContext, mergedMeshId, meshIds[i]); - } - m_mesh = new Mesh(meshliteContext, mergedMeshId); -#endif } meshlite_destroy_context(meshliteContext); diff --git a/src/unionmesh.cpp b/src/unionmesh.cpp new file mode 100644 index 00000000..2f26c3f0 --- /dev/null +++ b/src/unionmesh.cpp @@ -0,0 +1,257 @@ +#include "unionmesh.h" +#include "meshlite.h" + +#define USE_CARVE 0 +#define USE_CGAL 1 + +#define USE_EXTERNAL (USE_CARVE == 1 || USE_CGAL == 1) + +#if USE_CARVE == 1 +#if defined(HAVE_CONFIG_H) +# include +#endif +#include +#include +#include +#endif + +#define MAX_VERTICES_PER_FACE 100 + +#if USE_CGAL == 1 +// Polygon_mesh_processing/corefinement_mesh_union.cpp +// https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2corefinement_mesh_union_8cpp-example.html#a2 +// https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2triangulate_faces_example_8cpp-example.html +// https://github.com/CGAL/cgal/issues/2875 +#include +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; +typedef CGAL::Surface_mesh CgalMesh; +namespace PMP = CGAL::Polygon_mesh_processing; + +CgalMesh *makeCgalMeshFromMeshlite(void *meshlite, int meshId) +{ + CgalMesh *mesh = new CgalMesh; + int vertexCount = meshlite_get_vertex_count(meshlite, meshId); + float *vertexPositions = new float[vertexCount * 3]; + int vertexArrayLen = meshlite_get_vertex_position_array(meshlite, meshId, vertexPositions, vertexCount * 3); + int offset = 0; + assert(vertexArrayLen == vertexCount * 3); + std::vector vertices; + for (int i = 0; i < vertexCount; i++) { + vertices.push_back(mesh->add_vertex(Kernel::Point_3(vertexPositions[offset + 0], + vertexPositions[offset + 1], + vertexPositions[offset + 2]))); + offset += 3; + } + int faceCount = meshlite_get_face_count(meshlite, meshId); + int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE]; + int filledLength = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * MAX_VERTICES_PER_FACE); + int i = 0; + while (i < filledLength) { + int num = faceVertexNumAndIndices[i++]; + assert(num > 0 && num <= MAX_VERTICES_PER_FACE); + std::vector faceIndices; + for (int j = 0; j < num; j++) { + int index = faceVertexNumAndIndices[i++]; + assert(index >= 0 && index < vertexCount); + faceIndices.push_back(vertices[index]); + } + mesh->add_face(faceIndices); + } + delete[] faceVertexNumAndIndices; + delete[] vertexPositions; + return mesh; +} + +// https://doc.cgal.org/latest/Surface_mesh/index.html#circulators_example +// https://www.cgal.org/FAQ.html + +int makeMeshliteMeshFromCgal(void *meshlite, CgalMesh *mesh) +{ + CgalMesh::Vertex_range vertexRange = mesh->vertices(); + int vertexCount = vertexRange.size(); + float *vertexPositions = new float[vertexCount * 3]; + int offset = 0; + CgalMesh::Vertex_range::iterator vertexIt; + std::map vertexIndexMap; + int i = 0; + for (vertexIt = vertexRange.begin(); vertexIt != vertexRange.end(); vertexIt++) { + Kernel::Point_3 point = mesh->point(*vertexIt); + vertexPositions[offset++] = CGAL::to_double(point.x()); + vertexPositions[offset++] = CGAL::to_double(point.y()); + vertexPositions[offset++] = CGAL::to_double(point.z()); + vertexIndexMap[*vertexIt] = i; + i++; + } + CgalMesh::Face_range faceRage = mesh->faces(); + int faceCount = faceRage.size(); + int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE]; + CgalMesh::Face_range::iterator faceIt; + offset = 0; + for (faceIt = faceRage.begin(); faceIt != faceRage.end(); faceIt++) { + CGAL::Vertex_around_face_iterator vbegin, vend; + std::vector indices; + for (boost::tie(vbegin, vend) = CGAL::vertices_around_face(mesh->halfedge(*faceIt), *mesh); + vbegin != vend; + ++vbegin){ + indices.push_back(vertexIndexMap[*vbegin]); + } + faceVertexNumAndIndices[offset++] = indices.size(); + for (int j = 0; j < (int)indices.size(); j++) { + faceVertexNumAndIndices[offset++] = indices[j]; + } + } + int meshId = meshlite_build(meshlite, vertexPositions, vertexCount, faceVertexNumAndIndices, offset); + delete[] vertexPositions; + delete[] faceVertexNumAndIndices; + return meshId; +} + +CgalMesh *unionCgalMeshs(CgalMesh *first, CgalMesh *second) +{ + CgalMesh *mesh = new CgalMesh; + if (!PMP::corefine_and_compute_union(*first, *second, *mesh)) { + return NULL; + } + return mesh; +} + +#endif + +#if USE_CARVE == 1 + +carve::poly::Polyhedron *makeCarveMeshFromMeshlite(void *meshlite, int meshId) +{ + carve::input::PolyhedronData data; + int vertexCount = meshlite_get_vertex_count(meshlite, meshId); + float *vertexPositions = new float[vertexCount * 3]; + int vertexArrayLen = meshlite_get_vertex_position_array(meshlite, meshId, vertexPositions, vertexCount * 3); + int offset = 0; + assert(vertexArrayLen == vertexCount * 3); + for (int i = 0; i < vertexCount; i++) { + data.addVertex(carve::geom::VECTOR( + vertexPositions[offset + 0], + vertexPositions[offset + 1], + vertexPositions[offset + 2])); + offset += 3; + } + int faceCount = meshlite_get_face_count(meshlite, meshId); + int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE]; + int filledLength = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * MAX_VERTICES_PER_FACE); + int i = 0; + while (i < filledLength) { + int num = faceVertexNumAndIndices[i++]; + assert(num > 0 && num <= MAX_VERTICES_PER_FACE); + std::vector faceIndices; + for (int j = 0; j < num; j++) { + int index = faceVertexNumAndIndices[i++]; + assert(index >= 0 && index < vertexCount); + faceIndices.push_back(index); + } + data.addFace(faceIndices.begin(), faceIndices.end()); + } + delete[] faceVertexNumAndIndices; + delete[] vertexPositions; + return new carve::poly::Polyhedron(data.points, data.getFaceCount(), data.faceIndices); +} + +int makeMeshliteMeshFromCarve(void *meshlite, carve::poly::Polyhedron *polyhedron) +{ + int vertexCount = polyhedron->vertices.size(); + float *vertexPositions = new float[vertexCount * 3]; + int offset = 0; + std::map::vertex_t *, int> vertexIndexMap; + for (int i = 0; i < vertexCount; i++) { + auto vertex = &polyhedron->vertices[i]; + vertexPositions[offset++] = vertex->v.x; + vertexPositions[offset++] = vertex->v.y; + vertexPositions[offset++] = vertex->v.z; + vertexIndexMap[vertex] = i; + } + int faceCount = polyhedron->faces.size(); + int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE]; + offset = 0; + for (int i = 0; i < faceCount; i++) { + auto face = &polyhedron->faces[i]; + faceVertexNumAndIndices[offset++] = face->vertices.size(); + for (int j = 0; j < (int)face->vertices.size(); j++) { + faceVertexNumAndIndices[offset++] = vertexIndexMap[face->vertices[j]]; + } + } + int meshId = meshlite_build(meshlite, vertexPositions, vertexCount, faceVertexNumAndIndices, offset); + delete[] vertexPositions; + delete[] faceVertexNumAndIndices; + return meshId; +} + +carve::poly::Polyhedron *unionCarveMeshs(carve::poly::Polyhedron *first, + carve::poly::Polyhedron *second) +{ + carve::csg::CSG csg; + carve::poly::Polyhedron *result = csg.compute(first, second, carve::csg::CSG::UNION, NULL, carve::csg::CSG::CLASSIFY_EDGE); + return new carve::poly::Polyhedron(*result); +} + +#endif + +#if USE_CARVE == 1 +#define ExternalMesh carve::poly::Polyhedron +#define makeExternalMeshFromMeshlite makeCarveMeshFromMeshlite +#define unionExternalMeshs unionCarveMeshs +#define makeMeshliteMeshFromExternal makeMeshliteMeshFromCarve +#endif + +#if USE_CGAL == 1 +#define ExternalMesh CgalMesh +#define makeExternalMeshFromMeshlite makeCgalMeshFromMeshlite +#define unionExternalMeshs unionCgalMeshs +#define makeMeshliteMeshFromExternal makeMeshliteMeshFromCgal +#endif + +int unionMeshs(void *meshliteContext, const std::vector &meshIds) +{ +#if USE_EXTERNAL +# if USE_CGAL + CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); +# endif + std::vector externalMeshs; + for (size_t i = 0; i < meshIds.size(); i++) { + int triangledMeshId = meshlite_triangulate(meshliteContext, meshIds[i]); + if (meshlite_is_triangulated_manifold(meshliteContext, triangledMeshId)) + externalMeshs.push_back(makeExternalMeshFromMeshlite(meshliteContext, triangledMeshId)); + } + if (externalMeshs.size() > 0) { + ExternalMesh *mergedExternalMesh = externalMeshs[0]; + for (size_t i = 1; i < externalMeshs.size(); i++) { + if (!mergedExternalMesh) + break; + ExternalMesh *unionedExternalMesh = NULL; + try { + unionedExternalMesh = unionExternalMeshs(mergedExternalMesh, externalMeshs[i]); + } catch (...) { + // ignore; + } + delete mergedExternalMesh; + delete externalMeshs[i]; + mergedExternalMesh = unionedExternalMesh; + } + if (mergedExternalMesh) { + int mergedMeshId = makeMeshliteMeshFromExternal(meshliteContext, mergedExternalMesh); + delete mergedExternalMesh; + return mergedMeshId; + } + } +#else + int mergedMeshId = meshIds[0]; + for (size_t i = 1; i < meshIds.size(); i++) { + mergedMeshId = meshlite_merge(meshliteContext, mergedMeshId, meshIds[i]); + } + return mergedMeshId; +#endif + return 0; +} \ No newline at end of file diff --git a/src/unionmesh.h b/src/unionmesh.h new file mode 100644 index 00000000..20a627e0 --- /dev/null +++ b/src/unionmesh.h @@ -0,0 +1,7 @@ +#ifndef UNION_MESH_H +#define UNION_MESH_H +#include + +int unionMeshs(void *meshliteContext, const std::vector &meshIds); + +#endif