<JakeSays>
somewhere i saw some scad code that would turn a text in to a path and then place objects along that path, but now i don't remember where i saw it. sound familiar to anyone?
ferdna has quit [Quit: Leaving]
arebil has quit [Quit: My keyboard has gone to sleep. ZZZzzz…]
rvt has joined #openscad
teepee has quit [Remote host closed the connection]
teepee has joined #openscad
rvt has quit [Quit: rvt]
rvt has joined #openscad
rvt has quit [Quit: rvt]
ur5us has joined #openscad
ur5us has quit [Ping timeout: 264 seconds]
arebil has joined #openscad
ur5us has joined #openscad
ur5us has quit [Remote host closed the connection]
ur5us has joined #openscad
ur5us has quit [Ping timeout: 264 seconds]
lastrodamo has joined #openscad
sublim8 has joined #openscad
jotweh has joined #openscad
Zauberfisch has quit [Ping timeout: 240 seconds]
Zauberfisch has joined #openscad
Zauberfisch has quit [Ping timeout: 244 seconds]
Zauberfisch has joined #openscad
othx has quit [Ping timeout: 245 seconds]
othx has joined #openscad
aiyion has quit [Remote host closed the connection]
aiyion has joined #openscad
arebil has quit [Quit: My keyboard has gone to sleep. ZZZzzz…]
la1yv_a has quit [Ping timeout: 265 seconds]
la1yv_a has joined #openscad
Junxter has quit [Remote host closed the connection]
Junxter has joined #openscad
la1yv_a has quit [Read error: Connection reset by peer]
la1yv_a has joined #openscad
la1yv_a has quit [Read error: Connection reset by peer]
la1yv_a has joined #openscad
la1yv_a has quit [Read error: Connection reset by peer]
la1yv_a has joined #openscad
la1yv_a has quit [Read error: Connection reset by peer]
la1yv_a has joined #openscad
aiyion has quit [Remote host closed the connection]
aiyion has joined #openscad
rvt has joined #openscad
ferdna has joined #openscad
rvt has quit [Quit: rvt]
rvt has joined #openscad
Teslamax has quit [Remote host closed the connection]
rvt has quit [Quit: rvt]
ferdna has quit [Quit: Leaving]
snakedLX is now known as snaked
<sublim8>
Question for any developers in the chat. How come there isn't a builtin module named "center" that centers its children around the origin?
Junxter has quit [Ping timeout: 260 seconds]
<sublim8>
Is there a good reason for not having such specialized built in modules?
<teepee>
yes, it interferes badly with the preview mode, which I assume is the main topic
<sublim8>
How do you mean?
<teepee>
in addition I think it would be too specialized and inflexible, but that said it's not easy to define something that works flexible and for everyone :)
<teepee>
center needs to know the actual coordinates / the mesh of the child modules
<teepee>
that is not available in preview
<sublim8>
I am asking because I have actually implemented such a builtin module and I don't know if I should bother submitting it. Creating a fork and all that.
<sublim8>
I don't seem to have an issue with preview.
<InPhase>
sublim8: How did you define "center"?
<InPhase>
sublim8: A bounding box center?
<sublim8>
yes
<sublim8>
it works like a charm for imported meshes too.
<sublim8>
like importing stl files and centering them.
<InPhase>
sublim8: If you got that to work properly for both preview and render, then that could be very valuable. But while you're working on it, do you think it would be hard to make one that origin-locks as well right beside it?
<InPhase>
sublim8: As in, move the bounding box corner to 0,0,0
<InPhase>
I assume that's identical logic.
<teepee>
that's what I mean, I would not want to see left() top() bottom() center() ....
<sublim8>
I managed to do that aswell by different means.
<sublim8>
I can also measure meshes and return dimensions as a vector
<peepsalot>
sublim8: does the solution use resize() ?
<sublim8>
no
<InPhase>
sublim8: Does returning dimensions trigger an additional render step?
<sublim8>
no, but there is a catch.
<InPhase>
sublim8: That particular one has been avoided only because it's costly.
<teepee>
it has to do the render (except when it's already a mesh like if the child module is only a single import)
<InPhase>
It would require module literals and processing stages to work, and runs incompatibly with special variables.
<teepee>
render as in "calculate the combined mesh"
<sublim8>
The catch is that, I cannot get the dimensions of a module at the same scope level the module is defined in. I can get it one level deeper.
<sublim8>
Because of module evaluation order.
<teepee>
what's the scad example?
<teepee>
I was assuming something like "center() import("file.stl");"
<sublim8>
Exactly that
Iz23 has joined #openscad
<sublim8>
Center works without any issue in all cases. Only my "size_of" has the scope issue.
<sublim8>
InPhase what do you mean module literals? I might be doing something like that already for getting the size.
<Iz23>
How do i download the paths extension?
<InPhase>
center() and a to_origin() I can picture working without messing anything else up. size_of I suspect has a lot of consequences that will need to be considered.
<teepee>
simply put: assign a module to a variable
<teepee>
which is not possible at all right now
<teepee>
as of recent version you can assign functions to variables and pass around
<sublim8>
I am working around that
<InPhase>
sublim8: Can you prepare separate PRs with one for for center() plus to_origin(), and another for size_of()? Because I bet the one will be a lot easier to get right and integrated while the other will require some edge case testing and sorting out complexities.
<teepee>
Iz23: what's a path extension?
<Iz23>
how do i download it?
Iz23 has quit [Client Quit]
<teepee>
I'd suggest creating a ticket first, I don't think we want all combinations as separate modules
Junxter has joined #openscad
<sublim8>
InPhase How would origin() compare to center() ?
<teepee>
there's an ancient "pos()" which was going way overboard with options but could maybe serve as other extreme to the discussion :)
<InPhase>
sublim8: Well I'm picturing most often wanting to move the corner to the origin.
<sublim8>
oh yeah
<InPhase>
sublim8: Particularly if getting the size is expensive, working from the origin on an unknown size is super helpful.
<sublim8>
I could do something like center with an align parameter instead of origin. So that we can align any edge of the object with the origin. What do you think?
<InPhase>
Off the top of my head, maybe teepee's option-explosion can be mitigated with the following syntax: relocate(p=[0,0,0], center=True) where center can take True, False, or [False, True, False] for centering just 1-2 axes.
<gbruno>
[github] t-paul closed issue #3946 (Raspberry Pi 3 running Raspbian 10 buster armv7l Linux 5.10.63-v7+: /usr/include/GLES3/gl32.h:1821:187: error: void __glewTexStorage3DMultisample(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean) redeclared as different kind of symbol). https://github.com/openscad/openscad/issues/3946
<teepee>
or alternatively we could try if we can solve the "get bounding box" in a reasonable way, specifically not using probe() + fixed magic variables
<InPhase>
relocate vs translate solves the problem with analogous syntax to scale and resize.
<InPhase>
relative and absolute
<sublim8>
Right now I modified the group module to accept a string so that I can name the underlying geometry.
<sublim8>
And created a size_of builtin function that accepts a string and returns the bounding box dimensions as a vector
<sublim8>
example:
<sublim8>
group("mygroup1") cube([10,10,10]);
<sublim8>
echo("Size is ", size_of("mygroup1"));
<sublim8>
this works
<sublim8>
because echo is a module
<sublim8>
size_of works when used as a parameter to a module or when is assigned to a variable within a module
<InPhase>
Hmm. group() has historically been the command we pretend doesn't exist.
<sublim8>
(btw the string is optional, you can have group without the string)
<sublim8>
I could do the same thing with any of the union, difference, intersection modules, I don't need group
<sublim8>
It's only when I assign size_of("mygroup1") to a variable in the same scope level with the named group definition that I don't get the correct value (I get undefined because size_of is evaluated before the group module)
<InPhase>
Well, it sounds like that restriction does in fact solve the special variable problem.
<sublim8>
For example in the same example as above the following:
<sublim8>
myvar=size_of("mygroup1");
<sublim8>
would be undefined
<sublim8>
but if I did:
<InPhase>
Although one needs to understand what happens with group("Foo") Foo(size_of("Bar")); group("Bar") Bar(size_of("Foo"));
<sublim8>
But still you can do amazing things with it.
<InPhase>
peepsalot will want to say something about lazy evaluation probably.
<sublim8>
I was trying to find a way to do exactly that
<InPhase>
Although we will have to wait to here his comment if that ping did not work.
<InPhase>
s/here/hear/
<InPhase>
sublim8: So is it correct that the center alignment is fully separable from the group/size_of changes?
<sublim8>
It's separable
<InPhase>
They both sound like you put a good bit of thought into the implications, but they are going to be very different in potential impact. Separating will make this easier.
<sublim8>
I just had a "cousin" module to center called center_on("groupname", offset") that depends on size_of
<InPhase>
What are your thoughts on that relocate syntax for it?
<sublim8>
it's like translate([0,0,0]) center() box([10,10,10]);
<sublim8>
isn't it?
<InPhase>
translate([0,0,0]) is a no-op.
<sublim8>
with having the option to omit the "center()"
<sublim8>
yes I it was based on the relocate(p=[0,0,0],center);
<sublim8>
would relocate(p=[1,2,3], center)
<InPhase>
Ah. Yes, it's true that the p is excessive.
<sublim8>
do the same as translate([1,2,3]) center()
<sublim8>
?
<InPhase>
Perhaps just relocate(center=...)
<InPhase>
I think most important is that option of True, False, or a 3-vector of bools.
<sublim8>
that sound good
<sublim8>
sounds good
<InPhase>
I'm undecided whether or not center should default to true or false.
<InPhase>
(Excuse the capitalization on True/False. I've been hammering out a lot of Python lately.)
<sublim8>
it could be center([true,false,true])
<sublim8>
and center() would default to all true
<InPhase>
Well center(center=True) sounds sketchy. :)
<InPhase>
to_origin(center=true) maybe.
<InPhase>
relocate is also the wrong term with p gone.
<sublim8>
I think the best solution would be to have something like "align" module
<sublim8>
like align(point, mode="top/topleft/bottom/...etc")
<sublim8>
maybe?
<InPhase>
Well that's just relocate but with string parsing.
<sublim8>
or even better maybe align(point, x="min/max/center", y="min/max/center", z="min/max/center");
<InPhase>
teepee: Wow, that's quite a lot of stuff.
<teepee>
yep
<sublim8>
I'll have to go through that. I see some guy (clothbot) proposed the exact same thing I just said.
<sublim8>
hehe
<sublim8>
I don't understand why such ideas were turned down and we didn't get some version of that in the end.
<sublim8>
I would think that it could simplify people's work a great deal
<teepee>
I suppose because never more than 2 people could even agree on how it's defined
ferdna has joined #openscad
<InPhase>
:) The bottom of page 15 of that pdf looks like my demo_wavy_donut.scad from the closepoints library.
<sublim8>
Hehe, right.
<InPhase>
sublim8: I think the key is to just not bite off too big of a chunk at a time.
<InPhase>
sublim8: And, it's very helpful to make the minimal change that empowers the scad implementers to do a new thing well. One must resist the urge to integrate solving too many problems, because those integrated solutions might not work for all problems. But certain features open up new classes of solutions as possible and/or reasonable, which is the case here.
<InPhase>
That loop_extrude for example in the 2013 proposal went away from this philosophy into trying to put a new language into the parameters of loop_extrude.
<InPhase>
I implemented a lot of those features as a more flexible library, although without having seen this pdf first.
<sublim8>
This loop thing seems really complex
<InPhase>
The notion of box() from that proposal is reasonable and would be convenient, but again it tries to put too much into the parameters.
<InPhase>
Hence when we look at yours, we should look for a clean simple syntax that provides the critical features, but doesn't try to solve everything that can be done already with extra scad code.
<Scopeuk>
center([<<vec3 0/1 to set yes no for axis>>])
<InPhase>
Like, rotate_extrude rotates around the y-axis. It does NOT need parameters to rotate around the x-axis, because that's already solvable.
<sublim8>
So it seems we don't like to have multiple ways of doing the same thing...
<InPhase>
It adds maintenance complexity but without empowering more.
<sublim8>
Right.
<InPhase>
Every redundancy is stealing more feature space from the future. :)
<sublim8>
I think being able to measure objects would be simple and very empowering. If only I could get a clean solution.
<sublim8>
Simple, syntax wise
<Scopeuk>
there is a lot of discussion around it
<InPhase>
The language shot itself in the foot a bit on that one with dynamic scope variables, which is why the solution everybody wants doesn't quite work.
<InPhase>
It would at minimum require special rules for special variables every time you go to measure and propagate back up to the same scope.
<sublim8>
Yes, something like that.
<sublim8>
That was what I was trying to tackle today.
<sublim8>
Hasn't worked thus far.
<sublim8>
But I am not familiar with openscad source code at all. If I had some more time to work on it I might come up with something.
<sublim8>
I managed to do all the things I mentioned earlier just in one day. And it was the first time a laid eyes on the source code.
<InPhase>
Your group solution effectively creates a different type of string variable that follows a different rule. I'm not wild about that on principle, but I'm intrigued that it does not result in the same conflicts from trying to use normal variables.
<sublim8>
I don't use openscad variables
<sublim8>
I just take the string parameter from the group module
<sublim8>
and put it in a map with the corresponding AbstractNode
<InPhase>
Yeah. What I mean is that is effectively acting as a variable, but not a standard one, so it doesn't come with the same expectations.
<InPhase>
And it was never an assignment statement, so there is no confusion about whether or not the module was instantiated as a geometry.
<sublim8>
Yes.
<sublim8>
inside the builtin_group function I take the newly created AbstractNode and associate it with the group name string passed as an argument
<InPhase>
To be honest, when you started talking about that I set myself up to explain why it wasn't going to work. :) But, I'm impressed that I cannot currently rule it out as a viable solution. This is not my first time down the path of a size-getting proposal.
<sublim8>
then in when the size_of function is called, I just lookup the string passed
<sublim8>
I get the AbstractNode, I create a new Tree and evaluate it with a GeometryEvaluator
<sublim8>
then I get the bounding box
<sublim8>
Oh well. At least I dabbled enough with openscad source code to make it work for me.
<InPhase>
sublim8: And to be explicit, does it do the same number of total evaluations? Or does it do an extra evaluation of the object being sized?
<sublim8>
It might do an extra evaluation. I'm not sure if anything is being cached.
<InPhase>
Okay, so an extra eval is called, put with potential cache effects saving it if we make sure those are in place.
<sublim8>
Yeap
<InPhase>
It will be interesting to benchmark.
<sublim8>
Yes, I'll have to do that.
<InPhase>
I would definitely encourage the two PRs. Some sort of to_origin maybe, thinking about our syntax discussions, and a group/size_of. I think they both have potential.
<sublim8>
It actually works most of the time. There is only an edge case where it doesn't.
<sublim8>
Thanks for the encouragement. I might do that.
<InPhase>
Pick one of the clean syntaxes for to_origin and I'll be endorsing it quickly if it passes testing and I spot no code flaws.
<InPhase>
group/size_of will need some community discussion because there's a lot to consider, but that's a worthwhile discussion to have.
rvt has joined #openscad
<InPhase>
If you saw the user-level to_origin I wrote, you would cry a little inside. ;)
rvt has quit [Client Quit]
<sublim8>
hehehe
<sublim8>
I can only imagine
<Scopeuk>
InPhase that part of the primitives in user space?
<InPhase>
In older versions of OpenSCAD I used to have big=10000; but this no longer works. Now if you put big=500; it works but deforms in horrendous ways, which is bad.
<InPhase>
Probably we should be more attentive to whatever causes those deformations now.
<sublim8>
ouch
<InPhase>
And at the end of the day, it only approximately moves to the origin. :)
<InPhase>
So, yes. Proper with built-in is the way to go.
<teepee>
I would prefer separating things, as it would not bind the implementation to a specific use case
<sublim8>
What do you mean teepee?
<teepee>
being able to get the numbers would mean it's possible to cover any of the use cases, if that's align-left, center or anything between
<sublim8>
yes!
<teepee>
without introducing magic words like align="left"
<sublim8>
I'm with you on that
<teepee>
now there's 2 levels, one trivial case that is already solvable without much disagreement would be for import()
<sublim8>
getting size and position would be very usefull
<teepee>
we now have that as special case for text() via textmetrics()
<teepee>
similar would be possible for import()
<teepee>
the more interesting part would be for general case using any geometry instantiated by modules
Junxter has quit [Ping timeout: 245 seconds]
<sublim8>
I think textmetrics measures the text without touching the geometry. It uses freetype directly.
<sublim8>
You mean we should get the size of the imported file the same way?
<sublim8>
Without touching the geometry?
<teepee>
yes
<sublim8>
And seperately make a general case for all modules
<sublim8>
I see
<teepee>
which is why that's a much easier case, there's not much surprising stuff that way
<teepee>
it would be a shortcut if there's no general solution, but it also could return even additional data
<teepee>
e.g. for file formats that have additional properties, those could be returned too
<sublim8>
True. But I don't know if you can get a bounding box from easily without processing from most file formats.
<teepee>
all file 3d formats we have right now are mesh so it's quite easy to just iterate over all points
<sublim8>
That's a bit expensive too.
<teepee>
CGAL would even support minimal bounding box ,not just aligned but I have not looked into that
<sublim8>
I'll have to check it out. What other information do you think the file might have that is useful?
<teepee>
iterating over all points should be negligable compared to anything CSG with that geometry
<sublim8>
I was looking for a minimal (non aligned) bounding box too, hehe
<sublim8>
Looking at the rotating calipers algorithm
<teepee>
the ideal solution would be that we could pass a user space function that can interrogate the geometry
<sublim8>
For that you would expect the function to return a transformation matrix
<teepee>
but I don't have a good idea yet if that works and what other traps that could hold
<sublim8>
or something. To get the rotation angles too.
<InPhase>
Aligned bounding box is the most useful for within code.
<sublim8>
yes
<InPhase>
You have to know how it's facing to work with it. :)
<teepee>
it was suggested before, and I'm still not clear if it's the best solution but data = render(); does look not too bad while hinting at the extra effort imposed by rendering
<InPhase>
Yeah, I advocated for that before.
<sublim8>
Didn't quite catch that. Could you explain?
<teepee>
now with render(func = aligned_bounding_box); or render(func = optimal_bounding_box); it could even give both results
<InPhase>
I'm also not sure if it's the best solution though.
<teepee>
at least it would give some separation between what is calculated and the implementation
<teepee>
while giving the options to the user instead of fixed magic calculations
<teepee>
but of course it's the most complex option :)
<teepee>
plus we have not tried it yet at all
<InPhase>
I think my favorite was the module literals type syntaxes, where you can do things like: foo = Foo(); where Foo() is a module call, and then grab variables from foo that describe the bounding box or dimensions. But it leaves an awkward question of does Foo() appear as a geometry when you do that? Or do you need a second foo(); ?
<InPhase>
This group idea at least skips those questions for now. Although the module literal also means you can pass it as a parameter.
<teepee>
yeah, that's still a bit fuzzy in my mind too
<InPhase>
Or, geometry literal.
<InPhase>
I guess in my mind I blur module literal and geometry literal, which is the source of the confusion. I'm not sure what it should be.
<InPhase>
I suppose we have separate options of object literals, module literals, and geometry literals, all of which have a purpose.
<InPhase>
I feel sort of like we're on the cusp of reinventing OOP badly. :)
<teepee>
oop is bad already, so no worries there :P
<sublim8>
lol
<InPhase>
:)
ali1234 has quit [Remote host closed the connection]