Add mesh generation group
parent
ff19efa188
commit
a749324e79
|
@ -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));
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,8 +97,10 @@ 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];
|
||||||
|
for (size_t j = 0; j < group->nodes.size(); j++) {
|
||||||
|
SkeletonNode *node = &group->nodes[j];
|
||||||
if (left < 0 || node->originX < left) {
|
if (left < 0 || node->originX < left) {
|
||||||
left = node->originX;
|
left = node->originX;
|
||||||
}
|
}
|
||||||
|
@ -106,6 +120,7 @@ void SkeletonToMesh::process()
|
||||||
zRight = node->originZ;
|
zRight = node->originZ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
float height = bottom - top;
|
float height = bottom - top;
|
||||||
if (height <= 0) {
|
if (height <= 0) {
|
||||||
emit finished();
|
emit finished();
|
||||||
|
@ -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];
|
||||||
|
group->bmeshId = meshlite_bmesh_create(context);
|
||||||
|
for (size_t j = 0; j < group->nodes.size(); j++) {
|
||||||
|
SkeletonNode *node = &group->nodes[j];
|
||||||
float x = (node->originX - left - height / 2) / height;
|
float x = (node->originX - left - height / 2) / height;
|
||||||
float y = (node->originY - top - height / 2) / height;
|
float y = (node->originY - top - height / 2) / height;
|
||||||
float z = (node->originZ - zLeft - zWidth / 2) / height;
|
float z = (node->originZ - zLeft - zWidth / 2) / height;
|
||||||
float r = node->radius / height;
|
float r = node->radius / height;
|
||||||
node->bmeshNodeId = meshlite_bmesh_add_node(context, bmesh, x, y, z, r);
|
node->bmeshNodeId = meshlite_bmesh_add_node(context, group->bmeshId, x, y, z, r);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < m_edges.size(); i++) {
|
for (size_t j = 0; j < group->edges.size(); j++) {
|
||||||
SkeletonNode *firstNode = &m_nodes[m_edges[i].firstNode];
|
SkeletonNode *firstNode = &group->nodes[group->edges[j].firstNode];
|
||||||
SkeletonNode *secondNode = &m_nodes[m_edges[i].secondNode];
|
SkeletonNode *secondNode = &group->nodes[group->edges[j].secondNode];
|
||||||
meshlite_bmesh_add_edge(context, bmesh, firstNode->bmeshNodeId, secondNode->bmeshNodeId);
|
meshlite_bmesh_add_edge(context, group->bmeshId, firstNode->bmeshNodeId, secondNode->bmeshNodeId);
|
||||||
}
|
}
|
||||||
int mesh = meshlite_bmesh_generate_mesh(context, bmesh, m_nodes[m_rootNodeId].bmeshNodeId);
|
group->meshId = meshlite_bmesh_generate_mesh(context, group->bmeshId, group->nodes[group->rootNode].bmeshNodeId);
|
||||||
meshlite_bmesh_destroy(context, bmesh);
|
}
|
||||||
int triangulate = meshlite_triangulate(context, mesh);
|
|
||||||
|
int unionMeshId = m_groups[0].meshId;
|
||||||
|
for (size_t i = 1; i < m_groups.size(); i++) {
|
||||||
|
int newUnionMeshId = meshlite_union(context, m_groups[i].meshId, unionMeshId);
|
||||||
|
// TODO: destroy last unionMeshId
|
||||||
|
// ... ...
|
||||||
|
unionMeshId = newUnionMeshId;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < m_groups.size(); i++) {
|
||||||
|
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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue