KittyCAD / modeling-app

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

the step file from the sample code exported looks weird #766

Closed jessfraz closed 12 months ago

jessfraz commented 1 year ago

cc @jgomez720 to make sure its not this shitty viewer i used

Screenshot 2023-10-03 at 12 21 11 PM
const sigmaAllow = 15000 // psi
const width = 11 // inch
const p = 150 // Force on shelf - lbs
const distance = 12 // inches
const FOS = 2
const thickness = sqrt(distance * p * FOS * 6 / ( sigmaAllow * width ))
const filletR = thickness * 2
const shelfMountL = 9
const wallMountL = 8

const bracket = startSketchAt([0, 0])
  |> line([0, wallMountL], %)
  |> tangentalArc({
    radius: filletR,
    offset: 90
  }, %)
  |> line([-shelfMountL, 0], %)
  |> line([0, -thickness], %)
  |> line([shelfMountL, 0], %)
  |> tangentalArc({
    radius: filletR - thickness,
    offset: -90
  }, %)
  |> line([0, -wallMountL], %)
  |> close(%)
  |> extrude(width, %)

show(bracket)
jgomez720 commented 1 year ago

Nope, something is certainly weird.

Also, the tauri dev app doesn't export something readable at all. I could only get something from the web app. I think @franknoirot and I talked about that once before too

Screenshot 2023-10-03 at 12 50 09 PM

jgomez720 commented 1 year ago

@alteous, this has something to do with the tangentialArcs, because @franknoirot and I exported a good looking bracket without that before.

jessfraz commented 1 year ago

I can def look into the specific tauri side

jessfraz commented 1 year ago

is it just step on tauri or all types?

jgomez720 commented 1 year ago

Just tested. All file types. Creating an issue now

alteous commented 1 year ago

That’s interesting. I expect this is a problem with the export code in the engine repository although it is strange we don’t get the same(?) output from the dev app. If you happen to have it at hand, could you provide the glTF output from both the dev app and the web app? I’ll try to reproduce today otherwise.

jgomez720 commented 1 year ago

Issue766.zip

There's one GLTF from the tauri app and one from the web app

alteous commented 1 year ago

image For my reference, this is what the model should look like.

alteous commented 1 year ago

I'm attempting to reproduce this issue in the engine tests. Are these the expected commands? https://github.com/KittyCAD/engine/pull/1501/files

jessfraz commented 1 year ago

yeah pretty much that looks right! thanks!

jessfraz commented 1 year ago

Fwiw the issue was fixed so you do get the same output from both the web and tauri side so it’s just the tangential arc bit remaining :)

alteous commented 1 year ago
 66 SelectClear
 67 SelectAdd(SelectAdd { entities: [] })
 68 CameraDragStart(CameraDragStart { interaction: Rotate, window: Point2d { x: 994.0, y: 278.0 } })
 69 CameraDragEnd(CameraDragEnd { interaction: Rotate, window: Point2d { x: 1000.0, y: 290.0 } })
 70 ReconfigureStream(ReconfigureStream { width: 1708, height: 884, fps: 60 })
 71 ReconfigureStream(ReconfigureStream { width: 1708, height: 928, fps: 60 })
 72 SelectClear
 73 SelectAdd(SelectAdd { entities: [] })
 74 SelectClear
 75 SelectAdd(SelectAdd { entities: [] })
 76 SelectClear
 77 SelectAdd(SelectAdd { entities: [] })
 78 RemoveSceneObjects(RemoveSceneObjects { object_ids: {4c9c1917-d432-4f84-b180-8578b43a6aa6} })
 79 StartPath
 80 MovePathPen(MovePathPen { path: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), to: Point3d { x: 0.0, y: 0.0, z: 0.0 } })
 81 ExtendPath(ExtendPath { path: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), segment: Line { end: Point3d { x: 0.0, y: 8.0, z: 0.0 }, relative: true } })
 82 ExtendPath(ExtendPath { path: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), segment: TangentialArc { radius: 0.7236272269866327, offset: Angle { unit: Degrees, value: 90.0 } } })
 83 ExtendPath(ExtendPath { path: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), segment: Line { end: Point3d { x: -9.0, y: 0.0, z: 0.0 }, relative: true } })
 84 ExtendPath(ExtendPath { path: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), segment: Line { end: Point3d { x: 0.0, y: -0.3618136134933164, z: 0.0 }, relative: true } })
 85 ExtendPath(ExtendPath { path: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), segment: Line { end: Point3d { x: 9.0, y: 0.0, z: 0.0 }, relative: true } })
 86 ExtendPath(ExtendPath { path: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), segment: TangentialArc { radius: 0.3618136134933164, offset: Angle { unit: Degrees, value: -90.0 } } })
 87 ExtendPath(ExtendPath { path: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), segment: Line { end: Point3d { x: 0.0, y: -8.0, z: 0.0 }, relative: true } })
 88 ClosePath(ClosePath { path_id: 5f182efe-cfe5-4bbe-b058-58aef57de04a })
 89 Extrude(Extrude { target: ModelingCmdId(5f182efe-cfe5-4bbe-b058-58aef57de04a), distance: 11.0, cap: true })
 90 PathGetInfo(PathGetInfo { path_id: 5f182efe-cfe5-4bbe-b058-58aef57de04a })
 91 Export(Export { entity_ids: [], source_unit: Inches, format: Step(ExportOptions { coords: System { forward: AxisDirectionPair { axis: Y, direction: Negative }, up: AxisDirectionPair { axis: Z, direction: Positive } }, created: None })     })

Modelling commands dumped from local dev-stack.

jessfraz commented 1 year ago

Startpath movepathpen extendpath closepath extrude are all that really matters

alteous commented 1 year ago

The model doesn't display immediately, even in the local setup. The commands are at least correct and still produce the same export data as reported.

alteous commented 1 year ago

This explains why the test image doesn't show any geometry.

alteous commented 1 year ago

B-rep dump from OpenNURBS:

ON_Brep:
surfaces:   10
3d curve:   24
2d curves:  48
vertices:   16
edges:      24
trims:      48
loops:      10
faces:      10
curve2d[ 0]: ON_NurbsCurve domain(0,8) start(0,0) end(8,0)
curve2d[ 1]: ON_NurbsCurve domain(0,11) start(8,0) end(8,11)
curve2d[ 2]: ON_NurbsCurve domain(0,8) start(8,11) end(0,11)
curve2d[ 3]: ON_NurbsCurve domain(0,11) start(0,11) end(0,0)
curve2d[ 4]: ON_NurbsCurve domain(8,9) start(8,0) end(9,0)
curve2d[ 5]: ON_NurbsCurve domain(0,11) start(9,0) end(9,11)
curve2d[ 6]: ON_NurbsCurve domain(8,9) start(9,11) end(8,11)
curve2d[ 7]: ON_NurbsCurve domain(0,11) start(8,11) end(8,0)
curve2d[ 8]: ON_NurbsCurve domain(9,18) start(9,0) end(18,0)
curve2d[ 9]: ON_NurbsCurve domain(0,11) start(18,0) end(18,11)
curve2d[10]: ON_NurbsCurve domain(9,18) start(18,11) end(9,11)
curve2d[11]: ON_NurbsCurve domain(0,11) start(9,11) end(9,0)
curve2d[12]: ON_NurbsCurve domain(18,18.3618) start(18,0) end(18.3618,0)
curve2d[13]: ON_NurbsCurve domain(0,11) start(18.3618,0) end(18.3618,11)
curve2d[14]: ON_NurbsCurve domain(18,18.3618) start(18.3618,11) end(18,11)
curve2d[15]: ON_NurbsCurve domain(0,11) start(18,11) end(18,0)
curve2d[16]: ON_NurbsCurve domain(18.3618,27.3618) start(18.3618,0) end(27.3618,0)
curve2d[17]: ON_NurbsCurve domain(0,11) start(27.3618,0) end(27.3618,11)
curve2d[18]: ON_NurbsCurve domain(18.3618,27.3618) start(27.3618,11) end(18.3618,11)
curve2d[19]: ON_NurbsCurve domain(0,11) start(18.3618,11) end(18.3618,0)
curve2d[20]: ON_NurbsCurve domain(27.3618,28.3618) start(27.3618,0) end(28.3618,0)
curve2d[21]: ON_NurbsCurve domain(0,11) start(28.3618,0) end(28.3618,11)
curve2d[22]: ON_NurbsCurve domain(27.3618,28.3618) start(28.3618,11) end(27.3618,11)
curve2d[23]: ON_NurbsCurve domain(0,11) start(27.3618,11) end(27.3618,0)
curve2d[24]: ON_NurbsCurve domain(28.3618,36.3618) start(28.3618,0) end(36.3618,0)
curve2d[25]: ON_NurbsCurve domain(0,11) start(36.3618,0) end(36.3618,11)
curve2d[26]: ON_NurbsCurve domain(28.3618,36.3618) start(36.3618,11) end(28.3618,11)
curve2d[27]: ON_NurbsCurve domain(0,11) start(28.3618,11) end(28.3618,0)
curve2d[28]: ON_NurbsCurve domain(36.3618,36.7236) start(36.3618,0) end(36.7236,0)
curve2d[29]: ON_NurbsCurve domain(0,11) start(36.7236,0) end(36.7236,11)
curve2d[30]: ON_NurbsCurve domain(36.3618,36.7236) start(36.7236,11) end(36.3618,11)
curve2d[31]: ON_NurbsCurve domain(0,11) start(36.3618,11) end(36.3618,0)
curve2d[32]: ON_NurbsCurve domain(0,8) start(0,0) end(0,8)
curve2d[33]: ON_NurbsCurve domain(8,9) start(0,8) end(-0.723627,8.72363)
curve2d[34]: ON_NurbsCurve domain(9,18) start(-0.723627,8.72363) end(-9.72363,8.72363)
curve2d[35]: ON_NurbsCurve domain(18,18.3618) start(-9.72363,8.72363) end(-9.72363,8.36181)
curve2d[36]: ON_NurbsCurve domain(18.3618,27.3618) start(-9.72363,8.36181) end(-0.723627,8.36181)
curve2d[37]: ON_NurbsCurve domain(27.3618,28.3618) start(-0.723627,8.36181) end(-0.361814,8)
curve2d[38]: ON_NurbsCurve domain(28.3618,36.3618) start(-0.361814,8) end(-0.361814,0)
curve2d[39]: ON_NurbsCurve domain(36.3618,36.7236) start(-0.361814,0) end(0,0)
curve2d[40]: ON_NurbsCurve domain(0,8) start(0,0) end(0,8)
curve2d[41]: ON_NurbsCurve domain(8,9) start(0,8) end(-0.723627,8.72363)
curve2d[42]: ON_NurbsCurve domain(9,18) start(-0.723627,8.72363) end(-9.72363,8.72363)
curve2d[43]: ON_NurbsCurve domain(18,18.3618) start(-9.72363,8.72363) end(-9.72363,8.36181)
curve2d[44]: ON_NurbsCurve domain(18.3618,27.3618) start(-9.72363,8.36181) end(-0.723627,8.36181)
curve2d[45]: ON_NurbsCurve domain(27.3618,28.3618) start(-0.723627,8.36181) end(-0.361814,8)
curve2d[46]: ON_NurbsCurve domain(28.3618,36.3618) start(-0.361814,8) end(-0.361814,0)
curve2d[47]: ON_NurbsCurve domain(36.3618,36.7236) start(-0.361814,0) end(0,0)
curve3d[ 0]: ON_NurbsCurve domain(0,8) start(0,0,0) end(0,8,0)
curve3d[ 1]: ON_NurbsCurve domain(0,11) start(0,8,0) end(0,8,11)
curve3d[ 2]: ON_NurbsCurve domain(0,8) start(0,0,11) end(0,8,11)
curve3d[ 3]: ON_NurbsCurve domain(0,11) start(0,0,0) end(0,0,11)
curve3d[ 4]: ON_NurbsCurve domain(8,9) start(0,8,0) end(-0.723627,8.72363,0)
curve3d[ 5]: ON_NurbsCurve domain(0,11) start(-0.723627,8.72363,0) end(-0.723627,8.72363,11)
curve3d[ 6]: ON_NurbsCurve domain(8,9) start(0,8,11) end(-0.723627,8.72363,11)
curve3d[ 7]: ON_NurbsCurve domain(9,18) start(-0.723627,8.72363,0) end(-9.72363,8.72363,0)
curve3d[ 8]: ON_NurbsCurve domain(0,11) start(-9.72363,8.72363,0) end(-9.72363,8.72363,11)
curve3d[ 9]: ON_NurbsCurve domain(9,18) start(-0.723627,8.72363,11) end(-9.72363,8.72363,11)
curve3d[10]: ON_NurbsCurve domain(18,18.3618) start(-9.72363,8.72363,0) end(-9.72363,8.36181,0)
curve3d[11]: ON_NurbsCurve domain(0,11) start(-9.72363,8.36181,0) end(-9.72363,8.36181,11)
curve3d[12]: ON_NurbsCurve domain(18,18.3618) start(-9.72363,8.72363,11) end(-9.72363,8.36181,11)
curve3d[13]: ON_NurbsCurve domain(18.3618,27.3618) start(-9.72363,8.36181,0) end(-0.723627,8.36181,0)
curve3d[14]: ON_NurbsCurve domain(0,11) start(-0.723627,8.36181,0) end(-0.723627,8.36181,11)
curve3d[15]: ON_NurbsCurve domain(18.3618,27.3618) start(-9.72363,8.36181,11) end(-0.723627,8.36181,11)
curve3d[16]: ON_NurbsCurve domain(27.3618,28.3618) start(-0.723627,8.36181,0) end(-0.361814,8,0)
curve3d[17]: ON_NurbsCurve domain(0,11) start(-0.361814,8,0) end(-0.361814,8,11)
curve3d[18]: ON_NurbsCurve domain(27.3618,28.3618) start(-0.723627,8.36181,11) end(-0.361814,8,11)
curve3d[19]: ON_NurbsCurve domain(28.3618,36.3618) start(-0.361814,8,0) end(-0.361814,0,0)
curve3d[20]: ON_NurbsCurve domain(0,11) start(-0.361814,0,0) end(-0.361814,0,11)
curve3d[21]: ON_NurbsCurve domain(28.3618,36.3618) start(-0.361814,8,11) end(-0.361814,0,11)
curve3d[22]: ON_NurbsCurve domain(36.3618,36.7236) start(-0.361814,0,0) end(0,0,0)
curve3d[23]: ON_NurbsCurve domain(36.3618,36.7236) start(-0.361814,0,11) end(0,0,11)
surface[ 0]: ON_NurbsSurface u(0,8) v(0,11)
surface[ 1]: ON_NurbsSurface u(8,9) v(0,11)
surface[ 2]: ON_NurbsSurface u(9,18) v(0,11)
surface[ 3]: ON_NurbsSurface u(18,18.3618) v(0,11)
surface[ 4]: ON_NurbsSurface u(18.3618,27.3618) v(0,11)
surface[ 5]: ON_NurbsSurface u(27.3618,28.3618) v(0,11)
surface[ 6]: ON_NurbsSurface u(28.3618,36.3618) v(0,11)
surface[ 7]: ON_NurbsSurface u(36.3618,36.7236) v(0,11)
surface[ 8]: ON_PlaneSurface u(-10.9391,1.21545) v(-1.09045,9.81408)
surface[ 9]: ON_PlaneSurface u(-10.9391,1.21545) v(-1.09045,9.81408)
vertex[ 0]: (0.000000 0.000000 0.000000) tolerance(0)
    edges (0,3,22)
vertex[ 1]: (0.000000 8.000000 0.000000) tolerance(0)
    edges (0,1,4)
vertex[ 2]: (0.000000 8.000000 11.000000) tolerance(0)
    edges (1,2,6)
vertex[ 3]: (0.000000 0.000000 11.000000) tolerance(0)
    edges (2,3,23)
vertex[ 4]: (-0.723627 8.723627 0.000000) tolerance(0)
    edges (4,5,7)
vertex[ 5]: (-0.723627 8.723627 11.000000) tolerance(0)
    edges (5,6,9)
vertex[ 6]: (-9.723627 8.723627 0.000000) tolerance(0)
    edges (7,8,10)
vertex[ 7]: (-9.723627 8.723627 11.000000) tolerance(0)
    edges (8,9,12)
vertex[ 8]: (-9.723627 8.361814 0.000000) tolerance(0)
    edges (10,11,13)
vertex[ 9]: (-9.723627 8.361814 11.000000) tolerance(0)
    edges (11,12,15)
vertex[10]: (-0.723627 8.361814 0.000000) tolerance(0)
    edges (13,14,16)
vertex[11]: (-0.723627 8.361814 11.000000) tolerance(0)
    edges (14,15,18)
vertex[12]: (-0.361814 8.000000 0.000000) tolerance(0)
    edges (16,17,19)
vertex[13]: (-0.361814 8.000000 11.000000) tolerance(0)
    edges (17,18,21)
vertex[14]: (-0.361814 0.000000 0.000000) tolerance(0)
    edges (19,20,22)
vertex[15]: (-0.361814 0.000000 11.000000) tolerance(0)
    edges (20,21,23)
edge[ 0]: v0( 0) v1( 1) 3d_curve(0) tolerance(0)
    domain(0,8) start(0,0,0) end(0,8,0)
    trims (+0,+32)
edge[ 1]: v0( 1) v1( 2) 3d_curve(1) tolerance(0)
    domain(0,11) start(0,8,0) end(0,8,11)
    trims (+1,-7)
edge[ 2]: v0( 3) v1( 2) 3d_curve(2) tolerance(0)
    domain(0,8) start(0,0,11) end(0,8,11)
    trims (-2,+40)
edge[ 3]: v0( 0) v1( 3) 3d_curve(3) tolerance(0)
    domain(0,11) start(0,0,0) end(0,0,11)
    trims (-3,+29)
edge[ 4]: v0( 1) v1( 4) 3d_curve(4) tolerance(0)
    domain(8,9) start(0,8,0) end(-0.723627,8.72363,0)
    trims (+4,+33)
edge[ 5]: v0( 4) v1( 5) 3d_curve(5) tolerance(0)
    domain(0,11) start(-0.723627,8.72363,0) end(-0.723627,8.72363,11)
    trims (+5,-11)
edge[ 6]: v0( 2) v1( 5) 3d_curve(6) tolerance(0)
    domain(8,9) start(0,8,11) end(-0.723627,8.72363,11)
    trims (-6,+41)
edge[ 7]: v0( 4) v1( 6) 3d_curve(7) tolerance(0)
    domain(9,18) start(-0.723627,8.72363,0) end(-9.72363,8.72363,0)
    trims (+8,+34)
edge[ 8]: v0( 6) v1( 7) 3d_curve(8) tolerance(0)
    domain(0,11) start(-9.72363,8.72363,0) end(-9.72363,8.72363,11)
    trims (+9,-15)
edge[ 9]: v0( 5) v1( 7) 3d_curve(9) tolerance(0)
    domain(9,18) start(-0.723627,8.72363,11) end(-9.72363,8.72363,11)
    trims (-10,+42)
edge[10]: v0( 6) v1( 8) 3d_curve(10) tolerance(0)
    domain(18,18.3618) start(-9.72363,8.72363,0) end(-9.72363,8.36181,0)
    trims (+12,+35)
edge[11]: v0( 8) v1( 9) 3d_curve(11) tolerance(0)
    domain(0,11) start(-9.72363,8.36181,0) end(-9.72363,8.36181,11)
    trims (+13,-19)
edge[12]: v0( 7) v1( 9) 3d_curve(12) tolerance(0)
    domain(18,18.3618) start(-9.72363,8.72363,11) end(-9.72363,8.36181,11)
    trims (-14,+43)
edge[13]: v0( 8) v1(10) 3d_curve(13) tolerance(0)
    domain(18.3618,27.3618) start(-9.72363,8.36181,0) end(-0.723627,8.36181,0)
    trims (+16,+36)
edge[14]: v0(10) v1(11) 3d_curve(14) tolerance(0)
    domain(0,11) start(-0.723627,8.36181,0) end(-0.723627,8.36181,11)
    trims (+17,-23)
edge[15]: v0( 9) v1(11) 3d_curve(15) tolerance(0)
    domain(18.3618,27.3618) start(-9.72363,8.36181,11) end(-0.723627,8.36181,11)
    trims (-18,+44)
edge[16]: v0(10) v1(12) 3d_curve(16) tolerance(0)
    domain(27.3618,28.3618) start(-0.723627,8.36181,0) end(-0.361814,8,0)
    trims (+20,+37)
edge[17]: v0(12) v1(13) 3d_curve(17) tolerance(0)
    domain(0,11) start(-0.361814,8,0) end(-0.361814,8,11)
    trims (+21,-27)
edge[18]: v0(11) v1(13) 3d_curve(18) tolerance(0)
    domain(27.3618,28.3618) start(-0.723627,8.36181,11) end(-0.361814,8,11)
    trims (-22,+45)
edge[19]: v0(12) v1(14) 3d_curve(19) tolerance(0)
    domain(28.3618,36.3618) start(-0.361814,8,0) end(-0.361814,0,0)
    trims (+24,+38)
edge[20]: v0(14) v1(15) 3d_curve(20) tolerance(0)
    domain(0,11) start(-0.361814,0,0) end(-0.361814,0,11)
    trims (+25,-31)
edge[21]: v0(13) v1(15) 3d_curve(21) tolerance(0)
    domain(28.3618,36.3618) start(-0.361814,8,11) end(-0.361814,0,11)
    trims (-26,+46)
edge[22]: v0(14) v1( 0) 3d_curve(22) tolerance(0)
    domain(36.3618,36.7236) start(-0.361814,0,0) end(0,0,0)
    trims (+28,+39)
edge[23]: v0(15) v1( 3) 3d_curve(23) tolerance(0)
    domain(36.3618,36.7236) start(-0.361814,0,11) end(0,0,11)
    trims (-30,+47)
face[ 0]: surface(0) reverse(0) loops(0)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    (Face geometry is the same as underlying surface.)
    loop[ 0]: type(outer) 4 trims(0,1,2,3)
        trim[ 0]: edge( 0) v0( 0) v1( 1) tolerance(0,0)
            type(mated   -south side iso) rev3d(0) 2d_curve(0)
            domain(0,8) start(0,0) end(8,0)
            surface points start(0,0,0) end(0,8,0)
        trim[ 1]: edge( 1) v0( 1) v1( 2) tolerance(0,0)
            type(mated   -east side iso) rev3d(0) 2d_curve(1)
            domain(0,11) start(8,0) end(8,11)
            surface points start(0,8,0) end(0,8,11)
        trim[ 2]: edge( 2) v0( 2) v1( 3) tolerance(0,0)
            type(mated   -north side iso) rev3d(1) 2d_curve(2)
            domain(0,8) start(8,11) end(0,11)
            surface points start(0,8,11) end(0,0,11)
        trim[ 3]: edge( 3) v0( 3) v1( 0) tolerance(0,0)
            type(mated   -west side iso) rev3d(1) 2d_curve(3)
            domain(0,11) start(0,11) end(0,0)
            surface points start(0,0,11) end(0,0,0)
face[ 1]: surface(1) reverse(0) loops(1)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    (Face geometry is the same as underlying surface.)
    loop[ 1]: type(outer) 4 trims(4,5,6,7)
        trim[ 4]: edge( 4) v0( 1) v1( 4) tolerance(0,0)
            type(mated   -south side iso) rev3d(0) 2d_curve(4)
            domain(8,9) start(8,0) end(9,0)
            surface points start(0,8,0) end(-0.723627,8.72363,0)
        trim[ 5]: edge( 5) v0( 4) v1( 5) tolerance(0,0)
            type(mated   -east side iso) rev3d(0) 2d_curve(5)
            domain(0,11) start(9,0) end(9,11)
            surface points start(-0.723627,8.72363,0) end(-0.723627,8.72363,11)
        trim[ 6]: edge( 6) v0( 5) v1( 2) tolerance(0,0)
            type(mated   -north side iso) rev3d(1) 2d_curve(6)
            domain(8,9) start(9,11) end(8,11)
            surface points start(-0.723627,8.72363,11) end(0,8,11)
        trim[ 7]: edge( 1) v0( 2) v1( 1) tolerance(0,0)
            type(mated   -west side iso) rev3d(1) 2d_curve(7)
            domain(0,11) start(8,11) end(8,0)
            surface points start(0,8,11) end(0,8,0)
face[ 2]: surface(2) reverse(0) loops(2)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    (Face geometry is the same as underlying surface.)
    loop[ 2]: type(outer) 4 trims(8,9,10,11)
        trim[ 8]: edge( 7) v0( 4) v1( 6) tolerance(0,0)
            type(mated   -south side iso) rev3d(0) 2d_curve(8)
            domain(9,18) start(9,0) end(18,0)
            surface points start(-0.723627,8.72363,0) end(-9.72363,8.72363,0)
        trim[ 9]: edge( 8) v0( 6) v1( 7) tolerance(0,0)
            type(mated   -east side iso) rev3d(0) 2d_curve(9)
            domain(0,11) start(18,0) end(18,11)
            surface points start(-9.72363,8.72363,0) end(-9.72363,8.72363,11)
        trim[10]: edge( 9) v0( 7) v1( 5) tolerance(0,0)
            type(mated   -north side iso) rev3d(1) 2d_curve(10)
            domain(9,18) start(18,11) end(9,11)
            surface points start(-9.72363,8.72363,11) end(-0.723627,8.72363,11)
        trim[11]: edge( 5) v0( 5) v1( 4) tolerance(0,0)
            type(mated   -west side iso) rev3d(1) 2d_curve(11)
            domain(0,11) start(9,11) end(9,0)
            surface points start(-0.723627,8.72363,11) end(-0.723627,8.72363,0)
face[ 3]: surface(3) reverse(0) loops(3)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    (Face geometry is the same as underlying surface.)
    loop[ 3]: type(outer) 4 trims(12,13,14,15)
        trim[12]: edge(10) v0( 6) v1( 8) tolerance(0,0)
            type(mated   -south side iso) rev3d(0) 2d_curve(12)
            domain(18,18.3618) start(18,0) end(18.3618,0)
            surface points start(-9.72363,8.72363,0) end(-9.72363,8.36181,0)
        trim[13]: edge(11) v0( 8) v1( 9) tolerance(0,0)
            type(mated   -east side iso) rev3d(0) 2d_curve(13)
            domain(0,11) start(18.3618,0) end(18.3618,11)
            surface points start(-9.72363,8.36181,0) end(-9.72363,8.36181,11)
        trim[14]: edge(12) v0( 9) v1( 7) tolerance(0,0)
            type(mated   -north side iso) rev3d(1) 2d_curve(14)
            domain(18,18.3618) start(18.3618,11) end(18,11)
            surface points start(-9.72363,8.36181,11) end(-9.72363,8.72363,11)
        trim[15]: edge( 8) v0( 7) v1( 6) tolerance(0,0)
            type(mated   -west side iso) rev3d(1) 2d_curve(15)
            domain(0,11) start(18,11) end(18,0)
            surface points start(-9.72363,8.72363,11) end(-9.72363,8.72363,0)
face[ 4]: surface(4) reverse(0) loops(4)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    (Face geometry is the same as underlying surface.)
    loop[ 4]: type(outer) 4 trims(16,17,18,19)
        trim[16]: edge(13) v0( 8) v1(10) tolerance(0,0)
            type(mated   -south side iso) rev3d(0) 2d_curve(16)
            domain(18.3618,27.3618) start(18.3618,0) end(27.3618,0)
            surface points start(-9.72363,8.36181,0) end(-0.723627,8.36181,0)
        trim[17]: edge(14) v0(10) v1(11) tolerance(0,0)
            type(mated   -east side iso) rev3d(0) 2d_curve(17)
            domain(0,11) start(27.3618,0) end(27.3618,11)
            surface points start(-0.723627,8.36181,0) end(-0.723627,8.36181,11)
        trim[18]: edge(15) v0(11) v1( 9) tolerance(0,0)
            type(mated   -north side iso) rev3d(1) 2d_curve(18)
            domain(18.3618,27.3618) start(27.3618,11) end(18.3618,11)
            surface points start(-0.723627,8.36181,11) end(-9.72363,8.36181,11)
        trim[19]: edge(11) v0( 9) v1( 8) tolerance(0,0)
            type(mated   -west side iso) rev3d(1) 2d_curve(19)
            domain(0,11) start(18.3618,11) end(18.3618,0)
            surface points start(-9.72363,8.36181,11) end(-9.72363,8.36181,0)
face[ 5]: surface(5) reverse(0) loops(5)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    (Face geometry is the same as underlying surface.)
    loop[ 5]: type(outer) 4 trims(20,21,22,23)
        trim[20]: edge(16) v0(10) v1(12) tolerance(0,0)
            type(mated   -south side iso) rev3d(0) 2d_curve(20)
            domain(27.3618,28.3618) start(27.3618,0) end(28.3618,0)
            surface points start(-0.723627,8.36181,0) end(-0.361814,8,0)
        trim[21]: edge(17) v0(12) v1(13) tolerance(0,0)
            type(mated   -east side iso) rev3d(0) 2d_curve(21)
            domain(0,11) start(28.3618,0) end(28.3618,11)
            surface points start(-0.361814,8,0) end(-0.361814,8,11)
        trim[22]: edge(18) v0(13) v1(11) tolerance(0,0)
            type(mated   -north side iso) rev3d(1) 2d_curve(22)
            domain(27.3618,28.3618) start(28.3618,11) end(27.3618,11)
            surface points start(-0.361814,8,11) end(-0.723627,8.36181,11)
        trim[23]: edge(14) v0(11) v1(10) tolerance(0,0)
            type(mated   -west side iso) rev3d(1) 2d_curve(23)
            domain(0,11) start(27.3618,11) end(27.3618,0)
            surface points start(-0.723627,8.36181,11) end(-0.723627,8.36181,0)
face[ 6]: surface(6) reverse(0) loops(6)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    (Face geometry is the same as underlying surface.)
    loop[ 6]: type(outer) 4 trims(24,25,26,27)
        trim[24]: edge(19) v0(12) v1(14) tolerance(0,0)
            type(mated   -south side iso) rev3d(0) 2d_curve(24)
            domain(28.3618,36.3618) start(28.3618,0) end(36.3618,0)
            surface points start(-0.361814,8,0) end(-0.361814,0,0)
        trim[25]: edge(20) v0(14) v1(15) tolerance(0,0)
            type(mated   -east side iso) rev3d(0) 2d_curve(25)
            domain(0,11) start(36.3618,0) end(36.3618,11)
            surface points start(-0.361814,0,0) end(-0.361814,0,11)
        trim[26]: edge(21) v0(15) v1(13) tolerance(0,0)
            type(mated   -north side iso) rev3d(1) 2d_curve(26)
            domain(28.3618,36.3618) start(36.3618,11) end(28.3618,11)
            surface points start(-0.361814,0,11) end(-0.361814,8,11)
        trim[27]: edge(17) v0(13) v1(12) tolerance(0,0)
            type(mated   -west side iso) rev3d(1) 2d_curve(27)
            domain(0,11) start(28.3618,11) end(28.3618,0)
            surface points start(-0.361814,8,11) end(-0.361814,8,0)
face[ 7]: surface(7) reverse(0) loops(7)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    (Face geometry is the same as underlying surface.)
    loop[ 7]: type(outer) 4 trims(28,29,30,31)
        trim[28]: edge(22) v0(14) v1( 0) tolerance(0,0)
            type(mated   -south side iso) rev3d(0) 2d_curve(28)
            domain(36.3618,36.7236) start(36.3618,0) end(36.7236,0)
            surface points start(-0.361814,0,0) end(0,0,0)
        trim[29]: edge( 3) v0( 0) v1( 3) tolerance(0,0)
            type(mated   -east side iso) rev3d(0) 2d_curve(29)
            domain(0,11) start(36.7236,0) end(36.7236,11)
            surface points start(0,0,0) end(0,0,11)
        trim[30]: edge(23) v0( 3) v1(15) tolerance(0,0)
            type(mated   -north side iso) rev3d(1) 2d_curve(30)
            domain(36.3618,36.7236) start(36.7236,11) end(36.3618,11)
            surface points start(0,0,11) end(-0.361814,0,11)
        trim[31]: edge(20) v0(15) v1(14) tolerance(0,0)
            type(mated   -west side iso) rev3d(1) 2d_curve(31)
            domain(0,11) start(36.3618,11) end(36.3618,0)
            surface points start(-0.361814,0,11) end(-0.361814,0,0)
face[ 8]: surface(8) reverse(1) loops(8)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    loop[ 8]: type(outer) 8 trims(32,33,34,35,36,37,38,39)
        trim[32]: edge( 0) v0( 0) v1( 1) tolerance(0,0)
            type(mated   -u iso) rev3d(0) 2d_curve(32)
            domain(0,8) start(0,0) end(0,8)
            surface points start(0,0,0) end(0,8,0)
        trim[33]: edge( 4) v0( 1) v1( 4) tolerance(0,0)
            type(mated   ) rev3d(0) 2d_curve(33)
            domain(8,9) start(0,8) end(-0.723627,8.72363)
            surface points start(0,8,0) end(-0.723627,8.72363,0)
        trim[34]: edge( 7) v0( 4) v1( 6) tolerance(0,0)
            type(mated   -v iso) rev3d(0) 2d_curve(34)
            domain(9,18) start(-0.723627,8.72363) end(-9.72363,8.72363)
            surface points start(-0.723627,8.72363,0) end(-9.72363,8.72363,0)
        trim[35]: edge(10) v0( 6) v1( 8) tolerance(0,0)
            type(mated   -u iso) rev3d(0) 2d_curve(35)
            domain(18,18.3618) start(-9.72363,8.72363) end(-9.72363,8.36181)
            surface points start(-9.72363,8.72363,0) end(-9.72363,8.36181,0)
        trim[36]: edge(13) v0( 8) v1(10) tolerance(0,0)
            type(mated   -v iso) rev3d(0) 2d_curve(36)
            domain(18.3618,27.3618) start(-9.72363,8.36181) end(-0.723627,8.36181)
            surface points start(-9.72363,8.36181,0) end(-0.723627,8.36181,0)
        trim[37]: edge(16) v0(10) v1(12) tolerance(0,0)
            type(mated   ) rev3d(0) 2d_curve(37)
            domain(27.3618,28.3618) start(-0.723627,8.36181) end(-0.361814,8)
            surface points start(-0.723627,8.36181,0) end(-0.361814,8,0)
        trim[38]: edge(19) v0(12) v1(14) tolerance(0,0)
            type(mated   -u iso) rev3d(0) 2d_curve(38)
            domain(28.3618,36.3618) start(-0.361814,8) end(-0.361814,0)
            surface points start(-0.361814,8,0) end(-0.361814,0,0)
        trim[39]: edge(22) v0(14) v1( 0) tolerance(0,0)
            type(mated   -v iso) rev3d(0) 2d_curve(39)
            domain(36.3618,36.7236) start(-0.361814,0) end(0,0)
            surface points start(-0.361814,0,0) end(0,0,0)
face[ 9]: surface(9) reverse(0) loops(9)
    Render mesh = nullptr
    Analysis mesh = nullptr
    Preview mesh = nullptr
    loop[ 9]: type(outer) 8 trims(40,41,42,43,44,45,46,47)
        trim[40]: edge( 2) v0( 3) v1( 2) tolerance(0,0)
            type(mated   -u iso) rev3d(0) 2d_curve(40)
            domain(0,8) start(0,0) end(0,8)
            surface points start(0,0,11) end(0,8,11)
        trim[41]: edge( 6) v0( 2) v1( 5) tolerance(0,0)
            type(mated   ) rev3d(0) 2d_curve(41)
            domain(8,9) start(0,8) end(-0.723627,8.72363)
            surface points start(0,8,11) end(-0.723627,8.72363,11)
        trim[42]: edge( 9) v0( 5) v1( 7) tolerance(0,0)
            type(mated   -v iso) rev3d(0) 2d_curve(42)
            domain(9,18) start(-0.723627,8.72363) end(-9.72363,8.72363)
            surface points start(-0.723627,8.72363,11) end(-9.72363,8.72363,11)
        trim[43]: edge(12) v0( 7) v1( 9) tolerance(0,0)
            type(mated   -u iso) rev3d(0) 2d_curve(43)
            domain(18,18.3618) start(-9.72363,8.72363) end(-9.72363,8.36181)
            surface points start(-9.72363,8.72363,11) end(-9.72363,8.36181,11)
        trim[44]: edge(15) v0( 9) v1(11) tolerance(0,0)
            type(mated   -v iso) rev3d(0) 2d_curve(44)
            domain(18.3618,27.3618) start(-9.72363,8.36181) end(-0.723627,8.36181)
            surface points start(-9.72363,8.36181,11) end(-0.723627,8.36181,11)
        trim[45]: edge(18) v0(11) v1(13) tolerance(0,0)
            type(mated   ) rev3d(0) 2d_curve(45)
            domain(27.3618,28.3618) start(-0.723627,8.36181) end(-0.361814,8)
            surface points start(-0.723627,8.36181,11) end(-0.361814,8,11)
        trim[46]: edge(21) v0(13) v1(15) tolerance(0,0)
            type(mated   -u iso) rev3d(0) 2d_curve(46)
            domain(28.3618,36.3618) start(-0.361814,8) end(-0.361814,0)
            surface points start(-0.361814,8,11) end(-0.361814,0,11)
        trim[47]: edge(23) v0(15) v1( 3) tolerance(0,0)
            type(mated   -v iso) rev3d(0) 2d_curve(47)
            domain(36.3618,36.7236) start(-0.361814,0) end(0,0)
            surface points start(-0.361814,0,11) end(0,0,11)
alteous commented 1 year ago

I wrote a program that edits the glTF file and inserts points to visualise the control points of the NURBS surfaces. The points are coloured differently for each surface. These are the only points I can see and they are in weird places. The export data says there are six control points in each surface.

control-points

alteous commented 1 year ago

I amended the code to display little cubes instead. The control points are much easier to see now. They are still in strange places.

image

alteous commented 1 year ago

The contents of the dump for the NURBS surfaces from OpenNURBS matches the glTF output.

ON_NurbsSurface dim = 3 is_rat = 1
        order = 3 X 2 cv_count = 3 X 2
Knot Vector 0 ( 4 knots )
index                     value  mult       delta
    0       27.361813613493318     2
    2       28.361813613493318     2           1
Knot Vector 1 ( 2 knots )
index                     value  mult       delta
    0                        0     1
    1                       11     1          11
Control Points  6 rational points
  index               value
  CV[ 0][ 0] [-0.72362722698663262, 8.3618136134933163, 0, 1] = (-0.72362722698663262, 8.3618136134933163, 0)
  CV[ 0][ 1] [-0.72362722698663262, 8.3618136134933163, 11, 1] = (-0.72362722698663262, 8.3618136134933163, 11)

  CV[ 1][ 0] [-0.25584085962673253, 5.912695109119114, 0, 0.70710678118654757] = (-0.36181361349331631, 8.3618136134933181, 0)
  CV[ 1][ 1] [-0.25584085962673253, 5.912695109119114, 7.7781745930520234, 0.70710678118654757] = (-0.36181361349331631, 8.3618136134933181, 11)

  CV[ 2][ 0] [-0.36181361349331626, 8, 0, 1] = (-0.36181361349331626, 8, 0)
  CV[ 2][ 1] [-0.36181361349331626, 8, 11, 1] = (-0.36181361349331626, 8, 11)
ON_NurbsSurface dim = 3 is_rat = 1
        order = 3 X 2 cv_count = 3 X 2
Knot Vector 0 ( 4 knots )
index                     value  mult       delta
    0                        8     2
    2                        9     2           1
Knot Vector 1 ( 2 knots )
index                     value  mult       delta
    0                        0     1
    1                       11     1          11
Control Points  6 rational points
  index               value
  CV[ 0][ 0] [0, 8, 0, 1] = (0, 8, 0)
  CV[ 0][ 1] [0, 8, 11, 1] = (0, 8, 11)

  CV[ 1][ 0] [0, 6.1685359687458456, 0, 0.70710678118654757] = (0, 8.7236272269866326, 0)
  CV[ 1][ 1] [0, 6.1685359687458456, 7.7781745930520234, 0.70710678118654757] = (0, 8.7236272269866326, 11)

  CV[ 2][ 0] [-0.72362722698663273, 8.7236272269866326, 0, 1] = (-0.72362722698663273, 8.7236272269866326, 0)
  CV[ 2][ 1] [-0.72362722698663273, 8.7236272269866326, 11, 1] = (-0.72362722698663273, 8.7236272269866326, 11)
        {
          "type": "nurbs",
          "nurbs": {
            "controlPoints": [
              [
                -0.724,
                8.362,
                0.0,
                1.0
              ],
              [
                -0.724,
                8.362,
                11.0,
                1.0
              ],
              [
                -0.256,
                5.913,
                0.0,
                0.707
              ],
              [
                -0.256,
                5.913,
                7.778,
                0.707
              ],
              [
                -0.362,
                8.0,
                0.0,
                1.0
              ],
              [
                -0.362,
                8.0,
                11.0,
                1.0
              ]
            ],
            "numControlPoints": [
              3,
              2
            ],
            "numKnots": [
              6,
              4
            ],
            "knotVector": [
              27.362,
              27.362,
              27.362,
              28.362,
              28.362,
              28.362,
              0.0,
              0.0,
              11.0,
              11.0
            ],
            "order": [
              3,
              2
            ]
          }
        },
        {
          "type": "nurbs",
          "nurbs": {
            "controlPoints": [
              [
                0.0,
                8.0,
                0.0,
                1.0
              ],
              [
                0.0,
                8.0,
                11.0,
                1.0
              ],
              [
                0.0,
                6.1690000000000005,
                0.0,
                0.707
              ],
              [
                0.0,
                6.1690000000000005,
                7.778,
                0.707
              ],
              [
                -0.724,
                8.724,
                0.0,
                1.0
              ],
              [
                -0.724,
                8.724,
                11.0,
                1.0
              ]
            ],
            "numControlPoints": [
              3,
              2
            ],
            "numKnots": [
              6,
              4
            ],
            "knotVector": [
              8.0,
              8.0,
              8.0,
              9.0,
              9.0,
              9.0,
              0.0,
              0.0,
              11.0,
              11.0
            ],
            "order": [
              3,
              2
            ]
          }
        },
alteous commented 1 year ago

@mlfarrell, are you able to confirm you are using the same B-rep data to render with? I can only work with the data I'm given, so either I'm reading the wrong data or the data is incorrect.

mlfarrell commented 1 year ago

@alteous the ON data is generated from ON itself when converting curves (tangent arcs in this case) to nurbs curves and eventually nurbs surfaces. When I render, I'm simply calling the ON surface evaluator. So i'd be very surprised if the data that I was using to render is wrong.

alteous commented 12 months ago

I created a similar part which renders correctly in the modelling app but fails to generate a valid B-rep when calling Scene::Model::Brep::Brep::getForRust:

image

BC and FG are the expected control points for the NURBS curves.

sketch

I have modified a test to reproduce the issue locally: https://github.com/KittyCAD/engine/pull/1501/commits/767182c17647feeea0e1f3a53c80a1266fa69683#diff-a0262fea108af44a98cc49e5eb72641963dd816513f2d0a22eb738fcfed55ebe

This is the output:

running 1 test
KittyCAD Engine Renderer Initialized 
  NVIDIA GeForce RTX 3060 Laptop GPU (2)
  Vulkan 1.3
CUDA (nvenc) GPU in use: NVIDIA GeForce RTX 3060 Laptop GPU
center: (0, 0)
pole: (0, -1)
angle: 90 degrees
offset: 0 degrees
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
endpoint: (2, 0, 0)
Warning: Brep validation failed!
Warning: brep.m_E[19] edge is not valid.
    edge.m_tolerance=-1.23432e+308 (should be >= 0.0)
ON_Brep.m_E[19] is invalid.

test tests::serial_test_run_engine_stream_check_lines_with_extrude_export_to_step ... FAILED

failures:

---- tests::serial_test_run_engine_stream_check_lines_with_extrude_export_to_step stdout ----
thread 'tests::serial_test_run_engine_stream_check_lines_with_extrude_export_to_step' panicked at src/tests.rs:894:23:
called `Result::unwrap()` on an `Err` value: CppErrors([CppError { code: InternalEngine, msg_internal: "Invalid boundary representation", msg_external: "Invalid boundary representation" }])
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Note the endpoint of the tangental arc is point C as expected. I'm not sure why the B-rep is invalid in this case but it is certainly related to the arcs. If I replace the arcs with simple line curves then I get a correct result:

image

alteous commented 12 months ago

~I also notice some artifacts which may or may not be related:~ The artifacts go away when the model is scaled up so I expect this is simply a floating point precision issue.

artifacts

alteous commented 12 months ago

I understand the surfaces are being evaluated using the 2D trim space rather than the 3D curves. If the 2D curves and the 3D curves do not agree with each other then this would explain why it is rendered correctly but does not produce a valid B-rep.

Until now, I have only been exporting the 3D curves in the glTF, since this is the all that's strictly necessary. I plan to add the 2D curves next and will verify the correctness then.

mlfarrell commented 12 months ago

I suspect this error is due to an out-of-tolerance gap in the brep. let me debug

mlfarrell commented 12 months ago

for the validation failure - https://github.com/KittyCAD/engine/pull/1515

mlfarrell commented 12 months ago

for the rendering glitch - https://github.com/KittyCAD/engine/pull/1516

alteous commented 12 months ago

I can make the B-rep appear as expected by tweaking the control points. The NURBS control points are computed by ON_ArcCurve::GetNurbForm. This function is called by Scene::Model::Brep::Face::updateDrawInfo. Using the debugger, I inspected the values computed by GetNurbForm and found them to be the same as what I'm getting. I have no idea how the engine is rendering this correctly but I am quite certain these values are wrong. My tweaked values are those based on this document (see the 'quarter circle' section): https://www.geometrictools.com/Documentation/NURBSCircleSphere.pdf.

diff -u lines_with_extrude.gltf original_lines_with_extrude.gltf
--- lines_with_extrude.gltf 2023-10-10 17:18:42.911129785 +0100
+++ original_lines_with_extrude.gltf    2023-10-10 17:15:50.476390344 +0100
@@ -810,9 +810,9 @@
                 1.0
               ],
               [
-                1.0,
+                0.707,
                 0.0,
-                -1.0,
+                -0.707,
                 0.707
               ],
               [
@@ -863,9 +863,9 @@
                 1.0
               ],
               [
-                1.0,
-                2.0,
-                -1.0,
+                0.707,
+                1.414,
+                -0.707,
                 0.707
               ],
               [
@@ -1201,15 +1201,15 @@
                 1.0
               ],
               [
-                1.0,
+                0.707,
                 0.0,
-                -1.0,
+                -0.707,
                 0.707
               ],
               [
-                1.0,
-                2.0,
-                -1.0,
+                0.707,
+                1.414,
+                -0.707,
                 0.707
               ],
               [

image

mlfarrell commented 12 months ago

@alteous i'll take a closer look. i dont have your full path set up (the brep export step part), but I'll at least see if I can understand why you're getting the values that you do.

alteous commented 12 months ago

@mlfarrell and I discussed this on Slack. Mike recognised the 3D part of the control points were pre-multiplied by the 4D homogeneous component.

I'm disappointed I didn't notice this myself sooner but at least we know what the problem is now. Amending the export code to un-pre-multiply (i.e., divide :stuck_out_tongue:) the spatial components by the w component fixes the issue.

I'll make the required changes soon and add a new test for this arc case soon. This will add more work to the looming engine test refactor but this fix really can't wait.

alteous commented 12 months ago

https://github.com/KittyCAD/engine/pull/1518 fixes this issue and adds my reproducer code as a new test.

STEP

image

glTF

image