Thoughts on UI for interactivity in 3D view

26 views
Skip to first unread message

William Adams

unread,
Jul 2, 2025, 8:46:18 AMJul 2
to PythonSCAD
This was asked after recently when I suggested it, and it's come up for discussion at:


so here are my thoughts on it:

 - some folks are working on projects/parts where there is _not_ a direct correspondence betwixt the 3D view and the model instantiated by the code and the code (e.g., an edge of a part completely cut away by a chamfer or roundover tool so that the ultimate dimension of the part will depend on tool and path geometry)
 - there needs to be a generalized way to specify a 3D appearance on-screen and have a contextual view of one or more numbers associated with it
 - the actual interface elements will need to appear on an as-needed basis in a predictable fashion which the user is able to control using a reasonable interface and they should similarly vanish (or fade away?) when not wanted

So perhaps a programming interface along the lines of:

stock_thickness = 3

design_width = 20
design_depth = 10
design_thickness = stock_thickness

def my_part(design_width, design_depth, design_thickness) # 
part_outline # this is a command which takes the following arguments:
    part_width =  design_width  (drag = true, textUI = true, nudge = true, slider = true, range = stock_thickness * 3--1000),
    part_depth = design_depth (drag = true, textUI = true, nudge = true, slider = false, range = part_width * 2--200), 
    part_thickness = design_thickness (drag = false, textUI = true, nudge = false, slider = true, range = 2.5--10)
    # once defined, the defined variables are used as expected 
    cube([part_width, part_outline, part_thickness]) # this would create a matching region which when the cursor enters/interacts would create a transoarent 3D element which once highlighted, could be selected, and then once selected, a specific face selected --- once that face is selected, then it could be directly dragged (if that is enabled), a number keyed in (if textUI for that dimension is positive), adjusted up/down incrementally using nudges/spin arrows, or adjusted using a slider, depending on which UI options are enabled

After draggin/entering/interaction, the UI fades away in stages when the mouse exits that area.

Hopefully the above description is clear enough --- I'll try to mock up a visual this evening.

William

W W

unread,
Jul 3, 2025, 4:11:16 PMJul 3
to PythonSCAD
Let's see if I get the gist of what you are proposing...

You want GUI interactions (e.g., dragging a solid's vertex) to modify the underlying scad code correspondingly. Is this correct?

Off the top of head: this could be quite difficult due to CSG tree applying changes recursively.

Even for "simple" solids like a cube; dragging one of the vertex means the solid may not be express-able with a cube alone. It may need to morph into a polyhedron.

Unless there's a structured, simple, and deterministic way to do this, it may be intractable with the limited resources available (e.g., unless openscad supports it, it may be infeasible to have it as a pythonscad feature).

-W

Guenther Sohler

unread,
Jul 3, 2025, 4:22:46 PMJul 3
to W W, PythonSCAD
Nope, that's not as difficult as it appears -
pythonSCAD can already do that to some extent.

Let's imagine a simple cube first and imagine, that its height is variable, so you can write:

cube([10,10,marked(10)]).show()

press F6, hold Ctrl and try to drag a vertex and try to increase height ...
But this was too simple, was it ?

When doing a drag operation, PythonSCAD does "reverse rendering" to find out, which vertex in the code is addressed.

When you try:

translate(cube([10,10,marked(10)], [10,0,0])).show()

pythonSCAD can also drag the point correctly, because it finds it after traversing 2 hierarchy levels instead.
that's the principle.
Hower, right now, not many module parameters are "enabled"  for dragging. 
its basically the primitives few parameters of translate and rotate.

its not difficult to extend, it's just a matter of doing ...



--
You received this message because you are subscribed to the Google Groups "PythonSCAD" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pythonscad+...@googlegroups.com.
To view this discussion, visit https://groups.google.com/d/msgid/pythonscad/63b1faf5-7656-4233-94cf-b3aaf0db2e92n%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

W W

unread,
Jul 3, 2025, 5:41:14 PMJul 3
to PythonSCAD
/1/ Is it correct to say the dragging only works for variables wrapped with marked()?

/2/ Does the dragging still work if the rendered solid is the result of union()/difference()/intersection() ?

Guenther Sohler

unread,
Jul 3, 2025, 5:44:45 PMJul 3
to W W, PythonSCAD
1)  yes, another option to mark 10 is writing as string. but i am not sure if we shall keep that

2) yes, CSG operation should/do also work with marking. it's just gets more cpu intensive, as the tool searches all the childs of the operation




Raymond West

unread,
Jul 4, 2025, 6:45:25 AMJul 4
to pythonSCAD

Just my twopenn'orth -

size = 6

cube([marked(size), marked(size), marked(size)]).show()


This kind of usage breaks the parametric concept. The marked() function suggests we're marking a fixed value rather than a variable — it's no longer truly parametric, just draggable.

I know this is still in early development, but currently, it doesn’t handle things like cube([], True) properly, nor does it work well in the negative quadrants. Why not have all vertices draggable by default? In many conventional GUI-based drawing packages, vertex points can be shown (although typically at a resolution finer than OpenSCAD’s view window). There are plenty of these GUI drawing tools — but very few that are parametric.

At present, dragging affects the sides, not the actual corner points. That’s a partial solution. Maybe using Ctrl/Shift to drag a point directly would work — but positioning anything accurately becomes tricky unless it’s constrained to snap to another defined point.

What about circles or arcs? Their resolution varies with fn, so how would point-based manipulation even behave there?

I’m not sure what your long-term vision is, but if it’s aiming for a clean, intuitive parametric GUI, maybe consider revisiting the foundation. Right now it feels like starting from the wrong place.

In geometry, the hierarchy starts from a point, then to a line, then a plane, and finally a solid. In OpenSCAD (and now PythonSCAD), the smallest directly viewable item is a plane. This makes GUI manipulation a bit clunky. Representing 3D geometry via a 2D interface is always tricky — especially when you’re trying to support both direct manipulation and strict parametric modelling.

Best wishes,

Ray

Raymond West

unread,
Jul 4, 2025, 5:55:25 PMJul 4
to Guenther Sohler, PythonSCAD

Maybe it is just me, but I know in the past I would have liked to have moved a point in openscad, but now I think it is unnecessary.  I had earlier used freecad, and the interface was annoying. I prefer the programmatical approach for most of what I do. Dragging things around the screen seems rather imprecise, unless trying to trace part of an existing shape.

If you want to manipulate a cube, (any shape, in fact) treat it as a polyhedron. If you leave it as a cube then you'll have to feed back to the script the distance dragged, etc. If you don't do that, the script will be useless to the user if referred to later on, expecting the same results. (Of course a list of points and faces is not much use the user, either). I do not think that the system lends itself to an interactive gui, the feedback will be too slow, certainly for any non-trivial shapes.

On 04/07/2025 12:22, Guenther Sohler wrote:
Hi Raymond,

Yes I should actually check, if the argument of marked() is actually a number and not a variable.
But we are just at the "evaluate options"  phase ;)

Best practice so far is to put least amount of marked() into your code, because they could  very easily become
contradictory. Imagine this one


translate(cube([10,10,marked(10)]), [0,0,marked(10)]) 

This is a 10x10x10 cube elevated by 10.
If you now vertically drag  the point, it's not clear if the user wants to reduce the height of the cube or to move it lower. 
I believe current implementation alters both parameters which is not the users intent.
(right now this actually does not happen due to an internal weakness)


Its not possible to have all vertices of a cube draggable by default, because if you can very easily render situation where the result is not a cube anymore and therefore cannot be described as cube() in the code.

Nope, dragging on the cube does neither affect edges, faces or edges, but only parameters(these can be altered in code).
The behaviour you are experiencing was my best guess to make it look reasonable. But there might be
better strategies, how to map a mouse movement to cube parameters.

yes: Representing 3D geometry via a 2D interface is always tricky.
This is why interactive dragging works best if the drag movement path is parallel to your screen surface 🤣
So before each drag operation , please optimize your viewing angle ...





Matthieu Hendriks

unread,
Jul 7, 2025, 10:51:56 AMJul 7
to Raymond West, Guenther Sohler, PythonSCAD

I also prefer the programmatic approach — it's much more precise. Dragging things around the screen tends to be imprecise.

Dragging can be useful when arranging multiple objects right before printing, but that's something the slicer handles perfectly.

Trying to mix both techniques in OpenSCAD will probably lead to nightmares.


Op vr 4 jul 2025 om 23:55 schreef Raymond West <ray...@raywest.com>:
Reply all
Reply to author
Forward
0 new messages