profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/doug-moen/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.

curv3d/curv 871

a language for making art using mathematics

doug-moen/openscad2 21

better abstraction mechanisms for OpenSCAD

doug-moen/art 2

3D printed sculptures, made using Curv

doug-moen/bash-rename 0

A file rename script for bash, supporint wildcards.

doug-moen/clemency 0

An OpenCL marching cubes implementation.

doug-moen/cubicreator 0

Cubicreator fork of CuraEngine (May 23 2018 snapshot)

doug-moen/Dual-Contouring 0

Dual Contoruing implemented in C++

doug-moen/glslViewer 0

Live GLSL coding render for MacOS and Linux

issue commentlibfive/libfive

Rust binding?

I think you could do something like your first implementation (Tree1), but without the phantom data marker and 'static lifetime: just hold a libfive_tree (which is an opaque pointer), and call libfive_tree_delete in the impl Drop.

Internally, the libfive_tree object is already a reference-counted DAG; it frees itself (and any children that become orphans) when the last copy is deleted with libfive_tree_delete. Since it's reference-counted inside the libfive API, you can't make it Copy, but it could be Clone by adding something like this to libfive.cpp:

void libfive_tree_clone(libfive_tree ptr)
{
    // Build a new tree (increasing the refcount), then release it (without
    // decrementing the refcount) to create a spare raw pointer.  This must
    // be deleted with `libfive_tree_delete` to avoid memory leaks.
    Tree(ptr).release()
}

I'd vote against re-implementing the DAG + stdlib in Rust: the DAG already exists behind the scenes, and the whole point of the C++ stdlib + C API is to avoid rewriting it in every language 😛 .

virtualritz

comment created time in an hour

issue commentlibfive/libfive

Rust binding?

So I now have two implementations for Tree in Rust.

Using references with (mandatory) lifetimes:

pub struct Tree1<'a> {
    tree: sys::libfive_tree,
    _marker: PhantomData<*mut &'a ()>,
}

impl Tree<'static> {
    pub fn x() -> Self {
        Self {
            tree: unsafe { sys::libfive_tree_x() },
            _marker: PhantomData,
        }
    }

    ...
}

impl<'a> Tree<'a> {
    pub fn union_self<'b>(&'b self, b: &'b Tree) -> Tree<'b> {
        Tree {
            tree: unsafe { sys::libfivestd_union(self.tree, b.tree) },
            _marker: PhantomData,
        }
    }
    
    ...
}

impl<'a> Drop for Tree1<'a> {
    fn drop(&mut self) {
        unsafe { sys::libfive_tree_delete(self.tree) };
    }
}

This variant is straightforward. Everything takes references; including any operators. This is reasonably easy to implement. Leaf nodes have 'static lifetimes. Everything else is tracked with individual lifetimes.

This all works. But everything being references, issues arise once you want to move Tree1s around because of Rust's move semantics. I.e. great for quick results and demo apps but probably not so much for a real CAD app.

The 2nd variant uses Rc and basically creates a copy of the tree to track ownership for getting deallocations right. Also this allows to easily keep copies of (sub)Tree2s and move them around in an app:

pub struct Tree2 {
    tree: Rc<sys::libfive_tree>,
    child_a: Option<Rc<Tree2>>,
    child_b: Option<Rc<Tree2>>,
}

impl Tree2 {
    pub fn x() -> Self {
        Self {
            tree: Rc::new(unsafe { sys::libfive_tree_x() }),
            child_a: None,
            child_b: None,
        }
    }
    
    pub fn union(self, b: Tree2) -> Self {
        Self {
            tree: Rc::new(unsafe { sys::libfivestd_union(*self.tree, *b.tree) }),
            child_a: Some(Rc::new(self)),
            child_b: Some(Rc::new(b)),
        }
    }
    
    ...
}

impl Clone for Tree2 {
    fn clone(&self) -> Self {
        Self {
            tree: Rc::new(*self.tree.as_ref()),
            child_a: self.child_a.as_ref().map(|t| t.clone()),
            child_b: self.child_b.as_ref().map(|t| t.clone()),
        }
    }
}

impl Drop for Tree2 {
    fn drop(&mut self) {
        if 1 == Rc::strong_count(&self.tree) {
            unsafe { sys::libfive_tree_delete(*self.tree) };
        }
    }
}

The second variant is modeled so that a tree has full ownership of all children. Subtrees can be cloned and deallocation happens as expected because of the use of Rc.

The issue here is the standard lib. Many operators take more than two operands. So if I want to wrap that I have two options:

  1. Swap out child_a & child_b for a children: Vec<Tree2> and use the stdlib.h header.
  2. Just RRIR, stdlib_impl.cpp that is.

I'm currently leaning towards 2. as that is probably also just 1h of search & replace, mostly.

Any thoughts/suggestions/ideas?

virtualritz

comment created time in 4 hours

pull request commentcurv3d/curv

Add 2D polyline

Another idea I have is to pass a transform function into repeat. e.g. in the bracelet example, repeat + rotate should be faster than the large union.

zeeyang

comment created time in a day

pull request commentcurv3d/curv

Add 2D polyline

Thank you!!! Will check

On Fri, May 7, 2021 at 9:18 AM Doug Moen ***@***.***> wrote:

Merged #127 https://github.com/curv3d/curv/pull/127 into master.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/curv3d/curv/pull/127#event-4701827191, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFMFLVVF6HHQB7WJS37S4WLTMPRY3ANCNFSM44IUFFEA .

zeeyang

comment created time in a day

PR opened curv3d/curv

Add 2D polyline

Justification

I was trying to model a bridge truss and it was slow unioning a number of strokes. Polyline was derived from IQ's polygon function, sans the signed internal function and added stroke size (d).

How to test

polyline {d:0.1, v:[[0,0],[1,0],[1,1],[0,0]]}  // right triangle

Screen Shot 2021-05-06 at 8 23 21 PM

polyline {d:0.1, v:[[0,0],[1,0],[1,1],[0,0]]} >> extrude 0.2

Screen Shot 2021-05-06 at 8 23 47 PM

+31 -2

0 comment

3 changed files

pr created time in 2 days

push eventlibfive/libfive

Matt Keeter

commit sha 9aa20520497636659b8d5bda25057631837e998a

Switch to C99-compatible syntax for deprecation (fixes #430)

view details

push time in 3 days

issue closedlibfive/libfive

Deprecation block makes C compiler fall over

This is from line 236 in libfive.h:

[[deprecated("use libfive_tree_nullary instead")]]
libfive_tree libfive_tree_nonary(int op);

Which makes clang fall over with:

  /Users/moritz/code/libfive/build/libfive/include/libfive.h:236:2: error: expected expression
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:1: error: redefinition of 'libfive_tree' as different kind of symbol
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:188:31: note: previous definition is here
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:13: error: expected ';' after top level declarator
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:236:2: error: expected expression, err: true
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int], err: false
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:1: error: redefinition of 'libfive_tree' as different kind of symbol, err: true
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:13: error: expected ';' after top level declarator, err: true

I think this [[...]] stuff is C++14 and later but a C compiler can't understand it?

closed time in 3 days

virtualritz

issue commentlibfive/libfive

Prefix stdlib.h functions?

What I have done in my fork is to prefix every function in stdlib.h with libfivestd_. I also changed the gen_c.py to do the right thing already. I.e. generated files hav no diff with previous ones except signatures in C API.

Would you accept a PR for this if I changed the the other binding generator scripts accordingly and everything builds/runs/tests fine?

virtualritz

comment created time in 3 days

issue commentlibfive/libfive

Why does _union() start with an underscore in stdlib.h?

Yeah, I get it. I wrote a gen_rust.py and there I have the issue with move (Rust keyword). I swap that out for moveit.

virtualritz

comment created time in 3 days

PR opened curv3d/curv

Add github action for macos build

Justification

Run make test and make release build in macos environment for PR and master builds. See https://github.com/curv3d/curv/pull/125#issuecomment-832831058

How to test

  • go to github Actions tab
  • verify workflow logs
+26 -6

0 comment

1 changed file

pr created time in 3 days

issue openedAmokHuginnsson/replxx

Memory handling for replxx_add_completion() / replxx_add_color_completion() undocumented

When passing completions to replxx via https://github.com/AmokHuginnsson/replxx/blob/master/include/replxx.h#L311, the docs / header file is silent on memory handling.

Specifically, there is no mention of the required lifetime of the string passed into the completion.

From experimentation, it appears that replxx expects all completions to live at least as long as the replxx_input() call, which could technically be forever if enter is never sent.

Ideally replxx should make its own copy of the string, and then free/delete the string when required. This frees the application to make memory cleanups directly after the replxx_add_completion() call.

Unfortunately the example code is contrived, as the example code uses a fixed array of completions, which isn't realistic in real world code.

At the very least, the memory lifetime requirements need to be documented into each API call.

created time in 3 days

issue commentlibfive/libfive

Why does _union() start with an underscore in stdlib.h?

Not quite – this is because the C and C++ union need to be distinguished by the bindings generator, and functions which take zero arguments but return different types aren't allowed.

virtualritz

comment created time in 3 days

issue openedlibfive/libfive

Why does _union() start with an underscore in stdlib.h?

See subject.

created time in 3 days

pull request commentcurv3d/curv

Continue march backward when inside shape

Oops sorry about the tests.

zeeyang

comment created time in 3 days

issue commentlibfive/libfive

Rust binding?

So I abandoned my tries to get the C++ header through bindgen for the time being.

I have a rough version of the Rust API in place – https://github.com/virtualritz/libfive-rs.

This contains libfive itself as a subrepo under libfive-sys. This is built from source. Currently this tracks my fork as I have added a libfivestd_ prefix to the stdlib.h functions (see #432).

Feedback welcome. Probably best to build the docs to get an idea.

cargo doc -p libfive --no-deps --open

Not sure how to ever get this published on docs.rs since that is sandboxed so all dependencies must be part of the package.

With boost being one that is pretty much impossible due to crates.io size constraints, I guess.

virtualritz

comment created time in 3 days

issue commentlibfive/libfive

Deprecation block makes C compiler fall over

Yes, that fixes it for me.

virtualritz

comment created time in 4 days

issue commentlibfive/libfive

[stdlib.h] Missing typedef makes C compiler fall over

Thanks, fixed!

virtualritz

comment created time in 4 days

push eventlibfive/libfive

Matt Keeter

commit sha 26e0d0abf8dac30fb2be7ab006be13886f58fcdd

Add typedefs (fixes #431)

view details

push time in 4 days

issue closedlibfive/libfive

[stdlib.h] Missing typedef makes C compiler fall over

I get several dozens of those:

libfive/libfive-sys/libfive/libfive/stdlib/stdlib.h:80:37: error: must use 'struct' tag to refer to type 'tvec3'

Adding two typedefs to stdlib.h fixes this:

typedef struct tvec2 tvec2;
struct tvec2 {
    libfive_tree x, y;
};
typedef struct tvec3 tvec3;
struct tvec3 {
    libfive_tree x, y, z;
};

closed time in 4 days

virtualritz

issue commentlibfive/libfive

Deprecation block makes C compiler fall over

Does this work with

__attribute__((deprecated("deprecated", "libfive_tree_nullary")))
libfive_tree libfive_tree_nonary(int op);

?

virtualritz

comment created time in 4 days

issue openedlibfive/libfive

Prefix stdlib.h functions?

When using something like bindgen it is preferable to use whitelisting (allowlisting).

Unfortunately the stdlib functions do not have a prefix so if one wants to generate bindings for those, only blacklisting (blocklisting) is possible which is tedious and never really prevents everything unrelated to be filtered out from the bindings, unless one starts blacklisting individual items.

Would is be possible to also prefix the stdlib.h functions with libfive_?

created time in 4 days

issue openedlibfive/libfive

[stdlib.h] Missing typedef makes C compiler fall over

I get several dozens of those:

libfive/libfive-sys/libfive/libfive/stdlib/stdlib.h:80:37: error: must use 'struct' tag to refer to type 'tvec3'

Adding two typedefs to stdlib.h fixes this:

typedef struct tvec2 tvec2;
struct tvec2 {
    libfive_tree x, y;
};
typedef struct tvec3 tvec3;
struct tvec3 {
    libfive_tree x, y, z;
};

created time in 4 days

pull request commentcurv3d/curv

Continue march backward when inside shape

👍

zeeyang

comment created time in 4 days

issue openedlibfive/libfive

Deprecation block makes C compiler fall over

This is from line 236 in libfive.h

[[deprecated("use libfive_tree_nullary instead")]]
libfive_tree libfive_tree_nonary(int op);

Which makes clang fall over with:

  /Users/moritz/code/libfive/build/libfive/include/libfive.h:236:2: error: expected expression
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:1: error: redefinition of 'libfive_tree' as different kind of symbol
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:188:31: note: previous definition is here
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:13: error: expected ';' after top level declarator
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:236:2: error: expected expression, err: true
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int], err: false
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:1: error: redefinition of 'libfive_tree' as different kind of symbol, err: true
  /Users/moritz/code/libfive/build/libfive/include/libfive.h:237:13: error: expected ';' after top level declarator, err: true

I think this [[...]] stuff is C++14 and later but a C compiler can't understand it?

created time in 5 days

pull request commentcurv3d/curv

Continue march backward when inside shape

Improvement with sinc.

let
    sinc x = if (x == 0) 1 else sin x / x;
in
make_shape {
  dist[x,y,z,t] = abs(z - sinc(mag[x,y])*10) - 1;
  is_3d = true;
}
>> lipschitz 3
>> into intersection [box[40,40,40]]

Before: Screen Shot 2021-05-03 at 10 00 26 PM

After: Screen Shot 2021-05-03 at 10 01 00 PM

zeeyang

comment created time in 5 days

pull request commentcurv3d/curv

Continue march backward when inside shape

Oh no it doesn't look good with kaboom.

Before: Screen Shot 2021-05-03 at 9 45 33 PM

After: Screen Shot 2021-05-03 at 9 47 26 PM

zeeyang

comment created time in 5 days

PR closed curv3d/curv

Add repeat_helix to curv std

Justification

repeat_helix was listed in the repetition future work section. It's useful for making staircases, chained links, etc. Also remapped repeat_radial as repeat_helix with step size of 0.

How to test

parametric
    w :: slider[0, 20] = 15;
    dy :: slider[-20, 20] = 6;
    step :: slider[0, 40] = 5;
in
box [5,w,1]
    >> move [0,dy,0]
    >> repeat_helix{reps:12, step:step} 
    >> lipschitz 10

Screen Shot 2021-05-01 at 9 02 44 AM

+46 -3

4 comments

4 changed files

zeeyang

pr closed time in 5 days

pull request commentcurv3d/curv

Add repeat_helix to curv std

Cleaned up and closing this for now until I can find a better sdf for helix repeat.

zeeyang

comment created time in 5 days

PR opened curv3d/curv

Continue march backward when inside shape

Justification

See previous comment on rendering artifacts in helix distance function: https://github.com/curv3d/curv/pull/124#issuecomment-830681165.

Here is a video I found by Martijn Steinrucken which explains the 2 scenarios where sphere tracer goes 1) inside shape 2) behind shape. https://www.youtube.com/watch?v=Vmb7VGBVZJA&t=505s

This PR fixes scenario 1 where tracer is inside shape. The fix is to keep the tracer loop going so it can take negative steps back and get closer to the isosurface.

Fix for scenario 2 is to reduce trace increments (>> lipschitz x).

How to test

Here is a quick test on the helix repeat branch, but you can try any shape with render artifacts.

parametric
    w :: slider[0, 20] = 10;
    dy :: slider[-20, 20] = 10;
    step :: slider[0, 20] = 5;
in
box [3,w,3]
    >> move [0,dy,0]
    >> repeat_helix{reps:10, step:step} 
    >> lipschitz 1

Before: Screen Shot 2021-05-03 at 8 49 59 PM After: Screen Shot 2021-05-03 at 8 51 01 PM

+1 -1

0 comment

1 changed file

pr created time in 5 days

pull request commentcurv3d/curv

Add repeat_helix to curv std

Thanks @doug-moen. The shadertoy link's math does look much simpler. Let me dig into that tonight and restore repeat_radial.

I did notice the shape was getting very choppy further away from origin. lipschitz 10 fixed it but I didn't really understand it. Are the gaps caused by undefined areas in the distance function? I tried show_gradient but it didn't yield anything useful.

Screen Shot 2021-05-01 at 3 20 40 PM

zeeyang

comment created time in 7 days