Implement mesh state combine
parent
cb85a56364
commit
9fe28f84df
|
@ -20,6 +20,7 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dust3d/mesh/mesh_recombiner.h>
|
||||||
#include <dust3d/mesh/mesh_state.h>
|
#include <dust3d/mesh/mesh_state.h>
|
||||||
|
|
||||||
namespace dust3d {
|
namespace dust3d {
|
||||||
|
@ -30,4 +31,58 @@ void MeshState::fetch(std::vector<Vector3>& vertices, std::vector<std::vector<si
|
||||||
mesh->fetch(vertices, faces);
|
mesh->fetch(vertices, faces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MeshState> MeshState::combine(const MeshState& first, const MeshState& second,
|
||||||
|
MeshCombiner::Method method)
|
||||||
|
{
|
||||||
|
if (first.mesh->isNull() || second.mesh->isNull())
|
||||||
|
return nullptr;
|
||||||
|
std::vector<std::pair<MeshCombiner::Source, size_t>> combinedVerticesSources;
|
||||||
|
auto newMesh = std::unique_ptr<MeshCombiner::Mesh>(MeshCombiner::combine(*first.mesh,
|
||||||
|
*second.mesh,
|
||||||
|
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 (MeshState::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;
|
||||||
|
}
|
||||||
|
auto newMeshState = std::make_unique<MeshState>();
|
||||||
|
newMeshState->mesh = std::move(newMesh);
|
||||||
|
return newMeshState;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MeshState::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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,9 @@ public:
|
||||||
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;
|
||||||
|
|
||||||
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;
|
||||||
|
static std::unique_ptr<MeshState> combine(const MeshState& first, const MeshState& second,
|
||||||
|
MeshCombiner::Method method);
|
||||||
|
static bool isWatertight(const std::vector<std::vector<size_t>>& faces);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue