snakedLX has quit [Read error: Connection reset by peer]
snakedLX has joined #openscad
snakedGT has quit [Ping timeout: 265 seconds]
default__ has quit [Ping timeout: 260 seconds]
The_Jag_ has joined #openscad
The_Jag has quit [Ping timeout: 260 seconds]
<JakeSays>
i need to place objects along the middle of a text outline. for example, i have the number 8, and i want to place LED's inside of it. any idea how i would do this?
linext__ has quit [Read error: Connection reset by peer]
paddymahoney has joined #openscad
<peepsalot>
JakeSays: direct access to the font outline geometry/paths is not really possible, you'd have to calculate a path on your own to place leds along such a path
<JakeSays>
peepsalot: i was afraid of that:(
<JakeSays>
hmm. it'd be pretty easy to write a little cmd line tool that'd create the path. i'll do that.
Junxter has joined #openscad
default__ has joined #openscad
Junxter has quit [Ping timeout: 252 seconds]
Junxter has joined #openscad
Junxter has quit [Remote host closed the connection]
Junxter has joined #openscad
Zauberfisch has quit [Read error: Connection reset by peer]
<InPhase>
JakeSays: peepsalot is correct that it's impossible. Except... you can still cheat. :) https://bpa.st/SKEA
<InPhase>
JakeSays: Try alterations like text_len = text_height*8; text_str = "867-5309"; and you'll see it's not perfect in the general case. But, also, not bad. :)
<sublim8>
Thanks. I'm working on creating a pull request for importmetrics right now.
<sublim8>
InPhase, about size_of. When I evaluate the geometry it does indeed get cached in GeometryCache and CGALCache. So that's a win.
<sublim8>
No multiple evaluations for the same mesh
arebil has joined #openscad
linext has joined #openscad
linext has quit [Read error: Connection reset by peer]
linext has joined #openscad
rvt has joined #openscad
rvt has quit [Quit: rvt]
<InPhase>
sublim8: Nice.
<InPhase>
Although does the importmetrics approach to that load twice? That might be okay still as a first pass behavior, but I want to understand the consequences.
<sublim8>
I was thinking about that too. If you call importmetrics before import (same file) then the next time you call import there will a second load. If you call importmetrics after import then no second load happens.
<sublim8>
I might be able to fix the first case also in the future.
<InPhase>
Yep.
<sublim8>
Also I am dumping the size_of (and the other functions in that family that I didn't mention yesterday, min_bounds_of, max_bounds_of, center_of) for a metrics module that returns all the metrics in a single object.
<sublim8>
It's more generic, more versatile, will create less code clutter and will have a better chance of getting accepted.
<sublim8>
it will let people roll their own user modules like relocate, position, align, center etc.
<sublim8>
If you don't like the "min" "max" strings you can roll your own, having only true and false for each dimension doesn't provide complete alignment options. We need three states for each dimension.
<InPhase>
sublim8: Is there any reason then to do importmetrics separate from this approach?
<sublim8>
teepee asked for it :p
<InPhase>
teepee's mind is as maleable as my own, if a better idea comes along. :)
<sublim8>
At first I thought it might be a bit more efficient for imports
<sublim8>
But looking at the code, and the fact that geometries are getting cached, that might not be the case.
<sublim8>
Also it's just that importmetrics avoids the group("name") thing
<sublim8>
and as such, doesn't suffer from the scope issue
arebil has quit [Quit: My keyboard has gone to sleep. ZZZzzz…]
<teepee>
the point is also that data = import() allows for extra data not just geometry, which is why I think it might be useful on it's own even if we want the more flexible geometry query at some point
<sublim8>
What other data are you suggesting teepee?
<sublim8>
Just realized I was naming the groups "myshpere" even though they contain cubes, hehe.
<teepee>
3MF for example has additional properties that can be attached to the file
<teepee>
I'm not convinced we should do the named grouping stuff, that's something that could never be removed again once it's out there and seems to not match the normal language
<sublim8>
True, but there's no alternative for measuring objects.
<sublim8>
As far as I can tell you can not assign to variables results from modules
<sublim8>
modules have rendering/output effect only
<teepee>
true, but same there's no named groups currently
<sublim8>
Sure but the functionality is too good to pass. If there is some other way to get it, I am all for it. I just can't see how.
<teepee>
the point is that we struggle with the adhoc nature of the past very badly already
<sublim8>
Yep
<teepee>
going some shortcuts now will make it impossible to go back, removing things is very bad for existing scripts
<sublim8>
There is a deprecation mechanism.
<sublim8>
Named groups dom have to become a major thing
<sublim8>
don't
<sublim8>
It can remain a fringe thing that helps out when there is no other way.
<sublim8>
You think that it will be adapted so heavily by the users that it's going to become an issue in the future?
<teepee>
it does not work like that, the normal behavior is that people start using even the unintended side effects and very loudly complain when those get changed
<teepee>
even in cases where it's not documented or even documented to no do that
<teepee>
e.g. example is unnamed { }
<sublim8>
I can understand that.
<sublim8>
I have no problem keeping it for myself. I'll just have to patch my openscad every time I install.
<teepee>
it would be great to get that feature going, it's been discussed over and over again
<sublim8>
I can imagine
<teepee>
but we need to have a solution that is possible to maintain in the future and that's the tricky part
<teepee>
same with path extrusion
<sublim8>
Could you think of an example where named groups would become a liability in the future?
<sublim8>
Are there any plans in the future to create a mechanism for returning data from modules?
<sublim8>
That would make named groups obsolete for sure.
<peepsalot>
af: did you mean like this? module mycyl(rx1, ry1, rx2, ry2, h) linear_extrude(height=h, scale=[rx2/rx1,ry2/ry1]) scale([1,ry1/rx1]) circle(r=rx1); mycyl(20,40,40,20,40, $fs=1, $fa=1);
<sublim8>
But is that something anyone is seriously considering? Is it even possible without redesigning the whole pipeline?
<sublim8>
There is no serious complexity in the named groups mechanism. It's just a string associated with the AbstractNode. And as such, a way to reference it by a string parameter to a function or module.
<teepee>
what happens if the name is duplicated?
<sublim8>
It gets overwritten. The AbstractNode associated last with the name returned.
<sublim8>
Top down philosophy.
<sublim8>
Same that happens to all variables.
<sublim8>
And that already happens in the example I provided in the last image.
<sublim8>
The group "Children" is getting overwritten every time. It's expected and there is no issue.
<sublim8>
It's the user's responsibility to keep the names unique if he needs them to be unique.
<sublim8>
the first is valid only until before line 2
<InPhase>
sublim8: It seems you can simply reuse the group syntax on import statements without inventing two kinds of round wheel.
<InPhase>
sublim8: Even if imports need to be special-cased internally, the same syntax would be nice.
<sublim8>
InPhase, true, but as teepee said, importmetrics could return more data.
<InPhase>
What additionals would those be?
<sublim8>
making a special case for group("foo") import() might be worth it.
<teepee>
we could even decide to let data = import() return the points in addition too
<sublim8>
I don't know, teepee said something about 3MF format. It has more information that could be returned.
<sublim8>
teepee indeed we could
<sublim8>
but so can named groups
<teepee>
other example is DXF which has specific markers we currently import by a separate call
<sublim8>
I have access to the Geometry object in both cases.
<teepee>
those could also be returned
<sublim8>
I'll have to see if the AbstractNode preserves this information or a way to access them. In that case just making a special case for group("foo") import() would work too.
<teepee>
why would that need a node?
<teepee>
that's the geometry part, the data is in the file
<sublim8>
the geometry object is associated with a node
<teepee>
yes, but running data = import("x.stl"); would not need to generate a node
<teepee>
it could if that helps internally, but just reading the data would work just as well
<sublim8>
I think it does
<sublim8>
oh yes, I mean, importmetrics does not create a node
<sublim8>
import creates a node
<sublim8>
importmetrics works like you described
<teepee>
I tend to think we should just call it import too, but we can leave that to last decision :)
<InPhase>
teepee: At that point, group("Foo") Foo(); could return the points as well. :)
<sublim8>
I was just following the fontmetrics example. I have no opinion on names.
<InPhase>
teepee: If you have the box, you have the points. They could be returned.
<teepee>
InPhase: yes, but group() + name seems to be the worst solution language wise
<sublim8>
InPhase yes indeed.
<teepee>
data = render() .. seems more obvious and would not need naming hacks
<sublim8>
what if we made every module taggable with a string?
<InPhase>
teepee: Well. Agreed.
<sublim8>
not just group
<sublim8>
heh
<teepee>
yes, for extra annotations that's probably useful, but that's a quite different feature I think
<InPhase>
teepee: BUT, data = render() requires thinking more carefully about that variable structure. We need a way to make it ordered.
<InPhase>
teepee: Do we declare that data = render() only uses variables declared above it? Because this is a very different thing.
<teepee>
not sure, I'm not seeing any extra features regarding scoping, but I might miss something
<InPhase>
teepee: sublim8's group("foo") thing only provides access to that group data one level lower in geometry calls.
<InPhase>
teepee: Before that one level lower, it's undefined.
<sublim8>
yeap
<InPhase>
teepee: So that would be like: data = render(), except data is undefined until one level more nested.
<teepee>
and because of that it's scary as it's a completely new logic
<InPhase>
Yes it is. But it cleverly skips over all the issues with the ordering questions.
<InPhase>
Wait. What if we only allow data = render() in a let context?
<sublim8>
I was thinking of making the node visit multithreaded and delay evaluating references that haven't been defined yet. But that seems a bit complicated.
<sublim8>
I also saw that someone had tried something similar in the past but didn't get accepted.
<InPhase>
You can put as many of them as you want inside of that let statement.
<sublim8>
Not yet at least.
<InPhase>
let is also strictly ordered! And sublim8's groups need to be strictly ordered.
<teepee>
probe() has exactly the same issue + every discussion on adding test cases was ignored, that's not how complicated new features are accepted
<InPhase>
I think that enforces all the requirements, but rather than a mystical next-group syntax, the let spells out exactly where it's valid and where it's not.
snakedLX has quit [Ping timeout: 260 seconds]
<teepee>
hmm, yes, interesting idea
<InPhase>
That was staring us in the face all along, but I'm pretty sure I would have never thought of that without sublim8 spelling out exactly the scope-nesting requirement there.
<af>
peepsalot: That's perfect, thank you!
<af>
Scopeuk: yes but you can't scale the bottom and top variadically
<InPhase>
Let us default let(data = render() ...) to never make geometries, since let statements don't do that, but then inside enable something like { data.render(); } to bring back the geometry if wanted.
<InPhase>
Also a polyhedron(points=data.points(), faces=data.faces()); for 3D should work, and a polygon(data.points()) for 2D should work. But a data.render(); would be super convenient, even if we need to special-case it.
<Scopeuk>
Af agreed. I hadn't realised that element of the problem, glad you found something
<teepee>
yeah, the geometry part may still need some extra effort, but it might be ok to start out with data only and extend later
<teepee>
adding new stuff is backward compatible in most cases
<InPhase>
Yes. At the very least modules can already be used to avoid repetition.
<InPhase>
So that data.render() idea doesn't need to be there in the first-pass.
<InPhase>
sublim8: Do you understand the let syntax proposal, and does it make sense to you?
<sublim8>
To be honest, no.
<sublim8>
Didn't understand
<InPhase>
sublim8: Are you familiar with let statements? I will explain from where you are missing.
<sublim8>
I'm not that proficient in openscad syntax. I can't remember ever having to use it.
<sublim8>
It lets you redefine a variable?
<sublim8>
in order?
<InPhase>
Okay. So a let statement is a way to establish a new context scope within a module (or function, but modules matter here).
jonasbits_ has quit [Quit: No Ping reply in 180 seconds.]
<teepee>
I'm no yet 100% clear why that restriction is necessary, so I'll listen closely too :)
<InPhase>
Inside the let statement, the defines are comma separated, and sequentially ordered.
<sublim8>
ok
<InPhase>
Then following the parenthetic list of defines, there is a brace scope, within which that list of defines is valid. For your purposes, this makes the brace scope equivalent to the second group or union in which your group strings were valid.
jonasbits has joined #openscad
<sublim8>
Yes true, I already tried that and it works
<InPhase>
This means we can use assignment syntax rather than the group strings, and it will not clash with any existing variable behaviors. Nothing inside the brace scope can affect outside, and nothing in the let define list goes out of order.
<sublim8>
I can put the m=metrics("name"); inside let() parenthesis or inside the curly brackets and it works.
<InPhase>
Well we don't need "name" anymore. The variable is the name.
<teepee>
in totally unrelated news, it seems Travis is dead now, they seem to require a credit card now even for free/open source plans
ferdna has joined #openscad
<InPhase>
teepee: Do they charge it if usage exceeds some limit?
<teepee>
supposedly only checking $1 and giving that back, but who knows and I'm not ok with trying
<InPhase>
teepee: It is suspicious behavior.
<InPhase>
sublim8: Feel free to throw some questions if any of that so far is unclear. I can show some classic let examples if that will help, but I will try typing up a let example of your proposal.
<sublim8>
how would the syntax you're proposing look like for getting the metrics?
<teepee>
wouldn't that work with just normal assignments too? with just the same restrictions as we have?
<InPhase>
teepee: Special variable ordering is pretty bad.
<InPhase>
teepee: A sequentiality requirement fixes it.
<teepee>
what would be an example that causes issues?
<InPhase>
sublim8: It's actually a completely different thing when used in the other syntax.
<InPhase>
sublim8: It's just reuse of a keyword really.
<InPhase>
That cylinder height in my example should be h of course. Clearly I did not execute the code using non-implemented syntax. :)
<InPhase>
I'm really liking this. It captures everything sublim8 thought of, but blends seamlessly with the existing syntax, with the only restriction to write in the manual being "Due to scoping issues, assignments from render() can only occur inside of let statements."
<sublim8>
Cool. what's missing for it to work?
<InPhase>
sublim8: Well, can you morph your code that captures these values to that syntax?
<sublim8>
does render() already work as expected in this syntax?
<InPhase>
No.
<InPhase>
That was simply an old proposal.
rvt has quit [Quit: rvt]
<InPhase>
One that we abandoned because we couldn't reason out the scoping.
paddymahoney has quit [Remote host closed the connection]
<sublim8>
I think I could morph it.
<InPhase>
Therefore, no one tried implementing it.
<sublim8>
So what "part of speech" is render() ?
<InPhase>
Currently render() works as a module. This would make a render in the function space.
<InPhase>
Well.
<sublim8>
function? How does it accept children? Do we change the syntax?
<InPhase>
teepee: Help here. :)
paddymahoney has joined #openscad
<sublim8>
I think openscad uses bison for that, right?
<InPhase>
teepee is the one most experienced with reworking the syntax edges like this. He got the function literals working right.
<sublim8>
So render is going to be a new hybrid thing. Correct?
<sublim8>
A new part of speech for openscad.
<teepee>
sort-of yes. internally it would be basically just both a function and a module
<teepee>
I'm not too much concerned about the internal part though, the ciritical topic is what's visible to user as that's the mostly unchangable part once it's released officially
<teepee>
we'll start with flagging those features as experimental to highlight changes are still possible, so we can try things out a bit earlier
paddymahoney has quit [Remote host closed the connection]
<teepee>
yes, the parser is flex + bison
<InPhase>
I think that was a very productive and well-timed conversation. I think this is likely going to be an elegant and powerful language addition now.
<sublim8>
Hope so :)
<InPhase>
In one stroke it solves several of the most frequently asked for features of the language, and in a smooth way.
<sublim8>
what other data will render provide except from the bounding box?
<InPhase>
The points and faces.
<InPhase>
That will be huge.
<sublim8>
Yes
<teepee>
yeah, it's still a bit of a middle ground to full object/module support, but it seems like it's a reasonable thing that still fits into the language
<InPhase>
The top asked for features: 1) How can I access the points? 2) How can I access the bounding box? 3) How can I make renders go faster? 4) How can I track part information?
<InPhase>
This hacks off numbers 1 and 2. ochafik is in charge of number 3, and back in progress.
<teepee>
:)
<InPhase>
Although peepsalot also is making progress on #3 with that memory work, which is probably additive with ochafik's work.
<teepee>
indeed, in combination that could be quite huge
rvt has joined #openscad
<InPhase>
Part information is a big nebulous really. Some of this object literals should hit nicely. Some is the growing need for labeling material information, which ventures into multi-color multi-material renders for which we don't have clear notions yet, but will need to figure out within a couple years.
<InPhase>
s/big nebulous/bit nebulous/
marek has joined #openscad
paddymahoney has joined #openscad
paddymahoney has quit [Read error: No route to host]
paddymahoney has joined #openscad
teepee has quit [Ping timeout: 276 seconds]
teepee has joined #openscad
arebil has joined #openscad
marek has quit []
arebil has quit [Quit: My keyboard has gone to sleep. ZZZzzz…]
<Scopeuk>
materials are a weird one, I think something like material(<<name as a number or a string>>) could work, a little like colour does now
Guest15 has joined #openscad
Guest15 has quit [Client Quit]
_xxoxx has joined #openscad
<Scopeuk>
annotating this into outputs however is more tricky
<Scopeuk>
I suppose you could tie a material into the shader experimentation that happened recently
<Scopeuk>
more of an ecosystem issue than an openscad issue
Junxter has quit [Ping timeout: 258 seconds]
_xxoxx has quit [Quit: Leaving]
<Scopeuk>
I guess that then raise do you allow arbitrary meta data to be added up to the limits of say 3mf
<Scopeuk>
or do you limit it to just materials and let the assign happen at slicer
<teepee>
I still think the general annotations would be quite useful
<Scopeuk>
yes
<Scopeuk>
just marking as is material 1 or is material "pink" would be suitable for handing off to a slicer or an intermediate to set what each of those is allocated to
<Scopeuk>
it seams internally 3mf's materials are just a vector with property fields