Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model digging holes #60

Closed
vltown opened this issue Apr 2, 2024 · 4 comments
Closed

Model digging holes #60

vltown opened this issue Apr 2, 2024 · 4 comments

Comments

@vltown
Copy link

vltown commented Apr 2, 2024

I saw an example of cube-in-cube. If I want to dig out a small-cube from one side of the big-cube, how should I implement it? I haven't found the relevant method. Can you help me?

@lynaghk
Copy link
Contributor

lynaghk commented Apr 4, 2024

I think one way you can do it is to use truck_shapeops::and with your big cube and an inverted small cube. Here's the result I got:

Screen Shot 2024-04-04 at 2 36 49 PM

Note that the shapeops boolean operations don't work correctly if faces are coincident (see #57), which is why I didn't line up the small cube exactly with the big cube.

use truck_meshalgo::{filters::*, tessellation::*};
use truck_modeling::*;

fn main() {
    let tolerance = 1e-6;

    let cube_big = {
        let v = builder::vertex(Point3::new(0.0, 0.0, 0.0));
        let e = builder::tsweep(&v, Vector3::unit_x());
        let f = builder::tsweep(&e, Vector3::unit_y());
        builder::tsweep(&f, Vector3::unit_z())
    };

    let mut cube_small = {
        let scale = 0.5;
        let v = builder::vertex(Point3::new(0.6, 0.2, 0.2));
        let e = builder::tsweep(&v, scale * Vector3::unit_x());
        let f = builder::tsweep(&e, scale * Vector3::unit_y());
        builder::tsweep(&f, scale * Vector3::unit_z())
    };

    // Invert all of the faces so the cube is "inside out" and will be "subtracted" from the other
    cube_small.not();

    let solid = truck_shapeops::and(&cube_big, &cube_small, tolerance).unwrap();

    let mut mesh = solid.triangulation(tolerance).to_polygon();
    mesh.put_together_same_attrs(tolerance)
        .remove_degenerate_faces()
        .remove_unused_attrs();

    let file = std::fs::File::create("foo.obj").unwrap();
    truck_polymesh::obj::write(&mesh, file).unwrap();
}

@vltown
Copy link
Author

vltown commented Apr 10, 2024

I think one way you can do it is to use truck_shapeops::and with your big cube and an inverted small cube. Here's the result I got:我认为有一种方法可以做到这一点,那就是用 truck_shapeops::and 和你的大立方体以及一个倒置的小立方体。这就是我得到的结果:

Screen Shot 2024-04-04 at 2 36 49 PM Note that the shapeops boolean operations don't work correctly if faces are coincident (see #57), which is why I didn't line up the small cube exactly with the big cube.请注意,如果面是重合的,shapeops 布尔运算将无法正常工作(参见 #57 ),这就是为什么我没有将小立方体与大立方体完全对齐。
use truck_meshalgo::{filters::*, tessellation::*};
use truck_modeling::*;

fn main() {
    let tolerance = 1e-6;

    let cube_big = {
        let v = builder::vertex(Point3::new(0.0, 0.0, 0.0));
        let e = builder::tsweep(&v, Vector3::unit_x());
        let f = builder::tsweep(&e, Vector3::unit_y());
        builder::tsweep(&f, Vector3::unit_z())
    };

    let mut cube_small = {
        let scale = 0.5;
        let v = builder::vertex(Point3::new(0.6, 0.2, 0.2));
        let e = builder::tsweep(&v, scale * Vector3::unit_x());
        let f = builder::tsweep(&e, scale * Vector3::unit_y());
        builder::tsweep(&f, scale * Vector3::unit_z())
    };

    // Invert all of the faces so the cube is "inside out" and will be "subtracted" from the other
    cube_small.not();

    let solid = truck_shapeops::and(&cube_big, &cube_small, tolerance).unwrap();

    let mut mesh = solid.triangulation(tolerance).to_polygon();
    mesh.put_together_same_attrs(tolerance)
        .remove_degenerate_faces()
        .remove_unused_attrs();

    let file = std::fs::File::create("foo.obj").unwrap();
    truck_polymesh::obj::write(&mesh, file).unwrap();
}

Thank you very much, I can already achieve this effect. I see that your screenshot page is not a window in truck. Your page looks much better. Did you implement it yourself through wgpu and wgsl, or did you use some crates? I can't find many tutorials online now. I'm new to truck and can only get a little bit of exposure through truck-tutorial and source code. However, these tutorials are almost out of date. Do you have any suggestions for learning truck?

@lynaghk
Copy link
Contributor

lynaghk commented Apr 10, 2024

The screenshots are from XCode, which seems to be the default program on my Mac for opening and viewing .obj and .stl files.

I don't have any advice about learning Truck specifically --- I've just been reading the source code myself and trying to understand it. I had a similar question about background understanding and I opened #61 and hope the author replies there with some suggestions.

Aside from that, I enjoyed Solid Modelling and CAD Systems: How to Survive a CAD System, so if you can find a copy of that at your library or a website somewhere, I would recommend reading it to better understand boundary representations in CAD.

@twitchyliquid64
Copy link

You could:

  1. Make a hole in the face you are cutting out from by adding an inverted wire representing the boundary of the outer face and the cutout
  2. Make the 'inner boundary' by adding the 5 sides of the hole. You can do this by making a cube with the same dimensions as the cutout (i.e. coincident) and then adding all but the coincident face to the shell.

This is how I implemented 'bores' in liquid-cad, you can read the relevant code here: https://github.com/twitchyliquid64/liquid-cad/blob/main/drawing/src/l/three_d.rs#L203-L223

@vltown vltown closed this as completed Jul 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants