Add mesh state

master
Jeremy HU 2022-10-31 21:28:56 +11:00
parent 7ce09d1cd6
commit cb85a56364
8 changed files with 139 additions and 18 deletions

View File

@ -265,6 +265,8 @@ SOURCES += ../dust3d/mesh/mesh_generator.cc
HEADERS += ../dust3d/mesh/mesh_node.h HEADERS += ../dust3d/mesh/mesh_node.h
HEADERS += ../dust3d/mesh/mesh_recombiner.h HEADERS += ../dust3d/mesh/mesh_recombiner.h
SOURCES += ../dust3d/mesh/mesh_recombiner.cc SOURCES += ../dust3d/mesh/mesh_recombiner.cc
HEADERS += ../dust3d/mesh/mesh_state.h
SOURCES += ../dust3d/mesh/mesh_state.cc
HEADERS += ../dust3d/mesh/re_triangulator.h HEADERS += ../dust3d/mesh/re_triangulator.h
SOURCES += ../dust3d/mesh/re_triangulator.cc SOURCES += ../dust3d/mesh/re_triangulator.cc
HEADERS += ../dust3d/mesh/resolve_triangle_source_node.h HEADERS += ../dust3d/mesh/resolve_triangle_source_node.h

View File

@ -63,6 +63,7 @@ public:
std::vector<std::vector<size_t>> triangleAndQuads; std::vector<std::vector<size_t>> triangleAndQuads;
std::vector<std::vector<size_t>> triangles; std::vector<std::vector<size_t>> triangles;
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<Vector3> triangleNormals; std::vector<Vector3> triangleNormals;
std::vector<Color> triangleColors; std::vector<Color> triangleColors;
bool alphaEnabled = false; bool alphaEnabled = false;

View File

@ -900,7 +900,7 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentMesh(const st
groupMeshes.emplace_back(std::make_tuple(std::move(stitchingMesh), CombineMode::Normal, String::join(stitchingComponents, ":"))); groupMeshes.emplace_back(std::make_tuple(std::move(stitchingMesh), CombineMode::Normal, String::join(stitchingComponents, ":")));
} }
} }
mesh = combineMultipleMeshes(std::move(groupMeshes), true); mesh = combineMultipleMeshes(std::move(groupMeshes));
ComponentPreview preview; ComponentPreview preview;
if (mesh) if (mesh)
mesh->fetch(preview.vertices, preview.triangles); mesh->fetch(preview.vertices, preview.triangles);
@ -917,7 +917,7 @@ 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, bool recombine) std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshCombiner::Mesh>, CombineMode, std::string>>&& multipleMeshes)
{ {
std::unique_ptr<MeshCombiner::Mesh> mesh; std::unique_ptr<MeshCombiner::Mesh> mesh;
std::string meshIdStrings; std::string meshIdStrings;
@ -936,23 +936,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;
if (recombine)
meshIdStrings += "!";
std::unique_ptr<MeshCombiner::Mesh> newMesh; std::unique_ptr<MeshCombiner::Mesh> 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) { if (nullptr != findCached->second.mesh) {
newMesh = std::make_unique<MeshCombiner::Mesh>(*findCached->second); newMesh = std::make_unique<MeshCombiner::Mesh>(*findCached->second.mesh);
} }
} else { } else {
newMesh = combineTwoMeshes(*mesh, newMesh = combineTwoMeshes(*mesh,
*subMesh, *subMesh,
combinerMethod, combinerMethod);
recombine);
if (nullptr != newMesh) if (nullptr != newMesh)
m_cacheContext->cachedCombination.insert({ meshIdStrings, std::make_unique<MeshCombiner::Mesh>(*newMesh) }); m_cacheContext->cachedCombination.insert({ meshIdStrings, GeneratedCombination { std::make_unique<MeshCombiner::Mesh>(*newMesh) } });
else else
m_cacheContext->cachedCombination.insert({ meshIdStrings, nullptr }); m_cacheContext->cachedCombination.insert({ meshIdStrings, GeneratedCombination {} });
} }
if (newMesh && !newMesh->isNull()) { if (newMesh && !newMesh->isNull()) {
mesh = std::move(newMesh); mesh = std::move(newMesh);
@ -984,6 +981,8 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentChildGroupMes
componentCache.sharedQuadEdges.insert(it); componentCache.sharedQuadEdges.insert(it);
for (const auto& it : childComponentCache.partTriangleUvs) for (const auto& it : childComponentCache.partTriangleUvs)
componentCache.partTriangleUvs.insert({ it.first, it.second }); componentCache.partTriangleUvs.insert({ it.first, it.second });
for (const auto& it : childComponentCache.seamTriangleUvs)
componentCache.seamTriangleUvs.push_back(it);
for (const auto& it : childComponentCache.objectNodes) for (const auto& it : childComponentCache.objectNodes)
componentCache.objectNodes.push_back(it); componentCache.objectNodes.push_back(it);
for (const auto& it : childComponentCache.objectEdges) for (const auto& it : childComponentCache.objectEdges)
@ -1001,8 +1000,7 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineComponentChildGroupMes
} }
std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineTwoMeshes(const MeshCombiner::Mesh& first, const MeshCombiner::Mesh& second, std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineTwoMeshes(const MeshCombiner::Mesh& first, const MeshCombiner::Mesh& second,
MeshCombiner::Method method, MeshCombiner::Method method)
bool recombine)
{ {
if (first.isNull() || second.isNull()) if (first.isNull() || second.isNull())
return nullptr; return nullptr;
@ -1013,7 +1011,7 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combineTwoMeshes(const MeshCo
&combinedVerticesSources)); &combinedVerticesSources));
if (nullptr == newMesh) if (nullptr == newMesh)
return nullptr; return nullptr;
if (!newMesh->isNull() && recombine) { if (!newMesh->isNull()) {
MeshRecombiner recombiner; MeshRecombiner recombiner;
std::vector<Vector3> combinedVertices; std::vector<Vector3> combinedVertices;
std::vector<std::vector<size_t>> combinedFaces; std::vector<std::vector<size_t>> combinedFaces;
@ -1352,6 +1350,7 @@ void MeshGenerator::generate()
m_object->nodes = componentCache.objectNodes; m_object->nodes = componentCache.objectNodes;
m_object->edges = componentCache.objectEdges; m_object->edges = componentCache.objectEdges;
m_object->partTriangleUvs = componentCache.partTriangleUvs; m_object->partTriangleUvs = componentCache.partTriangleUvs;
m_object->seamTriangleUvs = componentCache.seamTriangleUvs;
m_nodeVertices = componentCache.objectNodeVertices; m_nodeVertices = componentCache.objectNodeVertices;
std::vector<Vector3> combinedVertices; std::vector<Vector3> combinedVertices;

View File

@ -73,6 +73,7 @@ public:
std::unique_ptr<MeshCombiner::Mesh> mesh; std::unique_ptr<MeshCombiner::Mesh> 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::set<PositionKey> noneSeamVertices; std::set<PositionKey> noneSeamVertices;
std::vector<ObjectNode> objectNodes; std::vector<ObjectNode> objectNodes;
std::vector<std::pair<std::pair<Uuid, Uuid>, std::pair<Uuid, Uuid>>> objectEdges; std::vector<std::pair<std::pair<Uuid, Uuid>, std::pair<Uuid, Uuid>>> objectEdges;
@ -82,6 +83,7 @@ public:
mesh.reset(); mesh.reset();
sharedQuadEdges.clear(); sharedQuadEdges.clear();
partTriangleUvs.clear(); partTriangleUvs.clear();
seamTriangleUvs.clear();
noneSeamVertices.clear(); noneSeamVertices.clear();
objectNodes.clear(); objectNodes.clear();
objectEdges.clear(); objectEdges.clear();
@ -89,11 +91,16 @@ 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, std::unique_ptr<MeshCombiner::Mesh>> cachedCombination; std::map<std::string, GeneratedCombination> cachedCombination;
}; };
struct ComponentPreview { struct ComponentPreview {
@ -158,13 +165,12 @@ private:
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, std::unique_ptr<MeshCombiner::Mesh> combineTwoMeshes(const MeshCombiner::Mesh& first, const MeshCombiner::Mesh& second,
MeshCombiner::Method method, MeshCombiner::Method method);
bool recombine = true);
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<MeshCombiner::Mesh> 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, bool recombine = true); std::unique_ptr<MeshCombiner::Mesh> combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshCombiner::Mesh>, CombineMode, std::string>>&& multipleMeshes);
std::unique_ptr<MeshCombiner::Mesh> combineStitchingMesh(const std::vector<std::string>& partIdStrings, std::unique_ptr<MeshCombiner::Mesh> combineStitchingMesh(const std::vector<std::string>& partIdStrings,
const std::vector<std::string>& componentIdStrings, const std::vector<std::string>& componentIdStrings,
GeneratedComponent& componentCache); GeneratedComponent& componentCache);

View File

@ -149,7 +149,7 @@ bool MeshRecombiner::recombine()
} }
} }
std::map<size_t, size_t> seamVertexToIslandMap; std::map<size_t, size_t> seamVertexToIslandMap;
size_t islands = splitSeamVerticesToIslands(seamLink, &seamVertexToIslandMap); splitSeamVerticesToIslands(seamLink, &seamVertexToIslandMap);
std::map<std::pair<size_t, size_t>, std::pair<size_t, bool>> edgesInSeamArea; std::map<std::pair<size_t, size_t>, std::pair<size_t, bool>> edgesInSeamArea;
for (size_t faceIndex = 0; faceIndex < (*m_faces).size(); ++faceIndex) { for (size_t faceIndex = 0; faceIndex < (*m_faces).size(); ++faceIndex) {
@ -376,6 +376,22 @@ bool MeshRecombiner::bridge(const std::vector<size_t>& first, const std::vector<
void MeshRecombiner::fillPairs(const std::vector<size_t>& small, const std::vector<size_t>& large) void MeshRecombiner::fillPairs(const std::vector<size_t>& small, const std::vector<size_t>& large)
{ {
std::vector<std::pair<std::array<Vector3, 3>, std::array<Vector2, 3>>> bridgingFaceUvs;
std::vector<double> leftV(small.size(), 0.0);
double leftOffset = 0.0;
for (size_t j = 1; j < small.size(); ++j) {
leftOffset += ((*m_vertices)[small[j]] - (*m_vertices)[small[j - 1]]).length();
leftV[j] = leftOffset;
}
std::vector<double> rightV(large.size(), 0.0);
double rightOffset = 0.0;
for (size_t j = 1; j < large.size(); ++j) {
rightOffset += ((*m_vertices)[large[j]] - (*m_vertices)[large[j - 1]]).length();
rightV[j] = rightOffset;
}
size_t smallIndex = 0; size_t smallIndex = 0;
size_t largeIndex = 0; size_t largeIndex = 0;
while (smallIndex + 1 < small.size() || largeIndex + 1 < large.size()) { while (smallIndex + 1 < small.size() || largeIndex + 1 < large.size()) {
@ -388,12 +404,18 @@ void MeshRecombiner::fillPairs(const std::vector<size_t>& small, const std::vect
m_regeneratedFaces.push_back({ small[smallIndex], m_regeneratedFaces.push_back({ small[smallIndex],
small[smallIndex + 1], small[smallIndex + 1],
large[largeIndex] }); large[largeIndex] });
bridgingFaceUvs.emplace_back(std::make_pair(
std::array<Vector3, 3> { (*m_vertices)[small[smallIndex]], (*m_vertices)[small[smallIndex + 1]], (*m_vertices)[large[largeIndex]] },
std::array<Vector2, 3> { Vector2(0.0, leftV[smallIndex]), Vector2(0.0, leftV[smallIndex + 1]), Vector2(1.0, rightV[largeIndex]) }));
++smallIndex; ++smallIndex;
continue; continue;
} }
m_regeneratedFaces.push_back({ large[largeIndex + 1], m_regeneratedFaces.push_back({ large[largeIndex + 1],
large[largeIndex], large[largeIndex],
small[smallIndex] }); small[smallIndex] });
bridgingFaceUvs.emplace_back(std::make_pair(
std::array<Vector3, 3> { (*m_vertices)[large[largeIndex + 1]], (*m_vertices)[large[largeIndex]], (*m_vertices)[small[smallIndex]] },
std::array<Vector2, 3> { Vector2(1.0, rightV[largeIndex + 1]), Vector2(1.0, rightV[largeIndex]), Vector2(0.0, rightV[largeIndex]) }));
++largeIndex; ++largeIndex;
continue; continue;
} }
@ -401,6 +423,9 @@ void MeshRecombiner::fillPairs(const std::vector<size_t>& small, const std::vect
m_regeneratedFaces.push_back({ large[largeIndex + 1], m_regeneratedFaces.push_back({ large[largeIndex + 1],
large[largeIndex], large[largeIndex],
small[smallIndex] }); small[smallIndex] });
bridgingFaceUvs.emplace_back(std::make_pair(
std::array<Vector3, 3> { (*m_vertices)[large[largeIndex + 1]], (*m_vertices)[large[largeIndex]], (*m_vertices)[small[smallIndex]] },
std::array<Vector2, 3> { Vector2(1.0, rightV[largeIndex + 1]), Vector2(1.0, rightV[largeIndex]), Vector2(0.0, rightV[largeIndex]) }));
++largeIndex; ++largeIndex;
continue; continue;
} }
@ -408,11 +433,16 @@ void MeshRecombiner::fillPairs(const std::vector<size_t>& small, const std::vect
m_regeneratedFaces.push_back({ small[smallIndex], m_regeneratedFaces.push_back({ small[smallIndex],
small[smallIndex + 1], small[smallIndex + 1],
large[largeIndex] }); large[largeIndex] });
bridgingFaceUvs.emplace_back(std::make_pair(
std::array<Vector3, 3> { (*m_vertices)[small[smallIndex]], (*m_vertices)[small[smallIndex + 1]], (*m_vertices)[large[largeIndex]] },
std::array<Vector2, 3> { Vector2(0.0, leftV[smallIndex]), Vector2(0.0, leftV[smallIndex + 1]), Vector2(1.0, rightV[largeIndex]) }));
++smallIndex; ++smallIndex;
continue; continue;
} }
break; break;
} }
m_generatedBridgingTriangleUvs.emplace_back(bridgingFaceUvs);
} }
void MeshRecombiner::removeReluctantVertices() void MeshRecombiner::removeReluctantVertices()
@ -438,4 +468,9 @@ void MeshRecombiner::removeReluctantVertices()
m_regeneratedFaces = rearrangedFaces; m_regeneratedFaces = rearrangedFaces;
} }
const std::vector<std::vector<std::pair<std::array<Vector3, 3>, std::array<Vector2, 3>>>>& MeshRecombiner::generatedBridgingTriangleUvs()
{
return m_generatedBridgingTriangleUvs;
}
} }

View File

@ -23,6 +23,7 @@
#ifndef DUST3D_MESH_MESH_RECOMBINER_H_ #ifndef DUST3D_MESH_MESH_RECOMBINER_H_
#define DUST3D_MESH_MESH_RECOMBINER_H_ #define DUST3D_MESH_MESH_RECOMBINER_H_
#include <dust3d/base/vector2.h>
#include <dust3d/mesh/mesh_combiner.h> #include <dust3d/mesh/mesh_combiner.h>
#include <map> #include <map>
#include <set> #include <set>
@ -38,6 +39,7 @@ public:
const std::vector<Vector3>& regeneratedVertices(); const std::vector<Vector3>& regeneratedVertices();
const std::vector<std::pair<MeshCombiner::Source, size_t>>& regeneratedVerticesSourceIndices(); const std::vector<std::pair<MeshCombiner::Source, size_t>>& regeneratedVerticesSourceIndices();
const std::vector<std::vector<size_t>>& regeneratedFaces(); const std::vector<std::vector<size_t>>& regeneratedFaces();
const std::vector<std::vector<std::pair<std::array<Vector3, 3>, std::array<Vector2, 3>>>>& generatedBridgingTriangleUvs();
bool recombine(); bool recombine();
private: private:
@ -50,6 +52,7 @@ private:
std::map<std::pair<size_t, size_t>, size_t> m_halfEdgeToFaceMap; std::map<std::pair<size_t, size_t>, size_t> m_halfEdgeToFaceMap;
std::map<size_t, size_t> m_facesInSeamArea; std::map<size_t, size_t> m_facesInSeamArea;
std::set<size_t> m_goodSeams; std::set<size_t> m_goodSeams;
std::vector<std::vector<std::pair<std::array<Vector3, 3>, std::array<Vector2, 3>>>> m_generatedBridgingTriangleUvs;
bool addFaceToHalfEdgeToFaceMap(size_t faceIndex, bool addFaceToHalfEdgeToFaceMap(size_t faceIndex,
std::map<std::pair<size_t, size_t>, size_t>& halfEdgeToFaceMap); std::map<std::pair<size_t, size_t>, size_t>& halfEdgeToFaceMap);

33
dust3d/mesh/mesh_state.cc Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2016-2022 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/mesh/mesh_state.h>
namespace dust3d {
void MeshState::fetch(std::vector<Vector3>& vertices, std::vector<std::vector<size_t>>& faces) const
{
if (mesh)
mesh->fetch(vertices, faces);
}
}

42
dust3d/mesh/mesh_state.h Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2016-2022 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_MESH_MESH_STATE_H_
#define DUST3D_MESH_MESH_STATE_H_
#include <dust3d/base/position_key.h>
#include <dust3d/mesh/mesh_combiner.h>
#include <map>
namespace dust3d {
class MeshState {
public:
std::unique_ptr<MeshCombiner::Mesh> mesh;
std::vector<std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> seamTriangleUvs;
void fetch(std::vector<Vector3>& vertices, std::vector<std::vector<size_t>>& faces) const;
};
}
#endif