Fix deform
parent
ce41e654fb
commit
f1b219333f
|
@ -1,2 +1,3 @@
|
|||
moc_*
|
||||
.DS_Store
|
||||
*.o
|
||||
|
|
|
@ -125,9 +125,12 @@ void MeshGenerator::process()
|
|||
int bmeshId = meshlite_bmesh_create(meshliteContext);
|
||||
if (subdived)
|
||||
meshlite_bmesh_set_cut_subdiv_count(meshliteContext, bmeshId, 1);
|
||||
QString thicknessString = valueOfKeyInMapOrEmpty(part->second, "thickness");
|
||||
QString thicknessString = valueOfKeyInMapOrEmpty(part->second, "deformThickness");
|
||||
if (!thicknessString.isEmpty())
|
||||
meshlite_bmesh_set_thickness(meshliteContext, bmeshId, thicknessString.toFloat());
|
||||
meshlite_bmesh_set_deform_thickness(meshliteContext, bmeshId, thicknessString.toFloat());
|
||||
QString widthString = valueOfKeyInMapOrEmpty(part->second, "deformWidth");
|
||||
if (!widthString.isEmpty())
|
||||
meshlite_bmesh_set_deform_width(meshliteContext, bmeshId, widthString.toFloat());
|
||||
if (MeshGenerator::enableDebug)
|
||||
meshlite_bmesh_enable_debug(meshliteContext, bmeshId, 1);
|
||||
partBmeshMap[partIdIt] = bmeshId;
|
||||
|
|
|
@ -585,8 +585,10 @@ void SkeletonDocument::toSnapshot(SkeletonSnapshot *snapshot, const std::set<QUu
|
|||
part["disabled"] = partIt.second.disabled ? "true" : "false";
|
||||
part["xMirrored"] = partIt.second.xMirrored ? "true" : "false";
|
||||
part["zMirrored"] = partIt.second.zMirrored ? "true" : "false";
|
||||
if (partIt.second.thicknessAdjusted())
|
||||
part["thickness"] = QString::number(partIt.second.thickness);
|
||||
if (partIt.second.deformThicknessAdjusted())
|
||||
part["deformThickness"] = QString::number(partIt.second.deformThickness);
|
||||
if (partIt.second.deformWidthAdjusted())
|
||||
part["deformWidth"] = QString::number(partIt.second.deformWidth);
|
||||
if (!partIt.second.name.isEmpty())
|
||||
part["name"] = partIt.second.name;
|
||||
snapshot->parts[part["id"]] = part;
|
||||
|
@ -657,9 +659,12 @@ void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
|
|||
part.disabled = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "disabled"));
|
||||
part.xMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "xMirrored"));
|
||||
part.zMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "zMirrored"));
|
||||
const auto &thicknessIt = partKv.second.find("thickness");
|
||||
if (thicknessIt != partKv.second.end())
|
||||
part.setThickness(thicknessIt->second.toFloat());
|
||||
const auto &deformThicknessIt = partKv.second.find("deformThickness");
|
||||
if (deformThicknessIt != partKv.second.end())
|
||||
part.setDeformThickness(deformThicknessIt->second.toFloat());
|
||||
const auto &deformWidthIt = partKv.second.find("deformWidth");
|
||||
if (deformWidthIt != partKv.second.end())
|
||||
part.setDeformWidth(deformWidthIt->second.toFloat());
|
||||
partMap[part.id] = part;
|
||||
}
|
||||
for (const auto &nodeKv : snapshot.nodes) {
|
||||
|
@ -929,15 +934,27 @@ void SkeletonDocument::setPartZmirrorState(QUuid partId, bool mirrored)
|
|||
emit skeletonChanged();
|
||||
}
|
||||
|
||||
void SkeletonDocument::setPartThickness(QUuid partId, float thickness)
|
||||
void SkeletonDocument::setPartDeformThickness(QUuid partId, float thickness)
|
||||
{
|
||||
auto part = partMap.find(partId);
|
||||
if (part == partMap.end()) {
|
||||
qDebug() << "Part not found:" << partId;
|
||||
return;
|
||||
}
|
||||
part->second.setThickness(thickness);
|
||||
emit partThicknessChanged(partId);
|
||||
part->second.setDeformThickness(thickness);
|
||||
emit partDeformThicknessChanged(partId);
|
||||
emit skeletonChanged();
|
||||
}
|
||||
|
||||
void SkeletonDocument::setPartDeformWidth(QUuid partId, float width)
|
||||
{
|
||||
auto part = partMap.find(partId);
|
||||
if (part == partMap.end()) {
|
||||
qDebug() << "Part not found:" << partId;
|
||||
return;
|
||||
}
|
||||
part->second.setDeformWidth(width);
|
||||
emit partDeformWidthChanged(partId);
|
||||
emit skeletonChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,8 @@ public:
|
|||
bool disabled;
|
||||
bool xMirrored;
|
||||
bool zMirrored;
|
||||
float thickness;
|
||||
float deformThickness;
|
||||
float deformWidth;
|
||||
QImage preview;
|
||||
std::vector<QUuid> nodeIds;
|
||||
SkeletonPart(const QUuid &withId=QUuid()) :
|
||||
|
@ -81,21 +82,38 @@ public:
|
|||
disabled(false),
|
||||
xMirrored(false),
|
||||
zMirrored(false),
|
||||
thickness(1.0)
|
||||
deformThickness(1.0),
|
||||
deformWidth(1.0)
|
||||
{
|
||||
id = withId.isNull() ? QUuid::createUuid() : withId;
|
||||
}
|
||||
void setThickness(float toThickness)
|
||||
void setDeformThickness(float toThickness)
|
||||
{
|
||||
if (toThickness < 0)
|
||||
toThickness = 0;
|
||||
else if (toThickness > 2)
|
||||
toThickness = 2;
|
||||
thickness = toThickness;
|
||||
deformThickness = toThickness;
|
||||
}
|
||||
bool thicknessAdjusted() const
|
||||
void setDeformWidth(float toWidth)
|
||||
{
|
||||
return fabs(thickness - 1.0) >= 0.01;
|
||||
if (toWidth < 0)
|
||||
toWidth = 0;
|
||||
else if (toWidth > 2)
|
||||
toWidth = 2;
|
||||
deformWidth = toWidth;
|
||||
}
|
||||
bool deformThicknessAdjusted() const
|
||||
{
|
||||
return fabs(deformThickness - 1.0) >= 0.01;
|
||||
}
|
||||
bool deformWidthAdjusted() const
|
||||
{
|
||||
return fabs(deformWidth - 1.0) >= 0.01;
|
||||
}
|
||||
bool deformAdjusted() const
|
||||
{
|
||||
return deformThicknessAdjusted() || deformWidthAdjusted();
|
||||
}
|
||||
bool isEditVisible() const
|
||||
{
|
||||
|
@ -109,7 +127,8 @@ public:
|
|||
disabled = other.disabled;
|
||||
xMirrored = other.xMirrored;
|
||||
zMirrored = other.zMirrored;
|
||||
thickness = other.thickness;
|
||||
deformThickness = other.deformThickness;
|
||||
deformWidth = other.deformWidth;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -161,7 +180,8 @@ signals:
|
|||
void partDisableStateChanged(QUuid partId);
|
||||
void partXmirrorStateChanged(QUuid partId);
|
||||
void partZmirrorStateChanged(QUuid partId);
|
||||
void partThicknessChanged(QUuid partId);
|
||||
void partDeformThicknessChanged(QUuid partId);
|
||||
void partDeformWidthChanged(QUuid partId);
|
||||
void cleanup();
|
||||
void originChanged();
|
||||
void xlockStateChanged();
|
||||
|
@ -220,7 +240,8 @@ public slots:
|
|||
void setPartDisableState(QUuid partId, bool disabled);
|
||||
void setPartXmirrorState(QUuid partId, bool mirrored);
|
||||
void setPartZmirrorState(QUuid partId, bool mirrored);
|
||||
void setPartThickness(QUuid partId, float thickness);
|
||||
void setPartDeformThickness(QUuid partId, float thickness);
|
||||
void setPartDeformWidth(QUuid partId, float width);
|
||||
void saveSnapshot();
|
||||
void undo();
|
||||
void redo();
|
||||
|
|
|
@ -422,7 +422,8 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
|
|||
connect(m_document, &SkeletonDocument::partSubdivStateChanged, partListWidget, &SkeletonPartListWidget::partSubdivStateChanged);
|
||||
connect(m_document, &SkeletonDocument::partDisableStateChanged, partListWidget, &SkeletonPartListWidget::partDisableStateChanged);
|
||||
connect(m_document, &SkeletonDocument::partXmirrorStateChanged, partListWidget, &SkeletonPartListWidget::partXmirrorStateChanged);
|
||||
connect(m_document, &SkeletonDocument::partThicknessChanged, partListWidget, &SkeletonPartListWidget::partThicknessChanged);
|
||||
connect(m_document, &SkeletonDocument::partDeformThicknessChanged, partListWidget, &SkeletonPartListWidget::partDeformChanged);
|
||||
connect(m_document, &SkeletonDocument::partDeformWidthChanged, partListWidget, &SkeletonPartListWidget::partDeformChanged);
|
||||
connect(m_document, &SkeletonDocument::cleanup, partListWidget, &SkeletonPartListWidget::partListChanged);
|
||||
|
||||
connect(m_document, &SkeletonDocument::skeletonChanged, m_document, &SkeletonDocument::generateMesh);
|
||||
|
|
|
@ -31,9 +31,9 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
|||
initButton(m_xMirrorButton);
|
||||
updateXmirrorButton();
|
||||
|
||||
m_thicknessButton = new QPushButton();
|
||||
initButton(m_thicknessButton);
|
||||
updateThicknessButton();
|
||||
m_deformButton = new QPushButton();
|
||||
initButton(m_deformButton);
|
||||
updateDeformButton();
|
||||
|
||||
m_previewLabel = new QLabel;
|
||||
|
||||
|
@ -49,8 +49,8 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
|||
miniBottomToolLayout->setSpacing(0);
|
||||
miniBottomToolLayout->setContentsMargins(0, 0, 0, 0);
|
||||
miniBottomToolLayout->addWidget(m_subdivButton);
|
||||
miniBottomToolLayout->addWidget(m_deformButton);
|
||||
miniBottomToolLayout->addWidget(m_xMirrorButton);
|
||||
miniBottomToolLayout->addWidget(m_thicknessButton);
|
||||
miniBottomToolLayout->addStretch();
|
||||
|
||||
QWidget *hrWidget = new QWidget;
|
||||
|
@ -74,7 +74,8 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
|||
connect(this, &SkeletonPartWidget::setPartSubdivState, m_document, &SkeletonDocument::setPartSubdivState);
|
||||
connect(this, &SkeletonPartWidget::setPartDisableState, m_document, &SkeletonDocument::setPartDisableState);
|
||||
connect(this, &SkeletonPartWidget::setPartXmirrorState, m_document, &SkeletonDocument::setPartXmirrorState);
|
||||
connect(this, &SkeletonPartWidget::setPartThickness, m_document, &SkeletonDocument::setPartThickness);
|
||||
connect(this, &SkeletonPartWidget::setPartDeformThickness, m_document, &SkeletonDocument::setPartDeformThickness);
|
||||
connect(this, &SkeletonPartWidget::setPartDeformWidth, m_document, &SkeletonDocument::setPartDeformWidth);
|
||||
|
||||
connect(m_lockButton, &QPushButton::clicked, [=]() {
|
||||
const SkeletonPart *part = m_document->findPart(m_partId);
|
||||
|
@ -121,17 +122,25 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
|||
emit setPartXmirrorState(m_partId, !part->xMirrored);
|
||||
});
|
||||
|
||||
connect(m_thicknessButton, &QPushButton::clicked, [=]() {
|
||||
connect(m_deformButton, &QPushButton::clicked, [=]() {
|
||||
const SkeletonPart *part = m_document->findPart(m_partId);
|
||||
if (!part) {
|
||||
qDebug() << "Part not found:" << m_partId;
|
||||
return;
|
||||
}
|
||||
showThicknessSettingPopup(mapFromGlobal(QCursor::pos()));
|
||||
showDeformSettingPopup(mapFromGlobal(QCursor::pos()));
|
||||
});
|
||||
}
|
||||
|
||||
void SkeletonPartWidget::showThicknessSettingPopup(const QPoint &pos)
|
||||
void SkeletonPartWidget::initToolButton(QPushButton *button)
|
||||
{
|
||||
button->setFont(Theme::awesome()->font(Theme::toolIconFontSize / 2));
|
||||
button->setFixedSize(Theme::toolIconSize / 2, Theme::toolIconSize / 2);
|
||||
button->setStyleSheet("QPushButton {color: #f7d9c8}");
|
||||
button->setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
void SkeletonPartWidget::showDeformSettingPopup(const QPoint &pos)
|
||||
{
|
||||
QMenu popupMenu;
|
||||
|
||||
|
@ -141,14 +150,50 @@ void SkeletonPartWidget::showThicknessSettingPopup(const QPoint &pos)
|
|||
return;
|
||||
}
|
||||
|
||||
FloatNumberWidget *popup = new FloatNumberWidget;
|
||||
popup->setRange(0, 2);
|
||||
popup->setValue(part->thickness);
|
||||
QWidget *popup = new QWidget;
|
||||
|
||||
connect(popup, &FloatNumberWidget::valueChanged, [=](float value) {
|
||||
emit setPartThickness(m_partId, value);
|
||||
FloatNumberWidget *thicknessWidget = new FloatNumberWidget;
|
||||
thicknessWidget->setRange(0, 2);
|
||||
thicknessWidget->setValue(part->deformThickness);
|
||||
|
||||
connect(thicknessWidget, &FloatNumberWidget::valueChanged, [=](float value) {
|
||||
emit setPartDeformThickness(m_partId, value);
|
||||
});
|
||||
|
||||
FloatNumberWidget *widthWidget = new FloatNumberWidget;
|
||||
widthWidget->setRange(0, 2);
|
||||
widthWidget->setValue(part->deformWidth);
|
||||
|
||||
connect(widthWidget, &FloatNumberWidget::valueChanged, [=](float value) {
|
||||
emit setPartDeformWidth(m_partId, value);
|
||||
});
|
||||
|
||||
QPushButton *thicknessEraser = new QPushButton(QChar(fa::eraser));
|
||||
initToolButton(thicknessEraser);
|
||||
|
||||
connect(thicknessEraser, &QPushButton::clicked, [=]() {
|
||||
thicknessWidget->setValue(1.0);
|
||||
});
|
||||
|
||||
QPushButton *widthEraser = new QPushButton(QChar(fa::eraser));
|
||||
initToolButton(widthEraser);
|
||||
|
||||
connect(widthEraser, &QPushButton::clicked, [=]() {
|
||||
widthWidget->setValue(1.0);
|
||||
});
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
QHBoxLayout *thicknessLayout = new QHBoxLayout;
|
||||
QHBoxLayout *widthLayout = new QHBoxLayout;
|
||||
thicknessLayout->addWidget(thicknessEraser);
|
||||
thicknessLayout->addWidget(thicknessWidget);
|
||||
widthLayout->addWidget(widthEraser);
|
||||
widthLayout->addWidget(widthWidget);
|
||||
layout->addLayout(thicknessLayout);
|
||||
layout->addLayout(widthLayout);
|
||||
|
||||
popup->setLayout(layout);
|
||||
|
||||
QWidgetAction *action = new QWidgetAction(this);
|
||||
action->setDefaultWidget(popup);
|
||||
|
||||
|
@ -248,17 +293,17 @@ void SkeletonPartWidget::updateXmirrorButton()
|
|||
updateButton(m_xMirrorButton, QChar(fa::balancescale), false);
|
||||
}
|
||||
|
||||
void SkeletonPartWidget::updateThicknessButton()
|
||||
void SkeletonPartWidget::updateDeformButton()
|
||||
{
|
||||
const SkeletonPart *part = m_document->findPart(m_partId);
|
||||
if (!part) {
|
||||
qDebug() << "Part not found:" << m_partId;
|
||||
return;
|
||||
}
|
||||
if (part->thicknessAdjusted())
|
||||
updateButton(m_thicknessButton, QChar(fa::handlizardo), true);
|
||||
if (part->deformAdjusted())
|
||||
updateButton(m_deformButton, QChar(fa::handlizardo), true);
|
||||
else
|
||||
updateButton(m_thicknessButton, QChar(fa::handlizardo), false);
|
||||
updateButton(m_deformButton, QChar(fa::handlizardo), false);
|
||||
}
|
||||
|
||||
void SkeletonPartWidget::reload()
|
||||
|
@ -269,7 +314,7 @@ void SkeletonPartWidget::reload()
|
|||
updateSubdivButton();
|
||||
updateDisableButton();
|
||||
updateXmirrorButton();
|
||||
updateThicknessButton();
|
||||
updateDeformButton();
|
||||
}
|
||||
|
||||
SkeletonPartListWidget::SkeletonPartListWidget(const SkeletonDocument *document) :
|
||||
|
@ -376,7 +421,7 @@ void SkeletonPartListWidget::partXmirrorStateChanged(QUuid partId)
|
|||
widget->updateXmirrorButton();
|
||||
}
|
||||
|
||||
void SkeletonPartListWidget::partThicknessChanged(QUuid partId)
|
||||
void SkeletonPartListWidget::partDeformChanged(QUuid partId)
|
||||
{
|
||||
auto item = m_itemMap.find(partId);
|
||||
if (item == m_itemMap.end()) {
|
||||
|
@ -384,5 +429,5 @@ void SkeletonPartListWidget::partThicknessChanged(QUuid partId)
|
|||
return;
|
||||
}
|
||||
SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second);
|
||||
widget->updateThicknessButton();
|
||||
widget->updateDeformButton();
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ signals:
|
|||
void setPartDisableState(QUuid partId, bool disabled);
|
||||
void setPartXmirrorState(QUuid partId, bool mirrored);
|
||||
void setPartZmirrorState(QUuid partId, bool mirrored);
|
||||
void setPartThickness(QUuid partId, float thickness);
|
||||
void setPartDeformThickness(QUuid partId, float thickness);
|
||||
void setPartDeformWidth(QUuid partId, float width);
|
||||
public:
|
||||
SkeletonPartWidget(const SkeletonDocument *document, QUuid partId);
|
||||
void reload();
|
||||
|
@ -27,9 +28,9 @@ public:
|
|||
void updateDisableButton();
|
||||
void updateXmirrorButton();
|
||||
void updateZmirrorButton();
|
||||
void updateThicknessButton();
|
||||
void updateDeformButton();
|
||||
public slots:
|
||||
void showThicknessSettingPopup(const QPoint &pos);
|
||||
void showDeformSettingPopup(const QPoint &pos);
|
||||
private:
|
||||
const SkeletonDocument *m_document;
|
||||
QUuid m_partId;
|
||||
|
@ -40,9 +41,10 @@ private:
|
|||
QPushButton *m_disableButton;
|
||||
QPushButton *m_xMirrorButton;
|
||||
QPushButton *m_zMirrorButton;
|
||||
QPushButton *m_thicknessButton;
|
||||
QPushButton *m_deformButton;
|
||||
QLabel *m_nameLabel;
|
||||
private:
|
||||
void initToolButton(QPushButton *button);
|
||||
void initButton(QPushButton *button);
|
||||
void updateButton(QPushButton *button, QChar icon, bool highlighted);
|
||||
};
|
||||
|
@ -61,7 +63,7 @@ public slots:
|
|||
void partSubdivStateChanged(QUuid partId);
|
||||
void partDisableStateChanged(QUuid partId);
|
||||
void partXmirrorStateChanged(QUuid partId);
|
||||
void partThicknessChanged(QUuid partId);
|
||||
void partDeformChanged(QUuid partId);
|
||||
private:
|
||||
const SkeletonDocument *m_document;
|
||||
std::map<QUuid, QListWidgetItem *> m_itemMap;
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -33,7 +33,8 @@ int meshlite_get_halfedge_normal_array(void *context, int mesh_id, float *buffer
|
|||
int meshlite_build(void *context, float *vertex_position_buffer, int vertex_count, int *face_index_buffer, int face_index_buffer_len);
|
||||
int meshlite_bmesh_create(void *context);
|
||||
int meshlite_bmesh_set_cut_subdiv_count(void *context, int bmesh_id, int subdiv_count);
|
||||
int meshlite_bmesh_set_thickness(void *context, int bmesh_id, float thickness);
|
||||
int meshlite_bmesh_set_deform_thickness(void *context, int bmesh_id, float thickness);
|
||||
int meshlite_bmesh_set_deform_width(void *context, int bmesh_id, float width);
|
||||
int meshlite_bmesh_enable_debug(void *context, int bmesh_id, int enable);
|
||||
int meshlite_bmesh_add_node(void *context, int bmesh_id, float x, float y, float z, float radius);
|
||||
int meshlite_bmesh_add_edge(void *context, int bmesh_id, int first_node_id, int second_node_id);
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -33,7 +33,8 @@ int meshlite_get_halfedge_normal_array(void *context, int mesh_id, float *buffer
|
|||
int meshlite_build(void *context, float *vertex_position_buffer, int vertex_count, int *face_index_buffer, int face_index_buffer_len);
|
||||
int meshlite_bmesh_create(void *context);
|
||||
int meshlite_bmesh_set_cut_subdiv_count(void *context, int bmesh_id, int subdiv_count);
|
||||
int meshlite_bmesh_set_thickness(void *context, int bmesh_id, float thickness);
|
||||
int meshlite_bmesh_set_deform_thickness(void *context, int bmesh_id, float thickness);
|
||||
int meshlite_bmesh_set_deform_width(void *context, int bmesh_id, float width);
|
||||
int meshlite_bmesh_enable_debug(void *context, int bmesh_id, int enable);
|
||||
int meshlite_bmesh_add_node(void *context, int bmesh_id, float x, float y, float z, float radius);
|
||||
int meshlite_bmesh_add_edge(void *context, int bmesh_id, int first_node_id, int second_node_id);
|
||||
|
|
Loading…
Reference in New Issue