KittyCAD / modeling-app

The KittyCAD modeling app.
https://kittycad.io/modeling-app/download
MIT License
422 stars 35 forks source link

spoon16 cannot shell 2 cubes with the same thickness #4104

Open lf94 opened 1 month ago

lf94 commented 1 month ago

User spoon16 from Discord tried the following:

const base = startSketchOn('XY')
  |> startProfileAt([0, 0], %)
  |> line([50, 0], %)
  |> line([0, 50], %, $leftPlane)
  |> line([-50, 0], %, $rightPlane)
  |> lineTo([profileStartX(%), profileStartY(%)], %)
  |> close(%)
  |> extrude(50, %)

const bracketBottom = startSketchOn(base, 'START')
  |> startProfileAt([0, 0], %)
  |> line([-50, 0], %)
  |> line([0, 50], %)
  |> line([50, 0], %)
  |> lineTo([profileStartX(%), profileStartY(%)], %)
  |> close(%)
  |> extrude(86, %)
  |> shell({ faces: ['end'], thickness: 6 }, %)

const bracketLeft = startSketchOn(base, leftPlane)
  |> startProfileAt([0, 0], %)
  |> line([50, 0], %)
  |> line([0, 50], %)
  |> line([-50, 0], %)
  |> lineTo([profileStartX(%), profileStartY(%)], %)
  |> close(%)
  |> extrude(86, %)
  |> shell({ faces: ['end'], thickness: 6 }, %)

const bracketRight = startSketchOn(base, rightPlane)
  |> startProfileAt([0, 0], %)
  |> line([-50, 0], %)
  |> line([0, 50], %)
  |> line([50, 0], %)
  |> lineTo([profileStartX(%), profileStartY(%)], %)
  |> close(%)
  |> extrude(86, %)

but it fails.

Upon investigating, if you play with the thickness of one, and make it less than half of the first one, it will work!

jessfraz commented 1 month ago

@benjamaan476 might have ideas..?

benjamaan476 commented 1 month ago

It might not seem like it, but this is all one big solid object. You cannot shell more than once without getting weird results as the second operation will include the new geometry generated by the first operation. The reason that it works when it is less than half the thickness is because it is actually creating a shell on the inside of the bracketBottom walls so it needs to be half as thick to fit. Just for reference you can achieve this effect by making one shell call at the end of the process

const base = startSketchOn('XY')
  |> startProfileAt([0, 0], %)
  |> line([50, 0], %)
  |> line([0, 50], %, $leftPlane)
  |> line([-50, 0], %, $rightPlane)
  |> lineTo([profileStartX(%), profileStartY(%)], %)
  |> close(%)
  |> extrude(50, %)

const bracketBottom = startSketchOn(base, 'START')
  |> startProfileAt([0, 0], %)
  |> line([-50, 0], %)
  |> line([0, 50], %)
  |> line([50, 0], %)
  |> lineTo([profileStartX(%), profileStartY(%)], %)
  |> close(%)
  |> extrude(86, %)
//  |> shell({ faces: ['end'], thickness: 6 }, %)

const bracketLeft = startSketchOn(base, leftPlane)
  |> startProfileAt([0, 0], %)
  |> line([50, 0], %)
  |> line([0, 50], %)
  |> line([-50, 0], %)
  |> lineTo([profileStartX(%), profileStartY(%)], %)
  |> close(%)
  |> extrude(86, %)
//  |> shell({ faces: ['end'], thickness: 6 }, %)

const bracketRight = startSketchOn(base, rightPlane)
  |> startProfileAt([0, 0], %)
  |> line([-50, 0], %)
  |> line([0, 50], %)
  |> line([50, 0], %)
  |> lineTo([profileStartX(%), profileStartY(%)], %)
  |> close(%)
  |> extrude(86, %)

  shell({
    thickness: 3.14,
    faces: ["end"],
  }, [bracketLeft, bracketBottom])

This will, however, still shell the inside of bracketRight as it is connected to the same object.

spoon16 commented 1 month ago

Thanks for the explanation. There is an example in the documentation that explains this, but I did not understand the semantics of the shell function properly. If I want to leave base solid I will have to use negative extrusions. Is that right?

benjamaan476 commented 1 month ago

Currently I can only think to reorder the kcl. If you created the left/bottom bracket before the base, shelled them and then created the base. This would produce a solid base without any internal faces. The same for the right bracket.