Clean up
parent
aae9d3fca5
commit
1bd1d58069
|
@ -394,9 +394,6 @@ HEADERS += src/proceduralanimation.h
|
|||
SOURCES += src/boundingboxmesh.cpp
|
||||
HEADERS += src/boundingboxmesh.h
|
||||
|
||||
SOURCES += src/regionfiller.cpp
|
||||
HEADERS += src/regionfiller.h
|
||||
|
||||
SOURCES += src/meshwrapper.cpp
|
||||
HEADERS += src/meshwrapper.h
|
||||
|
||||
|
|
1364
src/document.cpp
1364
src/document.cpp
File diff suppressed because it is too large
Load Diff
338
src/document.h
338
src/document.h
|
@ -40,153 +40,6 @@ public:
|
|||
Snapshot snapshot;
|
||||
};
|
||||
|
||||
class Component
|
||||
{
|
||||
public:
|
||||
Component()
|
||||
{
|
||||
}
|
||||
Component(const QUuid &withId, const QString &linkData=QString(), const QString &linkDataType=QString())
|
||||
{
|
||||
id = withId.isNull() ? QUuid::createUuid() : withId;
|
||||
if (!linkData.isEmpty()) {
|
||||
if ("partId" == linkDataType) {
|
||||
linkToPartId = QUuid(linkData);
|
||||
}
|
||||
}
|
||||
}
|
||||
QUuid id;
|
||||
QString name;
|
||||
QUuid linkToPartId;
|
||||
QUuid parentId;
|
||||
bool expanded = true;
|
||||
CombineMode combineMode = Preferences::instance().componentCombineMode();
|
||||
bool dirty = true;
|
||||
float smoothAll = 0.0;
|
||||
float smoothSeam = 0.0;
|
||||
std::vector<QUuid> childrenIds;
|
||||
QString linkData() const
|
||||
{
|
||||
return linkToPartId.isNull() ? QString() : linkToPartId.toString();
|
||||
}
|
||||
QString linkDataType() const
|
||||
{
|
||||
return linkToPartId.isNull() ? QString() : QString("partId");
|
||||
}
|
||||
void addChild(QUuid childId)
|
||||
{
|
||||
if (m_childrenIdSet.find(childId) != m_childrenIdSet.end())
|
||||
return;
|
||||
m_childrenIdSet.insert(childId);
|
||||
childrenIds.push_back(childId);
|
||||
}
|
||||
void removeChild(QUuid 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(QUuid childId, QUuid 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(QUuid childId)
|
||||
{
|
||||
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
|
||||
if (it == childrenIds.end()) {
|
||||
qDebug() << "Child not found in list:" << childId;
|
||||
return;
|
||||
}
|
||||
|
||||
auto index = std::distance(childrenIds.begin(), it);
|
||||
if (index == 0)
|
||||
return;
|
||||
std::swap(childrenIds[index - 1], childrenIds[index]);
|
||||
}
|
||||
void moveChildDown(QUuid childId)
|
||||
{
|
||||
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
|
||||
if (it == childrenIds.end()) {
|
||||
qDebug() << "Child not found in list:" << childId;
|
||||
return;
|
||||
}
|
||||
|
||||
auto index = std::distance(childrenIds.begin(), it);
|
||||
if (index == (int)childrenIds.size() - 1)
|
||||
return;
|
||||
std::swap(childrenIds[index], childrenIds[index + 1]);
|
||||
}
|
||||
void moveChildToTop(QUuid childId)
|
||||
{
|
||||
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
|
||||
if (it == childrenIds.end()) {
|
||||
qDebug() << "Child not found in list:" << childId;
|
||||
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(QUuid childId)
|
||||
{
|
||||
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
|
||||
if (it == childrenIds.end()) {
|
||||
qDebug() << "Child not found in list:" << childId;
|
||||
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 setSmoothAll(float toSmoothAll)
|
||||
{
|
||||
if (toSmoothAll < 0)
|
||||
toSmoothAll = 0;
|
||||
else if (toSmoothAll > 1)
|
||||
toSmoothAll = 1;
|
||||
smoothAll = toSmoothAll;
|
||||
}
|
||||
void setSmoothSeam(float toSmoothSeam)
|
||||
{
|
||||
if (toSmoothSeam < 0)
|
||||
toSmoothSeam = 0;
|
||||
else if (toSmoothSeam > 1)
|
||||
toSmoothSeam = 1;
|
||||
smoothSeam = toSmoothSeam;
|
||||
}
|
||||
bool smoothAllAdjusted() const
|
||||
{
|
||||
return fabs(smoothAll - 0.0) >= 0.01;
|
||||
}
|
||||
bool smoothSeamAdjusted() const
|
||||
{
|
||||
return fabs(smoothSeam - 0.0) >= 0.01;
|
||||
}
|
||||
bool smoothAdjusted() const
|
||||
{
|
||||
return smoothAllAdjusted() || smoothSeamAdjusted();
|
||||
}
|
||||
private:
|
||||
std::set<QUuid> m_childrenIdSet;
|
||||
};
|
||||
|
||||
class Motion
|
||||
{
|
||||
public:
|
||||
|
@ -261,25 +114,9 @@ class Document : public SkeletonDocument
|
|||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void partAdded(QUuid partId);
|
||||
void nodeAdded(QUuid nodeId);
|
||||
void edgeAdded(QUuid edgeId);
|
||||
void partRemoved(QUuid partId);
|
||||
void componentNameChanged(QUuid componentId);
|
||||
void componentChildrenChanged(QUuid componentId);
|
||||
void componentRemoved(QUuid componentId);
|
||||
void componentAdded(QUuid componentId);
|
||||
void componentExpandStateChanged(QUuid componentId);
|
||||
void componentLayerChanged(QUuid componentId);
|
||||
void nodeRemoved(QUuid nodeId);
|
||||
void edgeRemoved(QUuid edgeId);
|
||||
void nodeRadiusChanged(QUuid nodeId);
|
||||
void nodeBoneMarkChanged(QUuid nodeId);
|
||||
void nodeColorStateChanged(QUuid nodeId);
|
||||
void nodeCutRotationChanged(QUuid nodeId);
|
||||
void nodeCutFaceChanged(QUuid nodeId);
|
||||
void nodeOriginChanged(QUuid nodeId);
|
||||
void edgeReversed(QUuid edgeId);
|
||||
void partPreviewChanged(QUuid partId);
|
||||
void resultMeshChanged();
|
||||
void resultPartPreviewsChanged();
|
||||
|
@ -287,7 +124,6 @@ signals:
|
|||
void turnaroundChanged();
|
||||
void editModeChanged();
|
||||
void paintModeChanged();
|
||||
void skeletonChanged();
|
||||
//void resultSkeletonChanged();
|
||||
void resultTextureChanged();
|
||||
void resultColorTextureChanged();
|
||||
|
@ -295,10 +131,7 @@ signals:
|
|||
void postProcessedResultChanged();
|
||||
void resultRigChanged();
|
||||
void rigChanged();
|
||||
void partLockStateChanged(QUuid partId);
|
||||
void partVisibleStateChanged(QUuid partId);
|
||||
void partSubdivStateChanged(QUuid partId);
|
||||
void partDisableStateChanged(QUuid partId);
|
||||
void partXmirrorStateChanged(QUuid partId);
|
||||
//void partZmirrorStateChanged(QUuid partId);
|
||||
void partBaseChanged(QUuid partId);
|
||||
|
@ -320,11 +153,9 @@ signals:
|
|||
void partHollowThicknessChanged(QUuid partId);
|
||||
void partCountershadeStateChanged(QUuid partId);
|
||||
void partSmoothStateChanged(QUuid partId);
|
||||
void partGridStateChanged(QUuid partId);
|
||||
void componentCombineModeChanged(QUuid componentId);
|
||||
void cleanup();
|
||||
void cleanupScript();
|
||||
void originChanged();
|
||||
void xlockStateChanged();
|
||||
void ylockStateChanged();
|
||||
void zlockStateChanged();
|
||||
|
@ -338,7 +169,6 @@ signals:
|
|||
void uncheckAll();
|
||||
void checkNode(QUuid nodeId);
|
||||
void checkEdge(QUuid edgeId);
|
||||
void optionsChanged();
|
||||
void rigTypeChanged();
|
||||
void motionsChanged();
|
||||
void motionAdded(QUuid motionId);
|
||||
|
@ -368,30 +198,28 @@ signals:
|
|||
void mousePickRadiusChanged();
|
||||
void objectLockStateChanged();
|
||||
public: // need initialize
|
||||
QImage *textureImage;
|
||||
QByteArray *textureImageByteArray;
|
||||
QImage *textureNormalImage;
|
||||
QByteArray *textureNormalImageByteArray;
|
||||
QImage *textureMetalnessImage;
|
||||
QByteArray *textureMetalnessImageByteArray;
|
||||
QImage *textureRoughnessImage;
|
||||
QByteArray *textureRoughnessImageByteArray;
|
||||
QImage *textureAmbientOcclusionImage;
|
||||
QByteArray *textureAmbientOcclusionImageByteArray;
|
||||
RigType rigType;
|
||||
bool weldEnabled;
|
||||
QColor brushColor;
|
||||
bool objectLocked;
|
||||
QImage *textureImage = nullptr;
|
||||
QByteArray *textureImageByteArray = nullptr;
|
||||
QImage *textureNormalImage = nullptr;
|
||||
QByteArray *textureNormalImageByteArray = nullptr;
|
||||
QImage *textureMetalnessImage = nullptr;
|
||||
QByteArray *textureMetalnessImageByteArray = nullptr;
|
||||
QImage *textureRoughnessImage = nullptr;
|
||||
QByteArray *textureRoughnessImageByteArray = nullptr;
|
||||
QImage *textureAmbientOcclusionImage = nullptr;
|
||||
QByteArray *textureAmbientOcclusionImageByteArray = nullptr;
|
||||
RigType rigType = RigType::None;
|
||||
bool weldEnabled = true;
|
||||
QColor brushColor = Qt::white;
|
||||
bool objectLocked = false;
|
||||
float brushMetalness = Model::m_defaultMetalness;
|
||||
float brushRoughness = Model::m_defaultRoughness;
|
||||
public:
|
||||
Document();
|
||||
~Document();
|
||||
std::map<QUuid, Component> componentMap;
|
||||
std::map<QUuid, Material> materialMap;
|
||||
std::vector<QUuid> materialIdList;
|
||||
std::map<QUuid, Motion> motionMap;
|
||||
Component rootComponent;
|
||||
QImage preview;
|
||||
bool undoable() const override;
|
||||
bool redoable() const override;
|
||||
|
@ -412,9 +240,6 @@ public:
|
|||
Import
|
||||
};
|
||||
void addFromSnapshot(const Snapshot &snapshot, enum SnapshotSource source=SnapshotSource::Paste);
|
||||
const Component *findComponent(QUuid componentId) const;
|
||||
const Component *findComponentParent(QUuid componentId) const;
|
||||
QUuid findComponentParentId(QUuid componentId) const;
|
||||
const Material *findMaterial(QUuid materialId) const;
|
||||
const Motion *findMotion(QUuid motionId) const;
|
||||
Model *takeResultMesh();
|
||||
|
@ -436,8 +261,6 @@ public:
|
|||
const Object ¤tPostProcessedObject() const;
|
||||
bool isExportReady() const;
|
||||
bool isPostProcessResultObsolete() const;
|
||||
void collectComponentDescendantParts(QUuid componentId, std::vector<QUuid> &partIds) const;
|
||||
void collectComponentDescendantComponents(QUuid componentId, std::vector<QUuid> &componentIds) const;
|
||||
const std::vector<std::pair<QtMsgType, QString>> &resultRigMessages() const;
|
||||
const Object ¤tRiggedObject() const;
|
||||
bool currentRigSucceed() const;
|
||||
|
@ -455,29 +278,15 @@ public slots:
|
|||
void undo() override;
|
||||
void redo() override;
|
||||
void paste() override;
|
||||
void removeNode(QUuid nodeId);
|
||||
void removeEdge(QUuid edgeId);
|
||||
void removePart(QUuid partId);
|
||||
void addNodeWithId(QUuid nodeId, float x, float y, float z, float radius, QUuid fromNodeId);
|
||||
void addNode(float x, float y, float z, float radius, QUuid fromNodeId);
|
||||
void scaleNodeByAddRadius(QUuid nodeId, float amount);
|
||||
void moveNodeBy(QUuid nodeId, float x, float y, float z);
|
||||
void setNodeOrigin(QUuid nodeId, float x, float y, float z);
|
||||
void setNodeRadius(QUuid nodeId, float radius);
|
||||
void setNodeBoneMark(QUuid nodeId, BoneMark mark);
|
||||
void setNodeCutRotation(QUuid nodeId, float cutRotation);
|
||||
void setNodeCutFace(QUuid nodeId, CutFace cutFace);
|
||||
void setNodeCutFaceLinkedId(QUuid nodeId, QUuid linkedId);
|
||||
void clearNodeCutFaceSettings(QUuid nodeId);
|
||||
void switchNodeXZ(QUuid nodeId);
|
||||
void moveOriginBy(float x, float y, float z);
|
||||
void addEdge(QUuid fromNodeId, QUuid toNodeId);
|
||||
void setEditMode(SkeletonDocumentEditMode mode);
|
||||
void setMeshLockState(bool locked);
|
||||
void setPaintMode(PaintMode mode);
|
||||
void setMousePickRadius(float radius);
|
||||
void createSinglePartFromEdges(const std::vector<QVector3D> &nodes,
|
||||
const std::vector<std::pair<size_t, size_t>> &edges);
|
||||
void uiReady();
|
||||
void generateMesh();
|
||||
void regenerateMesh();
|
||||
|
@ -495,10 +304,7 @@ public slots:
|
|||
void pickMouseTarget(const QVector3D &nearPosition, const QVector3D &farPosition);
|
||||
void paint();
|
||||
void paintReady();
|
||||
void setPartLockState(QUuid partId, bool locked);
|
||||
void setPartVisibleState(QUuid partId, bool visible);
|
||||
void setPartSubdivState(QUuid partId, bool subdived);
|
||||
void setPartDisableState(QUuid partId, bool disabled);
|
||||
void setPartXmirrorState(QUuid partId, bool mirrored);
|
||||
//void setPartZmirrorState(QUuid partId, bool mirrored);
|
||||
void setPartBase(QUuid partId, PartBase base);
|
||||
|
@ -522,31 +328,6 @@ public slots:
|
|||
void setPartCountershaded(QUuid partId, bool countershaded);
|
||||
void setPartSmoothState(QUuid partId, bool smooth);
|
||||
void setComponentCombineMode(QUuid componentId, CombineMode combineMode);
|
||||
void moveComponentUp(QUuid componentId);
|
||||
void moveComponentDown(QUuid componentId);
|
||||
void moveComponentToTop(QUuid componentId);
|
||||
void moveComponentToBottom(QUuid componentId);
|
||||
void renameComponent(QUuid componentId, QString name);
|
||||
void removeComponent(QUuid componentId);
|
||||
void addComponent(QUuid parentId);
|
||||
void moveComponent(QUuid componentId, QUuid toParentId);
|
||||
void setCurrentCanvasComponentId(QUuid componentId);
|
||||
void createNewComponentAndMoveThisIn(QUuid componentId);
|
||||
void createNewChildComponent(QUuid parentComponentId);
|
||||
void setComponentExpandState(QUuid componentId, bool expanded);
|
||||
void hideOtherComponents(QUuid componentId);
|
||||
void lockOtherComponents(QUuid componentId);
|
||||
void hideAllComponents();
|
||||
void showAllComponents();
|
||||
void showOrHideAllComponents();
|
||||
void collapseAllComponents();
|
||||
void expandAllComponents();
|
||||
void lockAllComponents();
|
||||
void unlockAllComponents();
|
||||
void hideDescendantComponents(QUuid componentId);
|
||||
void showDescendantComponents(QUuid componentId);
|
||||
void lockDescendantComponents(QUuid componentId);
|
||||
void unlockDescendantComponents(QUuid componentId);
|
||||
void saveSnapshot();
|
||||
void batchChangeBegin();
|
||||
void batchChangeEnd();
|
||||
|
@ -555,15 +336,10 @@ public slots:
|
|||
void clearHistories();
|
||||
void silentReset();
|
||||
void silentResetScript();
|
||||
void breakEdge(QUuid edgeId);
|
||||
void reduceNode(QUuid nodeId);
|
||||
void reverseEdge(QUuid edgeId);
|
||||
void setXlockState(bool locked);
|
||||
void setYlockState(bool locked);
|
||||
void setZlockState(bool locked);
|
||||
void setRadiusLockState(bool locked);
|
||||
void enableAllPositionRelatedLocks();
|
||||
void disableAllPositionRelatedLocks();
|
||||
void toggleSmoothNormal();
|
||||
void enableWeld(bool enabled);
|
||||
void setRigType(RigType toRigType);
|
||||
|
@ -590,62 +366,48 @@ public slots:
|
|||
void setMousePickMaskNodeIds(const std::set<QUuid> &nodeIds);
|
||||
void updateObject(Object *object);
|
||||
private:
|
||||
void splitPartByNode(std::vector<std::vector<QUuid>> *groups, QUuid nodeId);
|
||||
void joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId, std::set<QUuid> *visitMap, QUuid noUseEdgeId=QUuid());
|
||||
void splitPartByEdge(std::vector<std::vector<QUuid>> *groups, QUuid edgeId);
|
||||
bool isPartReadonly(QUuid partId) const;
|
||||
QUuid createNode(QUuid nodeId, float x, float y, float z, float radius, QUuid fromNodeId);
|
||||
void settleOrigin();
|
||||
void checkExportReadyState();
|
||||
void removePartDontCareComponent(QUuid partId);
|
||||
void addPartToComponent(QUuid partId, QUuid componentId);
|
||||
bool isDescendantComponent(QUuid componentId, QUuid suspiciousId);
|
||||
void removeComponentRecursively(QUuid componentId);
|
||||
void resetDirtyFlags();
|
||||
void markAllDirty();
|
||||
void removeRigResults();
|
||||
void updateLinkedPart(QUuid oldPartId, QUuid newPartId);
|
||||
bool updateDefaultVariables(const std::map<QString, std::map<QString, QString>> &defaultVariables);
|
||||
private: // need initialize
|
||||
bool m_isResultMeshObsolete;
|
||||
MeshGenerator *m_meshGenerator;
|
||||
Model *m_resultMesh;
|
||||
Model *m_paintedMesh;
|
||||
std::map<QUuid, std::map<QString, QVector2D>> *m_resultMeshNodesCutFaces;
|
||||
bool m_isMeshGenerationSucceed;
|
||||
int m_batchChangeRefCount;
|
||||
Object *m_currentObject;
|
||||
bool m_isTextureObsolete;
|
||||
TextureGenerator *m_textureGenerator;
|
||||
bool m_isPostProcessResultObsolete;
|
||||
MeshResultPostProcessor *m_postProcessor;
|
||||
Object *m_postProcessedObject;
|
||||
Model *m_resultTextureMesh;
|
||||
unsigned long long m_textureImageUpdateVersion;
|
||||
QUuid m_currentCanvasComponentId;
|
||||
bool m_allPositionRelatedLocksEnabled;
|
||||
bool m_smoothNormal;
|
||||
RigGenerator *m_rigGenerator;
|
||||
Model *m_resultRigWeightMesh;
|
||||
std::vector<RigBone> *m_resultRigBones;
|
||||
std::map<int, RigVertexWeights> *m_resultRigWeights;
|
||||
bool m_isRigObsolete;
|
||||
Object *m_riggedObject;
|
||||
bool m_currentRigSucceed;
|
||||
MaterialPreviewsGenerator *m_materialPreviewsGenerator;
|
||||
MotionsGenerator *m_motionsGenerator;
|
||||
quint64 m_meshGenerationId;
|
||||
quint64 m_nextMeshGenerationId;
|
||||
private:
|
||||
bool m_isResultMeshObsolete = false;
|
||||
MeshGenerator *m_meshGenerator = nullptr;
|
||||
Model *m_resultMesh = nullptr;
|
||||
Model *m_paintedMesh = nullptr;
|
||||
std::map<QUuid, std::map<QString, QVector2D>> *m_resultMeshNodesCutFaces = nullptr;
|
||||
bool m_isMeshGenerationSucceed = true;
|
||||
int m_batchChangeRefCount = 0;
|
||||
Object *m_currentObject = nullptr;
|
||||
bool m_isTextureObsolete = false;
|
||||
TextureGenerator *m_textureGenerator = nullptr;
|
||||
bool m_isPostProcessResultObsolete = false;
|
||||
MeshResultPostProcessor *m_postProcessor = nullptr;
|
||||
Object *m_postProcessedObject = new Object;
|
||||
Model *m_resultTextureMesh = nullptr;
|
||||
unsigned long long m_textureImageUpdateVersion = 0;
|
||||
bool m_smoothNormal = !Preferences::instance().flatShading();
|
||||
RigGenerator *m_rigGenerator = nullptr;
|
||||
Model *m_resultRigWeightMesh = nullptr;
|
||||
std::vector<RigBone> *m_resultRigBones = nullptr;
|
||||
std::map<int, RigVertexWeights> *m_resultRigWeights = nullptr;
|
||||
bool m_isRigObsolete = false;
|
||||
Object *m_riggedObject = new Object;
|
||||
bool m_currentRigSucceed = false;
|
||||
MaterialPreviewsGenerator *m_materialPreviewsGenerator = nullptr;
|
||||
MotionsGenerator *m_motionsGenerator = nullptr;
|
||||
quint64 m_meshGenerationId = 0;
|
||||
quint64 m_nextMeshGenerationId = 0;
|
||||
std::map<QString, std::map<QString, QString>> m_cachedVariables;
|
||||
std::map<QString, std::map<QString, QString>> m_mergedVariables;
|
||||
ScriptRunner *m_scriptRunner;
|
||||
bool m_isScriptResultObsolete;
|
||||
TexturePainter *m_texturePainter;
|
||||
bool m_isMouseTargetResultObsolete;
|
||||
PaintMode m_paintMode;
|
||||
float m_mousePickRadius;
|
||||
GeneratedCacheContext *m_generatedCacheContext;
|
||||
TexturePainterContext *m_texturePainterContext;
|
||||
ScriptRunner *m_scriptRunner = nullptr;
|
||||
bool m_isScriptResultObsolete = false;
|
||||
TexturePainter *m_texturePainter = nullptr;
|
||||
bool m_isMouseTargetResultObsolete = false;
|
||||
PaintMode m_paintMode = PaintMode::None;
|
||||
float m_mousePickRadius = 0.02f;
|
||||
GeneratedCacheContext *m_generatedCacheContext = nullptr;
|
||||
TexturePainterContext *m_texturePainterContext = nullptr;
|
||||
private:
|
||||
static unsigned long m_maxSnapshot;
|
||||
std::deque<HistoryItem> m_undoItems;
|
||||
|
|
|
@ -133,9 +133,9 @@ void PartTreeWidget::updateComponentAppearance(QUuid componentId)
|
|||
|
||||
void PartTreeWidget::updateComponentSelectState(QUuid componentId, bool selected)
|
||||
{
|
||||
const Component *component = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *component = m_document->findComponent(componentId);
|
||||
if (nullptr == component) {
|
||||
qDebug() << "Component not found:" << componentId;
|
||||
qDebug() << "SkeletonComponent not found:" << componentId;
|
||||
return;
|
||||
}
|
||||
if (!component->linkToPartId.isNull()) {
|
||||
|
@ -196,7 +196,7 @@ void PartTreeWidget::handleSingleClick(const QPoint &pos)
|
|||
auto componentId = QUuid(item->data(0, Qt::UserRole).toString());
|
||||
if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) {
|
||||
if (!m_shiftStartComponentId.isNull()) {
|
||||
const Component *parent = m_document->findComponentParent(m_shiftStartComponentId);
|
||||
const SkeletonComponent *parent = m_document->findComponentParent(m_shiftStartComponentId);
|
||||
if (parent) {
|
||||
if (!parent->childrenIds.empty()) {
|
||||
bool startAdd = false;
|
||||
|
@ -288,7 +288,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted)
|
|||
//delete m_delayedMousePressTimer;
|
||||
//m_delayedMousePressTimer = nullptr;
|
||||
|
||||
const Component *component = nullptr;
|
||||
const SkeletonComponent *component = nullptr;
|
||||
const SkeletonPart *part = nullptr;
|
||||
PartWidget *partWidget = nullptr;
|
||||
|
||||
|
@ -305,7 +305,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted)
|
|||
QUuid componentId = *componentIds.begin();
|
||||
component = m_document->findComponent(componentId);
|
||||
if (nullptr == component) {
|
||||
qDebug() << "Component not found:" << componentId;
|
||||
qDebug() << "SkeletonComponent not found:" << componentId;
|
||||
return;
|
||||
}
|
||||
if (component && !component->linkToPartId.isNull()) {
|
||||
|
@ -394,7 +394,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted)
|
|||
if (nullptr == partBaseSelectBox) {
|
||||
std::set<PartBase> partBases;
|
||||
for (const auto &componentId: componentIds) {
|
||||
const Component *oneComponent = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *oneComponent = m_document->findComponent(componentId);
|
||||
if (nullptr == oneComponent || oneComponent->linkToPartId.isNull())
|
||||
continue;
|
||||
const SkeletonPart *onePart = m_document->findPart(oneComponent->linkToPartId);
|
||||
|
@ -419,7 +419,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted)
|
|||
if (index < startIndex)
|
||||
return;
|
||||
for (const auto &componentId: componentIds) {
|
||||
const Component *oneComponent = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *oneComponent = m_document->findComponent(componentId);
|
||||
if (nullptr == oneComponent || oneComponent->linkToPartId.isNull())
|
||||
continue;
|
||||
emit setPartBase(oneComponent->linkToPartId, (PartBase)(index - startIndex));
|
||||
|
@ -432,7 +432,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted)
|
|||
if (nullptr == combineModeSelectBox) {
|
||||
std::set<CombineMode> combineModes;
|
||||
for (const auto &componentId: componentIds) {
|
||||
const Component *oneComponent = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *oneComponent = m_document->findComponent(componentId);
|
||||
if (nullptr == oneComponent)
|
||||
continue;
|
||||
combineModes.insert(oneComponent->combineMode);
|
||||
|
@ -732,7 +732,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted)
|
|||
});
|
||||
|
||||
addChildGroupsFunc = [this, &groupsActions, &addChildGroupsFunc, &moveToMenu, &componentIds](QUuid currentId, int tabs) -> void {
|
||||
const Component *current = m_document->findComponent(currentId);
|
||||
const SkeletonComponent *current = m_document->findComponent(currentId);
|
||||
if (nullptr == current)
|
||||
return;
|
||||
if (!current->id.isNull() && current->linkDataType().isEmpty()) {
|
||||
|
@ -799,7 +799,7 @@ void PartTreeWidget::componentNameChanged(QUuid componentId)
|
|||
return;
|
||||
}
|
||||
|
||||
const Component *component = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *component = m_document->findComponent(componentId);
|
||||
if (nullptr == component) {
|
||||
qDebug() << "Find component failed:" << componentId;
|
||||
return;
|
||||
|
@ -816,7 +816,7 @@ void PartTreeWidget::componentExpandStateChanged(QUuid componentId)
|
|||
return;
|
||||
}
|
||||
|
||||
const Component *component = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *component = m_document->findComponent(componentId);
|
||||
if (nullptr == component) {
|
||||
qDebug() << "Find component failed:" << componentId;
|
||||
return;
|
||||
|
@ -837,12 +837,12 @@ void PartTreeWidget::componentTargetChanged(QUuid componentId)
|
|||
|
||||
void PartTreeWidget::addComponentChildrenToItem(QUuid componentId, QTreeWidgetItem *parentItem)
|
||||
{
|
||||
const Component *parentComponent = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *parentComponent = m_document->findComponent(componentId);
|
||||
if (nullptr == parentComponent)
|
||||
return;
|
||||
|
||||
for (const auto &childId: parentComponent->childrenIds) {
|
||||
const Component *component = m_document->findComponent(childId);
|
||||
const SkeletonComponent *component = m_document->findComponent(childId);
|
||||
if (nullptr == component)
|
||||
continue;
|
||||
if (!component->linkToPartId.isNull()) {
|
||||
|
@ -885,7 +885,7 @@ void PartTreeWidget::deleteItemChildren(QTreeWidgetItem *item)
|
|||
while (!children.isEmpty()) {
|
||||
auto first = children.takeFirst();
|
||||
auto componentId = QUuid(first->data(0, Qt::UserRole).toString());
|
||||
const Component *component = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *component = m_document->findComponent(componentId);
|
||||
if (nullptr != component) {
|
||||
m_componentItemMap.erase(componentId);
|
||||
if (!component->linkToPartId.isNull()) {
|
||||
|
@ -983,7 +983,7 @@ void PartTreeWidget::groupChanged(QTreeWidgetItem *item, int column)
|
|||
|
||||
auto componentId = QUuid(item->data(0, Qt::UserRole).toString());
|
||||
|
||||
const Component *component = m_document->findComponent(componentId);
|
||||
const SkeletonComponent *component = m_document->findComponent(componentId);
|
||||
if (nullptr == component) {
|
||||
qDebug() << "Find component failed:" << componentId;
|
||||
return;
|
||||
|
|
1496
src/regionfiller.cpp
1496
src/regionfiller.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,74 +0,0 @@
|
|||
#ifndef DUST3D_REGION_FILLER_H
|
||||
#define DUST3D_REGION_FILLER_H
|
||||
#include <QVector3D>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
class RegionFiller
|
||||
{
|
||||
public:
|
||||
struct Node
|
||||
{
|
||||
QVector3D position;
|
||||
float radius = 0.0;
|
||||
size_t source = 0;
|
||||
};
|
||||
RegionFiller(const std::vector<Node> *vertices,
|
||||
const std::vector<std::vector<size_t>> *polylines);
|
||||
~RegionFiller();
|
||||
bool fill();
|
||||
void fillWithoutPartition();
|
||||
const std::vector<Node> &getOldAndNewVertices();
|
||||
const std::vector<std::vector<size_t>> &getNewFaces();
|
||||
private:
|
||||
const std::vector<Node> *m_sourceVertices = nullptr;
|
||||
std::vector<std::vector<size_t>> *m_sourcePolylines = nullptr;
|
||||
int m_sideNum = 0;
|
||||
int m_sumOfSegments = 0;
|
||||
std::vector<int> m_sideSegmentNums;
|
||||
std::vector<Node> m_oldAndNewVertices;
|
||||
std::vector<std::vector<size_t>> m_newFaces;
|
||||
std::vector<std::vector<std::vector<size_t>>> m_newRegions;
|
||||
std::set<size_t> m_centerSources;
|
||||
float averageRadius(size_t *maxNodeIndex=nullptr);
|
||||
void createPointsBetween(size_t fromIndex,
|
||||
size_t toIndex,
|
||||
size_t segments,
|
||||
std::vector<size_t> *newPointIndices);
|
||||
std::vector<size_t> createPointsBetween(size_t fromIndex,
|
||||
size_t toIndex,
|
||||
size_t segments);
|
||||
void collectEdgePoints(size_t polyline, int startPos, int stopPos,
|
||||
std::vector<size_t> *pointIndices);
|
||||
std::vector<size_t> collectEdgePoints(size_t polyline, int startPos, int stopPos);
|
||||
std::vector<size_t> reversed(const std::vector<size_t> &pointIndices);
|
||||
std::vector<size_t> createPointsToMapBetween(size_t fromIndex,
|
||||
size_t toIndex,
|
||||
size_t segments,
|
||||
std::map<std::pair<size_t, size_t>, std::vector<size_t>> *map);
|
||||
bool resolveOddSidedEvenSumOfSegments(int siUpperBound);
|
||||
bool resolveOddSidedOddSumOfSegments(int siUpperBound);
|
||||
bool resolveEvenSidedEvenSumOfSegmentsAndBothL2L2AreEven();
|
||||
bool resolveEvenSidedEvenSumOfSegmentsAndBothL2L2AreOdd();
|
||||
bool resolveEvenSideEvenSumOfSegmentsAndL1IsEvenL2IsOdd();
|
||||
bool resolveEvenSideEvenSumOfSegmentsAndL1IsOddL2IsEven();
|
||||
bool resolveQuadrilateralRegion();
|
||||
bool resolveQuadrilateralRegionWithIntegerSolution(int m, int n, int p, int q, bool pqSwapped);
|
||||
bool resolveQuadrilateralRegionMismatchSimilarCase(int m, int n, int p, int q, bool pqSwapped);
|
||||
bool resolveQuadrilateralRegionWithNonIntegerSolution(int m, int n, int p, int q, bool pqSwapped);
|
||||
bool resolveQuadrilateralRegionDirectCase();
|
||||
void convertRegionsToFaces();
|
||||
void prepare();
|
||||
bool createCoonsPatch(const std::vector<std::vector<size_t>> ®ion);
|
||||
bool convertRegionsToPatches();
|
||||
bool createCoonsPatchFrom(const std::vector<size_t> &c0,
|
||||
const std::vector<size_t> &c1,
|
||||
const std::vector<size_t> &d0,
|
||||
const std::vector<size_t> &d1,
|
||||
bool fillLastTriangle=false);
|
||||
bool createCoonsPatchThreeSidedRegion(const std::vector<std::vector<size_t>> ®ion);
|
||||
void convertPolylinesToFaces();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -6,6 +6,7 @@
|
|||
#include <cmath>
|
||||
#include <QImage>
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include "bonemark.h"
|
||||
#include "theme.h"
|
||||
#include "model.h"
|
||||
|
@ -183,7 +184,6 @@ public:
|
|||
QUuid deformMapImageId;
|
||||
float hollowThickness;
|
||||
bool countershaded;
|
||||
bool gridded;
|
||||
QUuid fillMeshLinkedId;
|
||||
bool isPreviewMeshObsolete;
|
||||
QPixmap previewPixmap;
|
||||
|
@ -213,7 +213,6 @@ public:
|
|||
deformMapScale(1.0),
|
||||
hollowThickness(0.0),
|
||||
countershaded(false),
|
||||
gridded(false),
|
||||
isPreviewMeshObsolete(false),
|
||||
smooth(true)
|
||||
{
|
||||
|
@ -441,9 +440,147 @@ enum class SkeletonProfile
|
|||
Side
|
||||
};
|
||||
|
||||
class SkeletonComponent
|
||||
{
|
||||
public:
|
||||
SkeletonComponent()
|
||||
{
|
||||
}
|
||||
SkeletonComponent(const QUuid &withId, const QString &linkData=QString(), const QString &linkDataType=QString())
|
||||
{
|
||||
id = withId.isNull() ? QUuid::createUuid() : withId;
|
||||
if (!linkData.isEmpty()) {
|
||||
if ("partId" == linkDataType) {
|
||||
linkToPartId = QUuid(linkData);
|
||||
}
|
||||
}
|
||||
}
|
||||
QUuid id;
|
||||
QString name;
|
||||
QUuid linkToPartId;
|
||||
QUuid parentId;
|
||||
bool expanded = true;
|
||||
CombineMode combineMode = Preferences::instance().componentCombineMode();
|
||||
bool dirty = true;
|
||||
std::vector<QUuid> childrenIds;
|
||||
QString linkData() const
|
||||
{
|
||||
return linkToPartId.isNull() ? QString() : linkToPartId.toString();
|
||||
}
|
||||
QString linkDataType() const
|
||||
{
|
||||
return linkToPartId.isNull() ? QString() : QString("partId");
|
||||
}
|
||||
void addChild(QUuid childId)
|
||||
{
|
||||
if (m_childrenIdSet.find(childId) != m_childrenIdSet.end())
|
||||
return;
|
||||
m_childrenIdSet.insert(childId);
|
||||
childrenIds.push_back(childId);
|
||||
}
|
||||
void removeChild(QUuid 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(QUuid childId, QUuid 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(QUuid childId)
|
||||
{
|
||||
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
|
||||
if (it == childrenIds.end()) {
|
||||
qDebug() << "Child not found in list:" << childId;
|
||||
return;
|
||||
}
|
||||
|
||||
auto index = std::distance(childrenIds.begin(), it);
|
||||
if (index == 0)
|
||||
return;
|
||||
std::swap(childrenIds[index - 1], childrenIds[index]);
|
||||
}
|
||||
void moveChildDown(QUuid childId)
|
||||
{
|
||||
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
|
||||
if (it == childrenIds.end()) {
|
||||
qDebug() << "Child not found in list:" << childId;
|
||||
return;
|
||||
}
|
||||
|
||||
auto index = std::distance(childrenIds.begin(), it);
|
||||
if (index == (int)childrenIds.size() - 1)
|
||||
return;
|
||||
std::swap(childrenIds[index], childrenIds[index + 1]);
|
||||
}
|
||||
void moveChildToTop(QUuid childId)
|
||||
{
|
||||
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
|
||||
if (it == childrenIds.end()) {
|
||||
qDebug() << "Child not found in list:" << childId;
|
||||
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(QUuid childId)
|
||||
{
|
||||
auto it = std::find(childrenIds.begin(), childrenIds.end(), childId);
|
||||
if (it == childrenIds.end()) {
|
||||
qDebug() << "Child not found in list:" << childId;
|
||||
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]);
|
||||
}
|
||||
private:
|
||||
std::set<QUuid> m_childrenIdSet;
|
||||
};
|
||||
|
||||
class SkeletonDocument : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void partAdded(QUuid partId);
|
||||
void nodeAdded(QUuid nodeId);
|
||||
void edgeAdded(QUuid edgeId);
|
||||
void partRemoved(QUuid partId);
|
||||
void partLockStateChanged(QUuid partId);
|
||||
void partVisibleStateChanged(QUuid partId);
|
||||
void partDisableStateChanged(QUuid partId);
|
||||
void componentNameChanged(QUuid componentId);
|
||||
void componentChildrenChanged(QUuid componentId);
|
||||
void componentRemoved(QUuid componentId);
|
||||
void componentAdded(QUuid componentId);
|
||||
void componentExpandStateChanged(QUuid componentId);
|
||||
void nodeRemoved(QUuid nodeId);
|
||||
void edgeRemoved(QUuid edgeId);
|
||||
void nodeRadiusChanged(QUuid nodeId);
|
||||
void nodeOriginChanged(QUuid nodeId);
|
||||
void edgeReversed(QUuid edgeId);
|
||||
void originChanged();
|
||||
void skeletonChanged();
|
||||
void optionsChanged();
|
||||
public:
|
||||
SkeletonDocumentEditMode editMode = SkeletonDocumentEditMode::Select;
|
||||
bool xlocked = false;
|
||||
|
@ -455,6 +592,8 @@ public:
|
|||
std::map<QUuid, SkeletonPart> partMap;
|
||||
std::map<QUuid, SkeletonNode> nodeMap;
|
||||
std::map<QUuid, SkeletonEdge> edgeMap;
|
||||
std::map<QUuid, SkeletonComponent> componentMap;
|
||||
SkeletonComponent rootComponent;
|
||||
|
||||
const SkeletonNode *findNode(QUuid nodeId) const;
|
||||
const SkeletonEdge *findEdge(QUuid edgeId) const;
|
||||
|
@ -462,6 +601,13 @@ public:
|
|||
const SkeletonEdge *findEdgeByNodes(QUuid firstNodeId, QUuid secondNodeId) const;
|
||||
void findAllNeighbors(QUuid nodeId, std::set<QUuid> &neighbors) const;
|
||||
bool isNodeConnectable(QUuid nodeId) const;
|
||||
const SkeletonComponent *findComponent(QUuid componentId) const;
|
||||
const SkeletonComponent *findComponentParent(QUuid componentId) const;
|
||||
QUuid findComponentParentId(QUuid componentId) const;
|
||||
void collectComponentDescendantParts(QUuid componentId, std::vector<QUuid> &partIds) const;
|
||||
void collectComponentDescendantComponents(QUuid componentId, std::vector<QUuid> &componentIds) const;
|
||||
void resetDirtyFlags();
|
||||
void markAllDirty();
|
||||
|
||||
virtual bool undoable() const = 0;
|
||||
virtual bool redoable() const = 0;
|
||||
|
@ -528,10 +674,70 @@ public slots:
|
|||
virtual void redo() = 0;
|
||||
virtual void paste() = 0;
|
||||
|
||||
void removeNode(QUuid nodeId);
|
||||
void removeEdge(QUuid edgeId);
|
||||
void removePart(QUuid partId);
|
||||
void addNodeWithId(QUuid nodeId, float x, float y, float z, float radius, QUuid fromNodeId);
|
||||
void addNode(float x, float y, float z, float radius, QUuid fromNodeId);
|
||||
void scaleNodeByAddRadius(QUuid nodeId, float amount);
|
||||
void moveNodeBy(QUuid nodeId, float x, float y, float z);
|
||||
void setNodeOrigin(QUuid nodeId, float x, float y, float z);
|
||||
void setNodeRadius(QUuid nodeId, float radius);
|
||||
void switchNodeXZ(QUuid nodeId);
|
||||
void moveOriginBy(float x, float y, float z);
|
||||
void addEdge(QUuid fromNodeId, QUuid toNodeId);
|
||||
void moveComponentUp(QUuid componentId);
|
||||
void moveComponentDown(QUuid componentId);
|
||||
void moveComponentToTop(QUuid componentId);
|
||||
void moveComponentToBottom(QUuid componentId);
|
||||
void renameComponent(QUuid componentId, QString name);
|
||||
void removeComponent(QUuid componentId);
|
||||
void addComponent(QUuid parentId);
|
||||
void moveComponent(QUuid componentId, QUuid toParentId);
|
||||
void setCurrentCanvasComponentId(QUuid componentId);
|
||||
void createNewComponentAndMoveThisIn(QUuid componentId);
|
||||
void createNewChildComponent(QUuid parentComponentId);
|
||||
void setComponentExpandState(QUuid componentId, bool expanded);
|
||||
void hideOtherComponents(QUuid componentId);
|
||||
void lockOtherComponents(QUuid componentId);
|
||||
void hideAllComponents();
|
||||
void showAllComponents();
|
||||
void showOrHideAllComponents();
|
||||
void collapseAllComponents();
|
||||
void expandAllComponents();
|
||||
void lockAllComponents();
|
||||
void unlockAllComponents();
|
||||
void hideDescendantComponents(QUuid componentId);
|
||||
void showDescendantComponents(QUuid componentId);
|
||||
void lockDescendantComponents(QUuid componentId);
|
||||
void unlockDescendantComponents(QUuid componentId);
|
||||
void setPartLockState(QUuid partId, bool locked);
|
||||
void setPartVisibleState(QUuid partId, bool visible);
|
||||
void setPartDisableState(QUuid partId, bool disabled);
|
||||
void enableAllPositionRelatedLocks();
|
||||
void disableAllPositionRelatedLocks();
|
||||
bool isPartReadonly(QUuid partId) const;
|
||||
void breakEdge(QUuid edgeId);
|
||||
void reduceNode(QUuid nodeId);
|
||||
void reverseEdge(QUuid edgeId);
|
||||
|
||||
private:
|
||||
float m_originX = 0;
|
||||
float m_originY = 0;
|
||||
float m_originZ = 0;
|
||||
|
||||
QUuid m_currentCanvasComponentId;
|
||||
bool m_allPositionRelatedLocksEnabled = true;
|
||||
|
||||
void splitPartByNode(std::vector<std::vector<QUuid>> *groups, QUuid nodeId);
|
||||
void joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId, std::set<QUuid> *visitMap, QUuid noUseEdgeId=QUuid());
|
||||
void splitPartByEdge(std::vector<std::vector<QUuid>> *groups, QUuid edgeId);
|
||||
void removePartDontCareComponent(QUuid partId);
|
||||
void addPartToComponent(QUuid partId, QUuid componentId);
|
||||
bool isDescendantComponent(QUuid componentId, QUuid suspiciousId);
|
||||
void removeComponentRecursively(QUuid componentId);
|
||||
void updateLinkedPart(QUuid oldPartId, QUuid newPartId);
|
||||
QUuid createNode(QUuid nodeId, float x, float y, float z, float radius, QUuid fromNodeId);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue