Comments (12)
I'm curious what particular limitations of cadquery are you facing?
from curv.
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.
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.
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.
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.
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.
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.
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.
@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.
@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.
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.
Here's another one. 3 Bezier splines joined into a closed 2D shape.
https://www.shadertoy.com/view/llyXDV
from curv.
Related Issues (20)
- Compiler error when compare parametric value to null HOT 2
- Curv can't find boost include file during build (M1 Mac with macOS 11.4) HOT 7
- Please upload AppImage to GitHub Releases HOT 1
- lib.builder: '}' doesn't pop the origin stack HOT 1
- `curv -le` stops reloading the file after a change, on Windows
- union seams during mesh export HOT 7
- rewrite Curv to use WebGPU HOT 2
- GLTF export produces bad output HOT 1
- Typo in Makefile HOT 1
- Broken link in documentation HOT 1
- 2D "slider" in parameters panel HOT 2
- Bad baground color after two rotation transformations HOT 3
- Error building Curv on Windows 10 with MSYS2 HOT 5
- Build Error on Win 10 HOT 9
- Error on Ubuntu (22.04 LTS) HOT 5
- libfive backend? HOT 10
- Give me access to curv3d/libfive HOT 2
- Something evaluating to incorrect number type
- Don't run GitHub actions on draft PRs
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from curv.