Assume you have a list like
MyList=[[[a000,a001,a002], [a010,a011,a012],[a020,a021,a022]],
[[a100,a101,a102], [a110,a111,a112],[a120,a121,a122]],
[[a200,a201,a202], [a210,a211,a212],[a220,a221,a222]]];
How would you address, say, element a122 and change its value from, say,
5 to 7?
Anybody?
Wolf wv99999@gmail.com writes:
Assume you have a list like
MyList=[[[a000,a001,a002], [a010,a011,a012],[a020,a021,a022]],
[[a100,a101,a102], [a110,a111,a112],[a120,a121,a122]],
[[a200,a201,a202], [a210,a211,a212],[a220,a221,a222]]];
How would you address, say, element a122 and change its value from,
say, 5 to 7?
Something like the below should work. Note that it is not possible to change
the value of a list during execution, instead a new list can be introduced
which is a modification of the original.
Often there will be a different way to solve the underlying problem; one
that works more natural with the functional nature of the OpenSCAD language,
and doesn't need to update elements individually.
function replace(list, index, new) =
[for (i = [0:len(list)-1]) (i==index ? new : list[i])];
MyList=[[["a000","a001","a002"], ["a010","a011","a012"],["a020","a021","a022"]],
[["a100","a101","a102"], ["a110","a111","a112"],["a120","a121","a122"]],
[["a200","a201","a202"], ["a210","a211","a212"],["a220","a221","a222"]]];
MyList2 = replace(MyList, 1,
replace(MyList[1], 2,
replace(MyList[1][2], 2, "NEW")));
echo(MyList);
echo(MyList2);
Kristian Nielsen knielsen@knielsen-hq.org writes:
function replace(list, index, new) =
[for (i = [0:len(list)-1]) (i==index ? new : list[i])];
MyList=[[["a000","a001","a002"], ["a010","a011","a012"],["a020","a021","a022"]],
[["a100","a101","a102"], ["a110","a111","a112"],["a120","a121","a122"]],
[["a200","a201","a202"], ["a210","a211","a212"],["a220","a221","a222"]]];
MyList2 = replace(MyList, 1,
replace(MyList[1], 2,
replace(MyList[1][2], 2, "NEW")));
This BTW generalises to arbitrary levels:
function multi_level_replace(list, indexes, new, level=0) =
(level >= len(indexes) ?
new :
replace(list, indexes[level],
multi_level_replace(list[indexes[level]], indexes, new, level+1)));
MyList3 = multi_level_replace(MyList, [1,2,2], "REPLACEMENT");
echo(MyList3);
Menge tak, Kristian
that is going to be useful. Now I have just a simple request to whoever
has the authority to do so: add the replace() / multi_level_replace()
functionality to the list comprehension documentation. It is just as
important to know about as is, say, flatten(), which removes one level
of brackets in a list. If it had been there, I would not have needed to
ask here, and I would have found how to address a list element in a
multi-level list: a123->MyList[1][2][3]
On 10/10/21 9:13 PM, Kristian Nielsen wrote:
Kristian Nielsen knielsen@knielsen-hq.org writes:
function replace(list, index, new) =
[for (i = [0:len(list)-1]) (i==index ? new : list[i])];
MyList=[[["a000","a001","a002"], ["a010","a011","a012"],["a020","a021","a022"]],
[["a100","a101","a102"], ["a110","a111","a112"],["a120","a121","a122"]],
[["a200","a201","a202"], ["a210","a211","a212"],["a220","a221","a222"]]];
MyList2 = replace(MyList, 1,
replace(MyList[1], 2,
replace(MyList[1][2], 2, "NEW")));
This BTW generalises to arbitrary levels:
function multi_level_replace(list, indexes, new, level=0) =
(level >= len(indexes) ?
new :
replace(list, indexes[level],
multi_level_replace(list[indexes[level]], indexes, new, level+1)));
MyList3 = multi_level_replace(MyList, [1,2,2], "REPLACEMENT");
echo(MyList3);
May I ask what your use case is? There might be a better way to handle this.
BTW, addressing a multiple-level list is addressed in the manual:
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/General#Values_and_Data_Types
See "indexing elements in vectors."
On Sun, Oct 10, 2021 at 7:17 PM Wolf wv99999@gmail.com wrote:
Menge tak, Kristian
that is going to be useful. Now I have just a simple request to whoever
has the authority to do so: add the replace() / multi_level_replace()
functionality to the list comprehension documentation. It is just as
important to know about as is, say, flatten(), which removes one level
of brackets in a list. If it had been there, I would not have needed to
ask here, and I would have found how to address a list element in a
multi-level list: a123->MyList[1][2][3]
On 10/10/21 9:13 PM, Kristian Nielsen wrote:
Kristian Nielsen knielsen@knielsen-hq.org writes:
function replace(list, index, new) =
[for (i = [0:len(list)-1]) (i==index ? new : list[i])];
MyList=[[["a000","a001","a002"],
["a010","a011","a012"],["a020","a021","a022"]],
[["a100","a101","a102"],
["a110","a111","a112"],["a120","a121","a122"]],
[["a200","a201","a202"],
["a210","a211","a212"],["a220","a221","a222"]]];
MyList2 = replace(MyList, 1,
replace(MyList[1], 2,
replace(MyList[1][2], 2, "NEW")));
This BTW generalises to arbitrary levels:
function multi_level_replace(list, indexes, new, level=0) =
(level >= len(indexes) ?
new :
replace(list, indexes[level],
multi_level_replace(list[indexes[level]], indexes, new,
level+1)));
MyList3 = multi_level_replace(MyList, [1,2,2], "REPLACEMENT");
echo(MyList3);
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
When I learned Afrikaans as a foreign language, I came across the term
"om die bos lei", literally, in English, "to lead to the other side of
the forest", since "bos" may mean a single bush, but also a large
forest. The closest meaning of that phrase in English would be "to
cheat" or "to blindside someone", and that describes accurately how
South Africans dealt with reality, i.e. blindsiding themselves by taking
up a position from where it was impossible to see what they did not want
to see. "What I cannot see is not there. Therefore, I am right."
The OpenSCAD developers have done the same thing to themselves by having
chosen a functional language to describe 3D relationships between, let's
call it 'shapes'. The simplest of these shapes would be a triangle, with
points A,B,C. When incorporating this triangle in a larger structure,
say a tetrahedron, or a cube, one also need to describe the sequence in
which one moves from one point to the next. In OpenSCAD, this sequence
is called a 'face'. If you do the sequence correctly, your triangle will
close theshape. If you do not, you create a hole. Try it with
polyhedron(), if you wish.
So far so good. But, as soon as you include into your analysis the fact
that your numbers have only a finite number of digits, the situation
changes. Assume now that point B is very close to the line AC, then the
need to round means the point may fall on either side of the line, and
you have to choose your rounding procedure based upon where A and C are
so that when rounding you keep your shape closed, i.e. you have to
consider 'state', 'state' being determined by where your other points
are, and what the effect is on all the faces that share this point. And
'state' is supposed to be irrelevant for a functional language and left
to those dinosaurs that insist on using an imperative language, where
'state' is part of the game and to be considered at all times. Create a
surface of nominal thickness zero by e.g. subtracting two equal sized
cubes from each other, and you'll see that above is for real in
OpenSCAD's preview mode. Rotate this "non-existing" cube, and the fun
gets even better.
So, polemic aside, you see that I am not a great admirer of OpenSCAD. It
does have drawbacks, in particular when you need to rely on its preview
mode and cannot use rendering. Rendering, if you do not already know,
uses arbitrary accuracy mathematics to bypass rounding errors, but it
also destroys color information.
And color information is essential for what I have set out to do: to
enable a person living some 10000 km away from me how to design and
manufacture a piece of tooling. This person has no previous experience
in drafting at all, but does know some programming. Drafting, i.e.
reducing a real-world object to some list of points and faces, does take
quite some time to acquire. Changing a number in a program is an ability
that can be acquired rather quickly. And that is why I use OpenSCAD. It
uses programming, and if properly prepared, even a newbie can adjust a
drawing to suit his/her needs. For my own needs OpenSCAD is way too slow.
"Too slow" for me refers to the time I need to spend on figuring out
where to translate() and rotate() a shape so that it does the job for
which it is intended. And if you need to repeat translations and
rotations of the same shape many times, you better keep track on where
that shape is. OpenSCAD does not do that for me at all. I have to rely
on eye-balling, which works reasonably for two or three
rotations/translations, but not for ten or more. And if you include
difference() into the equation, it gets way worse.
Let's now be a bit more practical: The task is to transform a piece of
plate, whose sides are either parallel to each other, or vertical, into
something where this is no longer true. The task is to be done on a
vertical milling machine, which means that the plate has to be presented
to the machine in such a way that the surface-after-cutting is
horizontal. The vise that must hold the plate has two vertical surfaces,
and if these surfaces do not touch the piece of plate over the whole
length, the cutting forces will simply throw out the piece, and in doing
so, destroy it. I anticipate about 10 machining actions, to be done one
after the other. The programming that simulates this machining will be
distributed over the same 10 programs, and needs to be done in such a
way that the consequences of a change in program 1 can be viewed in any
subsequent program, up to program 10.
Let's now look at the programmatical side: my piece of plate has 6 faces
and 8 corners, and will keep that over the course of machining. What
will change during machining are the length of all 12 edges, and the
angles under which the faces meet. None of this is a problem for
polyhedron(). I start with creating a cube, but not by using cube() or
$fn=4; cylinder(), but by using polyhedron(), a points list and a faces
list. The faces list remains unchanged, only the points list gets
updated from cutting action to cutting action, i.e. from program 1 to
program 10. Because I now have access to each point, I can define each
cutting shape to OpenSCADs accuracy of 6 or 7 decimal places, much
better than the 2 or three places that are possible by careful eyeballing.
And I also loose all zero-thickness faces that preview insists I must have.
I haven't done it yet, and there may be obstacles I have not
anticipated, being an imperative dinosaur. I know I can access functions
and modules from other programs, but what about data? That I still have
to try.
So, if you are willing, Father Horton, to generalize this idea to
OpenSCAD, the OpenSCAD developers could ditch CGAL and its longish
rendering times, making OpenSCAD a lot faster and its user community
happier. But that means you need to convince the developers to open
OpenSCAD to imperative programming . . .
I won't do it, but I can share my ideas. Maybe there is someone to pick
them up? There is one other item I know of that needs to be ditched:
ASCII formatted data files such as .stl. Rounding is not permitted, and
that means conversion from binary to decimal data formats are sources
for holes in meshes.
On 11/10/21 3:10 PM, Father Horton wrote:
May I ask what your use case is? There might be a better way to handle
this.
BTW, addressing a multiple-level list is addressed in the manual:
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/General#Values_and_Data_Types
See "indexing elements in vectors."
On Sun, Oct 10, 2021 at 7:17 PM Wolf <wv99999@gmail.com
mailto:wv99999@gmail.com> wrote:
Menge tak, Kristian
that is going to be useful. Now I have just a simple request to
whoever
has the authority to do so: add the replace() / multi_level_replace()
functionality to the list comprehension documentation. It is just as
important to know about as is, say, flatten(), which removes one
level
of brackets in a list. If it had been there, I would not have
needed to
ask here, and I would have found how to address a list element in a
multi-level list: a123->MyList[1][2][3]
On 10/10/21 9:13 PM, Kristian Nielsen wrote:
Kristian Nielsen <knielsen@knielsen-hq.org
<mailto:knielsen@knielsen-hq.org>> writes:
function replace(list, index, new) =
[for (i = [0:len(list)-1]) (i==index ? new : list[i])];
MyList=[[["a000","a001","a002"],
["a010","a011","a012"],["a020","a021","a022"]],
[["a100","a101","a102"],
["a110","a111","a112"],["a120","a121","a122"]],
[["a200","a201","a202"],
["a210","a211","a212"],["a220","a221","a222"]]];
MyList2 = replace(MyList, 1,
replace(MyList[1], 2,
replace(MyList[1][2], 2, "NEW")));
This BTW generalises to arbitrary levels:
function multi_level_replace(list, indexes, new, level=0) =
(level >= len(indexes) ?
new :
replace(list, indexes[level],
multi_level_replace(list[indexes[level]], indexes,
new, level+1)));
MyList3 = multi_level_replace(MyList, [1,2,2], "REPLACEMENT");
echo(MyList3);
- Kristian.
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
<mailto:discuss-leave@lists.openscad.org>
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
On 11/10/2021 09:20, Wolf wrote:
Let's now be a bit more practical: The task is to transform a piece of
plate, whose sides are either parallel to each other, or vertical,
into something where this is no longer true. The task is to be done on
a vertical milling machine, which means that the plate has to be
presented to the machine in such a way that the surface-after-cutting
is horizontal. The vise that must hold the plate has two vertical
surfaces, and if these surfaces do not touch the piece of plate over
the whole length, the cutting forces will simply throw out the piece,
and in doing so, destroy it. I anticipate about 10 machining actions,
to be done one after the other. The programming that simulates this
machining will be distributed over the same 10 programs, and needs to
be done in such a way that the consequences of a change in program 1
can be viewed in any subsequent program, up to program 10.
Let's now look at the programmatical side: my piece of plate has 6
faces and 8 corners, and will keep that over the course of machining.
What will change during machining are the length of all 12 edges, and
the angles under which the faces meet. None of this is a problem for
polyhedron(). I start with creating a cube, but not by using cube() or
$fn=4; cylinder(), but by using polyhedron(), a points list and a
faces list. The faces list remains unchanged, only the points list
gets updated from cutting action to cutting action, i.e. from program
1 to program 10. Because I now have access to each point, I can define
each cutting shape to OpenSCADs accuracy of 6 or 7 decimal places,
much better than the 2 or three places that are possible by careful
eyeballing.
Not sure what the problem is. Workholdimg - a parallel jaw machine
vice can only grip parallel side work pieces (with exceptions, of
course), generally not tapered pieces - no use for your second paragraph
description - but simple 'tricks'/attachments can solve most problems.
There are also many different work holding solutions more suitable for
plate work. A major part of machining is work-holding. Without knowing
the details, it is unlikely that anyone can give a useful reply.
Or is it that openscad does not produce accurate shapes (mentioned in
your previous paragraphs)?