#include "skeletontomesh.h" #include "meshlite.h" #include "skeletoneditnodeitem.h" #include "skeletoneditedgeitem.h" #include "skeletonsnapshot.h" #include "unionmesh.h" #include struct NodeItemInfo { int index; int neighborCount; }; SkeletonToMesh::SkeletonToMesh(SkeletonSnapshot *snapshot) : m_mesh(NULL), m_snapshot(*snapshot) { } SkeletonToMesh::~SkeletonToMesh() { delete m_mesh; } Mesh *SkeletonToMesh::takeResultMesh() { Mesh *mesh = m_mesh; m_mesh = NULL; return mesh; } #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 void SkeletonToMesh::process() { std::vector groups; QRectF globalFront = m_snapshot.boundingBoxFront(); QRectF globalSide = m_snapshot.boundingBoxSide(); QString rootNodeId = m_snapshot.rootNode(); printf("rootNodeId:%s\n", rootNodeId.toUtf8().constData()); float frontMiddleX = m_snapshot.nodes[rootNodeId]["x"].toFloat(); float frontMiddleY = m_snapshot.nodes[rootNodeId]["y"].toFloat(); float sideMiddleX = m_snapshot.nodes[m_snapshot.nodes[rootNodeId]["nextSidePair"]]["x"].toFloat(); m_snapshot.splitByConnectivity(&groups); std::vector meshIds; 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(); std::map bmeshNodeMap; std::map>::iterator nodeIterator; int bmeshId = meshlite_bmesh_create(meshliteContext); for (nodeIterator = skeleton->nodes.begin(); nodeIterator != skeleton->nodes.end(); nodeIterator++) { if ("red" != nodeIterator->second["sideColorName"]) continue; std::map>::iterator nextSidePair = skeleton->nodes.find(nodeIterator->second["nextSidePair"]); if (nextSidePair == skeleton->nodes.end()) continue; 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; } std::map>::iterator edgeIterator; for (edgeIterator = skeleton->edges.begin(); edgeIterator != skeleton->edges.end(); edgeIterator++) { std::map::iterator from = bmeshNodeMap.find(edgeIterator->second["from"]); if (from == bmeshNodeMap.end()) continue; std::map::iterator to = bmeshNodeMap.find(edgeIterator->second["to"]); if (to == bmeshNodeMap.end()) continue; printf("meshlite_bmesh_add_edge %d -> %d\n", from->second, to->second); meshlite_bmesh_add_edge(meshliteContext, bmeshId, from->second, to->second); } if (bmeshNodeMap.size() > 0 && !skeleton->rootNode().isEmpty()) { int meshId = meshlite_bmesh_generate_mesh(meshliteContext, bmeshId, bmeshNodeMap[skeleton->rootNode()]); meshIds.push_back(meshId); } meshlite_bmesh_destroy(meshliteContext, bmeshId); } if (meshIds.size() > 0) { int mergedMeshId = unionMeshs(meshliteContext, meshIds); if (mergedMeshId > 0) { m_mesh = new Mesh(meshliteContext, mergedMeshId); } } meshlite_destroy_context(meshliteContext); emit finished(); }