<HimeHaieto>
well as you said yourself, their attitude towards parallel computation/performance may be less than inspiring...they may not be hostile to it, but I guess they've tended to favour direct simplicity of their code over optimisation
<HimeHaieto>
so I don't know how they would even take to that sort of notion
<HimeHaieto>
the above was also my very brief evaluation of the topmost level, the low-hanging fruit kind of thing - it wasn't even making any adjustment to the algorithm for actually performing a union between polyhedrons, which could surely be done, let alone, say, taking it to an accelerator perhaps
<HimeHaieto>
if it's really intensive enough, I imagine an operation like that could potentially see its way toward going on the gpu, which could conceivably dwarf attempts to use any number of cpu threads
<HimeHaieto>
I didn't really delve too deeply into its code myself
<HimeHaieto>
however, like I said, even without any modifications to cgal, at the very least the top level change I mentioned could still be possible from within openscad itself
<HimeHaieto>
that would prolly be the quickest/easiest way to test the theory of whether that sort of optimisation could be helpful
Lagopus has quit [Ping timeout: 248 seconds]
Guest75 has joined #openscad
Guest75 has quit [Quit: Client closed]
califax has quit [Remote host closed the connection]
califax has joined #openscad
<HimeHaieto>
inphase: the simple-but-could-still-be-done-better solution - in (openscad's) src/cgalutils, function applyOperator, the boost_foreach could be made to instead be done by t threads, with each thread starting from child element 0 <= i < t, repeatedly applying the operation to the child t elements later, then have the main thread combine all the t results afterward
<HimeHaieto>
not the most optimal use of the threads, but should be really easy to code
<HimeHaieto>
however, first I'd prolly want to check to see whether your most expensive unions are generally with large numbers of children (of any size), or small numbers of large children...if it's the latter, then the above may not help you much
<HimeHaieto>
I don't really know, but I suspect the latter may be more likely for the most expensive of unions, so I wouldn't get too excited about the notion...it was just something I noticed about the simplistic style when perusing the code
teepee_ has joined #openscad
teepee has quit [Ping timeout: 255 seconds]
teepee_ is now known as teepee
fling_ has joined #openscad
fling has quit [Ping timeout: 255 seconds]
fling_ is now known as fling
lf94 has left #openscad [WeeChat 3.8]
aiyion1 has quit [Remote host closed the connection]
aiyion1 has joined #openscad
<InPhase>
HimeHaieto: Yeah, as design complexity goes up the portion of time occupied by the top level union also rises, and seems to rapidly reach the point where anything you do that doesn't improve that makes no difference.
<InPhase>
HimeHaieto: One can certainly speed up the more ordinary designs in a manner like you describe, and that IS useful. It means everybody spends less time waiting for the kind of work most people are actually doing. But to push the complexity envelope, that seems to all be hiding at the top level union.
ur5us_ has quit [Ping timeout: 260 seconds]
<HimeHaieto>
inphase: I'm not sure if we're on the same page - as far as csg trees are concerned, I was already aware we were talking about the final unions at the top - what I don't know is, for those typical larger projects, what those unions look like
<HimeHaieto>
if on the internal code side there's only two very large/complex polyhedrons to union and it takes really long, spreading out across multiple threads *before* calling into cgal won't help since there's only one call to make into it, but if there's 100 polyhedrons to work on, then it could make a large impact
<HimeHaieto>
get two threads going, and they could each union 50 of them, then one final union, and overall it'd take nearly half the time...easy enough to see
<HimeHaieto>
I'm not sure if or how often that's actually the case though vs having very few or even just two shapes, which would be important to know before anyone would consider such an external-to-cgal mt solution
J23511 has joined #openscad
J2351 has quit [Ping timeout: 260 seconds]
<InPhase>
HimeHaieto: https://bpa.st/5A3PO Here's a little benchmark script you can use.
<InPhase>
HimeHaieto: Make sure to do Design, Flush Cache, before each render. You'll really quickly see that the one and only determiner of asymptotic performance is the total facet count that goes into the top level union.
<InPhase>
HimeHaieto: You can try different modifications of that if you have different ideas, but this is typically a pretty good predictor overall.
<InPhase>
The 20+i is to make sure each sphere is different, to avoid caching spheres.
<JordanBrown[m]>
I was playing with a different benchmark, and see some interesting behavior.
<JordanBrown[m]>
https://bpa.st/P5VMW is a straight top-level union of eight sphere.
<JordanBrown[m]>
It spends all of its time at 999 of 1000, in the final union.
<InPhase>
JordanBrown[m]: I have the explicit union() just in case people have lazy union turned on.
<JordanBrown[m]>
OTOH, if you uncomment those "union" lines, so that it's pair-wise, it spends time at several steps, and relatively little at 999/1000.
<JordanBrown[m]>
The total is the same, but the distribution of where it spends time at the various counts is very different.
<JordanBrown[m]>
That suggests, maybe, that the pairwise one would get a significant win from parallelization.
<InPhase>
JordanBrown[m]: I got the same both times in 2022.01. Did you flush caches?
<InPhase>
Both were 3.2s for yours.
<InPhase>
2021.01
<JordanBrown[m]>
Same total time, yes. (And it's 14s for me, sigh.)
<InPhase>
We really need a new release soon.
<JordanBrown[m]>
But watch the progress bar.
<InPhase>
Ah, I see your point on that.
<InPhase>
But yes, it is distributed better.
<JordanBrown[m]>
I'm testing in 2021.01, so no fast-csg.
<InPhase>
It would require balancing by facet count.
<JordanBrown[m]>
Even stupidly pairing off would presumably be an improvement.
<JordanBrown[m]>
When you parallelize the pairs, that is.
<JordanBrown[m]>
That is, you do 1+2, 3+4, 5+6, 7+8 in parallel, then 12+34, 56+78 in parallel, then 1234+5678 single threaded.;
<InPhase>
JordanBrown[m]: Even more interesting variation of yours... I tried shuffling the order, mixing 0/4, 1/5, 2/6, 3/7. That actually put back a little more time focus on the top level union. It was BETTER distributed when overlapping parts were unioned EARLIER when the facet count was smaller.
<InPhase>
But it retained the same total time either way.
<JordanBrown[m]>
It surprises me a little that it's the same total time either way, but what's important is that the distribution of time at the various progress points suggests that the time isn't all in the final union, suggesting an opportunity for parallelism.
<InPhase>
But basically, parallelizing optimally requires attempting to construct similar facet count unions in a render tree structure favoring adjacency toward the leaf.
<JordanBrown[m]>
Sure. But stupid might be a significant improvement without needing to be fancy.
<JordanBrown[m]>
Presumably this applies to any union anywhere in the model, that you want to do a union of ≥4 things as multiple pair-wise unions.
<JordanBrown[m]>
Also: even without parallelizing, it might improve cancel-ability.
<InPhase>
It's a good bet that sequential items in the csg tree are more likely to be overlapping, so the stupid approach wins here.
<JordanBrown[m]>
Yes.
<InPhase>
Also, that's an easy thing to target if one really wanted to optimize a design.
<JordanBrown[m]>
I want an "always flush caches" mode, so that I don't have to keep remembering to do it.
<InPhase>
lol, yeah. For testing purposes.
<InPhase>
Actually "disable cache" might be nice.
<InPhase>
Horrible to leave on by accident. But handy.
<InPhase>
It would be worth it sometimes to disable it within run as well.
<JordanBrown[m]>
Maybe, but only maybe, because arguably you want intra-model caching.
<JordanBrown[m]>
You defeated intra-model caching by changing the size; I defeated it by changing the face count.
<InPhase>
There have in fact been cache bugs from within model collisions.
<JordanBrown[m]>
Hmm. Pair-wise unioning might get a dramatic speedup from intra-model caching.
<InPhase>
They're typically pretty easy to prove once you recognize them. But turning it off would be a great validator of cache bugs.
<InPhase>
JordanBrown[m]: Not with your plan of doing them in parallel! ;)
<JordanBrown[m]>
True.
<InPhase>
But maybe if you have enough of them to beat the thread pool size.
<JordanBrown[m]>
Rather to my surprise, I don't see a performance win from pairwise union of identical cylinders.
<JordanBrown[m]>
I would have expected that after 1+2, then 3+4, 5+6, and 7+8 would have been free. Similarly, I would have expected that after 12+34, then 56+78 would be free.
<JordanBrown[m]>
I wonder whether it doesn't recognize that they are identical because they are translated differently.
<JordanBrown[m]>
Translating them pairwise, so that 1+2, 3+4, 5+6, 7+8 are all identical, and similarly 12+45 and 56+78, got me a slight win, ~15%.
<InPhase>
Yeah, the cache is pretty mindless.
<InPhase>
It does a string lookup.
<InPhase>
You'd need to take your 4*dx and 5*dx translated ones and move translate 4*dx out of the union, and then the cache should pick it up.
califax has quit [Remote host closed the connection]
<JordanBrown[m]>
Right, that's what I did, and got a 15% speedup. Which seems like less than it should have been, given the distribution of the time in the progress reporting.
califax has joined #openscad
<JordanBrown[m]>
It might also be interesting to do some analysis with my geometry-as-data build, where with the render() function I can create the intermediate polyhedra and reuse them, without bringing caching per se into the picture.
guso78 has joined #openscad
<HimeHaieto>
jordanbrown, I modified your test a bit to make it more intensive (seconds is way too fast), and for a run that was 2m 56s, I got it down to completing in 1m 45s
<HimeHaieto>
that is, your original paste (with modified params) ran as is, vs with 4-thread "parallelisation" (simulated)
<HimeHaieto>
about half the time...not bad for not even actually doing anything at the real root of the problem (cgal)
<JordanBrown[m]>
That's with eight identical octagons, so that caching can help?
<JordanBrown[m]>
er, polygons.
<JordanBrown[m]>
I'm working octagons on another projects and so have them on the brain.
<HimeHaieto>
I'm honestly not entirely sure what you're referring to regarding the caching bit
<HimeHaieto>
the "simulated" part was simply taking each pair of cylinders and putting them in their own files, timing them all rendering to separate stl outputs, then running a pair of additional scad files each importing a pair of the first phase's output and unioning them, again to separate stl output, then a final phase doing the same again
<JordanBrown[m]>
OpenSCAD has a rendering cache. I'm not sure of the details, but in some fashion it recognizes subassemblies that it has rendered before, so that it doesn't have to render them again.
<HimeHaieto>
also, technically polygons are 2d, polyhedrons are 3d
<JordanBrown[m]>
It's why when you press F6 twice in a row the second one is fast.
<HimeHaieto>
I don't use that fancy pants gui crap all you kids rave about these days
<JordanBrown[m]>
Yes, I know. And yes, I misspoke - I was thinking only of the "base shape" of the cylinder, not the cylinder itself.
<JordanBrown[m]>
If you did parallelism work for your PhD, I'm probably old enough to be your father :-)
<HimeHaieto>
my invocations look more like `openscad --render -o uniontest-phase1-thread1.stl uniontest-phase1-thread1.scad`
<HimeHaieto>
so I don't think the cache stuff you're referring to here even applies in my case
<JordanBrown[m]>
I don't think there is any run-to-run caching; it's only intra-process.
<HimeHaieto>
could still stand for a lot more than 2x speedup with 4x processing threads if tackling it more properly within cgal though
<HimeHaieto>
but otoh...2x speedup is 2x speedup...
* HimeHaieto
shrugs
<JordanBrown[m]>
Indeed.
L29Ah has quit [Ping timeout: 252 seconds]
<JordanBrown[m]>
Depending, of course, on the details of the model in question.
<HimeHaieto>
well your test is pretty artificial, not sure about typical scenarios or if they might be any better or worse
ur5us_ has joined #openscad
siege has quit [*.net *.split]
wolfdeity[m] has quit [*.net *.split]
zauberfisch has quit [*.net *.split]
mohnish has quit [*.net *.split]
siege has joined #openscad
mohnish has joined #openscad
zauberfisch has joined #openscad
wolfdeity[m] has joined #openscad
ur5us_ has quit [Ping timeout: 248 seconds]
teepee has quit [Ping timeout: 255 seconds]
teepee has joined #openscad
castaway has joined #openscad
use-value has joined #openscad
SamantazFox has quit [Killed (NickServ (GHOST command used by SamantazFox_))]
SamantazFox_ has joined #openscad
linext__ has joined #openscad
vsellier_ has joined #openscad
vsellier has quit [Killed (cadmium.libera.chat (Nickname regained by services))]
vsellier_ is now known as vsellier
Alexer-_ has joined #openscad
veverak1 has joined #openscad
InPhase_ has joined #openscad
leptonix_ has joined #openscad
leptonix has quit [*.net *.split]
linext_ has quit [*.net *.split]
greenbigfrog has quit [*.net *.split]
paddymahoney has quit [*.net *.split]
lostapathy has quit [*.net *.split]
InPhase has quit [*.net *.split]
veverak has quit [*.net *.split]
Alexer- has quit [*.net *.split]
gbruno has quit [*.net *.split]
alexises has quit [*.net *.split]
Ekho has quit [*.net *.split]
Ekho- has joined #openscad
gbruno has joined #openscad
gbruno has quit [Changing host]
gbruno has joined #openscad
fury999io has joined #openscad
greenbigfrog has joined #openscad
alexises has joined #openscad
paddymahoney has joined #openscad
fury999io has quit [Client Quit]
lostapathy has joined #openscad
guso78 has quit [Quit: Client closed]
einichi[m] has joined #openscad
Igor2 has joined #openscad
<Igor2>
hi
<Igor2>
I have a question/idea (maybe feature request) bit I am not wollong to have a github account for this, is it a suitable place to ask/discuss it?
<Igor2>
(I mean is this channel a suitable place for that)
<teepee>
yes
<Igor2>
thanks!
<Igor2>
I amusing openscad for mechanical design, with two layers
<Igor2>
first I have a bunch of part designs, then an "assembly drawing"
<Igor2>
the "assembly drawing" basically has a bunch of use <> on the part designs and puts them together
<Igor2>
and that's where my problem starts, putting them togehter: it's real common that I have a mounting hole on one part then another on another part and what I really want is to have these two at the same coords
<Igor2>
I bet this is a common problem
<Igor2>
in simple cases, when I have only two parts, I can arrange that the origin of each part is at the mounting hole
<Igor2>
but in a more complex case, when a chain of parts are assambled so one part has two such "point of interactions" it's not really possible
<Igor2>
it would be obviosuly very useful in this situation to have some sort of query() that could return the coordinates of a specific object within a part model, but I think I understand why that's not possible in a declarative language
<Igor2>
however, I was wondering if there could be a workaround, a cheat:
<Igor2>
some kind of a render_this_temporarily() kind of operation that would run a module without making any modificaiton to the current model/world, just to be able to query geometry
califax has quit [Ping timeout: 255 seconds]
califax has joined #openscad
L29Ah has joined #openscad
<Scopeuk>
there is nothing currently to do it although there is some work ongoing (text metrics being the starting point in the snap shots) it becomes a tricky issue with none trivial shapes to define a boundary box
<Igor2>
I see
<Scopeuk>
what I have seen people do is define a function along with their module at time of writing that returns that information
<Igor2>
thanks, I thought of that, but there's an issue
<Scopeuk>
obviously that does depend on manual effort to create that function and maintain it but it is local to the geometry
<Igor2>
actually for this part-assembly thing it's not the bounding box that I'd need but the "base point"
<Igor2>
so the problem is I have the mounting holes behind some transformations
<Igor2>
nested translate() rotat()'s across modules
<Igor2>
and that's what I don't want to manually undo
J23511 has quit [Ping timeout: 260 seconds]
<Igor2>
so if I could just extract the 3d point where all those transformationms ended up right before the object is created....
<Igor2>
(or extract the transformation matrix at that point deep down in the transformation nesting)
<Scopeuk>
ok, what I have done personally is be careful over where I leave my origin to minimise that effort, i.e. all of my parts have the mating face set at 0 in an axis
<Igor2>
yup, works for a part with a single such point, but doesn't work well if I have multiple points far away
<Scopeuk>
agreed
<Scopeuk>
it is a language limitation and is something a lot of people would like
<Igor2>
yup
<Igor2>
that's why I was thining about this dummy "render" thing
<Igor2>
query(result) { module_call(); }
<Igor2>
then somewhere in the callee module I'd have a $result=whatever_value_I_extract_in_the_middle_of_the_code;
<Igor2>
and then a simple function that I could call and retruns current coords or transformation matrix
<Igor2>
then I could do something like this at the end:
<Igor2>
(well, not precisely this, but something like this, structurally)
<Igor2>
oops, s/foo/part/
<Scopeuk>
another possible option would be to separate your rotations/translation into a separate module with a child call at the bottom so you can re-use it. I'm not sure if I have your use case completely straight in my head for this model
<Igor2>
I really need the inverse transformation!
<Igor2>
so imagine a part that's a rod-like thing, a supporting struct, but with complex shape
<Igor2>
it has two joints and in the assembly drawing will be sitting between two other parts, linking them together, so I have a "chain" of three parts at the end
<Igor2>
I can put one of the joint points in the origin so I can transform this rod-like part to connect to the base properly, but then how do I make the 3rd part join to the other joint of the rod without knowing where that point is?
<Igor2>
for real simple cases I could pass that as an argument, "how long the rod is" kind of thing
<Igor2>
but that doesn't really work for complex shapes
<Igor2>
I have a model now with a brick-like center assembly and 7 chassis sides, each rather complex shapes
<Igor2>
and each chassis side would need to be mounted with scres onto the brick, and I obviosuly want to have the holes on the central brick and the chassis plates aligned up...
<Igor2>
I can come up with different ways where I should specify the coords/offsets of the holes and how to get them to the different parts and how to make the transformations right, but really, these all feel like ugly workarounds to the natural solution of "put it the same place where it is on the other module"
juri_ has quit [Ping timeout: 246 seconds]
<Scopeuk>
so another option that comes to mind would be to add a children(); call in your module (after all your transforms) which would let you do myMoudle() anotherModule() and have another module placed as if it existed where the children call is. other than that all I can say is it is a limitation and one a lot of people would like to see addressed but
<Scopeuk>
people run into the same issue of how do you define these points etc. it's difficult for a specific case at times and very difficult for the general case
juri_ has joined #openscad
<Igor2>
well, I thought that "render this off-world" operator would be generic enough
* Igor2
is trying to figure how this children() idea would work
<Igor2>
wouldn't that be limited to only two modules put togehter?
<Scopeuk>
module moduleWithChildren(){
<Scopeuk>
cube([50,10,10]);
<Scopeuk>
children();
<Scopeuk>
rotate([90,0,0]) translate([15,10,20])
<Scopeuk>
}
<Scopeuk>
moduleWithChildren() {
<Scopeuk>
cylinder(d=10,h=20);
<Scopeuk>
rotate([90,0,0]) cylinder(d=10,h=20);
<Scopeuk>
}
<Igor2>
tanks
<Igor2>
I think it works only as long as I have only one special point
<Igor2>
or I could probably do a narrower thing chan children()
<Igor2>
chidlren(1), children(2), etc for the different mounting holes
<Igor2>
but that also means I have to decide where the holes go in the assembly drawing I think
<Scopeuk>
it is only a partial solution, but you could use the indexed version to place something on each "anchnor"
<Igor2>
which is similar to simply passing on a vector with the coords
<Igor2>
(one of the solutions I meant above as a non-nice workaround - thing defined the wrong place in the model hierarchy)
J23 has joined #openscad
J23 has quit [Client Quit]
J23 has joined #openscad
teepee_ has joined #openscad
<teepee_>
oof, distracted by phone call... trying to catch up :)
<teepee_>
different libraries have some means for attaching stuff
<teepee_>
but the object proposal might bring some native means by making it possible to declare attach points and similar things
<Igor2>
attach points deep down within transformatins, or attach point outside on top level as coords?
teepee has quit [Ping timeout: 255 seconds]
teepee_ is now known as teepee
<teepee>
of the object
<teepee>
it remains to be seen if that actually works for the common cases
<teepee>
I did not have the time to really toy with the prototype implementation
<Igor2>
yup, but I mean is it just some property of the object I define in generic scope, or is it a mechanism that gets me the calculated coord under a translate() rotate() mirror() chain?
<Igor2>
because that's my real problem
<Igor2>
module does transformations then calls another module which makes further transformations and in the bottom of all this I would like to get the current coords or transformation matrix; then how I get it out to the caller is another problem; so question is whether attachment point solves the "how to get the coords deep in the transformations"
<Igor2>
or the "how to get it out to the caller" or both
<J23>
sounds difficult as the first module doesn't know about the position of the children() and the children doesn't know about the parents position - so you can implement a variable that is forwarded and the last children() would display the result
<teepee>
there's no call chain query and I'm not sure it's needed
<Igor2>
any comment on my off-world-rendering-for-query idea?
<Igor2>
J23, thanks, but this again would force me to define the attachment points centrally, which I'd like to avoid (that's why I was after some sort of query)
<J23>
how is that centrally ?
<Igor2>
maybe I misunderstood it, moment
<J23>
However best practice is to use an array with the coordinates of the holes then for(i=coords)translate(i) hole();
<Igor2>
ohh, ok you are right, it does solve the query half of the problem! (the getting-it-out problem is another thing)
<Igor2>
yup, that would be the centrally-specified approach
L29Ah has quit [Read error: Connection reset by peer]
<Igor2>
ok, so this example wraps transformations and keep track on them manually in a variable in parallel to the real transformations, nice
<Igor2>
teepee, thanks, checking that too
<J23>
you can only display it to the console but you can't get that variable from the childrens scope back to the top level ( i also wished sometimes this would be possible)
<Igor2>
yup, that's what I proposed this "off-world-rendering" thing for
<Igor2>
that would solve the bring out part by doing a nested rendering of the module and then discarding all primitives (but brining out a variable)
<J23>
you normally can solve this by using a function instead of modules
<Igor2>
but can they render objects in a next call?
<J23>
so instead of chain modules you chain the function and work with the coordinates at toplevel to translate
<J23>
in the end these are all multmatrix operations
<Igor2>
I thought function couldn't create a cube()
<J23>
they can create the position and they can generate points (which then can be used with polyhedron() ;)
<Igor2>
hehe, sounds complicated
<Igor2>
I mean compared to the natural solution of "draw your parts as easy as you can then glue them together at attach points"
<J23>
if you haven't done this - yes .. i have some library parts to make it bit easier - but you need to get used to work with that kind of data
<Igor2>
or maybe I would just use your original idea with that Move(), extending to other transformations, and add a layer around the whole thing outside of openscad
<Igor2>
yup, only if I had the inverse of that, an echomatrix!
<J23>
what is it you try to archive in the end - what should the result be?
<Igor2>
I have a few parts I design separately, and they end up how they end upm with attachment points randomly distributed, not getting them from some kind of parent
<Igor2>
I try to have an "assembly drawing" where I take a few of these parts and glue them together at their attahcment points
<J23>
people often try to bend openSCAD as they are used to different programming styles .. if so there are some translation so you can use openSCAD with python or js
<Igor2>
one part typically have multiple attachment points so I can't simply cheat and say I draw the part "with its attachment point at 0;0;0"
<Igor2>
I think it's more like bending it by the mechanical engineering use, hehe
<J23>
iirc the bosl libray also uses that alignment methode
<Igor2>
btw, yes, I had that thought above: take the part file run it separately (using a shell script) and somehow extract attachment point coords and generate an accompanying scad script with those
<Igor2>
then the asm drawing can include/use the part scad and the generated attachment point scad together to know how to attach it
<J23>
so as example you have a module creating a gear .. and you can call this module with the "anchor" to center the gear an its axle or put the gear connection on [0,0]
<Igor2>
yeah, but that's again "one anchor"
<Igor2>
I mean I create the gear once, with one anchor
<Igor2>
but what I am after is creating an instance of the part that ahs more than one anchors and I do want to use more than one anchors
<J23>
it is like the center variable - so for each instance you decide the alinement of that part
<Igor2>
imagine a chain of 3 objects, in the engineering sense, not in the programming sense; the middle object will have 2 attachment points
<Igor2>
then I go and increase the size of the middle object -> attachment points move -> other objects move
<Igor2>
but I don't want to have a hierarchy where the middle object is the root and the other two are children because that won't work on a chain of 4 objects
<J23>
well you normaly have the size variable at top level so the other parts are controlled for there ..
<Igor2>
(in my current design my "chain" is of 8 objects)
<Igor2>
yup, that's what I want to avoid
<Igor2>
it's really not practical on an assembly drawing
<J23>
however you can do this with children ($index) meaning the you can say which children should be aligned to which anchor
<Igor2>
but your idea (generalied for all transformations) and exteran scripts that generate atatchment point vectors could work
<Igor2>
would that work without the middle of the chain having to be the parent of the other two in some operation?
foul_owl has quit [Read error: Connection reset by peer]
<Igor2>
hmm, in an abstract sense, this enforces how parts are attached so an "overspecified"/contradicting hierarchy couldn't be done
<J23>
either hierarchy or calculation at top level - there is not much you can do .. except using some drag and click mouse software
<Igor2>
or except the other idea I had above...
<Igor2>
(with the external script to generate attachment coords)
<J23>
this is doing the calculation at top level just with extra steps
<Igor2>
ok, so the generic version of your latest idea would be like this:
<Igor2>
I design the part with, say, 4 mounting holes where I want the 4 attachment points, so next to each mounting hole object, within their transformation, I also add a children() call
<J23>
if you check the racetrack from scadvent you see how you can assemble recursively things
<J23>
which would be more difficult at top level
<Igor2>
then if this part ends up a "center" object in the random hierarchy I build at the top level (assembly drawing) I can refer to these attachment point by passing on children objects (module calls of other parts) and I could have an empty module for the case where I don't want to attach anything
<Igor2>
I think this could work, there's one problem I foresee: my part is not a single module but multiple modules in nested call, I wonder how I would "pass" children down
<J23>
here slight modification to use only available modules https://bpa.st/DFVXS
<J23>
but you can add an array to specify which children should go to which attachment
<Igor2>
this Track with its recursion is nice!
foul_owl has joined #openscad
<Igor2>
ok, I think I have a lot of input now, I appreciate your help!
<J23>
but you have animation so only the input thing is a bit tricky .. alt+arrow allows to change variables at cursor position
<J23>
(or alt+scroll)
<Igor2>
input: viewport $'s
<J23>
teepee did you noticed that alt+scroll only count up in both directions?
<Igor2>
$vpr, $vpt, $vpd
<J23>
yes and with some math you can also look at a target
<Igor2>
and when you reach some interesting point you can export an stl and print it, lol
<J23>
for art you can use random to generate objects with different parameter and put the seed out during the animation .. then you just need to pick the version you like
<Igor2>
hehe
<Igor2>
hmm, two more questions, different topic
<Igor2>
one is about mouse input: I use openscad a lot together with cura and it's annoying that the mouse bindings for rotation and zooming differ
<J23>
if you use some gamepad or 3D mouse you can set the axes mapping in preferences axes
<Igor2>
InPhase, my openscad is too old for this :(
<InPhase>
2021.01 runs it fine.
<Igor2>
I have 2019.something
<InPhase>
Okay, well 2021.01 is already pretty old. :)
<Igor2>
yeah, I know!
<J23>
hmm if you set scroll numbers to left mouse it counts up and down .. not if alt is involved
<InPhase>
Igor2: Oh, you're pre-function-literal. Yeah, that's too old to support. Function literals are essential now.
<Igor2>
hehe
<Igor2>
ok, so my last question (...for today): texture support in preview?
<Igor2>
I know I am abusing openscad, but.......
<InPhase>
The function literals here are used for a recursive function used to do the smooth view transitions.
<J23>
there was some shader thing for GSoC
<J23>
but not textures
<Igor2>
and no plan for textures?
<J23>
we don't even export colors ..
<Igor2>
I know
<Igor2>
it's only a preview thing
<J23>
for textures you need UV mapping
<Igor2>
my use case is rather special, really abusing openscad as a 3d render in this role
<Igor2>
yup
<J23>
sounds more like a blender job
<Igor2>
yes, or povray, but I really prefer openscad
<Igor2>
here's the background:
<Igor2>
I am the maintainer of an open source printed circuit design tool
<J23>
however you can generate texture as real geometry
<Igor2>
it's a rather UNIXy tool so I decided not to have 3d within my editor but rather rely on exporting 3d model and let other software, more specialized in 3d handle that part
<Igor2>
yup, I tried that but it didn't work out well
<Igor2>
imagine a 100*100 mm plate with a lot of copper traces running criss-cross
<J23>
here are different colored faces on the same object
<Igor2>
copper traces typically something like 0.2mm wide real thin thing
<Igor2>
I can export them as lines
<Igor2>
but openscad becomes very slow due to number of objects on a 100*100 mm board full of traces
Guest48 has joined #openscad
<J23>
what you now want performance too?
<J23>
.. render() helps
<Igor2>
so I made som experiments, including importing a pixmap as a height map, but that would require a huge map because of the typical 0.2mm trace width
<Igor2>
so that was not very fast either
<Igor2>
at the end, there are two main uses
<Igor2>
the more important is mechanical, where we don't need the traces just the plate with its whatever shape and holes in it
<J23>
as said just use color()render() Traces();
<Igor2>
but then the secondary use is "have a nice render"
Guest48 has quit [Client Quit]
<Igor2>
ok, let me read the doc on render()
Guest48 has joined #openscad
Guest48 has quit [Client Quit]
Guest48 has joined #openscad
<Igor2>
hmm, I don't think this render() trick is going to solve it, just makes it slow differntly
<Igor2>
(I've started openscad on the file and it's doing something at 100% CPU ... for 2 minutes already)
<J23>
yes it calculates the geometry .. which can then be used so doesn't require resources in preview
<Igor2>
clear
<J23>
some form of "baking"
<Igor2>
I think I really just have too many objects for this
snaked has quit [Quit: Leaving]
<Igor2>
(I also tried abusing polygons, generating all traces as a single big poly)
<J23>
after render is done - there is only one object .. with maybe a lot vertices
<Igor2>
yup, I will give it a few more minutes just to test it, but it's not practical for my use case, I mean users don't want to wait 10 minutes on load
<J23>
making it 2D can also speed up things .. and linear_extrude()
<Igor2>
yes, that was the poly approach
<J23>
if it doesn't change you can export it and import
<Igor2>
2d polygon, drawn in inverse (because 1 polygon can have only one positive island and many negative cutouts) and then extrude
<Igor2>
in the generic use case it would change all the time
<Igor2>
I mean it's not me having a board
<Igor2>
it's me having a software users want to use to export/render random boards they are working on
<J23>
i am using KiCAD
<Igor2>
yup, that's the most popular one
<Igor2>
I go for the niche market with mine
<InPhase>
Igor2: Traces should be done as 2D, then a single linear_extrude.
<InPhase>
Igor2: You really only need them ever so slightly extruded above the PCB color so that they are just barely visible as a different color.
<Igor2>
yup, I tried that, single polygon with tons of cutouts, was somehwta faster, but didn't cause a major speedup
<InPhase>
Igor2: Can you make the traces an svg?
<Igor2>
I could
<InPhase>
Then just import it, extrude, and done.
Guest48 has quit [Quit: Client closed]
<Igor2>
yeah, but how is that better than having a native openscad script with polygon()?
<InPhase>
Well workflow wise it might be simpler.
<Igor2>
I think it would be more complicated, becuase of multiple files
lkcl has joined #openscad
<Igor2>
simplest is when the export of a single board is a single scad file
<InPhase>
Well surely your traces are coming in from external files somehow anyway
<InPhase>
Either as numerical data or as an svg.
J23 has quit [Quit: Client closed]
J23 has joined #openscad
<Igor2>
no, no external file at the moment
<Igor2>
I generate an openscad script that contains the traces as 3d objects
<InPhase>
Well then you don't have a workflow so much as a model.
<Igor2>
I experimented with the multiple alternatives,one was generating a 2d polygon in openscad and extruding that
<InPhase>
A workflow would start with a PCB design, and then generate a model from it.
<Igor2>
yes, that's the workflow
<Igor2>
now, the initial problem is: rendering too slow
<Igor2>
with the 2d poly + extrude it was somewhat better but still slow
<Igor2>
you say svg+extrude - but why would that be faster than the poly?
<InPhase>
Did you render() on the 2D bit?
<Igor2>
nope
<Igor2>
maybe that was a mistake
<InPhase>
That's where you should do it, before the single extrude.
<Igor2>
ok, once this current experiment on the render() 3d() finishes, I will try that
<InPhase>
Performance wise, doing the render on the 2D should be equivalent to if you had done the svg import. The difference between those is only a question of workflow.
<InPhase>
Skipping the render on 2D can make the preview dynamics much slower though on a design like that.
<InPhase>
Doing the 2D bits separately and extruding them all separately can really slow down the preview dynamics.
<Igor2>
ohh, ok, thanks
<Igor2>
so if I have a 2d model that's not a single polygon object, but multiple whatever 2d objects
<InPhase>
Yeah.
<Igor2>
then I render() it and then I extrude, it should be (almost) as fast as if I had the single poly in render(), right?
<InPhase>
It will be equally fast.
<InPhase>
render turns it into one polygon object as a representation.
<Igor2>
(would make my life easier, this whole business of converting the traces into a negative polygon is a hassle)
<Igor2>
cool, thanks!
<InPhase>
Technically you are spending time doing the 2D render, but that should be trivial time, because it's 2D.
<Igor2>
and it can be done once, on load
<InPhase>
It will cache, yes.
<InPhase>
And render() says "do not do this again while reorienting the view".
<Igor2>
ok, I think I stop the other render() experiment, it ran 23 minutes already
<InPhase>
And if you have performance issues still like that, share the code so I can see where it's slow.
<Igor2>
thank you, I will (but that'll be another day, I don't think I will get there today)
J23 has quit [Quit: Client closed]
J23 has joined #openscad
<JordanBrown[m]>
Igor2: Going back a bit, children() or one of the library attach mechanisms based on it is the right approach to connecting components.
<JordanBrown[m]>
The objects proposal will allow you to get information out of a module, but I don't know how much it will help here, because we don't have any mechanisms to say "give me the 'real' coordinate for this point"... and even if we did, relative to what? You wouldn't really want "relative to the world", because then you couldn't manipulate anything built out of such a construct.
<Igor2>
I see
<JordanBrown[m]>
You could maybe imagine "relative to the module's origin", though that might be a little tricky too because there's not really any built-in notion of retaining the module's coordinate system when you're buried in additional levels of transformation.
<JordanBrown[m]>
Also, you'd need not only a coordinate but rotation, scaling, et cetera.
<JordanBrown[m]>
You'd need a transformation matrix.
<Igor2>
I could imagine this:
<Igor2>
I define a module in the assembly drawing and call all the parts from within that module
<Igor2>
so my reference coord system would be that modules coord system
<JordanBrown[m]>
The children() mechanism does mean that you need a root for your design, but that root doesn't have to be in the middle.
<Igor2>
and yes, I'd need the matrix, not the coord
<Igor2>
yeah, after thinking over, I realized that too
<Igor2>
in fact, it means a bit more
<Igor2>
in a generic setup you would optimally describe constraints
<JordanBrown[m]>
"all the parts"? Decomposed how far? You want subassemblies. You wouldn't want your overall design to have to position every component on every PCB.
<Igor2>
things like part1's attahcment point 4 is glued to part2's attachment pooint 8
<Igor2>
now if you ahve a lot of parts and a lot of such constraints, it works only if you take away exactly as many freedoms as each part has, otherwise the system is overspecified and can not be solved
<Igor2>
in a way the hierarchic approach solves that by forcing a fixed format that just doesn't allow more constraints
<JordanBrown[m]>
Yes, and in particular the children() scheme can only represent a tree; there can't be loops. Or, rather, ensuring that the loops connect properly is your problem.
<Igor2>
on the decomposing level queston: the assembly module could be used as a subassembly at a higher level
<Igor2>
yup, and that's exactly my problem with the children() approach!
<Igor2>
at the end it leaves some things to the old method, where I just look at the design and manually check if things lined up
<Igor2>
(things as in mounting holes)
<JordanBrown[m]>
Well, except that the real world imposes constraints that you either want to meet (by making the design flexible) or at least detect violations of.
<Igor2>
because I do have loops... I mean if you build a box out of sides plates, and you want to bolt them together, well, that's a loop
<Igor2>
sure
<Igor2>
some detections I can imagine, like once all parts are placed, pairwise intersection() should be empty
<Igor2>
this is again something that's not trivial with the strict-tree setup of children()
<Igor2>
so I am processing all the valuable input I got here and this idea of simply using an external script for extracting attachment points
<JordanBrown[m]>
If you have two components that attach to one another with two screws, you have to ensure that the second screw hole is in the right place.
<JordanBrown[m]>
Yes, the real world has loops.
<JordanBrown[m]>
I've used that technique, though it is quite tedious.
<Igor2>
exactly!
<Igor2>
at the moment I do all these manually, eyeballing the desing, which is... not good at all
<JordanBrown[m]>
Offhand, the guy I would ask about this is nophead; he does very elaborate designs of 3D printers.
<Igor2>
(and I have a lot more than 2 holes!)
<JordanBrown[m]>
PCBs, wiring, chains, frame, et cetera.
<Igor2>
does he visit this chan?
<JordanBrown[m]>
To respond to your original query... github is *not* a good place for questions. Here on IRC is OK, but you're sort of limited to whoever happens to be active at the moment. The mailing list is a better place to ask a broad group of people.
<Igor2>
btw, the external script could work real nicely, only if I could query/print/echo the current transofrmation matrix at a rnadom point in the script :/
<Igor2>
thanks!
<Igor2>
so far I am very happy with the quality of answers on this channel
<Igor2>
and for me it's a real good thing that I can just join here without any registration
<JordanBrown[m]>
We don't quite have 24x7 coverage on IRC, but it's close. By the time I'm going to bed, it's almost time for the guys in Germany to wake up. But of course most of the people have actual lives and jobs, and those can interfere with their OpenSCAD work.
<Igor2>
sure, in my project we have a similar (but smaller) IRC channel and the same considerations
<HimeHaieto>
seems like there's a hell of a conversation going here...I only glanced at a few points, but it seems like part of the problem raised by igor2 is verifying coordinates match for layers or objects otherwise meant to line up in given axes despite not being declared in the same scope?
<HimeHaieto>
you said something about eyballing the visual output as a workaround?
<JordanBrown[m]>
Yep.
<Igor2>
well, that's one side of it
<Igor2>
the other side is initial placement
<Igor2>
if I have 4 screws holding 2 parts together, both is going on
<Igor2>
I'd use 1 to specify coords to glue the two parts together and then check the other 3 if they line up
<HimeHaieto>
at least if you wanted a marginally better sanity check for that part, one thing I imagine that would be really easy to do while still being (more) precise would be...iono, to never directly use the translate function, ever?
<JordanBrown[m]>
It's kind of hard to position things without using translate().
<Igor2>
yup
<HimeHaieto>
like, declare your own translation function that performs the translate but also records the coords used
<JordanBrown[m]>
Well, I suppose you can just use only polygon() and polyhedron().
<Igor2>
yes, that's what J23 proposed
<Igor2>
I could track all transformations reproducing openscad's matrix in the openscad script
<JordanBrown[m]>
DIY transform functions can let you do some interesting things.
<HimeHaieto>
could if nothing else echo the results in a standardised way that would be easy to text process (awk!)
<Igor2>
(according to the doc I could even overload the original transformations keeping their names so it would be transparent)
<Igor2>
yeah, awk ftw!
<Igor2>
hehe, didn't expect to meet fellow awk fans here
<Igor2>
btw, I am also considering patching the code to have an echomatrix or something
<Igor2>
(that way I wouldn't need to reprodcue the whole transformation thing as an openscad script)
<HimeHaieto>
well, I once used a combination of things like cpp and awk to automatically generate code to dump internal data structures of code during runtime, so...I've done a few (unusual) things with awk
<Igor2>
nice!
<Igor2>
I also do unusual things with awk, maybe even too much of it
<JordanBrown[m]>
The current implementation in OpenSCAD doesn't actually know the transformation matrix while the program is running. The running program generates a CSG tree that describes individual transformations and operations. That tree doesn't get processed until after the running program is done.
<HimeHaieto>
actually, I say during runtime, but part of the code to do so is generated during compile time - so throw gcc in the mix there as well, along with some sql magic
<Igor2>
oh, I see
<JordanBrown[m]>
Not to say that it couldn't know.
<JordanBrown[m]>
It *could* track the matrix as the program runs, like my DIY transforms do, but currently doesn't.
<Igor2>
hmm
<Igor2>
I could maybe export to some format and extract it from there
<Igor2>
csg
<Igor2>
looks like some minimal parsing and matrix multiplications and marking the attachment objects
<JordanBrown[m]>
My guess is that the best approach is to have the higher-level assembly control attach points, and tell the lower level "you need to attach at these points".
<HimeHaieto>
meanwhile, here I am wondering why I can't make primitives with negative coordinates to have their size in that dimension extend to the opposite side of the plane produced from the other two dimensions
<Igor2>
yeah, but that's what I really want to avoid because the whole design proecss works the other way here
<Igor2>
I typically have constraints on each part that limits where I can put the attachment point
<Igor2>
local things
<JordanBrown[m]>
But as soon as you have loops, you need a global view.
<HimeHaieto>
as in "cube([-1, -1, -1])" equivalent to "translate([-1, -1, -1]) cube(1, 1, 1)"
<Igor2>
most of the time I am lucky and there are hard constraints only on one side, so it's most convenient if the attachment point is defined in that part
<Igor2>
yup, at the end I need global view
<Igor2>
but it doesn't feel practical to do these centrally
<JordanBrown[m]>
BTW, another difference between IRC and e-mail is that IRC doesn't scale worth beans; if there are two people with significant questions at the same time it's incomprehensible.
<Igor2>
I know
* Igor2
is ircing since 1999
<JordanBrown[m]>
HimeHaieto: I have a helper module jcube() that I like, that takes cube dimensions and a "justify" argument that is a vec3 of -1,0,+1 to negative-justify, center, or positive-justify on that axis.
<Igor2>
but then again, the support I got here today is excellent
<Igor2>
cool, I have a similar module
<Igor2>
this is one of the few things I don't like about the openscad language
<Igor2>
how cylinder is "centered" vs. how cube is centered
<JordanBrown[m]>
so jcube([10,10,10], j=[-1,0,1]) will give you a cube that is in -X, centered in Y, and +Z.
<Igor2>
I don't say I have a better idea, but this always felt a bit bumpy
<HimeHaieto>
the main thing I don't like about openscad is the lack of suitable alternatives that even fill the same role
<Igor2>
hehe
<JordanBrown[m]>
Sometimes I think that the default should be for everything to be centered, but then you'd have to do the math just to put the object at Z=0.
<JordanBrown[m]>
The bottom of the object, that is.
<HimeHaieto>
for some reason it seems rather unpopular among most people to programmatically do cad work in text files, despite the obvious advantages it can have for power and precision
<HimeHaieto>
nooooo to the default centering, omg
<HimeHaieto>
it sometimes has even annoyed me a bit that I can't make circles such that they're entirely in the first quadrant
banachtarski has joined #openscad
<HimeHaieto>
igor2's comment that it's apparently possible to override system functions with ones of the same name has me thinking that maybe I could actually consider overriding all the primitives to support those negative coords
<Igor2>
btw, if the center argumeng of cube() could be a vector, we could get jcube() automatically
<JordanBrown[m]>
Suitable alternatives to what, alignment or OpenSCAD itself?
<JordanBrown[m]>
There have been proposals to add a common alignment parameter akin to my "j" parameter, but they have stalled for two key reasons:
<JordanBrown[m]>
It's hard to see that it's OpenSCAD's problem that nobody else has seen the light :-)
<JordanBrown[m]>
2) It's pretty easy to DIY, so everybody does, so there's no need to put it in the base.
<JordanBrown[m]>
of course you can.
<JordanBrown[m]>
1) There are questions about exactly how flexible to make them. You can center, but can you also position the origin at the 1/3 point?
<JordanBrown[m]>
translate([r,r]) circle(r);
<JordanBrown[m]>
Yes, making center take a vec3 of some sort is a plausible candidate, though using the word "center" to left-align something is kind of weird.
<Igor2>
hehe
<Igor2>
yeah, I was just thinking about backward compatibility
<Igor2>
but probably it's a bad idea to overlod the same parameter name anyway
<JordanBrown[m]>
The hard part of positioning circles is that there are no circles. They are regular polygons, and so there are multiple definitions of what it means to position them.
<HimeHaieto>
without any further changes to existing code, I could, for instance, redefine "square([x, y])" to be "translate([min(0, x), min(0, y), 0]) square([abs(x), abs(y])"
<Igor2>
(similar to the problem I am addressing at the moment in my software about circle vs. polygon!)
<JordanBrown[m]>
You can redefine core functions and modules, but I wouldn't. Nobody would be able to read your programs.
<JordanBrown[m]>
And you might break libraries, if your versions were subtly incompatible.
<Igor2>
I generally agree - the exception is that idea from J23 to keep track on transformations
<Igor2>
but now I think I like the "mark object and export to csg and process csg with external script" idea better, sounds less less hassle
<HimeHaieto>
I'm the only one really expecting to read my own code, but would libraries really intentionally rely on the fact that any negative coordinate gets turned into 0?
<JordanBrown[m]>
Which of these two triangles is left aligned? r = 1;
<JordanBrown[m]>
translate([r,0,0]) circle(r=r);
<JordanBrown[m]>
Your redefined square() didn't process the "center" argument.
<HimeHaieto>
it also didn't include the keyword "module" anywhere...you wanted a full definition?
<JordanBrown[m]>
And next year when we add the "align=" argument, your redefined version won't support it. Or, worse, you will have defined it with an incompatible meaning.
<JordanBrown[m]>
The problem is that there are lots of features and behaviors, and if you don't duplicate all of them perfectly then there could be compatibility problems, and that problem extends into the future as the language evolves.
<HimeHaieto>
for when center = true, you'd simply not perform the translation and pass it to the original square call
<HimeHaieto>
it just seems so very odd and dare I say wrong even that negative values are ignored in a coordinate system for an environment like this
<JordanBrown[m]>
You do a DIY cylinder... does it select the number of sides in a compatible way? Does it position the vertexes in a compatible way?
<HimeHaieto>
I was so disappointed the first time I tried to do a "cube([x, -y, z])" :/
<JordanBrown[m]>
You *can* do it, for any particular feature set, if you figure out what all of the behaviors are that people might depend on. But that can be tough to do.
<JordanBrown[m]>
Negative coordinates are by no means ignored.
<JordanBrown[m]>
But negative dimensions are meaningless.
<JordanBrown[m]>
and cubes are not defined in terms of coordinates; they are defined in terms of dimensions.
<Igor2>
yeah, I don't like negative values not working in cube either
<JordanBrown[m]>
Also, that scheme doesn't generalize to support centering.
<HimeHaieto>
I already mentioned that, it's easy to just not do the translate if center = true, since the result would be the same as normal (the square would still use [abs(x), abs(y)] of course)
<JordanBrown[m]>
Right, but your left-justify / right-justify mechanism has to be separate from the center mechanism.
<JordanBrown[m]>
What would it mean to say that the X dimension is -5 *and* say that it should be centered in X?
<HimeHaieto>
also my comment about circles/cylinders was simply because I nearly never centre things, but as a result it can be a little more annoying when I'm working with say a mix of squares and circles and need them to be aligned properly with each other
<JordanBrown[m]>
What would cube([5,-5,5], center=true) mean?
<HimeHaieto>
but that's a minor annoyance, easy to work around, and having circles/cylinders/spheres centred at the x/y origin *does* actually make sense
<JordanBrown[m]>
But by all means define your own modules with the semantics that you like. I just wouldn't override the builtins to do it.
<HimeHaieto>
jordanbrown: it would effectively mean the exact same as "cube([5, 5, 5], center = true)"
<JordanBrown[m]>
That offends my sense of orthogonality.
<HimeHaieto>
how? "center" just refers to what happens to its positioning *after* being drawn
<JordanBrown[m]>
But like I said, if you like those semantics, by all means define a module that works that way.
<HimeHaieto>
if I draw a square in the third quadrant (square([-5, -5])), then centre the result on the origin, how does that not make sense or in any way conflict with drawing a 5x5 square anywhere else before getting centred on the origin?
<JordanBrown[m]>
I suppose that you could look at it that way, but since I don't think you can have a negative dimension I already had to interpret your negative dimensions as positioning instructions, so there are two sets of conflicting positioning instructions.
<JordanBrown[m]>
When I say "I don't think you can have a negative dimension", I mean "my definition of dimension does not allow for negative values".
<HimeHaieto>
math's definition of dimension does, and that's what's weird since openscad would seem to pride itself a bit on being more mathematically oriented, so to speak
<JordanBrown[m]>
Hmm. I'd have to ask of the of the mathematicians whether they think that you can have negative dimensions.
<HimeHaieto>
and negatives *are* still positioning, it's just that you're specifying a secondary positioning param that gets processed second
<JordanBrown[m]>
The ability to have a negative dimension implies the ability to have negative area, for instance.
<JordanBrown[m]>
Right, they're mixing dimensions with positioning, and I wouldn't do that.
<HimeHaieto>
well technically you *can* talk about negative area, but we're talking about a coordinate system here, which very much has negatives
<JordanBrown[m]>
Absolutely you can have negative coordinates. But I would contend that you cannot have negative dimensions.
<Igor2>
you could interpret it as: when center=false one corner of the cube is at [0,0,0] and you specify the coords of the opposite corner
<JordanBrown[m]>
You could. But when you set center=true it obviously *isn't* that.
<HimeHaieto>
here, let me help you a bit - even with normal openscad you're never really defining primitives with [] as "size" - in any other cad you could see the same thing...in librecad I can type "rectangle" then it asks for the first coord, then the second, and bam, the obvious happens
<HimeHaieto>
for openscad, you just implicitly always have the first coordinate at the origin, and primitive([coords]) is specifying that second coordinate
<HimeHaieto>
so...negative makes plenty of sense
<HimeHaieto>
"center = true" is just something nice and convenient that can happen afterward to translate the result as such
<JordanBrown[m]>
You could look at it that way, but then center=true doesn't make sense.
<JordanBrown[m]>
Also, it's defined to be the size. In fact, that's the name of the parameter.
<JordanBrown[m]>
You can say "square(size=[1,1])".
<JordanBrown[m]>
Nobody does, but that's the way it's defined.
<HimeHaieto>
sure center=true does...just as much as it ever did before
<JordanBrown[m]>
The cheat sheet says: square(size,center)
<HimeHaieto>
perhaps, but I fail to see what relevance that has to someone coming in and saying that seems wrong
<JordanBrown[m]>
You could certainly have a square() module that took coordinates, though I would consider it kind of weird if it only took *one* coordinate; if you're going to define a rectangle in terms of coordinates then you need two.
<JordanBrown[m]>
Well, OK, if you want to say "square should be defined in terms of coordinates instead of in terms of dimensions", then that would be a sensible position. I'd argue against such a primitive having a "center" option, though.
<HimeHaieto>
everything having the first coordinate at the origin is fine, but it would also be perfectly fine (and perhaps even a welcome change) if that were simply the default
<HimeHaieto>
"module...(first_coord = [0, 0, 0]" or something would be fine I think
<JordanBrown[m]>
You could, but that's redundant with the translate() operation.
<HimeHaieto>
also as far as centre goes, I might even tie it in to igor2's original lament and argue that what would might ideally be better is to not have any such params in the first place, but instead have it be a transformation that takes *any* number of children, finds the centre point, and translates as such
<JordanBrown[m]>
Anyhow, the great thing about a programmable system is that you can define an hhsquare() that has the semantics that you like.
<JordanBrown[m]>
That's actually harder than you might think.
<JordanBrown[m]>
It *can* be done, but it costs performance.
<HimeHaieto>
who cares about performance? all the performance is *really* being lost at the final unions anyway, right? ;p
<JordanBrown[m]>
My geometry-as-data work, which is part of the "objects" work (and, credit where it's due, is based on others' work before) does have that capability, but it needs to render the objects before it can determine the center.
<JordanBrown[m]>
Well, since you don't use the newfangled GUI with its preview mode I guess you don't care, but preview *is* a lot faster than render.
<HimeHaieto>
also I don't think finding the min and max coord values for each dimension across all points in a mesh, taking their difference, dividing by two, and translating by that amount is as hard as you make it seem?
<HimeHaieto>
impossible in openscad user code, but for the underlying implemenation that has all facet/point information?
<HimeHaieto>
seems pretty straightforward...?
<JordanBrown[m]>
The bounding box of the result is the union of the bounding box of the coordinates only if the only operation you do is union.
<JordanBrown[m]>
The bounding box of a difference or an intersection can be very different from the bounding boxes of any of the inputs.
<HimeHaieto>
oh, well I don't know about preview and any step-skipping one might attempt to do there...if the problem is not wanting to do the full calculation as in a render and somehow skipping some stuff, maybe that's where your caching stuff you mentioned could come in
<JordanBrown[m]>
Preview is over a hundred times faster.
<HimeHaieto>
preview shmeview :p
<JordanBrown[m]>
And that's for low-resolution spheres. With $fa=1 and $fs=0.5, preview is 0.12s and render is ... well, I'll get back to you with that when it finishes...
<JordanBrown[m]>
If you like waiting for renders to complete, well, OK... but I don't.
<InPhase>
JordanBrown[m]: fast-csg tends to win big in those cases. As it does here, getting 0.24s.
<JordanBrown[m]>
Is that for the low-res version or the high-res version?
<HimeHaieto>
I like being able to read code and know what it means without even needing a render to visualise it
<JordanBrown[m]>
Render of that high-res version finished, 2m50s. So, at least pre-fast-csg, preview is >500 times faster.
<JordanBrown[m]>
I can do that in simple cases, of course. But I would probably say that any case where I can read the code and be *sure* of what it will produce is a trivial case. Anything non-trivial requires testing.
<teepee>
workflow!
<InPhase>
That was for your paste. I'll try high res...
<teepee>
meh, is that bot still on vacation?
SamantazFox_ is now known as SamantazFox
<InPhase>
JordanBrown[m]: 1.0s for fast-csg and $fa=1; $fs=0.5;
<JordanBrown[m]>
I used to be an Emacs fan, back when it was real Emacs, before all of this namby-pamby LISP stuff, when it was written in TECO. But it was a pain to use on a keyboard without a meta key. Also, when I started using UNIX there was a vi on every system and if I wanted Emacs I had to port it.
<InPhase>
JordanBrown[m]: Preview is in fact faster, at 0.024s. But fast-csg is still fairly fast.
<JordanBrown[m]>
Yeah, that was going to be the next question, since your system is way faster than mine so the numbers can't be directly compared.
<JordanBrown[m]>
So preview is about 40x faster than fast-csg, for this particular test case.
<InPhase>
JordanBrown[m]: $fs=0.05; does fast-csg render in 12s.
<InPhase>
Preview is 0.17s So still a difference.
<JordanBrown[m]>
Pretty impressive, though I'd have to do the math to figure out how that changes the effective $fn.
<JordanBrown[m]>
You'd think that moving from $fs=0.5 to $fs=0.05 would be a 100x increase in sphere complexity, but at some point $fa is going to get you again.
<InPhase>
There were 11 times the final facets.
<InPhase>
But yeah, I expected 100 times.
<InPhase>
Probably $fa kicking in.
<peepsalot>
if i could figure out why I can't compile c++ anymore, and finish up the fmt branch, i really want to give it a try writing a CGAL number type with small buffer optimization
<peepsalot>
as an interface to lib GMP
<JordanBrown[m]>
The circumference of an r=10 sphere is 62, so with $fa=1 each side is about 0.166.
<peepsalot>
I also question if the added complexity of reference counting is worth it at the per number level, which CGAL's existing interface does
<JordanBrown[m]>
Then setting $fa=0.1 yielded ~1.6M.
<JordanBrown[m]>
And also yielded "node does not fit in cache" warnings...
<JordanBrown[m]>
For some reason preview starts being laggy at that point...
<JordanBrown[m]>
Preview of my ten-sphere test at fa=0.1 / fs=0.05 took 5s. I shudder to think what it would have taken to render. Seems likely to be a minimum of ~5 hours.
<JordanBrown[m]>
That's if it's only linear on the number of faces, and I bet that it's not.
<JordanBrown[m]>
But speaking of that four-letter word that interferes with my OpenSCAD work... I need to pretend to do some of it.
<Igor2>
thanks again for all the support and ideas, I'm heading out now
Igor2 has quit [Quit: good night]
teepee_ has joined #openscad
teepee has quit [Ping timeout: 255 seconds]
teepee_ is now known as teepee
peeps[work] has joined #openscad
banachtarski has quit [Ping timeout: 252 seconds]
<InPhase>
peeps[work]: Hello World also broken?
guso78 has joined #openscad
<peeps[work]>
dunno, at work for a few hours
banachtarski has joined #openscad
Ekho- is now known as Ekho
J23 has quit [Quit: Client closed]
J23 has joined #openscad
gknux has quit [Quit: ....and i am outta here....]
gknux has joined #openscad
ur5us_ has joined #openscad
TheCoffeMaker_ has joined #openscad
TheCoffeMaker has quit [Ping timeout: 256 seconds]
Lagopus has joined #openscad
<guso78>
just wondering, does the latest version in the master successfully compile on all platform or did something happen to the environment ?
<InPhase>
It does on the CI.
<InPhase>
And at least one person has compiled on every supported platform since then.
banachtarski has quit [Remote host closed the connection]
<InPhase>
We tend to hear about it pretty quickly if a platform breaks. And the CI check keeps us fairly reliably from merging things that flat out won't work on a given platform.
<HimeHaieto>
just a thought...are there any plans to maybe make offset work in both 2d and 3d?
<HimeHaieto>
just realised it's 2d only when I tried to use it for a box
<guso78>
ok,glad to hear:) I was just wondering, because i head some rumors aboua venv thing and in my place i dont see any action on the main repository for about 3 weeks now. probably i look into the wrong place XD
<guso78>
HimeHaieto, i am working on a 3d offset and it already works in ideal case.
<guso78>
but in order to merge it in, it need to work with all conditions
<HimeHaieto>
oh, cool, I imagine that could accomplish quite a lot
<HimeHaieto>
especially regarding fillets, as they seem to commonly be one of the bigger complaints against csg cad from what I've seen
<guso78>
HimeHaieto, actually i would really love to have working offset3d. Imagine, you could offset by -3 and then offset by +3 with round edges and you could round all your existing design!
<guso78>
and i have an exact plan how to make round offset once straight offset is workingf
<HimeHaieto>
my current use case was not even complicated but I still kinda wanted to maybe use it (just making a hollow box with offset instead of difference() between outer and inner dimensions
<guso78>
if you are careful with your settings, you can already benefit for offset3D. There is a PR to openscad/openscad with the required changges and its public.
<guso78>
just use the diffs and compile it locally :)
<guso78>
HimeHaieto, yes using difference between an object and its offsetted version has the advantage that that all walls have a fixed depth by design :)
<HimeHaieto>
exactly, no room for a typo like a missed metal_thickness or something causing the results to be wrong
<HimeHaieto>
mostly just a small safeguard or something
<HimeHaieto>
I'll be able to live without it for now though, for that simple use case at least
<guso78>
HimeHaieto, I realized you are mainly working on speedup openscad by making things parallel ?
SylvesterSneekly has joined #openscad
SylvesterSneekly has quit [Remote host closed the connection]
<guso78>
does anybody have use experience with Manifold library ?
<HimeHaieto>
guso78: I had a bit of an interesting discussion over that, but I wouldn't say I'm actually actively or necessarily likely to become actively developing anything of the sort
<peeps[work]>
guso78: if we did it would be implemented in OpenSCAD already :P
<guso78>
both peeps[work] and HimeHaieto refer to Manifold, right ?
<peeps[work]>
i was, yes
<guso78>
ok, i was able to create a cube in manifold, but i was not able to see it because i failed to export O:3 O:3
<HimeHaieto>
I'm not familiar with manifold
<HimeHaieto>
all I really did was confirm with a couple others here that we could get a fairly significant performance boost by taking a "dumb" approach to using multiple threads to divide and conquer the (top level only?) booleans of a csg tree
<HimeHaieto>
though even that was more of a hack really
<HimeHaieto>
if you really want to improve performance, most likely the place you'd really want to look to the most is cgal
<HimeHaieto>
we just used the opportunity to prove how great even a modest lower bound of performance improvement potential there was, even without needing cgal to pick up the work for it
<guso78>
opencsg has the advantage that its faster with small csg trees but display might only be 99% perfect. cgal has the advantage that its faster for huge csg trees, but you might have to wait for 1m minute to compile on each change :)
<HimeHaieto>
one single minute is nothing, if that's all that's at stake I wouldn't personally be worried too much
<HimeHaieto>
certainly nothing like coming back the next day to check up on it and seeing it's 40% done
<HimeHaieto>
after having worked with so many bigger/more intensive things (even *with* the benefits of parallel/accelerated performance), something like a single minute kinda feels like kiddie hour
<HimeHaieto>
I recognise that many feel rather differently though
<HimeHaieto>
for me though, come back to me when we're talking at least 30+ minutes, and maybe it'd be worth a little more time lol
<guso78>
HimeHaieto, appears that you are used to wait for long time
<guso78>
My attitude is that i like to do many incremental tests and want to see the result immediately. this i why i appreciate any speedup :)
<guso78>
teepee, FYI right now i am trying to implement Face scanning algorithm (aka like scanning algorithm) from scratch. I just to try to *walk" a cube which has neither face parallel to x/y/z . its tough
<teepee>
for which user side feature is that?
<guso78>
i believe if i get this working , this would be more reliable than the famous face-front/face-back algorithm because my the face-scanning algorithm can easily handle face-open+face-close at the same place
<guso78>
my intent is that i can use this to "polish" the offset result, but its also to challenge to myself if i can do it.
<teepee>
oh, so instead of the current preview CSG stuff?
<teepee>
fwiw there's some interesting sounding stuff out there coming from the gaming area - they called it real-time-csg
<guso78>
teepee, no its just for my challenge and for offset. no idea how far i can get
<teepee>
ah, ok. it does sound like an interesting challenge
<guso78>
yep . i know the line scanning algorithm very well from chip design. it only 2D there and i have actually implemented the algorithms of PVS there :)
<guso78>
teepee , do you think it would make sense to merge the latest changes of main branch into the python-support branch ?
<teepee>
for anything specific? I tend to think it's mostly good to go with both compiletime and runtime switch
<guso78>
teepee, just to keep up-to-date. in python-support there is already a compile time and runtime switch AFAIK
<HimeHaieto>
guso78: cheap processor, few cores or something?
<teepee>
yes, that's what I meant, as it's disabled by default it should not affect people unaware and after merge it's easier to get the builds sorted
<guso78>
HimeHaieto, i believe my pc was cheaper than my graphics card, less than 300 USD. I once bought a expensive grapics card, because i like the CURV tool from Doug Mouen(did i spell correclty) ?
<teepee>
moen I think
<guso78>
teepee, yes you are correct, but i see that python-support is out of date, especially it does not contain the latest additions about venv ...
<teepee>
yeah, but there's no conflict, so it should simply merge to master without issues
peeps[work] has quit [Quit: Leaving]
<teepee>
I just need to find some time to understand why there's some test result differences again
<teepee>
although the images really look identical at first glance
<guso78>
teepee, i would be glad if you could sync, every 2 weeks or so .
<HimeHaieto>
oh wow, a $300 computer...yeah, I think that would struggle with just about anything
snaked has joined #openscad
<guso78>
teepee, the results from curv really look impressive, i am really curious if openscad could get a "curv" primitive :)
<HimeHaieto>
here I had considered my current (and by now quite old) machine a bit of a "budget build" of its own, at merely $5k XD
<teepee>
curv primitive no, but I don't see any reason why it would not be able to handle SDF
<teepee>
after all there's a variant already doing that :)
<guso78>
an openscad fork ?
<teepee>
no, separate implementation in Haskell
<HimeHaieto>
funnily enough, the long awaited upgrade is actually what brought me into using openscad, to design a new custom chassis for it
<guso78>
implicitcad ?
<teepee>
yes, there's some compatibility on the scad script side
<teepee>
also someone implemented an openscad -> glsl translator
<guso78>
hmm. beeing based on an interpreter like hakell i doubt it has the the same performance like a natively glsl program
<teepee>
I suppose that would not handle minkowski but the normal csg operations do translate
<teepee>
yes, different goal, one producing mesh output, the other screen display
<teepee>
just saying the openscad language is only tied to mesh due to the use of CGAL
<guso78>
you wanted to replace CGAL by Manifold anyway once somebody understands, how to use it haha
<teepee>
the same language mostly works with other backends too, specifically SDF, but probably also with others like OCC
<guso78>
SDF - id dont know that, do you have a link/spec ?
<guso78>
again, i think its a good idea now to sync the latest changes of main into python-support. In the last 3 weeks you have introduced venv and a different image compare too. this might be the cause. can you please sync to see if i am right ?
<teepee>
I suspect those diffs actually came in by syncing the PRs
<teepee>
so this branch already includes some of those changes from master
<guso78>
i have see the image comparison in the link, but honestly: its 0:30 AM, got 2 beer already and i can't stand the "Find the 10 differences" challenge anymore ....O:3
<guso78>
teepee, yes, i did merge to master some time back and realized later, that its a bad idea
<teepee>
well, it not generally bad, it has good and bad sides, sometimes it's even needed to resolve conflicts
<guso78>
we could get it out of the way in any case if you merged latest main changes into python-support... but i know, i told it already ...
<guso78>
my git mentor told me to merge the base branch as often as possible. so in the end my branch will be abled to be merged back ...
<teepee>
it depends also on the workflow, if it's possible to have relatively short lived feature branches, it's not needed and you get a nice merge history
<teepee>
but as always in real world, things are not that simple :)
<teepee>
it's not a huge deal, my problem is simply that I still have a work backlog to resolve
<guso78>
got it.
<teepee>
and the weekend was occupied by a friend trying to rebuild some grave decoration using 3d printing after they stole the metal decorations
<teepee>
and doing the metalwork would cost about 25k€
<guso78>
did not want to stresss anybody. take your time to resolve the the issues in the right order:)
<teepee>
no worries, keeping the discussion going actually helps :)
<guso78>
FYI : i own an metal cast oven and i regularily use it to metal cast selected 3d prints(if they can demold properly in green-sand)
<teepee>
it's about 200 ~20cm big cylindrical thingies
<teepee>
wait, no, the bottom one was 18cm and the other ones 13cm
<teepee>
but still huge number stacked
<guso78>
this is why i like the roof openscad function so much. it enable so metal cast *ANY* SVG file to mold
<guso78>
need to take a break now.stressful day *today* need to re-energize now haha