splashsurf icon indicating copy to clipboard operation
splashsurf copied to clipboard

Some kind of odd mesh corruption

Open werner291 opened this issue 3 years ago • 1 comments

Hello,

I was trying for some generative art using metaballs. The idea was to generate a 3D-grid/cube of points/atoms/particles/whatever, and carve shapes out of it like a kind of computational "clay".

I wrote this program:

use kiss3d::window::Window;
use nalgebra::{Point3, Vector3, DMatrix};
use splashsurf_lib::{reconstruct_surface, Parameters, SpatialDecompositionParameters, SurfaceReconstruction, SubdivisionCriterion, ParticleDensityComputationStrategy};
use std::option::Option::{None, Some};
use kiss3d::ncollide3d::procedural::{TriMesh, IndexBuffer};
use std::convert::From;
use std::prelude::v1::Vec;
use kiss3d::ncollide3d::query::Ray;
use kiss3d::ncollide3d::shape::HeightField;
use kiss3d::ncollide3d::bounding_volume::AABB;
use kiss3d::light::Light;

fn main() {

    let mut window = Window::new("Hello");

    window.set_light(Light::StickToCamera);

    let mut particles = Vec::new();

    for x in 0..20 {
        for y in 0..20 {
            for z in 0..20 {
                particles.push(
                    Point3::new(x as f32, z as f32, y as f32)
                );
            }
        }
    }

    let carve_shape = AABB::new(Point3::new(0.0, 1.0, 1.0),
                                Point3::new(20.0, 18.0, 18.0));

    particles.retain(|pt| {
        !carve_shape.contains_local_point(pt)
    });

    let vectorized = particles.iter().map(|pt| pt.to_owned().coords).collect::<Vec<Vector3<f32>>>();

    let surface : SurfaceReconstruction<usize,f32> = reconstruct_surface(&vectorized, &Parameters {
        particle_radius: 1.0,
        rest_density: 1.0,
        compact_support_radius: 2.0,
        cube_size: 0.2,
        iso_surface_threshold: 0.5,
        domain_aabb: None,
        enable_multi_threading: false,
        spatial_decomposition: None,
    }).unwrap();

    let trimesh = TriMesh::new(
        surface.mesh().vertices.iter().map(|v| Point3::new(v.x, v.y, v.z)).collect(),
        None,
        None,
        Some(IndexBuffer::Unified(surface.mesh().triangles.iter().map(|idx| Point3::new(idx[0] as u32, idx[1] as u32, idx[2] as u32)).collect()))
    );

    window.add_trimesh(trimesh, Vector3::new(1.0,1.0,1.0));

    while window.render() {

    }

}

However, something seems to have gone a teensy bit wrong with the mesh generation:

image

Here's the used crates and opt levels:

[dependencies]
kiss3d = "0.29.0"
nalgebra = "0.24.1"
splashsurf_lib = "0.6.1"
noise = "0.7.0"

[profile.dev]
opt-level = 1

werner291 avatar Feb 28 '21 14:02 werner291

Hm, I'm not really sure what happens there. When I export the mesh to VTK and open it with ParaView, it looks fine.

image

I also tried to swap the order of the indices for the TriMesh in kiss3d but this didn't seem to help. I'm not 100% familiar with what kiss3d really expects here as input but on the other hand, I don't think there are many different variants of how you could pass the data into it? Is this possibly a bug in kiss3d? Can you try with some mesh where you know that it's correct? I don't have enough time at the moment to play around with e.g. the kiss3d examples...

w1th0utnam3 avatar Mar 01 '21 11:03 w1th0utnam3