Remove skeleton document

master
Jeremy HU 2022-10-22 14:11:00 +11:00
parent 86a6e5f163
commit 4fb109a583
16 changed files with 2179 additions and 2366 deletions

View File

@ -189,8 +189,6 @@ HEADERS += sources/preferences.h
SOURCES += sources/preferences.cc SOURCES += sources/preferences.cc
HEADERS += sources/preview_grid_view.h HEADERS += sources/preview_grid_view.h
SOURCES += sources/preview_grid_view.cc SOURCES += sources/preview_grid_view.cc
HEADERS += sources/skeleton_document.h
SOURCES += sources/skeleton_document.cc
HEADERS += sources/skeleton_graphics_widget.h HEADERS += sources/skeleton_graphics_widget.h
SOURCES += sources/skeleton_graphics_widget.cc SOURCES += sources/skeleton_graphics_widget.cc
HEADERS += sources/skeleton_ik_mover.h HEADERS += sources/skeleton_ik_mover.h
@ -203,8 +201,8 @@ HEADERS += sources/theme.h
SOURCES += sources/theme.cc SOURCES += sources/theme.cc
HEADERS += sources/toolbar_button.h HEADERS += sources/toolbar_button.h
SOURCES += sources/toolbar_button.cc SOURCES += sources/toolbar_button.cc
HEADERS += sources/tube_uv_preview_image_generator.h HEADERS += sources/uv_preview_image_generator.h
SOURCES += sources/tube_uv_preview_image_generator.cc SOURCES += sources/uv_preview_image_generator.cc
HEADERS += sources/turnaround_loader.h HEADERS += sources/turnaround_loader.h
SOURCES += sources/turnaround_loader.cc SOURCES += sources/turnaround_loader.cc
HEADERS += sources/updates_check_widget.h HEADERS += sources/updates_check_widget.h
@ -243,8 +241,6 @@ SOURCES += ../dust3d/base/ds3_file.cc
HEADERS += ../dust3d/base/math.h HEADERS += ../dust3d/base/math.h
HEADERS += ../dust3d/base/matrix4x4.h HEADERS += ../dust3d/base/matrix4x4.h
HEADERS += ../dust3d/base/object.h HEADERS += ../dust3d/base/object.h
HEADERS += ../dust3d/base/part_base.h
SOURCES += ../dust3d/base/part_base.cc
HEADERS += ../dust3d/base/part_target.h HEADERS += ../dust3d/base/part_target.h
SOURCES += ../dust3d/base/part_target.cc SOURCES += ../dust3d/base/part_target.cc
HEADERS += ../dust3d/base/position_key.h HEADERS += ../dust3d/base/position_key.h

View File

@ -188,12 +188,29 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document* document,
cutFaceGroupBox->setLayout(cutFaceLayout); cutFaceGroupBox->setLayout(cutFaceLayout);
} }
QGroupBox* skinGroupBox = nullptr;
if (nullptr != m_part) {
QCheckBox* useImageBox = new QCheckBox();
Theme::initCheckbox(useImageBox);
useImageBox->setText(tr("Use image"));
useImageBox->setChecked(m_part->rounded);
QHBoxLayout* skinLayout = new QHBoxLayout;
skinLayout->addStretch();
skinLayout->addWidget(useImageBox);
skinGroupBox = new QGroupBox(tr("Skin"));
skinGroupBox->setLayout(skinLayout);
}
QVBoxLayout* mainLayout = new QVBoxLayout; QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addLayout(colorLayout); mainLayout->addLayout(colorLayout);
if (nullptr != deformGroupBox) if (nullptr != deformGroupBox)
mainLayout->addWidget(deformGroupBox); mainLayout->addWidget(deformGroupBox);
if (nullptr != cutFaceGroupBox) if (nullptr != cutFaceGroupBox)
mainLayout->addWidget(cutFaceGroupBox); mainLayout->addWidget(cutFaceGroupBox);
if (nullptr != skinGroupBox)
mainLayout->addWidget(skinGroupBox);
mainLayout->setSizeConstraint(QLayout::SetFixedSize); mainLayout->setSizeConstraint(QLayout::SetFixedSize);
connect(this, &ComponentPropertyWidget::setPartColorState, m_document, &Document::setPartColorState); connect(this, &ComponentPropertyWidget::setPartColorState, m_document, &Document::setPartColorState);

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
#ifndef DUST3D_APPLICATION_DOCUMENT_H_ #ifndef DUST3D_APPLICATION_DOCUMENT_H_
#define DUST3D_APPLICATION_DOCUMENT_H_ #define DUST3D_APPLICATION_DOCUMENT_H_
#include "debug.h"
#include "material_layer.h" #include "material_layer.h"
#include "model_mesh.h" #include "model_mesh.h"
#include "monochrome_mesh.h" #include "monochrome_mesh.h"
#include "skeleton_document.h"
#include "theme.h" #include "theme.h"
#include <QImage> #include <QImage>
#include <QObject> #include <QObject>
@ -13,6 +13,8 @@
#include <cmath> #include <cmath>
#include <deque> #include <deque>
#include <dust3d/base/combine_mode.h> #include <dust3d/base/combine_mode.h>
#include <dust3d/base/cut_face.h>
#include <dust3d/base/part_target.h>
#include <dust3d/base/snapshot.h> #include <dust3d/base/snapshot.h>
#include <dust3d/base/texture_type.h> #include <dust3d/base/texture_type.h>
#include <dust3d/base/uuid.h> #include <dust3d/base/uuid.h>
@ -20,6 +22,535 @@
#include <set> #include <set>
#include <vector> #include <vector>
class SkeletonNode {
public:
SkeletonNode(const dust3d::Uuid& withId = dust3d::Uuid())
: radius(0)
, cutRotation(0.0)
, cutFace(dust3d::CutFace::Quad)
, hasCutFaceSettings(false)
, m_x(0)
, m_y(0)
, m_z(0)
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
void setRadius(float toRadius);
void setCutRotation(float toRotation)
{
if (toRotation < -1)
toRotation = -1;
else if (toRotation > 1)
toRotation = 1;
cutRotation = toRotation;
hasCutFaceSettings = true;
}
void setCutFace(dust3d::CutFace face)
{
cutFace = face;
cutFaceLinkedId = dust3d::Uuid();
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 partId;
QString name;
float radius;
float cutRotation;
dust3d::CutFace cutFace;
dust3d::Uuid cutFaceLinkedId;
bool hasCutFaceSettings;
std::vector<dust3d::Uuid> edgeIds;
private:
float m_x;
float m_y;
float m_z;
};
class SkeletonEdge {
public:
SkeletonEdge(const dust3d::Uuid& withId = dust3d::Uuid())
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
dust3d::Uuid id;
dust3d::Uuid partId;
QString name;
std::vector<dust3d::Uuid> nodeIds;
dust3d::Uuid neighborOf(dust3d::Uuid nodeId) const
{
if (nodeIds.size() != 2)
return dust3d::Uuid();
return nodeIds[0] == nodeId ? nodeIds[1] : nodeIds[0];
}
};
class SkeletonPart {
public:
dust3d::Uuid id;
QString name;
bool visible;
bool locked;
bool subdived;
bool disabled;
bool xMirrored;
float deformThickness;
float deformWidth;
bool deformUnified;
bool rounded;
bool chamfered;
QColor color;
bool hasColor;
dust3d::Uuid componentId;
std::vector<dust3d::Uuid> nodeIds;
bool dirty;
float cutRotation;
dust3d::CutFace cutFace;
dust3d::Uuid cutFaceLinkedId;
dust3d::Uuid materialId;
dust3d::PartTarget target;
float colorSolubility;
float metalness;
float roughness;
float hollowThickness;
bool countershaded;
bool smooth;
dust3d::Uuid colorImageId;
SkeletonPart(const dust3d::Uuid& withId = dust3d::Uuid())
: 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 hasPolyFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasSmoothFunction() const
{
return dust3d::PartTarget::Model == target;
}
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 materialAdjusted() const
{
return !materialId.isNull();
}
bool isEditVisible() const
{
return visible && !disabled;
}
void copyAttributes(const SkeletonPart& 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;
materialId = other.materialId;
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:
Q_DISABLE_COPY(SkeletonPart);
};
enum class DocumentEditMode {
Add = 0,
Select,
Paint,
Drag,
ZoomIn,
ZoomOut
};
enum class SkeletonProfile {
Unknown = 0,
Main,
Side
};
class SkeletonComponent {
public:
SkeletonComponent()
{
}
SkeletonComponent(const dust3d::Uuid& withId, const QString& linkData = QString(), const QString& linkDataType = QString())
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
if (!linkData.isEmpty()) {
if ("partId" == linkDataType) {
linkToPartId = dust3d::Uuid(linkData.toUtf8().constData());
}
}
}
dust3d::Uuid id;
QString name;
dust3d::Uuid linkToPartId;
dust3d::Uuid parentId;
bool expanded = true;
dust3d::CombineMode combineMode = dust3d::CombineMode::Normal;
bool dirty = true;
std::vector<dust3d::Uuid> childrenIds;
bool isPreviewMeshObsolete = false;
std::unique_ptr<QImage> previewImage;
bool isPreviewImageDecorationObsolete = false;
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:
std::unique_ptr<ModelMesh> m_previewMesh;
std::set<dust3d::Uuid> m_childrenIdSet;
};
class MaterialPreviewsGenerator; class MaterialPreviewsGenerator;
class TextureGenerator; class TextureGenerator;
class MeshGenerator; class MeshGenerator;
@ -66,7 +597,7 @@ enum class DocumentToSnapshotFor {
Materials Materials
}; };
class Document : public SkeletonDocument { class Document : public QObject {
Q_OBJECT Q_OBJECT
signals: signals:
void nodeCutRotationChanged(dust3d::Uuid nodeId); void nodeCutRotationChanged(dust3d::Uuid nodeId);
@ -80,7 +611,6 @@ signals:
void postProcessedResultChanged(); void postProcessedResultChanged();
void partSubdivStateChanged(dust3d::Uuid partId); void partSubdivStateChanged(dust3d::Uuid partId);
void partXmirrorStateChanged(dust3d::Uuid partId); void partXmirrorStateChanged(dust3d::Uuid partId);
void partBaseChanged(dust3d::Uuid partId);
void partDeformThicknessChanged(dust3d::Uuid partId); void partDeformThicknessChanged(dust3d::Uuid partId);
void partDeformWidthChanged(dust3d::Uuid partId); void partDeformWidthChanged(dust3d::Uuid partId);
void partDeformUnifyStateChanged(dust3d::Uuid partId); void partDeformUnifyStateChanged(dust3d::Uuid partId);
@ -118,6 +648,33 @@ signals:
void postProcessing(); void postProcessing();
void textureGenerating(); void textureGenerating();
void textureChanged(); void textureChanged();
void partAdded(dust3d::Uuid partId);
void nodeAdded(dust3d::Uuid nodeId);
void edgeAdded(dust3d::Uuid edgeId);
void partRemoved(dust3d::Uuid partId);
void partLockStateChanged(dust3d::Uuid partId);
void partVisibleStateChanged(dust3d::Uuid partId);
void partDisableStateChanged(dust3d::Uuid partId);
void partColorImageChanged(const dust3d::Uuid& partId);
void componentNameChanged(dust3d::Uuid componentId);
void componentChildrenChanged(dust3d::Uuid componentId);
void componentRemoved(dust3d::Uuid componentId);
void componentAdded(dust3d::Uuid componentId);
void componentExpandStateChanged(dust3d::Uuid componentId);
void componentPreviewMeshChanged(const dust3d::Uuid& componentId);
void componentPreviewPixmapChanged(const dust3d::Uuid& componentId);
void nodeRemoved(dust3d::Uuid nodeId);
void edgeRemoved(dust3d::Uuid edgeId);
void nodeRadiusChanged(dust3d::Uuid nodeId);
void nodeOriginChanged(dust3d::Uuid nodeId);
void edgeReversed(dust3d::Uuid edgeId);
void originChanged();
void skeletonChanged();
void optionsChanged();
void xlockStateChanged();
void ylockStateChanged();
void zlockStateChanged();
void radiusLockStateChanged();
public: // need initialize public: // need initialize
QImage* textureImage = nullptr; QImage* textureImage = nullptr;
@ -133,6 +690,18 @@ public: // need initialize
bool weldEnabled = true; bool weldEnabled = true;
float brushMetalness = ModelMesh::m_defaultMetalness; float brushMetalness = ModelMesh::m_defaultMetalness;
float brushRoughness = ModelMesh::m_defaultRoughness; float brushRoughness = ModelMesh::m_defaultRoughness;
DocumentEditMode editMode = DocumentEditMode::Select;
bool xlocked = false;
bool ylocked = false;
bool zlocked = false;
bool radiusLocked = false;
QImage turnaround;
QByteArray turnaroundPngByteArray;
std::map<dust3d::Uuid, SkeletonPart> partMap;
std::map<dust3d::Uuid, SkeletonNode> nodeMap;
std::map<dust3d::Uuid, SkeletonEdge> edgeMap;
std::map<dust3d::Uuid, SkeletonComponent> componentMap;
SkeletonComponent rootComponent;
public: public:
Document(); Document();
@ -140,13 +709,13 @@ public:
std::map<dust3d::Uuid, Material> materialMap; std::map<dust3d::Uuid, Material> materialMap;
std::vector<dust3d::Uuid> materialIdList; std::vector<dust3d::Uuid> materialIdList;
bool undoable() const override; bool undoable() const;
bool redoable() const override; bool redoable() const;
bool hasPastableNodesInClipboard() const override; bool hasPastableNodesInClipboard() const;
bool originSettled() const override; bool originSettled() const;
bool isNodeEditable(dust3d::Uuid nodeId) const override; bool isNodeEditable(dust3d::Uuid nodeId) const;
bool isEdgeEditable(dust3d::Uuid edgeId) const override; bool isEdgeEditable(dust3d::Uuid edgeId) const;
void copyNodes(std::set<dust3d::Uuid> nodeIdSet) const override; void copyNodes(std::set<dust3d::Uuid> nodeIdSet) const;
void toSnapshot(dust3d::Snapshot* snapshot, const std::set<dust3d::Uuid>& limitNodeIds = std::set<dust3d::Uuid>(), void toSnapshot(dust3d::Snapshot* snapshot, const std::set<dust3d::Uuid>& limitNodeIds = std::set<dust3d::Uuid>(),
DocumentToSnapshotFor forWhat = DocumentToSnapshotFor::Document, DocumentToSnapshotFor forWhat = DocumentToSnapshotFor::Document,
const std::set<dust3d::Uuid>& limitMaterialIds = std::set<dust3d::Uuid>()) const; const std::set<dust3d::Uuid>& limitMaterialIds = std::set<dust3d::Uuid>()) const;
@ -179,15 +748,72 @@ public:
bool isPostProcessing() const; bool isPostProcessing() const;
bool isTextureGenerating() const; bool isTextureGenerating() const;
void collectCutFaceList(std::vector<QString>& cutFaces) const; void collectCutFaceList(std::vector<QString>& cutFaces) const;
float getOriginX(bool rotated = false) const
{
if (rotated)
return m_originY;
return m_originX;
}
float getOriginY(bool rotated = false) const
{
if (rotated)
return m_originX;
return m_originY;
}
float getOriginZ(bool rotated = false) const
{
(void)rotated;
return m_originZ;
}
void setOriginX(float originX)
{
m_originX = originX;
}
void setOriginY(float originY)
{
m_originY = originY;
}
void setOriginZ(float originZ)
{
m_originZ = originZ;
}
void addOriginX(float originX)
{
m_originX += originX;
}
void addOriginY(float originY)
{
m_originY += originY;
}
void addOriginZ(float originZ)
{
m_originZ += originZ;
}
const SkeletonNode* findNode(dust3d::Uuid nodeId) const;
const SkeletonEdge* findEdge(dust3d::Uuid edgeId) const;
const SkeletonPart* findPart(dust3d::Uuid partId) const;
const SkeletonEdge* findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const;
void findAllNeighbors(dust3d::Uuid nodeId, std::set<dust3d::Uuid>& neighbors) const;
bool isNodeConnectable(dust3d::Uuid nodeId) const;
const SkeletonComponent* findComponent(dust3d::Uuid componentId) const;
const SkeletonComponent* findComponentParent(dust3d::Uuid componentId) const;
dust3d::Uuid findComponentParentId(dust3d::Uuid componentId) const;
void collectComponentDescendantParts(dust3d::Uuid componentId, std::vector<dust3d::Uuid>& partIds) const;
void collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector<dust3d::Uuid>& componentIds) const;
void setComponentPreviewMesh(const dust3d::Uuid& componentId, std::unique_ptr<ModelMesh> mesh);
void setComponentPreviewImage(const dust3d::Uuid& componentId, std::unique_ptr<QImage> image);
void resetDirtyFlags();
void markAllDirty();
public slots: public slots:
void undo() override; void undo();
void redo() override; void redo();
void paste() override; void paste();
void setNodeCutRotation(dust3d::Uuid nodeId, float cutRotation); void setNodeCutRotation(dust3d::Uuid nodeId, float cutRotation);
void setNodeCutFace(dust3d::Uuid nodeId, dust3d::CutFace cutFace); void setNodeCutFace(dust3d::Uuid nodeId, dust3d::CutFace cutFace);
void setNodeCutFaceLinkedId(dust3d::Uuid nodeId, dust3d::Uuid linkedId); void setNodeCutFaceLinkedId(dust3d::Uuid nodeId, dust3d::Uuid linkedId);
void clearNodeCutFaceSettings(dust3d::Uuid nodeId); void clearNodeCutFaceSettings(dust3d::Uuid nodeId);
void setEditMode(SkeletonDocumentEditMode mode); void setEditMode(DocumentEditMode mode);
void uiReady(); void uiReady();
void generateMesh(); void generateMesh();
void regenerateMesh(); void regenerateMesh();
@ -200,7 +826,6 @@ public slots:
void materialPreviewsReady(); void materialPreviewsReady();
void setPartSubdivState(dust3d::Uuid partId, bool subdived); void setPartSubdivState(dust3d::Uuid partId, bool subdived);
void setPartXmirrorState(dust3d::Uuid partId, bool mirrored); void setPartXmirrorState(dust3d::Uuid partId, bool mirrored);
void setPartBase(dust3d::Uuid partId, dust3d::PartBase base);
void setPartDeformThickness(dust3d::Uuid partId, float thickness); void setPartDeformThickness(dust3d::Uuid partId, float thickness);
void setPartDeformWidth(dust3d::Uuid partId, float width); void setPartDeformWidth(dust3d::Uuid partId, float width);
void setPartDeformUnified(dust3d::Uuid partId, bool unified); void setPartDeformUnified(dust3d::Uuid partId, bool unified);
@ -231,11 +856,73 @@ public slots:
void removeMaterial(dust3d::Uuid materialId); void removeMaterial(dust3d::Uuid materialId);
void setMaterialLayers(dust3d::Uuid materialId, std::vector<MaterialLayer> layers); void setMaterialLayers(dust3d::Uuid materialId, std::vector<MaterialLayer> layers);
void renameMaterial(dust3d::Uuid materialId, QString name); void renameMaterial(dust3d::Uuid materialId, QString name);
void removeNode(dust3d::Uuid nodeId);
void removeEdge(dust3d::Uuid edgeId);
void removePart(dust3d::Uuid partId);
void addNodeWithId(dust3d::Uuid nodeId, float x, float y, float z, float radius, dust3d::Uuid fromNodeId);
void addNode(float x, float y, float z, float radius, dust3d::Uuid fromNodeId);
void scaleNodeByAddRadius(dust3d::Uuid nodeId, float amount);
void moveNodeBy(dust3d::Uuid nodeId, float x, float y, float z);
void setNodeOrigin(dust3d::Uuid nodeId, float x, float y, float z);
void setNodeRadius(dust3d::Uuid nodeId, float radius);
void switchNodeXZ(dust3d::Uuid nodeId);
void moveOriginBy(float x, float y, float z);
void addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId);
void moveComponentUp(dust3d::Uuid componentId);
void moveComponentDown(dust3d::Uuid componentId);
void moveComponentToTop(dust3d::Uuid componentId);
void moveComponentToBottom(dust3d::Uuid componentId);
void renameComponent(dust3d::Uuid componentId, QString name);
void removeComponent(dust3d::Uuid componentId);
void addComponent(dust3d::Uuid parentId);
void moveComponent(dust3d::Uuid componentId, dust3d::Uuid toParentId);
void setCurrentCanvasComponentId(dust3d::Uuid componentId);
void groupComponents(const std::vector<dust3d::Uuid>& componentIds);
void ungroupComponent(const dust3d::Uuid& componentId);
void createNewChildComponent(dust3d::Uuid parentComponentId);
void setComponentExpandState(dust3d::Uuid componentId, bool expanded);
void hideOtherComponents(dust3d::Uuid componentId);
void lockOtherComponents(dust3d::Uuid componentId);
void hideAllComponents();
void showAllComponents();
void showOrHideAllComponents();
void collapseAllComponents();
void expandAllComponents();
void lockAllComponents();
void unlockAllComponents();
void hideDescendantComponents(dust3d::Uuid componentId);
void showDescendantComponents(dust3d::Uuid componentId);
void lockDescendantComponents(dust3d::Uuid componentId);
void unlockDescendantComponents(dust3d::Uuid componentId);
void setComponentPreviewPixmap(const dust3d::Uuid& componentId, const QPixmap& pixmap);
void setPartLockState(dust3d::Uuid partId, bool locked);
void setPartVisibleState(dust3d::Uuid partId, bool visible);
void setPartDisableState(dust3d::Uuid partId, bool disabled);
void setPartColorImage(const dust3d::Uuid& partId, const dust3d::Uuid& imageId);
void enableAllPositionRelatedLocks();
void disableAllPositionRelatedLocks();
bool isPartReadonly(dust3d::Uuid partId) const;
void breakEdge(dust3d::Uuid edgeId);
void reduceNode(dust3d::Uuid nodeId);
void reverseEdge(dust3d::Uuid edgeId);
void setXlockState(bool locked);
void setYlockState(bool locked);
void setZlockState(bool locked);
void setRadiusLockState(bool locked);
private: private:
void resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile); void resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile);
void settleOrigin(); void settleOrigin();
void checkExportReadyState(); void checkExportReadyState();
void splitPartByNode(std::vector<std::vector<dust3d::Uuid>>* groups, dust3d::Uuid nodeId);
void joinNodeAndNeiborsToGroup(std::vector<dust3d::Uuid>* group, dust3d::Uuid nodeId, std::set<dust3d::Uuid>* visitMap, dust3d::Uuid noUseEdgeId = dust3d::Uuid());
void splitPartByEdge(std::vector<std::vector<dust3d::Uuid>>* groups, dust3d::Uuid edgeId);
void removePartDontCareComponent(dust3d::Uuid partId);
void addPartToComponent(dust3d::Uuid partId, dust3d::Uuid componentId);
bool isDescendantComponent(dust3d::Uuid componentId, dust3d::Uuid suspiciousId);
void removeComponentRecursively(dust3d::Uuid componentId);
void updateLinkedPart(dust3d::Uuid oldPartId, dust3d::Uuid newPartId);
dust3d::Uuid createNode(dust3d::Uuid nodeId, float x, float y, float z, float radius, dust3d::Uuid fromNodeId);
bool m_isResultMeshObsolete = false; bool m_isResultMeshObsolete = false;
MeshGenerator* m_meshGenerator = nullptr; MeshGenerator* m_meshGenerator = nullptr;
@ -256,6 +943,11 @@ private:
quint64 m_meshGenerationId = 0; quint64 m_meshGenerationId = 0;
quint64 m_nextMeshGenerationId = 0; quint64 m_nextMeshGenerationId = 0;
void* m_generatedCacheContext = nullptr; void* m_generatedCacheContext = nullptr;
float m_originX = 0;
float m_originY = 0;
float m_originZ = 0;
dust3d::Uuid m_currentCanvasComponentId;
bool m_allPositionRelatedLocksEnabled = true;
private: private:
static unsigned long m_maxSnapshot; static unsigned long m_maxSnapshot;

View File

@ -511,11 +511,11 @@ DocumentWindow::DocumentWindow()
canvasGraphicsWidget, &SkeletonGraphicsWidget::turnaroundChanged); canvasGraphicsWidget, &SkeletonGraphicsWidget::turnaroundChanged);
connect(addButton, &QPushButton::clicked, [=]() { connect(addButton, &QPushButton::clicked, [=]() {
m_document->setEditMode(SkeletonDocumentEditMode::Add); m_document->setEditMode(DocumentEditMode::Add);
}); });
connect(selectButton, &QPushButton::clicked, [=]() { connect(selectButton, &QPushButton::clicked, [=]() {
m_document->setEditMode(SkeletonDocumentEditMode::Select); m_document->setEditMode(DocumentEditMode::Select);
}); });
connect(m_xLockButton, &QPushButton::clicked, [=]() { connect(m_xLockButton, &QPushButton::clicked, [=]() {

View File

@ -10,9 +10,9 @@ typedef struct
GLfloat posX; GLfloat posX;
GLfloat posY; GLfloat posY;
GLfloat posZ; GLfloat posZ;
GLfloat colorR = 0.0; GLfloat colorR = 24.0 / 255.0;
GLfloat colorG = 0.0; GLfloat colorG = 29.0 / 255.0;
GLfloat colorB = 0.0; GLfloat colorB = 49.0 / 255.0;
GLfloat alpha = 1.0; GLfloat alpha = 1.0;
} MonochromeOpenGLVertex; } MonochromeOpenGLVertex;
#pragma pack(pop) #pragma pack(pop)

File diff suppressed because it is too large Load Diff

View File

@ -1,757 +0,0 @@
#ifndef DUST3D_APPLICATION_SKELETON_DOCUMENT_H_
#define DUST3D_APPLICATION_SKELETON_DOCUMENT_H_
#include "debug.h"
#include "mesh_generator.h"
#include "model_mesh.h"
#include "theme.h"
#include <QByteArray>
#include <QDebug>
#include <QImage>
#include <QObject>
#include <QPixmap>
#include <QString>
#include <QVector3D>
#include <cmath>
#include <dust3d/base/combine_mode.h>
#include <dust3d/base/cut_face.h>
#include <dust3d/base/part_base.h>
#include <dust3d/base/part_target.h>
#include <dust3d/base/uuid.h>
class SkeletonNode {
public:
SkeletonNode(const dust3d::Uuid& withId = dust3d::Uuid())
: radius(0)
, cutRotation(0.0)
, cutFace(dust3d::CutFace::Quad)
, hasCutFaceSettings(false)
, m_x(0)
, m_y(0)
, m_z(0)
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
void setRadius(float toRadius)
{
if (toRadius < MeshGenerator::m_minimalRadius)
toRadius = MeshGenerator::m_minimalRadius;
else if (toRadius > 1)
toRadius = 1;
radius = toRadius;
}
void setCutRotation(float toRotation)
{
if (toRotation < -1)
toRotation = -1;
else if (toRotation > 1)
toRotation = 1;
cutRotation = toRotation;
hasCutFaceSettings = true;
}
void setCutFace(dust3d::CutFace face)
{
cutFace = face;
cutFaceLinkedId = dust3d::Uuid();
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 partId;
QString name;
float radius;
float cutRotation;
dust3d::CutFace cutFace;
dust3d::Uuid cutFaceLinkedId;
bool hasCutFaceSettings;
std::vector<dust3d::Uuid> edgeIds;
private:
float m_x;
float m_y;
float m_z;
};
class SkeletonEdge {
public:
SkeletonEdge(const dust3d::Uuid& withId = dust3d::Uuid())
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
}
dust3d::Uuid id;
dust3d::Uuid partId;
QString name;
std::vector<dust3d::Uuid> nodeIds;
dust3d::Uuid neighborOf(dust3d::Uuid nodeId) const
{
if (nodeIds.size() != 2)
return dust3d::Uuid();
return nodeIds[0] == nodeId ? nodeIds[1] : nodeIds[0];
}
};
class SkeletonPart {
public:
dust3d::Uuid id;
QString name;
bool visible;
bool locked;
bool subdived;
bool disabled;
bool xMirrored;
dust3d::PartBase base;
float deformThickness;
float deformWidth;
bool deformUnified;
bool rounded;
bool chamfered;
QColor color;
bool hasColor;
dust3d::Uuid componentId;
std::vector<dust3d::Uuid> nodeIds;
bool dirty;
float cutRotation;
dust3d::CutFace cutFace;
dust3d::Uuid cutFaceLinkedId;
dust3d::Uuid materialId;
dust3d::PartTarget target;
float colorSolubility;
float metalness;
float roughness;
float hollowThickness;
bool countershaded;
bool smooth;
SkeletonPart(const dust3d::Uuid& withId = dust3d::Uuid())
: visible(true)
, locked(false)
, subdived(false)
, disabled(false)
, xMirrored(false)
, base(dust3d::PartBase::Average)
, 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 hasPolyFunction() const
{
return dust3d::PartTarget::Model == target;
}
bool hasSmoothFunction() const
{
return dust3d::PartTarget::Model == target;
}
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 materialAdjusted() const
{
return !materialId.isNull();
}
bool isEditVisible() const
{
return visible && !disabled;
}
void copyAttributes(const SkeletonPart& other)
{
visible = other.visible;
locked = other.locked;
subdived = other.subdived;
disabled = other.disabled;
xMirrored = other.xMirrored;
base = other.base;
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;
materialId = other.materialId;
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:
Q_DISABLE_COPY(SkeletonPart);
};
enum class SkeletonDocumentEditMode {
Add = 0,
Select,
Paint,
Drag,
ZoomIn,
ZoomOut
};
enum class SkeletonProfile {
Unknown = 0,
Main,
Side
};
class SkeletonComponent {
public:
SkeletonComponent()
{
}
SkeletonComponent(const dust3d::Uuid& withId, const QString& linkData = QString(), const QString& linkDataType = QString())
{
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
if (!linkData.isEmpty()) {
if ("partId" == linkDataType) {
linkToPartId = dust3d::Uuid(linkData.toUtf8().constData());
}
}
}
dust3d::Uuid id;
QString name;
dust3d::Uuid linkToPartId;
dust3d::Uuid parentId;
bool expanded = true;
dust3d::CombineMode combineMode = dust3d::CombineMode::Normal;
bool dirty = true;
std::vector<dust3d::Uuid> childrenIds;
bool isPreviewMeshObsolete = false;
std::unique_ptr<QImage> previewImage;
bool isPreviewImageDecorationObsolete = false;
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:
std::unique_ptr<ModelMesh> m_previewMesh;
std::set<dust3d::Uuid> m_childrenIdSet;
};
class SkeletonDocument : public QObject {
Q_OBJECT
signals:
void partAdded(dust3d::Uuid partId);
void nodeAdded(dust3d::Uuid nodeId);
void edgeAdded(dust3d::Uuid edgeId);
void partRemoved(dust3d::Uuid partId);
void partLockStateChanged(dust3d::Uuid partId);
void partVisibleStateChanged(dust3d::Uuid partId);
void partDisableStateChanged(dust3d::Uuid partId);
void componentNameChanged(dust3d::Uuid componentId);
void componentChildrenChanged(dust3d::Uuid componentId);
void componentRemoved(dust3d::Uuid componentId);
void componentAdded(dust3d::Uuid componentId);
void componentExpandStateChanged(dust3d::Uuid componentId);
void componentPreviewMeshChanged(const dust3d::Uuid& componentId);
void componentPreviewPixmapChanged(const dust3d::Uuid& componentId);
void nodeRemoved(dust3d::Uuid nodeId);
void edgeRemoved(dust3d::Uuid edgeId);
void nodeRadiusChanged(dust3d::Uuid nodeId);
void nodeOriginChanged(dust3d::Uuid nodeId);
void edgeReversed(dust3d::Uuid edgeId);
void originChanged();
void skeletonChanged();
void optionsChanged();
void xlockStateChanged();
void ylockStateChanged();
void zlockStateChanged();
void radiusLockStateChanged();
public:
SkeletonDocumentEditMode editMode = SkeletonDocumentEditMode::Select;
bool xlocked = false;
bool ylocked = false;
bool zlocked = false;
bool radiusLocked = false;
QImage turnaround;
QByteArray turnaroundPngByteArray;
std::map<dust3d::Uuid, SkeletonPart> partMap;
std::map<dust3d::Uuid, SkeletonNode> nodeMap;
std::map<dust3d::Uuid, SkeletonEdge> edgeMap;
std::map<dust3d::Uuid, SkeletonComponent> componentMap;
SkeletonComponent rootComponent;
const SkeletonNode* findNode(dust3d::Uuid nodeId) const;
const SkeletonEdge* findEdge(dust3d::Uuid edgeId) const;
const SkeletonPart* findPart(dust3d::Uuid partId) const;
const SkeletonEdge* findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const;
void findAllNeighbors(dust3d::Uuid nodeId, std::set<dust3d::Uuid>& neighbors) const;
bool isNodeConnectable(dust3d::Uuid nodeId) const;
const SkeletonComponent* findComponent(dust3d::Uuid componentId) const;
const SkeletonComponent* findComponentParent(dust3d::Uuid componentId) const;
dust3d::Uuid findComponentParentId(dust3d::Uuid componentId) const;
void collectComponentDescendantParts(dust3d::Uuid componentId, std::vector<dust3d::Uuid>& partIds) const;
void collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector<dust3d::Uuid>& componentIds) const;
void setComponentPreviewMesh(const dust3d::Uuid& componentId, std::unique_ptr<ModelMesh> mesh);
void setComponentPreviewImage(const dust3d::Uuid& componentId, std::unique_ptr<QImage> image);
void resetDirtyFlags();
void markAllDirty();
virtual bool undoable() const = 0;
virtual bool redoable() const = 0;
virtual bool hasPastableNodesInClipboard() const = 0;
virtual bool originSettled() const = 0;
virtual bool isNodeEditable(dust3d::Uuid nodeId) const = 0;
virtual bool isEdgeEditable(dust3d::Uuid edgeId) const = 0;
virtual bool isNodeDeactivated(dust3d::Uuid nodeId) const
{
(void)nodeId;
return false;
};
virtual bool isEdgeDeactivated(dust3d::Uuid edgeId) const
{
(void)edgeId;
return false;
};
virtual void copyNodes(std::set<dust3d::Uuid> nodeIdSet) const = 0;
float getOriginX(bool rotated = false) const
{
if (rotated)
return m_originY;
return m_originX;
}
float getOriginY(bool rotated = false) const
{
if (rotated)
return m_originX;
return m_originY;
}
float getOriginZ(bool rotated = false) const
{
(void)rotated;
return m_originZ;
}
void setOriginX(float originX)
{
m_originX = originX;
}
void setOriginY(float originY)
{
m_originY = originY;
}
void setOriginZ(float originZ)
{
m_originZ = originZ;
}
void addOriginX(float originX)
{
m_originX += originX;
}
void addOriginY(float originY)
{
m_originY += originY;
}
void addOriginZ(float originZ)
{
m_originZ += originZ;
}
public slots:
virtual void undo() = 0;
virtual void redo() = 0;
virtual void paste() = 0;
void removeNode(dust3d::Uuid nodeId);
void removeEdge(dust3d::Uuid edgeId);
void removePart(dust3d::Uuid partId);
void addNodeWithId(dust3d::Uuid nodeId, float x, float y, float z, float radius, dust3d::Uuid fromNodeId);
void addNode(float x, float y, float z, float radius, dust3d::Uuid fromNodeId);
void scaleNodeByAddRadius(dust3d::Uuid nodeId, float amount);
void moveNodeBy(dust3d::Uuid nodeId, float x, float y, float z);
void setNodeOrigin(dust3d::Uuid nodeId, float x, float y, float z);
void setNodeRadius(dust3d::Uuid nodeId, float radius);
void switchNodeXZ(dust3d::Uuid nodeId);
void moveOriginBy(float x, float y, float z);
void addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId);
void moveComponentUp(dust3d::Uuid componentId);
void moveComponentDown(dust3d::Uuid componentId);
void moveComponentToTop(dust3d::Uuid componentId);
void moveComponentToBottom(dust3d::Uuid componentId);
void renameComponent(dust3d::Uuid componentId, QString name);
void removeComponent(dust3d::Uuid componentId);
void addComponent(dust3d::Uuid parentId);
void moveComponent(dust3d::Uuid componentId, dust3d::Uuid toParentId);
void setCurrentCanvasComponentId(dust3d::Uuid componentId);
void groupComponents(const std::vector<dust3d::Uuid>& componentIds);
void ungroupComponent(const dust3d::Uuid& componentId);
void createNewChildComponent(dust3d::Uuid parentComponentId);
void setComponentExpandState(dust3d::Uuid componentId, bool expanded);
void hideOtherComponents(dust3d::Uuid componentId);
void lockOtherComponents(dust3d::Uuid componentId);
void hideAllComponents();
void showAllComponents();
void showOrHideAllComponents();
void collapseAllComponents();
void expandAllComponents();
void lockAllComponents();
void unlockAllComponents();
void hideDescendantComponents(dust3d::Uuid componentId);
void showDescendantComponents(dust3d::Uuid componentId);
void lockDescendantComponents(dust3d::Uuid componentId);
void unlockDescendantComponents(dust3d::Uuid componentId);
void setComponentPreviewPixmap(const dust3d::Uuid& componentId, const QPixmap& pixmap);
void setPartLockState(dust3d::Uuid partId, bool locked);
void setPartVisibleState(dust3d::Uuid partId, bool visible);
void setPartDisableState(dust3d::Uuid partId, bool disabled);
void enableAllPositionRelatedLocks();
void disableAllPositionRelatedLocks();
bool isPartReadonly(dust3d::Uuid partId) const;
void breakEdge(dust3d::Uuid edgeId);
void reduceNode(dust3d::Uuid nodeId);
void reverseEdge(dust3d::Uuid edgeId);
void setXlockState(bool locked);
void setYlockState(bool locked);
void setZlockState(bool locked);
void setRadiusLockState(bool locked);
private:
float m_originX = 0;
float m_originY = 0;
float m_originZ = 0;
dust3d::Uuid m_currentCanvasComponentId;
bool m_allPositionRelatedLocksEnabled = true;
void splitPartByNode(std::vector<std::vector<dust3d::Uuid>>* groups, dust3d::Uuid nodeId);
void joinNodeAndNeiborsToGroup(std::vector<dust3d::Uuid>* group, dust3d::Uuid nodeId, std::set<dust3d::Uuid>* visitMap, dust3d::Uuid noUseEdgeId = dust3d::Uuid());
void splitPartByEdge(std::vector<std::vector<dust3d::Uuid>>* groups, dust3d::Uuid edgeId);
void removePartDontCareComponent(dust3d::Uuid partId);
void addPartToComponent(dust3d::Uuid partId, dust3d::Uuid componentId);
bool isDescendantComponent(dust3d::Uuid componentId, dust3d::Uuid suspiciousId);
void removeComponentRecursively(dust3d::Uuid componentId);
void updateLinkedPart(dust3d::Uuid oldPartId, dust3d::Uuid newPartId);
dust3d::Uuid createNode(dust3d::Uuid nodeId, float x, float y, float z, float radius, dust3d::Uuid fromNodeId);
};
#endif

View File

@ -13,7 +13,7 @@
#include <cmath> #include <cmath>
#include <queue> #include <queue>
SkeletonGraphicsWidget::SkeletonGraphicsWidget(const SkeletonDocument* document) SkeletonGraphicsWidget::SkeletonGraphicsWidget(const Document* document)
: m_document(document) : m_document(document)
{ {
setRenderHint(QPainter::Antialiasing, false); setRenderHint(QPainter::Antialiasing, false);
@ -101,20 +101,20 @@ void SkeletonGraphicsWidget::shortcutEscape()
if (!isVisible()) if (!isVisible())
return; return;
if (SkeletonDocumentEditMode::Add == m_document->editMode || SkeletonDocumentEditMode::Paint == m_document->editMode) { if (DocumentEditMode::Add == m_document->editMode || DocumentEditMode::Paint == m_document->editMode) {
emit setEditMode(SkeletonDocumentEditMode::Select); emit setEditMode(DocumentEditMode::Select);
return; return;
} }
} }
void SkeletonGraphicsWidget::showContextMenu(const QPoint& pos) void SkeletonGraphicsWidget::showContextMenu(const QPoint& pos)
{ {
if (SkeletonDocumentEditMode::Add == m_document->editMode) { if (DocumentEditMode::Add == m_document->editMode) {
emit setEditMode(SkeletonDocumentEditMode::Select); emit setEditMode(DocumentEditMode::Select);
return; return;
} }
if (SkeletonDocumentEditMode::Select != m_document->editMode) { if (DocumentEditMode::Select != m_document->editMode) {
return; return;
} }
@ -122,19 +122,19 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint& pos)
QAction addAction(tr("Add..."), this); QAction addAction(tr("Add..."), this);
connect(&addAction, &QAction::triggered, [=]() { connect(&addAction, &QAction::triggered, [=]() {
emit setEditMode(SkeletonDocumentEditMode::Add); emit setEditMode(DocumentEditMode::Add);
}); });
contextMenu.addAction(&addAction); contextMenu.addAction(&addAction);
QAction undoAction(tr("Undo"), this); QAction undoAction(tr("Undo"), this);
if (m_document->undoable()) { if (m_document->undoable()) {
connect(&undoAction, &QAction::triggered, m_document, &SkeletonDocument::undo); connect(&undoAction, &QAction::triggered, m_document, &Document::undo);
contextMenu.addAction(&undoAction); contextMenu.addAction(&undoAction);
} }
QAction redoAction(tr("Redo"), this); QAction redoAction(tr("Redo"), this);
if (m_document->redoable()) { if (m_document->redoable()) {
connect(&redoAction, &QAction::triggered, m_document, &SkeletonDocument::redo); connect(&redoAction, &QAction::triggered, m_document, &Document::redo);
contextMenu.addAction(&redoAction); contextMenu.addAction(&redoAction);
} }
@ -182,7 +182,7 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint& pos)
QAction pasteAction(tr("Paste"), this); QAction pasteAction(tr("Paste"), this);
if (m_document->hasPastableNodesInClipboard()) { if (m_document->hasPastableNodesInClipboard()) {
connect(&pasteAction, &QAction::triggered, m_document, &SkeletonDocument::paste); connect(&pasteAction, &QAction::triggered, m_document, &Document::paste);
contextMenu.addAction(&pasteAction); contextMenu.addAction(&pasteAction);
} }
@ -657,7 +657,7 @@ const QImage* SkeletonGraphicsWidget::loadedTurnaroundImage() const
void SkeletonGraphicsWidget::updateCursor() void SkeletonGraphicsWidget::updateCursor()
{ {
if (SkeletonDocumentEditMode::Add != m_document->editMode) { if (DocumentEditMode::Add != m_document->editMode) {
m_cursorEdgeItem->hide(); m_cursorEdgeItem->hide();
m_cursorNodeItem->hide(); m_cursorNodeItem->hide();
} }
@ -670,7 +670,7 @@ void SkeletonGraphicsWidget::updateCursor()
void SkeletonGraphicsWidget::editModeChanged() void SkeletonGraphicsWidget::editModeChanged()
{ {
updateCursor(); updateCursor();
if (SkeletonDocumentEditMode::Add == m_document->editMode) { if (DocumentEditMode::Add == m_document->editMode) {
SkeletonGraphicsNodeItem* choosenNodeItem = nullptr; SkeletonGraphicsNodeItem* choosenNodeItem = nullptr;
if (!m_rangeSelectionSet.empty()) { if (!m_rangeSelectionSet.empty()) {
std::set<SkeletonGraphicsNodeItem*> nodeItems; std::set<SkeletonGraphicsNodeItem*> nodeItems;
@ -771,7 +771,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent* event)
return true; return true;
} }
if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode) {
if (m_rangeSelectionStarted) { if (m_rangeSelectionStarted) {
QPointF mouseScenePos = mouseEventScenePos(event); QPointF mouseScenePos = mouseEventScenePos(event);
m_selectionItem->updateRange(m_rangeSelectionStartPos, mouseScenePos); m_selectionItem->updateRange(m_rangeSelectionStartPos, mouseScenePos);
@ -782,7 +782,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent* event)
} }
} }
if (SkeletonDocumentEditMode::Select == m_document->editMode || SkeletonDocumentEditMode::Add == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode || DocumentEditMode::Add == m_document->editMode) {
// //
// > For overlapping nodes, you can make it a bit better by selecting the node center nearest the mouse, rather than simply checking against the wider circle. // > For overlapping nodes, you can make it a bit better by selecting the node center nearest the mouse, rather than simply checking against the wider circle.
@ -872,7 +872,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent* event)
hoverPart(hoveredPartId); hoverPart(hoveredPartId);
} }
if (SkeletonDocumentEditMode::Add == m_document->editMode) { if (DocumentEditMode::Add == m_document->editMode) {
QPointF mouseScenePos = mouseEventScenePos(event); QPointF mouseScenePos = mouseEventScenePos(event);
m_cursorNodeItem->setOrigin(mouseScenePos); m_cursorNodeItem->setOrigin(mouseScenePos);
if (m_addFromNodeItem) { if (m_addFromNodeItem) {
@ -889,7 +889,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent* event)
return true; return true;
} }
if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode) {
if (m_moveStarted) { if (m_moveStarted) {
if (m_checkedOriginItem) { if (m_checkedOriginItem) {
QPointF mouseScenePos = mouseEventScenePos(event); QPointF mouseScenePos = mouseEventScenePos(event);
@ -1200,12 +1200,12 @@ bool SkeletonGraphicsWidget::wheel(QWheelEvent* event)
delta = 1; delta = 1;
else else
delta = -1; delta = -1;
if (SkeletonDocumentEditMode::Add == m_document->editMode) { if (DocumentEditMode::Add == m_document->editMode) {
if (m_cursorNodeItem->isVisible()) { if (m_cursorNodeItem->isVisible()) {
m_cursorNodeItem->setRadius(m_cursorNodeItem->radius() + delta); m_cursorNodeItem->setRadius(m_cursorNodeItem->radius() + delta);
return true; return true;
} }
} else if (SkeletonDocumentEditMode::Select == m_document->editMode) { } else if (DocumentEditMode::Select == m_document->editMode) {
if (!m_rangeSelectionSet.empty()) { if (!m_rangeSelectionSet.empty()) {
if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) { if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) {
scaleSelected(delta); scaleSelected(delta);
@ -1347,13 +1347,13 @@ QPointF SkeletonGraphicsWidget::mouseEventScenePos(QMouseEvent* event)
bool SkeletonGraphicsWidget::mousePress(QMouseEvent* event) bool SkeletonGraphicsWidget::mousePress(QMouseEvent* event)
{ {
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
if (SkeletonDocumentEditMode::ZoomIn == m_document->editMode) { if (DocumentEditMode::ZoomIn == m_document->editMode) {
ViewportAnchor lastAnchor = transformationAnchor(); ViewportAnchor lastAnchor = transformationAnchor();
setTransformationAnchor(QGraphicsView::AnchorUnderMouse); setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
scale(1.25, 1.25); scale(1.25, 1.25);
setTransformationAnchor(lastAnchor); setTransformationAnchor(lastAnchor);
return true; return true;
} else if (SkeletonDocumentEditMode::ZoomOut == m_document->editMode) { } else if (DocumentEditMode::ZoomOut == m_document->editMode) {
ViewportAnchor lastAnchor = transformationAnchor(); ViewportAnchor lastAnchor = transformationAnchor();
setTransformationAnchor(QGraphicsView::AnchorUnderMouse); setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
scale(0.8, 0.8); scale(0.8, 0.8);
@ -1363,20 +1363,20 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent* event)
// setTransform(QTransform()); // setTransform(QTransform());
//} //}
return true; return true;
} else if (SkeletonDocumentEditMode::Drag == m_document->editMode) { } else if (DocumentEditMode::Drag == m_document->editMode) {
if (!m_dragStarted) { if (!m_dragStarted) {
m_lastGlobalPos = event->globalPos(); m_lastGlobalPos = event->globalPos();
m_dragStarted = true; m_dragStarted = true;
updateCursor(); updateCursor();
} }
} else if (SkeletonDocumentEditMode::Add == m_document->editMode) { } else if (DocumentEditMode::Add == m_document->editMode) {
if (m_cursorNodeItem->isVisible()) { if (m_cursorNodeItem->isVisible()) {
if (m_addFromNodeItem) { if (m_addFromNodeItem) {
if (m_hoveredNodeItem && m_addFromNodeItem && m_hoveredNodeItem != m_addFromNodeItem && m_hoveredNodeItem->profile() == m_addFromNodeItem->profile() && !m_document->findEdgeByNodes(m_addFromNodeItem->id(), m_hoveredNodeItem->id()) && m_document->isNodeEditable(m_hoveredNodeItem->id())) { if (m_hoveredNodeItem && m_addFromNodeItem && m_hoveredNodeItem != m_addFromNodeItem && m_hoveredNodeItem->profile() == m_addFromNodeItem->profile() && !m_document->findEdgeByNodes(m_addFromNodeItem->id(), m_hoveredNodeItem->id()) && m_document->isNodeEditable(m_hoveredNodeItem->id())) {
if (m_document->isNodeConnectable(m_hoveredNodeItem->id())) { if (m_document->isNodeConnectable(m_hoveredNodeItem->id())) {
emit addEdge(m_addFromNodeItem->id(), m_hoveredNodeItem->id()); emit addEdge(m_addFromNodeItem->id(), m_hoveredNodeItem->id());
emit groupOperationAdded(); emit groupOperationAdded();
emit setEditMode(SkeletonDocumentEditMode::Select); emit setEditMode(DocumentEditMode::Select);
return true; return true;
} }
} }
@ -1410,7 +1410,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent* event)
emit groupOperationAdded(); emit groupOperationAdded();
return true; return true;
} }
} else if (SkeletonDocumentEditMode::Select == m_document->editMode) { } else if (DocumentEditMode::Select == m_document->editMode) {
bool processed = false; bool processed = false;
if (m_hoveredOriginItem != m_checkedOriginItem) { if (m_hoveredOriginItem != m_checkedOriginItem) {
if (m_checkedOriginItem) { if (m_checkedOriginItem) {
@ -1467,7 +1467,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent* event)
} }
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode) {
if (!m_rangeSelectionStarted) { if (!m_rangeSelectionStarted) {
m_rangeSelectionStartPos = mouseEventScenePos(event); m_rangeSelectionStartPos = mouseEventScenePos(event);
m_rangeSelectionStarted = true; m_rangeSelectionStarted = true;
@ -1644,10 +1644,10 @@ void SkeletonGraphicsWidget::shortcutDelete()
void SkeletonGraphicsWidget::shortcutAddMode() void SkeletonGraphicsWidget::shortcutAddMode()
{ {
if (SkeletonDocumentEditMode::Add == m_document->editMode) { if (DocumentEditMode::Add == m_document->editMode) {
emit setEditMode(SkeletonDocumentEditMode::Select); emit setEditMode(DocumentEditMode::Select);
} else { } else {
emit setEditMode(SkeletonDocumentEditMode::Add); emit setEditMode(DocumentEditMode::Add);
} }
} }
@ -1708,12 +1708,12 @@ void SkeletonGraphicsWidget::shortcutPaste()
void SkeletonGraphicsWidget::shortcutSelectMode() void SkeletonGraphicsWidget::shortcutSelectMode()
{ {
emit setEditMode(SkeletonDocumentEditMode::Select); emit setEditMode(DocumentEditMode::Select);
} }
void SkeletonGraphicsWidget::shortcutPaintMode() void SkeletonGraphicsWidget::shortcutPaintMode()
{ {
emit setEditMode(SkeletonDocumentEditMode::Paint); emit setEditMode(DocumentEditMode::Paint);
} }
void SkeletonGraphicsWidget::shortcutZoomRenderedModelByMinus10() void SkeletonGraphicsWidget::shortcutZoomRenderedModelByMinus10()
@ -1729,10 +1729,10 @@ void SkeletonGraphicsWidget::shortcutZoomSelectedByMinus1()
if (!isVisible()) if (!isVisible())
return; return;
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) { if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
zoomSelected(-1); zoomSelected(-1);
emit groupOperationAdded(); emit groupOperationAdded();
} else if (SkeletonDocumentEditMode::Add == m_document->editMode) { } else if (DocumentEditMode::Add == m_document->editMode) {
if (m_cursorNodeItem->isVisible()) { if (m_cursorNodeItem->isVisible()) {
m_cursorNodeItem->setRadius(m_cursorNodeItem->radius() + -1); m_cursorNodeItem->setRadius(m_cursorNodeItem->radius() + -1);
} }
@ -1752,10 +1752,10 @@ void SkeletonGraphicsWidget::shortcutZoomSelectedBy1()
if (!isVisible()) if (!isVisible())
return; return;
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) { if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
zoomSelected(1); zoomSelected(1);
emit groupOperationAdded(); emit groupOperationAdded();
} else if (SkeletonDocumentEditMode::Add == m_document->editMode) { } else if (DocumentEditMode::Add == m_document->editMode) {
if (m_cursorNodeItem->isVisible()) { if (m_cursorNodeItem->isVisible()) {
m_cursorNodeItem->setRadius(m_cursorNodeItem->radius() + 1); m_cursorNodeItem->setRadius(m_cursorNodeItem->radius() + 1);
} }
@ -1767,7 +1767,7 @@ void SkeletonGraphicsWidget::shortcutRotateSelectedByMinus1()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { if ((DocumentEditMode::Select == m_document->editMode) && hasSelection()) {
rotateSelected(-1); rotateSelected(-1);
emit groupOperationAdded(); emit groupOperationAdded();
} }
@ -1778,7 +1778,7 @@ void SkeletonGraphicsWidget::shortcutRotateSelectedBy1()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { if ((DocumentEditMode::Select == m_document->editMode) && hasSelection()) {
rotateSelected(1); rotateSelected(1);
emit groupOperationAdded(); emit groupOperationAdded();
} }
@ -1789,7 +1789,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToLeft()
if (!isVisible()) if (!isVisible())
return; return;
if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode) {
if (m_checkedOriginItem) { if (m_checkedOriginItem) {
moveCheckedOrigin(-1, 0); moveCheckedOrigin(-1, 0);
emit groupOperationAdded(); emit groupOperationAdded();
@ -1805,7 +1805,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToRight()
if (!isVisible()) if (!isVisible())
return; return;
if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode) {
if (m_checkedOriginItem) { if (m_checkedOriginItem) {
moveCheckedOrigin(1, 0); moveCheckedOrigin(1, 0);
emit groupOperationAdded(); emit groupOperationAdded();
@ -1821,7 +1821,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToUp()
if (!isVisible()) if (!isVisible())
return; return;
if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode) {
if (m_checkedOriginItem) { if (m_checkedOriginItem) {
moveCheckedOrigin(0, -1); moveCheckedOrigin(0, -1);
emit groupOperationAdded(); emit groupOperationAdded();
@ -1837,7 +1837,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToDown()
if (!isVisible()) if (!isVisible())
return; return;
if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode) {
if (m_checkedOriginItem) { if (m_checkedOriginItem) {
moveCheckedOrigin(0, 1); moveCheckedOrigin(0, 1);
emit groupOperationAdded(); emit groupOperationAdded();
@ -1853,7 +1853,7 @@ void SkeletonGraphicsWidget::shortcutScaleSelectedByMinus1()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { if ((DocumentEditMode::Select == m_document->editMode) && hasSelection()) {
scaleSelected(-1); scaleSelected(-1);
emit groupOperationAdded(); emit groupOperationAdded();
} }
@ -1864,7 +1864,7 @@ void SkeletonGraphicsWidget::shortcutScaleSelectedBy1()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { if ((DocumentEditMode::Select == m_document->editMode) && hasSelection()) {
scaleSelected(1); scaleSelected(1);
emit groupOperationAdded(); emit groupOperationAdded();
} }
@ -1875,7 +1875,7 @@ void SkeletonGraphicsWidget::shortcutSwitchProfileOnSelected()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { if ((DocumentEditMode::Select == m_document->editMode) && hasSelection()) {
switchProfileOnRangeSelection(); switchProfileOnRangeSelection();
} }
} }
@ -1885,7 +1885,7 @@ void SkeletonGraphicsWidget::shortcutShowOrHideSelectedPart()
if (!isVisible()) if (!isVisible())
return; return;
if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (DocumentEditMode::Select == m_document->editMode) {
if (!m_lastCheckedPart.isNull()) { if (!m_lastCheckedPart.isNull()) {
const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); const SkeletonPart* part = m_document->findPart(m_lastCheckedPart);
bool partVisible = part && part->visible; bool partVisible = part && part->visible;
@ -1902,7 +1902,7 @@ void SkeletonGraphicsWidget::shortcutEnableOrDisableSelectedPart()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { if ((DocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) {
const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); const SkeletonPart* part = m_document->findPart(m_lastCheckedPart);
bool partDisabled = part && part->disabled; bool partDisabled = part && part->disabled;
emit setPartDisableState(m_lastCheckedPart, !partDisabled); emit setPartDisableState(m_lastCheckedPart, !partDisabled);
@ -1915,7 +1915,7 @@ void SkeletonGraphicsWidget::shortcutLockOrUnlockSelectedPart()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { if ((DocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) {
const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); const SkeletonPart* part = m_document->findPart(m_lastCheckedPart);
bool partLocked = part && part->locked; bool partLocked = part && part->locked;
emit setPartLockState(m_lastCheckedPart, !partLocked); emit setPartLockState(m_lastCheckedPart, !partLocked);
@ -1928,7 +1928,7 @@ void SkeletonGraphicsWidget::shortcutXmirrorOnOrOffSelectedPart()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { if ((DocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) {
const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); const SkeletonPart* part = m_document->findPart(m_lastCheckedPart);
bool partXmirrored = part && part->xMirrored; bool partXmirrored = part && part->xMirrored;
emit setPartXmirrorState(m_lastCheckedPart, !partXmirrored); emit setPartXmirrorState(m_lastCheckedPart, !partXmirrored);
@ -1941,7 +1941,7 @@ void SkeletonGraphicsWidget::shortcutSubdivedOrNotSelectedPart()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { if ((DocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) {
const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); const SkeletonPart* part = m_document->findPart(m_lastCheckedPart);
bool partSubdived = part && part->subdived; bool partSubdived = part && part->subdived;
emit setPartSubdivState(m_lastCheckedPart, !partSubdived); emit setPartSubdivState(m_lastCheckedPart, !partSubdived);
@ -1954,7 +1954,7 @@ void SkeletonGraphicsWidget::shortcutChamferedOrNotSelectedPart()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { if ((DocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) {
const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); const SkeletonPart* part = m_document->findPart(m_lastCheckedPart);
bool partChamfered = part && part->chamfered; bool partChamfered = part && part->chamfered;
emit setPartChamferState(m_lastCheckedPart, !partChamfered); emit setPartChamferState(m_lastCheckedPart, !partChamfered);
@ -1975,7 +1975,7 @@ void SkeletonGraphicsWidget::shortcutRoundEndOrNotSelectedPart()
if (!isVisible()) if (!isVisible())
return; return;
if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { if ((DocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) {
const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); const SkeletonPart* part = m_document->findPart(m_lastCheckedPart);
bool partRounded = part && part->rounded; bool partRounded = part && part->rounded;
emit setPartRoundState(m_lastCheckedPart, !partRounded); emit setPartRoundState(m_lastCheckedPart, !partRounded);
@ -1986,10 +1986,10 @@ void SkeletonGraphicsWidget::shortcutRoundEndOrNotSelectedPart()
bool SkeletonGraphicsWidget::keyPress(QKeyEvent* event) bool SkeletonGraphicsWidget::keyPress(QKeyEvent* event)
{ {
if (event->key() == Qt::Key_Space) { if (event->key() == Qt::Key_Space) {
if (SkeletonDocumentEditMode::ZoomIn == m_document->editMode || SkeletonDocumentEditMode::ZoomOut == m_document->editMode || SkeletonDocumentEditMode::Select == m_document->editMode || SkeletonDocumentEditMode::Add == m_document->editMode) { if (DocumentEditMode::ZoomIn == m_document->editMode || DocumentEditMode::ZoomOut == m_document->editMode || DocumentEditMode::Select == m_document->editMode || DocumentEditMode::Add == m_document->editMode) {
m_inTempDragMode = true; m_inTempDragMode = true;
m_modeBeforeEnterTempDragMode = m_document->editMode; m_modeBeforeEnterTempDragMode = m_document->editMode;
emit setEditMode(SkeletonDocumentEditMode::Drag); emit setEditMode(DocumentEditMode::Drag);
return true; return true;
} }
} }
@ -2044,10 +2044,6 @@ void SkeletonGraphicsWidget::nodeAdded(dust3d::Uuid nodeId)
sideProfileItem->setRadius(sceneRadiusFromUnified(node->radius)); sideProfileItem->setRadius(sceneRadiusFromUnified(node->radius));
mainProfileItem->setId(nodeId); mainProfileItem->setId(nodeId);
sideProfileItem->setId(nodeId); sideProfileItem->setId(nodeId);
if (m_document->isNodeDeactivated(nodeId)) {
mainProfileItem->setDeactivated(true);
sideProfileItem->setDeactivated(true);
}
scene()->addItem(mainProfileItem); scene()->addItem(mainProfileItem);
scene()->addItem(sideProfileItem); scene()->addItem(sideProfileItem);
nodeItemMap[nodeId] = std::make_pair(mainProfileItem, sideProfileItem); nodeItemMap[nodeId] = std::make_pair(mainProfileItem, sideProfileItem);
@ -2115,10 +2111,6 @@ void SkeletonGraphicsWidget::edgeAdded(dust3d::Uuid edgeId)
sideProfileEdgeItem->setId(edgeId); sideProfileEdgeItem->setId(edgeId);
mainProfileEdgeItem->setEndpoints(fromIt->second.first, toIt->second.first); mainProfileEdgeItem->setEndpoints(fromIt->second.first, toIt->second.first);
sideProfileEdgeItem->setEndpoints(fromIt->second.second, toIt->second.second); sideProfileEdgeItem->setEndpoints(fromIt->second.second, toIt->second.second);
if (m_document->isNodeDeactivated(edgeId)) {
mainProfileEdgeItem->setDeactivated(true);
sideProfileEdgeItem->setDeactivated(true);
}
scene()->addItem(mainProfileEdgeItem); scene()->addItem(mainProfileEdgeItem);
scene()->addItem(sideProfileEdgeItem); scene()->addItem(sideProfileEdgeItem);
edgeItemMap[edgeId] = std::make_pair(mainProfileEdgeItem, sideProfileEdgeItem); edgeItemMap[edgeId] = std::make_pair(mainProfileEdgeItem, sideProfileEdgeItem);

View File

@ -1,8 +1,8 @@
#ifndef DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_ #ifndef DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_
#define DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_ #define DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_
#include "document.h"
#include "model_widget.h" #include "model_widget.h"
#include "skeleton_document.h"
#include "skeleton_ik_mover.h" #include "skeleton_ik_mover.h"
#include "theme.h" #include "theme.h"
#include "turnaround_loader.h" #include "turnaround_loader.h"
@ -398,7 +398,7 @@ signals:
void moveNodeBy(dust3d::Uuid nodeId, float x, float y, float z); void moveNodeBy(dust3d::Uuid nodeId, float x, float y, float z);
void removeNode(dust3d::Uuid nodeId); void removeNode(dust3d::Uuid nodeId);
void removePart(dust3d::Uuid partId); void removePart(dust3d::Uuid partId);
void setEditMode(SkeletonDocumentEditMode mode); void setEditMode(DocumentEditMode mode);
void removeEdge(dust3d::Uuid edgeId); void removeEdge(dust3d::Uuid edgeId);
void addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId); void addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId);
void cursorChanged(); void cursorChanged();
@ -442,7 +442,7 @@ signals:
void loadedTurnaroundImageChanged(); void loadedTurnaroundImageChanged();
public: public:
SkeletonGraphicsWidget(const SkeletonDocument* document); SkeletonGraphicsWidget(const Document* document);
std::map<dust3d::Uuid, std::pair<SkeletonGraphicsNodeItem*, SkeletonGraphicsNodeItem*>> nodeItemMap; std::map<dust3d::Uuid, std::pair<SkeletonGraphicsNodeItem*, SkeletonGraphicsNodeItem*>> nodeItemMap;
std::map<dust3d::Uuid, std::pair<SkeletonGraphicsEdgeItem*, SkeletonGraphicsEdgeItem*>> edgeItemMap; std::map<dust3d::Uuid, std::pair<SkeletonGraphicsEdgeItem*, SkeletonGraphicsEdgeItem*>> edgeItemMap;
bool mouseMove(QMouseEvent* event); bool mouseMove(QMouseEvent* event);
@ -600,7 +600,7 @@ private:
bool isFloatEqual(float a, float b); bool isFloatEqual(float a, float b);
private: private:
const SkeletonDocument* m_document = nullptr; const Document* m_document = nullptr;
QGraphicsPixmapItem* m_backgroundItem = nullptr; QGraphicsPixmapItem* m_backgroundItem = nullptr;
bool m_turnaroundChanged = false; bool m_turnaroundChanged = false;
TurnaroundLoader* m_turnaroundLoader = nullptr; TurnaroundLoader* m_turnaroundLoader = nullptr;
@ -629,7 +629,7 @@ private:
bool m_eventForwardingToModelWidget = false; bool m_eventForwardingToModelWidget = false;
ModelWidget* m_modelWidget = nullptr; ModelWidget* m_modelWidget = nullptr;
bool m_inTempDragMode = false; bool m_inTempDragMode = false;
SkeletonDocumentEditMode m_modeBeforeEnterTempDragMode = SkeletonDocumentEditMode::Select; DocumentEditMode m_modeBeforeEnterTempDragMode = DocumentEditMode::Select;
float m_turnaroundOpacity = 0.25f; float m_turnaroundOpacity = 0.25f;
bool m_rotated = false; bool m_rotated = false;
QImage* m_backgroundImage = nullptr; QImage* m_backgroundImage = nullptr;

View File

@ -1,20 +0,0 @@
#include "tube_uv_preview_image_generator.h"
const size_t TubeUvPreviewImageGenerator::m_uvImageSize = 1024;
TubeUvPreviewImageGenerator::TubeUvPreviewImageGenerator(std::vector<std::vector<dust3d::Vector2>>&& faceUvs)
: m_faceUvs(faceUvs)
{
}
void TubeUvPreviewImageGenerator::generate()
{
m_previewImage = std::make_unique<QImage>(m_uvImageSize, m_uvImageSize, QImage::Format_ARGB32);
// TODO:
}
void TubeUvPreviewImageGenerator::process()
{
generate();
emit finished();
}

View File

@ -0,0 +1,20 @@
#include "uv_preview_image_generator.h"
const size_t UvPreviewImageGenerator::m_uvImageSize = 1024;
UvPreviewImageGenerator::UvPreviewImageGenerator(std::vector<std::vector<dust3d::Vector2>>&& faceUvs)
: m_faceUvs(faceUvs)
{
}
void UvPreviewImageGenerator::generate()
{
m_previewImage = std::make_unique<QImage>(m_uvImageSize, m_uvImageSize, QImage::Format_ARGB32);
// TODO:
}
void UvPreviewImageGenerator::process()
{
generate();
emit finished();
}

View File

@ -1,5 +1,5 @@
#ifndef DUST3D_APPLICATION_TUBE_UV_PREVIEW_IMAGE_GENERATOR_H_ #ifndef DUST3D_APPLICATION_TUBE_PREVIEW_IMAGE_GENERATOR_H_
#define DUST3D_APPLICATION_TUBE_UV_PREVIEW_IMAGE_GENERATOR_H_ #define DUST3D_APPLICATION_TUBE_PREVIEW_IMAGE_GENERATOR_H_
#include <QImage> #include <QImage>
#include <QObject> #include <QObject>
@ -7,10 +7,10 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
class TubeUvPreviewImageGenerator : public QObject { class UvPreviewImageGenerator : public QObject {
Q_OBJECT Q_OBJECT
public: public:
TubeUvPreviewImageGenerator(std::vector<std::vector<dust3d::Vector2>>&& faceUvs); UvPreviewImageGenerator(std::vector<std::vector<dust3d::Vector2>>&& faceUvs);
void generate(); void generate();
signals: signals:
void finished(); void finished();

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2016-2021 Jeremy HU <jeremy-at-dust3d dot org>. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <dust3d/base/part_base.h>
namespace dust3d {
IMPL_PartBaseFromString
IMPL_PartBaseToString
IMPL_PartBaseToDispName
}

View File

@ -1,96 +0,0 @@
/*
* Copyright (c) 2016-2021 Jeremy HU <jeremy-at-dust3d dot org>. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef DUST3D_BASE_PART_BASE_H_
#define DUST3D_BASE_PART_BASE_H_
#include <string>
namespace dust3d {
enum class PartBase {
XYZ = 0,
Average,
YZ,
XY,
ZX,
Count
};
PartBase PartBaseFromString(const char* baseString);
#define IMPL_PartBaseFromString \
PartBase PartBaseFromString(const char* baseString) \
{ \
std::string base = baseString; \
if (base == "XYZ") \
return PartBase::XYZ; \
if (base == "Average") \
return PartBase::Average; \
if (base == "YZ") \
return PartBase::YZ; \
if (base == "XY") \
return PartBase::XY; \
if (base == "ZX") \
return PartBase::ZX; \
return PartBase::XYZ; \
}
const char* PartBaseToString(PartBase base);
#define IMPL_PartBaseToString \
const char* PartBaseToString(PartBase base) \
{ \
switch (base) { \
case PartBase::XYZ: \
return "XYZ"; \
case PartBase::Average: \
return "Average"; \
case PartBase::YZ: \
return "YZ"; \
case PartBase::XY: \
return "XY"; \
case PartBase::ZX: \
return "ZX"; \
default: \
return "XYZ"; \
} \
}
std::string PartBaseToDispName(PartBase base);
#define IMPL_PartBaseToDispName \
std::string PartBaseToDispName(PartBase base) \
{ \
switch (base) { \
case PartBase::XYZ: \
return std::string("Dynamic"); \
case PartBase::Average: \
return std::string("Average"); \
case PartBase::YZ: \
return std::string("Side Plane"); \
case PartBase::XY: \
return std::string("Front Plane"); \
case PartBase::ZX: \
return std::string("Top Plane"); \
default: \
return std::string("Dynamic"); \
} \
}
}
#endif

View File

@ -21,7 +21,6 @@
*/ */
#include <dust3d/base/cut_face.h> #include <dust3d/base/cut_face.h>
#include <dust3d/base/part_base.h>
#include <dust3d/base/part_target.h> #include <dust3d/base/part_target.h>
#include <dust3d/base/snapshot_xml.h> #include <dust3d/base/snapshot_xml.h>
#include <dust3d/base/string.h> #include <dust3d/base/string.h>
@ -591,7 +590,6 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combinePartMesh(const std::st
float cutRotation = 0.0; float cutRotation = 0.0;
float hollowThickness = 0.0; float hollowThickness = 0.0;
auto target = PartTargetFromString(String::valueOrEmpty(part, "target").c_str()); auto target = PartTargetFromString(String::valueOrEmpty(part, "target").c_str());
auto base = PartBaseFromString(String::valueOrEmpty(part, "base").c_str());
std::string searchPartIdString = __mirrorFromPartId.empty() ? partIdString : __mirrorFromPartId; std::string searchPartIdString = __mirrorFromPartId.empty() ? partIdString : __mirrorFromPartId;