Add remesh polycount configure

master
Jeremy Hu 2020-01-05 00:20:10 +09:30
parent 8c6a9fef29
commit 66ac0b3b7f
13 changed files with 176 additions and 46 deletions

View File

@ -372,6 +372,9 @@ HEADERS += src/posedocument.h
SOURCES += src/combinemode.cpp
HEADERS += src/combinemode.h
SOURCES += src/polycount.cpp
HEADERS += src/polycount.h
SOURCES += src/cutdocument.cpp
HEADERS += src/cutdocument.h

View File

@ -738,7 +738,11 @@ Tips:
</message>
<message>
<source>Remeshed</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Poly</source>
<translation></translation>
</message>
</context>
<context>
@ -1046,6 +1050,22 @@ Tips:
<source>Fall to Death</source>
<translation></translation>
</message>
<message>
<source>Low Poly</source>
<translation></translation>
</message>
<message>
<source>Original</source>
<translation></translation>
</message>
<message>
<source>High Poly</source>
<translation></translation>
</message>
<message>
<source>Extreme High Poly</source>
<translation></translation>
</message>
</context>
<context>
<name>RigWidget</name>

View File

@ -36,7 +36,7 @@ Document::Document() :
textureAmbientOcclusionImage(nullptr),
rigType(RigType::None),
weldEnabled(true),
remeshed(false),
polyCount(PolyCount::Original),
// private
m_isResultMeshObsolete(false),
m_meshGenerator(nullptr),
@ -1199,8 +1199,8 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set<QUuid> &limitNodeId
component["smoothAll"] = QString::number(componentIt.second.smoothAll);
if (componentIt.second.smoothSeamAdjusted())
component["smoothSeam"] = QString::number(componentIt.second.smoothSeam);
if (componentIt.second.remeshed)
component["remeshed"] = "true";
if (componentIt.second.polyCount != PolyCount::Original)
component["polyCount"] = PolyCountToString(componentIt.second.polyCount);
QStringList childIdList;
for (const auto &childId: componentIt.second.childrenIds) {
childIdList.append(childId.toString());
@ -1315,8 +1315,8 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set<QUuid> &limitNodeId
canvas["originY"] = QString::number(getOriginY());
canvas["originZ"] = QString::number(getOriginZ());
canvas["rigType"] = RigTypeToString(rigType);
if (this->remeshed)
canvas["remeshed"] = "true";
if (this->polyCount != PolyCount::Original)
canvas["polyCount"] = PolyCountToString(this->polyCount);
snapshot->canvas = canvas;
}
}
@ -1474,7 +1474,7 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
bool isOriginChanged = false;
bool isRigTypeChanged = false;
if (!fromPaste) {
this->remeshed = isTrueValueString(valueOfKeyInMapOrEmpty(snapshot.canvas, "remeshed"));
this->polyCount = PolyCountFromString(valueOfKeyInMapOrEmpty(snapshot.canvas, "polyCount").toUtf8().constData());
const auto &originXit = snapshot.canvas.find("originX");
const auto &originYit = snapshot.canvas.find("originY");
const auto &originZit = snapshot.canvas.find("originZ");
@ -1707,7 +1707,7 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
const auto &smoothSeamIt = componentKv.second.find("smoothSeam");
if (smoothSeamIt != componentKv.second.end())
component.setSmoothSeam(smoothSeamIt->second.toFloat());
component.remeshed = isTrueValueString(valueOfKeyInMapOrEmpty(componentKv.second, "remeshed"));
component.polyCount = PolyCountFromString(valueOfKeyInMapOrEmpty(componentKv.second, "polyCount").toUtf8().constData());
//qDebug() << "Add component:" << component.id << " old:" << componentKv.first << "name:" << component.name;
if ("partId" == linkDataType) {
QUuid partId = oldNewIdMap[QUuid(linkData)];
@ -2474,13 +2474,13 @@ void Document::setComponentExpandState(QUuid componentId, bool expanded)
emit optionsChanged();
}
void Document::setComponentRemeshState(QUuid componentId, bool remeshed)
void Document::setComponentPolyCount(QUuid componentId, PolyCount count)
{
if (componentId.isNull()) {
if (this->remeshed == remeshed)
if (polyCount == count)
return;
this->remeshed = remeshed;
emit componentRemeshStateChanged(componentId);
polyCount = count;
emit componentPolyCountChanged(componentId);
emit skeletonChanged();
return;
}
@ -2488,12 +2488,12 @@ void Document::setComponentRemeshState(QUuid componentId, bool remeshed)
Component *component = (Component *)findComponent(componentId);
if (nullptr == component)
return;
if (component->remeshed == remeshed)
if (component->polyCount == count)
return;
component->remeshed = remeshed;
component->polyCount = count;
component->dirty = true;
emit componentRemeshStateChanged(componentId);
emit componentPolyCountChanged(componentId);
emit skeletonChanged();
}

View File

@ -26,6 +26,7 @@
#include "jointnodetree.h"
#include "skeletondocument.h"
#include "combinemode.h"
#include "polycount.h"
#include "preferences.h"
#include "paintmode.h"
#include "proceduralanimation.h"
@ -65,7 +66,7 @@ public:
bool dirty = true;
float smoothAll = 0.0;
float smoothSeam = 0.0;
bool remeshed = false;
PolyCount polyCount = PolyCount::Original;
std::vector<QUuid> childrenIds;
QString linkData() const
{
@ -394,7 +395,7 @@ signals:
void componentExpandStateChanged(QUuid componentId);
void componentSmoothAllChanged(QUuid componentId);
void componentSmoothSeamChanged(QUuid componentId);
void componentRemeshStateChanged(QUuid componentId);
void componentPolyCountChanged(QUuid componentId);
void nodeRemoved(QUuid nodeId);
void edgeRemoved(QUuid edgeId);
void nodeRadiusChanged(QUuid nodeId);
@ -497,7 +498,7 @@ public: // need initialize
QImage *textureAmbientOcclusionImage;
RigType rigType;
bool weldEnabled;
bool remeshed;
PolyCount polyCount;
public:
Document();
~Document();
@ -640,7 +641,7 @@ public slots:
void setComponentExpandState(QUuid componentId, bool expanded);
void setComponentSmoothAll(QUuid componentId, float toSmoothAll);
void setComponentSmoothSeam(QUuid componentId, float toSmoothSeam);
void setComponentRemeshState(QUuid componentId, bool remeshed);
void setComponentPolyCount(QUuid componentId, PolyCount count);
void hideOtherComponents(QUuid componentId);
void lockOtherComponents(QUuid componentId);
void hideAllComponents();

View File

@ -990,7 +990,7 @@ DocumentWindow::DocumentWindow() :
connect(partTreeWidget, &PartTreeWidget::setComponentExpandState, m_document, &Document::setComponentExpandState);
connect(partTreeWidget, &PartTreeWidget::setComponentSmoothAll, m_document, &Document::setComponentSmoothAll);
connect(partTreeWidget, &PartTreeWidget::setComponentSmoothSeam, m_document, &Document::setComponentSmoothSeam);
connect(partTreeWidget, &PartTreeWidget::setComponentRemeshState, m_document, &Document::setComponentRemeshState);
connect(partTreeWidget, &PartTreeWidget::setComponentPolyCount, m_document, &Document::setComponentPolyCount);
connect(partTreeWidget, &PartTreeWidget::moveComponent, m_document, &Document::moveComponent);
connect(partTreeWidget, &PartTreeWidget::removeComponent, m_document, &Document::removeComponent);
connect(partTreeWidget, &PartTreeWidget::hideOtherComponents, m_document, &Document::hideOtherComponents);

View File

@ -17,6 +17,7 @@
#include "gridmeshbuilder.h"
#include "triangulatefaces.h"
#include "remesher.h"
#include "polycount.h"
MeshGenerator::MeshGenerator(Snapshot *snapshot) :
m_snapshot(snapshot)
@ -843,11 +844,14 @@ CombineMode MeshGenerator::componentCombineMode(const std::map<QString, QString>
return combineMode;
}
bool MeshGenerator::componentRemeshed(const std::map<QString, QString> *component)
bool MeshGenerator::componentRemeshed(const std::map<QString, QString> *component, float *polyCountValue)
{
if (nullptr == component)
return false;
return isTrueValueString(valueOfKeyInMapOrEmpty(*component, "remeshed"));
auto polyCount = PolyCountFromString(valueOfKeyInMapOrEmpty(*component, "polyCount").toUtf8().constData());
if (nullptr != polyCountValue)
*polyCountValue = PolyCountToValue(polyCount);
return polyCount != PolyCount::Original;
}
QString MeshGenerator::componentColorName(const std::map<QString, QString> *component)
@ -1032,7 +1036,8 @@ MeshCombiner::Mesh *MeshGenerator::combineComponentMesh(const QString &component
}
if (nullptr != mesh) {
bool remeshed = componentId.isNull() ? componentRemeshed(&m_snapshot->canvas) : componentRemeshed(component);
float polyCountValue = 1.0f;
bool remeshed = componentId.isNull() ? componentRemeshed(&m_snapshot->canvas, &polyCountValue) : componentRemeshed(component, &polyCountValue);
if (remeshed) {
std::vector<QVector3D> combinedVertices;
std::vector<std::vector<size_t>> combinedFaces;
@ -1043,6 +1048,7 @@ MeshCombiner::Mesh *MeshGenerator::combineComponentMesh(const QString &component
remesh(componentCache.outcomeNodes,
combinedVertices,
combinedFaces,
polyCountValue,
&newVertices,
&newQuads,
&newTriangles,
@ -1460,6 +1466,7 @@ void MeshGenerator::generate()
void MeshGenerator::remesh(const std::vector<OutcomeNode> &inputNodes,
const std::vector<QVector3D> &inputVertices,
const std::vector<std::vector<size_t>> &inputFaces,
float targetVertexMultiplyFactor,
std::vector<QVector3D> *outputVertices,
std::vector<std::vector<size_t>> *outputQuads,
std::vector<std::vector<size_t>> *outputTriangles,
@ -1476,7 +1483,7 @@ void MeshGenerator::remesh(const std::vector<OutcomeNode> &inputNodes,
Remesher remesher;
remesher.setMesh(inputVertices, inputFaces);
remesher.setNodes(nodes, sourceIds);
remesher.remesh();
remesher.remesh(targetVertexMultiplyFactor);
*outputVertices = remesher.getRemeshedVertices();
const auto &remeshedFaces = remesher.getRemeshedFaces();
*outputQuads = remeshedFaces;

View File

@ -120,7 +120,7 @@ private:
std::vector<std::vector<QVector3D>> *triangleVertexNormals);
const std::map<QString, QString> *findComponent(const QString &componentIdString);
CombineMode componentCombineMode(const std::map<QString, QString> *component);
bool componentRemeshed(const std::map<QString, QString> *component);
bool componentRemeshed(const std::map<QString, QString> *component, float *polyCountValue=nullptr);
MeshCombiner::Mesh *combineComponentChildGroupMesh(const std::vector<QString> &componentIdStrings,
GeneratedComponent &componentCache);
MeshCombiner::Mesh *combineMultipleMeshes(const std::vector<std::tuple<MeshCombiner::Mesh *, CombineMode, QString>> &multipleMeshes, bool recombine=true);
@ -130,6 +130,7 @@ private:
void remesh(const std::vector<OutcomeNode> &inputNodes,
const std::vector<QVector3D> &inputVertices,
const std::vector<std::vector<size_t>> &inputFaces,
float targetVertexMultiplyFactor,
std::vector<QVector3D> *outputVertices,
std::vector<std::vector<size_t>> *outputQuads,
std::vector<std::vector<size_t>> *outputTriangles,

View File

@ -11,7 +11,6 @@
#include <QClipboard>
#include <QMimeData>
#include <QApplication>
#include <QCheckBox>
#include "parttreewidget.h"
#include "partwidget.h"
#include "skeletongraphicswidget.h"
@ -289,24 +288,30 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
}
layout->addWidget(previewLabel);
}
QCheckBox *remeshBox = nullptr;
QComboBox *polyCountSelectBox = nullptr;
if (componentIds.size() <= 1) {
remeshBox = new QCheckBox();
remeshBox->setText(tr("Remeshed"));
polyCountSelectBox = new QComboBox;
if (nullptr == component) {
if (m_document->remeshed)
remeshBox->setChecked(true);
connect(remeshBox, &QCheckBox::stateChanged, this, [=]() {
emit setComponentRemeshState(QUuid(), remeshBox->isChecked());
for (size_t i = 0; i < (size_t)PolyCount::Count; ++i) {
PolyCount count = (PolyCount)i;
polyCountSelectBox->addItem(PolyCountToDispName(count));
}
polyCountSelectBox->setCurrentIndex((int)m_document->polyCount);
connect(polyCountSelectBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int index) {
emit setComponentPolyCount(QUuid(), (PolyCount)index);
emit groupOperationAdded();
});
} else {
if (component->remeshed)
remeshBox->setChecked(true);
connect(remeshBox, &QCheckBox::stateChanged, this, [=]() {
emit setComponentRemeshState(component->id, remeshBox->isChecked());
for (size_t i = 0; i < (size_t)PolyCount::Count; ++i) {
PolyCount count = (PolyCount)i;
polyCountSelectBox->addItem(PolyCountToDispName(count));
}
polyCountSelectBox->setCurrentIndex((int)component->polyCount);
connect(polyCountSelectBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int index) {
emit setComponentPolyCount(component->id, (PolyCount)index);
emit groupOperationAdded();
});
}
Theme::initCheckbox(remeshBox);
}
QWidget *widget = new QWidget;
if (nullptr != component) {
@ -318,6 +323,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
combineModeSelectBox->setCurrentIndex((int)component->combineMode);
connect(combineModeSelectBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int index) {
emit setComponentCombineMode(component->id, (CombineMode)index);
emit groupOperationAdded();
});
QComboBox *partTargetSelectBox = nullptr;
@ -330,6 +336,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
partTargetSelectBox->setCurrentIndex((int)part->target);
connect(partTargetSelectBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int index) {
emit setPartTarget(part->id, (PartTarget)index);
emit groupOperationAdded();
});
}
@ -343,6 +350,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
partBaseSelectBox->setCurrentIndex((int)part->base);
connect(partBaseSelectBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int index) {
emit setPartBase(part->id, (PartBase)index);
emit groupOperationAdded();
});
}
@ -353,6 +361,8 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
//combineModeLayout->addWidget(combineModeSelectBox);
QFormLayout *componentSettingsLayout = new QFormLayout;
if (nullptr != polyCountSelectBox)
componentSettingsLayout->addRow(tr("Poly"), polyCountSelectBox);
if (nullptr != partBaseSelectBox)
componentSettingsLayout->addRow(tr("Base"), partBaseSelectBox);
if (nullptr != partTargetSelectBox)
@ -361,15 +371,16 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
QVBoxLayout *newLayout = new QVBoxLayout;
newLayout->addLayout(layout);
if (nullptr != remeshBox)
newLayout->addWidget(remeshBox);
newLayout->addLayout(componentSettingsLayout);
widget->setLayout(newLayout);
} else {
QFormLayout *componentSettingsLayout = new QFormLayout;
if (nullptr != polyCountSelectBox)
componentSettingsLayout->addRow(tr("Poly"), polyCountSelectBox);
QVBoxLayout *newLayout = new QVBoxLayout;
newLayout->addLayout(layout);
if (nullptr != remeshBox)
newLayout->addWidget(remeshBox);
newLayout->addLayout(componentSettingsLayout);
widget->setLayout(newLayout);
}
forDisplayPartImage.setDefaultWidget(widget);

View File

@ -22,7 +22,7 @@ signals:
void setComponentExpandState(QUuid componentId, bool expanded);
void setComponentSmoothAll(QUuid componentId, float toSmoothAll);
void setComponentSmoothSeam(QUuid componentId, float toSmoothSeam);
void setComponentRemeshState(QUuid componentId, bool remeshed);
void setComponentPolyCount(QUuid componentId, PolyCount count);
void setPartTarget(QUuid partId, PartTarget target);
void setPartBase(QUuid partId, PartBase base);
void moveComponent(QUuid componentId, QUuid toParentId);

7
src/polycount.cpp Normal file
View File

@ -0,0 +1,7 @@
#include <QObject>
#include "polycount.h"
IMPL_PolyCountToString
IMPL_PolyCountFromString
IMPL_PolyCountToDispName
IMPL_PolyCountToValue

80
src/polycount.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef DUST3D_POLY_COUNT_H
#define DUST3D_POLY_COUNT_H
#include <QString>
enum class PolyCount
{
LowPoly,
Original,
HighPoly,
ExtremeHighPoly,
Count
};
PolyCount PolyCountFromString(const char *countString);
#define IMPL_PolyCountFromString \
PolyCount PolyCountFromString(const char *countString) \
{ \
QString count = countString; \
if (count == "LowPoly") \
return PolyCount::LowPoly; \
if (count == "Original") \
return PolyCount::Original; \
if (count == "HighPoly") \
return PolyCount::HighPoly; \
if (count == "ExtremeHighPoly") \
return PolyCount::ExtremeHighPoly; \
return PolyCount::Original; \
}
const char *PolyCountToString(PolyCount count);
#define IMPL_PolyCountToString \
const char *PolyCountToString(PolyCount count) \
{ \
switch (count) { \
case PolyCount::LowPoly: \
return "LowPoly"; \
case PolyCount::Original: \
return "Original"; \
case PolyCount::HighPoly: \
return "HighPoly"; \
case PolyCount::ExtremeHighPoly: \
return "ExtremeHighPoly"; \
default: \
return "Original"; \
} \
}
QString PolyCountToDispName(PolyCount count);
#define IMPL_PolyCountToDispName \
QString PolyCountToDispName(PolyCount count) \
{ \
switch (count) { \
case PolyCount::LowPoly: \
return QObject::tr("Low Poly"); \
case PolyCount::Original: \
return QObject::tr("Original"); \
case PolyCount::HighPoly: \
return QObject::tr("High Poly"); \
case PolyCount::ExtremeHighPoly: \
return QObject::tr("Extreme High Poly"); \
default: \
return QObject::tr("Original"); \
} \
}
float PolyCountToValue(PolyCount count);
#define IMPL_PolyCountToValue \
float PolyCountToValue(PolyCount count) \
{ \
switch (count) { \
case PolyCount::LowPoly: \
return 0.6f; \
case PolyCount::Original: \
return 1.0f; \
case PolyCount::HighPoly: \
return 1.2f; \
case PolyCount::ExtremeHighPoly: \
return 1.8f; \
default: \
return 1.0f; \
} \
}
#endif

View File

@ -32,7 +32,7 @@ const std::vector<std::pair<QUuid, QUuid>> &Remesher::getRemeshedVertexSources()
return m_remeshedVertexSources;
}
void Remesher::remesh()
void Remesher::remesh(float targetVertexMultiplyFactor)
{
std::vector<Dust3D_InstantMeshesVertex> inputVertices(m_vertices.size());
for (size_t i = 0; i < m_vertices.size(); ++i) {
@ -61,7 +61,7 @@ void Remesher::remesh()
size_t nResultQuads = 0;
Dust3D_instantMeshesRemesh(inputVertices.data(), inputVertices.size(),
inputTriangles.data(), inputTriangles.size(),
(size_t)(inputVertices.size() * 1.0f),
(size_t)(inputVertices.size() * targetVertexMultiplyFactor),
&resultVertices,
&nResultVertices,
&resultTriangles,

View File

@ -15,7 +15,7 @@ public:
const std::vector<std::vector<size_t>> &triangles);
void setNodes(const std::vector<std::pair<QVector3D, float>> &nodes,
const std::vector<std::pair<QUuid, QUuid>> &sourceIds);
void remesh();
void remesh(float targetVertexMultiplyFactor);
const std::vector<QVector3D> &getRemeshedVertices() const;
const std::vector<std::vector<size_t>> &getRemeshedFaces() const;
const std::vector<std::pair<QUuid, QUuid>> &getRemeshedVertexSources() const;