GithubHelp home page GithubHelp logo

Request: Splines? about curv HOT 12 OPEN

lf94 avatar lf94 commented on June 14, 2024
Request: Splines?

from curv.

Comments (12)

A-G-D avatar A-G-D commented on June 14, 2024

I'm curious what particular limitations of cadquery are you facing?

from curv.

doug-moen avatar doug-moen commented on June 14, 2024

Splines are possible. Exactly duplicating the CadQuery API is not possible, because CadQuery and Curv use quite different internal representations. Curv is a volumetric (V-rep) solid-modelling tool, meaning that the fundamental primitives are solid objects. CadQuery uses boundary representation (B-rep), meaning that the primitives describe the boundaries of solid objects. So it changes the set of primitives that are available, and it changes the way you design a model using those primitives.

We already have an ellipse primitive. Try curv -x 'ellipse[2,1]'

The CadQuery vLine, hLine etc appear to be used for specifying the boundary of a polygon, one face at a time. (I don't know CadQuery.) If so, then the equivalent in Curv is polygon, where you specify all of the vertices of a polygon at once. On the other hand, if vLine, hLine etc are stroked line primitives, where the strokes have thickness (like in SVG), then the corresponding 2D primitives are stroke and polyline.

The original paper describing the math behind Curv (signed distance fields or SDF) describes a spline primitive. See docs/papers in the Curv repo. But I never learned the math behind splines, so I've just never implemented it. Most of the Curv primitives are copied from code written by other SDF researchers. So it may just be a matter of finding SDF spline code on the internet and porting it to Curv. Sources I've used in the past include https://shadertoy.com and https://iquilezles.org

from curv.

lf94 avatar lf94 commented on June 14, 2024

Thank you very much @doug-moen !

Luckily I have looked into the math behind splines to implement my own spline in OpenSCAD:

// P = (1−t)³P1 + 3(1−t)²tP2 +3(1−t)t²P3 + t³P4
function bezier4(points) =
let (s = 1.0 / $fn)
[for(t = 0, i = 0; i < $fn + 1; t = t + s, i = i + 1)
       (pow(1 - t, 3)             * points[0])
+  (3 * pow(1 - t, 2) * pow(t, 1) * points[1])
+  (3 * pow(1 - t, 1) * pow(t, 2) * points[2])
+  (                    pow(t, 3) * points[3])
];

Well, "spline", it's for a 4-point bezier curve.

I'm curious, how would you model something like this (an ergonomic controller arm)?

I'm curious what particular limitations of cadquery are you facing?

In particular creating complex curved surfaces is not CadQuery's forté. While I can get pretty far using splines, arcs, and fillet, it gets increasingly hard for CadQuery to accept what I'm asking of it (it will simply say "cannot do B-rep operation" or something like that).

After literally playing with Curv for 1 hour last night and learning just from looking at examples and the docs I'm very impressed with how easy it was to pick up. It may have to do with how I have experience with functional PLs and OpenSCAD though (the latter I doubt because I feel the mental model is different compared to it).

from curv.

doug-moen avatar doug-moen commented on June 14, 2024

OpenSCAD uses boundary representation, which is different from Curv. Your OpenSCAD bezier4 function converts a spline into a collection of line segments, which you could feed into the Curv polygon or polyline function. But this is a polygonal approximation to a curved line, instead of directly representing a curved line (which is what you really want). Curv will encounter performance problems during preview if you subdivide the spline too much (don't try to feed 1000 vertexes to polygon, it will be too slow). Another approach is needed. This is the point where it is helpful to understand how to write SDF distance functions.

Here's the code for polygon, from lib/curv/std.curv in the repo:

// Finite polygon. May be nonconvex. Edges may cross, and the polygon may
// self intersect. Uses the "crossing number" method to determine which
// points are inside/outside the polygon. It doesn't matter if the vertexes
// are listed in clockwise or counterclockwise order.
// (http://geomalgorithms.com/a03-_inclusion.html)
// Exact distance field.
// From https://www.shadertoy.com/view/wdBXRW
// which is Copyright 2019 Inigo Quilez (The MIT Licence)
polygon v = make_shape {
  dist p =
    do
      local p = p@[X,Y];
      local num = count v;
      local d = dot[p-v@0, p-v@0];
      local s = 1;
      local j = num-1;
      for (i in 0..<num) (
        local e = v@j - v@i;
        local w = p - v@i;
        local b = w - e*clamp[dot[w,e]/dot[e,e], 0, 1];
        d := min[d, dot[b,b]];
        local cond = [p@Y >= v@i@Y, p@Y < v@j@Y, e@X*w@Y > e@Y*w@X];
        if (and cond || and(not cond)) s := -s;
        j := i;
      );
    in s * sqrt d;
  bbox = [[...min v,0], [...max v,0]];
  is_2d = true;
};

The dist function computes the distance from an arbitrary point [x,y] to the closest point on the boundary of the polygon. The result is positive if [x,y] is outside the polygon. It is 0 if the point is on the boundary. It is negative if [x,y] is inside the polygon. There are lots of tutorials explaining the SDF representation, here's the one I wrote: https://github.com/curv3d/curv/blob/master/docs/Theory.rst

The polygon code is magic, I didn't invent it, I just copied it from shadertoy.com and transliterated the code into Curv. The spline code needed for Curv will be magic in a similar way. I hope there is some SDF spline code on the internet that can be adopted.

from curv.

lf94 avatar lf94 commented on June 14, 2024

Excellent, I will look for an SDF spline then! Thank you for all the excellent help Doug. Your project is crazy awesome.

Edit: I'll leave this issue open until someone or me has implemented it.

from curv.

theohonohan avatar theohonohan commented on June 14, 2024

Hi,

I'm not sure if this is the right place to mention this. I had a look at the current code for sweeping along Bezier curves. I am also aware of a 2D analytic SDF for quadratic Beziers: https://www.shadertoy.com/view/MlKcDD which seems like it could be mentioned here.

from curv.

lf94 avatar lf94 commented on June 14, 2024

Thank @theohonohan - I've tried such SDFs but they don't work well for the reason of needing to make a closed shape.

from curv.

lf94 avatar lf94 commented on June 14, 2024

It seems a few smart people have come along and figured out some potential SDFs for this! https://www.shadertoy.com/view/3dtBR4

from curv.

theohonohan avatar theohonohan commented on June 14, 2024

@doug-moen posted some code which referred to Inigo Quilez. He founded ShaderToy and his site is a good place to start:
https://iquilezles.org/articles/distfunctions/
https://iquilezles.org/articles/distfunctions2d/

I am not sure what you mean by "the reason of needing to make a closed shape". It's hard not to end up with a closed contour when dealing with SDFs.
See https://iquilezles.org/articles/interiordistance/

from curv.

lf94 avatar lf94 commented on June 14, 2024

@theohonohan you can't just arbitrarily combine SDFs. There are "proper SDFs" that are necessary for further manipulations. An example is the offset manipulation. If you don't have a proper SDF, this will fail.

That example is not using bezier curves. I have studied those exact materials over a year ago and they were not sufficient to create proper SDFs for arbitrary closed shapes.

from curv.

theohonohan avatar theohonohan commented on June 14, 2024

RIght, the third link does discuss the difficulty of making a valid SDF. But the link https://www.shadertoy.com/view/3dtBR4 which you posted just uses min() to intersect SDFs, which is what gave me the idea that you were OK with approximate results.

The problem is not that the resulting shape isn't "closed", though.

from curv.

doug-moen avatar doug-moen commented on June 14, 2024

Here's another one. 3 Bezier splines joined into a closed 2D shape.
https://www.shadertoy.com/view/llyXDV

from curv.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.