ricosjp / truck

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

Generating truck objects from lists of points #54

Closed twitchyliquid64 closed 10 months ago

twitchyliquid64 commented 10 months ago

Hi!

I'm working on a 2d constraint-solving CAD, and would like to implement the ability to export a linear/lathe extrusion of the drawing as an STL or STEP file. Truck seems like the best library for the job as far as I can tell.

Can you help me work out how to do this?

I think I need to create a Wire to represent the boundary geometry, creates two faces from this wire for the top and bottom faces, and then glue them together somehow, perhaps glue_at_boundaries ? And then presumably i need to use boolean operations to cut out interior geometry?

Lathe extrusion might be easier, if I can create a Wire maybe I can use rsweep ?

twitchyliquid64 commented 10 months ago

I ... think I got it working? could it be?

https://github.com/twitchyliquid64/liquid-cad/commit/a0b5fb50946e002efc4c5f3284570c7cec1861c7#diff-1d4b34bc50dcd41fc559b9563fbba91dfab991671496865a28cee406e0e976ef

PrusaSlicer says my generate STL has a number of errors - I'm not sure if there is a bug in truck or I'm doing something incorrect.

MattFerraro commented 10 months ago

Hello,

Are you familiar with tsweep? That plus rsweep should get you most of the way there. The key is to sweep a face, not a wire, so that the outcome is a solid, not a shell.

Cheers, Matt

twitchyliquid64 commented 10 months ago

Thanks!

Yepp I'm sweeping a face to make a solid, the remaining issue is just that truck is producing an STL which PrusaSlicer says has errors, but I can file a separate issue for that!

twitchyliquid64 commented 10 months ago

For the sake of posterity, here's how I did it:

  1. Make a Wire by collecting a Vec of lines which connect your points to form a closed loop (you could also use the other builder methods here, no need for everything to be a straight line)
    
    let lines = vec![
    builder::line(builder::vertex(Point3::new(1.0, 0.0, 0.0)), builder::vertex(Point3::new(2.0, 0.0, 0.0))),
    builder::line(builder::vertex(Point3::new(2.0, 0.0, 0.0)), builder::vertex(Point3::new(2.0, 3.0, 0.0))),
    builder::line(builder::vertex(Point3::new(2.0, 3.0, 0.0)), builder::vertex(Point3::new(1.0, 0.0, 0.0))),
    ];
    // NOTE: Don't actually create duplicate vertex objects, reuse ones that point to the same point

let wire: Wire = lines.into();


2. Convert into a face

```rust
let face = builder::try_attach_plane(&wires).unwrap();
  1. Sweep to form a solid object:
let solid = builder::tsweep(&face, height * Vector3::unit_z());