GithubHelp home page GithubHelp logo

curv3d / curv Goto Github PK

View Code? Open in Web Editor NEW
1.1K 31.0 72.0 20.07 MB

a language for making art using mathematics

License: Apache License 2.0

CMake 1.09% Makefile 0.13% C++ 93.58% OpenSCAD 0.31% Shell 0.93% GLSL 2.89% C 0.38% PowerShell 0.69%
signed-distance-field function-representation solid-modeling functional-language language csg 3d creative-coding generative-art

curv's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

curv's Issues

Viewer window not opening / OSX Sierra, MBP2017

Greetings,
Install done almost as instructed, with a mod in transform.hpp (added #define GLM_ENABLE_EXPERIMENTAL at the start) to allow compilation to end.

i can generate an stl
but the viewer wont open

any tips to get it working?

Cheers

New: JSON API output

We've been discussing adding a JSON API to help integrating curv with an external interactive editing environment.

We agreed that a simple JSON-based, standard I/O based communication protocol would be ideal to get started. This new output format would be enabled using the -o json-api command line option.

In this protocol, each message is a JSON-encoded object terminated by \n. Each message has the following structure:

{
    "type": <"print"|"warning"|"error"|"shape"|"value">,
    "value": <...>
}

Note: Doug original proposed to have {"print":...}, {"warning":...} but the {type,value} format makes it slightly easier to dispatch messages (it's a map of the type attribute) and leaves room for extension without conflict.

Print & Warning messages

{
    "type": "print",
    "value": "<the string to be printed>"
}

Error message

{
    "type": "error",
    "value": {
         "path": <path to the curv source file>,
         "offset": <offset in bytes -- not UTF8 chars of the error>,
         "line": <line number, starting at 0>,
         "column": <column number, starting at 0>,
         "error": <string for the error name>,
         "description": <error description>,
         "context":[
             <an array of the last N lines up to the line that has an error>
          ]
    }
}

Value message

{
    "type": "value",
    "value": "<the JSON-encoded value>"
}

Shape message

{
    "type": "shape",
    "value": {
         "is2d":<true|false>,
         "is3d":<true|false>,
         "bounds": [x0,y0,z0, x1,y1,z1],
         "glsl" : {
             "platform"  : <platform requirements, to be defined>,
             "fragment": <string representation of the GLSL fragment shader>
         }
    }
}

sum(int) in addition to sum(vector)

I was trying to implement a between without conditionals, ie. from:

between(v,a,b) = if (a <= v && v <= b) 0.0 else 1.0;

to

between(v,a,b) = sum(abs(min(v,b) - max(v,a)));

but I realized this does not work with v as non-vector/list as sum(1) fails. I'm not sure about the state of polymorphic functions in curv, but I'd be happy to submit a patch to the standard library to support that if it doesn't present a performance risk.

Note that in practice, I assume that the first implementation is going to be more effective performance-wise... but maybe not! I've heard that conditionals should be avoided on the GPU.

How to construct polyhedra

Hi Group,

Right now I am quite excited about curv, this is why i wanted to port all the solids from Mercury.

I have:

===============

let
phi =(sqrt(5)+1)/2;
testvec=identity(3);
GDFVectors = [
normalize([1, 0, 0]),
normalize([0, 1, 0]),
normalize([0, 0, 1]),

    normalize([1, 1, 1 ]),
    normalize([-1, 1, 1]),
    normalize([1, -1, 1]),
    normalize([1, 1, -1]),

    normalize([0, 1, phi+1]),
    normalize([0, -1, phi+1]),
    normalize([phi+1, 0, 1]),
    normalize([-phi-1, 0, 1]),
    normalize([1, phi+1, 0]),
    normalize([-1, phi+1, 0]),

    normalize([0, phi, 1]),
    normalize([0, -phi, 1]),
    normalize([1, 0, phi]),
    normalize([-1, 0, phi]),
    normalize([phi, 1, 0]),
    normalize([-phi, 1, 0])

];

c0=GDFVectors[0];
c1=GDFVectors[1];
c2=GDFVectors[2];
c3=GDFVectors[3];
c4=GDFVectors[4];
c5=GDFVectors[5];
c6=GDFVectors[6];
c7=GDFVectors[7];

my_object = make_shape {
dist(x,y,z,t) = let
v=max(
abs(dot([x,y,z],c0)),
abs(dot([x,y,z],c1)),
abs(dot([x,y,z],c2)),
abs(dot([x,y,z],c3)),
abs(dot([x,y,z],c4)),
abs(dot([x,y,z],c5)),
abs(dot([x,y,z],c6)),
);

// tmp1=max(
// for (c in [c3,c4,c5,c6])
// abs(dot([x,y,z],c)),
// );

    in v- 1;
    is_3d = true;
    bbox = [[-1,-1,-1],[1,1,1]];

};

    tmp2=max(
    for (c in [c3,c4,c5,c6])
            abs(dot([1,1,1],c)),
     );

in

my_object

================

But I am facing small problems and i am not sure if curv yet support this.
I see that such functionality is already coded, but i'd like to further automate this.

  • Is it possible to move the for loop inside the make_shape and further inside the max function ?
    I get an
    ERROR: at field .dist: this expression is not supported by the geometry compiler: curv::For_Op

  • Is it possible to directly access GDFVectors[] without using temporary variables c0,c1,c2,c3 ?
    I get an
    ERROR: syntax error in delimited phrase

I tried several syntax constructs, but none of them worked, I would appreciate any help here.

best regards Guenther

Build error

After encountering #16 I used g++-6.4.0 by changing the CMake variable CMAKE_CXX_COMPILER to
/usr/bin/c++-6.4.0 using ccmake ., re-configuring and generating the makefile.

then make gives me the following output:

cube@gecko /tmp/curv (master) $ make
Scanning dependencies of target libcurv
[  2%] Building CXX object CMakeFiles/libcurv.dir/curv/analyser.cc.o
[  4%] Building CXX object CMakeFiles/libcurv.dir/curv/arg.cc.o
[  6%] Building CXX object CMakeFiles/libcurv.dir/curv/builtin.cc.o
[  8%] Building CXX object CMakeFiles/libcurv.dir/curv/context.cc.o
[ 10%] Building CXX object CMakeFiles/libcurv.dir/curv/definition.cc.o
[ 12%] Building CXX object CMakeFiles/libcurv.dir/curv/die.cc.o
[ 14%] Building CXX object CMakeFiles/libcurv.dir/curv/dtostr.cc.o
[ 16%] Building CXX object CMakeFiles/libcurv.dir/curv/evaluator.cc.o
[ 18%] Building CXX object CMakeFiles/libcurv.dir/curv/exception.cc.o
[ 20%] Building CXX object CMakeFiles/libcurv.dir/curv/file.cc.o
[ 22%] Building CXX object CMakeFiles/libcurv.dir/curv/function.cc.o
[ 24%] Building CXX object CMakeFiles/libcurv.dir/curv/gl_compiler.cc.o
[ 26%] Building CXX object CMakeFiles/libcurv.dir/curv/gl_context.cc.o
[ 28%] Building CXX object CMakeFiles/libcurv.dir/curv/list.cc.o
[ 30%] Building CXX object CMakeFiles/libcurv.dir/curv/location.cc.o
[ 32%] Building CXX object CMakeFiles/libcurv.dir/curv/math.cc.o
[ 34%] Building CXX object CMakeFiles/libcurv.dir/curv/module.cc.o
[ 36%] Building CXX object CMakeFiles/libcurv.dir/curv/parser.cc.o
[ 38%] Building CXX object CMakeFiles/libcurv.dir/curv/pattern.cc.o
[ 40%] Building CXX object CMakeFiles/libcurv.dir/curv/program.cc.o
[ 42%] Building CXX object CMakeFiles/libcurv.dir/curv/range.cc.o
[ 44%] Building CXX object CMakeFiles/libcurv.dir/curv/record.cc.o
[ 46%] Building CXX object CMakeFiles/libcurv.dir/curv/scanner.cc.o
[ 48%] Building CXX object CMakeFiles/libcurv.dir/curv/shape.cc.o
[ 50%] Building CXX object CMakeFiles/libcurv.dir/curv/string.cc.o
[ 52%] Building CXX object CMakeFiles/libcurv.dir/curv/structure.cc.o
[ 54%] Building CXX object CMakeFiles/libcurv.dir/curv/system.cc.o
[ 56%] Building CXX object CMakeFiles/libcurv.dir/curv/value.cc.o
[ 58%] Building CXX object CMakeFiles/libcurv.dir/curv/version.cc.o
[ 60%] Linking CXX static library libcurv.a
[ 60%] Built target libcurv
Scanning dependencies of target curv
[ 62%] Building C object CMakeFiles/curv.dir/cmd/readlinex.c.o
[ 64%] Building CXX object CMakeFiles/curv.dir/cmd/curv.cc.o
[ 66%] Building CXX object CMakeFiles/curv.dir/cmd/export.cc.o
[ 68%] Building CXX object CMakeFiles/curv.dir/cmd/export_mesh.cc.o
[ 70%] Building CXX object CMakeFiles/curv.dir/cmd/progdir.cc.o
[ 72%] Linking CXX executable curv
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: cannot open output file curv: Is a directory
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/curv.dir/build.make:200: curv] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/curv.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

I'm probably doing something wrong here :-)

Potentially uninitialized errors in make

I'm getting the following error from make on Ubuntu 18.04 with all dependencies installed.

In file included from /home/noah/curv/./curv/script.h:9:0,
                 from /home/noah/curv/./curv/location.h:8,
                 from /home/noah/curv/./curv/context.h:9,
                 from /home/noah/curv/curv/parser.cc:16:
/home/noah/curv/./curv/shared.h: In function ‘curv::Shared<curv::Phrase> curv::parse_pipeline(curv::Scanner&)’:
/home/noah/curv/./curv/shared.h:57:9: error: ‘<anonymous>’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
         ptr = new(raw) T(std::forward<Args>(args)...);
         ^~~
/home/noah/curv/./curv/shared.h:57:9: error: ‘*((void*)&<anonymous> +4)’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
/home/noah/curv/./curv/shared.h:57:9: error: ‘*((void*)&<anonymous> +8)’ may be used uninitialized in this function [-Werror=maybe-uninitialized]

Recursive function definition raises error

It seems that curv currently does not allow recursive function definition (see group thread). The following code

rand1 =  match [
    (x)   ->  frac(sin(x)*100000.0);
    (x,y) -> rand1(rand1(x) + rand1(y));
];

raises the following error:

ERROR: illegal recursive reference
at file "letrec.curv":
3|     (x,y) -> rand1(rand1(x) + rand1(y));
                ^^^^^          

Autocompletion in REPL

The REPL is editable (you can use arrow keys and backspace) and I saw somewhere “readline” as a dependency: afaik readline has autocompletion facilities, if curv use it, it could use them so that to offer autocompletion depending on current scope and namespace, as do most (lisp) REPL I knew until then. May be a first step to an eventual project of adding autocompletion to editor modes as I suggested and then to a future three-pane IDE as suggested in https://github.com/doug-moen/curv/blob/master/docs/Future_Work.rst#gui

Examples don't all work

I've been playing with your code but finding that not all the examples work, some just display a coloured screen.
Ones that have problems:
engrave.curv just shows a light blue.
gyroid.curv just shows a olive green
lathe.curv just shows a light blue
morph.curv just shows a light blue
neovius.curv shows the olive green
pancake.curv shows the olive green
plato.curv shows the light blue
rainbow.curv shows the light blue
rbgsphere.curv shows the light blue
rounded.curv shows the olive green
schartz.curv shows a red
shreks_donut shows the light blue
sinewaves.curv shows the light blue
smoke3.curv shows the light blue (however smoke works fine).
sterographic.curv shows the light blue
tor.curv shows the light blue
twist.curv shows the olive green

all other examples seem to work as expected. I'm using linux mint 18.2, nvidia driver glslViewer compiled from github.
Do these work for you?

Request: RNG builtin

It would be helpful both for constructing shapes and for testing if Curv had a built-in random number generator. A simple rnd() function that returns a uniform float from [0,1] should suffice for most use cases.

Curv doesn't have global mutable state so it is quite inconvenient to implement this in the language itself. Therefore, a builtin looks like the best solution here. A nice extra would be the ability to optionally seed the generator with a fixed value passed as a command line argument; this would enable reproducible output.

Working with lists inside distance functions

I am trying to build a library for working with polyhedra in Curv. I have written a function that computes the signed distance from a point to an arbitrary (convex or non-convex) polyhedron, described by a list of vertices and a list of faces, each of which consists of a list of vertex indices.

The function is working, in the sense that it gives the correct result when invoked separately, but I am hitting a brick wall trying to use it inside an actual shape's distance function. The problems all seem to come down to limitations when working with lists inside distance functions.

For instance, it does not seem to be possible to even index a list:

let
points = [[0, 0, 0]];
in
make_shape {
  dist (x, y, z, t) =
    mag points[0];    // <-- "Geometry Compiler: not a constant"
  bbox = [[0, 0, 0], [1, 1, 1]];
  is_3d = true;
}

Surrounding point[0] with parentheses gives a different error, which makes me suspect there is a bug here as the two expressions should be entirely equivalent:

let
points = [[0, 0, 0]];
in
make_shape {
  dist (x, y, z, t) =
    mag (points[0]);    // <-- "Geometry Compiler: [[0,0,0]] is not a function"
  bbox = [[0, 0, 0], [1, 1, 1]];
  is_3d = true;
}

Attempting to move the declaration of points inside the distance function reveals yet another problem:

make_shape {
  dist (x, y, z, t) =
    let
    points = [[0, 0, 0]];    // <-- "this list constructor does not support the Geometry Compiler"
    in
    mag points[0];
  bbox = [[0, 0, 0], [1, 1, 1]];
  is_3d = true;
}

The documentation does mention that standard iteration is not supported within distance functions and that imperative constructs are needed instead, so I was prepared to have to work around that. But from the above examples it appears that not only iteration, but lists in general are unsupported, as neither indexing nor construction appears to work. Is the Geometry Compiler really this limited?

Looking at the standard library, all existing distance functions seem to use either the built-in min/max primitives, which work with list arguments, or be constructed by repeated application of some fixed n-ary operator, allowing the handling of lists to be moved outside of the distance function. Neither of the two approaches will work for arbitrary nonconvex polyhedra with nonconvex faces.

I hope I am missing something here and that there is in fact a way to work with lists that has simply escaped my notice so far. If there isn't, it would unfortunately seem that many very interesting distance functions are currently out of reach 😟

Value Scrubbing / Graphical Value Pickers

"Value Scrubbing" is the ability to modify a value in a Curv program using direct manipulation. For example, tweaking a numerical value using a graphical slider. While you drag the indicator on the slider, the shape in the Viewer window updates in real time. This is an important "live coding" feature that makes it easy to explore the effect that different parameter values have on a parametric shape.

Here are two approaches that we could take in Curv. They aren't mutually exclusive, and they serve different types of users.

Value Pickers in the Viewer Window

In one approach, you modify the source code and declare which parameters can be "scrubbed" using an interactive value picker. The declaration includes the type of value picker, and additional information like the start and end values of a numeric slider. When the program is evaluated and the shape is displayed, a collection of value pickers is displayed in the Viewer window along with the shape. This is similar to the Thingiverse customizer, the OpenSCAD customizer, and Fragmentarium.

In this approach, a developer can design a parametric shape, and create a "user interface" for tweaking the parameters. Then another user, who may not understand the code, can use the value pickers in the Viewer window to customize the shape.

Value Pickers in the Editor Window

In the other approach, you select a literal constant in the source code, and a value picker appears above the constant for scrubbing the value. Examples:

Used by developers, for writing Curv programs.

Build process faild on openSuSE 42.3

Describe the bug
A clear and concise description of what the bug is.
This a build problem.

Build Log
echo '#define CURV_VERSION "'git describe --tags --always --dirty'"' >,v
if cmp -s ,v libcurv/version.h; then rm ,v; else mv ,v libcurv/version.h; fi
rm -rf CMakeCache.txt CMakeFiles
mkdir -p release
cd release; cmake -DCMAKE_BUILD_TYPE=Release ..
-- Boost version: 1.54.0
-- Found the following Boost libraries:
-- iostreams
-- system
-- thread
-- regex
-- chrono
-- date_time
-- atomic
-- Using X11 for window creation
-- Configuring done
-- Generating done
-- Build files have been written to: /home/peter/Downloads/Apps/3D-CAD/curv/release
cd release; make
make[1]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release'
make[2]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release'
make[3]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release'
Scanning dependencies of target replxx
make[3]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release'
make[3]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release'
[ 0%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/conversion.cxx.o
[ 0%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/replxx.cxx.o
[ 2%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/util.cxx.o
[ 2%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/prompt.cxx.o
[ 2%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/inputbuffer.cxx.o
[ 4%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/windows.cxx.o
[ 4%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/history.cxx.o
[ 4%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/io.cxx.o
[ 6%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/escape.cxx.o
[ 6%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/wcwidth.cpp.o
[ 9%] Building CXX object CMakeFiles/replxx.dir/extern/replxx/src/ConvertUTF.cpp.o
[ 9%] Linking CXX static library libreplxx.a
make[3]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release'
[ 9%] Built target replxx
make[3]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release'
Scanning dependencies of target libcurv
make[3]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release'
make[3]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release'
[ 11%] Building CXX object CMakeFiles/libcurv.dir/libcurv/record.cc.o
In file included from /home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/list.h:8:0,
from /home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/record.h:8,
from /home/peter/Downloads/Apps/3D-CAD/curv/libcurv/record.cc:5:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:105:49: warning: multi-character character constant [-Wmultichar]
static constexpr uint64_t k_nanbits = 0x7FFF'0000'0000'0000;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:105:59: warning: missing terminating ' character [enabled by default]
static constexpr uint64_t k_nanbits = 0x7FFF'0000'0000'0000;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:105:5: error: missing terminating ' character
static constexpr uint64_t k_nanbits = 0x7FFF'0000'0000'0000;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:113:50: warning: invalid suffix on literal; C++11 requires a space between literal and identifier [-Wliteral-suffix]
static constexpr uint64_t k_boolmask = 0xFFFF'FFFF'FFFF'FFFE;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:113:50: warning: multi-character character constant [-Wmultichar]
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:113:60: warning: missing terminating ' character [enabled by default]
static constexpr uint64_t k_boolmask = 0xFFFF'FFFF'FFFF'FFFE;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:113:5: error: missing terminating ' character
static constexpr uint64_t k_boolmask = 0xFFFF'FFFF'FFFF'FFFE;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:120:42: warning: invalid suffix on literal; C++11 requires a space between literal and identifier [-Wliteral-suffix]
bits_ = ((uint64_t)r & 0x0000'FFFF'FFFF'FFFF) | Value::k_nanbits;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:120:42: warning: multi-character character constant [-Wmultichar]
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:120:52: warning: missing terminating ' character [enabled by default]
bits_ = ((uint64_t)r & 0x0000'FFFF'FFFF'FFFF) | Value::k_nanbits;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:120:13: error: missing terminating ' character
bits_ = ((uint64_t)r & 0x0000'FFFF'FFFF'FFFF) | Value::k_nanbits;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:105:43: error: expected ‘;’ at end of member declaration
static constexpr uint64_t k_nanbits = 0x7FFF'0000'0000'0000;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:105:49: error: expected unqualified-id before '\x30303030'
static constexpr uint64_t k_nanbits = 0x7FFF'0000'0000'0000;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:113:44: error: expected ‘;’ at end of member declaration
static constexpr uint64_t k_boolmask = 0xFFFF'FFFF'FFFF'FFFE;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:113:50: error: expected unqualified-id before '\x46464646'
static constexpr uint64_t k_boolmask = 0xFFFF'FFFF'FFFF'FFFE;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:105:31: error: ‘curv::Value::k_nanbits’ may not be static because it is a member of a union
static constexpr uint64_t k_nanbits = 0x7FFF'0000'0000'0000;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:112:31: error: ‘curv::Value::k_boolbits’ may not be static because it is a member of a union
static constexpr uint64_t k_boolbits = k_nanbits|2;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:113:31: error: ‘curv::Value::k_boolmask’ may not be static because it is a member of a union
static constexpr uint64_t k_boolmask = 0xFFFF'FFFF'FFFF'FFFE;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h: In constructor ‘constexpr curv::Value::Value()’:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:134:47: error: ‘k_nullbits’ was not declared in this scope
inline constexpr Value() noexcept : bits_{k_nullbits} {}
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:134:57: error: cannot convert ‘’ to ‘uint64_t {aka long unsigned int}’ in initialization
inline constexpr Value() noexcept : bits_{k_nullbits} {}
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h: In member function ‘bool curv::Value::is_null() const’:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:139:25: error: ‘k_nullbits’ was not declared in this scope
return bits_ == k_nullbits;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h: In constructor ‘curv::Value::Value(double)’:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:172:21: error: ‘k_nullbits’ was not declared in this scope
bits_ = k_nullbits;
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h: In constructor ‘curv::Value::Value(curv::Sharedcurv::Ref_Value)’:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:209:53: error: ‘struct curv::Sharedcurv::Ref_Value’ has no member named ‘detach’
inline Value(Shared<Ref_Value> ptr) : Value(ptr.detach())
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h: In constructor ‘curv::Value::Value(curv::Value&&)’:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/value.h:313:21: error: ‘k_nullbits’ was not declared in this scope
val.bits_ = k_nullbits;
^
In file included from /home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/list.h:9:0,
from /home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/record.h:8,
from /home/peter/Downloads/Apps/3D-CAD/curv/libcurv/record.cc:5:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/tail_array.h: In static member function ‘static std::unique_ptr<curv::Tail_Array > curv::Tail_Array::make(size_t, Rest&& ...)’:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/tail_array.h:121:14: error: ‘is_trivially_default_constructible’ is not a member of ‘std’
if (!std::is_trivially_default_constructible<_value_type>::value) {
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/tail_array.h:121:65: error: expected primary-expression before ‘>’ token
if (!std::is_trivially_default_constructible<_value_type>::value) {
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/tail_array.h:121:66: error: ‘::value’ has not been declared
if (!std::is_trivially_default_constructible<_value_type>::value) {
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/tail_array.h: In static member function ‘static std::unique_ptr<curv::Tail_Array > curv::Tail_Array::make_copy(curv::Tail_Array::_value_type*, size_t, Rest&& ...)’:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/tail_array.h:193:13: error: ‘is_trivially_copy_constructible’ is not a member of ‘std’
if (std::is_trivially_copy_constructible<_value_type>::value) {
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/tail_array.h:193:61: error: expected primary-expression before ‘>’ token
if (std::is_trivially_copy_constructible<_value_type>::value) {
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/tail_array.h:193:62: error: ‘::value’ has not been declared
if (std::is_trivially_copy_constructible<_value_type>::value) {
^
In file included from /home/peter/Downloads/Apps/3D-CAD/curv/libcurv/record.cc:5:0:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/record.h: In member function ‘virtual std::unique_ptrcurv::Record::Iter curv::DRecord::iter() const’:
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/record.h:127:16: error: ‘make_unique’ is not a member of ‘std’
return std::make_unique(*this);
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/record.h:127:37: error: expected primary-expression before ‘>’ token
return std::make_unique(*this);
^
/home/peter/Downloads/Apps/3D-CAD/curv/./libcurv/record.h:128:5: warning: control reaches end of non-void function [-Wreturn-type]
}
^
CMakeFiles/libcurv.dir/build.make:62: recipe for target 'CMakeFiles/libcurv.dir/libcurv/record.cc.o' failed
make[3]: *** [CMakeFiles/libcurv.dir/libcurv/record.cc.o] Error 1
make[3]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release'
CMakeFiles/Makefile2:137: recipe for target 'CMakeFiles/libcurv.dir/all' failed
make[2]: *** [CMakeFiles/libcurv.dir/all] Error 2
make[2]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release'
Makefile:127: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release'
Makefile:2: recipe for target 'release' failed
make: *** [release] Error 2

CMakeError.log
Determining if the pthread_create exist failed with the following output:
Change Dir: /mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp

Run Build Command:"/usr/bin/gmake" "cmTC_94a60/fast"
gmake[1]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp'
/usr/bin/gmake -f CMakeFiles/cmTC_94a60.dir/build.make CMakeFiles/cmTC_94a60.dir/build
gmake[2]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_94a60.dir/CheckSymbolExists.c.o
/usr/bin/cc -o CMakeFiles/cmTC_94a60.dir/CheckSymbolExists.c.o -c /mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp/CheckSymbolExists.c
Linking C executable cmTC_94a60
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_94a60.dir/link.txt --verbose=1
/usr/bin/cc CMakeFiles/cmTC_94a60.dir/CheckSymbolExists.c.o -o cmTC_94a60 -rdynamic
CMakeFiles/cmTC_94a60.dir/CheckSymbolExists.c.o: In function main': CheckSymbolExists.c:(.text+0x16): undefined reference to pthread_create'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
collect2: error: ld returned 1 exit status
CMakeFiles/cmTC_94a60.dir/build.make:97: recipe for target 'cmTC_94a60' failed
gmake[2]: *** [cmTC_94a60] Error 1
gmake[2]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp'
Makefile:126: recipe for target 'cmTC_94a60/fast' failed
gmake[1]: *** [cmTC_94a60/fast] Error 2
gmake[1]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp'

File /mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp/CheckSymbolExists.c:
/* */
#include <pthread.h>

int main(int argc, char** argv)
{
(void)argv;
#ifndef pthread_create
return ((int*)(&pthread_create))[argc];
#else
(void)argc;
return 0;
#endif
}

Determining if the function pthread_create exists in the pthreads failed with the following output:
Change Dir: /mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp

Run Build Command:"/usr/bin/gmake" "cmTC_f7fbd/fast"
gmake[1]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp'
/usr/bin/gmake -f CMakeFiles/cmTC_f7fbd.dir/build.make CMakeFiles/cmTC_f7fbd.dir/build
gmake[2]: Entering directory '/mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_f7fbd.dir/CheckFunctionExists.c.o
/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -o CMakeFiles/cmTC_f7fbd.dir/CheckFunctionExists.c.o -c /usr/share/cmake/Modules/CheckFunctionExists.c
Linking C executable cmTC_f7fbd
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_f7fbd.dir/link.txt --verbose=1
/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create CMakeFiles/cmTC_f7fbd.dir/CheckFunctionExists.c.o -o cmTC_f7fbd -rdynamic -lpthreads
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: cannot find -lpthreads
collect2: error: ld returned 1 exit status
CMakeFiles/cmTC_f7fbd.dir/build.make:97: recipe for target 'cmTC_f7fbd' failed
gmake[2]: *** [cmTC_f7fbd] Error 1
gmake[2]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp'
Makefile:126: recipe for target 'cmTC_f7fbd/fast' failed
gmake[1]: *** [cmTC_f7fbd/fast] Error 2
gmake[1]: Leaving directory '/mnt/data2/Apps/3D-CAD/curv/release/CMakeFiles/CMakeTmp'

To Reproduce
on openSuSE 42.3 user or root terminal
Steps to reproduce the behavior:

  1. Go to 'cd /home/peter/Downloads/Apps/3D-CAD/curv'
    or 'cd /mnt/data2/Apps/3D-CAD/curv'
  2. Run '$ make'
  3. make failed (see buildlog above)
  4. See error 'CheckSymbolExists.c:(.text+0x16): undefined reference to `pthread_create'' in release/CMakeError.log above

Expected behavior
Because library pthreads is installed I would expect a make/cmake build without stop on this error

I found following comment at stackoverflow
In general, libraries should follow sources and objects on command line,
and -lpthread is not an "option", it's a library specification. On a system
with only libpthread.a installed,

Don't hesitate to ask for more infos, if needed.
Kind regards
Peter

Export STL enhancement

When exporting to STL the normal vector is always created as 0 0 0
This might be a problem for viewers which change brightness of a face dependant on the angle its
viewed from
BTW: Can I find a function reference manual somewhere ?

Definitions scope: block "let ... in ... where (...)"

Describe the bug
Code below used to work, now it doesn't. Is it by design? Seems most internal "let" can't see outside block definitions.

Curv Program

let
    dummy = 1;
in
    let
        b = a;
    in
        b;
where
    (
        a = sphere;
    )

Expected behavior
A simple sphere drawn on Viewer window. Getting this instead:

ERROR: a: not defined
b = a;
    ^

System Information (please complete the following information):

  • Operating System: Ubuntu 18.04
  • CPU manufacturer, model, version, and # of cores: Dell, Intel 3rd. gen, 4(8) cores
  • Amount of system memory: 16GB
  • GPU manufacturer, model and version: AMD Radeon 7730M
  • GPU driver, if on Linux: stock Ubuntu Gallium+Mesa
  • Are you running the curv command using a remote viewing protocol like VNC or NX? No
  • Are you running the curv command inside a VM? No
  • Curv Version: run the command curv --version and paste the output here.
Curv: 0.2-381-g8d2cda2-dirty
Compiler: gcc 7.3.0
Kernel: Linux 4.15.0-42-generic x86_64
GPU: X.Org, AMD CAPE VERDE (DRM 2.50.0 / 4.15.0-42-generic, LLVM 6.0.0)
OpenGL: 3.0 Mesa 18.0.5

Suggestion

If there is no file argument start interpreting stdin as the curve file or alternatively add an option to interpret stdin as the input file. Then you could do stuff like

cat vase.curv | curv

which might make things easier for adding an ide on top of it. I think that's what openscad did.

GL ERROR: src=33350,id=20,sev=37190 GL_INVALID_VALUE in glUseProgram

Describe the bug
Sometimes, when running a simple Curv program like cube, the viewer displays the shape, but the following lines appear in the terminal, repeated on every frame:

GL ERROR: src=33350,id=20,sev=37190 GL_INVALID_VALUE in glUseProgram
GL ERROR: src=33350,id=20,sev=37190 GL_INVALID_OPERATION in glUniform1("u_resolution"@1 has 2 components, not 1)

This does not always happen and there is no apparent pattern to when it does.

Curv Program

cube

To Reproduce
Cannot be reliably reproduced, although after it happens with one expression it generally happens for all expressions that are subsequently evaluated in the same Curv session.

System Information (please complete the following information):

  • Operating System: Fedora 28
  • CPU manufacturer, model, version, and # of cores: Intel® Core™ i5-6440HQ CPU @ 2.60GHz × 4
  • Amount of system memory: 15.5 GiB
  • GPU manufacturer, model and version: Intel® HD Graphics 530 (Skylake GT2)
  • GPU driver, if on Linux: Open source
  • Are you running the curv command using a remote viewing protocol like VNC or NX? No
  • Are you running the curv command inside a VM? No
  • Curv Version: run the command curv --version and paste the output here.
$ curv --version
Curv: 0.3-128-g3521724
Compiler: gcc 8.2.1 20181105 (Red Hat 8.2.1-5)
Kernel: Linux 4.19.3-200.fc28.x86_64 x86_64
GPU: Intel Open Source Technology Center, Mesa DRI Intel(R) HD Graphics 530 (Skylake GT2) 
OpenGL: 3.0 Mesa 18.0.5

$CURV_EDITOR not defined

Hello
I discover curv with a lot of pleasure, in ubuntu 16.04, but I fail to launch it in livemode
I got

$ curv -le

-e specified but $CURV_EDITOR not defined
Use curv --help for help.

I tried to set the
CURV_EDITOR=gedit

but the result is the same.
I've installed glslViewer, but not much better result.

any idea?

Extended String Literals

To help debug the GPU compiler, I will extend the curv tool to read and write the *.gpu file format, which represents the output of the GPU compiler. It's a hierarchical JSON-like data structure. However, rather than use JSON to represent the data, I'm going to use Curv.

Why use Curv to represent JSON-like data? For one thing, I don't have a JSON parser in the source code right now, but I do have a Curv parser. The bigger issue is that a *.gpu file contains a large block of GLSL source code. This would be unreadable in JSON, because newlines must be escaped as \n within string literals, and that makes a multi-line GLSL program unreadable. I need the *.gpu file to be human readable and human editable. Curv syntax will be easier to read and edit.

I plan to use Curv as a data interchange format more in the future, to help with various features, but this is where it starts.

To make Curv syntax more usable for these purposes, I plan to extend the syntax of string literals. There are two subfeatures: multi-line string literals, and compact escape sequences for escaping $ and " characters.

Multi-Line String Literals

It should be possible to indent a multi-line string literal without adding the indentation to the string content.

My solution: A non-initial line of a multi-line string literal begins with optional whitespace, followed by the '|' character, and this prefix is ignored. Note that '"' and '|' are both a single character, so they line up. Example:

my_string =
    "first line
    |second line
    |final line
    ";

Compact Escape Sequences for $ and "

The escape sequences for $ and " should be compact, and should not grow exponentially if you escape the escape sequence, and escape it again.

C-like languages use \\ and \" to escape the \ and " characters in a string literal. If you repeatedly escape these escape sequences, then you get exponential growth:

\ -> \\ -> \\\\ -> \\\\\\\\
" -> \" -> \\\" -> \\\\\\\"

This problem could occur if we take Curv source code and convert it to a string literal.

To avoid the exponential growth problem associated with repeated escaping, I'll introduce the following new escape sequences:

  • $. expands to $
  • $= expands to ". Mneumonic: = is a sideways " character.

With repeated escaping, these escape sequences grow linearly, instead of exponentially:

$ -> $. -> $.. -> $...
" -> $= -> $.= -> $..=

Can't live-edit file with 'include file' in it

First off: Thanks for writing this, and I am so glad some OpenSCAD folks pointed me to your work. I had just been working with ao/libfive, but running into some problems, and as luck would have it Curv is exactly what I need for some things I'm doing.

I just built Curv for NixOS 18.03 (I will do a PR soon to get this into Nixpkgs) from commit b691830.

I tried running the live editing mode with CURV_EDITOR=emacs curv -le examples/twist.curv and with curv -l examples/twist.curv and the file in another editor. I see the render appear and I'm able to interact with it with the mouse. However, as soon as I save the file (even with no changes or just whitespace), I see the following error in the console:

ERROR: argument #1 of file: illegal recursive reference to file "examples/lib/animate.curv"
at file "examples/twist.curv":
10| include file "lib/animate.curv";
                 ^^^^^^^^^^^^^^^^^^ 

I checked a few other examples and this only seems to happen on those with include file in them. Other files are fine.

Export to gcode

As far as I remember, especially for (reprap/free-software only?) 3D printers, there are two formats: the stl format contain the 3d structure (mesh afaik?) and is displayable, and then (inside or before) the 3D printer, stl is converted to gcode, which control the printer head movement and filament deposition.

Due to gcode working being a lot more voxelish than stl, I guess it wouldn’t be too difficult converting curv to gcode, with less precision limitations than stl, possibly controling color or other parameters in a more portable, adaptative or parametric way?

Has this already been discussed? proposed? thought? I’d like to know more

Normal argument to texturing

When creating textures (x,y,z,t) is available to plug in to some function.
In Shadertoy there are many examples where, in addition to the (x,y,z,t) coordinate, the normal of the field at that (x,y,z,t) point is made available. This is of course very useful for texture generation
I hacked up a thing like this
alt text
https://www.shadertoy.com/view/ld3BDj
the code
let

   RGB_normal  shape =
 
	  make_shape {
 
		dist p : shape.dist(p),
		colour p :  let n= (
		 (  normalize(
		 (shape.dist(p) - shape.dist(p+(0.001,0,0,0))  ) ,
		 (shape.dist(p) - shape.dist(p+(0,0.001,0,0))   )  ,
		 (shape.dist(p) - shape.dist(p+(0,0,0.001,0)) ) ))); 
		 in  
		 max(0,n[X])*[0,1,1]+max(0,n[Y])*[0,1,0]+max(0,n[Z])*[1,1,0]+
		 -min(0,n[X])*[1,0,0]+-min(0,n[Y])*[1,0,1]+-min(0,n[Z])*[0,0,1]
		 , 
		bbox : shape.bbox,
		is_2d : shape.is_2d,
		is_3d : shape.is_3d,
	};	
	 
  
  in
  
  
  
 union( 
 smooth 0.2 .union( 
 union(
	 ellipsoid (1,1.4,2) >>move(1,1,1)  ,
	 cone  {d:1, h:2}>>move(-1,1,0.5), 
	 cylinder  {d:1, h:1.5}>>move(1,-1,1), 
	 cube 1>>move(-1,-1,1) 
	 ), 
   morph 0.75 (  sphere 2 , cube 1.45>>offset 0.05),
   ),
  torus  {major:4, minor:1}>>move(0,0,-1)
 
 )
 >>   RGB_normal

AMD GPU doesn't work

Examples > not working

  • curv lathe.curv pancake, + others show the background colour, no content, 60 fps

  • tor, shreks_donut, + others show the background colour, no content, 1-10 fps

  • morph yields

EE ../../../../../src/gallium/drivers/r600/r600_shader.c:183 r600_pipe_shader_create - translation from TGSI failed !
EE ../../../../../src/gallium/drivers/r600/r600_state_common.c:799 r600_shader_select - Failed to build shader variant (type=1) -1

  • schwartz yields
EE ../../../../../src/gallium/drivers/r600/r600_shader.c:3663 r600_shader_from_tgsi - GPR limit exceeded - shader requires 181 registers
EE ../../../../../src/gallium/drivers/r600/r600_shader.c:183 r600_pipe_shader_create - translation from TGSI failed !
EE ../../../../../src/gallium/drivers/r600/r600_state_common.c:799 r600_shader_select - Failed to build shader variant (type=1) -12


Working:

  • smoke(looks amazing after zooming in slightly)
  • mandelbrot, test, log_spiral, function(all work but will pixelate after intensive zooming)

How do you register to a google groups mailing list without an account

Or is one (google account) required? Because I guess I had one, or two, a very very long time ago, for posting comments on youtube, or maybe (very less likely) for email, and that was before Google Great Unification of Accounts and Services, and I totally forgot passwords, usernames, etc. and i would like not to start this over again, especially with Google…
Or maybe a Google account is considered alike a github account, like, it’s okay to be required since you only need one of them instead of both? I’d like to know what’s the current idea here…
Thank you in advance!

Intel GPU doesn't work

I switched my Ubuntu system to Intel graphics. Shadertoy seems to work, so do the glslViewer examples.

3D Curv programs work. Many 2D programs crash or freeze the GPU (requiring a reboot), including 'square 1' and 'circle 1'. But smoke.curv works.

Okay, this looks like an issue with glslViewer. Here's the shadertoy.com "hello world" program:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
fragColor = vec4(uv,0.5+0.5*sin(iGlobalTime),1.0);
}

This program runs fine on the shadertoy.com website, inside Firefox. But give the same program to glslViewer and we need to reboot. The problem, apparently, is that glslViewer runs shader programs at max frame rate, with no throttling. If the shader program is too simple and fast, then BOOM.

Unicode operator symbols

Extend Curv syntax so that a fixed set of Unicode operator symbols is recognized, as a shorter way of writing code that could also be written in ASCII. (Alexandre Garreau proposed the → operator on the Curv mailing list.)

Adding general support for Unicode strings and Unicode identifiers is much harder, and is not part of this feature request.

Here are some ideas:

    90° == 90*deg
    ≤ ≥ ≠
    ¬a == !a
    a·b == dot(a,b)
    a×b == a*b or cross(a,b) -- not sure which is better
    a÷b
    √a  -- what is the precedence of the √ operator?
    a∧b == a&&b
    a∨b == a||b
    x→x+1   ==   x->x+1
    for (i ∈ 1..10)
    π == pi
    τ == tau
    ∞ == inf
    x↑y = x^y
    “foo” == "foo"  -- note, resistant to systems that translate "" to “”
    g∘f == compose[g,f] -- we don't have a compose function yet, it is planned

Lazy viewer geometry updates

Hi Doug,

I realized that Curv, as of now, keeps rendering the geometry continuously. It's ok for geometries that depend on the "time" variable (color changing ones, for example) and benchmark purposes. I found out, however, that it's not ideal for mobile laptop users (like me), since it increases temperature (and cooling need) and drains battery very fast.

I was thinking that maybe Curv should render the geometry only when really needed - I mean, when geometry changes and/or on users input (viewing changes, zooming, etc.). Of course, for geometries where time component is needed, the current behavior is right.

I've implemented the "lazy" viewer behavior on "lazy_viewer_update" branch, my fork. To be honest, I was trying to infer the need for "time" component from shape properties (there's a needTime() member that does it, supposedly) but the way it's implemented today makes it always consider time. I can't understand language parser well enough yet to try to tackle this duty myself, so I went "poor man" way: -O lazy command-line option. Obviously, it breaks some geometries (as your twistor.curv, for example).

What do you think, is this a feature worth dealing with?

--
Ivo

Link errors with gcc 7.2.0

Clean clone, Gentoo's media-gfx/openvdb-4.0.2.
This failure doesn't happen when I force using g++-6.4.0 as a compiler (but I'm getting stuck on #17).

cube@gecko /tmp/curv (master) $ make
mkdir -p release
cd release; cmake -DCMAKE_BUILD_TYPE=Release ..
-- The C compiler identification is GNU 7.2.0
-- The CXX compiler identification is GNU 7.2.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PythonInterp: /usr/bin/python (found version "3.6.1") 
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/curv/release
cd release; make
make[1]: Entering directory '/tmp/curv/release'
make[2]: Entering directory '/tmp/curv/release'
make[3]: Entering directory '/tmp/curv/release'
Scanning dependencies of target libcurv
make[3]: Leaving directory '/tmp/curv/release'
make[3]: Entering directory '/tmp/curv/release'
[  2%] Building CXX object CMakeFiles/libcurv.dir/curv/analyser.cc.o
[  4%] Building CXX object CMakeFiles/libcurv.dir/curv/arg.cc.o
[  6%] Building CXX object CMakeFiles/libcurv.dir/curv/builtin.cc.o
[  8%] Building CXX object CMakeFiles/libcurv.dir/curv/context.cc.o
[ 10%] Building CXX object CMakeFiles/libcurv.dir/curv/definition.cc.o
[ 12%] Building CXX object CMakeFiles/libcurv.dir/curv/die.cc.o
[ 14%] Building CXX object CMakeFiles/libcurv.dir/curv/dtostr.cc.o
[ 16%] Building CXX object CMakeFiles/libcurv.dir/curv/evaluator.cc.o
[ 18%] Building CXX object CMakeFiles/libcurv.dir/curv/exception.cc.o
[ 20%] Building CXX object CMakeFiles/libcurv.dir/curv/file.cc.o
[ 22%] Building CXX object CMakeFiles/libcurv.dir/curv/function.cc.o
[ 24%] Building CXX object CMakeFiles/libcurv.dir/curv/gl_compiler.cc.o
[ 26%] Building CXX object CMakeFiles/libcurv.dir/curv/gl_context.cc.o
[ 28%] Building CXX object CMakeFiles/libcurv.dir/curv/list.cc.o
[ 30%] Building CXX object CMakeFiles/libcurv.dir/curv/location.cc.o
[ 32%] Building CXX object CMakeFiles/libcurv.dir/curv/math.cc.o
[ 34%] Building CXX object CMakeFiles/libcurv.dir/curv/module.cc.o
[ 36%] Building CXX object CMakeFiles/libcurv.dir/curv/parser.cc.o
[ 38%] Building CXX object CMakeFiles/libcurv.dir/curv/pattern.cc.o
[ 40%] Building CXX object CMakeFiles/libcurv.dir/curv/program.cc.o
[ 42%] Building CXX object CMakeFiles/libcurv.dir/curv/range.cc.o
[ 44%] Building CXX object CMakeFiles/libcurv.dir/curv/record.cc.o
[ 46%] Building CXX object CMakeFiles/libcurv.dir/curv/scanner.cc.o
[ 48%] Building CXX object CMakeFiles/libcurv.dir/curv/shape.cc.o
[ 50%] Building CXX object CMakeFiles/libcurv.dir/curv/string.cc.o
[ 52%] Building CXX object CMakeFiles/libcurv.dir/curv/structure.cc.o
[ 54%] Building CXX object CMakeFiles/libcurv.dir/curv/system.cc.o
[ 56%] Building CXX object CMakeFiles/libcurv.dir/curv/value.cc.o
[ 58%] Building CXX object CMakeFiles/libcurv.dir/curv/version.cc.o
[ 60%] Linking CXX static library libcurv.a
make[3]: Leaving directory '/tmp/curv/release'
[ 60%] Built target libcurv
make[3]: Entering directory '/tmp/curv/release'
Scanning dependencies of target curv
make[3]: Leaving directory '/tmp/curv/release'
make[3]: Entering directory '/tmp/curv/release'
[ 62%] Building C object CMakeFiles/curv.dir/cmd/readlinex.c.o
[ 64%] Building CXX object CMakeFiles/curv.dir/cmd/curv.cc.o
[ 66%] Building CXX object CMakeFiles/curv.dir/cmd/export.cc.o
[ 68%] Building CXX object CMakeFiles/curv.dir/cmd/export_mesh.cc.o
[ 70%] Building CXX object CMakeFiles/curv.dir/cmd/progdir.cc.o
[ 72%] Linking CXX executable curv
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::math::AffineMap::postRotate(double, openvdb::v4_0_2::math::Axis) const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24math9AffineMap10postRotateEdNS1_4AxisE[_ZNK7openvdb6v4_0_24math9AffineMap10postRotateEdNS1_4AxisE]+0x66): undefined reference to `openvdb::v4_0_2::math::simplify(std::shared_ptr<openvdb::v4_0_2::math::AffineMap>)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::math::ScaleTranslateMap::postRotate(double, openvdb::v4_0_2::math::Axis) const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24math17ScaleTranslateMap10postRotateEdNS1_4AxisE[_ZNK7openvdb6v4_0_24math17ScaleTranslateMap10postRotateEdNS1_4AxisE]+0x66): undefined reference to `openvdb::v4_0_2::math::simplify(std::shared_ptr<openvdb::v4_0_2::math::AffineMap>)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::math::TranslationMap::postRotate(double, openvdb::v4_0_2::math::Axis) const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24math14TranslationMap10postRotateEdNS1_4AxisE[_ZNK7openvdb6v4_0_24math14TranslationMap10postRotateEdNS1_4AxisE]+0x66): undefined reference to `openvdb::v4_0_2::math::simplify(std::shared_ptr<openvdb::v4_0_2::math::AffineMap>)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::math::ScaleMap::postRotate(double, openvdb::v4_0_2::math::Axis) const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24math8ScaleMap10postRotateEdNS1_4AxisE[_ZNK7openvdb6v4_0_24math8ScaleMap10postRotateEdNS1_4AxisE]+0x66): undefined reference to `openvdb::v4_0_2::math::simplify(std::shared_ptr<openvdb::v4_0_2::math::AffineMap>)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::math::AffineMap::preShear(double, openvdb::v4_0_2::math::Axis, openvdb::v4_0_2::math::Axis) const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24math9AffineMap8preShearEdNS1_4AxisES3_[_ZNK7openvdb6v4_0_24math9AffineMap8preShearEdNS1_4AxisES3_]+0xb4): undefined reference to `openvdb::v4_0_2::math::simplify(std::shared_ptr<openvdb::v4_0_2::math::AffineMap>)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o:export_mesh.cc:(.text._ZNK7openvdb6v4_0_24math17ScaleTranslateMap8preShearEdNS1_4AxisES3_[_ZNK7openvdb6v4_0_24math17ScaleTranslateMap8preShearEdNS1_4AxisES3_]+0xb4): more undefined references to `openvdb::v4_0_2::math::simplify(std::shared_ptr<openvdb::v4_0_2::math::AffineMap>)' follow
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::GridBase::GridBase(openvdb::v4_0_2::GridBase const&)':
export_mesh.cc:(.text._ZN7openvdb6v4_0_28GridBaseC2ERKS1_[_ZN7openvdb6v4_0_28GridBaseC5ERKS1_]+0x51): undefined reference to `openvdb::v4_0_2::math::Transform::Transform(std::shared_ptr<openvdb::v4_0_2::math::MapBase> const&)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::tree::LeafBuffer<float, 3u>::doLoad() const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24tree10LeafBufferIfLj3EE6doLoadEv[_ZNK7openvdb6v4_0_24tree10LeafBufferIfLj3EE6doLoadEv]+0x13a): undefined reference to `openvdb::v4_0_2::io::setStreamMetadataPtr(std::ios_base&, std::shared_ptr<openvdb::v4_0_2::io::StreamMetadata>&, bool)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::tree::LeafBuffer<unsigned int, 3u>::doLoad() const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24tree10LeafBufferIjLj3EE6doLoadEv[_ZNK7openvdb6v4_0_24tree10LeafBufferIjLj3EE6doLoadEv]+0x13a): undefined reference to `openvdb::v4_0_2::io::setStreamMetadataPtr(std::ios_base&, std::shared_ptr<openvdb::v4_0_2::io::StreamMetadata>&, bool)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::tree::LeafBuffer<short, 3u>::doLoad() const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24tree10LeafBufferIsLj3EE6doLoadEv[_ZNK7openvdb6v4_0_24tree10LeafBufferIsLj3EE6doLoadEv]+0x13a): undefined reference to `openvdb::v4_0_2::io::setStreamMetadataPtr(std::ios_base&, std::shared_ptr<openvdb::v4_0_2::io::StreamMetadata>&, bool)'
CMakeFiles/curv.dir/cmd/export_mesh.cc.o: In function `openvdb::v4_0_2::tree::LeafBuffer<openvdb::v4_0_2::math::Vec3<float>, 3u>::doLoad() const':
export_mesh.cc:(.text._ZNK7openvdb6v4_0_24tree10LeafBufferINS0_4math4Vec3IfEELj3EE6doLoadEv[_ZNK7openvdb6v4_0_24tree10LeafBufferINS0_4math4Vec3IfEELj3EE6doLoadEv]+0x13a): undefined reference to `openvdb::v4_0_2::io::setStreamMetadataPtr(std::ios_base&, std::shared_ptr<openvdb::v4_0_2::io::StreamMetadata>&, bool)'
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/curv.dir/build.make:200: curv] Error 1
make[3]: Leaving directory '/tmp/curv/release'
make[2]: *** [CMakeFiles/Makefile2:68: CMakeFiles/curv.dir/all] Error 2
make[2]: Leaving directory '/tmp/curv/release'
make[1]: *** [Makefile:130: all] Error 2
make[1]: Leaving directory '/tmp/curv/release'
make: *** [Makefile:4: release] Error 2

problem with AMD Gallium/Mesa (open source) GPU driver on Linux

I tried to create a nice wire model cube like this, but it only renders @ 1 FPS
this is way slower then originator.
How to write fast curv code ?

union[
for (i in 0..1)
for (j in 0..1)
(
capsule{ d:0.3, from:[i,j,0], to:[i,j,1] } ;
capsule{ d:0.3, from:[i,0,j], to:[i,1,j] } ;
capsule{ d:0.3, from:[0,i,j], to:[1,i,j] }
)
]

Velocity Painting

"Velocity Painting" is a 3D printing technique that embosses patterns on the surface of a 3D printed object by varying the velocity of the print head, using G-Code manipulation.

https://www.velocitypainting.xyz/
https://github.com/MarkWheadon/velocity-painting

Curv lets you paint patterns on the surface of an object, which could then be used as input to the velocity painting algorithm. That's a technique I'd love to play with, and I like the fact that I could potentially design and preview the embossing pattern directly in Curv.

The big question is how to generate the G-Code. @MarkWheadon's original implementation on github works by mapping an image file onto the surface of a 3D object, and there is a limited set of options on how the projection works. This projection mechanism might not give you the fine level of control over the embossing pattern that Curv gives you.

For a given 3D model exported by Curv, the Curv geometry engine can directly map each point (x,y,z) on the surface to a RGB value, and I think that's what the Velocity Paint algorithm needs. So one way to do this is for the Velocity Paint code to call in to the Curv library.

velPaint is 300 lines of Perl, and Curv is written in C++. I don't know how a Perl program calls into a C++ library, but 300 lines isn't much, it might be easier just to rewrite velPaint in C++ and link it with libcurv.

This issue is related to #22, posted by @galex-713 (Export to G-code).

Improve Build Process for Maintainers

Hey, I just created an AUR package for curv.

There are two problems with the current build process I had to work around:

The Makefile doesn't expose the CMAKE flags

To create a binary package the installation root directory has to be set to a folder that can be bundled to form the package later. This requires setting -DCMAKE_INSTALL_PREFIX, which can only be set as a command line flag and is not exposed from your Makefile.

There is the DESTDIR env variable of make install that I can set, but cmake per default still modifies the path to point to $DESTDIR/usr/local, while Arch for example doesn't allow installing binaries to /usr/local/bin (they should go to /usr/bin) - so DESTDIR is not enough.

This also brings up the question - what is the benefit of the master Makefile? From a maintenance POV it seems preferrable to stick with the standard cmake build workflow.

The CMakeLists.txt doesn't honor CMAKE_INSTALL_PREFIX

In your CMakeLists.txt you install() your language specs to hardcoded paths. These paths should be correctly generated using CMAKE_INSTALL_PREFIX and ideally DESTDIR. In the current version this breaks my build by trying to install to a location outside of the build sandbox.

For now I fixed both issues by ignoring your master-Makefile and just unrolling the cmake setup myself, as well as including a patch that removes the lines I linked above and just omits the language specs.

prepare() {
  cd "$_pkgname"
  git submodule update --init
  patch -Np1 -i "${srcdir}/remove_lang_file.patch"

  echo '#define CURV_VERSION "'`git describe --tags --always --dirty`'"' >,v
  if cmp -s ,v libcurv/version.h; then rm ,v; else mv ,v libcurv/version.h; fi

  mkdir -p release
  cd release
  cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${pkgdir}"/usr ..
}

build() {
  cd "$_pkgname"/release
  make
}

package() {
  cd "$_pkgname"/release
  make install
}

Geometry compiler error with polymorphic function

This issue was mentioned by @doug-moen in the following thread: https://groups.google.com/forum/#!topic/curv/N99KRDfcmNU

The following code fails with a geometry compiler error:

let
rand1 x = x >> match [
    (x)   ->  frac(sin(x)*100000.0);
    (x,y) -> rand1(rand1(x) + rand1(y));
];
in
square >> colour ((x,y,z,t) -> sRGB.hue(rand1(x,y)))

and the error:

ERROR: Geometry Compiler: at field .colour: not a constant
at file "geom.curv":
2| rand1 x = x >> match [
                  ^^^^^^^
3|>    (x)   ->  frac(sin(x)*100000.0);
4|>    (x,y) -> rand1(rand1(x) + rand1(y));
5| ];
   ^ 
at file "geom.curv":
7| square >> colour ((x,y,z,t) -> sRGB.hue(rand1(x,y)))
                                           ^^^^^^^^^^  
at file "geom.curv":
7| square >> colour ((x,y,z,t) -> sRGB.hue(rand1(x,y)))

Unintuitive operator precedence

The code

let a = {x: 1}; in abs a.x

gives ERROR: abs({x:1}): domain error. The reason is that abs a.x is actually interpreted as (abs a).x. Similarly (and contrary to what I claimed in #48!), f a[0] appears to be equivalent to (f a)[0] rather than f(a[0]), although this is often hard to notice because of Curv's array nature.

I find this behavior highly unintuitive. The main reason is that the syntax itself already suggests that a and x (being joined together by a period) are bound more closely than abs and a (being separated by a space). I have been bitten by this issue in many forms; indeed, almost every time I was confused about what some Curv code did the problem came down to precedence.

Another confusing example is

move cross(a, b) cube

which one might expect to translate a cube by the cross product of a and b (since in every mainstream programming language, a function call f(a,b) forms a syntactic unit). Instead, it gives an error, because it attempts to pass the function cross as the argument to move, so move (cross(a, b)) cube is needed instead.

Such (apparently) ambiguous precedence rules are typical of research-associated languages like Haskell and OCaml. I have always found such languages to be very difficult to parse mentally. Lisp is on the opposite end of the spectrum, where everything is bracketed so there is never any question about precedence, at the expense of increased verbosity. Scala shows a nice balance between the two extremes.

Extending "reset view" with more defaults.

Love the new reset view function. Very useful.
I can immediately think of a couple of useful reset alternatives to default views.

  1. Regular stuff like top/bottom, left/right, front/back.
    Maybe repeated "reset" presses could toggle through them.
    Maybe single key for each.

  2. All combination of the above projections. like top+front.
    This makes more sense from command-line than as a toggle.
    Maybe typing up to three letter key combo for each. T, TLF, T F, T R, F, BRB.
    Nut sure how the shader can catch sequences of key presses though.

Beyond this feature request, but also relevant to the discussion of reseting views. stuff like:
-"zoom extents" if !inf , either by bounding box or field samples.

  • Setting default view from command line,
    This feature makes some sense when launching multiple views of the same file. Older cad style.
  • Possibly iso/perspective, I don't think viewer support this currently.
    /123

Build error

Attempting to build on OSX
[ 1%] Building CXX object CMakeFiles/libcurv.dir/libcurv/analyser.cc.o
In file included from /Users/Paul/curv/libcurv/analyser.cc:7:
In file included from /Users/Paul/curv/./libcurv/phrase.h:10:
/Users/Paul/curv/./libcurv/shared.h:8:10: fatal error: 'boost/intrusive_ptr.hpp' file not found
#include <boost/intrusive_ptr.hpp>
^~~~~~~~~~~~~~~~~~~~~~~~~

Syntax Colouring

I saw the idea of making a specific 3-pane GUI IDE just like libfive Studio or OpenSCAD. But a lot of people (at least me) already have their own editor/IDE that is neatly customized and can already edit (and possibly combine) several languages. libfive doesn’t require a such one since there is already scheme-mode and geiser under emacs (that does automatic autocompletion and autodoc in live using the repl).

But in emacs, as well as, I guess then, any other editor (gedit I guess), has absolutely no syntaxic coloring for curv and since the syntax is not strictly matching something already existing (or is it?) I then have all the text in only one (white) color, which can be quite boring and repulsive. Especially (I recall the time I saw people seeing their first languages in MS notepad…) for potential programming language newbies: I saw curv may be intended to try to attract more new artists than engineers, then it may (before to bring a standalone nice classic specific IDE) try to experiment with editing-capabilities so to make it more fun and attractive. And though emacs may be a bad example of newbie community, it is a good tool to experiment this kind of things and work for it may also be replicated on some more-newbie stuff such as gedit.

Sorry for maybe excessive verbosity, compared to this is.

Compilation warning (stopping compilation) about overflow, under Debian GNU/Linux stretch amd64

I don’t know what to give as precise informations, please ask what to do, here the log:

galex-713@PC713:~/src/curv$ LC_ALL=C make 
rm -rf CMakeCache.txt CMakeFiles
mkdir -p release
cd release; cmake -DCMAKE_BUILD_TYPE=Release ..
-- Configuring done
-- Generating done
-- Build files have been written to: /home/galex-713/src/curv/release
cd release; make
make[1]: Entering directory '/home/galex-713/src/curv/release'
make[2]: Entering directory '/home/galex-713/src/curv/release'
make[3]: Entering directory '/home/galex-713/src/curv/release'
make[3]: Leaving directory '/home/galex-713/src/curv/release'
[ 56%] Built target libcurv
make[3]: Entering directory '/home/galex-713/src/curv/release'
make[3]: Leaving directory '/home/galex-713/src/curv/release'
make[3]: Entering directory '/home/galex-713/src/curv/release'
[ 58%] Building CXX object CMakeFiles/curv.dir/cmd/export.cc.o
[ 60%] Building CXX object CMakeFiles/curv.dir/cmd/export_cpp.cc.o
[ 62%] Building CXX object CMakeFiles/curv.dir/cmd/export_mesh.cc.o
In member function 'void openvdb::v3_2::tree::Tree<_RootNodeType>::readBuffers(std::istream&, const openvdb::v3_2::math::CoordBBox&, bool) [with _RootNodeType = openvdb::v3_2::tree::RootNode<openvdb::v3_2::tree::InternalNode<openvdb::v3_2::tree::InternalNode<openvdb::v3_2::tree::LeafNode<bool, 3u>, 4u>, 5u> >]':
cc1plus: error: assuming signed overflow does not occur when assuming that (X + c) >= X is always true [-Werror=strict-overflow]
cc1plus: error: assuming signed overflow does not occur when assuming that (X + c) >= X is always true [-Werror=strict-overflow]
cc1plus: all warnings being treated as errors
CMakeFiles/curv.dir/build.make:182: recipe for target 'CMakeFiles/curv.dir/cmd/export_mesh.cc.o' failed
make[3]: *** [CMakeFiles/curv.dir/cmd/export_mesh.cc.o] Error 1
make[3]: Leaving directory '/home/galex-713/src/curv/release'
CMakeFiles/Makefile2:104: recipe for target 'CMakeFiles/curv.dir/all' failed
make[2]: *** [CMakeFiles/curv.dir/all] Error 2
make[2]: Leaving directory '/home/galex-713/src/curv/release'
Makefile:127: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/home/galex-713/src/curv/release'
Makefile:2: recipe for target 'release' failed
make: *** [release] Error 2
galex-713@PC713:~/src/curv$ 

Scriptable camera position

I would like to run curv with an offscreen rendering target (like -o png) so that it works with all curv programs. For instance:

curv -o png -O aa=4 curv/examples/mandelbrot.curv

yields the following error:

ERROR: can't export an infinite 2D shape to PNG
at file "deps/curv/examples/mandelbrot.curv":
 1|>make_shape {
 2|>    dist : everything.dist,
 3|>    colour (x,y,_,_) :
 4|>        do  var z := [x,y];
 5|>            var color := [0,0,0];
 6|>            var i := 0;
 7|>            while (i < 100) (
 8|>                z := csqr(z) + [x,y];
 9|>                if (dot(z,z) > 4)
10|>                    let cr = (i-1)-log(log(dot(z,z))/log 2)/log 2;
11|>                    in (
12|>                        color := [0.95+.012*cr, 1, .2+.4*(1+sin(.3*cr))];
13|>                        i := 100;
14|>                    )
15|>                else
16|>                    i := i + 1;
17|>            );
18|>        in sRGB.HSV color,
19|>    is_2d : true,
20|>}

I suppose this could be solved by introducing new options/flags to specify what should be rendered:

  • width, height for the width/height of the resulting image
  • scale for 2d renders (ie, the zoom)
  • x,y,z camera position for 3d renders (not sure if we can set fov and up) -- or whatever parameters you already use for rendering the 3d shapes.

This will allow me to fallback to server-side rendering when shaders don't compile to working WebGL:

image

Rendering in preview window does not match distance function

As mentioned in #48, I am working on a polyhedron library for Curv. The current state of that library is now available at https://github.com/p-e-w/curv-solids.

The main feature is a distance function for arbitrary polyhedra, including nonconvex ones, defined by a list of vertices and a list of faces, each of which is a list of vertex indices.

I have reason to believe that this distance function is correct at least in the case of the cube. Indeed, the following code shows that it gives the same value as the standard library cube when evaluated at a large number of random points:

let
solids = file "solids.curv";
// From the "smoke.curv" example
random xy = frac(sin(dot(xy, (12.9898,78.233)))*43758.5453123);
random_point i = map (j -> 10 * (random(i,j) - 0.5)) [X,Y,Z];
in
map (
i ->
  let
  [x,y,z] = random_point i;
  in
  solids.cube.dist(x,y,z,0) - cube.dist(x,y,z,0)
) (1..1000)

However, the preview window shows not a cube but this:

bug

Even stranger, the shape actually changes when rotating it in the preview window.

The arcs radiating outwards appear to be artefacts from sphere tracing, and the fact that they converge at the vertices might indicate a problem with precision or numerical stability. But the crucial parts of the algorithm (point-in-polygon and computation of normals) are numerically stable.

At this point I'm afraid I am out of my depth. The above appears to imply that the shaders generated by the Geometry Compiler somehow behave differently than the function as evaluated by the interpreter. I have no idea how to debug that.

See #51 for system information.

no error if temp file creation fails

@ersin-ertan said: Hey Doug, after I got curv to install, I didn't know what to do but I wanted to see something work and tried this:

curv rgbsphere.curv
make_shape{bbox:[[-1,-1,-1],[1,1,1]],colour:<function>,dist:<function>,is_2d:false,is_3d:true}
Error watching file ,curv25014.frag
Usage: glslViewer shader.frag [shader.vert] [mesh.(obj/.ply)] [texture.(png/jpg)] [-textureNameA texture.(png/jpg)] [-u] [-x x] [-y y] [-w width] [-h height] [-l/--livecoding] [--square] [-s seconds] [-o screenshot.png]

I can reproduce this by running curv in a directory with no write permissions. The temp file doesn't get created, and the error isn't detected and reported by the curv tool.

How to check if a list contains an element?

The best I could come up with without using imperative constructs is

contains (list, element) =
  count [for (e in list) if (e == element) e] > 0;

which is ugly and horribly inefficient. I guess the efficiency problem could be solved using a while loop, but the code would be even uglier.

Might it make sense to add a built-in contains operator?

Noise Library

A noise function is a math function that hashes one or more numbers onto a random number or random vector with certain properties that create a desired visual effect. The simplest noise function gives us white noise. Cellular noise is the basis for stochastic Voronoi patterns, which can be used for "biological" looking patterns and lattices. Fractal noise is useful for creating procedural textures like smoke and marble, or for creating fractal landscapes.

Many of the examples in the examples directory contain noise functions. It would be good to have a standard noise library (lib.noise), as a base for defining libraries of procedural textures and much more.

To start with, we can port http://github.com/ashima/webgl-noise from GLSL to Curv.

Other resources:
* https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83
* https://www.shadertoy.com/results?query=tag%3Dnoise

make error

Hello, got stuck at make, after apt-get install cmake libboost-dev libdouble-conversion-dev libreadline-dev any ideas?


[ 82%] Building CXX object CMakeFiles/tester.dir/tests/eval.cc.o
/home/mehmet/curv/tests/eval.cc: In function ‘testing::AssertionResult evaltest(const char*, const char*, Expectation)’:
/home/mehmet/curv/tests/eval.cc:162:1: error: control reaches end of non-void function [-Werror=return-type]
 }
 ^
cc1plus: all warnings being treated as errors
CMakeFiles/tester.dir/build.make:86: recipe for target 'CMakeFiles/tester.dir/tests/eval.cc.o' failed
make[4]: *** [CMakeFiles/tester.dir/tests/eval.cc.o] Error 1
make[4]: Leaving directory '/home/mehmet/curv/build'
CMakeFiles/Makefile2:142: recipe for target 'CMakeFiles/tester.dir/all' failed
make[3]: *** [CMakeFiles/tester.dir/all] Error 2
make[3]: Leaving directory '/home/mehmet/curv/build'
CMakeFiles/Makefile2:186: recipe for target 'CMakeFiles/tests.dir/rule' failed
make[2]: *** [CMakeFiles/tests.dir/rule] Error 2
make[2]: Leaving directory '/home/mehmet/curv/build'
Makefile:201: recipe for target 'tests' failed
make[1]: *** [tests] Error 2
make[1]: Leaving directory '/home/mehmet/curv/build'
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 2

RFC: let_parametric and let_mutable

These are the changes to Curv language syntax that I propose for release 0.4:

  • let_parametric is a variant of let that defines variables which are
    shape parameters, and which can be associated with sliders and other
    graphical value pickers. It replaces the parametric keyword in the
    prototype implementation of value pickers.
  • let_mutable is a variant of let that defines mutable variables.
    It replaces the undocumented var keyword.

The goal for both of these syntax changes is to make the syntax more
consistent and orthogonal. Local variables are now always defined using
the word "let".

let_parametric

The let_parametric feature allows you to define "parametric shapes",
with shape parameters that are bound to sliders and other graphical
value pickers in the Viewer window.

The following program declares a shape parameter that is
bound to a graphical slider widget:

  let_parametric
      size :: slider(1,5) = 3;
  in
  cube size

When you run this program, the Viewer window contains a slider that lets
you vary the size parameter from 1 to 5, with an initial value of 3.

There are 3 associated language features:

  • ::, the predicate assertion operator.
  • picker values, such as slider(1,5).
  • let_parametric.

predicate assertions

An expression of the form value :: predicate
asserts that predicate(value) returns true,
and then it returns value.

For example, x :: is_num returns x, after first checking that x
is a number, and aborting the program if x is non-numeric.
You could achieve the same thing by writing

do assert(is_num x) in x

name :: predicate is a predicate pattern that binds a value V
to name, after first checking that predicate(V) is true.
If the predicate is false, the pattern match fails.

For example,

let
    n :: is_num = f(x);
in use(n)

ensures that n is a number when it is defined.

For another example, given

cuboid =
    match [
    n :: is_num -> cube n;
    v :: is_vec3 -> box v;
    ]

then cuboid 3 is a cube of size 3, and cuboid[1,2,3] is a box
of dimensions [1,2,3].

picker values

A picker value is a predicate function that specifies the type and range of
values of a shape parameter that is associated with a graphical value picker.
It also specifies what kind of value picker widget is used by the GUI.

Here are the currently supported picker expressions:

  • checkbox -- A boolean parameter (true or false), represented by
    a checkbox widget.
  • colour_picker -- An RGB colour value. The widget allows you to edit RGB
    or HSV colour components directly, or use a colour wheel to select colours
    visually.
  • slider(low,high) -- The parameter is a number in a continuous range
    between low and high. A linear slider widget is used to set the number.
  • int_slider(low,high) -- The parameter is an integer between low and
    high. A linear slider widget is used to set the integer.
  • scale_picker -- The parameter is a scale factor: a number > 0 and < infinity.
    The widget lets you increase or decrease the value by dragging with the mouse,
    and the value changes according to a logarithmic (not linear) scale.
    This is the same logic used to modify the zoom factor in the Viewer window
    using a mouse scroll wheel or trackpad scroll gesture.

let_parametric

To add graphical parameters to a shape in a Curv program,
you prefix a shape expression with a let_parametric clause:

  let_parametric <parameter1>; <parameter2>; ... in <shape-expression>

This is an expression that returns a parametric shape value.

Each <parameter> has the form:

  <identifier> :: <picker> = <initial-value>;

A let_parametric expression differs from a let expression in several ways:

  • The right-hand expression must evaluate to a record value (usually a shape).
    This record is extended with parameter metadata used by the Viewer GUI.
  • The scoping is different. A let allows mutually recursive
    definitions, while the parameter definitions in let_parametric
    cannot reference one another.

let_mutable

This is a redesign of how mutable variables are defined and used.

The old syntax, which was an undocumented experimental feature, used the var
keyword to define mutable variables inside of a do block.

The new syntax uses let_mutable to define mutable variables.
With this change,

  • The feature is now referred to as "mutable variables".
  • Local variables are now always defined using the word "let".
  • Mutable variables now work in more contexts than with the old syntax. You can
    now use while loops within list comprehensions and record comprehensions.

The ability to define mutable variables using var will be deprecated.

Mutable variables in an expression:

sum a =
    let_mutable
        i := 0;
        total := 0;
    in do
        while (i < count a) (
            total := total + a[i];
            i := i + 1;
        );
    in total;

Mutable variables in a list comprehension.
In this case, we don't use do:

[ let_mutable i := 0; in while (i < 10) (i; i:=i+1;) ]
// => [0,1,2,3,4,5,6,7,8,9]

When multiple mutable variables are defined in a single block, the
definitions are executed in sequence, and are sequentially scoped.
The scope of each variable begins at the following definition.

minor issue

when using the live editing function, after quitting the editor the shader did not also quit.

export CURV_EDITOR=gvim
./curv -e -l lollipop.curv

Curv for VR /AR

There is a lot of effort going into medical imaging, search and rescue, architecture, product placement and lots of other applications. With the speed of model rendering in Curv, many prototype iterations could be accomplished and inspected in VR if this feature were available.

Something like a flashlight tool to inspect enclosed spaces would be very useful in this case.

Doug, Curv's creator, has a CT scan of his brain that he hopes to convert to a solid model. I can see converting a CT scan into a point cloud, and converting that to an STL (simplification).

An example application:
I had mentioned to my chiropractor the idea of getting a model of a spine in VR and looking at anomalies to better understand them.

curvc does not find std.curv

In my setup I symlinked curvcusing ln -sfr from curv's build path ~/.local/src/curv/release/curvc, howerver it seems that instead of using the canonical path as a root for the executable, boost uses the symlink's path:

{"error":{"message":"boost::filesystem::canonical: No such file or directory: \"/home/sebastien/.local/bin/../lib/std.curv\""}}

If it's not possible to correct that behaviour, would it be possible to use a CURV_PATH environment variable to indicate where the library is supposed to be found? In the meantime, I'll use a shell script that forwards arguments.

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.