Save/load bone info to/from document
parent
b2048cfbc7
commit
eba729d785
|
@ -1677,6 +1677,13 @@ void Document::toSnapshot(dust3d::Snapshot* snapshot, const std::set<dust3d::Uui
|
||||||
}
|
}
|
||||||
if (!nodeIt.second.name.isEmpty())
|
if (!nodeIt.second.name.isEmpty())
|
||||||
node["name"] = nodeIt.second.name.toUtf8().constData();
|
node["name"] = nodeIt.second.name.toUtf8().constData();
|
||||||
|
std::vector<std::string> nodeBoneIdList;
|
||||||
|
for (const auto& boneId : nodeIt.second.boneIds) {
|
||||||
|
nodeBoneIdList.push_back(boneId.toString());
|
||||||
|
}
|
||||||
|
std::string boneIds = dust3d::String::join(nodeBoneIdList, ",");
|
||||||
|
if (!boneIds.empty())
|
||||||
|
node["boneIdList"] = boneIds;
|
||||||
if (nodeIt.second.boneJoint)
|
if (nodeIt.second.boneJoint)
|
||||||
node["boneJoint"] = "true";
|
node["boneJoint"] = "true";
|
||||||
snapshot->nodes[node["id"]] = node;
|
snapshot->nodes[node["id"]] = node;
|
||||||
|
@ -1741,6 +1748,8 @@ void Document::toSnapshot(dust3d::Snapshot* snapshot, const std::set<dust3d::Uui
|
||||||
bone["id"] = boneIt.second.id.toString();
|
bone["id"] = boneIt.second.id.toString();
|
||||||
bone["attachBoneId"] = boneIt.second.attachBoneId.toString();
|
bone["attachBoneId"] = boneIt.second.attachBoneId.toString();
|
||||||
bone["attachBoneJointIndex"] = std::to_string(boneIt.second.attachBoneJointIndex);
|
bone["attachBoneJointIndex"] = std::to_string(boneIt.second.attachBoneJointIndex);
|
||||||
|
if (!boneIt.second.name.isEmpty())
|
||||||
|
bone["name"] = boneIt.second.name.toUtf8().constData();
|
||||||
snapshot->bones[bone["id"]] = bone;
|
snapshot->bones[bone["id"]] = bone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1773,6 +1782,7 @@ void Document::addFromSnapshot(const dust3d::Snapshot& snapshot, enum SnapshotSo
|
||||||
std::set<dust3d::Uuid> newAddedEdgeIds;
|
std::set<dust3d::Uuid> newAddedEdgeIds;
|
||||||
std::set<dust3d::Uuid> newAddedPartIds;
|
std::set<dust3d::Uuid> newAddedPartIds;
|
||||||
std::set<dust3d::Uuid> newAddedComponentIds;
|
std::set<dust3d::Uuid> newAddedComponentIds;
|
||||||
|
std::set<dust3d::Uuid> newAddedBoneIds;
|
||||||
|
|
||||||
std::set<dust3d::Uuid> inversePartIds;
|
std::set<dust3d::Uuid> inversePartIds;
|
||||||
|
|
||||||
|
@ -1857,6 +1867,20 @@ void Document::addFromSnapshot(const dust3d::Snapshot& snapshot, enum SnapshotSo
|
||||||
part.setCutFaceLinkedId(findNewLinkedId->second);
|
part.setCutFaceLinkedId(findNewLinkedId->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const auto& boneKv : snapshot.bones) {
|
||||||
|
Document::Bone bone;
|
||||||
|
oldNewIdMap[dust3d::Uuid(boneKv.first)] = bone.id;
|
||||||
|
bone.name = dust3d::String::valueOrEmpty(boneKv.second, "name").c_str();
|
||||||
|
bone.attachBoneJointIndex = dust3d::String::toInt(dust3d::String::valueOrEmpty(boneKv.second, "attachBoneJointIndex").c_str());
|
||||||
|
boneMap.emplace(bone.id, std::move(bone));
|
||||||
|
newAddedBoneIds.insert(bone.id);
|
||||||
|
}
|
||||||
|
for (const auto& boneKv : snapshot.bones) {
|
||||||
|
auto attachBoneId = dust3d::Uuid(dust3d::String::valueOrEmpty(boneKv.second, "attachBoneId"));
|
||||||
|
if (!attachBoneId.isNull()) {
|
||||||
|
boneMap[oldNewIdMap[dust3d::Uuid(boneKv.first)]].attachBoneId = oldNewIdMap[attachBoneId];
|
||||||
|
}
|
||||||
|
}
|
||||||
for (const auto& nodeKv : snapshot.nodes) {
|
for (const auto& nodeKv : snapshot.nodes) {
|
||||||
if (nodeKv.second.find("radius") == nodeKv.second.end() || nodeKv.second.find("x") == nodeKv.second.end() || nodeKv.second.find("y") == nodeKv.second.end() || nodeKv.second.find("z") == nodeKv.second.end() || nodeKv.second.find("partId") == nodeKv.second.end())
|
if (nodeKv.second.find("radius") == nodeKv.second.end() || nodeKv.second.find("x") == nodeKv.second.end() || nodeKv.second.find("y") == nodeKv.second.end() || nodeKv.second.find("z") == nodeKv.second.end() || nodeKv.second.find("partId") == nodeKv.second.end())
|
||||||
continue;
|
continue;
|
||||||
|
@ -1889,6 +1913,11 @@ void Document::addFromSnapshot(const dust3d::Snapshot& snapshot, enum SnapshotSo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const auto& boneIdString : dust3d::String::split(dust3d::String::valueOrEmpty(nodeKv.second, "boneIdList"), ',')) {
|
||||||
|
if (boneIdString.empty())
|
||||||
|
continue;
|
||||||
|
node.boneIds.insert(oldNewIdMap[dust3d::Uuid(boneIdString)]);
|
||||||
|
}
|
||||||
nodeMap[node.id] = node;
|
nodeMap[node.id] = node;
|
||||||
newAddedNodeIds.insert(node.id);
|
newAddedNodeIds.insert(node.id);
|
||||||
}
|
}
|
||||||
|
@ -1985,6 +2014,11 @@ void Document::addFromSnapshot(const dust3d::Snapshot& snapshot, enum SnapshotSo
|
||||||
emit componentChildrenChanged(dust3d::Uuid());
|
emit componentChildrenChanged(dust3d::Uuid());
|
||||||
if (isOriginChanged)
|
if (isOriginChanged)
|
||||||
emit originChanged();
|
emit originChanged();
|
||||||
|
|
||||||
|
for (const auto& boneIt : newAddedBoneIds) {
|
||||||
|
emit boneAdded(boneIt);
|
||||||
|
}
|
||||||
|
|
||||||
emit skeletonChanged();
|
emit skeletonChanged();
|
||||||
|
|
||||||
for (const auto& partIt : newAddedPartIds) {
|
for (const auto& partIt : newAddedPartIds) {
|
||||||
|
@ -2874,3 +2908,15 @@ void Document::setBoneAttachment(const dust3d::Uuid& boneId, const dust3d::Uuid&
|
||||||
emit boneAttachmentChanged(boneId);
|
emit boneAttachmentChanged(boneId);
|
||||||
emit rigChanged();
|
emit rigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Document::renameBone(const dust3d::Uuid& boneId, const QString& name)
|
||||||
|
{
|
||||||
|
auto boneIt = boneMap.find(boneId);
|
||||||
|
if (boneIt == boneMap.end())
|
||||||
|
return;
|
||||||
|
if (boneIt->second.name == name)
|
||||||
|
return;
|
||||||
|
boneIt->second.name = name;
|
||||||
|
emit boneNameChanged(boneId);
|
||||||
|
emit rigChanged();
|
||||||
|
}
|
||||||
|
|
|
@ -562,7 +562,8 @@ public:
|
||||||
public:
|
public:
|
||||||
dust3d::Uuid id;
|
dust3d::Uuid id;
|
||||||
dust3d::Uuid attachBoneId;
|
dust3d::Uuid attachBoneId;
|
||||||
int attachBoneJointIndex;
|
int attachBoneJointIndex = 0;
|
||||||
|
QString name;
|
||||||
|
|
||||||
Bone(const dust3d::Uuid& withId = dust3d::Uuid());
|
Bone(const dust3d::Uuid& withId = dust3d::Uuid());
|
||||||
};
|
};
|
||||||
|
@ -641,6 +642,7 @@ signals:
|
||||||
void boneRemoved(const dust3d::Uuid& boneId);
|
void boneRemoved(const dust3d::Uuid& boneId);
|
||||||
void boneAttachmentChanged(const dust3d::Uuid& boneId);
|
void boneAttachmentChanged(const dust3d::Uuid& boneId);
|
||||||
void boneNodesChanged(const dust3d::Uuid& boneId);
|
void boneNodesChanged(const dust3d::Uuid& boneId);
|
||||||
|
void boneNameChanged(const dust3d::Uuid& boneId);
|
||||||
void rigChanged();
|
void rigChanged();
|
||||||
|
|
||||||
public: // need initialize
|
public: // need initialize
|
||||||
|
@ -668,10 +670,9 @@ public: // need initialize
|
||||||
std::map<dust3d::Uuid, Node> nodeMap;
|
std::map<dust3d::Uuid, Node> nodeMap;
|
||||||
std::map<dust3d::Uuid, Edge> edgeMap;
|
std::map<dust3d::Uuid, Edge> edgeMap;
|
||||||
std::map<dust3d::Uuid, Component> componentMap;
|
std::map<dust3d::Uuid, Component> componentMap;
|
||||||
|
Component rootComponent;
|
||||||
std::map<dust3d::Uuid, Bone> boneMap;
|
std::map<dust3d::Uuid, Bone> boneMap;
|
||||||
std::vector<dust3d::Uuid> boneIdList;
|
std::vector<dust3d::Uuid> boneIdList;
|
||||||
Component rootComponent;
|
|
||||||
Bone rootBone;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Document();
|
Document();
|
||||||
|
@ -872,6 +873,7 @@ public slots:
|
||||||
void removeNodesFromBone(const dust3d::Uuid& boneId, const std::vector<dust3d::Uuid>& nodeIds);
|
void removeNodesFromBone(const dust3d::Uuid& boneId, const std::vector<dust3d::Uuid>& nodeIds);
|
||||||
void removeBone(const dust3d::Uuid& boneId);
|
void removeBone(const dust3d::Uuid& boneId);
|
||||||
void setBoneAttachment(const dust3d::Uuid& boneId, const dust3d::Uuid& toBoneId, int toBoneJointIndex);
|
void setBoneAttachment(const dust3d::Uuid& boneId, const dust3d::Uuid& toBoneId, int toBoneJointIndex);
|
||||||
|
void renameBone(const dust3d::Uuid& boneId, const QString& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile);
|
void resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile);
|
||||||
|
|
|
@ -103,6 +103,20 @@ void loadSnapshotFromXmlString(Snapshot* snapshot, char* xmlString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rapidxml::xml_node<>* bones = canvas->first_node("bones");
|
||||||
|
if (nullptr != bones) {
|
||||||
|
for (rapidxml::xml_node<>* node = bones->first_node(); nullptr != node; node = node->next_sibling()) {
|
||||||
|
rapidxml::xml_attribute<>* idAttribute = node->first_attribute("id");
|
||||||
|
if (nullptr != idAttribute) {
|
||||||
|
std::map<std::string, std::string>* boneMap = &snapshot->bones[idAttribute->value()];
|
||||||
|
for (rapidxml::xml_attribute<>* attribute = node->first_attribute();
|
||||||
|
attribute; attribute = attribute->next_attribute()) {
|
||||||
|
(*boneMap)[attribute->name()] = attribute->value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rapidxml::xml_node<>* partIdList = canvas->first_node("partIdList");
|
rapidxml::xml_node<>* partIdList = canvas->first_node("partIdList");
|
||||||
if (nullptr != partIdList) {
|
if (nullptr != partIdList) {
|
||||||
for (rapidxml::xml_node<>* partId = partIdList->first_node(); nullptr != partId; partId = partId->next_sibling()) {
|
for (rapidxml::xml_node<>* partId = partIdList->first_node(); nullptr != partId; partId = partId->next_sibling()) {
|
||||||
|
@ -218,6 +232,22 @@ void saveSnapshotToXmlString(const Snapshot& snapshot, std::string& xmlString)
|
||||||
}
|
}
|
||||||
xmlString += " </parts>\n";
|
xmlString += " </parts>\n";
|
||||||
|
|
||||||
|
if (!snapshot.bones.empty()) {
|
||||||
|
xmlString += " <bones>\n";
|
||||||
|
std::map<std::string, std::map<std::string, std::string>>::const_iterator boneIterator;
|
||||||
|
for (boneIterator = snapshot.bones.begin(); boneIterator != snapshot.bones.end(); boneIterator++) {
|
||||||
|
std::map<std::string, std::string>::const_iterator boneAttributeIterator;
|
||||||
|
xmlString += " <bone";
|
||||||
|
for (boneAttributeIterator = boneIterator->second.begin(); boneAttributeIterator != boneIterator->second.end(); boneAttributeIterator++) {
|
||||||
|
if (String::startsWith(boneAttributeIterator->first, "__"))
|
||||||
|
continue;
|
||||||
|
xmlString += " " + boneAttributeIterator->first + "=\"" + boneAttributeIterator->second + "\"";
|
||||||
|
}
|
||||||
|
xmlString += "/>\n";
|
||||||
|
}
|
||||||
|
xmlString += " </bones>\n";
|
||||||
|
}
|
||||||
|
|
||||||
const auto& childrenIds = snapshot.rootComponent.find("children");
|
const auto& childrenIds = snapshot.rootComponent.find("children");
|
||||||
if (childrenIds != snapshot.rootComponent.end()) {
|
if (childrenIds != snapshot.rootComponent.end()) {
|
||||||
xmlString += " <components>\n";
|
xmlString += " <components>\n";
|
||||||
|
|
|
@ -87,6 +87,11 @@ namespace String {
|
||||||
return (float)std::stod(string);
|
return (float)std::stod(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int toInt(const std::string& string)
|
||||||
|
{
|
||||||
|
return std::stoi(string);
|
||||||
|
}
|
||||||
|
|
||||||
std::string join(const std::vector<std::string>& stringList, const char* separator);
|
std::string join(const std::vector<std::string>& stringList, const char* separator);
|
||||||
|
|
||||||
inline std::string valueOrEmpty(const std::map<std::string, std::string>& map, const std::string& key)
|
inline std::string valueOrEmpty(const std::map<std::string, std::string>& map, const std::string& key)
|
||||||
|
|
Loading…
Reference in New Issue