Add mesh generation group

master
Jeremy Hu 2018-03-16 11:06:51 +08:00
parent ff19efa188
commit a749324e79
5 changed files with 98 additions and 52 deletions

View File

@ -179,7 +179,7 @@ void ModelingWidget::initializeGL()
// Our camera never changes in this example. // Our camera never changes in this example.
m_camera.setToIdentity(); m_camera.setToIdentity();
m_camera.translate(0, 0, -4.5); m_camera.translate(0, 0, -2.5);
// Light position is fixed. // Light position is fixed.
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70)); m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));

View File

@ -151,6 +151,13 @@ void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
SkeletonEditEdgeItem *newEdge = new SkeletonEditEdgeItem(); SkeletonEditEdgeItem *newEdge = new SkeletonEditEdgeItem();
newEdge->setNodes(masterNode, m_nextStartNodeItem); newEdge->setNodes(masterNode, m_nextStartNodeItem);
scene()->addItem(newEdge); scene()->addItem(newEdge);
masterNode->setGroup(m_nextStartNodeItem->group());
slaveNode->setGroup(masterNode->group());
} else {
QGraphicsItemGroup *group = new QGraphicsItemGroup();
scene()->addItem(group);
masterNode->setGroup(group);
slaveNode->setGroup(masterNode->group());
} }
setNextStartNodeItem(masterNode); setNextStartNodeItem(masterNode);
emit nodesChanged(); emit nodesChanged();

View File

@ -26,6 +26,7 @@ private:
bool m_isNextStartNode; bool m_isNextStartNode;
SkeletonEditNodeItem *m_master; SkeletonEditNodeItem *m_master;
SkeletonEditNodeItem *m_slave; SkeletonEditNodeItem *m_slave;
private:
void updateBorder(); void updateBorder();
}; };

View File

@ -12,21 +12,34 @@ struct NodeItemInfo
}; };
SkeletonToMesh::SkeletonToMesh(SkeletonEditGraphicsView *graphicsView) : SkeletonToMesh::SkeletonToMesh(SkeletonEditGraphicsView *graphicsView) :
m_mesh(NULL), m_rootNodeId(0) m_mesh(NULL)
{ {
QList<QGraphicsItem *>::iterator it; QList<QGraphicsItem *>::iterator it;
QList<QGraphicsItem *> list = graphicsView->scene()->items(); QList<QGraphicsItem *> list = graphicsView->scene()->items();
std::map<SkeletonEditNodeItem *, NodeItemInfo> nodeItemsMap; std::map<SkeletonEditNodeItem *, NodeItemInfo> nodeItemsMap;
std::map<QGraphicsItemGroup *, int> groupIdsMap;
int maxNeighborCount = 0; int maxNeighborCount = 0;
for (it = list.begin(); it != list.end(); ++it) { for (it = list.begin(); it != list.end(); ++it) {
if ((*it)->data(0).toString() == "edge") { if ((*it)->data(0).toString() == "edge") {
SkeletonEditEdgeItem *edgeItem = static_cast<SkeletonEditEdgeItem *>(*it); SkeletonEditEdgeItem *edgeItem = static_cast<SkeletonEditEdgeItem *>(*it);
SkeletonEditNodeItem *nodeItems[] = {edgeItem->firstNode(), edgeItem->secondNode()}; SkeletonEditNodeItem *nodeItems[] = {edgeItem->firstNode(), edgeItem->secondNode()};
int nodeIndices[] = {0, 0}; int nodeIndices[] = {0, 0};
SkeletonGroup *skeletonGroup = NULL;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
SkeletonEditNodeItem *nodeItem = nodeItems[i]; SkeletonEditNodeItem *nodeItem = nodeItems[i];
std::map<SkeletonEditNodeItem *, NodeItemInfo>::iterator findResult = nodeItemsMap.find(nodeItem); std::map<QGraphicsItemGroup *, int>::iterator findGroupId = groupIdsMap.find(nodeItem->group());
if (findResult == nodeItemsMap.end()) { if (findGroupId == groupIdsMap.end()) {
SkeletonGroup group;
group.maxNeighborCount = 0;
group.rootNode = 0;
group.bmeshId = -1;
group.meshId = -1;
groupIdsMap[nodeItem->group()] = m_groups.size();
m_groups.push_back(group);
}
skeletonGroup = &m_groups[groupIdsMap[nodeItem->group()]];
std::map<SkeletonEditNodeItem *, NodeItemInfo>::iterator findNode = nodeItemsMap.find(nodeItem);
if (findNode == nodeItemsMap.end()) {
SkeletonNode node; SkeletonNode node;
NodeItemInfo info; NodeItemInfo info;
QPointF origin = nodeItem->origin(); QPointF origin = nodeItem->origin();
@ -34,29 +47,28 @@ SkeletonToMesh::SkeletonToMesh(SkeletonEditGraphicsView *graphicsView) :
node.originX = origin.x(); node.originX = origin.x();
node.originY = origin.y(); node.originY = origin.y();
node.originZ = nodeItem->slave()->origin().x(); node.originZ = nodeItem->slave()->origin().x();
node.processed = false;
node.bmeshNodeId = -1; node.bmeshNodeId = -1;
node.radius = nodeItem->radius(); node.radius = nodeItem->radius();
info.index = m_nodes.size(); info.index = skeletonGroup->nodes.size();
info.neighborCount = 1; info.neighborCount = 1;
nodeIndices[i] = info.index; nodeIndices[i] = info.index;
nodeItemsMap[nodeItem] = info; nodeItemsMap[nodeItem] = info;
m_nodes.push_back(node); skeletonGroup->nodes.push_back(node);
} else { } else {
nodeIndices[i] = findResult->second.index; nodeIndices[i] = findNode->second.index;
findResult->second.neighborCount++; findNode->second.neighborCount++;
if (findResult->second.neighborCount > maxNeighborCount) { if (findNode->second.neighborCount > skeletonGroup->maxNeighborCount) {
m_rootNodeId = findResult->second.index; skeletonGroup->rootNode = findNode->second.index;
maxNeighborCount = findResult->second.neighborCount; maxNeighborCount = findNode->second.neighborCount;
} }
} }
} }
SkeletonEdge edge; SkeletonEdge edge;
edge.firstNode = nodeIndices[0]; edge.firstNode = nodeIndices[0];
edge.secondNode = nodeIndices[1]; edge.secondNode = nodeIndices[1];
m_edges.push_back(edge); skeletonGroup->edges.push_back(edge);
} }
} }
} }
@ -75,7 +87,7 @@ Mesh *SkeletonToMesh::takeResultMesh()
void SkeletonToMesh::process() void SkeletonToMesh::process()
{ {
if (m_nodes.size() <= 1) { if (m_groups.size() <= 0) {
emit finished(); emit finished();
return; return;
} }
@ -85,25 +97,28 @@ void SkeletonToMesh::process()
float bottom = -1; float bottom = -1;
float zLeft = -1; float zLeft = -1;
float zRight = -1; float zRight = -1;
for (size_t i = 0; i < m_nodes.size(); i++) { for (size_t i = 0; i < m_groups.size(); i++) {
SkeletonNode *node = &m_nodes[i]; SkeletonGroup *group = &m_groups[i];
if (left < 0 || node->originX < left) { for (size_t j = 0; j < group->nodes.size(); j++) {
left = node->originX; SkeletonNode *node = &group->nodes[j];
} if (left < 0 || node->originX < left) {
if (top < 0 || node->originY < top) { left = node->originX;
top = node->originY; }
} if (top < 0 || node->originY < top) {
if (node->originX > right) { top = node->originY;
right = node->originX; }
} if (node->originX > right) {
if (node->originY > bottom) { right = node->originX;
bottom = node->originY; }
} if (node->originY > bottom) {
if (zLeft < 0 || node->originZ < zLeft) { bottom = node->originY;
zLeft = node->originZ; }
} if (zLeft < 0 || node->originZ < zLeft) {
if (node->originZ > zRight) { zLeft = node->originZ;
zRight = node->originZ; }
if (node->originZ > zRight) {
zRight = node->originZ;
}
} }
} }
float height = bottom - top; float height = bottom - top;
@ -113,23 +128,39 @@ void SkeletonToMesh::process()
} }
float zWidth = right - left; float zWidth = right - left;
void *context = meshlite_create_context(); void *context = meshlite_create_context();
int bmesh = meshlite_bmesh_create(context);
for (size_t i = 0; i < m_nodes.size(); i++) { for (size_t i = 0; i < m_groups.size(); i++) {
SkeletonNode *node = &m_nodes[i]; SkeletonGroup *group = &m_groups[i];
float x = (node->originX - left - height / 2) / height; group->bmeshId = meshlite_bmesh_create(context);
float y = (node->originY - top - height / 2) / height; for (size_t j = 0; j < group->nodes.size(); j++) {
float z = (node->originZ - zLeft - zWidth / 2) / height; SkeletonNode *node = &group->nodes[j];
float r = node->radius / height; float x = (node->originX - left - height / 2) / height;
node->bmeshNodeId = meshlite_bmesh_add_node(context, bmesh, x, y, z, r); float y = (node->originY - top - height / 2) / height;
float z = (node->originZ - zLeft - zWidth / 2) / height;
float r = node->radius / height;
node->bmeshNodeId = meshlite_bmesh_add_node(context, group->bmeshId, x, y, z, r);
}
for (size_t j = 0; j < group->edges.size(); j++) {
SkeletonNode *firstNode = &group->nodes[group->edges[j].firstNode];
SkeletonNode *secondNode = &group->nodes[group->edges[j].secondNode];
meshlite_bmesh_add_edge(context, group->bmeshId, firstNode->bmeshNodeId, secondNode->bmeshNodeId);
}
group->meshId = meshlite_bmesh_generate_mesh(context, group->bmeshId, group->nodes[group->rootNode].bmeshNodeId);
} }
for (size_t i = 0; i < m_edges.size(); i++) {
SkeletonNode *firstNode = &m_nodes[m_edges[i].firstNode]; int unionMeshId = m_groups[0].meshId;
SkeletonNode *secondNode = &m_nodes[m_edges[i].secondNode]; for (size_t i = 1; i < m_groups.size(); i++) {
meshlite_bmesh_add_edge(context, bmesh, firstNode->bmeshNodeId, secondNode->bmeshNodeId); int newUnionMeshId = meshlite_union(context, m_groups[i].meshId, unionMeshId);
// TODO: destroy last unionMeshId
// ... ...
unionMeshId = newUnionMeshId;
} }
int mesh = meshlite_bmesh_generate_mesh(context, bmesh, m_nodes[m_rootNodeId].bmeshNodeId);
meshlite_bmesh_destroy(context, bmesh); for (size_t i = 1; i < m_groups.size(); i++) {
int triangulate = meshlite_triangulate(context, mesh); meshlite_bmesh_destroy(context, m_groups[i].bmeshId);
}
int triangulate = meshlite_triangulate(context, unionMeshId);
meshlite_export(context, triangulate, "/Users/jeremy/testlib.obj"); meshlite_export(context, triangulate, "/Users/jeremy/testlib.obj");
m_mesh = new Mesh(context, triangulate); m_mesh = new Mesh(context, triangulate);
meshlite_destroy_context(context); meshlite_destroy_context(context);

View File

@ -13,7 +13,6 @@ struct SkeletonNode
float originY; float originY;
float originZ; float originZ;
float radius; float radius;
bool processed;
int bmeshNodeId; int bmeshNodeId;
}; };
@ -23,6 +22,16 @@ struct SkeletonEdge
int secondNode; int secondNode;
}; };
struct SkeletonGroup
{
std::vector<SkeletonNode> nodes;
std::vector<SkeletonEdge> edges;
int rootNode;
int maxNeighborCount;
int bmeshId;
int meshId;
};
class SkeletonToMesh : public QObject class SkeletonToMesh : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -36,9 +45,7 @@ public slots:
void process(); void process();
private: private:
Mesh *m_mesh; Mesh *m_mesh;
std::vector<SkeletonNode> m_nodes; std::vector<SkeletonGroup> m_groups;
std::vector<SkeletonEdge> m_edges;
int m_rootNodeId;
}; };
#endif #endif