Skip to content

mesh_intersection between two meshes with co-planner triangles crashes the test #289

@piaoger

Description

@piaoger

I found a couple of issues while playing with parry for mesh intersections.
Even after upgrading to 0.17.3, I still find below test result for co-planner meshes is still crash with below message. Hope my test case is helpful.

thread 'test::test_mesh_intersection_2' panicked at /home/user/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/spade-2.12.1/src/cdt.rs:550:53:
Constraint edges must not intersect.
stack backtrace:
   0: rust_begin_unwind
   1: core::panicking::panic_fmt
   2: spade::cdt::ConstrainedDelaunayTriangulation<V,DE,UE,F,L>::add_constraint
   3: spade::delaunay_core::bulk_load::bulk_load_stable
   4: parry3d_f64::transformation::mesh_intersection::mesh_intersection::merge_triangle_sets
   5: parry3d_f64::transformation::mesh_intersection::mesh_intersection::intersect_meshes_with_tolerances
   6: basalt_clash::test::test_mesh_intersection_2
   7: core::ops::function::FnOnce::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
test test::test_mesh_intersection_2 ... FAILED

two meshes with co-planner triangles

e4a99aa9001e792db8d0e9c2127d660

test code

#[cfg(test)]
mod test {
    use nalgebra::{Point3, Vector3};
    use obj::Obj;
    use obj::ObjData;
    use parry3d_f64::math::{Isometry, Real};
    use parry3d_f64::shape::{TriMesh, TriMeshFlags};
    use parry3d_f64::transformation::intersect_meshes_with_tolerances;
    use std::path::PathBuf;

    fn load_trimesh_from_obj(objfile: &str) -> TriMesh {
        let Obj {
            data: ObjData {
                position, objects, ..
            },
            ..
        } = Obj::load(objfile).unwrap();

        let mesh = TriMesh::with_flags(
            position
                .iter()
                .map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
                .collect::<Vec<_>>(),
            objects[0].groups[0]
                .polys
                .iter()
                .map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32])
                .collect::<Vec<_>>(),
            TriMeshFlags::all(),
        );

        mesh
    }

    #[test]
    fn test_mesh_intersection_2() {
        let colliders = vec!["1.obj", "2.obj"];

        let mesh_a = load_trimesh_from_obj(&colliders[0]);
        let mesh_b = load_trimesh_from_obj(&colliders[1]);

        mesh_a.to_obj_file(&PathBuf::from(format!("intersection_test-2-a.obj")));
        mesh_b.to_obj_file(&PathBuf::from(format!("intersection_test-2-b.obj")));

        let mut tolerance = parry3d_f64::transformation::MeshIntersectionTolerances::default();
        tolerance.global_insertion_epsilon = 0.001;
        tolerance.angle_epsilon = (0.1_f64).to_radians();

        let mut result = intersect_meshes_with_tolerances(
            &Isometry::identity(),
            &mesh_a,
            false,
            &Isometry::translation(0.0, 0.0, 0.0),
            &mesh_b,
            false,
            tolerance,
        )
        .unwrap();

        if let Some(result) = result {
            let _ = result.to_obj_file(&PathBuf::from("intersection_test_result.obj"));
        }
    }
}

sample obj files

See attched objs.zip
objs.zip

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions