Add wrap button to enable use controlled convex hull generation for part.
This feature could be useful to generate complex mesh as part.master
parent
6bab154cf5
commit
df9c8e8e3c
|
@ -66,6 +66,8 @@ Keyboard
|
||||||
+----------------------+--------------------------------------------------------------------------+
|
+----------------------+--------------------------------------------------------------------------+
|
||||||
| U | Toggle Part End Roundable |
|
| U | Toggle Part End Roundable |
|
||||||
+----------------------+--------------------------------------------------------------------------+
|
+----------------------+--------------------------------------------------------------------------+
|
||||||
|
| W | Toggle Part Wrap Status: (W)rap using Convex hull/Normal |
|
||||||
|
+----------------------+--------------------------------------------------------------------------+
|
||||||
| TAB | Swith the Selected Nodes to Different Profile (Main / Side) |
|
| TAB | Swith the Selected Nodes to Different Profile (Main / Side) |
|
||||||
+----------------------+--------------------------------------------------------------------------+
|
+----------------------+--------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,7 @@ void *MeshGenerator::combinePartMesh(QString partId)
|
||||||
bool isDisabled = isTrueValueString(valueOfKeyInMapOrEmpty(part, "disabled"));
|
bool isDisabled = isTrueValueString(valueOfKeyInMapOrEmpty(part, "disabled"));
|
||||||
bool xMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(part, "xMirrored"));
|
bool xMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(part, "xMirrored"));
|
||||||
bool subdived = isTrueValueString(valueOfKeyInMapOrEmpty(part, "subdived"));
|
bool subdived = isTrueValueString(valueOfKeyInMapOrEmpty(part, "subdived"));
|
||||||
|
bool wrapped = isTrueValueString(valueOfKeyInMapOrEmpty(part, "wrapped"));
|
||||||
int bmeshId = meshlite_bmesh_create(m_meshliteContext);
|
int bmeshId = meshlite_bmesh_create(m_meshliteContext);
|
||||||
if (subdived)
|
if (subdived)
|
||||||
meshlite_bmesh_set_cut_subdiv_count(m_meshliteContext, bmeshId, 1);
|
meshlite_bmesh_set_cut_subdiv_count(m_meshliteContext, bmeshId, 1);
|
||||||
|
@ -288,14 +289,21 @@ void *MeshGenerator::combinePartMesh(QString partId)
|
||||||
if (!bmeshToNodeIdMap.empty()) {
|
if (!bmeshToNodeIdMap.empty()) {
|
||||||
meshId = meshlite_bmesh_generate_mesh(m_meshliteContext, bmeshId);
|
meshId = meshlite_bmesh_generate_mesh(m_meshliteContext, bmeshId);
|
||||||
loadVertexSources(m_meshliteContext, meshId, partIdNotAsString, bmeshToNodeIdMap, cacheBmeshVertices);
|
loadVertexSources(m_meshliteContext, meshId, partIdNotAsString, bmeshToNodeIdMap, cacheBmeshVertices);
|
||||||
resultMesh = convertToCombinableMesh(m_meshliteContext, meshlite_triangulate(m_meshliteContext, meshId));
|
if (wrapped)
|
||||||
|
resultMesh = convertToCombinableConvexHullMesh(m_meshliteContext, meshId);
|
||||||
|
else
|
||||||
|
resultMesh = convertToCombinableMesh(m_meshliteContext, meshlite_triangulate(m_meshliteContext, meshId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr != resultMesh) {
|
if (nullptr != resultMesh) {
|
||||||
if (xMirrored) {
|
if (xMirrored) {
|
||||||
int xMirroredMeshId = meshlite_mirror_in_x(m_meshliteContext, meshId, 0);
|
int xMirroredMeshId = meshlite_mirror_in_x(m_meshliteContext, meshId, 0);
|
||||||
loadVertexSources(m_meshliteContext, xMirroredMeshId, mirroredPartIdNotAsString, bmeshToNodeIdMap, cacheBmeshVertices);
|
loadVertexSources(m_meshliteContext, xMirroredMeshId, mirroredPartIdNotAsString, bmeshToNodeIdMap, cacheBmeshVertices);
|
||||||
void *mirroredMesh = convertToCombinableMesh(m_meshliteContext, meshlite_triangulate(m_meshliteContext, xMirroredMeshId));
|
void *mirroredMesh = nullptr;
|
||||||
|
if (wrapped)
|
||||||
|
mirroredMesh = convertToCombinableConvexHullMesh(m_meshliteContext, xMirroredMeshId);
|
||||||
|
else
|
||||||
|
mirroredMesh = convertToCombinableMesh(m_meshliteContext, meshlite_triangulate(m_meshliteContext, xMirroredMeshId));
|
||||||
if (nullptr != mirroredMesh) {
|
if (nullptr != mirroredMesh) {
|
||||||
void *newResultMesh = unionCombinableMeshs(resultMesh, mirroredMesh);
|
void *newResultMesh = unionCombinableMeshs(resultMesh, mirroredMesh);
|
||||||
deleteCombinableMesh(mirroredMesh);
|
deleteCombinableMesh(mirroredMesh);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <CGAL/Polygon_mesh_processing/remesh.h>
|
#include <CGAL/Polygon_mesh_processing/remesh.h>
|
||||||
#include <CGAL/subdivision_method_3.h>
|
#include <CGAL/subdivision_method_3.h>
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
#include <CGAL/convex_hull_3.h>
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_exact_constructions_kernel ExactKernel;
|
typedef CGAL::Exact_predicates_exact_constructions_kernel ExactKernel;
|
||||||
typedef CGAL::Simple_cartesian<double> SimpleKernel;
|
typedef CGAL::Simple_cartesian<double> SimpleKernel;
|
||||||
|
@ -132,6 +133,34 @@ int makeMeshliteMeshFromCgal(void *meshlite, typename CGAL::Surface_mesh<typenam
|
||||||
return meshId;
|
return meshId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Kernel>
|
||||||
|
ExactMesh *makeCgalConvexHullMeshFromMeshlite(void *meshlite, int meshId)
|
||||||
|
{
|
||||||
|
typename CGAL::Surface_mesh<typename Kernel::Point_3> *mesh = new typename CGAL::Surface_mesh<typename Kernel::Point_3>;
|
||||||
|
int vertexCount = meshlite_get_vertex_count(meshlite, meshId);
|
||||||
|
float *vertexPositions = new float[vertexCount * 3];
|
||||||
|
int vertexArrayLen = meshlite_get_vertex_position_array(meshlite, meshId, vertexPositions, vertexCount * 3);
|
||||||
|
int offset = 0;
|
||||||
|
assert(vertexArrayLen == vertexCount * 3);
|
||||||
|
std::vector<typename Kernel::Point_3> points;
|
||||||
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
|
float x = vertexPositions[offset + 0];
|
||||||
|
float y = vertexPositions[offset + 1];
|
||||||
|
float z = vertexPositions[offset + 2];
|
||||||
|
if (std::isnan(x) || std::isinf(x))
|
||||||
|
x = 0;
|
||||||
|
if (std::isnan(y) || std::isinf(y))
|
||||||
|
y = 0;
|
||||||
|
if (std::isnan(z) || std::isinf(z))
|
||||||
|
z = 0;
|
||||||
|
points.push_back(typename Kernel::Point_3(x, y, z));
|
||||||
|
offset += 3;
|
||||||
|
}
|
||||||
|
delete[] vertexPositions;
|
||||||
|
CGAL::convex_hull_3(points.begin(), points.end(), *mesh);
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
ExactMesh *unionCgalMeshs(ExactMesh *first, ExactMesh *second)
|
ExactMesh *unionCgalMeshs(ExactMesh *first, ExactMesh *second)
|
||||||
{
|
{
|
||||||
ExactMesh *mesh = new ExactMesh;
|
ExactMesh *mesh = new ExactMesh;
|
||||||
|
@ -315,3 +344,8 @@ void *cloneCombinableMesh(void *mesh)
|
||||||
return (void *)new ExactMesh(*(ExactMesh *)mesh);
|
return (void *)new ExactMesh(*(ExactMesh *)mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *convertToCombinableConvexHullMesh(void *meshliteContext, int meshId)
|
||||||
|
{
|
||||||
|
ExactMesh *mesh = makeCgalConvexHullMeshFromMeshlite<ExactKernel>(meshliteContext, meshId);
|
||||||
|
return (void *)mesh;
|
||||||
|
}
|
||||||
|
|
|
@ -15,5 +15,6 @@ void *diffCombinableMeshs(void *first, void *second);
|
||||||
int convertFromCombinableMesh(void *meshliteContext, void *mesh);
|
int convertFromCombinableMesh(void *meshliteContext, void *mesh);
|
||||||
void deleteCombinableMesh(void *mesh);
|
void deleteCombinableMesh(void *mesh);
|
||||||
void *cloneCombinableMesh(void *mesh);
|
void *cloneCombinableMesh(void *mesh);
|
||||||
|
void *convertToCombinableConvexHullMesh(void *meshliteContext, int meshId);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -661,6 +661,7 @@ void SkeletonDocument::toSnapshot(SkeletonSnapshot *snapshot, const std::set<QUu
|
||||||
part["xMirrored"] = partIt.second.xMirrored ? "true" : "false";
|
part["xMirrored"] = partIt.second.xMirrored ? "true" : "false";
|
||||||
part["zMirrored"] = partIt.second.zMirrored ? "true" : "false";
|
part["zMirrored"] = partIt.second.zMirrored ? "true" : "false";
|
||||||
part["rounded"] = partIt.second.rounded ? "true" : "false";
|
part["rounded"] = partIt.second.rounded ? "true" : "false";
|
||||||
|
part["wrapped"] = partIt.second.wrapped ? "true" : "false";
|
||||||
part["dirty"] = partIt.second.dirty ? "true" : "false";
|
part["dirty"] = partIt.second.dirty ? "true" : "false";
|
||||||
if (partIt.second.hasColor)
|
if (partIt.second.hasColor)
|
||||||
part["color"] = partIt.second.color.name();
|
part["color"] = partIt.second.color.name();
|
||||||
|
@ -777,6 +778,7 @@ void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
|
||||||
part.xMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "xMirrored"));
|
part.xMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "xMirrored"));
|
||||||
part.zMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "zMirrored"));
|
part.zMirrored = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "zMirrored"));
|
||||||
part.rounded = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "rounded"));
|
part.rounded = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "rounded"));
|
||||||
|
part.wrapped = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "wrapped"));
|
||||||
if (isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "inverse")))
|
if (isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "inverse")))
|
||||||
inversePartIds.insert(part.id);
|
inversePartIds.insert(part.id);
|
||||||
const auto &colorIt = partKv.second.find("color");
|
const auto &colorIt = partKv.second.find("color");
|
||||||
|
@ -1733,6 +1735,21 @@ void SkeletonDocument::setPartRoundState(QUuid partId, bool rounded)
|
||||||
emit skeletonChanged();
|
emit skeletonChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonDocument::setPartWrapState(QUuid partId, bool wrapped)
|
||||||
|
{
|
||||||
|
auto part = partMap.find(partId);
|
||||||
|
if (part == partMap.end()) {
|
||||||
|
qDebug() << "Part not found:" << partId;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (part->second.wrapped == wrapped)
|
||||||
|
return;
|
||||||
|
part->second.wrapped = wrapped;
|
||||||
|
part->second.dirty = true;
|
||||||
|
emit partWrapStateChanged(partId);
|
||||||
|
emit skeletonChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void SkeletonDocument::setPartColorState(QUuid partId, bool hasColor, QColor color)
|
void SkeletonDocument::setPartColorState(QUuid partId, bool hasColor, QColor color)
|
||||||
{
|
{
|
||||||
auto part = partMap.find(partId);
|
auto part = partMap.find(partId);
|
||||||
|
|
|
@ -87,6 +87,7 @@ public:
|
||||||
QUuid componentId;
|
QUuid componentId;
|
||||||
std::vector<QUuid> nodeIds;
|
std::vector<QUuid> nodeIds;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
|
bool wrapped;
|
||||||
SkeletonPart(const QUuid &withId=QUuid()) :
|
SkeletonPart(const QUuid &withId=QUuid()) :
|
||||||
visible(true),
|
visible(true),
|
||||||
locked(false),
|
locked(false),
|
||||||
|
@ -99,7 +100,8 @@ public:
|
||||||
rounded(false),
|
rounded(false),
|
||||||
color(Theme::white),
|
color(Theme::white),
|
||||||
hasColor(false),
|
hasColor(false),
|
||||||
dirty(true)
|
dirty(true),
|
||||||
|
wrapped(false)
|
||||||
{
|
{
|
||||||
id = withId.isNull() ? QUuid::createUuid() : withId;
|
id = withId.isNull() ? QUuid::createUuid() : withId;
|
||||||
}
|
}
|
||||||
|
@ -148,6 +150,7 @@ public:
|
||||||
rounded = other.rounded;
|
rounded = other.rounded;
|
||||||
color = other.color;
|
color = other.color;
|
||||||
hasColor = other.hasColor;
|
hasColor = other.hasColor;
|
||||||
|
wrapped = other.wrapped;
|
||||||
componentId = other.componentId;
|
componentId = other.componentId;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -328,6 +331,7 @@ signals:
|
||||||
void partDeformWidthChanged(QUuid partId);
|
void partDeformWidthChanged(QUuid partId);
|
||||||
void partRoundStateChanged(QUuid partId);
|
void partRoundStateChanged(QUuid partId);
|
||||||
void partColorStateChanged(QUuid partId);
|
void partColorStateChanged(QUuid partId);
|
||||||
|
void partWrapStateChanged(QUuid partId);
|
||||||
void componentInverseStateChanged(QUuid partId);
|
void componentInverseStateChanged(QUuid partId);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void originChanged();
|
void originChanged();
|
||||||
|
@ -425,6 +429,7 @@ public slots:
|
||||||
void setPartDeformWidth(QUuid partId, float width);
|
void setPartDeformWidth(QUuid partId, float width);
|
||||||
void setPartRoundState(QUuid partId, bool rounded);
|
void setPartRoundState(QUuid partId, bool rounded);
|
||||||
void setPartColorState(QUuid partId, bool hasColor, QColor color);
|
void setPartColorState(QUuid partId, bool hasColor, QColor color);
|
||||||
|
void setPartWrapState(QUuid partId, bool wrapped);
|
||||||
void setComponentInverseState(QUuid componentId, bool inverse);
|
void setComponentInverseState(QUuid componentId, bool inverse);
|
||||||
void moveComponentUp(QUuid componentId);
|
void moveComponentUp(QUuid componentId);
|
||||||
void moveComponentDown(QUuid componentId);
|
void moveComponentDown(QUuid componentId);
|
||||||
|
|
|
@ -547,6 +547,7 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
|
||||||
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartDisableState, m_document, &SkeletonDocument::setPartDisableState);
|
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartDisableState, m_document, &SkeletonDocument::setPartDisableState);
|
||||||
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartXmirrorState, m_document, &SkeletonDocument::setPartXmirrorState);
|
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartXmirrorState, m_document, &SkeletonDocument::setPartXmirrorState);
|
||||||
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartRoundState, m_document, &SkeletonDocument::setPartRoundState);
|
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartRoundState, m_document, &SkeletonDocument::setPartRoundState);
|
||||||
|
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartWrapState, m_document, &SkeletonDocument::setPartWrapState);
|
||||||
|
|
||||||
connect(graphicsWidget, &SkeletonGraphicsWidget::setXlockState, m_document, &SkeletonDocument::setXlockState);
|
connect(graphicsWidget, &SkeletonGraphicsWidget::setXlockState, m_document, &SkeletonDocument::setXlockState);
|
||||||
connect(graphicsWidget, &SkeletonGraphicsWidget::setYlockState, m_document, &SkeletonDocument::setYlockState);
|
connect(graphicsWidget, &SkeletonGraphicsWidget::setYlockState, m_document, &SkeletonDocument::setYlockState);
|
||||||
|
@ -614,6 +615,7 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
|
||||||
connect(m_document, &SkeletonDocument::partDeformThicknessChanged, partTreeWidget, &SkeletonPartTreeWidget::partDeformChanged);
|
connect(m_document, &SkeletonDocument::partDeformThicknessChanged, partTreeWidget, &SkeletonPartTreeWidget::partDeformChanged);
|
||||||
connect(m_document, &SkeletonDocument::partDeformWidthChanged, partTreeWidget, &SkeletonPartTreeWidget::partDeformChanged);
|
connect(m_document, &SkeletonDocument::partDeformWidthChanged, partTreeWidget, &SkeletonPartTreeWidget::partDeformChanged);
|
||||||
connect(m_document, &SkeletonDocument::partRoundStateChanged, partTreeWidget, &SkeletonPartTreeWidget::partRoundStateChanged);
|
connect(m_document, &SkeletonDocument::partRoundStateChanged, partTreeWidget, &SkeletonPartTreeWidget::partRoundStateChanged);
|
||||||
|
connect(m_document, &SkeletonDocument::partWrapStateChanged, partTreeWidget, &SkeletonPartTreeWidget::partWrapStateChanged);
|
||||||
connect(m_document, &SkeletonDocument::partColorStateChanged, partTreeWidget, &SkeletonPartTreeWidget::partColorStateChanged);
|
connect(m_document, &SkeletonDocument::partColorStateChanged, partTreeWidget, &SkeletonPartTreeWidget::partColorStateChanged);
|
||||||
connect(m_document, &SkeletonDocument::partRemoved, partTreeWidget, &SkeletonPartTreeWidget::partRemoved);
|
connect(m_document, &SkeletonDocument::partRemoved, partTreeWidget, &SkeletonPartTreeWidget::partRemoved);
|
||||||
connect(m_document, &SkeletonDocument::cleanup, partTreeWidget, &SkeletonPartTreeWidget::removeAllContent);
|
connect(m_document, &SkeletonDocument::cleanup, partTreeWidget, &SkeletonPartTreeWidget::removeAllContent);
|
||||||
|
|
|
@ -1502,6 +1502,14 @@ bool SkeletonGraphicsWidget::keyPress(QKeyEvent *event)
|
||||||
emit groupOperationAdded();
|
emit groupOperationAdded();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else if (event->key() == Qt::Key_W) {
|
||||||
|
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
|
||||||
|
const SkeletonPart *part = m_document->findPart(m_lastCheckedPart);
|
||||||
|
bool partWrapped = part && part->wrapped;
|
||||||
|
emit setPartWrapState(m_lastCheckedPart, !partWrapped);
|
||||||
|
emit groupOperationAdded();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,6 +379,7 @@ signals:
|
||||||
void setPartDisableState(QUuid partId, bool disabled);
|
void setPartDisableState(QUuid partId, bool disabled);
|
||||||
void setPartXmirrorState(QUuid partId, bool mirrored);
|
void setPartXmirrorState(QUuid partId, bool mirrored);
|
||||||
void setPartRoundState(QUuid partId, bool rounded);
|
void setPartRoundState(QUuid partId, bool rounded);
|
||||||
|
void setPartWrapState(QUuid partId, bool wrapped);
|
||||||
void setXlockState(bool locked);
|
void setXlockState(bool locked);
|
||||||
void setYlockState(bool locked);
|
void setYlockState(bool locked);
|
||||||
void setZlockState(bool locked);
|
void setZlockState(bool locked);
|
||||||
|
|
|
@ -561,6 +561,17 @@ void SkeletonPartTreeWidget::partRoundStateChanged(QUuid partId)
|
||||||
widget->updateRoundButton();
|
widget->updateRoundButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonPartTreeWidget::partWrapStateChanged(QUuid partId)
|
||||||
|
{
|
||||||
|
auto item = m_partItemMap.find(partId);
|
||||||
|
if (item == m_partItemMap.end()) {
|
||||||
|
qDebug() << "Part item not found:" << partId;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second, 0);
|
||||||
|
widget->updateWrapButton();
|
||||||
|
}
|
||||||
|
|
||||||
void SkeletonPartTreeWidget::partColorStateChanged(QUuid partId)
|
void SkeletonPartTreeWidget::partColorStateChanged(QUuid partId)
|
||||||
{
|
{
|
||||||
auto item = m_partItemMap.find(partId);
|
auto item = m_partItemMap.find(partId);
|
||||||
|
|
|
@ -53,6 +53,7 @@ public slots:
|
||||||
void partXmirrorStateChanged(QUuid partId);
|
void partXmirrorStateChanged(QUuid partId);
|
||||||
void partDeformChanged(QUuid partId);
|
void partDeformChanged(QUuid partId);
|
||||||
void partRoundStateChanged(QUuid partId);
|
void partRoundStateChanged(QUuid partId);
|
||||||
|
void partWrapStateChanged(QUuid partId);
|
||||||
void partColorStateChanged(QUuid partId);
|
void partColorStateChanged(QUuid partId);
|
||||||
void partChecked(QUuid partId);
|
void partChecked(QUuid partId);
|
||||||
void partUnchecked(QUuid partId);
|
void partUnchecked(QUuid partId);
|
||||||
|
|
|
@ -48,6 +48,10 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
||||||
m_colorButton->setSizePolicy(retainSizePolicy);
|
m_colorButton->setSizePolicy(retainSizePolicy);
|
||||||
initButton(m_colorButton);
|
initButton(m_colorButton);
|
||||||
|
|
||||||
|
m_wrapButton = new QPushButton;
|
||||||
|
m_wrapButton->setSizePolicy(retainSizePolicy);
|
||||||
|
initButton(m_wrapButton);
|
||||||
|
|
||||||
m_previewLabel = new QLabel;
|
m_previewLabel = new QLabel;
|
||||||
m_previewLabel->setFixedSize(Theme::previewImageSize, Theme::previewImageSize);
|
m_previewLabel->setFixedSize(Theme::previewImageSize, Theme::previewImageSize);
|
||||||
|
|
||||||
|
@ -68,9 +72,9 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
||||||
toolsLayout->setContentsMargins(0, 0, 5, 0);
|
toolsLayout->setContentsMargins(0, 0, 5, 0);
|
||||||
int row = 0;
|
int row = 0;
|
||||||
int col = 0;
|
int col = 0;
|
||||||
toolsLayout->addWidget(m_visibleButton, row, col++, Qt::AlignBottom);
|
|
||||||
toolsLayout->addWidget(m_lockButton, row, col++, Qt::AlignBottom);
|
toolsLayout->addWidget(m_lockButton, row, col++, Qt::AlignBottom);
|
||||||
toolsLayout->addWidget(m_disableButton, row, col++, Qt::AlignBottom);
|
toolsLayout->addWidget(m_disableButton, row, col++, Qt::AlignBottom);
|
||||||
|
toolsLayout->addWidget(m_wrapButton, row, col++, Qt::AlignBottom);
|
||||||
toolsLayout->addWidget(m_colorButton, row, col++, Qt::AlignBottom);
|
toolsLayout->addWidget(m_colorButton, row, col++, Qt::AlignBottom);
|
||||||
row++;
|
row++;
|
||||||
col = 0;
|
col = 0;
|
||||||
|
@ -79,17 +83,21 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
||||||
toolsLayout->addWidget(m_xMirrorButton, row, col++, Qt::AlignTop);
|
toolsLayout->addWidget(m_xMirrorButton, row, col++, Qt::AlignTop);
|
||||||
toolsLayout->addWidget(m_roundButton, row, col++, Qt::AlignTop);
|
toolsLayout->addWidget(m_roundButton, row, col++, Qt::AlignTop);
|
||||||
|
|
||||||
|
m_visibleButton->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
QHBoxLayout *previewAndToolsLayout = new QHBoxLayout;
|
QHBoxLayout *previewAndToolsLayout = new QHBoxLayout;
|
||||||
previewAndToolsLayout->setSpacing(0);
|
previewAndToolsLayout->setSpacing(0);
|
||||||
previewAndToolsLayout->setContentsMargins(0, 0, 0, 0);
|
previewAndToolsLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
previewAndToolsLayout->addWidget(m_visibleButton);
|
||||||
previewAndToolsLayout->addWidget(m_previewLabel);
|
previewAndToolsLayout->addWidget(m_previewLabel);
|
||||||
previewAndToolsLayout->addLayout(toolsLayout);
|
previewAndToolsLayout->addLayout(toolsLayout);
|
||||||
previewAndToolsLayout->setStretch(0, 0);
|
previewAndToolsLayout->setStretch(0, 0);
|
||||||
previewAndToolsLayout->setStretch(1, 0);
|
previewAndToolsLayout->setStretch(1, 0);
|
||||||
|
previewAndToolsLayout->setStretch(2, 1);
|
||||||
|
|
||||||
QWidget *backgroundWidget = new QWidget;
|
QWidget *backgroundWidget = new QWidget;
|
||||||
backgroundWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
backgroundWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
backgroundWidget->setFixedSize(Theme::previewImageSize + Theme::miniIconSize * 4 + 5, Theme::previewImageSize);
|
backgroundWidget->setFixedSize(preferredSize().width(), Theme::previewImageSize);
|
||||||
backgroundWidget->setObjectName("background");
|
backgroundWidget->setObjectName("background");
|
||||||
m_backgroundWidget = backgroundWidget;
|
m_backgroundWidget = backgroundWidget;
|
||||||
backgroundWidget->setLayout(previewAndToolsLayout);
|
backgroundWidget->setLayout(previewAndToolsLayout);
|
||||||
|
@ -119,6 +127,7 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
||||||
connect(this, &SkeletonPartWidget::setPartDeformThickness, m_document, &SkeletonDocument::setPartDeformThickness);
|
connect(this, &SkeletonPartWidget::setPartDeformThickness, m_document, &SkeletonDocument::setPartDeformThickness);
|
||||||
connect(this, &SkeletonPartWidget::setPartDeformWidth, m_document, &SkeletonDocument::setPartDeformWidth);
|
connect(this, &SkeletonPartWidget::setPartDeformWidth, m_document, &SkeletonDocument::setPartDeformWidth);
|
||||||
connect(this, &SkeletonPartWidget::setPartRoundState, m_document, &SkeletonDocument::setPartRoundState);
|
connect(this, &SkeletonPartWidget::setPartRoundState, m_document, &SkeletonDocument::setPartRoundState);
|
||||||
|
connect(this, &SkeletonPartWidget::setPartWrapState, m_document, &SkeletonDocument::setPartWrapState);
|
||||||
connect(this, &SkeletonPartWidget::setPartColorState, m_document, &SkeletonDocument::setPartColorState);
|
connect(this, &SkeletonPartWidget::setPartColorState, m_document, &SkeletonDocument::setPartColorState);
|
||||||
connect(this, &SkeletonPartWidget::checkPart, m_document, &SkeletonDocument::checkPart);
|
connect(this, &SkeletonPartWidget::checkPart, m_document, &SkeletonDocument::checkPart);
|
||||||
connect(this, &SkeletonPartWidget::enableBackgroundBlur, m_document, &SkeletonDocument::enableBackgroundBlur);
|
connect(this, &SkeletonPartWidget::enableBackgroundBlur, m_document, &SkeletonDocument::enableBackgroundBlur);
|
||||||
|
@ -202,6 +211,16 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
||||||
showColorSettingPopup(mapFromGlobal(QCursor::pos()));
|
showColorSettingPopup(mapFromGlobal(QCursor::pos()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(m_wrapButton, &QPushButton::clicked, [=]() {
|
||||||
|
const SkeletonPart *part = m_document->findPart(m_partId);
|
||||||
|
if (!part) {
|
||||||
|
qDebug() << "Part not found:" << m_partId;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit setPartWrapState(m_partId, !part->wrapped);
|
||||||
|
emit groupOperationAdded();
|
||||||
|
});
|
||||||
|
|
||||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
setFixedSize(preferredSize());
|
setFixedSize(preferredSize());
|
||||||
|
|
||||||
|
@ -210,7 +229,7 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
|
||||||
|
|
||||||
QSize SkeletonPartWidget::preferredSize()
|
QSize SkeletonPartWidget::preferredSize()
|
||||||
{
|
{
|
||||||
return QSize(Theme::previewImageSize + Theme::miniIconSize * 4 + 5 + 2, Theme::previewImageSize + 6);
|
return QSize(Theme::miniIconSize + Theme::previewImageSize + Theme::miniIconSize * 4 + 5 + 2, Theme::previewImageSize + 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonPartWidget::updateAllButtons()
|
void SkeletonPartWidget::updateAllButtons()
|
||||||
|
@ -223,6 +242,7 @@ void SkeletonPartWidget::updateAllButtons()
|
||||||
updateDeformButton();
|
updateDeformButton();
|
||||||
updateRoundButton();
|
updateRoundButton();
|
||||||
updateColorButton();
|
updateColorButton();
|
||||||
|
updateWrapButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonPartWidget::updateCheckedState(bool checked)
|
void SkeletonPartWidget::updateCheckedState(bool checked)
|
||||||
|
@ -505,15 +525,21 @@ void SkeletonPartWidget::updateColorButton()
|
||||||
updateButton(m_colorButton, QChar(fa::eyedropper), false);
|
updateButton(m_colorButton, QChar(fa::eyedropper), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonPartWidget::updateWrapButton()
|
||||||
|
{
|
||||||
|
const SkeletonPart *part = m_document->findPart(m_partId);
|
||||||
|
if (!part) {
|
||||||
|
qDebug() << "Part not found:" << m_partId;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (part->wrapped)
|
||||||
|
updateButton(m_wrapButton, QChar(fa::cube), true);
|
||||||
|
else
|
||||||
|
updateButton(m_wrapButton, QChar(fa::cube), false);
|
||||||
|
}
|
||||||
|
|
||||||
void SkeletonPartWidget::reload()
|
void SkeletonPartWidget::reload()
|
||||||
{
|
{
|
||||||
updatePreview();
|
updatePreview();
|
||||||
updateLockButton();
|
updateAllButtons();
|
||||||
updateVisibleButton();
|
|
||||||
updateSubdivButton();
|
|
||||||
updateDisableButton();
|
|
||||||
updateXmirrorButton();
|
|
||||||
updateDeformButton();
|
|
||||||
updateRoundButton();
|
|
||||||
updateColorButton();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ signals:
|
||||||
void setPartDeformWidth(QUuid partId, float width);
|
void setPartDeformWidth(QUuid partId, float width);
|
||||||
void setPartRoundState(QUuid partId, bool rounded);
|
void setPartRoundState(QUuid partId, bool rounded);
|
||||||
void setPartColorState(QUuid partId, bool hasColor, QColor color);
|
void setPartColorState(QUuid partId, bool hasColor, QColor color);
|
||||||
void setPartInverseState(QUuid partId, bool inverse);
|
void setPartWrapState(QUuid partId, bool wrapped);
|
||||||
void movePartUp(QUuid partId);
|
void movePartUp(QUuid partId);
|
||||||
void movePartDown(QUuid partId);
|
void movePartDown(QUuid partId);
|
||||||
void movePartToTop(QUuid partId);
|
void movePartToTop(QUuid partId);
|
||||||
|
@ -41,6 +41,7 @@ public:
|
||||||
void updateDeformButton();
|
void updateDeformButton();
|
||||||
void updateRoundButton();
|
void updateRoundButton();
|
||||||
void updateColorButton();
|
void updateColorButton();
|
||||||
|
void updateWrapButton();
|
||||||
void updateCheckedState(bool checked);
|
void updateCheckedState(bool checked);
|
||||||
static QSize preferredSize();
|
static QSize preferredSize();
|
||||||
protected:
|
protected:
|
||||||
|
@ -62,6 +63,7 @@ private:
|
||||||
QPushButton *m_deformButton;
|
QPushButton *m_deformButton;
|
||||||
QPushButton *m_roundButton;
|
QPushButton *m_roundButton;
|
||||||
QPushButton *m_colorButton;
|
QPushButton *m_colorButton;
|
||||||
|
QPushButton *m_wrapButton;
|
||||||
QLabel *m_nameLabel;
|
QLabel *m_nameLabel;
|
||||||
QWidget *m_backgroundWidget;
|
QWidget *m_backgroundWidget;
|
||||||
private:
|
private:
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue