Fix bone preview mesh

master
Jeremy HU 2022-12-04 03:58:33 +11:00
parent 03f1440e7d
commit 6e53452dc8
8 changed files with 76 additions and 47 deletions

View File

@ -1,7 +1,15 @@
#include "bone_generator.h"
#include <QDebug>
#include <QElapsedTimer>
#include <dust3d/mesh/smooth_normal.h>
#include <dust3d/mesh/trim_vertices.h>
BoneGenerator::BoneGenerator(std::unique_ptr<dust3d::Object> object, std::unique_ptr<dust3d::Snapshot> snapshot)
: m_object(std::move(object))
, m_snapshot(std::move(snapshot))
{
}
std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* BoneGenerator::takeBonePreviewMeshes()
{
return m_bonePreviewMeshes.release();
@ -9,6 +17,34 @@ std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* BoneGenerator::takeBonePrevi
void BoneGenerator::process()
{
QElapsedTimer countTimeConsumed;
countTimeConsumed.start();
setVertices(m_object->vertices);
setTriangles(m_object->triangles);
setPositionToNodeMap(m_object->positionToNodeIdMap);
for (const auto& it : m_object->nodeMap) {
Node node;
node.position = it.second.origin;
addNode(it.first, node);
}
for (const auto& it : m_snapshot->boneIdList) {
Bone bone;
addBone(dust3d::Uuid(it), bone);
}
for (const auto& it : m_snapshot->nodes) {
NodeBinding nodeBinding;
for (const auto& boneIdString : dust3d::String::split(dust3d::String::valueOrEmpty(it.second, "boneIdList"), ',')) {
if (boneIdString.empty())
continue;
nodeBinding.boneIds.insert(dust3d::Uuid(boneIdString));
}
addNodeBinding(dust3d::Uuid(it.first), nodeBinding);
}
generate();
m_bonePreviewMeshes = std::make_unique<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>>();
@ -36,5 +72,7 @@ void BoneGenerator::process()
previewTriangleVertexNormals);
}
qDebug() << "The bone generation took" << countTimeConsumed.elapsed() << "milliseconds";
emit finished();
}

View File

@ -3,6 +3,7 @@
#include "model_mesh.h"
#include <QObject>
#include <dust3d/base/snapshot.h>
#include <dust3d/rig/bone_generator.h>
#include <map>
#include <memory>
@ -10,6 +11,7 @@
class BoneGenerator : public QObject, public dust3d::BoneGenerator {
Q_OBJECT
public:
BoneGenerator(std::unique_ptr<dust3d::Object> object, std::unique_ptr<dust3d::Snapshot> snapshot);
std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* takeBonePreviewMeshes();
public slots:
void process();
@ -18,6 +20,8 @@ signals:
private:
std::unique_ptr<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>> m_bonePreviewMeshes;
std::unique_ptr<dust3d::Object> m_object;
std::unique_ptr<dust3d::Snapshot> m_snapshot;
};
#endif

View File

@ -3036,10 +3036,13 @@ void Document::generateBone()
emit boneGenerating();
// TODO:
auto object = std::make_unique<dust3d::Object>(*m_uvMappedObject);
auto snapshot = std::make_unique<dust3d::Snapshot>();
toSnapshot(snapshot.get());
QThread* thread = new QThread;
m_boneGenerator = std::make_unique<BoneGenerator>();
m_boneGenerator = std::make_unique<BoneGenerator>(std::move(object), std::move(snapshot));
m_boneGenerator->moveToThread(thread);
connect(thread, &QThread::started, m_boneGenerator.get(), &BoneGenerator::process);
connect(m_boneGenerator.get(), &BoneGenerator::finished, this, &Document::boneReady);

View File

@ -40,7 +40,7 @@ namespace dust3d {
struct ObjectNode {
//Uuid partId;
//Uuid nodeId;
//Vector3 origin;
Vector3 origin;
//float radius = 0.0;
Color color;
//float colorSolubility = 0.0;

View File

@ -641,7 +641,7 @@ std::unique_ptr<MeshState> MeshGenerator::combinePartMesh(const std::string& par
partCache.nodeMap.clear();
for (const auto& meshNode : meshNodes) {
partCache.nodeMap.emplace(std::make_pair(meshNode.sourceId,
ObjectNode { partColor }));
ObjectNode { meshNode.origin, partColor }));
}
if (PartTarget::Model == target) {
@ -767,30 +767,6 @@ CombineMode MeshGenerator::componentCombineMode(const std::map<std::string, std:
return combineMode;
}
std::string MeshGenerator::componentColorName(const std::map<std::string, std::string>* component)
{
if (nullptr == component)
return std::string();
std::string linkDataType = String::valueOrEmpty(*component, "linkDataType");
if ("partId" == linkDataType) {
std::string partIdString = String::valueOrEmpty(*component, "linkData");
auto findPart = m_snapshot->parts.find(partIdString);
if (findPart == m_snapshot->parts.end()) {
return std::string();
}
auto& part = findPart->second;
std::string colorSolubility = String::valueOrEmpty(part, "colorSolubility");
if (!colorSolubility.empty()) {
return std::string("+");
}
std::string colorName = String::valueOrEmpty(part, "color");
if (colorName.empty())
return std::string("-");
return colorName;
}
return std::string();
}
std::unique_ptr<MeshState> MeshGenerator::combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode)
{
std::unique_ptr<MeshState> mesh;

View File

@ -163,7 +163,6 @@ private:
std::unique_ptr<MeshState> combineStitchingMesh(const std::vector<std::string>& partIdStrings,
const std::vector<std::string>& componentIdStrings,
GeneratedComponent& componentCache);
std::string componentColorName(const std::map<std::string, std::string>* component);
void collectUncombinedComponent(const std::string& componentIdString);
void cutFaceStringToCutTemplate(const std::string& cutFaceString, std::vector<Vector2>& cutTemplate);
void postprocessObject(Object* object);

View File

@ -21,7 +21,6 @@
*/
#include <dust3d/rig/bone_generator.h>
#include <unordered_map>
namespace dust3d {
@ -161,25 +160,29 @@ std::map<Uuid, BoneGenerator::BonePreview>& BoneGenerator::bonePreviews()
return m_bonePreviews;
}
void BoneGenerator::addBonePreviewTriangle(BonePreview& bonePreview,
std::unordered_map<size_t, size_t>& oldToNewVertexMap,
const std::vector<size_t>& triangle)
{
std::vector<size_t> newTriangle(3);
for (size_t i = 0; i < 3; ++i) {
auto findVertex = oldToNewVertexMap.find(triangle[i]);
if (findVertex == oldToNewVertexMap.end()) {
oldToNewVertexMap.insert(std::make_pair(triangle[i], bonePreview.vertices.size()));
newTriangle[i] = bonePreview.vertices.size();
bonePreview.vertices.push_back(m_vertices[triangle[i]]);
} else {
newTriangle[i] = findVertex->second;
}
}
bonePreview.triangles.emplace_back(newTriangle);
}
void BoneGenerator::generateBonePreviews()
{
for (const auto& it : m_boneVertices) {
BonePreview bonePreview;
std::unordered_map<size_t, size_t> oldToNewVertexMap;
auto addTriangleAsLocal = [&](const std::vector<size_t>& globalTriangle) {
std::vector<size_t> newTriangle(3);
for (size_t i = 0; i < 3; ++i) {
auto findVertex = oldToNewVertexMap.find(globalTriangle[i]);
if (findVertex == oldToNewVertexMap.end()) {
oldToNewVertexMap.insert(std::make_pair(globalTriangle[i], bonePreview.vertices.size()));
newTriangle[i] = bonePreview.vertices.size();
bonePreview.vertices.push_back(m_vertices[globalTriangle[i]]);
} else {
newTriangle[i] = findVertex->first;
}
}
bonePreview.triangles.emplace_back(newTriangle);
};
for (const auto& triangle : m_triangles) {
size_t countedPoints = 0;
@ -189,7 +192,7 @@ void BoneGenerator::generateBonePreviews()
}
if (0 == countedPoints)
continue;
addTriangleAsLocal(triangle);
addBonePreviewTriangle(bonePreview, oldToNewVertexMap, triangle);
}
m_bonePreviews.emplace(std::make_pair(it.first, std::move(bonePreview)));

View File

@ -30,6 +30,7 @@
#include <dust3d/base/vector3.h>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
@ -64,14 +65,16 @@ public:
};
BoneGenerator();
void generate();
std::map<Uuid, BonePreview>& bonePreviews();
protected:
void setVertices(const std::vector<Vector3>& vertices);
void setTriangles(const std::vector<std::vector<size_t>>& triangles);
void setPositionToNodeMap(const std::map<PositionKey, Uuid>& positionToNodeMap);
void addBone(const Uuid& boneId, const Bone& bone);
void addNodeBinding(const Uuid& nodeId, const NodeBinding& nodeBidning);
void addNode(const Uuid& nodeId, const Node& node);
void generate();
std::map<Uuid, BonePreview>& bonePreviews();
private:
std::vector<Vector3> m_vertices;
@ -92,6 +95,9 @@ private:
void buildBoneJoints();
void assignVerticesToBoneJoints();
void generateBonePreviews();
void addBonePreviewTriangle(BonePreview& bonePreview,
std::unordered_map<size_t, size_t>& oldToNewVertexMap,
const std::vector<size_t>& triangle);
};
}