teepee changed the topic of #openscad to: OpenSCAD - The Programmers Solid 3D CAD Modeller | This channel is logged! | Website: http://www.openscad.org/ | FAQ: https://goo.gl/pcT7y3 | Request features / report bugs: https://goo.gl/lj0JRI | Tutorial: https://bit.ly/37P6z0B | Books: https://bit.ly/3xlLcQq | FOSDEM 2020: https://bit.ly/35xZGy6 | Logs: https://bit.ly/32MfbH5
<kwikius> foo is either a module or a module_reference ( You can of course do module reference to module reference)
<JordanBrown[m]> points = [ for (x=[0:10:100], y=[0:10:100]) [x,y] ];
<phryk> mhh, that would work with a function definition too, right? so i can use function parameters in the list comprehension…
<JordanBrown[m]> Of course.
<phryk> great.#
<JordanBrown[m]> @kwikius so you are saying that you cannot have a module literal with an empty body. (You can have a traditional module like that.) But I would be worried that the parser - or a human reader - will not be able to tell the difference until it gets to a semicolon instead of an open brace.
fling has quit [Ping timeout: 258 seconds]
califax has quit [Quit: ZNC 1.8.2 - https://znc.in]
fling has joined #openscad
<kwikius> o = module {};
califax has joined #openscad
<JordanBrown[m]> Oh, wait, I misread your original example.
<kwikius> Note the semicolon ( like c++ class definition!)
<JordanBrown[m]> I read the first line as having a name between the word "module" and the open parenthesis.
<JordanBrown[m]> Which isn't there, of course.
<JordanBrown[m]> There has to be a semicolon at the end. It's an assignment.
<kwikius> You don't need it in array of course
<kwikius> shape_lookup = [
<kwikius>   ["cylinder", module(hgt) cylinder(d= 10,h=hgt,$fn = 20,center = true)],
<kwikius>   ["cube",module(side,side1) cube([side,side1,side], center = true)],
<kwikius>   ["pill", module {
<kwikius>       hull(){
<kwikius>          ts = module (z) {
<kwikius>             translate([0,0,z])sphere(d = 18,$fn = 50);
<kwikius>          };
<kwikius>          ts(10);
<kwikius>          ts(-10);
<kwikius>       }
<kwikius>    }
<kwikius>   ]
<kwikius> ];
aiyion has quit [Remote host closed the connection]
<kwikius> (don't need semicolon)
<JordanBrown[m]> You need the semicolon at the end, because it's what ends the assignment.
aiyion has joined #openscad
<JordanBrown[m]> In the middle, agreed, no semicolons, because there are no semicolons in list syntax.
<phryk> how do i build a 3d vector out of a 2d one? [2dvector, z] ?
J1A848624 has joined #openscad
<phryk> huh, don't even need that. translate works with 2d vectors^^
<InPhase> JordanBrown[m], kwikius: Modules cannot ever return values without it being a breaking change.
<InPhase> The decision about whether to look up a module or a function is made by usage context.
<kwikius> fwiw
<kwikius> function to3d(xyAr, z) = concat(xyAr,[z]);
<kwikius> r = to3d([1,2],3);
<kwikius> echo(r);
<InPhase> But you can always instantiate a module inside of an object literal. You just won't get access to the embedded values.
J1A8486 has quit [Ping timeout: 252 seconds]
<kwikius> in
<InPhase> phryk: For future reference, [each 2dvector, z]
<phryk> InPhase: cool, thanks. :)
<kwikius> in
<kwikius> x = module cube(size)x ;
<kwikius> No module is instantiated so I think it will work, but that is phase 2  and if I understand correctly what was said on github the original PR will never be merged anyway :)
<InPhase> kwikius: Which original PR?
<kwikius> ModuleLiteral, which I am working on. https://github.com/kwikius/openscad/tree/module_literal_v2
geoffder has joined #openscad
<JordanBrown[m]> @phryk: I like concat(vec2, z).
<InPhase> Well there's broad agreement we want module literals. Just keep in regular contact about design questions and such to make sure it fits a consensus for how they should operate, since this is going to be a major syntax change that we need to get right at first release.
<kwikius> I think it is syntax
<kwikius> x = module cube(size).x ;   is element x of some module cube. So yeah that is why you need module there !
<kwikius> x = cube(size).x    is presumably a function
<phryk> JordanBrown[m]: oh that looks more legible, too. :)
<JordanBrown[m]> that's why I prefer it :-)
<InPhase> Many things about the code we can fix up later, but syntax changes are the big thing that gets locked in and then dealt with for another decade or more as-is.
<InPhase> That's the whole reason JordanBrown[m] and I are bothering to discuss objects and dictionaries so carefully. Once it's in... it's in.
<JordanBrown[m]> When we say "module returns value", that's being fast-and-loose with terminology.
<InPhase> We can add features, but we can't take them away without a long deprecation period.
<kwikius> is presumably a function returning something with a member x
<JordanBrown[m]> I haven't really fully thought through the behavior of module references in expression context.
<JordanBrown[m]> Though perversely the problem is more with how you use a module reference in *statement* context.
<InPhase> JordanBrown[m], kwikius: Line 22 there, elem[2](height) should have probably also been an option that would work.
<JordanBrown[m]> Yes.
<InPhase> That will require some special parser support probably.
<JordanBrown[m]> That's exactly the case that I mean, using a module reference in statement context.
<JordanBrown[m]> yes
<JordanBrown[m]> because it's an expression
<JordanBrown[m]> if done really right.
<InPhase> "foo()()();" could be a valid module call if foo returns a function reference which returns a module reference.
<JordanBrown[m]> exactly.
<kwikius> I am pretty confident that
<kwikius> x = module cube([1,2,3]).x ;
<kwikius> should do what you expect and in fact it was the whole reason for doing this, because you can encapsulate data in a module and get access to it rather than have all that global data.
<JordanBrown[m]> And you could throw some parentheses and bracked in there.
<InPhase> kwikius: x = module cube([1,2,3]).x This makes no sense to me as syntax.
<JordanBrown[m]> Right, I'm having trouble with that too.
<InPhase> What are you even intending by it?
<JordanBrown[m]> I think it's intended as a module *invocation*, invoking the "cube" module, and then taking the result of that invocation and extracting the "x" member.
<geoffder> Is x supposed to be a field of the module? Then (module cube(...)).x would be more clear wouldn't it?
<phryk> mhh, a contribution i might maybe even be able to pull off: less engineer-broken-brain navigation. just wasd,qe and mouselook. the weird rotation around some imaginary point is such an unbelievable hassle. :F
<JordanBrown[m]> Except that cube probably doesn't *have* an x member. But that's a detail.
<geoffder> Unless x is the module that the keyword is being applied to
<JordanBrown[m]> the way that I parse it is as you say: x = (module cube([1,2,3])).x
<geoffder> I feel like the parens are necessary there
<kwikius> m = module (size) cube(size);
<kwikius> m1 = module m([1,2,3);
<kwikius> x = m1.size.x;
<kwikius> happier with that?
<geoffder> omitting them has a totally different meaning
<JordanBrown[m]> OK, there I'm following you, but I'm still not comfortable with the "module" part of the second line.
<JordanBrown[m]> And I don't think it's necessary. m is already a module reference; m(whatever) is an invocation of that reference.
<phryk> can one of you check what size the openscad repo is real quick? only got 1,2G free on this machine and would like to at least do something like "grep -ri camera" to see whether it looks doable.
<kwikius> You need that since
<kwikius> x = m([1,2,3]) is a function call.
<kwikius> whereas
<kwikius> x = module m([1,2,3]) is a moduleLiteral
<JordanBrown[m]> And noting that "size" here works because "size" is the name of the first parameter to the anonymous module defined on line 1.
<JordanBrown[m]> no, it's the first line that's the module literal. The second line is an invocation of the resulting module reference.
<kwikius> actually
<kwikius> actually
<kwikius> you have to do
<kwikius> x = module([1,2,3]).x; // ! because otherwise it makes no sense!
<JordanBrown[m]> Why does it not make sense?
<JordanBrown[m]> and I assume there's a missing "m" in there.
<kwikius> x = module m([1,2,3]).x
<kwikius> I meant!
<kwikius> Yep of course
<kwikius> x = module m(1,2,3) makes sense!
<geoffder> So forgive my ignorance as I don't use the openscad language directly (generated via ocaml), but what will differences be between modules and functions when there are literals? I thought the main difference between functions and modules was that modules could return shape objects, as opposed to functions which cannot.
<geoffder> I've spent a time looking at BOSL2 so  that is the impression that I got anyway
<JordanBrown[m]> So that's an interesting fallout of the "hybrid" model that I was proposing.
<JordanBrown[m]> You are absolutely correct that today a module can only "return" geometry, and a function can only return a data value.
<JordanBrown[m]> I put "return" in quotes there because it is a non-traditional form of returning something.
<geoffder> is there something that prevents merging of the concepts in the dynamic openscad language?
<JordanBrown[m]> But once we have the concept of geometry-as-data, that you can have an expression that evaluates to a cube, a function becomes largely equivalent to a module.
<JordanBrown[m]> The biggest obstacle is namespace.
<JordanBrown[m]> Today, you can have a function foo, a module foo, and a variable foo, and they are all separate.
<geoffder> right, that's what they do in bosl2 to return geometries or points depending on the calling context
<JordanBrown[m]> If you can have variables that refer to functions (and you can, in the development snapshot), then you don't know whether foo() in expression context means to call the function foo, or to call the function that the variable foo refers to.
<geoffder> same name and args
<JordanBrown[m]> BOSL2 has modules and functions with the same name and related semantics.
<JordanBrown[m]> And indeed one of the things that we have to watch out for is accidentally breaking their usage.
<geoffder> Sounds like some unfortunate baggage to wrestle with
<JordanBrown[m]> So, like I said, if you have a variable foo and a function foo, and you say foo(), does that mean the function, or does it mean the function that the variable points at?
<JordanBrown[m]> yes
<JordanBrown[m]> The answer for functions is, I believe, a priority list.
<JordanBrown[m]> If there's a user-defined function foo, then it means that.
<JordanBrown[m]> Else if there's a variable foo that points at a function, it means that.
<JordanBrown[m]> Else if foo is a built-in function, it means that.
<JordanBrown[m]> But notably if foo is a variable with a value that is something *other* than a function, you skip that step. It is not an error, as it would be in many languages.
<kwikius> On subject of syntax change. There isnt any. The module literals proposals is a pure extension. Nothing breaks. All existing programs will be unaffected. (I also added th Experimantal optio) but yet to push that version. TBH It would be far faster to download the fork build it and test it out than to carry on in the abstract like this!
<JordanBrown[m]> Abstract is better :-)
<JordanBrown[m]> There is a way that module literals could break things, if it's not done just right.
<JordanBrown[m]> module m() { cube(10);}
<JordanBrown[m]> m = 123;
<JordanBrown[m]> m();
<JordanBrown[m]> has to invoke the module, not complain that m isn't a module.
<JordanBrown[m]> And that has to coexist with the notion that
<JordanBrown[m]> m = module () { cube(10); };
<JordanBrown[m]> m();
<JordanBrown[m]> invokes that anonymous module.
<JordanBrown[m]> This is the same problem as
<JordanBrown[m]> function f() = 5;
<JordanBrown[m]> f = 3;
<JordanBrown[m]> x = f();
<JordanBrown[m]> has to yield 5, not an error, but
<JordanBrown[m]> f = function () 5;
<JordanBrown[m]> x = f();
<JordanBrown[m]> has to yield 5.
<JordanBrown[m]> I think it can be done, but it has to be done *just so*.
<phryk> hokay, repo is ~130M and grep -ir camera actually finds things – probably most pertinently src/glview/Camera.cc. Might look into that next week or so.
<kwikius> As I say You could build the fork and  try it out. I just did
<kwikius> module m() cube(10);
<kwikius> m= 123;
<kwikius> m();
<kwikius> echo(m);
<kwikius> Instantiates a cube.
<kwikius> and Echo's 123
<kwikius> Got to go. Download , build and try it out or let me know if build fails of course
kwikius has quit [Quit: Client closed]
geoffder has quit [Quit: Client closed]
Colere has joined #openscad
LoupGris has quit [Ping timeout: 265 seconds]
<JordanBrown[m]> They say that the map is not the territory. Similarly, the specification is not the program.
<JordanBrown[m]> But the two are not the same: If the map and the territory disagree, it is the map that is wrong. If the specification and the program disagree, it is the program that is wrong.
Furor has joined #openscad
Colere has quit [Ping timeout: 252 seconds]
<JordanBrown[m]> phryk: Exactly what is your complaint with the camera controls?
<phryk> JordanBrown[m]: everything. :'D
<JordanBrown[m]> That's not a very actionable complaint :-)
<JordanBrown[m]> What would you want them to do differently?
<phryk> it's so ridiculously finicky to actually get the camera onto small details. whenever you need to move the camera forward, you first have to look up or down in order to move it forward or backward so you don't even see if you moved enough or too far or slightly in the wrong direction…
<phryk> fps controls. mouselook + wasd and two keys for up down, probably q and e
<phryk> that way i can actually look at what i'm moving the camera to. not this weird "rotate around an imaginary point" mindfuckery. :F
fling has quit [Ping timeout: 258 seconds]
<JordanBrown[m]> OTOH it's a heck of a lot easier to orbit an object with these controls than with FPS controls.
<phryk> not really tho. only if you want a completely neat curve. if you just want to fly around it keep pressing a and d and just move the mouse to keep the object centered – super easy.
<phryk> and i have not ever needed a clean orbit around some object.
<phryk> i can't even come up with an actual use-case for that…
<JordanBrown[m]> I think of it as grabbing the object and turning it so that I can look at it from all angles.
<JordanBrown[m]> I am generally much larger than the object, so I don't think of it as moving myself around the object.
<phryk> yeah, but what for? when i design something i'm usually focused on one detail of the object.
<phryk> and for example now trying to get the camera on the holes for the screws *within the boards* is damn near impossible. and getting the camera into the cable tray of the desk two days ago also took me like 3 full minutes. with fps controls that's literally less than a second.
<JordanBrown[m]> But regardless, having the choice of rotation controls turning the object, versus turning the camera, seems reasonable.
<JordanBrown[m]> I think that pan and zoom are symmetric; it doesn't matter whether you're moving the object or the camera.
<phryk> also keyboard bound movement of the camera, that one is kind of a must for mouselook to make sense.
<phryk> really close zoom always has some culling weirdness or something tho where objects get cut out of existence…
snaked has joined #openscad
<JordanBrown[m]> and no, I'm wrong, zoom isn't the same, at least if you have mouse-centric zooming. FPS move-forward is always toward the center of the screen; OpenSCAD zoom is around the mouse cursor.
<JordanBrown[m]> Yes, things that are too close are cropped. I'm not entirely sure why.
<JordanBrown[m]> But it's a common thing in 3D graphics.
<JordanBrown[m]> Worse, for OpenSCAD, is that the previewer can't handle it if you are inside a negative object.
<phryk> JordanBrown[m]: if you want to take a look at a great implementation, check out godot. hold down the right mouse button and you can navigate in first person. shift moves faster, but you can also change general movement speed with the mouse wheel while holding rmb.
<JordanBrown[m]> But how long would I have to wait for it?
<phryk> (without holding rmb, mousewheel changes the zoom factor)
<InPhase> JordanBrown[m]: Oof. We missed a good opportunity.
<phryk> JordanBrown[m]: :P 4.0 had a beta last week or so ;)
<JordanBrown[m]> Hmm?
<JordanBrown[m]> InPhase which opportunity was that?
<phryk> naming openscad godot instead? :P
<InPhase> JordanBrown[m]: Imagine an OpenSCAD where modules and functions are not separate things. Where there is only one of these. If the returned value is { r=5; sphere(r); } then calling it bare is like saying "obj;" and thus instantiates the geometry. But if the value it generates is "x+5" it returns x+5.
<JordanBrown[m]> I think we are awfully close to ending up there.
<InPhase> JordanBrown[m]: Then you have "Foo();" displays the geometry, and "x = Foo();" returns the value it is specified to make, which could be an object.
<JordanBrown[m]> and "x;" makes it.
<InPhase> JordanBrown[m]: This is basically the natural next step of what we're discussing, except it breaks the namespace divide.
<JordanBrown[m]> yes
<JordanBrown[m]> it's easy (well, sort of) to have geometry-as-data.
<InPhase> let(...) gets omitted for returning values.
<JordanBrown[m]> the problem then is how you take your geometry-in-a-variable, and put it into the model.
<JordanBrown[m]> We discussed render(g);
<JordanBrown[m]> and we discussed just "g;".
<InPhase> Which also means, for things we can actually do, let(...) is how you define a variable in an object that is private!
<InPhase> I need to add that to the wiki.
<InPhase> Modules already support let(...)
<JordanBrown[m]> I have never tried to understand statement-context "let".
<InPhase> Well it's not usually necessary, but it matters for objects.
<JordanBrown[m]> OK, I tried it a little.
<JordanBrown[m]> let(x=5) ...
<JordanBrown[m]> appears to be roughly equivalent to
<JordanBrown[m]> group() { x = 5; ... }
<InPhase> Oh wait. let establishes a group. This doesn't work.
<JordanBrown[m]> Eh, why not?
<InPhase> let(r=5) sphere(r); cube([r,r,r]); The cube does not have r defined.
<InPhase> You need to do: let(r=5) { sphere(r); cube([r,r,r]); }
<JordanBrown[m]> right, you'd have to do
<JordanBrown[m]> let(r=5) { sphere(r); cube([r,r,r]); }
<JordanBrown[m]> jinx
<InPhase> :)
<JordanBrown[m]> but that's equivalent to
<JordanBrown[m]> union() { r=5; sphere(r); cube([r,r,r]); }
<InPhase> Yes.
<InPhase> So you can hide values, but only in a nested manner.
<JordanBrown[m]> yes
<InPhase> Which is kind of limiting. It means you can only hide the tail of calculations, and not the start of them.
<JordanBrown[m]> which just means "put all of the stuff you want to export at the top level, and everything else at a lower level".
<InPhase> I suppose that is the more likely desire though.
<InPhase> So at least it's in the more common direction of utility.
<JordanBrown[m]> ah, what you are saying is that you can't hide the start and *not* the tail.
<InPhase> Right.
<JordanBrown[m]> But: who said you had to do your calculation inside the object?
<InPhase> I suppose I can still hide it with function literals.
<JordanBrown[m]> or with plain functions
<JordanBrown[m]> function foo(r) = let(d=r*2) { sphere(d=d); };
<InPhase> Or... with let. x = let(start=5) start+2;
<InPhase> well foo is exposed then.
<InPhase> I just want some control over the "API" of an object.
<InPhase> I'm thinking now like a library designer.
<JordanBrown[m]> Yes, but you also have to think about how the object gets out to the caller.
<InPhase> I think with that inline let or inline function literals, most of what I'd want to do becomes possible.
<JordanBrown[m]> In OpenSCAD, the *only* way that you can hide an intermediate value from the statements that consume the final value is to use a function or an expression-context let.
<InPhase> If you can hide the start or the end, even if it's ugly, then you can pick and choose variables in the middle with a little bit of boilerplate.
<JordanBrown[m]> In fact, scratch that, the only way that you can hide an intermediate value is with expression-context let.
<InPhase> x = (function(start=5) start+2)();
<InPhase> ;)
<JordanBrown[m]> yeah
<JordanBrown[m]> But just like when you're building an array, there are ways to not put your intermediate values into the array.
<InPhase> Actually, oddly there is no difference at all between an in-place function literal call and a let statement except the code path this is going to take.
<InPhase> As long as it's an empty () call.
<JordanBrown[m]> but going back to namespace...
<JordanBrown[m]> if we allow "g;" then we ought to allow all sorts of other expressions.
<JordanBrown[m]> notably including functions that return geometry.
<InPhase> Yes. I only blocked some of them in the wiki proposal because of the namespace issue.
<InPhase> But it sure would be nice.
<JordanBrown[m]> My initial reaction is that namespace blocks it.
<JordanBrown[m]> But then I realized that function literals and references already have that problem.
<JordanBrown[m]> function f() = 1;
<JordanBrown[m]> f = 2;
<JordanBrown[m]> x = f();
<JordanBrown[m]> has to return 1, not an error.
<JordanBrown[m]> but
<JordanBrown[m]> f = function() 2;
<JordanBrown[m]> x = f();
<JordanBrown[m]> has to return 2.
<JordanBrown[m]> Similarly, if you allow a function call in statement context, and there's a name collision with a module, the module has to win.
<JordanBrown[m]> I *think* it's just a matter of a priority list.
<InPhase> Well, we sort of abandoned the namespace divide for literals/references.
<InPhase> But because we could do it without breaking backwards compatibility.
<JordanBrown[m]> and I think the same thing can be done for module invocations.
<JordanBrown[m]> Maybe there is just something I'm missing, but I think it works.
<InPhase> But it will require that if function foo and module foo exists as non-references, the context still determines which one is called.
<JordanBrown[m]> yes
<InPhase> Perhaps we could say that if neither exist as references, it is permissible to call either.
<InPhase> i.e., the last one defined.
<InPhase> (Per standard.)
<JordanBrown[m]> Only one of them can exist as a reference.
<InPhase> Right now we have: f = function() 1; function f() = 2; echo(f()); prints 2. function f() = 2; f = function() 1; echo(f()); prints 1. Neither produces a warning or error.
<InPhase> But for references, these are values, and only the last one assigned survives.
<JordanBrown[m]> really? Maybe I just always tried them in the right order.
<JordanBrown[m]> No, order doesn't matter. The old-school function wins.
<InPhase> Oof. So worse than that.
<InPhase> Order doesn't matter. Which version of openscad you run the test on determines which wins. lol
<JordanBrown[m]> Hmm?
<InPhase> Last release, function literals win. Master branch, old-school function wins.
<JordanBrown[m]> In what version does the function reference win?
<InPhase> 2021.01
<InPhase> I'm not sure if that was an intentional change or a side-effect of a change. But, that's what it is.
<JordanBrown[m]> Oops.
<JordanBrown[m]> But neither of them is backwards-incompatible with pre-2021.
<InPhase> It will check local scope first as well, so a function literal in a local scope will override an outer scope old-school function.
<InPhase> Probably the master branch approach is for the best. Keep priority on the old approach if it's there.
<JordanBrown[m]> I guess I don't really care whether a function literal beats an old-school function, as long as an old-school function beats a variable that isn't a function at all.
<InPhase> In fact we need that for what we just discussed. Old-school functions and modules need to win if they exist, for the sake of BOSL2.
<JordanBrown[m]> yes
<JordanBrown[m]> no
<JordanBrown[m]> wait
<JordanBrown[m]> let me think
<InPhase> And then we could say that if no old-school module or old-school function exists for a particular name, then it can evaluate a function literal in a module context and express the geometry.
<JordanBrown[m]> in statement context, an old-school module has to beat a function.
<JordanBrown[m]> function reference versus old school function should resolve the same way in expression and statement contexts.
<JordanBrown[m]> and based on 2021.01, that way is... function reference wins.
<JordanBrown[m]> but an old-school module has to beat both of them.
<InPhase> The master branch philosophy is old school wins, so we're set following that.
<JordanBrown[m]> Well, wait, if 2021.01 has function references winning, then that's the standard that we should follow.
<InPhase> Why?
<JordanBrown[m]> Because that's what compatibility means?
<JordanBrown[m]> That's a release. Its behavior is what is cast in concrete.
<JordanBrown[m]> What does compatibility mean, if not "the behavior in previous releases is continued in new releases"?
<InPhase> I'm reasonably confident/hopeful nobody depended upon this esoteric behavior yet.
<JordanBrown[m]> That way lies madness.
<JordanBrown[m]> Of course, the other way lies madness too.
<JordanBrown[m]> Madness everywhere.
<InPhase> If you made an old-school function and a function literal in the same scope depending on the resolution to make one inaccessible, then you deserve whatever you have coming to you. ;)
<JordanBrown[m]> and it's not like either behavior is clearly right or wrong.
<JordanBrown[m]> well, yeah.
<InPhase> It really only becomes significant in the broader context we're discussing.
<JordanBrown[m]> yeah, but (unfortunately) people *do* depend on things that nobody expected them to depend on.
<InPhase> Well, somebody already changed it in the master branch some time ago.
<InPhase> I'm willing to let that slide on out and not worry about the random person who might have done that.
<JordanBrown[m]> Eww... in 2021.01, if you have a top-level function reference and a local function, guess which one wins.
<InPhase> Well from your Eww I suppose the wrong one, being the top-level?
<JordanBrown[m]> yep.
<InPhase> Then we'll call that a bug fix.
<JordanBrown[m]> https://bpa.st/K7FQ
<JordanBrown[m]> ECHO: 2
<InPhase> I will firmly stand by the notion that the implementation can have bugs with syntactic or semantic consequences, and we should not treat all of them as untouchable features.
<JordanBrown[m]> Sure.
<InPhase> It impedes progress too much.
<JordanBrown[m]> But until we discovered that behavior, which is clearly wrong, we didn't have something that was clearly wrong.
<InPhase> A slightly balanced touch is required, considering how rare usage is, and the simplicity of just fixing those rare dependencies on buggy behavior.
<JordanBrown[m]> If local always wins, then it doesn't matter whether old-school functions beat function references; either choice is equally good.
<JordanBrown[m]> But local has to win.
<InPhase> Yes, local must win.
<JordanBrown[m]> Anyhow, going back to statement context, I think it's a very similar problem amenable to a very similar solution.
<InPhase> I agree it is indeed possible to permit direct invocation of geometry from a function literal then, absent a same-named module.
<InPhase> And that also means function literals are the new module literal. Done!
<InPhase> In fact, we don't have to bother writing module literals at all.
<JordanBrown[m]> And, sliding down the slippery slope a little further, if you have a module reference m...
<JordanBrown[m]> m = module (size) { cube(size) };
<JordanBrown[m]> then you should probably be able to invoke it in expression context to get geometry
<JordanBrown[m]> g = m(10);
<InPhase> We only need objects, to add the rule about function literals evaluating geometry in a module call context, and then module literals are done, they are just called "functions".
<JordanBrown[m]> there's no compatibility concern there, because to get there you have to use a module literal, and they are ne.
<JordanBrown[m]> new.
<JordanBrown[m]> Yes, there is a good argument that that's the end.
<JordanBrown[m]> Of that particular slope.
<InPhase> I suppose we forgot to think about children though.
<JordanBrown[m]> But maybe you should be able to say
<JordanBrown[m]> module m(size) { cube(size); }
<JordanBrown[m]> g = m(10);
<InPhase> Can objects have children?
<InPhase> Or what am I saying... Objects can't. Can function literals have children?
<JordanBrown[m]> thinking
<JordanBrown[m]> you mean object literatls
<InPhase> function references is really what I mean.
<InPhase> Upon calling them.
<JordanBrown[m]> hmmmmmmmmmm
<JordanBrown[m]> I *think* no.
<JordanBrown[m]> which does imply the need for module references (and probably, but not necessarily, module literals).
<JordanBrown[m]> but this is hurting my brain.
<JordanBrown[m]> m();
<JordanBrown[m]> I see where you're going, but I don't think it can work.
<InPhase> I'm missing a semicolon after there.
<JordanBrown[m]> But this is part of what is making my brain explode.
<JordanBrown[m]> m();
<JordanBrown[m]> might be an expression that happens to be a function call, or might be a module reference.
<InPhase> I think it could be done.
<JordanBrown[m]> or, heck, might be an old-school module invocation.
<InPhase> But it would sort of be a special-case thing that has to be written to give children a value before a function reference call.
<JordanBrown[m]> I'm not at all sure that the parser could figure out whether it's an expression or a module invocation.
<JordanBrown[m]> never mind children for now.
<JordanBrown[m]> well, sort of.
<JordanBrown[m]> the parser has to be able to resolve
<JordanBrown[m]> m();
<JordanBrown[m]> into being either a module invocation that doesn't happen to have children, or an expression that one hopes yields geometry.
<InPhase> Well, the lookup has to check if old-school module m exists. If not, lookup function literals, then if one exists evaluate it and see if you get an object. If you do, all good, if not, warning.
<JordanBrown[m]> and I would worry a lot about whether it can draw that distinction without a substantially more elaborate syntax.
<JordanBrown[m]> Or, rather, a substantially more elaborate syntax *change*.
<JordanBrown[m]> yeah, but you haven't gotten to the lookup yet. You're still parsing.
<JordanBrown[m]> which parse target does that resolve to?
<InPhase> Module lookup, but if it fails it checks function literals.
<InPhase> You just wedge in a plan B, and then we depend on plan B for this. :)
tachoknight has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<JordanBrown[m]> I think that means that it can't be a general expression, because if it could be a general expression then there's a syntactic ambiguity.
<InPhase> The parser doesn't care how the lookup is actually done.
<InPhase> We write that code separately.
<JordanBrown[m]> parsing time, not execution time.
<InPhase> All we're calling for here is an extra lookup path after parsing is done.
<InPhase> No change is needed to parsing for this.
<JordanBrown[m]> for m(), no.
<JordanBrown[m]> for "g;", yes.,
<JordanBrown[m]> for "o.g;", yes
<InPhase> For that, yes, that's a parsing change.
<JordanBrown[m]> for "list[n];", yes.
<JordanBrown[m]> I was thinking that an arbitrary expression could be a valid statement.
<InPhase> These will need to be object reference lookups.
<JordanBrown[m]> But f() is a valid expression, and so f(); would be a valid statement.
<JordanBrown[m]> But f() is also a valid statement because it's a module reference.
<JordanBrown[m]> -> parsing conflict.
<JordanBrown[m]> er, make that "because it's a module invocation".
<InPhase> Not a parsing conflict.
<InPhase> Always parse it as a module.
<InPhase> What we're changing is the meaning of "parsed as a module".
<InPhase> It now means "try to find a module, but if you failed, check for a function reference and if so let's call that and try to get an object back."
<JordanBrown[m]> But if one of the options for "statement" is "expr", then "m();" can match either expr or module_instantiation.
<JordanBrown[m]> (here I am referring to the syntax in parser.y)
<JordanBrown[m]> But I must go feed the hungry wife.
<InPhase> I don't understand there being any ambiguity there, since no new syntax is introduced by this part.
<InPhase> But, you can try explaining later. :)
<InPhase> I should probably go relax a bit anyway.
GNUmoon has quit [Ping timeout: 258 seconds]
GNUmoon has joined #openscad
<JordanBrown[m]> the new syntax is allowing an expression at the top level of statement context.
<JordanBrown[m]> If we *only* allowed some particular subset of expressions there, then it's avoidable, but (a) that would be unfortunate and (b) I think it would still take care.
<JordanBrown[m]> In particular, if a "call" is allowed at the top level of "statement", we're in trouble. It would be OK to allow a "primary", I think.
<JordanBrown[m]> But that excludes function calls, array references, and object references from the top level.
<JordanBrown[m]> I'm not sure whether we can solve that by splitting "call" into two targets or not.
<InPhase> Oh. I think I get you now. You're referring to top-level statements like, "a[2]();" which would be a required parsing change for any module literal approach, whether separate or piggybacking on function literals.
<InPhase> In either case the parser change would be the same. It would need to be an updated case of parsing at the statement level, and then it would need to call the module lookup. And then the module lookup could defer to function literals as its plan B for this as well to do the discussed approach.
<JordanBrown[m]> Something like that, yes.
<JordanBrown[m]> The problem is that the obvious way to represent it in the parser would have "m();" matching two different parse patterns.
<JordanBrown[m]> I would also worry that even in cases where it *isn't* ambiguous, it might be more complex than the parser can handle. But I'm not a strong enough parser guy to be sure one way or the other.
<JordanBrown[m]> ... though the more I think about it, the more likely I think it is that there's a problem there, if we made "expr" be one of the options on "statement". In particular, "expr" can match
<JordanBrown[m]> echo() echo() echo();
<JordanBrown[m]> and so can module_instantiation.
<JordanBrown[m]> No, wait, expr can't match that. But it can't *know* that it can't match that until it gets to the very end, and at that point I think it may be too late to back out and match module_instantiation instead.
<JordanBrown[m]> But as I said, I'm not a strong enough parser guy. In particular, I don't know precisely what this statement means:
<JordanBrown[m]> Bison by default generates LALR(1) parsers but it can also generate canonical LR, IELR(1) and GLR parsers.
<phryk> is there a feature to automatically "overcommit" cutouts so you don't get z-fighting when using accurate coordinates for your cutsouts?
<JordanBrown[m]> No.
<JordanBrown[m]> Such a feature would have to figure out which face(s) need to be extended.
<phryk> mhh, true…
pbsds has quit [Ping timeout: 252 seconds]
pbsds has joined #openscad
pbsds has quit [Ping timeout: 268 seconds]
<phryk> alpha mixing seems… weird.
<phryk> https://paste.xinu.at/f5P6h0/ currently trying to make all components visible from the outside. but when looking through a translucent thing, the barrel nuts are not visible – the cutouts for them are, tho…
<phryk> at least some of this seems to be orientation-dependent, too – when i look through the opposite site, i see neither the barrel nuts nor the cutouts for them…
ur5us has quit [Ping timeout: 244 seconds]
<phryk> when i go into "thrown together" view, it works from both sides, but *only* for the cutouts, screws and nuts aren't visible when looking through either side
<phryk> but even there, there's weirdness with the cutouts for the screws on the top are visible being visible on the sides but only for screws on top, while for the horizontal boards they are only visible on the bottom one, but not the top one… o_O
<phryk> the cutouts *are* all there, tho – i can see them fine if i move the camera *into* the boards.
<phryk> and in wireframe mode the screws (or their cutouts?) are visible in the top and bottom board, but not the ones on the side and the barrel nuts (again, cutouts?) are visible on the bottom but not the top
<phryk> this makes pretty much every one of these views useless… :F
<phryk> is there really no way to just see all the modules at once?
<JordanBrown[m]> Alpha mixing *is* weird. I don't remember all of the details, except that order is important.
<JordanBrown[m]> As for seeing everything at once - you mean by making it all translucent? - I don't know.
<phryk> openscad doesn't implement culling, does it?
<JordanBrown[m]> I am not a strong 3D graphics person, but in preview mode I don't think it does.
<JordanBrown[m]> The previewer cheats. A lot.
<phryk> mhh, ./src/glview/preview/OpenCSGRenderer.cc has a bunch of occurences of 'cull->' tho…
<JordanBrown[m]> It produces results that generally look like the final model, but through mechanisms that do not at all figure out what the final model is actually built like.
<phryk> i think the fix might just be to completely deactivate culling^^
<JordanBrown[m]> I don't know.
<JordanBrown[m]> But I do know that alpha mixing is a particularly weak point.
<phryk> if it properly worked, it would fill an important niche that none of the view modes currently does…
<phryk> i also have no idea why wireframe is apparently of the rendered thing – a wireframe of the preview would probably also show all components at once…
<JordanBrown[m]> A wireframe of the preview would show many things that you don't want to see, because every single component of the model is present in the preview.
<JordanBrown[m]> Including negative objects and portions that are cut away.
<JordanBrown[m]> But yeah, if you want to see through the model and see all of the parts at once, wireframe is probably your best bet.
<phryk> well, currently, it's not *at all* useful for that.
<phryk> and has it's own weirdness comparable to that of alpha mixing.
<JordanBrown[m]> I can't say that I use wireframe much at all, but I haven't seen it behave oddly.
<JordanBrown[m]> Aside, of course, from the fact that wireframe only works on a rendered object and so has no color support.
<phryk> last one is wireframe
<phryk> see how the barrel nuts (or their cutouts) are visible on the bottom but not the top? it should either have both or none…
<JordanBrown[m]> Is the model small enough that you can just give it to me to look at?
<JordanBrown[m]> The .scad source, that is.
<phryk> sure, sec.
<phryk> https://paste.xinu.at/YyW for wgettable raw format
<JordanBrown[m]> I agree, there is something strange. Looking more.
<phryk> Thanks you. :)
<phryk> s/s//
<JordanBrown[m]> OK, I understand part of it.
<JordanBrown[m]> You are expecting the individual pieces to retain their identity through the render.
<JordanBrown[m]> But that's not what happens.
<JordanBrown[m]> They all become one with the Body.
<JordanBrown[m]> If you have a hole, and you perfectly fill that hole with a cylinder, the result is ... no hole, no cylinder.
<phryk> not in preview mode, tho… all the geometry actually exists, i can see it if i move the camera into the boards…
<JordanBrown[m]> I'm puzzled by the little partial remnants that you were getting for some of the barrel nuts. I would have figured that you would have ended up with valid 3D objects there.
<JordanBrown[m]> Like I said, preview cheats, and has all of the geometry present.
<phryk> that's a good point tho – openscad should have something to denote something as a separate thing so you end up with multiple meshes. would also fix my complaints with the rendered view :P
<JordanBrown[m]> Make your hole diameters just a little bit larger.
<JordanBrown[m]> I multiplied them by 1.01, but adding a small number might be appropriate.
<JordanBrown[m]> That will make there be a non-zero gap between the screws and barrel nuts and the holes that they are in.
<phryk> ah, then they're visible in wireframe at least.
<phryk> preview / thrown together still has the exact same weirdness, but that's all alpha mixing.
lostapathy has quit [Ping timeout: 268 seconds]
<JordanBrown[m]> Right, the render was unioning the metal parts with the wood parts, and mostly (but not quite completely) the result was to re-fill the holes.
<phryk> i assume the mystery behind that is "something something floating point inaccuracy"?
<JordanBrown[m]> Don't know.
<JordanBrown[m]> I'm not a big fan of blaming floating point inaccuracy, but it is sometimes responsible.
<phryk> mhh, another thing i just noticed: activating "show edges" in preview mode introduces z-fighting. did not expect that one.^^
<JordanBrown[m]> Yeah, that's pretty cool.
<JordanBrown[m]> No idea.
<phryk> yeah, also not really important. :P
<phryk> anyhow, i think i'm done with my openscad adventures for today. skipped work entirely. i think i'll ask whether i can take yesterday off. :'D
Furor is now known as LoupGris
<phryk> thanks for all the help. :)
<JordanBrown[m]> Yeah, difference doesn't get along at all well with show-edges.
lostapathy has joined #openscad
<phryk> aaah, that explains why i didn't see it in the earlier stages of this project when i was just putting cubes together. :)
<JordanBrown[m]> I am, by the way, not attempting to *explain*... just agreeing, having demonstrated that Z-fighting on a very simple model.
<JordanBrown[m]> difference() {
<JordanBrown[m]> cube([10,10,1], center=true);
<JordanBrown[m]> cube([3,3,2], center=true);
<JordanBrown[m]> }
<JordanBrown[m]> I can't say that I'm shocked... I've looked at how difference is implemented in the previewer, and to a certain extent I consider it a miracle that it works most of the time.
<JordanBrown[m]> Or maybe black magic is a better description than "miracle".
<phryk> "ludicrous hacks" might also apply :P
<phryk> mhh, does cgal depend on opencsg? wondering what both libraries role are in openscad…
<JordanBrown[m]> CGAL is what does renders.
<JordanBrown[m]> It actually does the boolean operations, unioning, differencing, et cetera.
<JordanBrown[m]> I am not sure about OpenCSG's role, but I think it ties into the previewer.
<JordanBrown[m]> ... which, as I have said, cheats.
<phryk> yeah, glview/preview/OpenCSGRenderer.cc seems to imply so. so essentially openscad uses 2 implementations for CSG – that's what I've been wondering^^
<JordanBrown[m]> yes
<JordanBrown[m]> one does the real operations, the other fakes them with OpenGL trickery.
<JordanBrown[m]> The previewer is much, much faster.
<JordanBrown[m]> If I had to guess, the previewer is O(n) on the number of triangles, and render is O(n^2).
<JordanBrown[m]> That's without any knowledge of the CGAL algorithms, but it makes sense, and it kind of agrees with the relative times.
<phryk> ah, so OpenCSG just displays things CSG'd(ish), but CGAL actually returns some kind of mesh object holding all the vertices/faces after the CSG operations, gotcha.
<JordanBrown[m]> Right.
<JordanBrown[m]> The difference is easiest to imagine for union.
<JordanBrown[m]> The previewer just throws all of the triangles in the object at the screen, and some combination of the software and the hardware only displays the frontmost ones.
<JordanBrown[m]> It doesn't actually know how to union... it just knows how to show only the frontmost triangles.
<phryk> yeah, from the name "OpenCSG" i would have expected it to do the actual operations, but it seems that's just a reference to OpenGL
<JordanBrown[m]> I don't know.
<JordanBrown[m]> I'm starting to be sort of familiar with the programming-language side of the implementation, but the 3D graphics side is still largely a mystery.
<JordanBrown[m]> I looked at it enough to understand why people kept telling me that the previewer didn't do geometry.
<JordanBrown[m]> And to sort of barely get past my initial reaction, which was "this isn't DOING anything, how can it work?".
<phryk> yeah, i can only mostly guess at how it works, and only because i've already had some limited contact with opengl programming^^
<phryk> i stumbled over enough of the weird implications of vertex ordering even with the little bit of opengl i can at least guess at how mindbending the previewer must be to actually understand ^^
<JordanBrown[m]> But, congratulations: I've been using this for several years now, and you came up with a couple of odd behaviors that I hadn't seen before.
<JordanBrown[m]> There is a new renderer in the works called fast-csg that may help with some of those. It's supposed to be fast enough that it might replace the previewer, but actually doing the operations.
<JordanBrown[m]> I don't know any details.
<phryk> that'd be great. tho i think many of my problems are coming from the fact that (at least afaik) there's no way to delineate pieces into separate meshes (like the screws and bolts for example).
<phryk> this would probably be a complete no-deal but IMO every module that's not CSGd into another one should be a separate mesh in both the preview and actual render.
<JordanBrown[m]> But they *are* CSGed into one another. There's implicit unions all over the place.
<JordanBrown[m]> But things will probably be better for that if we ever get multi-material support.
<JordanBrown[m]> I think I know how to do that, but (a) it will be even slower, and (b) the scheme I'm thinking of doesn't get along well with the previewer *at all*.
<phryk> implicit unions? why are there implicit boolean operations at all? o_O
<JordanBrown[m]> So that
<JordanBrown[m]> produces a single object.
<JordanBrown[m]> cylinder(h=10, d=1); cylinder(h=1,d=10);
<phryk> yes, that i understood now – but why?
<phryk> like, when I'm not applying a union, I'm doing that for a reason.^^
<JordanBrown[m]> Those design decisions are from long before I was involved, but I think the answer is because the goal is usually to produce an STL file for 3D printing, and you can't do that if you've got surfaces inside objects.
<phryk> is it tho? that seems like just a niche of CAD and I was under the impression that openSCAD is supposed to be a general-purpose CAD tool – was I mistaken?
<JordanBrown[m]> I can't speak to intent, but practically speaking my guess would be that >90% of its use is for 3D printing.
<phryk> every single scad model i've ever written was supposed to be made up of several objects.^^
<phryk> Okay, that thing i'm at least certain enough about that I'll probably open an issue for it some time this week… at the very least this should be optional behavior.
<JordanBrown[m]> And for 3DP, if they're supposed to be separate objects, they need to be separate prints.
<phryk> yeah, but then I'll still want a .scad for the fully assembled object…
<JordanBrown[m]> But for that it doesn't matter whether or not it's one mesh...
<phryk> Yes it does, otherwise how am i supposed to check whether everything aligns alright…
<JordanBrown[m]> Oh. Yeah, that.
<JordanBrown[m]> For one model where I had to care about that, where N components were all modeled independently and had to not overlap, I had a special mode that intersected every pair of them to see if there was anything left over.
<phryk> My ambition for OpenSCAD is essentially to bootstrap a socialist industry. I absolutely don't want to stand in front of a huge CNC mill, process a literal ton of steel and THEN notice that shit don't fit together. :D
<phryk> in the long run, I'll want things like designs for industrial robots written in openscad…^^
<JordanBrown[m]> So far, I haven't found a toolchain that l like that starts with OpenSCAD and ends at my mill...
<JordanBrown[m]> Of course, my budget for it is about zero.
<JordanBrown[m]> But part of the problem is that unlike in 3DP, in milling there are all kinds of things other than raw geometry that matter.
<phryk> same, hence I'm taking things slow. speakers > desk > ? > tinyhouse > ??? > industrial robots
<JordanBrown[m]> 3DP has some of that, but milling has a lot more.
<JordanBrown[m]> Anyhow, it's bedtime. G'nite.
<phryk> nighty :)
zxrom has joined #openscad
kwikius has joined #openscad
paddymahoney has joined #openscad
kwikius has quit [Quit: Client closed]
epony has quit [Remote host closed the connection]
epony has joined #openscad
GNUmoon has quit [Remote host closed the connection]
GNUmoon has joined #openscad
califax has quit [Remote host closed the connection]
califax has joined #openscad
TheAssassin has quit [Remote host closed the connection]
TheAssassin has joined #openscad
teepee_ has joined #openscad
<gbruno> [github] robiwano edited issue #4366 (OPENSCADPATH not adhered to. Windows 10.) https://github.com/openscad/openscad/issues/4366
<gbruno> [github] robiwano opened issue #4366 (OPENSCADPATH not adhered to. Windows 10.) https://github.com/openscad/openscad/issues/4366
teepee has quit [Ping timeout: 258 seconds]
teepee_ is now known as teepee
ur5us has joined #openscad
ur5us has quit [Remote host closed the connection]
ur5us has joined #openscad
ur5us has quit [Ping timeout: 250 seconds]
kwikius has joined #openscad
<gbruno> [github] robiwano closed issue #4366 (OPENSCADPATH not adhered to. Windows 10.) https://github.com/openscad/openscad/issues/4366
ccox_ has joined #openscad
ccox has quit [Ping timeout: 252 seconds]
<juri_> printing will solve everything. if you still have problems, you just haven't applied enough of it.
zxrom has left #openscad [Leaving]
<InPhase> phryk: Implicit union is necessary because of manifoldness requirements. You need overlapping components to be unioned to create a valid output. What remains possible is leaving and computing non-overlapping components as separate objects, but to do that, you need to prove they are truly non-overlapping, which is itself a geometric calculation.
<InPhase> phryk: Sometimes however that calculation will be fast with clear bounding box separation.
<kwikius> future syntax using module_operators on module_literals
<kwikius> module fold(sheet, pivotPt, pivotAngle, foldAngle){
<kwikius>   // used to mask off one or other side of fold line
<kwikius>   mask1 = module {
<kwikius>     translate([-100,-100,-50])
<kwikius>       cube([200,100,100]);
<kwikius>   };
<kwikius>   mask2 = module {
<kwikius>     translate([-100,0,-50]) cube([200,100,100]);
<kwikius>   };
<kwikius>   s0 = (sheet -> -pivotPt) ^> -pivotAngle;
<kwikius>   s1 = ((s0 - mask1) ^> [foldAngle,0,0]);
<kwikius>   s2 = s0 - mask2;
<kwikius>   result = ((s1 | s2) ^> pivotAngle ) -> pivotPt;
<kwikius>   result();
<kwikius> }
<kwikius> link to working example current syntax ( using module literasl) and equivalent module_operator expressions
<teepee> what's the squiggly stuff?
<teepee> in general that goes much into the direction of the object proposal too, so getting all those things sorted is nice
<kwikius> ^> is rotate and -> is translate
<kwikius> Not tested in parser yet I hasten to add but think it will work!
<teepee> hmm, not sure we want to mix that in yet, trying to get too much things into one big thing always ends in tears
<teepee> the older proposal had some other way of specifying functions the other way around, might be worth a look too
<kwikius> Anyway the actual characters for the operators are of course up for discussion...
<teepee> the + / - seem like a good idea as they are pretty natural and are basically in the language already
<teepee> just opening up due to geometry as data
<kwikius> No I don't expect you will mix the original in for a while, but doesnt stop me working on it. Will KISS in first PR!
<kwikius> Well * is mux by matrix   I presume but rotations and translatins are arrays.
<kwikius>  Anyawy it is another thing that can be done if modules are first class..
<teepee> indeed
<teepee> new syntax is just a little bit more tricky as it's basically set in stone once officially released, so things are going a bit slower in that area
<teepee> giving module + module a meaning is much more relaxed in that regard
califax has quit [Read error: Connection reset by peer]
GNUmoon has quit [Read error: Connection reset by peer]
califax has joined #openscad
califax has quit [Ping timeout: 258 seconds]
califax has joined #openscad
<kwikius> so module + module is  group/union and  module + array is translation?
<kwikius> Happy to try it. not hard to change in the parser
<kwikius> but for rotation module  * ^ ~  ...?
<teepee> maybe we first keep it to module / module and think about more options later
<kwikius> No module_operators or module'.' members in first PR anyway.   For group / intersection   '|'  and '&' seemed appropriate. or is boolean add, & is boolean multiply
castaway has quit [Remote host closed the connection]
TheAssassin has quit [Ping timeout: 258 seconds]
<kwikius>  missed a trick in original example !
<kwikius>     mask1 = module{
<kwikius>      translate([-100,-100,-50]) cube([200,100,100]);
<kwikius>    };
<kwikius>    becomes
<kwikius>    mask1 = module cube([200,100,100]) -> [-100,-100,-50];
<kwikius>   ( ... or some other translation operator)
TheAssassin has joined #openscad
tachoknight has joined #openscad
<kwikius> module fold(sheet, pivotPt, pivotAngle, foldAngle){
<kwikius>   // used to mask off one or other side of fold line
<kwikius>   mask1 = module cube([200,100,100]) + [-100,-100,-50];
<kwikius>   mask2 = module cube([200,100,100]) + [-100,0,-50];
<kwikius>   s0 = (sheet * -pivotPt) * -pivotAngle;
<kwikius>   s1 = ((s0 - mask1) * [foldAngle,0,0]);
<kwikius>   s2 = s0 - mask2;
<kwikius>   result = ((s1 + s2) * pivotAngle ) + pivotPt;
<kwikius>   result();
<kwikius> }
<kwikius> Yep.. looks ok :)
<kwikius> And of course you don't need to do it. Can still use the old ways :)
kwikius has quit [Quit: Client closed]
califax has quit [Remote host closed the connection]
califax has joined #openscad
califax has quit [Remote host closed the connection]
califax has joined #openscad
tachoknight has quit [Ping timeout: 248 seconds]
TheAssassin has quit [Remote host closed the connection]
kwikius has joined #openscad
TheAssassin has joined #openscad
<kwikius> Am getting errors as follows ( on my Fork, quite close to master):
<kwikius>        1256 - fastcsg-cgalpng_polyhedron-tests (Failed)
<kwikius>         1287 - fastcsg-lazyunion-3mfpngtest_lazyunion-toplevel-objects (Failed)
<kwikius>         1288 - fastcsg-lazyunion-3mfpngtest_lazyunion-toplevel-for (Failed)
<kwikius>         1289 - fastcsg-lazyunion-3mfpngtest_lazyunion-nested-for (Failed)
<kwikius>         1290 - fastcsg-lazyunion-3mfpngtest_lazyunion-children (Failed)
<kwikius>         1291 - fastcsg-lazyunion-3mfpngtest_lazyunion-hull-for (Failed)
<kwikius>         1292 - fastcsg-lazyunion-3mfpngtest_lazyunion-root-for (Failed)
<kwikius>         1293 - fastcsg-lazyunion-3mfpngtest_lazyunion-intersection-for (Failed)
<kwikius>         1294 - fastcsg-lazyunion-3mfpngtest_lazyunion-difference-for (Failed)
<kwikius>         1295 - fastcsg-lazyunion-3mfpngtest_lazyunion-minkowski-for (Failed)
<kwikius>         1296 - fastcsg-lazyunion-3mfpngtest_lazyunion-transform-for (Failed)
<kwikius>         1297 - fastcsg-lazyunion-3mfpngtest_2d-3d (Failed)
<kwikius>         1298 - fastcsg-lazyunion-3mfpngtest_fastcsg-lazyunion-issue4109-1 (Failed)
<kwikius>         1299 - fastcsg-lazyunion-3mfpngtest_fastcsg-lazyunion-issue4109-2 (Failed)
<kwikius>         1300 - fastcsg-lazyunion-3mfpngtest_fastcsg-lazyunion-issue4109-3 (Failed)
<kwikius>         1301 - fastcsg-lazyunion-3mfpngtest_fastcsg-lazyunion-issue4109-4 (Failed)
<kwikius> Not sure whether this is a regression or not and if it is my fault?
tachoknight has joined #openscad
<InPhase> kwikius: https://bpa.st would be better for that sort of thing.
<InPhase> And yes, you probably have a regression of some sort. I presume that would be a parser error. You could try doing those test files manually to see.
<InPhase> kwikius: On syntax for your work, please take a look at this proposal: https://github.com/openscad/openscad/wiki/OEP8:-Unifying-Objects-with-Geometry-as-data
<teepee> kwikius: at the end the test gives an output line mentioning an *.html file which has most of the details for the failures
<InPhase> kwikius: It seems like what you are attempting is closer to what we have decided to designate as an object literal rather than as a module literal. We have different ideas in mind for module literals. But for the object literals we have some simpler syntax options in mind in that proposal, which look like they would be compatible with what you are attempting there.
<InPhase> kwikius: In short the distinction between a module literal versus an object literal is the computational evaluation time. A module literal is a deferred evaluation which can accept parameters later and pick up dynamic scope later. An object literal is a constant thing with data and geometry created at the spot it is written out, and thus would be appropriate for the usages you are proposing there with
<InPhase> the operators.
<kwikius> Currently building master on my system to see what the differences are
<InPhase> kwikius: Syntax-wise, but not behavior-wise.
<InPhase> kwikius: What you are doing behaves like the object literals.
<InPhase> kwikius: So if you want that behavior, consider the object literal syntax. :)
<kwikius> Coulld you show me a code example of wher I am going wrong?
<kwikius> How does what I am doing "behave like object literals" ?
<InPhase> "mask1 = module cube([200,100,100]) + [-100,-100,-50];" --> "mask1 = {cube ([200,100,100]);} + [-100,-100,-50];"
<InPhase> The proposal on the wiki does not include those translation operators, but it includes the parts left of " + " as being the thing that you could do further geometric operations on.
<kwikius> The above is just syntactic sugar for translate(-100,-100,-50) cube([200,100,100) ( and is not part of the proposal  anyway
<InPhase> Those "module literals" mentioned as related ideas can NOT have geometric operations performed on them, because they do not have geometry!
<InPhase> That would look like: mask_gen = module(pos) { translate(pos) cube([200,100,100]); }; mask1 = { mask_gen([-100,-100,-50]); }; mask2 = { mask_gen([-100,0,-50]); };
<InPhase> Objects have geometry, modules are instructions to create geometry.
<kwikius> Did you try out my fork?
<InPhase> I did not.
<InPhase> At work at the moment.
<InPhase> I just wanted to slip in to let you know about the better matching syntax before you dove too far into trying to patch up the parsing of that.
<kwikius> Only 12 tests failedfrom 1000 or so.. so not bad to start with!
<kwikius> "Better matching syntax" ...?
<InPhase> As in better matching the lengthy discussions we've had about object literals, module literals, references, dictionaries, and all those interacting future changes to the core of the language. :)
TheAssassin has quit [Remote host closed the connection]
TheAssassin has joined #openscad
<InPhase> There are a few different ideas brewing about, but there's a pretty good consensus going that object literals will be the stores of geometry, and most concure that they should support that simple syntax I showed of just being like a scope block that is then assigned or used in a value context.
<kwikius> Well, I suggest you try out the fork and then show me where I am going wrong. I have read the lengthy discussions but they are not any substitute for actual code
<InPhase> I don't doubt you it works. I'm just suggesting shifting the syntax for how they are declared.
<InPhase> I think the extra syntax for the operators on them is actually an intriguing and innovative idea. Although we'll probably need some vibrant discussion about all the possible edge cases of ambiguity and such for that.
<kwikius> Module operators not part of the original proposal. "Vibrant discussion" I have seen plenty of here, but very little actual code :)
<InPhase> Those operators will be syntactically clearer though with the object literals syntax from the wiki, because of the built-in scope markers.
<InPhase> Well, on this issue, it's because syntax changes need consensus discussion as they become things we cannot change later. There have been many past errors on this that got baked into the language as undesired aspects, and we end up having to tiptoe or work around them for a long time.
<InPhase> It's easier to make rapid code on things not involving syntax changes to the language.
<kwikius> Got to go.. Bye!
kwikius has quit [Quit: Client closed]
TheAssassin has quit [Remote host closed the connection]
califax has quit [Remote host closed the connection]
TheAssassin has joined #openscad
califax has joined #openscad
califax has quit [Ping timeout: 258 seconds]
castaway has joined #openscad
califax has joined #openscad
<JordanBrown[m]> I'm not sure whether I'm just being overly picky, but I cringe a little when I see "module + module", because in the terminology that I would use that's not a meaningful operation. It is like saying "function + function" in a more conventional language. You can't add two functions, because functions are executable subprograms. You can add two *values*. If you say "sin(a) + cos(b)", you are not adding the sin and cos functions; you
<JordanBrown[m]> are adding the results of processing those functions on those arguments.
<JordanBrown[m]> "geometry + geometry", yes, that you could do.
<JordanBrown[m]> But that's geometry as a first class citizen, not modules as first class citizens. You could do it without having modules as first-class citizens, if you could invoke a module in expression context to yield geometry. That would not require being able to hand around module references as data.
<teepee> that was in context of the pr calling things modules
<JordanBrown[m]> Yes, I understand... I'm just commenting on the terminology. Terminology matters.
<teepee> it does, but it does not work disussing something based on a different terminology
<JordanBrown[m]> Which is why I think that one of the first things that has to happen is to get everybody using the same terminology.
<teepee> maybe we get to the same terminology soon-ish
<teepee> as there's also no chance to have 2 implementations :)
<JordanBrown[m]> Fingers crossed.
<JordanBrown[m]> I have lower-level design concerns, but *mostly* that stuff is easy.
<teepee> yes, the challenge is to not end up with zero implementations
<JordanBrown[m]> I have really mixed feelings about using arithmetic operators on geometry. It makes perfect sense, but I don't *like* it. Generally speaking, I'm not comfortable with operator overloading. I've probably just spent too many years in environments where it isn't a thing. Offhand, the only overloaded operator that I'm really comfortable with is string+string.
<JordanBrown[m]> I wouldn't oppose it, I just wouldn't push for it.
kwikius has joined #openscad
ToAruShiroiNeko has quit [Remote host closed the connection]
<kwikius> I'm getting exactly the same set of failed test on master!  So   not my fault!
ToAruShiroiNeko has joined #openscad
<kwikius> tumbleweed
drfff has joined #openscad
<teepee> maybe I'll have a supercomputer sometime, but my notebooks is not that fast
<kwikius> Sorry! uncalled for!
<kwikius> I think it may be this (from html report) WARNING: Import from 3MF format was not enabled when building the application, import() at line 1
<teepee> yep, that seems to match the failures
<teepee> so no big concern
<kwikius> Hokey Dokey :)
<teepee> not sure about that one fastcsg-cgalpng_polyhedron-tests - does it have 2 images in the html?
Guest85 has joined #openscad
Guest85 has quit [Client Quit]
<kwikius> Apologies will figure the link shortly meanwhile polyhedron tests gives
<kwikius> stderr output: DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use polyhedron(faces=[]) instead. in file polyhedron-tests.scad, line 2
<kwikius> DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use polyhedron(faces=[]) instead. in file polyhedron-tests.scad, line 7
<kwikius> DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use polyhedron(faces=[]) instead. in file polyhedron-tests.scad, line 12
<kwikius> ERROR: Unable to convert points = undef to a vector of coordinates in file polyhedron-tests.scad, line 23
<kwikius> ERROR: Unable to convert faces = undef to a vector of vector of point indices in file polyhedron-tests.scad, line 24
<kwikius> ERROR: Unable to convert points = undef to a vector of coordinates in file polyhedron-tests.scad, line 26
<kwikius> ERROR: Unable to convert points[0] = 0 to a vec3 of numbers in file polyhedron-tests.scad, line 27
<kwikius> WARNING: Warning: mesh is not closed!
<kwikius> WARNING: Warning: mesh is not closed!
<kwikius> WARNING: [fast-csg] Corefinement corefinement mesh difference #0 failed
<kwikius> ERROR: CGAL error in CGALUtils::applyOperator3DHybrid difference: CGAL ERROR: assertion violation!
<kwikius> etc..
<kwikius> Yes 2 images in the html
<teepee> that might be the one testing various bogus input polyhedrons
<teepee> possibly disabled for CI pipeline checks
<kwikius> Since test on my fork match master, I'll have a quick review and try for a PR , if that is OK?
<teepee> depends on the expectation
<kwikius> My expectation is that it will sit there for a very long time. Meanwhile I will try to  keep it attached to master branch :)
<teepee> that's not the ideal outcome, best thing would be if we could get that code and the work JordanBrown[m] is doing enough in sync that they agree
<teepee> from what was discussed earlier it seems the 2 are not that far apart, except maybe in terminology
<kwikius> Sure. If there is a link to the latest version of the code, I will happily try it out.
<kwikius> JordanBrown[m] ?
<kwikius> I was wondering if there isnt a better build structure. Separate cgal from core and gui and build separate libraries, to speed up build process + review the header structure to see if there are any bogus includes that trip recompilation etc..  Faster build would get more interested and more work done
<teepee> quite likely, biggest offender probably being header file creep like the one found a couple of days ago
<teepee> building parts as official library should not change much as cmake usually gets the dependency definitions correctly generated
<teepee> not sure about CGAL, at this point openscad is pretty useless without even though there's still an unmaintained flag to build without
<teepee> getting things restructured better so we maybe even could use an alternative library (specifically Manifold) would be cool though
<teepee> alternative for some operations, I think it does not support everything we use from CGAL
tachoknight has quit [Quit: Textual IRC Client: www.textualapp.com]
tachoknight has joined #openscad
teepee_ has joined #openscad
califax has quit [Remote host closed the connection]
teepee has quit [Ping timeout: 258 seconds]
teepee_ is now known as teepee
califax has joined #openscad
<kwikius> I think I have pretty much the same version
<teepee> that sounds like my old branch
<kwikius> Well otherwise what  object literals code are we talking about ?
<teepee> I'm not sure if he published code yet, but there's a nice summary and disucssion of features and details on the wiki page
<kwikius> version on my fork does actually run too :)
<kwikius> How about I do the ModuleLiterals PR. The part the  objectLiterals code seems to do is member access mainly ( which I have avoided in this PR) . Am I right? That can be phase 2
<kwikius> It is your old branch BTW :)
teepee has quit [Ping timeout: 258 seconds]
teepee has joined #openscad
kwikius has quit [Quit: Client closed]
kwikius has joined #openscad
<gbruno> [github] kwikius opened pull request #4367 (ModuleLiterals: making openSCAD modules first class.) https://github.com/openscad/openscad/pull/4367
ur5us has joined #openscad
califax has quit [Quit: ZNC 1.8.2 - https://znc.in]
califax has joined #openscad
<teepee> just paging through the PR I have 2 questions...
califax has quit [Remote host closed the connection]
teepee has quit [Remote host closed the connection]
califax has joined #openscad
teepee has joined #openscad
<teepee> meh
<teepee> of course it disconnected just before the actual questions ;-)
<teepee> 1) is there a chance to minimize the parser changes? it feels like a huge diff for mostly existing syntax
<teepee> 2) is it correctly capturing references of enclosing scopes
<teepee> also wondering if the circle-ci build will go through, they seem to have changed something in the integration
ur5us has quit [Ping timeout: 244 seconds]
<JordanBrown[m]> Note that while *module literals* need to capture references of enclosing scopes, neither *object literals* nor *geometry-as-data* need to.
ur5us has joined #openscad
<teepee> how so?
<InPhase> kwikius: The member access is part of what object literals are supposed to provide, but there are critical differences in that execution point. Yours is aligned with the object literals plan.
<teepee> value capture is needed for expression evaluation
linext has quit [Read error: Connection reset by peer]
<InPhase> kwikius: This is why I was saying it was not a module literal. A module literal is like a function literal, something that can be placed into a reference and called later for execution.
<teepee> JordanBrown[m]: hmm, I think I see what you mean. it might not be needed as they are "executed in place"
<InPhase> kwikius: A module literal is to be a thing that creates a reference that can be passed around as a value, but otherwise behaves like a module in usage. An object literal is to be able to store geometry that has been calculated already at creation, and then can be further operated on by geometry modification routines (like translate, rotate, etc).
<JordanBrown[m]> Right. It is only when we are squirreling away a reference to an executable subprogram that we need that.
<InPhase> kwikius: If it helps as a rough analogy, a module literal is sort of like declaring a class, while an object literal is kind of like having an object in OOP that is already constructed.
<InPhase> This analogy is loose of course, because we're not quite going that way.
<InPhase> But they serve comparable roles.
<JordanBrown[m]> A module literal is exactly equivalent to an inline function in JavaScript.
<JordanBrown[m]> We are still debating the exact semantics of objects and how they relate to geometry, but one facet of that area is what many languages would call an associative array, and another facet is a data structure that represents calculated geometry, the *result* of processing geometric requests.
<JordanBrown[m]> A module literal is also directly equivalent to OpenSCAD's existing function-literal mechanism.
ur5us has quit [Ping timeout: 246 seconds]
aiyion has quit [Ping timeout: 258 seconds]
aiyion has joined #openscad
epony has quit [Ping timeout: 252 seconds]
<gbruno> [github] podsvirov opened pull request #4368 (Update Russian translation) https://github.com/openscad/openscad/pull/4368
epony has joined #openscad
epony has quit [Ping timeout: 252 seconds]
epony has joined #openscad
teepee has quit [Quit: bye...]
teepee has joined #openscad
ur5us has joined #openscad
epony has quit [Ping timeout: 252 seconds]
epony has joined #openscad
ur5us has quit [Ping timeout: 244 seconds]
ur5us has joined #openscad
<kwikius>  tepee, I'm sure the code in parser.y could be optimised, though I am happy with the grammar,  but feel free to tinker with it and provide  a patch or PR to test.
<kwikius> As far as getting the correct contexts for default params args etc, I would say that needs to be investigated.  It should also do named arguments.
<kwikius> .. which it doesnt atm
<kwikius> Anyway bedtime. Bye!
kwikius has quit [Quit: Client closed]
ur5us has quit [Ping timeout: 264 seconds]
teepee_ has joined #openscad
teepee has quit [Ping timeout: 258 seconds]
teepee_ is now known as teepee