ricosjp / truck

Truck is a Rust CAD Kernel.
Apache License 2.0
1.02k stars 53 forks source link

Shapeops OR function not behaving as expected when solids touch but do not overlap #57

Open MattFerraro opened 9 months ago

MattFerraro commented 9 months ago

Here is a minimal example:

use truck_modeling::builder::{tsweep, vertex};
use truck_modeling::{Point3, Vector3};
use truck_shapeops::or;

fn main() {
    let point_a = vertex(Point3::new(0.0, 0.0, 0.0));
    let line_a = tsweep(&point_a, Vector3::unit_x());
    let square_a = tsweep(&line_a, Vector3::unit_y());
    let cube_a = tsweep(&square_a, Vector3::unit_z());

    let z_offset = 1.0;
    let x_offset = 0.1;
    let y_offset = 0.1;
    let point_b = vertex(Point3::new(x_offset, y_offset, z_offset));
    let line_b = tsweep(&point_b, Vector3::unit_x());
    let square_b = tsweep(&line_b, Vector3::unit_y());
    let cube_b = tsweep(&square_b, Vector3::unit_z());

    let combined_cube = or(&cube_a, &cube_b, 0.01);
    match combined_cube {
        Some(c) => {
            println!(
                "combined_cube has {:?} shell boundaries",
                c.boundaries().len()
            );
        }
        None => {
            println!("combined_cube: None");
        }
    }
}

When I run this, the output I see is:

combined_cube: None

I expected the output to be:

combined_cube has 1 shell boundaries

If I change the value to: let z_offset = 0.9 then I get the correct behavior:

combined_cube has 1 shell boundaries

If I change the value to: let z_offset = 1.1 then I get different behavior which is also correct:

combined_cube has 2 shell boundaries

It is only when I choose let z_offset = 1.0 when the None value is returned. Is this the intended behavior? How can I merge two solids which are touching but not overlapping?

MattFerraro commented 9 months ago

Maybe I'm misunderstanding the purpose of the or function. Is there some other way to join two cubes together that share a face?