MK
Marius Kintel
Thu, Feb 9, 2017 4:23 AM
Thanks Doug,
It’s helpful to see how you’re thinking.
I guess passing lambdas is the classic approach towards capturing scope like this.
I do sympathize with nophead and others taking a liking to the simplistic syntax of OpenSCAD. It does, however, come with drawbacks.
My thoughts on this is currently that it should be be more clear when you’re entering the “power user” aspects of the language. Dynamic lookup tricks like he demonstrated, as well as function literals (and functions as first-class values) is probably well into that domain.
-Marius
Thanks Doug,
It’s helpful to see how you’re thinking.
I guess passing lambdas is the classic approach towards capturing scope like this.
I do sympathize with nophead and others taking a liking to the simplistic syntax of OpenSCAD. It does, however, come with drawbacks.
My thoughts on this is currently that it should be be more clear when you’re entering the “power user” aspects of the language. Dynamic lookup tricks like he demonstrated, as well as function literals (and functions as first-class values) is probably well into that domain.
-Marius
A
adrian
Thu, Feb 9, 2017 4:42 AM
i->pillar(pillars[i])
This is a function literal. The formal parameter is 'i', the body of the
function is 'pillar(pillars[i])'.
Just as if you had defined
F(i) = pillar(pillars[i]);
and then used the value of 'F'.
doug.moen wrote
> i->pillar(pillars[i])
> This is a function literal. The formal parameter is 'i', the body of the
> function is 'pillar(pillars[i])'.
> Just as if you had defined
> F(i) = pillar(pillars[i]);
> and then used the value of 'F'.
Ah, right. It's been awhile since I've touched a functional language that
uses that syntax.
Thanks for your patience,
A
--
View this message in context: http://forum.openscad.org/Special-variable-scoping-rules-tp20305p20379.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Thu, Feb 9, 2017 8:48 AM
I think Doug's language is so different it is hard to see how it is
relevant to OpenSCAD's future. Getting back to the original issue:
If OpenSCAD were to be changed so that dynamic variables in used modules
were overridden by the module doing the using then it is likely to break
existing code where $fn is set at the top level of a used file and in the
using file.
Although inelegant, they are simple and useful and I can't see a simple way
to replace them. The child that uses them may be several nodes lower in the
tree. E.g. there may be translates and rotates between the parent and the
child that takes parameters. One solution would be to make all the parent's
variables in scope for the child but that is probably another breaking
change. Or perhaps list variables to be made dynamic in the children
statement. But why change it, perhaps better to just document it?
Another use of dynamic variables is to inject global values into used
modules in the way I showed earlier and the original subject of this
thread. Again that is inelegant to language theorists but is very useful
for being able to configure libraries. It isn't easy to do the same in
C/C++ and I have resorted to code generators in the past to configure
reusable components. I created a meta language for building code generators
and funnily enough it shared some similarities to OpenSCAD:
Although it didn't use C syntax it is a purely declarative language that
builds a tree of data and variables are named constants that can be
overridden and only the last value used for the entire code generation
stage. So this is probably why I find OpenSCAD natural and don't miss
mutable variables. in it. Descriptions don't need mutable variables. My
code generation templates do have an imperative language embedded in them
for rendering code and that does have mutable variables.
In Doug's language how would you have a library with global variables such
as layer height and BOM detail level and be able to change those in the
project using the library. I do this both globally and on a per module
basis. For example I can set $bom = 0 to turn off BOM generation for the
project but turn it on in one module to see the parts it is using.
On 9 February 2017 at 04:42, adrian adrianh.bsc@gmail.com wrote:
i->pillar(pillars[i])
This is a function literal. The formal parameter is 'i', the body of the
function is 'pillar(pillars[i])'.
Just as if you had defined
F(i) = pillar(pillars[i]);
and then used the value of 'F'.
I think Doug's language is so different it is hard to see how it is
relevant to OpenSCAD's future. Getting back to the original issue:
If OpenSCAD were to be changed so that dynamic variables in used modules
were overridden by the module doing the using then it is likely to break
existing code where $fn is set at the top level of a used file and in the
using file.
Although inelegant, they are simple and useful and I can't see a simple way
to replace them. The child that uses them may be several nodes lower in the
tree. E.g. there may be translates and rotates between the parent and the
child that takes parameters. One solution would be to make all the parent's
variables in scope for the child but that is probably another breaking
change. Or perhaps list variables to be made dynamic in the children
statement. But why change it, perhaps better to just document it?
Another use of dynamic variables is to inject global values into used
modules in the way I showed earlier and the original subject of this
thread. Again that is inelegant to language theorists but is very useful
for being able to configure libraries. It isn't easy to do the same in
C/C++ and I have resorted to code generators in the past to configure
reusable components. I created a meta language for building code generators
and funnily enough it shared some similarities to OpenSCAD:
Although it didn't use C syntax it is a purely declarative language that
builds a tree of data and variables are named constants that can be
overridden and only the last value used for the entire code generation
stage. So this is probably why I find OpenSCAD natural and don't miss
mutable variables. in it. Descriptions don't need mutable variables. My
code generation templates do have an imperative language embedded in them
for rendering code and that does have mutable variables.
In Doug's language how would you have a library with global variables such
as layer height and BOM detail level and be able to change those in the
project using the library. I do this both globally and on a per module
basis. For example I can set $bom = 0 to turn off BOM generation for the
project but turn it on in one module to see the parts it is using.
On 9 February 2017 at 04:42, adrian <adrianh.bsc@gmail.com> wrote:
> doug.moen wrote
> > i->pillar(pillars[i])
> > This is a function literal. The formal parameter is 'i', the body of the
> > function is 'pillar(pillars[i])'.
> > Just as if you had defined
> > F(i) = pillar(pillars[i]);
> > and then used the value of 'F'.
>
> Ah, right. It's been awhile since I've touched a functional language that
> uses that syntax.
>
> Thanks for your patience,
>
>
> A
>
>
>
> --
> View this message in context: http://forum.openscad.org/
> Special-variable-scoping-rules-tp20305p20379.html
> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
DM
doug moen
Thu, Feb 9, 2017 2:43 PM
Nop Head's use of special variables to implement a layout function reminds
me of the Relativity library on Thingiverse, which is a more generalized
layout library that is implemented the same way.
In both cases, this strikes me as a convoluted way to accomplish something
that would be simple with better language facilities.
First, I'd make the width of the pillar a property of the pillar 'p'
itself. Eg p.width, or size(p).x.
Then I'd pass a list of pillar shapes to the layout function, and dispense
with a separate list of widths.
Then you'd just call layout(pillars, gap).
On 8 February 2017 at 22:01, doug moen doug@moens.org wrote:
i->pillar(pillars[i])
This is a function literal. The formal parameter is 'i', the body of the
function is 'pillar(pillars[i])'.
Just as if you had defined
F(i) = pillar(pillars[i]);
and then used the value of 'F'.
The layout function has a formal parameter 'f', and when layout is called,
the function "i->pillar(pillars[i])" is bound to the parameter 'f'.
It might have been clearer if I had used a different name than 'i' for the
formal parameter, to make it clear that this is a different 'i' than the
'i' used in the for loop. I will also get rid of the "curried" function
call syntax, which is causing confusion.
layout(widths, gap, f) = union([
for (i=[0..len(widths) - 1])
translate([layout_offset(widths, i, gap), 0, 0])
f(i)
]);
layout(
[for(p = pillars) pillar_od(p)],
2,
x->pillar(pillars[x]));
In the functional programming style that I am using, it is common to pass
functions as arguments and return functions as results. It helps to have a
very terse syntax for anonymous function literals.
The technique that Nop Head is using is an advanced technique that isn't
documented in the OpenSCAD manual, and probably most people don't know the
feature exists. To do the same thing in my language, you must instead pass
functions as arguments, which is arguably also an advanced technique.
Another way to write the layout function in my language is to pass a list
of shapes as the third argument. This is less "magical" than passing a
function argument, I think.
layout(widths, gap, shapes) = union([
for (i=[0..len(widths) - 1])
translate([layout_offset(widths, i, gap), 0, 0])
shapes[i]
]);
layout(
[for (p = pillars) pillar_od(p)],
2,
[for (p = pillars) pillar(p)]);
On 8 February 2017 at 20:58, adrian adrianh.bsc@gmail.com wrote:
doug.moen wrote
i->pillar(pillars[i]) is a function literal with a single parameter 'i'.
In Javascript, you would instead write i=>pillar(pillars[i]). C++11 uses ->
in its syntax for lambda expressions, and so do many other languages.
Oh, and C++11 doesn't use -> for its lambda expressions exactly, it is an
artifact of how regular functions signatures can now be written as:
auto fn() -> ret_type
Allowing for return type inference. Lambda only uses -> because it allows
for the return type to be explicitly specified instead of inferred.
I'm understanding your code a bit more, but I'm still trying to wrap my
head around it. In
layout(widths, gap=2) f = union([
for (i=[0..len(widths) - 1])
translate([layout_offset(widths, i, gap), 0, 0])
f(i)
]);
layout([for(p = pillars) pillar_od(p)])
i->pillar(pillars[i]);
What is the i to the left of the -> in i->pillar(pillars[i]);
supposed to be? Is it getting the i from the f(i)? In which case, it
would appear that you are doing something similar to what nophead is doing.
If not, then I'm just lost.
View this message in context: Re: Special variable scoping rules
http://forum.openscad.org/Special-variable-scoping-rules-tp20305p20376.html
Sent from the OpenSCAD mailing list archive http://forum.openscad.org/
at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Nop Head's use of special variables to implement a layout function reminds
me of the Relativity library on Thingiverse, which is a more generalized
layout library that is implemented the same way.
In both cases, this strikes me as a convoluted way to accomplish something
that would be simple with better language facilities.
First, I'd make the width of the pillar a property of the pillar 'p'
itself. Eg p.width, or size(p).x.
Then I'd pass a list of pillar shapes to the layout function, and dispense
with a separate list of widths.
Then you'd just call layout(pillars, gap).
On 8 February 2017 at 22:01, doug moen <doug@moens.org> wrote:
> i->pillar(pillars[i])
> This is a function literal. The formal parameter is 'i', the body of the
> function is 'pillar(pillars[i])'.
> Just as if you had defined
> F(i) = pillar(pillars[i]);
> and then used the value of 'F'.
>
> The layout function has a formal parameter 'f', and when layout is called,
> the function "i->pillar(pillars[i])" is bound to the parameter 'f'.
>
> It might have been clearer if I had used a different name than 'i' for the
> formal parameter, to make it clear that this is a different 'i' than the
> 'i' used in the for loop. I will also get rid of the "curried" function
> call syntax, which is causing confusion.
>
> layout(widths, gap, f) = union([
> for (i=[0..len(widths) - 1])
> translate([layout_offset(widths, i, gap), 0, 0])
> f(i)
> ]);
> layout(
> [for(p = pillars) pillar_od(p)],
> 2,
> x->pillar(pillars[x]));
>
>
> In the functional programming style that I am using, it is common to pass
> functions as arguments and return functions as results. It helps to have a
> very terse syntax for anonymous function literals.
>
> The technique that Nop Head is using is an advanced technique that isn't
> documented in the OpenSCAD manual, and probably most people don't know the
> feature exists. To do the same thing in my language, you must instead pass
> functions as arguments, which is arguably also an advanced technique.
>
> Another way to write the layout function in my language is to pass a list
> of shapes as the third argument. This is less "magical" than passing a
> function argument, I think.
>
> layout(widths, gap, shapes) = union([
> for (i=[0..len(widths) - 1])
> translate([layout_offset(widths, i, gap), 0, 0])
> shapes[i]
> ]);
> layout(
> [for (p = pillars) pillar_od(p)],
> 2,
> [for (p = pillars) pillar(p)]);
>
>
>
> On 8 February 2017 at 20:58, adrian <adrianh.bsc@gmail.com> wrote:
>
>> doug.moen wrote
>> i->pillar(pillars[i]) is a function literal with a single parameter 'i'.
>> In Javascript, you would instead write i=>pillar(pillars[i]). C++11 uses ->
>> in its syntax for lambda expressions, and so do many other languages.
>>
>> Oh, and C++11 doesn't use -> for its lambda expressions exactly, it is an
>> artifact of how regular functions signatures can now be written as:
>>
>> auto fn() -> ret_type
>>
>> Allowing for return type inference. Lambda only uses -> because it allows
>> for the return type to be explicitly specified instead of inferred.
>>
>> I'm understanding your code a bit more, but I'm still trying to wrap my
>> head around it. In
>>
>> layout(widths, gap=2) f = union([
>> for (i=[0..len(widths) - 1])
>> translate([layout_offset(widths, i, gap), 0, 0])
>> f(i)
>> ]);
>> layout([for(p = pillars) pillar_od(p)])
>> i->pillar(pillars[i]);
>>
>> What is the *i* to the left of the *->* in *i->pillar(pillars[i]);*
>> supposed to be? Is it getting the *i* from the *f(i)*? In which case, it
>> would appear that you are doing something similar to what nophead is doing.
>> If not, then I'm just lost.
>>
>> ------------------------------
>> View this message in context: Re: Special variable scoping rules
>> <http://forum.openscad.org/Special-variable-scoping-rules-tp20305p20376.html>
>> Sent from the OpenSCAD mailing list archive <http://forum.openscad.org/>
>> at Nabble.com.
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss@lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>>
>
DM
doug moen
Thu, Feb 9, 2017 3:14 PM
"In Doug's language how would you have a library with global variables such
as layer height and BOM detail level and be able to change those in the
project using the library. I do this both globally and on a per module
basis."
In the OpenSCAD2 proposal, there is a detailed writeup of how to do BOM and
how to do parameterized libraries, without using dynamic variables.
BOM is done by attaching metadata to each shape in the CSG tree, and then
writing a function to walk the tree, query the metadata and generate a
report.
Libraries are objects. You can "customize" a library object, overriding
specific global variables and creating a new specialized instance of the
library.
https://github.com/doug-moen/openscad2/blob/master/rfc/Library_Scripts.md#parameterized-libraries
In my new language, I'm planning to implement this same functionality, but
I'm still working on the design.
On 9 February 2017 at 03:48, nop head nop.head@gmail.com wrote:
I think Doug's language is so different it is hard to see how it is
relevant to OpenSCAD's future. Getting back to the original issue:
If OpenSCAD were to be changed so that dynamic variables in used modules
were overridden by the module doing the using then it is likely to break
existing code where $fn is set at the top level of a used file and in the
using file.
Although inelegant, they are simple and useful and I can't see a simple
way to replace them. The child that uses them may be several nodes lower in
the tree. E.g. there may be translates and rotates between the parent and
the child that takes parameters. One solution would be to make all the
parent's variables in scope for the child but that is probably another
breaking change. Or perhaps list variables to be made dynamic in the
children statement. But why change it, perhaps better to just document it?
Another use of dynamic variables is to inject global values into used
modules in the way I showed earlier and the original subject of this
thread. Again that is inelegant to language theorists but is very useful
for being able to configure libraries. It isn't easy to do the same in
C/C++ and I have resorted to code generators in the past to configure
reusable components. I created a meta language for building code generators
and funnily enough it shared some similarities to OpenSCAD:
Although it didn't use C syntax it is a purely declarative language that
builds a tree of data and variables are named constants that can be
overridden and only the last value used for the entire code generation
stage. So this is probably why I find OpenSCAD natural and don't miss
mutable variables. in it. Descriptions don't need mutable variables. My
code generation templates do have an imperative language embedded in them
for rendering code and that does have mutable variables.
In Doug's language how would you have a library with global variables such
as layer height and BOM detail level and be able to change those in the
project using the library. I do this both globally and on a per module
basis. For example I can set $bom = 0 to turn off BOM generation for the
project but turn it on in one module to see the parts it is using.
On 9 February 2017 at 04:42, adrian adrianh.bsc@gmail.com wrote:
i->pillar(pillars[i])
This is a function literal. The formal parameter is 'i', the body of the
function is 'pillar(pillars[i])'.
Just as if you had defined
F(i) = pillar(pillars[i]);
and then used the value of 'F'.
"In Doug's language how would you have a library with global variables such
as layer height and BOM detail level and be able to change those in the
project using the library. I do this both globally and on a per module
basis."
In the OpenSCAD2 proposal, there is a detailed writeup of how to do BOM and
how to do parameterized libraries, without using dynamic variables.
BOM is done by attaching metadata to each shape in the CSG tree, and then
writing a function to walk the tree, query the metadata and generate a
report.
Libraries are objects. You can "customize" a library object, overriding
specific global variables and creating a new specialized instance of the
library.
https://github.com/doug-moen/openscad2/blob/master/rfc/Library_Scripts.md#parameterized-libraries
In my new language, I'm planning to implement this same functionality, but
I'm still working on the design.
On 9 February 2017 at 03:48, nop head <nop.head@gmail.com> wrote:
> I think Doug's language is so different it is hard to see how it is
> relevant to OpenSCAD's future. Getting back to the original issue:
>
> If OpenSCAD were to be changed so that dynamic variables in used modules
> were overridden by the module doing the using then it is likely to break
> existing code where $fn is set at the top level of a used file and in the
> using file.
>
> Although inelegant, they are simple and useful and I can't see a simple
> way to replace them. The child that uses them may be several nodes lower in
> the tree. E.g. there may be translates and rotates between the parent and
> the child that takes parameters. One solution would be to make all the
> parent's variables in scope for the child but that is probably another
> breaking change. Or perhaps list variables to be made dynamic in the
> children statement. But why change it, perhaps better to just document it?
>
> Another use of dynamic variables is to inject global values into used
> modules in the way I showed earlier and the original subject of this
> thread. Again that is inelegant to language theorists but is very useful
> for being able to configure libraries. It isn't easy to do the same in
> C/C++ and I have resorted to code generators in the past to configure
> reusable components. I created a meta language for building code generators
> and funnily enough it shared some similarities to OpenSCAD:
>
> Although it didn't use C syntax it is a purely declarative language that
> builds a tree of data and variables are named constants that can be
> overridden and only the last value used for the entire code generation
> stage. So this is probably why I find OpenSCAD natural and don't miss
> mutable variables. in it. Descriptions don't need mutable variables. My
> code generation templates do have an imperative language embedded in them
> for rendering code and that does have mutable variables.
>
> In Doug's language how would you have a library with global variables such
> as layer height and BOM detail level and be able to change those in the
> project using the library. I do this both globally and on a per module
> basis. For example I can set $bom = 0 to turn off BOM generation for the
> project but turn it on in one module to see the parts it is using.
>
>
> On 9 February 2017 at 04:42, adrian <adrianh.bsc@gmail.com> wrote:
>
>> doug.moen wrote
>> > i->pillar(pillars[i])
>> > This is a function literal. The formal parameter is 'i', the body of the
>> > function is 'pillar(pillars[i])'.
>> > Just as if you had defined
>> > F(i) = pillar(pillars[i]);
>> > and then used the value of 'F'.
>>
>> Ah, right. It's been awhile since I've touched a functional language that
>> uses that syntax.
>>
>> Thanks for your patience,
>>
>>
>> A
>>
>>
>>
>> --
>> View this message in context: http://forum.openscad.org/Spec
>> ial-variable-scoping-rules-tp20305p20379.html
>> Sent from the OpenSCAD mailing list archive at Nabble.com.
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss@lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
RZ
Reinoud Zandijk
Mon, Feb 13, 2017 12:03 PM
On Thu, Feb 09, 2017 at 10:14:37AM -0500, doug moen wrote:
In the OpenSCAD2 proposal, there is a detailed writeup of how to do BOM and
how to do parameterized libraries, without using dynamic variables.
I must have missed that post! Where can I find this proposal?
With regards,
Reinoud
On Thu, Feb 09, 2017 at 10:14:37AM -0500, doug moen wrote:
> In the OpenSCAD2 proposal, there is a detailed writeup of how to do BOM and
> how to do parameterized libraries, without using dynamic variables.
I must have missed that post! Where can I find this proposal?
With regards,
Reinoud
RZ
Reinoud Zandijk
Mon, Feb 13, 2017 12:18 PM
On Thu, Feb 09, 2017 at 09:43:38AM -0500, doug moen wrote:
Nop Head's use of special variables to implement a layout function reminds
me of the Relativity library on Thingiverse, which is a more generalized
layout library that is implemented the same way.
In both cases, this strikes me as a convoluted way to accomplish something
that would be simple with better language facilities.
First, I'd make the width of the pillar a property of the pillar 'p'
itself. Eg p.width, or size(p).x.
Then I'd pass a list of pillar shapes to the layout function, and dispense
with a separate list of widths.
Then you'd just call layout(pillars, gap).
Isn't a similar thing used in `MCAD/stepper.scad'? It there passes an
variable/value list constant for construction. It uses "motor(Nema14)" where
Nema14 is a list of (variable,value) pairs. Now if records would be supported
and mutable variables...
What about using say a construct like global var=5;' that gives var' the
status to be a global override of all descenders unless they are redefined
within a scope.
Can't we go the ImplicitCAD route where the object is specified using a much
simplified Haskell derivative language? Say with only simple list generators,
function declaration etc? Julia Longtin wouldn't be unhelpfull to assist in
the languge setup I think.
With regards,
Reinoud
On Thu, Feb 09, 2017 at 09:43:38AM -0500, doug moen wrote:
> Nop Head's use of special variables to implement a layout function reminds
> me of the Relativity library on Thingiverse, which is a more generalized
> layout library that is implemented the same way.
>
> In both cases, this strikes me as a convoluted way to accomplish something
> that would be simple with better language facilities.
>
> First, I'd make the width of the pillar a property of the pillar 'p'
> itself. Eg p.width, or size(p).x.
> Then I'd pass a list of pillar shapes to the layout function, and dispense
> with a separate list of widths.
> Then you'd just call layout(pillars, gap).
Isn't a similar thing used in `MCAD/stepper.scad'? It there passes an
variable/value list constant for construction. It uses "motor(Nema14)" where
Nema14 is a list of (variable,value) pairs. Now if records would be supported
and mutable variables...
What about using say a construct like `global var=5;' that gives `var' the
status to be a global override of all descenders unless they are redefined
within a scope.
Can't we go the ImplicitCAD route where the object is specified using a much
simplified Haskell derivative language? Say with only simple list generators,
function declaration etc? Julia Longtin wouldn't be unhelpfull to assist in
the languge setup I think.
With regards,
Reinoud
DM
doug moen
Mon, Feb 13, 2017 5:46 PM
The OpenSCAD2 proposal is here. Note that it hasn't been updated since
Summer 2015, and there's been discussion on the list since then.
https://github.com/doug-moen/openscad2
As for ImplicitCAD.
- Well, it already exists as an alternative to OpenSCAD, for those who want
to use it.
- It is unable to import STL files. Antimony has the same limitation. I
haven't found an open source F-Rep geometry system that imports STL files
yet, although I haven't looked really hard. It looks like a tricky problem
to solve.
I am implementing an F-Rep geometry system using a simple language inspired
by OpenSCAD and ImplicitCAD. What makes my system distinctive is that the
geometric primitives (cube, union, rotate, etc) are implemented in the
scripting language itself, rather than in an underlying implementation
language like C++ or Haskell. The code for these primitives will initially
resemble the ImplicitCAD Haskell implementation (data structures and
algorithms, not syntax). Also, I'm compiling the F-Rep CSG tree into GPU
code, for direct execution on a GPU.
- It is still in the initial development stage. I can preview shapes in an
OpenGL window now, but the language and geometry kernel are still
incomplete.
Based on this experience, I can say that F-Rep is incredibly powerful, and
much better than OpenSCAD for the particular kinds of shapes I want to
make. Curved organic shapes are easy, and I can render extremely complex
fractals (eg with millions of polygons) very quickly, as long as those
shapes are procedurally generated within the language. But, it doesn't seem
to be good at importing large polyhedral meshes.
In order to get F-Rep into OpenSCAD, you need a hybrid geometry system
where some shapes are meshes, and some shapes are F-Rep. F-Rep shapes are
converted into polyhedra as the first stage of rendering. OpenSCAD would
remain a mesh-oriented system, and there is an F-Rep subsystem which
provides a different way of generating meshes. This design might not give
access to the full power of F-Rep, but would add expressive power without
compromising any of OpenSCAD's mesh semantics.
On 13 February 2017 at 07:18, Reinoud Zandijk reinoud@13thmonkey.org
wrote:
On Thu, Feb 09, 2017 at 09:43:38AM -0500, doug moen wrote:
Nop Head's use of special variables to implement a layout function
me of the Relativity library on Thingiverse, which is a more generalized
layout library that is implemented the same way.
In both cases, this strikes me as a convoluted way to accomplish
that would be simple with better language facilities.
First, I'd make the width of the pillar a property of the pillar 'p'
itself. Eg p.width, or size(p).x.
Then I'd pass a list of pillar shapes to the layout function, and
with a separate list of widths.
Then you'd just call layout(pillars, gap).
Isn't a similar thing used in `MCAD/stepper.scad'? It there passes an
variable/value list constant for construction. It uses "motor(Nema14)"
where
Nema14 is a list of (variable,value) pairs. Now if records would be
supported
and mutable variables...
What about using say a construct like global var=5;' that gives var' the
status to be a global override of all descenders unless they are redefined
within a scope.
Can't we go the ImplicitCAD route where the object is specified using a
much
simplified Haskell derivative language? Say with only simple list
generators,
function declaration etc? Julia Longtin wouldn't be unhelpfull to assist in
the languge setup I think.
With regards,
Reinoud
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
The OpenSCAD2 proposal is here. Note that it hasn't been updated since
Summer 2015, and there's been discussion on the list since then.
https://github.com/doug-moen/openscad2
As for ImplicitCAD.
* Well, it already exists as an alternative to OpenSCAD, for those who want
to use it.
* It is unable to import STL files. Antimony has the same limitation. I
haven't found an open source F-Rep geometry system that imports STL files
yet, although I haven't looked really hard. It looks like a tricky problem
to solve.
I am implementing an F-Rep geometry system using a simple language inspired
by OpenSCAD and ImplicitCAD. What makes my system distinctive is that the
geometric primitives (cube, union, rotate, etc) are implemented in the
scripting language itself, rather than in an underlying implementation
language like C++ or Haskell. The code for these primitives will initially
resemble the ImplicitCAD Haskell implementation (data structures and
algorithms, not syntax). Also, I'm compiling the F-Rep CSG tree into GPU
code, for direct execution on a GPU.
* It is still in the initial development stage. I can preview shapes in an
OpenGL window now, but the language and geometry kernel are still
incomplete.
Based on this experience, I can say that F-Rep is incredibly powerful, and
much better than OpenSCAD for the particular kinds of shapes I want to
make. Curved organic shapes are easy, and I can render extremely complex
fractals (eg with millions of polygons) very quickly, as long as those
shapes are procedurally generated within the language. But, it doesn't seem
to be good at importing large polyhedral meshes.
In order to get F-Rep into OpenSCAD, you need a hybrid geometry system
where some shapes are meshes, and some shapes are F-Rep. F-Rep shapes are
converted into polyhedra as the first stage of rendering. OpenSCAD would
remain a mesh-oriented system, and there is an F-Rep subsystem which
provides a different way of generating meshes. This design might not give
access to the full power of F-Rep, but would add expressive power without
compromising any of OpenSCAD's mesh semantics.
On 13 February 2017 at 07:18, Reinoud Zandijk <reinoud@13thmonkey.org>
wrote:
> On Thu, Feb 09, 2017 at 09:43:38AM -0500, doug moen wrote:
> > Nop Head's use of special variables to implement a layout function
> reminds
> > me of the Relativity library on Thingiverse, which is a more generalized
> > layout library that is implemented the same way.
> >
> > In both cases, this strikes me as a convoluted way to accomplish
> something
> > that would be simple with better language facilities.
> >
> > First, I'd make the width of the pillar a property of the pillar 'p'
> > itself. Eg p.width, or size(p).x.
> > Then I'd pass a list of pillar shapes to the layout function, and
> dispense
> > with a separate list of widths.
> > Then you'd just call layout(pillars, gap).
>
> Isn't a similar thing used in `MCAD/stepper.scad'? It there passes an
> variable/value list constant for construction. It uses "motor(Nema14)"
> where
> Nema14 is a list of (variable,value) pairs. Now if records would be
> supported
> and mutable variables...
>
> What about using say a construct like `global var=5;' that gives `var' the
> status to be a global override of all descenders unless they are redefined
> within a scope.
>
> Can't we go the ImplicitCAD route where the object is specified using a
> much
> simplified Haskell derivative language? Say with only simple list
> generators,
> function declaration etc? Julia Longtin wouldn't be unhelpfull to assist in
> the languge setup I think.
>
> With regards,
> Reinoud
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
>