
12

I see three possible behaviors in the evaluation of an expression by OpenSCAD: it does what is expected, it does something surprising but reasonable and it does something unreasonable. The last one is clearly a bug. The first one is the normal case. My interest now is on the second case: a reasonable surprising behavior. It is surprising when it comprises less common conditions that are not documented. Being undocumented make them not eligible to be a feature and that is the issue.
A first example is the product of a list by a float. It is mentioned in the manual just for vectors. But it works as expected with any list of floats, like matrices, ndimensional matrices or even trees of floats. The same happens with the addition (subtraction) of lists. I cannot expect to add two lists with different structures (like a vector and a bidimensional matrix) but OpenSCAD is able to add lists of floats with the same structure: [ 1, [2, 3] ] + [ 5, [5, 5] ] = [ 6, [7, 8] ] . It works even with void lists.
As those more general cases are missing in the documentation, I can not rely on it as a feature. However, a lot of code I have been written (my Bezier/Spline library, for instance) benefits from that generality. If needed I can provide simple examples.
So, my question is: could we rely on the current behavior of those operators as a feature? Is there a commitment with this feature for the future versions? This should be clarified and the documentation be expanded accordingly. I hope the answer be yes :)
I have a couple of other issues like that. I will post about them later.


Here's the behaviour of the + operator, as I understand it.
n is a number, a, b are arbitrary values.
n0 + n1 == the sum of two numbers
[a0, a1, ... ai] + [b0, b1, ... bi] == [a0+b0, a1+b1, ... ai+bi] (both lists have the same length i)
This is a recursive definition, from which it follows that [] + [] == [] [1,[2]] + [1,[1]] == [2,[3]]
etc.
Is this expected behaviour? From my perspective, yes. 1. OpenSCAD is a language for computational geometry, which puts it into the same family as "math and science" languages like Mathematica, Matlab, Julia, and many more. 2. All of the "math and science" languages I know support elementwise addition of vectors, matrices, etc, so it is familiar and expected behaviour.
Most mathandscience languages represent matrices using a builtin multidimensional array type, which constrains these arrays to have a "rectangular" shape. If nested arrays are supported at all, then they are less convenient/more complex to use than normal arrays.
However, there are a few mathandscience languages that don't have multidimensional arrays as a primitive concept: instead, they have 1dimensional lists, and represent 2D matrices as lists of lists of numbers. Examples include Mathematica/Wolfram, K and OpenSCAD. These languages happen to all be dynamically typed, and elementwise addition works as it does in OpenSCAD. Elementwise addition of lists works even if the structure is irregular.
The one thing I find surprising is that OpenSCAD doesn't support "broadcasting", unlike all of the other mathandscience languages I know. That is, I expect that 1 + [2,3,4] == [3,4,5]
but that's not supported in OpenSCAD.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


On 10/01/2016 09:52 PM, doug moen wrote:
> The one thing I find surprising is that OpenSCAD doesn't support
> "broadcasting", unlike all of the other mathandscience languages
> I know.
> That is, I expect that
> 1 + [2,3,4] == [3,4,5]
> but that's not supported in OpenSCAD.
>
Maybe we can collect a list of all those cases and just implement
them. The risk breaking existing scripts is probably not very big,
I hope nobody relies on the fact 1 + [2,3,4] returns undef.
Or is there a formal description of all cases for one of the
existing languages, so we can see if we can (start to) match
features?
ciao,
Torsten.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 Torsten


Thank you, doug, for your answer.
Yes, that is also what I expect from the scalar product and sum of lists. I could not say, however, that this was my understanding unless I had read the OpenSCAD code (what I am not able to do :( ). Without a language specification, the only source to solve this kind of doubts are the manual and you, the team is working hard for a fantastic open software. And the manual is sometimes incomplete or misleading. I have started a small contribution to the manual but in respect to some issues I need your confirmation.
I don't like the way the manual presents those operator. I don't like the name vectors for lists. It is misleading for the beginner that may think of a list of two or three numbers, the coordinates of a 2D or 3D vector. If you understand [x, [y, z, [w]] ], where x, y, z, w are numbers, as an element of a vector space, well, I agree that the addition of lists is an addition of vectors defined for vectors in the same vector space and undef otherwise. But how many OpenSCAD users have this understanding?
When, by means of lots of tests, I realized that and saw how beautiful is the language and how misleading is this topic in the manual. And I use it in my codes.
So, if this behavior is part of the language specification, nice!, I would try to express it in a manual review. And I can trust in it and keep using it.
I have never seen the "broadcasting" addition before. Combining this operator with the recursive nature of the addition of lists, may I expect that [1, 1] + [[2, 3], [4, 5]] == [[3, 4], [5, 6]] ?
Ronaldo


There is no language specification. The language manual is actually a wiki that is edited by end users. Some parts of that documentation is based on experiments to reverse engineer the specification (that's what I do a lot of the time), other parts of the documentation are written by developers when new features are added. Parts of the documentation are great, other parts are bad and misleading. You can edit it yourself to clarify the meaning of the + operator.
Ronaldo wrote: I have never seen the "broadcasting" addition before. Combining this operator with the recursive nature of the addition of lists, may I expect that [1, 1] + [[2, 3], [4, 5]] == [[3, 4], [5, 6]] ?
Yes, that's correct.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


I asked this before but got no answer. By mistake, I found that I could use a 3x3 matrix instead of a 4x4 in the multmatrix() operator to get a linear transformation. It seems that, in general, extra lines and columns of the input matrix (if more then 4 is present) are discarded and missing elements from the 4x4 standard are fulfilled by the respective elements of the identity matrix. You can confirm this displaying the CSG tree. The important case for me is the possibility to input a 3x3 matrix when I don't need a translation. Don't you think this simplifies the code and should be documented in the on line manual?


In my experience the "de facto" language spec is in the several hundred
regression tests.
Just as a simple example, here is the test for "min, max" functions
https://github.com/openscad/openscad/blob/master/testdata/scad/functions/minmaxtests.scadHere are the expected results
https://github.com/openscad/openscad/blob/master/tests/regression/echotest/minmaxtestsexpected.echoIf a build doesnt produce those results, the test will fail.
I have a feeling that most of the people working on the project do not
want to make changes that break the regression tests.
If you dig around the tests/scad you can find tests for vector / list
operations. I am not sure if the complicated ones you are using are in
there, but they might be.
There is a Travis CI automatic test that gets run every time someone
commits code to the master branch. It actually runs the regression tests
as part of it's "build". You can see results here
https://travisci.org/openscad/openscadpast results here
https://travisci.org/openscad/openscad/builds
don bright
[hidden email]
On Sat, Oct 1, 2016, at 05:50 PM, Ronaldo wrote:
> I asked this before but got no answer. By mistake, I found that I could
> use a
> 3x3 matrix instead of a 4x4 in the multmatrix() operator to get a linear
> transformation. It seems that, in general, extra lines and columns of the
> input matrix (if more then 4 is present) are discarded and missing
> elements
> from the 4x4 standard are fulfilled by the respective elements of the
> identity matrix. You can confirm this displaying the CSG tree. The
> important
> case for me is the possibility to input a 3x3 matrix when I don't need a
> translation. Don't you think this simplifies the code and should be
> documented in the on line manual?
>
>
>
> 
> View this message in context:
> http://forum.openscad.org/Clarifyingbehaviorstp18492p18505.html> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Valuable information, don bright. Thank you.
donbright wrote
If you dig around the tests/scad you can find tests for vector / list
operations. I am not sure if the complicated ones you are using are in
there, but they might be.
In a first quick look, I found just simple tests with homogeneous uni and bidimensional lists. But I found many interesting and surprising others. As a lazy man, when I want to check something I generate random data, animate the code and sit back staring at the console...
My use of those properties is neither exoctic nor complicated. I will give you a simple example. Suppose you define a function performing the calculations of a polynomial given its coefficients:
function polynomial(coef, u) =
sum_list([ for(i=[0:len(coef)1]) coef[i]*pow(u,i) ]);
Although, the code has been written for a polynomial with real coefficients it can be used for more general cases if you observe that the only operations with parameter coef inside this function are additions and scalar products by the power factors. In fact, we may use 2D or 3D points and vectors as coefficients of the function and define a parametric curve in the space without any change in its code:
function curve(p,n) = [ for(i=[0:n]) polynomial(p,i/n)];
p = [ [0,0], [1,0], [1,1] ];
echo(curve(p,5));
// ECHO: [[0, 0], [0.24, 0.04], [0.56, 0.16], [0.96, 0.36], [1.44, 0.64], [2, 1]]
We may go further and compute the mesh of parametric 3D surfaces from curve() and polynomial() by:
function surface(q, n, m) =
let( c = curve(q, n) ) [ for(i=[0:m]) polynomial(c,i/m) ];
q = [ [ [0,0,0], [1,0,0], [1,1,0] ],
[ [0,0,1], [1,0,1], [1,1,1] ],
[ [0,0,2], [1,0,2], [1,1,2] ] ];
echo(surface(q,2,3));
// ECHO: [ [[0, 0, 0], [1, 0, 0], [1, 1, 0]],
// [[0, 0, 0.666667], [1.91667, 0, 0.666667], [1.91667, 1.91667, 0.666667]],
// [[0, 0, 2], [3.5, 0, 2], [3.5, 3.5, 2]], [[0, 0, 4], [5.75, 0, 4], [5.75, 5.75, 4]]]
Note that the input argument coef of polynomial() is a list of points in curve() and a matrix of points in surface(). And that the results of the function polynomial() are homogeneous list of objects of the same type of coef. The fundamental concept here is that the starting function is linear in respect to the argument coef.
That code conciseness is impossible with typed programming languages.


In another thread:
Parkinbot wrote
CGAL seems to collapse all vertices with same coordinates and connect faces based on vertex coordinates, similar to STL processing. This observation simplified a lot the task of integrating many surfaces in one polyhedron: each face may be processed individually.
but as far as I know, this is not documented and might change in future. Usually it is not a good idea, to build new cities on such grounding. Maybe one from the dev team can say more about this.
Many things are not documented in OpenSCAD and some of them are very basic ones like variable scopes. That is why I opened the current discussion.
My hyphotesis is reasonable. It is the same behind the STL format. So if OpenSCAD is able to import STL files it should be able to comply with the rule I rely on. Further, if OpenSCAD do not comply with this rule in the future, either using CGAL or any other geometric engine, I will claim that rejecting the union of two cubes with just one vertex in common is a bug. Either the topology is consistent with the geometry or not. If it is not I will abandon OpenSCAD.


kintel wrote
> On Nov 18, 2016, at 13:47, Ronaldo < [hidden email]> wrote:
>
> I will claim that rejecting the union of two cubes with just one vertex in common is a bug.
I’d love to be able to robustly process such objects, at the very least since they can be valuable partial results.
However, our path into CGAL uses software components with a strict manifold requirement, so this is no trivial to implement.
So no, it’s not a bug, it’s a missing feature. It needs resources to implement properly.
Sorry, Kintel, may be I had not been clear enough. I am not defending that two cubes meeting in a vertex should be acceptable. I am saying that the topology should be consistent with the geometry. Therefore, if two vertices in the vertex list of a polyhedron definition have the same coordinates (geometrically equal) they should be topologically equal too. If this rule fails in polyhedron definitions they should fail everywhere.

Administrator

> On Nov 18, 2016, at 15:57, Ronaldo < [hidden email]> wrote:
>
> Sorry, Kintel, may be I had not been clear enough. I am not defending that
> two cubes meeting in a vertex should be acceptable. I am saying that the
> topology should be consistent with the geometry. Therefore, if two vertices
> in the vertex list of a polyhedron definition have the same coordinates
> (geometrically equal) they should be topologically equal too. If this rule
> fails in polyhedron definitions they should fail everywhere.
>
Thanks for the clarification. Geometrically equal vertices are always topologically equal today, also for polyhedron definitions.
There was a bug related to this, which triggered in some rare cases, which I fixed yesterday (as discussed in another thread).
Some file formats require vertices to be split up in order to attach certain attributes to them. This may include meta data to be able to identify which closed volume that vertex is part of. We may need to both read, preserve and write such information if we want to keep topology unambiguous. These are potential future enhancements though.
Marius
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Administrator

It is not just behaviour that is somewhat grey, syntax is not very clear in the wiki.
I had considered trying to document it in BNF, specifically I like EBNF.
Thoughts?
Admin  email* me if you need anything, or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.
Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.
The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!


So let's put this equivalence into the wiki. The following two polyhedra are identical and will be forever:
x = [[0,0,0], [0,10,0], [5,5,0], [2,2,2]];
polyhedron(x, [[0,2,1], [0,1,3], [1,2,3], [0,3,2]] );
y = [[0,0,0],[5,5,0], [0,10,0],
[0,0,0],[5,5,0], [0,10,0],
[0,10,0], [5,5,0],[2,2,2],
[0,0,0],[2,2,2],[5,5,0],
[0,0,0], [2,2,2], [0,10,0]];
polyhedron(y, [[0,1,2], [3,4,5], [6,7,8], [9,10,11]] );


On 11/19/2016 01:54 AM, Parkinbot wrote:
> So let's put this equivalence into the wiki. The following two
> polyhedra are identical and will be forever:
>
I guess the better solution would be an actual test case that
shows things break just after some change.
That also needs a more specific definition of "identical" (e.g.
after sorting triangles? identical STL export? AMF? 3MF?).
ciao,
Torsten.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 Torsten


>identical STL export?
Currently openscad STL files have nondeterministic order because IIRC some part of the software uses machine addresses to order vertices. If you change any of the source code or compile it on another machine it can make the facet and vertex order change even when the object is identical.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


I would like to resume this:
Parkinbot wrote
So let's put this equivalence into the wiki. The following two polyhedra are identical and will be forever:
x = [[0,0,0], [0,10,0], [5,5,0], [2,2,2]];
polyhedron(x, [[0,2,1], [0,1,3], [1,2,3], [0,3,2]] );
y = [[0,0,0],[5,5,0], [0,10,0],
[0,0,0],[5,5,0], [0,10,0],
[0,10,0], [5,5,0],[2,2,2],
[0,0,0],[2,2,2],[5,5,0],
[0,0,0], [2,2,2], [0,10,0]];
polyhedron(y, [[0,1,2], [3,4,5], [6,7,8], [9,10,11]] );
I may do an addition to the Manual but I need beforehand Kintel's agreement. I understand that equivalence may be ambiguous or too strong but we may say that both models above express the same geometry and topology eventually with different internal and external representations.


Von: Ronaldo < [hidden email]>
> I may do an addition to the Manual but I need
> beforehand Kintel's agreement.
> I understand that equivalence may be ambiguous
> or too strong but we may say that both models
> above express the same geometry and topology eventually
> with different internal and external representations.
>
As said before, having this only in the Manual is not
really helpful. It might break without anybody noticing
for a long time after which it's hard to impossible to
change behavior back.
The only way to prevent that, is to have an actual
test case added to our test suite after the details
are clear.
Of cause having an additional note in the Manual would
be good.
If this clarification is much desired, the best
strategy is to create an issue on github as it's
not as easily lost as some mails/forum entries.
ciao,
Torsten.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 Torsten

12
