Divide document elements to separate file

master
Jeremy HU 2022-11-16 19:58:19 +11:00
parent 6335742b17
commit 0f77ed243d
10 changed files with 664 additions and 446 deletions

View File

@ -121,6 +121,11 @@ HEADERS += sources/debug.h
SOURCES += sources/debug.cc SOURCES += sources/debug.cc
HEADERS += sources/document.h HEADERS += sources/document.h
SOURCES += sources/document.cc SOURCES += sources/document.cc
SOURCES += sources/document_bone.cc
SOURCES += sources/document_component.cc
SOURCES += sources/document_edge.cc
SOURCES += sources/document_node.cc
SOURCES += sources/document_part.cc
HEADERS += sources/document_saver.h HEADERS += sources/document_saver.h
SOURCES += sources/document_saver.cc SOURCES += sources/document_saver.cc
HEADERS += sources/document_window.h HEADERS += sources/document_window.h

View File

@ -20,20 +20,6 @@
unsigned long Document::m_maxSnapshot = 1000; unsigned long Document::m_maxSnapshot = 1000;
Document::Bone::Bone(const dust3d::Uuid& withId)
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
void Document::Node::setRadius(float toRadius)
{
if (toRadius < MeshGenerator::m_minimalRadius)
toRadius = MeshGenerator::m_minimalRadius;
else if (toRadius > 1)
toRadius = 1;
radius = toRadius;
}
Document::Document() Document::Document()
{ {
} }

View File

@ -57,84 +57,21 @@ public:
class Node { class Node {
public: public:
Node(const dust3d::Uuid& withId = dust3d::Uuid()) Node(const dust3d::Uuid& withId = dust3d::Uuid());
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
void setRadius(float toRadius); void setRadius(float toRadius);
void setCutRotation(float toRotation) void setCutRotation(float toRotation);
{ void setCutFace(dust3d::CutFace face);
if (toRotation < -1) void setCutFaceLinkedId(const dust3d::Uuid& linkedId);
toRotation = -1; void clearCutFaceSettings();
else if (toRotation > 1) float getX(bool rotated = false) const;
toRotation = 1; float getY(bool rotated = false) const;
cutRotation = toRotation; float getZ(bool rotated = false) const;
hasCutFaceSettings = true; void setX(float x);
} void setY(float y);
void setCutFace(dust3d::CutFace face) void setZ(float z);
{ void addX(float x);
cutFace = face; void addY(float y);
cutFaceLinkedId = dust3d::Uuid(); void addZ(float z);
hasCutFaceSettings = true;
}
void setCutFaceLinkedId(const dust3d::Uuid& linkedId)
{
if (linkedId.isNull()) {
clearCutFaceSettings();
return;
}
cutFace = dust3d::CutFace::UserDefined;
cutFaceLinkedId = linkedId;
hasCutFaceSettings = true;
}
void clearCutFaceSettings()
{
cutFace = dust3d::CutFace::Quad;
cutFaceLinkedId = dust3d::Uuid();
cutRotation = 0;
hasCutFaceSettings = false;
}
float getX(bool rotated = false) const
{
if (rotated)
return m_y;
return m_x;
}
float getY(bool rotated = false) const
{
if (rotated)
return m_x;
return m_y;
}
float getZ(bool rotated = false) const
{
(void)rotated;
return m_z;
}
void setX(float x)
{
m_x = x;
}
void setY(float y)
{
m_y = y;
}
void setZ(float z)
{
m_z = z;
}
void addX(float x)
{
m_x += x;
}
void addY(float y)
{
m_y += y;
}
void addZ(float z)
{
m_z += z;
}
dust3d::Uuid id; dust3d::Uuid id;
dust3d::Uuid partId; dust3d::Uuid partId;
QString name; QString name;
@ -155,20 +92,12 @@ public:
class Edge { class Edge {
public: public:
Edge(const dust3d::Uuid& withId = dust3d::Uuid()) Edge(const dust3d::Uuid& withId = dust3d::Uuid());
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
dust3d::Uuid id; dust3d::Uuid id;
dust3d::Uuid partId; dust3d::Uuid partId;
QString name; QString name;
std::vector<dust3d::Uuid> nodeIds; std::vector<dust3d::Uuid> nodeIds;
dust3d::Uuid neighborOf(dust3d::Uuid nodeId) const dust3d::Uuid neighborOf(dust3d::Uuid nodeId) const;
{
if (nodeIds.size() != 2)
return dust3d::Uuid();
return nodeIds[0] == nodeId ? nodeIds[1] : nodeIds[0];
}
}; };
class Part { class Part {
@ -201,201 +130,39 @@ public:
bool countershaded; bool countershaded;
bool smooth; bool smooth;
dust3d::Uuid colorImageId; dust3d::Uuid colorImageId;
Part(const dust3d::Uuid& withId = dust3d::Uuid()) Part(const dust3d::Uuid& withId = dust3d::Uuid());
: visible(true) bool hasPolyFunction() const;
, locked(false) bool hasSmoothFunction() const;
, subdived(false) bool hasSubdivFunction() const;
, disabled(false) bool hasRoundEndFunction() const;
, xMirrored(false) bool hasMirrorFunction() const;
, deformThickness(1.0) bool hasChamferFunction() const;
, deformWidth(1.0) bool hasRotationFunction() const;
, deformUnified(false) bool hasHollowFunction() const;
, rounded(false) bool hasCutFaceFunction() const;
, chamfered(false) bool hasLayerFunction() const;
, color(Qt::white) bool hasTargetFunction() const;
, hasColor(false) bool hasBaseFunction() const;
, dirty(true) bool hasCombineModeFunction() const;
, cutRotation(0.0) bool hasDeformFunction() const;
, cutFace(dust3d::CutFace::Quad) bool hasColorFunction() const;
, target(dust3d::PartTarget::Model) void setDeformThickness(float toThickness);
, colorSolubility(0.0) void setDeformWidth(float toWidth);
, metalness(0.0) void setCutRotation(float toRotation);
, roughness(1.0) void setCutFace(dust3d::CutFace face);
, hollowThickness(0.0) void setCutFaceLinkedId(const dust3d::Uuid& linkedId);
, countershaded(false) bool deformThicknessAdjusted() const;
, smooth(false) bool deformWidthAdjusted() const;
{ bool deformAdjusted() const;
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; bool colorSolubilityAdjusted() const;
} bool metalnessAdjusted() const;
bool hasPolyFunction() const bool roughnessAdjusted() const;
{ bool cutRotationAdjusted() const;
return dust3d::PartTarget::Model == target; bool hollowThicknessAdjusted() const;
} bool cutFaceAdjusted() const;
bool hasSmoothFunction() const bool cutAdjusted() const;
{ bool isEditVisible() const;
return dust3d::PartTarget::Model == target; void copyAttributes(const Part& other);
}
bool hasSubdivFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasRoundEndFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasMirrorFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasChamferFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasRotationFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasHollowFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasCutFaceFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasLayerFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasTargetFunction() const
{
return true;
}
bool hasBaseFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasCombineModeFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasDeformFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasColorFunction() const
{
return dust3d::PartTarget::Model == target;
}
void setDeformThickness(float toThickness)
{
if (toThickness < 0)
toThickness = 0;
else if (toThickness > 2)
toThickness = 2;
deformThickness = toThickness;
}
void setDeformWidth(float toWidth)
{
if (toWidth < 0)
toWidth = 0;
else if (toWidth > 2)
toWidth = 2;
deformWidth = toWidth;
}
void setCutRotation(float toRotation)
{
if (toRotation < -1)
toRotation = -1;
else if (toRotation > 1)
toRotation = 1;
cutRotation = toRotation;
}
void setCutFace(dust3d::CutFace face)
{
cutFace = face;
cutFaceLinkedId = dust3d::Uuid();
}
void setCutFaceLinkedId(const dust3d::Uuid& linkedId)
{
if (linkedId.isNull()) {
setCutFace(dust3d::CutFace::Quad);
return;
}
cutFace = dust3d::CutFace::UserDefined;
cutFaceLinkedId = linkedId;
}
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() || deformUnified;
}
bool colorSolubilityAdjusted() const
{
return fabs(colorSolubility - 0.0) >= 0.01;
}
bool metalnessAdjusted() const
{
return fabs(metalness - 0.0) >= 0.01;
}
bool roughnessAdjusted() const
{
return fabs(roughness - 1.0) >= 0.01;
}
bool cutRotationAdjusted() const
{
return fabs(cutRotation - 0.0) >= 0.01;
}
bool hollowThicknessAdjusted() const
{
return fabs(hollowThickness - 0.0) >= 0.01;
}
bool cutFaceAdjusted() const
{
return cutFace != dust3d::CutFace::Quad;
}
bool cutAdjusted() const
{
return cutRotationAdjusted() || cutFaceAdjusted() || hollowThicknessAdjusted();
}
bool isEditVisible() const
{
return visible && !disabled;
}
void copyAttributes(const Part& other)
{
visible = other.visible;
locked = other.locked;
subdived = other.subdived;
disabled = other.disabled;
xMirrored = other.xMirrored;
deformThickness = other.deformThickness;
deformWidth = other.deformWidth;
rounded = other.rounded;
chamfered = other.chamfered;
color = other.color;
hasColor = other.hasColor;
cutRotation = other.cutRotation;
cutFace = other.cutFace;
cutFaceLinkedId = other.cutFaceLinkedId;
componentId = other.componentId;
dirty = other.dirty;
target = other.target;
colorSolubility = other.colorSolubility;
countershaded = other.countershaded;
metalness = other.metalness;
roughness = other.roughness;
deformUnified = other.deformUnified;
smooth = other.smooth;
hollowThickness = other.hollowThickness;
}
private: private:
Q_DISABLE_COPY(Part); Q_DISABLE_COPY(Part);
@ -403,18 +170,20 @@ public:
class Component { class Component {
public: public:
Component() Component();
{ Component(const dust3d::Uuid& withId, const QString& linkData = QString(), const QString& linkDataType = QString());
} QString linkData() const;
Component(const dust3d::Uuid& withId, const QString& linkData = QString(), const QString& linkDataType = QString()) QString linkDataType() const;
{ void addChild(dust3d::Uuid childId);
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; void replaceChildWithOthers(const dust3d::Uuid& childId, const std::vector<dust3d::Uuid>& others);
if (!linkData.isEmpty()) { void removeChild(dust3d::Uuid childId);
if ("partId" == linkDataType) { void replaceChild(dust3d::Uuid childId, dust3d::Uuid newId);
linkToPartId = dust3d::Uuid(linkData.toUtf8().constData()); void moveChildUp(dust3d::Uuid childId);
} void moveChildDown(dust3d::Uuid childId);
} void moveChildToTop(dust3d::Uuid childId);
} void moveChildToBottom(dust3d::Uuid childId);
void updatePreviewMesh(std::unique_ptr<ModelMesh> mesh);
ModelMesh* takePreviewMesh() const;
dust3d::Uuid id; dust3d::Uuid id;
QString name; QString name;
dust3d::Uuid linkToPartId; dust3d::Uuid linkToPartId;
@ -427,131 +196,6 @@ public:
std::unique_ptr<QImage> previewImage; std::unique_ptr<QImage> previewImage;
bool isPreviewImageDecorationObsolete = false; bool isPreviewImageDecorationObsolete = false;
QPixmap previewPixmap; QPixmap previewPixmap;
QString linkData() const
{
return linkToPartId.isNull() ? QString() : QString(linkToPartId.toString().c_str());
}
QString linkDataType() const
{
return linkToPartId.isNull() ? QString() : QString("partId");
}
void addChild(dust3d::Uuid childId)
{
if (m_childrenIdSet.find(childId) != m_childrenIdSet.end())
return;
m_childrenIdSet.insert(childId);
childrenIds.push_back(childId);
}
void replaceChildWithOthers(const dust3d::Uuid& childId, const std::vector<dust3d::Uuid>& others)
{
if (m_childrenIdSet.find(childId) == m_childrenIdSet.end())
return;
m_childrenIdSet.erase(childId);
std::vector<dust3d::Uuid> candidates;
for (const auto& it : others) {
if (m_childrenIdSet.find(it) == m_childrenIdSet.end()) {
m_childrenIdSet.insert(it);
candidates.emplace_back(it);
}
}
for (size_t i = 0; i < childrenIds.size(); ++i) {
if (childId == childrenIds[i]) {
size_t newAddSize = candidates.size() - 1;
if (newAddSize > 0) {
size_t oldSize = childrenIds.size();
childrenIds.resize(childrenIds.size() + newAddSize);
for (int j = (int)oldSize - 1; j > (int)i; --j) {
childrenIds[j + newAddSize] = childrenIds[j];
}
}
for (size_t k = 0; k < candidates.size(); ++k)
childrenIds[i + k] = candidates[k];
break;
}
}
}
void removeChild(dust3d::Uuid childId)
{
if (m_childrenIdSet.find(childId) == m_childrenIdSet.end())
return;
m_childrenIdSet.erase(childId);
auto findResult = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (findResult != childrenIds.end())
childrenIds.erase(findResult);
}
void replaceChild(dust3d::Uuid childId, dust3d::Uuid newId)
{
if (m_childrenIdSet.find(childId) == m_childrenIdSet.end())
return;
if (m_childrenIdSet.find(newId) != m_childrenIdSet.end())
return;
m_childrenIdSet.erase(childId);
m_childrenIdSet.insert(newId);
auto findResult = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (findResult != childrenIds.end())
*findResult = newId;
}
void moveChildUp(dust3d::Uuid childId)
{
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (it == childrenIds.end()) {
return;
}
auto index = std::distance(childrenIds.begin(), it);
if (index == 0)
return;
std::swap(childrenIds[index - 1], childrenIds[index]);
}
void moveChildDown(dust3d::Uuid childId)
{
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (it == childrenIds.end()) {
return;
}
auto index = std::distance(childrenIds.begin(), it);
if (index == (int)childrenIds.size() - 1)
return;
std::swap(childrenIds[index], childrenIds[index + 1]);
}
void moveChildToTop(dust3d::Uuid childId)
{
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (it == childrenIds.end()) {
return;
}
auto index = std::distance(childrenIds.begin(), it);
if (index == 0)
return;
for (int i = index; i >= 1; i--)
std::swap(childrenIds[i - 1], childrenIds[i]);
}
void moveChildToBottom(dust3d::Uuid childId)
{
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (it == childrenIds.end()) {
return;
}
auto index = std::distance(childrenIds.begin(), it);
if (index == (int)childrenIds.size() - 1)
return;
for (int i = index; i <= (int)childrenIds.size() - 2; i++)
std::swap(childrenIds[i], childrenIds[i + 1]);
}
void updatePreviewMesh(std::unique_ptr<ModelMesh> mesh)
{
m_previewMesh = std::move(mesh);
isPreviewMeshObsolete = true;
}
ModelMesh* takePreviewMesh() const
{
if (nullptr == m_previewMesh)
return nullptr;
return new ModelMesh(*m_previewMesh);
}
private: private:
std::unique_ptr<ModelMesh> m_previewMesh; std::unique_ptr<ModelMesh> m_previewMesh;

View File

@ -0,0 +1,6 @@
#include "document.h"
Document::Bone::Bone(const dust3d::Uuid& withId)
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}

View File

@ -0,0 +1,152 @@
#include "document.h"
Document::Component::Component()
{
}
Document::Component::Component(const dust3d::Uuid& withId, const QString& linkData, const QString& linkDataType)
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
if (!linkData.isEmpty()) {
if ("partId" == linkDataType) {
linkToPartId = dust3d::Uuid(linkData.toUtf8().constData());
}
}
}
QString Document::Component::linkData() const
{
return linkToPartId.isNull() ? QString() : QString(linkToPartId.toString().c_str());
}
QString Document::Component::linkDataType() const
{
return linkToPartId.isNull() ? QString() : QString("partId");
}
void Document::Component::addChild(dust3d::Uuid childId)
{
if (m_childrenIdSet.find(childId) != m_childrenIdSet.end())
return;
m_childrenIdSet.insert(childId);
childrenIds.push_back(childId);
}
void Document::Component::replaceChildWithOthers(const dust3d::Uuid& childId, const std::vector<dust3d::Uuid>& others)
{
if (m_childrenIdSet.find(childId) == m_childrenIdSet.end())
return;
m_childrenIdSet.erase(childId);
std::vector<dust3d::Uuid> candidates;
for (const auto& it : others) {
if (m_childrenIdSet.find(it) == m_childrenIdSet.end()) {
m_childrenIdSet.insert(it);
candidates.emplace_back(it);
}
}
for (size_t i = 0; i < childrenIds.size(); ++i) {
if (childId == childrenIds[i]) {
size_t newAddSize = candidates.size() - 1;
if (newAddSize > 0) {
size_t oldSize = childrenIds.size();
childrenIds.resize(childrenIds.size() + newAddSize);
for (int j = (int)oldSize - 1; j > (int)i; --j) {
childrenIds[j + newAddSize] = childrenIds[j];
}
}
for (size_t k = 0; k < candidates.size(); ++k)
childrenIds[i + k] = candidates[k];
break;
}
}
}
void Document::Component::removeChild(dust3d::Uuid childId)
{
if (m_childrenIdSet.find(childId) == m_childrenIdSet.end())
return;
m_childrenIdSet.erase(childId);
auto findResult = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (findResult != childrenIds.end())
childrenIds.erase(findResult);
}
void Document::Component::replaceChild(dust3d::Uuid childId, dust3d::Uuid newId)
{
if (m_childrenIdSet.find(childId) == m_childrenIdSet.end())
return;
if (m_childrenIdSet.find(newId) != m_childrenIdSet.end())
return;
m_childrenIdSet.erase(childId);
m_childrenIdSet.insert(newId);
auto findResult = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (findResult != childrenIds.end())
*findResult = newId;
}
void Document::Component::moveChildUp(dust3d::Uuid childId)
{
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (it == childrenIds.end()) {
return;
}
auto index = std::distance(childrenIds.begin(), it);
if (index == 0)
return;
std::swap(childrenIds[index - 1], childrenIds[index]);
}
void Document::Component::moveChildDown(dust3d::Uuid childId)
{
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (it == childrenIds.end()) {
return;
}
auto index = std::distance(childrenIds.begin(), it);
if (index == (int)childrenIds.size() - 1)
return;
std::swap(childrenIds[index], childrenIds[index + 1]);
}
void Document::Component::moveChildToTop(dust3d::Uuid childId)
{
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (it == childrenIds.end()) {
return;
}
auto index = std::distance(childrenIds.begin(), it);
if (index == 0)
return;
for (int i = index; i >= 1; i--)
std::swap(childrenIds[i - 1], childrenIds[i]);
}
void Document::Component::moveChildToBottom(dust3d::Uuid childId)
{
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
if (it == childrenIds.end()) {
return;
}
auto index = std::distance(childrenIds.begin(), it);
if (index == (int)childrenIds.size() - 1)
return;
for (int i = index; i <= (int)childrenIds.size() - 2; i++)
std::swap(childrenIds[i], childrenIds[i + 1]);
}
void Document::Component::updatePreviewMesh(std::unique_ptr<ModelMesh> mesh)
{
m_previewMesh = std::move(mesh);
isPreviewMeshObsolete = true;
}
ModelMesh* Document::Component::takePreviewMesh() const
{
if (nullptr == m_previewMesh)
return nullptr;
return new ModelMesh(*m_previewMesh);
}

View File

@ -0,0 +1,13 @@
#include "document.h"
Document::Edge::Edge(const dust3d::Uuid& withId)
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
dust3d::Uuid Document::Edge::neighborOf(dust3d::Uuid nodeId) const
{
if (nodeIds.size() != 2)
return dust3d::Uuid();
return nodeIds[0] == nodeId ? nodeIds[1] : nodeIds[0];
}

View File

@ -0,0 +1,102 @@
#include "document.h"
#include "mesh_generator.h"
Document::Node::Node(const dust3d::Uuid& withId)
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
void Document::Node::setRadius(float toRadius)
{
if (toRadius < MeshGenerator::m_minimalRadius)
toRadius = MeshGenerator::m_minimalRadius;
else if (toRadius > 1)
toRadius = 1;
radius = toRadius;
}
void Document::Node::setCutRotation(float toRotation)
{
if (toRotation < -1)
toRotation = -1;
else if (toRotation > 1)
toRotation = 1;
cutRotation = toRotation;
hasCutFaceSettings = true;
}
void Document::Node::setCutFace(dust3d::CutFace face)
{
cutFace = face;
cutFaceLinkedId = dust3d::Uuid();
hasCutFaceSettings = true;
}
void Document::Node::setCutFaceLinkedId(const dust3d::Uuid& linkedId)
{
if (linkedId.isNull()) {
clearCutFaceSettings();
return;
}
cutFace = dust3d::CutFace::UserDefined;
cutFaceLinkedId = linkedId;
hasCutFaceSettings = true;
}
void Document::Node::clearCutFaceSettings()
{
cutFace = dust3d::CutFace::Quad;
cutFaceLinkedId = dust3d::Uuid();
cutRotation = 0;
hasCutFaceSettings = false;
}
float Document::Node::getX(bool rotated) const
{
if (rotated)
return m_y;
return m_x;
}
float Document::Node::getY(bool rotated) const
{
if (rotated)
return m_x;
return m_y;
}
float Document::Node::getZ(bool rotated) const
{
(void)rotated;
return m_z;
}
void Document::Node::setX(float x)
{
m_x = x;
}
void Document::Node::setY(float y)
{
m_y = y;
}
void Document::Node::setZ(float z)
{
m_z = z;
}
void Document::Node::addX(float x)
{
m_x += x;
}
void Document::Node::addY(float y)
{
m_y += y;
}
void Document::Node::addZ(float z)
{
m_z += z;
}

View File

@ -0,0 +1,229 @@
#include "document.h"
Document::Part::Part(const dust3d::Uuid& withId)
: visible(true)
, locked(false)
, subdived(false)
, disabled(false)
, xMirrored(false)
, deformThickness(1.0)
, deformWidth(1.0)
, deformUnified(false)
, rounded(false)
, chamfered(false)
, color(Qt::white)
, hasColor(false)
, dirty(true)
, cutRotation(0.0)
, cutFace(dust3d::CutFace::Quad)
, target(dust3d::PartTarget::Model)
, colorSolubility(0.0)
, metalness(0.0)
, roughness(1.0)
, hollowThickness(0.0)
, countershaded(false)
, smooth(false)
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
bool Document::Part::hasPolyFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasSmoothFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasSubdivFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasRoundEndFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasMirrorFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasChamferFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasRotationFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasHollowFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasCutFaceFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasLayerFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasTargetFunction() const
{
return true;
}
bool Document::Part::hasBaseFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasCombineModeFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasDeformFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool Document::Part::hasColorFunction() const
{
return dust3d::PartTarget::Model == target;
}
void Document::Part::setDeformThickness(float toThickness)
{
if (toThickness < 0)
toThickness = 0;
else if (toThickness > 2)
toThickness = 2;
deformThickness = toThickness;
}
void Document::Part::setDeformWidth(float toWidth)
{
if (toWidth < 0)
toWidth = 0;
else if (toWidth > 2)
toWidth = 2;
deformWidth = toWidth;
}
void Document::Part::setCutRotation(float toRotation)
{
if (toRotation < -1)
toRotation = -1;
else if (toRotation > 1)
toRotation = 1;
cutRotation = toRotation;
}
void Document::Part::setCutFace(dust3d::CutFace face)
{
cutFace = face;
cutFaceLinkedId = dust3d::Uuid();
}
void Document::Part::setCutFaceLinkedId(const dust3d::Uuid& linkedId)
{
if (linkedId.isNull()) {
setCutFace(dust3d::CutFace::Quad);
return;
}
cutFace = dust3d::CutFace::UserDefined;
cutFaceLinkedId = linkedId;
}
bool Document::Part::deformThicknessAdjusted() const
{
return fabs(deformThickness - 1.0) >= 0.01;
}
bool Document::Part::deformWidthAdjusted() const
{
return fabs(deformWidth - 1.0) >= 0.01;
}
bool Document::Part::deformAdjusted() const
{
return deformThicknessAdjusted() || deformWidthAdjusted() || deformUnified;
}
bool Document::Part::colorSolubilityAdjusted() const
{
return fabs(colorSolubility - 0.0) >= 0.01;
}
bool Document::Part::metalnessAdjusted() const
{
return fabs(metalness - 0.0) >= 0.01;
}
bool Document::Part::roughnessAdjusted() const
{
return fabs(roughness - 1.0) >= 0.01;
}
bool Document::Part::cutRotationAdjusted() const
{
return fabs(cutRotation - 0.0) >= 0.01;
}
bool Document::Part::hollowThicknessAdjusted() const
{
return fabs(hollowThickness - 0.0) >= 0.01;
}
bool Document::Part::cutFaceAdjusted() const
{
return cutFace != dust3d::CutFace::Quad;
}
bool Document::Part::cutAdjusted() const
{
return cutRotationAdjusted() || cutFaceAdjusted() || hollowThicknessAdjusted();
}
bool Document::Part::isEditVisible() const
{
return visible && !disabled;
}
void Document::Part::copyAttributes(const Part& other)
{
visible = other.visible;
locked = other.locked;
subdived = other.subdived;
disabled = other.disabled;
xMirrored = other.xMirrored;
deformThickness = other.deformThickness;
deformWidth = other.deformWidth;
rounded = other.rounded;
chamfered = other.chamfered;
color = other.color;
hasColor = other.hasColor;
cutRotation = other.cutRotation;
cutFace = other.cutFace;
cutFaceLinkedId = other.cutFaceLinkedId;
componentId = other.componentId;
dirty = other.dirty;
target = other.target;
colorSolubility = other.colorSolubility;
countershaded = other.countershaded;
metalness = other.metalness;
roughness = other.roughness;
deformUnified = other.deformUnified;
smooth = other.smooth;
hollowThickness = other.hollowThickness;
}

View File

@ -48,22 +48,93 @@ void SkeletonGenerator::addBone(const Uuid& boneId, const Bone& bone)
m_boneMap.emplace(std::make_pair(boneId, bone)); m_boneMap.emplace(std::make_pair(boneId, bone));
} }
void SkeletonGenerator::addNodeBinding(const Uuid& nodeId, const NodeBinding& node) void SkeletonGenerator::addNodeBinding(const Uuid& nodeId, const NodeBinding& nodeBinding)
{ {
m_nodeBindingMap.emplace(std::make_pair(nodeId, node)); m_nodeBindingMap.emplace(std::make_pair(nodeId, nodeBinding));
}
void SkeletonGenerator::buildEdges()
{
for (const auto& face : m_faces) {
for (size_t i = 0; i < face.size(); ++i) {
size_t j = (i + 1) % face.size();
m_edges[face[i]].insert(face[j]);
m_edges[face[j]].insert(face[i]);
}
}
}
Uuid SkeletonGenerator::resolveVertexSourceByBreadthFirstSearch(size_t vertexIndex, std::unordered_set<size_t>& visited)
{
visited.insert(vertexIndex);
auto findNeighbors = m_edges.find(vertexIndex);
if (findNeighbors == m_edges.end())
return Uuid();
for (const auto& it : findNeighbors->second) {
if (!m_vertexSourceNodes[it].isNull())
return m_vertexSourceNodes[it];
}
for (const auto& it : findNeighbors->second) {
if (visited.end() != visited.find(it))
continue;
Uuid foundId = resolveVertexSourceByBreadthFirstSearch(it, visited);
if (!foundId.isNull())
return foundId;
}
return Uuid();
}
void SkeletonGenerator::resolveVertexSources()
{
m_vertexSourceNodes.resize(m_vertices.size());
for (size_t i = 0; i < m_vertices.size(); ++i) {
auto findNode = m_positionToNodeMap.find(m_vertices[i]);
if (findNode == m_positionToNodeMap.end())
continue;
m_vertexSourceNodes[i] = findNode->second;
}
for (size_t i = 0; i < m_vertexSourceNodes.size(); ++i) {
if (!m_vertexSourceNodes[i].isNull())
continue;
std::unordered_set<size_t> visited;
m_vertexSourceNodes[i] = resolveVertexSourceByBreadthFirstSearch(i, visited);
}
}
void SkeletonGenerator::buildBoneJoints()
{
// TODO:
}
void SkeletonGenerator::assignBoneJointToVertices()
{
// TODO:
}
void SkeletonGenerator::groupBoneVertices()
{
/*
for (size_t i = 0; i < m_vertexSourceNodes.size(); ++i) {
const Uuid& sourceNodeId = m_vertexSourceNodes[i];
if (sourceNodeId.isNull())
continue;
auto findBinding = m_nodeBindingMap.find(sourceNodeId);
if (findBinding == m_nodeBindingMap.end())
continue;
// TODO:
}
*/
// TODO:
} }
void SkeletonGenerator::bind() void SkeletonGenerator::bind()
{ {
// TODO: Build vertex edge map buildEdges();
resolveVertexSources();
// TODO: Bind unbound nodes groupBoneVertices();
buildBoneJoints();
// TODO: Build bone skeleton assignBoneJointToVertices();
// TODO: Assign bone to vertex
// TODO: finalize
} }
} }

View File

@ -27,6 +27,8 @@
#include <dust3d/base/uuid.h> #include <dust3d/base/uuid.h>
#include <dust3d/base/vector3.h> #include <dust3d/base/vector3.h>
#include <map> #include <map>
#include <set>
#include <unordered_set>
#include <vector> #include <vector>
namespace dust3d { namespace dust3d {
@ -40,7 +42,6 @@ public:
struct Bone { struct Bone {
std::string name; std::string name;
std::string parent;
}; };
SkeletonGenerator(); SkeletonGenerator();
@ -48,7 +49,7 @@ public:
void setFaces(const std::vector<std::vector<size_t>>& faces); void setFaces(const std::vector<std::vector<size_t>>& faces);
void setPositionToNodeMap(const std::map<PositionKey, Uuid>& positionToNodeMap); void setPositionToNodeMap(const std::map<PositionKey, Uuid>& positionToNodeMap);
void addBone(const Uuid& boneId, const Bone& bone); void addBone(const Uuid& boneId, const Bone& bone);
void addNodeBinding(const Uuid& nodeId, const NodeBinding& node); void addNodeBinding(const Uuid& nodeId, const NodeBinding& nodeBinding);
void bind(); void bind();
private: private:
@ -57,6 +58,15 @@ private:
std::map<PositionKey, Uuid> m_positionToNodeMap; std::map<PositionKey, Uuid> m_positionToNodeMap;
std::map<Uuid, NodeBinding> m_nodeBindingMap; std::map<Uuid, NodeBinding> m_nodeBindingMap;
std::map<Uuid, Bone> m_boneMap; std::map<Uuid, Bone> m_boneMap;
std::map<size_t, std::set<size_t>> m_edges;
std::vector<Uuid> m_vertexSourceNodes;
void buildEdges();
void resolveVertexSources();
Uuid resolveVertexSourceByBreadthFirstSearch(size_t vertexIndex, std::unordered_set<size_t>& visited);
void groupBoneVertices();
void buildBoneJoints();
void assignBoneJointToVertices();
}; };
} }