Tristan! Do you c++? I think I'm just going to bite the bullet and c++
And use an IDE to do it
I am currently entering c++, but it's a big place.
Why IDE? I'd encourage IDEing so we can compare contrast. I use grep+vim+gdb
I'm using vscode
It's not great
I will stop once I figure out why IDEs are good
And get better at vim
Neither is grep+vim+gdb
Yeah
Alternatively I might write an IDE, Mahi-Gui is going pretty well
Everything else is not
But Mahi-Gui is
I like c++ though, mostly for defacto reasons. Like, the newcomers might be better, but they are also newcomers.
Mostly I've been using jump to source so that's a feature I want for vim
I would like to write 15 guis, I feel the 15th would be passable.
Nah man, Mahi gui is great
Supposedly you can put it in with ctags, but I didn't have luck with my 20 min of trying so gave up.
It's a GUI toolkit esigned for making actual tools
s/gui/ide/
sorry
Oh yeah, well obviously I'd just embed neovim in something
I've been using pyimgui and it annoys me in new and different ways.
I know right?
Talk to me about annoyances
(also it doesn't seem to perform worse than pure cpp imgui, in my admittedly limited experience)
Buttons and fields are indexed by their name. You can't have two ok buttons on the same window.
or send or whatever
You can, you just need to give them a unique name. Annoying it's true, I think everying before or after a # is stripped from the display
Also I end up writing retaining systems myself because of the way I manage data.
You you'd do "send#send1" "send#send2"
writing retaining systems yourself is probably the cleanest way to couple it to the code, most of the time?
Does #notshown not get shown?
I have a habit of writing spagetti since I'm not forced to break out
functions, though that's more a complaint about my own code DX.
It does not
get shown
That is good to know. I already invented a terrible work around that I'm not taking out, but it is good to know.
And yeah, imgui really is for rapid prototyping shitty code
Also I invented a terrible thing I call the "withif"
Don't remember where I put it, but basically it's a with statement that can be conditional by modifying how python managees top-level exceptions to exit a with statement early
Oh, and my biggest grievance is that retained and immode are both ways of specifying a thing. It should be possible to write immode and have it retain except when it actually needs to update.
With no extra syntax
withif... what kind of context would you use that in?
https://gist.github.com/traverseda/4bdc8d6446b6cc15d4ef66df229a5d6c
So you'd use it as
with imgui.Window("myWindow"): Do a bunch of stuff, but only if window is visible
Ok... that's interesting. I think that makes sense. As an aside, your description of the withif as a 'hack' has given me insight into something I've long complained about. In math many things are named "weird new unnatural thing x" and it annoys me because those things are often normal old reasonable things. But it's because when they are proposed, its "I don't know if this makes sense or not" and once everyone says "yeah, this seems to make sense" the name has already stuck.
I do not believe withif is one of those things
So my new complaint is not calling things new hacky, but rather the nature of the lifecycle of naming things.
I believe it to be generally bad, only useful in an incredibly narrow situatio
No, certainly not something that will stick around for hundreds of years as it stands.
I think python really needs better syntax for building trees though, and maybe the solution is lists
is withs
not lists
LIke this!: https://gist.github.com/traverseda/da367acbf7fdabac41b923265536c3e9
I forgot I wrote that
Are you aware that dictionaries exist?
Yes, but I like yaml?! Syntactically significant whitespace for defining more complicated relationships
Admittedly I was thinking about imgui when I made this.
You can slap an if statement right in the middle of that
But yeah, I think this is likely also bad, but could be good for more complicated xml-ey type situations
Anyway, take a look at this. I've gotten demo windows drawing in c++, with support for cool imgui docking:
http://0fb41a0e35b3.ngrok.io/catCad
(link is very ephemeral)
I'm more dubious on tree thing than withif, though I think it probably makes good sense in context.
They're both pretty dubious
alas
My code is a tower of mistakes. I don't think I have any insight within it worth sharing.
QueryPerms is pretty solid though, the president of the django software foundation said so: https://gist.github.com/traverseda/dabe97d56f28d9a2d12aedf1eab7eff5
I'm trying to move away from the style "be clever enough to work with your own terrible code" and towards "be clever enough to write readable code" but it is a struggle.
Yeah
I worry about cpp
Yeah, query perms is a really good idea.
What's the worry?
That it's going to encourage cleverness, and that no one ever really documents their shit
I like pointers. Working with them makes sense.
Encapsulation paradigm is also good
python is worse for not having it.
What's the difference between pointers and weakref?
I didn't know weakref existed. I'll have to read about it, but it looks like it might be the same thing.
Except if de-references when the object gets GC'd, instead of pointing to the wrong object
I think, no habla C
Don't dereference the null pointer.
Yeah, most people use abstraction over pointers in cpp
That's good
Depends on the context I guess. It's nice to have the option to go that low if you need to, and understanding pointers and pass by ref vs pass by copy and all that is needed. You just have to learn it in c, you can get by without in python...
So, not really a benefit that applies to you.
And I'm sure there are ways to do encapsulation in python, but I and most proggers haven't sought them out. Maybe insideFun and dunders is enough.
It's all pass by reference unless the object is immutable or I explicitly make a copy
not for primitives
Have you forgotten what it's like to work with raw variables from your object ivory tower?!
Primitives are immutable!
but also yes
lol
That's probs a good thing.
I keep passing piles of variables through functions when it should instead be a nicely designed object structure and it makes me want to puke.
Not a fan of functional programming?
Cause I write my code in layers and don't refactor enough.
"passing piles of variables thorough functions".jpeg
Any thoughts on how to make a good CAD program? In particular parametric cad with minimal programming? I'd like to avoid my solution of "everything is a python object" for reasons, but I'd like to be able to do things like reference the diameter of a gear and maybe do some kind of geometric constraint solving on top of that
Probably start with a mini programming language, then build gui tools on top of that...
You've used solvespace?
I think it's not a problem with functional vs oop vs anything on the program
level, I think I actually don't like words... I'm going to have to think about
this before complaining about it again...
Minimal programming in the interface? Yes.
Minimal programming to build it? No.
I will look at solvespace.
Fusion 360 constraints look good.
See also bret victor.
Not minimal programming to build, god no
Sorry, first sentence was ref pile of vars.
I think a good one would be vertex based and create the finished model through an operation tree, where each operation would be subject to constraints. Is that too obvious?
Or I guess it would actually be an operation list, or an upside down tree. You know, like an irl tree, lol.
Nah, I've got that. It's more how to reference constrains on related objects and stuff. Like I want it to be heavily parametric, I want you to give a "gear" object a bunch of variables, and be able to read a bunch of variables out from them
So like I hand the gear a "tooth_count" and can reference it's final diameter, or it's center position
Each of those vars should have a graphical representation on the part you are working with.
Yeah, that's also really true
I guess there will need to be a good system to control what variables are currently visible.
Movement into and out of objects, and up and down the tree.
I was thinking force-directed graphs
What's a force
And yeah, moving up and down the tree is part of the challenge
Don't forget into and out of abstraction on the tree!
The labels all sort of try to get as close to the object as they can while trying to stay away from other labels
Add gear is a node, but it's made up of a tree itself.
Probably using dead simple physics.
Yeah
It's hard to actually implement, or to imagine what the language looks like in practice
Eww, no. No force directed graph.
Just for the labels
No. No... maybe... I don't think so, let me explain.
Like, if you need to edit them as individual ints or whatever, use a menu.
But this should be avoided most of the time, because the shape of the object should describe the shape of the object.
Not numbers or whatever.
Likewise, if you want to see all of the operations, it should just be in a menu list. Otherwise, you are thinking about the direction from the operation you are currently working on, so you use hotkeys or menu buttons to move up and down, in and out, and do your work.
What would be the advantage of glooby graphs of things?
(except as an operation that one might apply to their part)
Documentation, you can see what the variables are doing, what they're attached to
I tentatively think that should be done through interaction and highlighting, not lines connecting nodes. More exploration needed, but for example, you have this gear is locked so it meshes with that gear, so when you have this gear selected, it also highlights the circle around the center of that gear representing the mesh point. If you then select that circle you may be able to see how it is made up of the mesh diameters of the two gears and set around that gear.
Sensible
And if you are ever just saying "oh, whatever make the gear this big" that doesn't need to be shown, and if you ever want to see it it's just "0.5486..." in a window.
"How to think through what needs to be related" and "How to come to understand parts / operations you didn't write" are interesting to think on, and gooby graphs might creep in there, but I think well defined expand/collaps-able lists and well defined hotkey motion in operation space is the salve.
Oh, also really good flexibility for changing the operation directed graph,
it's a dir-graph sorry, I called it a tree wrongly earlier. Anyway it should
obviously attempt to be flexible enough that it's easy to go back in a
finished part and modify add and move operations to fix your mistakes in the
required relations.
I mean, that's kinda obvious as well, that's kinda the whole point isn't it?
Combine the flexibility of direct modeling with the ease of modification of
parametric?
Ulg, this is a good subject.
Good goal. Difficult though. Are you actually want to build one of these?
I need better CAD, it's not happening on it's own
I imagine I'll build something shitty that does the job that inkscape does, but with support for geometric constrains
Not unlike solvespace but less shitty
Mmm... each operation function thing should have a 'gRepr' function, saying how it shows itself in the part/scene. And there needs to be the division of view and model so its easy to make it look sleek like original autocat oscilloscope stuff but also make it look normie tier new.
We can just write the shitty sleek view, but it needs to be easy for someone else to write the shiny view.
imo
I haven't into solvespace much. Can you point at what it does wrong?
A few things:
Generally it handles layers poorly, since layers are the only tool you have to segment your code into different parts that's a big problem
No programmability, you couldn't make say a parametric gear except via copy+paste I guess
Generally intolerable UX, full modal windows that lock the app if you click the wrong things when you create a constraint
Waaaay too many constraints visible
No support for variables, no way to make a constraint reference another constraint except for things like the same length constraints
Basically there's no way to make a gear with a variable number of teeth parametrically
Layers -> that is a big problem.
no programm -> damn big problem
modes are good, but locking interfaces are bad.
Yeah, movement in operation space is a better way of thinking about it I think
than "look at all these constraints"
no constraint ref other constraint -> unacceptable.
It's not modes, it's a modal window. A popup you need to click to get it to go away.
Yeah, ok, is it open source? The base may be salvageable, but I'm thinking you're right it's not, operation-space-abstraction needs to be fundamental from the start.
A punishment for clicking the wrong window window? Gross.
I'm thinking the base probably isn't salvageable, and there are better geometric constraint solvers available nowdays. It's got a custom one that is apparently pretty hard to work with, I've talked to the ex-maintainer
If the constraint solving core wasn't purportedly a PITA I'd be into it
But proabbly better to build on something like https://www.gecode.org/doc- latest/MPG.pdf
I think constraints might be the wrong way to think of things. Constraints are
like making an environment where you can play with a thing, but still have it
stay in certain bounds... That's interesting, but not how I was thinking about
it.
I was thinking "I put a circle down! I put it's center on this other circle!"
and so it's not like it's constrained, that's just where you put it. You could
add a new operation where you move it base on something else you built, but
you don't really 'move it around with this constraint' you 'go back and change
where you originally put it'.
Also cmake is hard
cmake can s#ck a d*ck
Is there a flag for that?
Why is bash ok for managing builds? Answer: it's not. It's something you put up with so you can work with C and gcc
I think there should be a flag for that.
I think constraints are probably a decent way of having things be dependent on other variables? What you're actually building is a big set od math that depends on other math, one big equation
But doing that in openscad is unpleasant
Variables that depend on other variables
But yeah, you need to by default constrain objects to where you actually put them
Yeah, I think "default constrain objects where you put them" says it. To move an object is not to move an object but to change or add an operation done to it, such as changing the operation of placing it in its original location. Certain operations like move operations should want to just merge together so adding a move is just changing a move (or put) unless you have a really good reason for having different moves... the composition of those operations and how they work with one another is the thing to care about. Constraints if they can be called such a thing are just ways of getting vars to feed operations. "Find me the point where these circles intersect, I place it on the most clockwise one from this circle."
An aside, cmake should not wander through directories looking for changes but just go to where my git diff says the changes are, unless I'm misunderstanding what it's doing wandering through all the dirs. Linking should not take that long?
I really enjoy the tup build system, for things where I know what I'm doing well enough to actually write my build from scratch
I use it for my personal site
https://github.com/traverseda/traverseda.github.io/blob/master/Tupdefault
tup looks nice.
@catcat, I think one of the problems we will see is that "most clockwise one"
thing, cause it's easy to see you want to put the thing 'here' it's harder to
see 'why' you want to put it there. First you get a set of space, and you need
to narrow it down to a single point somehow. That's the 'constraint solver'
but it does need to go down to an actual single point, (or set of points if
multiple objs) so there's a lot of ways to go with that. Once you select the
set of points on the edge of two intersecting circles, you really have two
points and have to choose only one of them in a way that will continue to make
sense when you fiddle with other operations. That's one of the reasons it
needs to of course be flexible. You start moving an operation and oh, the gear
popped over to the wrong place, I just set it to 'leftmost' but it needed to
be 'clockwise from gear a' just change that selection over eh?
Maybe that's a good way to think of it, you can't 'add a circle' you can only select a point and a length and only then can you generate a circle with that center point and given radius.
People describe objects as fully constrained or partially constrained, depending. Play with solvespace a bit, it's crappy but it deals with these problems in a way that sort of almost works
At least the problems are problems are probably the right problems
No, I don't like it, partially constrained objects don't make any more sense than partially placed objects.
What they actually are is objects where one of the constraints is variable, where it can be filled in with whatever to make the equation work
Solve for X, where X is axis that isn't fully constrained
If you could add dependant constraints it would be much better
This line must be at least 10 mm
Under constraint is just implicit dependent constraints
maybe... maybe...
Yes, ok, I agree. When defining a gear there is a relationship between the
tooth size, radius, and num teeth. So would modeling a gear involve specifying
that relationship and then filling it with specific values? That would be
difficult to make a good interface for doing naturally. Interesting, but
difficult.
I think we want most modules to be built from primitives in the same way as
parts are built, but is that possible? Or would you instead need to write a
gear(selector(possibleGearSet(radius,toothsize)) module and if anyone wants to
make a gear with 11 2mm teeth they need to instead use the gear(radius,#teeth)
module...
I guess having a natural way to specify constraint relationships is the more
worthy goal. I will brood on it.
Yeah, I imagining you define the relationship between the parts all at once, and the user gets a set of variables and they can edit whatever ones make sense
I'm imagining it auto-generates Equations for every possible constraint
Then you fill in the ones that make sense
You name the constrains, and other people can use that as a module, and define whatever constraints make sense.
Then you put all the parts together
I guess 'selector' above would actually be "max(below(" or some such... It
would be interesting to see and work with those 'selectors', like, 'below'
would look like a line or circle, and you would see it as a line or circle
with it's passing possibilities highlighted and the outer ones faded. Then
'max' you wouldn't see the too big possibilities from below, and would see
highlighted the biggest with the other possibilities faded.
Interesting here is that the context of what's being selected should inform
how possibilities are visualized.
'possibleGearSet' would also be a selector selecting from all real numbers
based on radius and toothsize.
It would be possible to have selectors return empty or multiple and would have
to raise an exception in those cases. That feels ugly but is probably
something that has to be lived with.
I do like the idea though that when modeling you go through selectors to get
the appropriate args before generating objects, rather than the other way
around.
It's order of constraints. Auto generating functions that take values and return sets of possibilities... and yeah, auto generating them from constraints is the right way... but my thinking here is definitely still fuzzy...
I presume there's a way to define a set of constraints and get a pretty equation from it
That's admittedly a big presumption
Oh! There's infinite variables that one may want to constrain... so you are both breaking out variables, and constraining them. For the triangle, should it by default break out volume and allow calculation of angle based on volume? What about square root of volume? Obviously not, so the act of creating modules is not just constraining, but breaking out variables that are useful to constrain, as well as constraining variables already broken out.
Yep, that just completed the line of thought I was having
And you can have an online thing with object inheritance, someone defines a good base thread object, other people constrain it with common thread types
As I imagine good base objects like a generic "thread" is going to have a lot of variables broken out
Where as an "ISO garden hose thread" will have much fewer variables broken out, or at least defaults for most of the annoying bits like thread profiles
Online lib gets pointing in a direction that would be complicated but good...
If you grab a module, it should look to you like a part you're working on. You
can zoom inside it's operations and look around. Maybe there's an indication
that you've crossed the bound into external code. But then you can start
modifying it, and if you modify it it will become another module, either more
or less primative. This way you adapting it to your needs may be seen &
possibly used by others. Are many people adapting it in this way? Maybe it
should come up in the search before the more constrained version. Fuzzy
thoughts.
Yeah... ISO... like, you'd have a tag 'ISO' tag that is only true so long as
this radius is xyz and nothing else in the module has been changed.
I'm imagining modules live in a different panel than your main work-piece, not just a zoom in. Since they're re-usable
You'd need to make an explicit copy to edit it
Source files basically
But with content-addressable hashes
So there are 'parts', 'relations' and 'selectors'. I prefer 'selector' to 'constraint'. Feels more of a general concept. Also more cheery for people who aren't really into bondage. By applying relations, you can a ascertain values that will become properties of higher level parts.
I want to implement cubic bezier as a generic part, I think it would prove the flexibility of the system really well., but be quite challenging to actually do
Any system that you can implement your own cubic bezier in is powerfull enough
I think there should be one primitive part. Vertex. But making a bunch of generics would be good.
I have two primitive parts defined, points and lineSegments
cubic beizer would be more of a selecter you put vertexes on, right?
But points don't really count
Points are the only thing that counts.
Ehh, it outputs a bunch of line segments, so I'm not sure
I think it would be a part
Shouldn't it output an stl?
Oh, I guess for working in 2d.
Yeah
Beziers output line segments in 2D, line segments are straight
You may have it figured out, but I need to be more clear on how 'parts', 'relations', and 'selectors' work. Are those the only object level things that the UI must allow interaction with?
Is that in fact a good way of thinking of these things?
I'm imagining each worksheet has, at the top, a list of named variables.
I've been imagining it as relations are the variables that you broke out, those are named variables. Variables that aren't broken out are anonymous variables. Parts can also have names.
So for example if you wanted to reference the tooth count on your main gears
sun-gear you'd do something like myvar=Maingear.sun.tooth_count
A part is an object that exposes some number of variables
If you wanted to reference an un-named variable I guess you'd go in and name it? Tricky for parts that are auto-generated, we need some kind of loop primitive...
Selectors are just binding a variable to a name, really
We probably need to allow for anonymous selectors as well though
So no, I don't have a super clear view of what's going on, except that parts are a DAG of smaller parts
And you explicitly name what variables exist
I was thinking variables are relations you broke out... or they don't exist at all. Can we call them properties. Properties have relations. A certain number of properties must be specified to actually specify a part, rather than a set of possible parts. Selectors are how you go from a set of possible parts to a smaller set of possible parts to a single actual part.
s/./?/
Constraint really is the right term, not selector. It's what all the other cad programs call it, and what the geometric constraint solvers call it
Properties have relations, yeah
Also, relations are unknown, like actually not calculated at all in most cases, unless they have been 'created' or 'named' or whatever we are calling it.
I need to think more about 'constraint' vs 'selector'...
Yeah, that follows I think
Obviously its just a name, but I had an inclination there is some reason what we should be thinking of isn't really that thing they are using...
query might be better...
Fair, selector like an html selector? Grabbing a node out of the DoM?
I imagine it more like database constraints
And relations like database queries, like maingear.sun.tooth_count
Yeah, no, 'query' works much better, 'query' and 'filter'...
'maingear.sun.tooth_count' would be a property, right, it would be fit into the relation between the radiuses and number of other gears and stuff
It's a property, but it's a property on a different part, yeah
Maybe I want to grab every gear tooth, filter to every second one, then find it's middle and add an insignia there. That feels much more like a selection, filter, property thing thing, not a constraint. Yeah, I 'constrain' the insignias to what I get from that selection, but it's not like I'm constraining theme there, I'm just creating them there. Constraining never happened, except for the filter 'constraining to odd number tooth id's' or if you want to say that it is a 'constraint' to a set of real points, but that's baloney.
Hmm, I suppose when you start getting into any kind of loop/map then selector makes a lot more sense, yeah
I'm not sure a selector is the same as the constraint though, I imagine you query (select?) based on something, and then you do your constraint as a seperate step
And I feel like with most modeling that's the default, and constraint is the exception, making it a more specific case of a query/filter thing.
yeah, a lot of stuff starts out with querying all real numbers, or doing a get on a specific point, I imagine...
for i in select("gears"):
constrain(emblem.center=i.center)
Only you know, in a way that isn't turning complete
And ideally more like 'mouse hover over relevent already broken out property, select, filter hotkey -> pop open menu for complex filter -> id %2==0, make hotkey -> insignia'
Yeah, that looks like a reasonable workflow
Frustrating for a certain kind of part, but it should be mathematically solvable you know?
Like we should be able to make stuff like that part of the giant equation
And have gecode solve it
Also gecode was easy to add to cmake so I like it
It looks cool. I don't know enough about it yet.
Seems like it's the best constraint solver for cpp
Constraint solvers are just computer algebra systems I think
Lots and lots of stuff
https://pypi.org/project/python-constraint/ looks good for playing around with, of course it doesn't do any geometry you need to add the geometry yourself
Copyright 2019-2024 Alex Davies
Revision history