VOXELFORMAT: fixed endless loop in subdivideTri

master
Martin Gerhardy 2022-05-18 19:30:05 +02:00
parent c1d613ab34
commit 7d73a9f9ca
8 changed files with 19 additions and 17 deletions

View File

@ -640,7 +640,7 @@ bool GLTFFormat::loadGlftAttributes(const core::String &filename, core::StringMa
bool GLTFFormat::subdivideShape(const tinygltf::Model &model, const core::DynamicArray<uint32_t> &indices,
const core::DynamicArray<GltfVertex> &vertices,
const core::StringMap<image::ImagePtr> &textures,
core::DynamicArray<Tri> &subdivided) const {
TriCollection &subdivided) const {
const glm::vec3 &scale = getScale();
if (indices.size() % 3 != 0) {
Log::error("Unexpected amount of indices %i", (int)indices.size());
@ -761,6 +761,7 @@ bool GLTFFormat::loadGltfNode_r(const core::String &filename, SceneGraph &sceneG
Log::warn(
"Large meshes will take a lot of time and use a lot of memory. Consider scaling the mesh!");
}
Log::debug("region mins(%i:%i:%i)/maxs(%i:%i:%i)", imins.x, imins.y, imins.z, imaxs.x, imaxs.y, imaxs.z);
SceneGraphNode node;
const SceneGraphTransform &transform = loadGltfTransform(gltfNode);
@ -770,7 +771,7 @@ bool GLTFFormat::loadGltfNode_r(const core::String &filename, SceneGraph &sceneG
voxel::RawVolume *volume = new voxel::RawVolume(region);
node.setVolume(volume, true);
core::DynamicArray<Tri> subdivided;
TriCollection subdivided;
int newParent = parentNodeId;
if (!subdivideShape(model, indices, vertices, textures, subdivided)) {
Log::error("Failed to subdivide node %i", gltfNodeIdx);

View File

@ -57,7 +57,7 @@ private:
bool subdivideShape(const tinygltf::Model &model, const core::DynamicArray<uint32_t> &indices,
const core::DynamicArray<GltfVertex> &vertices, const core::StringMap<image::ImagePtr> &textures,
core::DynamicArray<Tri> &subdivided) const;
TriCollection &subdivided) const;
void calculateAABB(const core::DynamicArray<GltfVertex> &vertices, glm::vec3 &mins, glm::vec3 &maxs) const;
public:

View File

@ -40,11 +40,11 @@ bool MeshFormat::flipWinding(const glm::vec3 &scale) {
return (scale.x * scale.y * scale.z) < 0.0f ? true : false;
}
void MeshFormat::subdivideTri(const Tri &tri, core::DynamicArray<Tri> &tinyTris) {
void MeshFormat::subdivideTri(const Tri &tri, TriCollection &tinyTris) {
const glm::vec3 &mins = tri.mins();
const glm::vec3 &maxs = tri.maxs();
const glm::vec3 size = maxs - mins;
if (glm::any(glm::greaterThan(size, glm::vec3(1.0f)))) {
if (size.x * size.y * size.z > 1.0f) {
Tri out[4];
tri.subdivide(out);
for (int i = 0; i < lengthof(out); ++i) {
@ -55,10 +55,7 @@ void MeshFormat::subdivideTri(const Tri &tri, core::DynamicArray<Tri> &tinyTris)
tinyTris.push_back(tri);
}
void MeshFormat::voxelizeTris(voxel::RawVolume *volume, const core::DynamicArray<Tri> &subdivided) {
const voxel::Palette &pal = voxel::getPalette();
core::DynamicArray<glm::vec4> materialColors;
pal.toVec4f(materialColors);
void MeshFormat::voxelizeTris(voxel::RawVolume *volume, const TriCollection &subdivided) {
struct PosSamplingEntry {
inline PosSamplingEntry(float _area, const glm::vec4 &_color) : area(_area), color(_color) {
}
@ -107,6 +104,7 @@ void MeshFormat::voxelizeTris(voxel::RawVolume *volume, const core::DynamicArray
}
}
}
Log::debug("create voxels");
PaletteLookup palLookup;
for (const auto &entry : posMap) {
const PosSampling &pos = entry->second;
@ -115,6 +113,7 @@ void MeshFormat::voxelizeTris(voxel::RawVolume *volume, const core::DynamicArray
const voxel::Voxel voxel = voxel::createVoxel(voxel::VoxelType::Generic, index);
volume->setVoxel(entry->first, voxel);
}
Log::debug("fill hollows");
voxelutil::fillHollow(*volume, voxel::Voxel(voxel::VoxelType::Generic, 2));
}

View File

@ -87,12 +87,14 @@ protected:
}
};
using TriCollection = core::DynamicArray<Tri, 512>;
/**
* Subdivide until we brought the triangles down to the size of 1 or smaller
*/
static void subdivideTri(const Tri &tri, core::DynamicArray<Tri> &tinyTris);
static void subdivideTri(const Tri &tri, TriCollection &tinyTris);
static void voxelizeTris(voxel::RawVolume *volume, const core::DynamicArray<Tri> &tinyTris);
static void voxelizeTris(voxel::RawVolume *volume, const TriCollection &tinyTris);
struct MeshExt {
MeshExt(voxel::Mesh *mesh, const SceneGraphNode &node, bool applyTransform);

View File

@ -189,7 +189,7 @@ bool OBJFormat::saveMeshes(const core::Map<int, int> &, const SceneGraph &sceneG
void OBJFormat::subdivideShape(const tinyobj::mesh_t &mesh, const core::StringMap<image::ImagePtr> &textures,
const tinyobj::attrib_t &attrib, const std::vector<tinyobj::material_t> &materials,
core::DynamicArray<Tri> &subdivided) {
TriCollection &subdivided) {
const glm::vec3 &scale = getScale();
int indexOffset = 0;
for (size_t faceNum = 0; faceNum < mesh.num_face_vertices.size(); ++faceNum) {
@ -342,7 +342,7 @@ bool OBJFormat::loadGroups(const core::String &filename, io::SeekableReadStream
SceneGraphNode node;
node.setVolume(volume, true);
node.setName(shape.name.c_str());
core::DynamicArray<Tri> subdivided;
TriCollection subdivided;
subdivideShape(shape.mesh, textures, attrib, materials, subdivided);
voxelizeTris(volume, subdivided);
return core::move(node);

View File

@ -23,7 +23,7 @@ private:
glm::vec3 &maxs);
static void subdivideShape(const tinyobj::mesh_t &mesh, const core::StringMap<image::ImagePtr> &textures,
const tinyobj::attrib_t &attrib, const std::vector<tinyobj::material_t> &materials,
core::DynamicArray<Tri> &subdivided);
TriCollection &subdivided);
public:
bool saveMeshes(const core::Map<int, int> &, const SceneGraph &, const Meshes& meshes, const core::String &filename, io::SeekableWriteStream& stream, const glm::vec3 &scale, bool quad, bool withColor, bool withTexCoords) override;

View File

@ -16,7 +16,7 @@ namespace priv {
static constexpr const size_t BinaryHeaderSize = 80;
}
void STLFormat::subdivideShape(const core::DynamicArray<Face> &faces, core::DynamicArray<Tri> &subdivided) {
void STLFormat::subdivideShape(const core::DynamicArray<Face> &faces, TriCollection &subdivided) {
const glm::vec3 &scale = getScale();
for (const Face &face : faces) {
@ -175,7 +175,7 @@ bool STLFormat::loadGroups(const core::String &filename, io::SeekableReadStream
SceneGraphNode node;
node.setVolume(volume, true);
node.setName(filename);
core::DynamicArray<Tri> subdivided;
TriCollection subdivided;
subdivideShape(faces, subdivided);
voxelizeTris(volume, subdivided);
sceneGraph.emplace(core::move(node));

View File

@ -35,7 +35,7 @@ private:
};
static void calculateAABB(const core::DynamicArray<Face> &faces, glm::vec3 &mins, glm::vec3 &maxs);
static void subdivideShape(const core::DynamicArray<Face> &faces, core::DynamicArray<Tri> &subdivided);
static void subdivideShape(const core::DynamicArray<Face> &faces, TriCollection &subdivided);
bool writeVertex(io::SeekableWriteStream &stream, const MeshExt &meshExt, const voxel::VoxelVertex &v1, const glm::vec3 &offset, const glm::vec3 &scale);