Skip to content

Commit

Permalink
Add part mirror
Browse files Browse the repository at this point in the history
  • Loading branch information
huxingyi committed Apr 15, 2018
1 parent 7437ddb commit 44a8ca6
Show file tree
Hide file tree
Showing 17 changed files with 565 additions and 120 deletions.
97 changes: 44 additions & 53 deletions src/meshgenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,55 +75,9 @@ QImage *MeshGenerator::takePartPreview(const QString &partId)
return resultImage;
}

void MeshGenerator::resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile)
void MeshGenerator::resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile, const QString &partId)
{
float left = 0;
bool leftFirstTime = true;
float right = 0;
bool rightFirstTime = true;
float top = 0;
bool topFirstTime = true;
float bottom = 0;
bool bottomFirstTime = true;
float zLeft = 0;
bool zLeftFirstTime = true;
float zRight = 0;
bool zRightFirstTime = true;
for (const auto &nodeIt: m_snapshot->nodes) {
float radius = valueOfKeyInMapOrEmpty(nodeIt.second, "radius").toFloat();
float x = valueOfKeyInMapOrEmpty(nodeIt.second, "x").toFloat();
float y = valueOfKeyInMapOrEmpty(nodeIt.second, "y").toFloat();
float z = valueOfKeyInMapOrEmpty(nodeIt.second, "z").toFloat();
if (leftFirstTime || x - radius < left) {
left = x - radius;
leftFirstTime = false;
}
if (topFirstTime || y - radius < top) {
top = y - radius;
topFirstTime = false;
}
if (rightFirstTime || x + radius > right) {
right = x + radius;
rightFirstTime = false;
}
if (bottomFirstTime || y + radius > bottom) {
bottom = y + radius;
bottomFirstTime = false;
}
if (zLeftFirstTime || z - radius < zLeft) {
zLeft = z - radius;
zLeftFirstTime = false;
}
if (zRightFirstTime || z + radius > zRight) {
zRight = z + radius;
zRightFirstTime = false;
}
}
*mainProfile = QRectF(QPointF(left, top), QPointF(right, bottom));
*sideProfile = QRectF(QPointF(zLeft, top), QPointF(zRight, bottom));
qDebug() << "resolveBoundingBox left:" << left << "top:" << top << "right:" << right << "bottom:" << bottom << " zLeft:" << zLeft << "zRight:" << zRight;
qDebug() << "mainHeight:" << mainProfile->height() << "mainWidth:" << mainProfile->width();
qDebug() << "sideHeight:" << sideProfile->height() << "sideWidth:" << sideProfile->width();
m_snapshot->resolveBoundingBox(mainProfile, sideProfile, partId);
}

void MeshGenerator::process()
Expand All @@ -145,6 +99,19 @@ void MeshGenerator::process()
float mainProfileMiddleX = mainProfile.x() + mainProfile.width() / 2;
float sideProfileMiddleX = sideProfile.x() + sideProfile.width() / 2;
float mainProfileMiddleY = mainProfile.y() + mainProfile.height() / 2;
float originX = valueOfKeyInMapOrEmpty(m_snapshot->canvas, "originX").toFloat();
float originY = valueOfKeyInMapOrEmpty(m_snapshot->canvas, "originY").toFloat();
float originZ = valueOfKeyInMapOrEmpty(m_snapshot->canvas, "originZ").toFloat();
bool originSettled = false;
if (originX > 0 && originY > 0 && originZ > 0) {
qDebug() << "Use settled origin: " << originX << originY << originZ << " calculated:" << mainProfileMiddleX << mainProfileMiddleY << sideProfileMiddleX;
mainProfileMiddleX = originX;
mainProfileMiddleY = originY;
sideProfileMiddleX = originZ;
originSettled = true;
} else {
qDebug() << "No settled origin, calculated:" << mainProfileMiddleX << mainProfileMiddleY << sideProfileMiddleX;
}

for (const auto &partIdIt: m_snapshot->partIdList) {
const auto &part = m_snapshot->parts.find(partIdIt);
Expand Down Expand Up @@ -241,7 +208,19 @@ void MeshGenerator::process()
int meshId = meshlite_bmesh_generate_mesh(meshliteContext, bmeshId);
if (meshlite_bmesh_error_count(meshliteContext, bmeshId) != 0)
broken = true;
bool subdived = isTrueValueString(part->second["subdived"]);
bool xMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(part->second, "xMirrored"));
bool zMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(part->second, "zMirrored"));
int xMirroredMeshId = 0;
int zMirroredMeshId = 0;
if (xMirrored || zMirrored) {
if (xMirrored) {
xMirroredMeshId = meshlite_mirror_in_x(meshliteContext, meshId, 0);
}
if (zMirrored) {
zMirroredMeshId = meshlite_mirror_in_z(meshliteContext, meshId, 0);
}
}
bool subdived = isTrueValueString(valueOfKeyInMapOrEmpty(part->second, "subdived"));
if (m_requirePartPreviewMap.find(partIdIt) != m_requirePartPreviewMap.end()) {
ModelOfflineRender *render = m_partPreviewRenderMap[partIdIt];
int trimedMeshId = meshlite_trim(meshliteContext, meshId, 1);
Expand All @@ -255,10 +234,19 @@ void MeshGenerator::process()
QImage *image = new QImage(render->toImage(QSize(Theme::previewImageSize, Theme::previewImageSize)));
m_partPreviewMap[partIdIt] = image;
}
if (subdived)
if (subdived) {
subdivMeshIds.push_back(meshId);
else
if (xMirroredMeshId)
subdivMeshIds.push_back(xMirroredMeshId);
if (zMirroredMeshId)
subdivMeshIds.push_back(zMirroredMeshId);
} else {
meshIds.push_back(meshId);
if (xMirroredMeshId)
meshIds.push_back(xMirroredMeshId);
if (zMirroredMeshId)
meshIds.push_back(zMirroredMeshId);
}
}

if (!subdivMeshIds.empty()) {
Expand Down Expand Up @@ -307,8 +295,11 @@ void MeshGenerator::process()
QImage *image = new QImage(m_previewRender->toImage(QSize(Theme::previewImageSize, Theme::previewImageSize)));
m_preview = image;
}
int trimedMeshId = meshlite_trim(meshliteContext, mergedMeshId, 1);
m_mesh = new Mesh(meshliteContext, trimedMeshId, broken);
int finalMeshId = mergedMeshId;
if (!originSettled) {
finalMeshId = meshlite_trim(meshliteContext, mergedMeshId, 1);
}
m_mesh = new Mesh(meshliteContext, finalMeshId, broken);
}

if (m_previewRender) {
Expand Down
2 changes: 1 addition & 1 deletion src/meshgenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public slots:
std::map<QString, ModelOfflineRender *> m_partPreviewRenderMap;
QThread *m_thread;
private:
void resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile);
void resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile, const QString &partId=QString());
static bool enableDebug;
};

Expand Down
94 changes: 91 additions & 3 deletions src/skeletondocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@
unsigned long SkeletonDocument::m_maxSnapshot = 1000;

SkeletonDocument::SkeletonDocument() :
// public
originX(0),
originY(0),
originZ(0),
editMode(SkeletonDocumentEditMode::Select),
// private
m_resultMeshIsObsolete(false),
m_resultMesh(nullptr),
m_meshGenerator(nullptr),
m_batchChangeRefCount(0),
editMode(SkeletonDocumentEditMode::Select)
m_resultMesh(nullptr),
m_batchChangeRefCount(0)
{
}

Expand Down Expand Up @@ -285,6 +290,11 @@ const SkeletonEdge *SkeletonDocument::findEdgeByNodes(QUuid firstNodeId, QUuid s
return nullptr;
}

bool SkeletonDocument::originSettled() const
{
return originX > 0 && originY > 0 && originZ > 0;
}

void SkeletonDocument::addEdge(QUuid fromNodeId, QUuid toNodeId)
{
if (findEdgeByNodes(fromNodeId, toNodeId)) {
Expand Down Expand Up @@ -431,6 +441,15 @@ void SkeletonDocument::moveNodeBy(QUuid nodeId, float x, float y, float z)
emit skeletonChanged();
}

void SkeletonDocument::moveOriginBy(float x, float y, float z)
{
originX += x;
originY += y;
originZ += z;
emit originChanged();
emit skeletonChanged();
}

void SkeletonDocument::setNodeOrigin(QUuid nodeId, float x, float y, float z)
{
auto it = nodeMap.find(nodeId);
Expand Down Expand Up @@ -552,6 +571,8 @@ void SkeletonDocument::toSnapshot(SkeletonSnapshot *snapshot, const std::set<QUu
part["locked"] = partIt.second.locked ? "true" : "false";
part["subdived"] = partIt.second.subdived ? "true" : "false";
part["disabled"] = partIt.second.disabled ? "true" : "false";
part["xMirrored"] = partIt.second.xMirrored ? "true" : "false";
part["zMirrored"] = partIt.second.zMirrored ? "true" : "false";
if (!partIt.second.name.isEmpty())
part["name"] = partIt.second.name;
snapshot->parts[part["id"]] = part;
Expand Down Expand Up @@ -591,10 +612,26 @@ void SkeletonDocument::toSnapshot(SkeletonSnapshot *snapshot, const std::set<QUu
continue;
snapshot->partIdList.push_back(partIdIt.toString());
}
std::map<QString, QString> canvas;
canvas["originX"] = QString::number(originX);
canvas["originY"] = QString::number(originY);
canvas["originZ"] = QString::number(originZ);
snapshot->canvas = canvas;
}

void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
{
const auto &originXit = snapshot.canvas.find("originX");
const auto &originYit = snapshot.canvas.find("originY");
const auto &originZit = snapshot.canvas.find("originZ");
if (originXit != snapshot.canvas.end() &&
originYit != snapshot.canvas.end() &&
originZit != snapshot.canvas.end()) {
originX = originXit->second.toFloat();
originY = originYit->second.toFloat();
originZ = originZit->second.toFloat();
}

std::map<QUuid, QUuid> oldNewIdMap;
for (const auto &partKv : snapshot.parts) {
SkeletonPart part;
Expand All @@ -604,6 +641,8 @@ void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
part.locked = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "locked"));
part.subdived = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "subdived"));
part.disabled = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "disabled"));
part.xMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "xMirrored"));
part.zMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "zMirrored"));
partMap[part.id] = part;
}
for (const auto &nodeKv : snapshot.nodes) {
Expand Down Expand Up @@ -664,11 +703,15 @@ void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
}

emit partListChanged();
emit originChanged();
emit skeletonChanged();
}

void SkeletonDocument::reset()
{
originX = 0;
originY = 0;
originZ = 0;
nodeMap.clear();
edgeMap.clear();
partMap.clear();
Expand Down Expand Up @@ -824,6 +867,51 @@ void SkeletonDocument::setPartDisableState(QUuid partId, bool disabled)
emit skeletonChanged();
}

void SkeletonDocument::settleOrigin()
{
if (originSettled())
return;
SkeletonSnapshot snapshot;
toSnapshot(&snapshot);
QRectF mainProfile;
QRectF sideProfile;
snapshot.resolveBoundingBox(&mainProfile, &sideProfile);
originX = mainProfile.x() + mainProfile.width() / 2;
originY = mainProfile.y() + mainProfile.height() / 2;
originZ = sideProfile.x() + sideProfile.width() / 2;
emit originChanged();
}

void SkeletonDocument::setPartXmirrorState(QUuid partId, bool mirrored)
{
auto part = partMap.find(partId);
if (part == partMap.end()) {
qDebug() << "Part not found:" << partId;
return;
}
if (part->second.xMirrored == mirrored)
return;
part->second.xMirrored = mirrored;
settleOrigin();
emit partXmirrorStateChanged(partId);
emit skeletonChanged();
}

void SkeletonDocument::setPartZmirrorState(QUuid partId, bool mirrored)
{
auto part = partMap.find(partId);
if (part == partMap.end()) {
qDebug() << "Part not found:" << partId;
return;
}
if (part->second.zMirrored == mirrored)
return;
part->second.zMirrored = mirrored;
settleOrigin();
emit partZmirrorStateChanged(partId);
emit skeletonChanged();
}

void SkeletonDocument::saveSnapshot()
{
if (m_undoItems.size() + 1 > m_maxSnapshot)
Expand Down

0 comments on commit 44a8ca6

Please sign in to comment.