Use MeshState in MeshGenerator
parent
9fe28f84df
commit
1fa1e0e199
|
@ -103,24 +103,6 @@ void MeshGenerator::subdivideFace(std::vector<Vector2>* face)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MeshGenerator::isWatertight(const std::vector<std::vector<size_t>>& faces)
|
|
||||||
{
|
|
||||||
std::set<std::pair<size_t, size_t>> halfEdges;
|
|
||||||
for (const auto& face : faces) {
|
|
||||||
for (size_t i = 0; i < face.size(); ++i) {
|
|
||||||
size_t j = (i + 1) % face.size();
|
|
||||||
auto insertResult = halfEdges.insert({ face[i], face[j] });
|
|
||||||
if (!insertResult.second)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto& it : halfEdges) {
|
|
||||||
if (halfEdges.find({ it.second, it.first }) == halfEdges.end())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeshGenerator::recoverQuads(const std::vector<Vector3>& vertices, const std::vector<std::vector<size_t>>& triangles, const std::set<std::pair<PositionKey, PositionKey>>& sharedQuadEdges, std::vector<std::vector<size_t>>& triangleAndQuads)
|
void MeshGenerator::recoverQuads(const std::vector<Vector3>& vertices, const std::vector<std::vector<size_t>>& triangles, const std::set<std::pair<PositionKey, PositionKey>>& sharedQuadEdges, std::vector<std::vector<size_t>>& triangleAndQuads)
|
||||||
{
|
{
|
||||||
std::vector<PositionKey> verticesPositionKeys;
|
std::vector<PositionKey> verticesPositionKeys;
|
||||||
|
@ -439,7 +421,7 @@ bool MeshGenerator::fetchPartOrderedNodes(const std::string& partIdString, std::
|
||||||
|
|
||||||
builderNodeIdStringToIndexMap.insert({ nodeIdString, builderNodes.size() });
|
builderNodeIdStringToIndexMap.insert({ nodeIdString, builderNodes.size() });
|
||||||
builderNodes.emplace_back(MeshNode {
|
builderNodes.emplace_back(MeshNode {
|
||||||
Vector3((double)x, (double)y, (double)z), (double)radius });
|
Vector3((double)x, (double)y, (double)z), (double)radius, Uuid(nodeIdString) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builderNodes.empty()) {
|
if (builderNodes.empty()) {
|
||||||
|
@ -480,7 +462,7 @@ bool MeshGenerator::fetchPartOrderedNodes(const std::string& partIdString, std::
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineStitchingMesh(const std::vector<std::string>& partIdStrings,
|
std::unique_ptr<MeshState> MeshGenerator::combineStitchingMesh(const std::vector<std::string>& partIdStrings,
|
||||||
const std::vector<std::string>& componentIdStrings,
|
const std::vector<std::string>& componentIdStrings,
|
||||||
GeneratedComponent& componentCache)
|
GeneratedComponent& componentCache)
|
||||||
{
|
{
|
||||||
|
@ -511,7 +493,7 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineStitchingMesh(const st
|
||||||
stitchMeshBuilder->generatedFaces(),
|
stitchMeshBuilder->generatedFaces(),
|
||||||
&componentCache.sharedQuadEdges);
|
&componentCache.sharedQuadEdges);
|
||||||
|
|
||||||
auto mesh = std::make_unique<MeshCombiner::Mesh>(stitchMeshBuilder->generatedVertices(),
|
auto mesh = std::make_unique<MeshState>(stitchMeshBuilder->generatedVertices(),
|
||||||
stitchMeshBuilder->generatedFaces());
|
stitchMeshBuilder->generatedFaces());
|
||||||
if (mesh && mesh->isNull())
|
if (mesh && mesh->isNull())
|
||||||
mesh.reset();
|
mesh.reset();
|
||||||
|
@ -563,7 +545,7 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineStitchingMesh(const st
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combinePartMesh(const std::string& partIdString,
|
std::unique_ptr<MeshState> MeshGenerator::combinePartMesh(const std::string& partIdString,
|
||||||
const std::string& componentIdString,
|
const std::string& componentIdString,
|
||||||
bool* hasError)
|
bool* hasError)
|
||||||
{
|
{
|
||||||
|
@ -704,9 +686,9 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combinePartMesh(const std::st
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasMeshError = false;
|
bool hasMeshError = false;
|
||||||
std::unique_ptr<MeshCombiner::Mesh> mesh;
|
std::unique_ptr<MeshState> mesh;
|
||||||
|
|
||||||
mesh = std::make_unique<MeshCombiner::Mesh>(partCache.vertices, partCache.faces);
|
mesh = std::make_unique<MeshState>(partCache.vertices, partCache.faces);
|
||||||
if (mesh->isNull()) {
|
if (mesh->isNull()) {
|
||||||
hasMeshError = true;
|
hasMeshError = true;
|
||||||
}
|
}
|
||||||
|
@ -800,9 +782,9 @@ std::string MeshGenerator::componentColorName(const std::map<std::string, std::s
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode)
|
std::unique_ptr<MeshState> MeshGenerator::combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode)
|
||||||
{
|
{
|
||||||
std::unique_ptr<MeshCombiner::Mesh> mesh;
|
std::unique_ptr<MeshState> mesh;
|
||||||
|
|
||||||
Uuid componentId;
|
Uuid componentId;
|
||||||
const std::map<std::string, std::string>* component = &m_snapshot->rootComponent;
|
const std::map<std::string, std::string>* component = &m_snapshot->rootComponent;
|
||||||
|
@ -822,7 +804,7 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentMesh(const st
|
||||||
if (m_cacheEnabled) {
|
if (m_cacheEnabled) {
|
||||||
if (m_dirtyComponentIds.find(componentIdString) == m_dirtyComponentIds.end()) {
|
if (m_dirtyComponentIds.find(componentIdString) == m_dirtyComponentIds.end()) {
|
||||||
if (nullptr != componentCache.mesh)
|
if (nullptr != componentCache.mesh)
|
||||||
return std::make_unique<MeshCombiner::Mesh>(*componentCache.mesh);
|
return std::make_unique<MeshState>(*componentCache.mesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -887,7 +869,7 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentMesh(const st
|
||||||
}
|
}
|
||||||
combineGroups[currentGroupIndex].second.push_back(childIdString);
|
combineGroups[currentGroupIndex].second.push_back(childIdString);
|
||||||
}
|
}
|
||||||
std::vector<std::tuple<std::unique_ptr<MeshCombiner::Mesh>, CombineMode, std::string>> groupMeshes;
|
std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>> groupMeshes;
|
||||||
for (const auto& group : combineGroups) {
|
for (const auto& group : combineGroups) {
|
||||||
auto childMesh = combineComponentChildGroupMesh(group.second, componentCache);
|
auto childMesh = combineComponentChildGroupMesh(group.second, componentCache);
|
||||||
if (nullptr == childMesh || childMesh->isNull())
|
if (nullptr == childMesh || childMesh->isNull())
|
||||||
|
@ -908,7 +890,7 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentMesh(const st
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr != mesh)
|
if (nullptr != mesh)
|
||||||
componentCache.mesh = std::make_unique<MeshCombiner::Mesh>(*mesh);
|
componentCache.mesh = std::make_unique<MeshState>(*mesh);
|
||||||
|
|
||||||
if (nullptr != mesh && mesh->isNull()) {
|
if (nullptr != mesh && mesh->isNull()) {
|
||||||
mesh.reset();
|
mesh.reset();
|
||||||
|
@ -917,9 +899,9 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentMesh(const st
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshCombiner::Mesh>, CombineMode, std::string>>&& multipleMeshes)
|
std::unique_ptr<MeshState> MeshGenerator::combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>>&& multipleMeshes)
|
||||||
{
|
{
|
||||||
std::unique_ptr<MeshCombiner::Mesh> mesh;
|
std::unique_ptr<MeshState> mesh;
|
||||||
std::string meshIdStrings;
|
std::string meshIdStrings;
|
||||||
for (auto& it : multipleMeshes) {
|
for (auto& it : multipleMeshes) {
|
||||||
auto subMesh = std::move(std::get<0>(it));
|
auto subMesh = std::move(std::get<0>(it));
|
||||||
|
@ -936,20 +918,20 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineMultipleMeshes(std::ve
|
||||||
auto combinerMethod = childCombineMode == CombineMode::Inversion ? MeshCombiner::Method::Diff : MeshCombiner::Method::Union;
|
auto combinerMethod = childCombineMode == CombineMode::Inversion ? MeshCombiner::Method::Diff : MeshCombiner::Method::Union;
|
||||||
auto combinerMethodString = combinerMethod == MeshCombiner::Method::Union ? "+" : "-";
|
auto combinerMethodString = combinerMethod == MeshCombiner::Method::Union ? "+" : "-";
|
||||||
meshIdStrings += combinerMethodString + subMeshIdString;
|
meshIdStrings += combinerMethodString + subMeshIdString;
|
||||||
std::unique_ptr<MeshCombiner::Mesh> newMesh;
|
std::unique_ptr<MeshState> newMesh;
|
||||||
auto findCached = m_cacheContext->cachedCombination.find(meshIdStrings);
|
auto findCached = m_cacheContext->cachedCombination.find(meshIdStrings);
|
||||||
if (findCached != m_cacheContext->cachedCombination.end()) {
|
if (findCached != m_cacheContext->cachedCombination.end()) {
|
||||||
if (nullptr != findCached->second.mesh) {
|
if (nullptr != findCached->second) {
|
||||||
newMesh = std::make_unique<MeshCombiner::Mesh>(*findCached->second.mesh);
|
newMesh = std::make_unique<MeshState>(*findCached->second);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newMesh = combineTwoMeshes(*mesh,
|
newMesh = MeshState::combine(*mesh,
|
||||||
*subMesh,
|
*subMesh,
|
||||||
combinerMethod);
|
combinerMethod);
|
||||||
if (nullptr != newMesh)
|
if (nullptr != newMesh)
|
||||||
m_cacheContext->cachedCombination.insert({ meshIdStrings, GeneratedCombination { std::make_unique<MeshCombiner::Mesh>(*newMesh) } });
|
m_cacheContext->cachedCombination.insert({ meshIdStrings, std::make_unique<MeshState>(*newMesh) });
|
||||||
else
|
else
|
||||||
m_cacheContext->cachedCombination.insert({ meshIdStrings, GeneratedCombination {} });
|
m_cacheContext->cachedCombination.insert({ meshIdStrings, nullptr });
|
||||||
}
|
}
|
||||||
if (newMesh && !newMesh->isNull()) {
|
if (newMesh && !newMesh->isNull()) {
|
||||||
mesh = std::move(newMesh);
|
mesh = std::move(newMesh);
|
||||||
|
@ -963,12 +945,12 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineMultipleMeshes(std::ve
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentChildGroupMesh(const std::vector<std::string>& componentIdStrings, GeneratedComponent& componentCache)
|
std::unique_ptr<MeshState> MeshGenerator::combineComponentChildGroupMesh(const std::vector<std::string>& componentIdStrings, GeneratedComponent& componentCache)
|
||||||
{
|
{
|
||||||
std::vector<std::tuple<std::unique_ptr<MeshCombiner::Mesh>, CombineMode, std::string>> multipleMeshes;
|
std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>> multipleMeshes;
|
||||||
for (const auto& childIdString : componentIdStrings) {
|
for (const auto& childIdString : componentIdStrings) {
|
||||||
CombineMode childCombineMode = CombineMode::Normal;
|
CombineMode childCombineMode = CombineMode::Normal;
|
||||||
std::unique_ptr<MeshCombiner::Mesh> subMesh = combineComponentMesh(childIdString, &childCombineMode);
|
std::unique_ptr<MeshState> subMesh = combineComponentMesh(childIdString, &childCombineMode);
|
||||||
|
|
||||||
if (CombineMode::Uncombined == childCombineMode) {
|
if (CombineMode::Uncombined == childCombineMode) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -999,40 +981,6 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentChildGroupMes
|
||||||
return combineMultipleMeshes(std::move(multipleMeshes));
|
return combineMultipleMeshes(std::move(multipleMeshes));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineTwoMeshes(const MeshCombiner::Mesh& first, const MeshCombiner::Mesh& second,
|
|
||||||
MeshCombiner::Method method)
|
|
||||||
{
|
|
||||||
if (first.isNull() || second.isNull())
|
|
||||||
return nullptr;
|
|
||||||
std::vector<std::pair<MeshCombiner::Source, size_t>> combinedVerticesSources;
|
|
||||||
auto newMesh = std::unique_ptr<MeshCombiner::Mesh>(MeshCombiner::combine(first,
|
|
||||||
second,
|
|
||||||
method,
|
|
||||||
&combinedVerticesSources));
|
|
||||||
if (nullptr == newMesh)
|
|
||||||
return nullptr;
|
|
||||||
if (!newMesh->isNull()) {
|
|
||||||
MeshRecombiner recombiner;
|
|
||||||
std::vector<Vector3> combinedVertices;
|
|
||||||
std::vector<std::vector<size_t>> combinedFaces;
|
|
||||||
newMesh->fetch(combinedVertices, combinedFaces);
|
|
||||||
recombiner.setVertices(&combinedVertices, &combinedVerticesSources);
|
|
||||||
recombiner.setFaces(&combinedFaces);
|
|
||||||
if (recombiner.recombine()) {
|
|
||||||
if (isWatertight(recombiner.regeneratedFaces())) {
|
|
||||||
auto reMesh = std::make_unique<MeshCombiner::Mesh>(recombiner.regeneratedVertices(), recombiner.regeneratedFaces());
|
|
||||||
if (!reMesh->isNull()) {
|
|
||||||
newMesh = std::move(reMesh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (newMesh->isNull()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return newMesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeshGenerator::makeXmirror(const std::vector<Vector3>& sourceVertices, const std::vector<std::vector<size_t>>& sourceFaces,
|
void MeshGenerator::makeXmirror(const std::vector<Vector3>& sourceVertices, const std::vector<std::vector<size_t>>& sourceFaces,
|
||||||
std::vector<Vector3>* destVertices, std::vector<std::vector<size_t>>* destFaces)
|
std::vector<Vector3>* destVertices, std::vector<std::vector<size_t>>* destFaces)
|
||||||
{
|
{
|
||||||
|
@ -1135,7 +1083,7 @@ void MeshGenerator::postprocessObject(Object* object)
|
||||||
object->setTriangleVertexNormals(triangleVertexNormals);
|
object->setTriangleVertexNormals(triangleVertexNormals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshGenerator::collectIncombinableMesh(const MeshCombiner::Mesh* mesh, const GeneratedComponent& componentCache)
|
void MeshGenerator::collectIncombinableMesh(const MeshState* mesh, const GeneratedComponent& componentCache)
|
||||||
{
|
{
|
||||||
if (nullptr == mesh)
|
if (nullptr == mesh)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <dust3d/base/uuid.h>
|
#include <dust3d/base/uuid.h>
|
||||||
#include <dust3d/mesh/mesh_combiner.h>
|
#include <dust3d/mesh/mesh_combiner.h>
|
||||||
#include <dust3d/mesh/mesh_node.h>
|
#include <dust3d/mesh/mesh_node.h>
|
||||||
|
#include <dust3d/mesh/mesh_state.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -70,7 +71,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GeneratedComponent {
|
struct GeneratedComponent {
|
||||||
std::unique_ptr<MeshCombiner::Mesh> mesh;
|
std::unique_ptr<MeshState> mesh;
|
||||||
std::set<std::pair<PositionKey, PositionKey>> sharedQuadEdges;
|
std::set<std::pair<PositionKey, PositionKey>> sharedQuadEdges;
|
||||||
std::unordered_map<Uuid, std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> partTriangleUvs;
|
std::unordered_map<Uuid, std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> partTriangleUvs;
|
||||||
std::vector<std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> seamTriangleUvs;
|
std::vector<std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> seamTriangleUvs;
|
||||||
|
@ -91,16 +92,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GeneratedCombination {
|
|
||||||
std::unique_ptr<MeshCombiner::Mesh> mesh;
|
|
||||||
std::vector<std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> seamTriangleUvs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GeneratedCacheContext {
|
struct GeneratedCacheContext {
|
||||||
std::map<std::string, GeneratedComponent> components;
|
std::map<std::string, GeneratedComponent> components;
|
||||||
std::map<std::string, GeneratedPart> parts;
|
std::map<std::string, GeneratedPart> parts;
|
||||||
std::map<std::string, std::string> partMirrorIdMap;
|
std::map<std::string, std::string> partMirrorIdMap;
|
||||||
std::map<std::string, GeneratedCombination> cachedCombination;
|
std::map<std::string, std::unique_ptr<MeshState>> cachedCombination;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ComponentPreview {
|
struct ComponentPreview {
|
||||||
|
@ -151,27 +147,25 @@ private:
|
||||||
bool m_weldEnabled = true;
|
bool m_weldEnabled = true;
|
||||||
|
|
||||||
void collectParts();
|
void collectParts();
|
||||||
void collectIncombinableMesh(const MeshCombiner::Mesh* mesh, const GeneratedComponent& componentCache);
|
void collectIncombinableMesh(const MeshState* mesh, const GeneratedComponent& componentCache);
|
||||||
bool checkIsComponentDirty(const std::string& componentIdString);
|
bool checkIsComponentDirty(const std::string& componentIdString);
|
||||||
bool checkIsPartDirty(const std::string& partIdString);
|
bool checkIsPartDirty(const std::string& partIdString);
|
||||||
bool checkIsPartDependencyDirty(const std::string& partIdString);
|
bool checkIsPartDependencyDirty(const std::string& partIdString);
|
||||||
void checkDirtyFlags();
|
void checkDirtyFlags();
|
||||||
std::unique_ptr<MeshCombiner::Mesh> combinePartMesh(const std::string& partIdString,
|
std::unique_ptr<MeshState> combinePartMesh(const std::string& partIdString,
|
||||||
const std::string& componentIdString,
|
const std::string& componentIdString,
|
||||||
bool* hasError);
|
bool* hasError);
|
||||||
std::unique_ptr<MeshCombiner::Mesh> combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode);
|
std::unique_ptr<MeshState> combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode);
|
||||||
void makeXmirror(const std::vector<Vector3>& sourceVertices, const std::vector<std::vector<size_t>>& sourceFaces,
|
void makeXmirror(const std::vector<Vector3>& sourceVertices, const std::vector<std::vector<size_t>>& sourceFaces,
|
||||||
std::vector<Vector3>* destVertices, std::vector<std::vector<size_t>>* destFaces);
|
std::vector<Vector3>* destVertices, std::vector<std::vector<size_t>>* destFaces);
|
||||||
void collectSharedQuadEdges(const std::vector<Vector3>& vertices, const std::vector<std::vector<size_t>>& faces,
|
void collectSharedQuadEdges(const std::vector<Vector3>& vertices, const std::vector<std::vector<size_t>>& faces,
|
||||||
std::set<std::pair<PositionKey, PositionKey>>* sharedQuadEdges);
|
std::set<std::pair<PositionKey, PositionKey>>* sharedQuadEdges);
|
||||||
std::unique_ptr<MeshCombiner::Mesh> combineTwoMeshes(const MeshCombiner::Mesh& first, const MeshCombiner::Mesh& second,
|
|
||||||
MeshCombiner::Method method);
|
|
||||||
const std::map<std::string, std::string>* findComponent(const std::string& componentIdString);
|
const std::map<std::string, std::string>* findComponent(const std::string& componentIdString);
|
||||||
CombineMode componentCombineMode(const std::map<std::string, std::string>* component);
|
CombineMode componentCombineMode(const std::map<std::string, std::string>* component);
|
||||||
std::unique_ptr<MeshCombiner::Mesh> combineComponentChildGroupMesh(const std::vector<std::string>& componentIdStrings,
|
std::unique_ptr<MeshState> combineComponentChildGroupMesh(const std::vector<std::string>& componentIdStrings,
|
||||||
GeneratedComponent& componentCache);
|
GeneratedComponent& componentCache);
|
||||||
std::unique_ptr<MeshCombiner::Mesh> combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshCombiner::Mesh>, CombineMode, std::string>>&& multipleMeshes);
|
std::unique_ptr<MeshState> combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>>&& multipleMeshes);
|
||||||
std::unique_ptr<MeshCombiner::Mesh> combineStitchingMesh(const std::vector<std::string>& partIdStrings,
|
std::unique_ptr<MeshState> combineStitchingMesh(const std::vector<std::string>& partIdStrings,
|
||||||
const std::vector<std::string>& componentIdStrings,
|
const std::vector<std::string>& componentIdStrings,
|
||||||
GeneratedComponent& componentCache);
|
GeneratedComponent& componentCache);
|
||||||
std::string componentColorName(const std::map<std::string, std::string>* component);
|
std::string componentColorName(const std::map<std::string, std::string>* component);
|
||||||
|
@ -187,7 +181,6 @@ private:
|
||||||
|
|
||||||
static void chamferFace(std::vector<Vector2>* face);
|
static void chamferFace(std::vector<Vector2>* face);
|
||||||
static void subdivideFace(std::vector<Vector2>* face);
|
static void subdivideFace(std::vector<Vector2>* face);
|
||||||
static bool isWatertight(const std::vector<std::vector<size_t>>& faces);
|
|
||||||
static void flattenLinks(const std::unordered_map<size_t, size_t>& links,
|
static void flattenLinks(const std::unordered_map<size_t, size_t>& links,
|
||||||
std::vector<size_t>* array,
|
std::vector<size_t>* array,
|
||||||
bool* isCircle);
|
bool* isCircle);
|
||||||
|
|
|
@ -25,17 +25,37 @@
|
||||||
|
|
||||||
namespace dust3d {
|
namespace dust3d {
|
||||||
|
|
||||||
|
MeshState::MeshState(const std::vector<Vector3>& vertices, const std::vector<std::vector<size_t>>& faces)
|
||||||
|
{
|
||||||
|
mesh = std::make_unique<MeshCombiner::Mesh>(vertices, faces);
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshState::MeshState(const MeshState& other)
|
||||||
|
{
|
||||||
|
if (nullptr != other.mesh)
|
||||||
|
mesh = std::make_unique<MeshCombiner::Mesh>(*other.mesh);
|
||||||
|
seamTriangleUvs = other.seamTriangleUvs;
|
||||||
|
}
|
||||||
|
|
||||||
void MeshState::fetch(std::vector<Vector3>& vertices, std::vector<std::vector<size_t>>& faces) const
|
void MeshState::fetch(std::vector<Vector3>& vertices, std::vector<std::vector<size_t>>& faces) const
|
||||||
{
|
{
|
||||||
if (mesh)
|
if (mesh)
|
||||||
mesh->fetch(vertices, faces);
|
mesh->fetch(vertices, faces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MeshState::isNull() const
|
||||||
|
{
|
||||||
|
if (nullptr == mesh)
|
||||||
|
return true;
|
||||||
|
return mesh->isNull();
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<MeshState> MeshState::combine(const MeshState& first, const MeshState& second,
|
std::unique_ptr<MeshState> MeshState::combine(const MeshState& first, const MeshState& second,
|
||||||
MeshCombiner::Method method)
|
MeshCombiner::Method method)
|
||||||
{
|
{
|
||||||
if (first.mesh->isNull() || second.mesh->isNull())
|
if (first.mesh->isNull() || second.mesh->isNull())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
auto newMeshState = std::make_unique<MeshState>();
|
||||||
std::vector<std::pair<MeshCombiner::Source, size_t>> combinedVerticesSources;
|
std::vector<std::pair<MeshCombiner::Source, size_t>> combinedVerticesSources;
|
||||||
auto newMesh = std::unique_ptr<MeshCombiner::Mesh>(MeshCombiner::combine(*first.mesh,
|
auto newMesh = std::unique_ptr<MeshCombiner::Mesh>(MeshCombiner::combine(*first.mesh,
|
||||||
*second.mesh,
|
*second.mesh,
|
||||||
|
@ -54,6 +74,19 @@ std::unique_ptr<MeshState> MeshState::combine(const MeshState& first, const Mesh
|
||||||
if (MeshState::isWatertight(recombiner.regeneratedFaces())) {
|
if (MeshState::isWatertight(recombiner.regeneratedFaces())) {
|
||||||
auto reMesh = std::make_unique<MeshCombiner::Mesh>(recombiner.regeneratedVertices(), recombiner.regeneratedFaces());
|
auto reMesh = std::make_unique<MeshCombiner::Mesh>(recombiner.regeneratedVertices(), recombiner.regeneratedFaces());
|
||||||
if (!reMesh->isNull()) {
|
if (!reMesh->isNull()) {
|
||||||
|
for (const auto& uvSeams : recombiner.generatedBridgingTriangleUvs()) {
|
||||||
|
std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>> uvs;
|
||||||
|
for (const auto& it : uvSeams) {
|
||||||
|
uvs.insert(std::make_pair(std::array<PositionKey, 3> {
|
||||||
|
PositionKey(it.first[0]),
|
||||||
|
PositionKey(it.first[1]),
|
||||||
|
PositionKey(it.first[2]) },
|
||||||
|
it.second));
|
||||||
|
}
|
||||||
|
if (uvs.empty())
|
||||||
|
continue;
|
||||||
|
newMeshState->seamTriangleUvs.push_back(uvs);
|
||||||
|
}
|
||||||
newMesh = std::move(reMesh);
|
newMesh = std::move(reMesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +95,6 @@ std::unique_ptr<MeshState> MeshState::combine(const MeshState& first, const Mesh
|
||||||
if (newMesh->isNull()) {
|
if (newMesh->isNull()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto newMeshState = std::make_unique<MeshState>();
|
|
||||||
newMeshState->mesh = std::move(newMesh);
|
newMeshState->mesh = std::move(newMesh);
|
||||||
return newMeshState;
|
return newMeshState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,11 @@ public:
|
||||||
std::unique_ptr<MeshCombiner::Mesh> mesh;
|
std::unique_ptr<MeshCombiner::Mesh> mesh;
|
||||||
std::vector<std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> seamTriangleUvs;
|
std::vector<std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> seamTriangleUvs;
|
||||||
|
|
||||||
|
MeshState() = default;
|
||||||
|
MeshState(const std::vector<Vector3>& vertices, const std::vector<std::vector<size_t>>& faces);
|
||||||
|
MeshState(const MeshState& other);
|
||||||
void fetch(std::vector<Vector3>& vertices, std::vector<std::vector<size_t>>& faces) const;
|
void fetch(std::vector<Vector3>& vertices, std::vector<std::vector<size_t>>& faces) const;
|
||||||
|
bool isNull() const;
|
||||||
static std::unique_ptr<MeshState> combine(const MeshState& first, const MeshState& second,
|
static std::unique_ptr<MeshState> combine(const MeshState& first, const MeshState& second,
|
||||||
MeshCombiner::Method method);
|
MeshCombiner::Method method);
|
||||||
static bool isWatertight(const std::vector<std::vector<size_t>>& faces);
|
static bool isWatertight(const std::vector<std::vector<size_t>>& faces);
|
||||||
|
|
Loading…
Reference in New Issue