Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question/Feature request] Can there be an interaction of selected objects in the viewer and build123d? #126

Open
SuperMechaDeathChrist opened this issue Nov 29, 2024 · 8 comments
Labels
wontfix This will not be worked on

Comments

@SuperMechaDeathChrist
Copy link

I was wondering if it is possible to, for example, select a face in the viewer and based on its identifier get the face and perform actions on the part (in the code that actually builds the part runing in the python interpreter).

I think it is confusing to explain, but basically i was experimenting with running ocp_vscode in standalone mode and i noticed that when i select a face, a request in the server is registered like this:

Data sent PropertiesResponse(type='backend_response', center_info='/Group/Solid/faces/faces_1 : Reference point has been taken as the center of the geometry', subtype='tool_response', tool_type='PropertiesMeasurement', center=(0.0, -0.0, 2.0), vertex_coords=(0.0, -0.0, 2.0), length=2.2, width=0.0, area=84.32, volume=None, radius=None, radius2=None, geom_type='PLANE')

I want to be able to do something like this:

  • Select a face in the viewer (like the top face, for example).
  • Display in the viewer which face is selected: /Group/Solid/faces/faces_1, or a unique integer ID of the face).
  • Copy the info above (maybe allow multiselecting objects and copy that as a list).
  • Go back to the editor and do something like: face = get_face(ID=1) or face = get_face(route="/Group/Solid/faces/faces_1")
  • Use the face as reference to perform further build actions (make a plane, make a cut, extrude, make a hole, etc.)

This will allow for a more interactive approach (like using a full CAD software with an user interface), eliminating the need that, for example, sorting a list of faces by their coordinates in order to perform something as simple as selecting a top face.

What if i have an object with a lot of faces with different angles, and i want to select a face that is neither top nor bottom in any coordinate? Selecting it will be a mathematical challenge in itself.

Something like a button to perform an action like "copy selected" and functions to get these objects would be an absolute improvement in the user experience.

Please let me know if something like this is supported already or it can be implemented.

@dalibor-frivaldsky
Copy link

For such a functionality to work properly, the face identifier (and any other object type interactive in this way) would need to be given an identifier that is consistent (or to some extent consistent) across multiple executions of the code.

For examle, if the unique ID of the face changes with every execution of the code (let's say by generating a UUID each time), your code face = get_face(ID='....') would not work at all. The ID would identify the selected face only for the render your are selecting from, not for any subsequent re-renders.

The example of using some path to the face as an identifier would work only for as long as the geometry stays unchanged or the changes coincidentally lead to the selected face still having the same path. Which may be impossible to guarantee.

There may be some ways how to generate reasonably consistent identifiers for geometries, someone else would have to pitch in here, though. But I would say this would first need to be done inside build123d, if it's desirable.

For your usecase, for simple things like selecting the "top" face, you can write a small function that would do that instead of typing out the filter and sort every time. For the more complex scenario, I would say you are better off storing the face you want to edit later in a variable at the time it is created (supposedly before the rest of the other complex geometry exists) and then instead of selecting it anew, you start from that variable. What I think could be helpful in this case is the ability to highlight the code in the code editor that created or modified a face selected in the view.

@bernhard-42
Copy link
Owner

bernhard-42 commented Dec 2, 2024

thanks @dalibor-frivaldsky, I fully agree with what you said.
This has been discussed several times on discord, but with no actionable result.
The point is, that in build123d or cadquery you can run the code with changes again and again. So an identified object in one run can have a totally different id in the next run.
At the end, build123d and cadquery rely on OCP, which relies on opencascade.
In opencascade one can enumerate e.g. the edges of a given face or the faces of a given solid in a repeatable way as long as the objects are not modified (opc-tessellate does this), but this doesn't hold after modifying an object.

@jdegenstein
Copy link
Contributor

There may be some ways how to generate reasonably consistent identifiers for geometries, someone else would have to pitch in here, though. But I would say this would first need to be done inside build123d, if it's desirable.

@dalibor-frivaldsky Once cadquery-ocp is updated to 7.8+ I am planning to look at the possibility of generating and storing a hash of the brep (as in the plaintext OCCT kernel file format) in build123d. I hope this will allow to find identical geometry run-to-run and may enable some more features like this one in the future.

@bernhard-42
Copy link
Owner

@jdegenstein The viewer already uses a more complex cache key to identify objects it doesn't need to tessellate any more. I will also move to 7.8.1 hashes.

@jdegenstein
Copy link
Contributor

@bernhard-42 Just to clarify here is what I hope to include in build123d based on cadquery-ocp==7.8.1+

  1. standard new OCCT hash result using the 64bit number instead of old 32bit number implementation (if I recall these details correctly). As you are well aware this new hash enables essentially collision-free detection of "this is the same shape for this execution run only".
  2. my idea to add an additional hash function in build123d to hash the brep file format representation that should be able to say "this is the same shape at the same position across multiple execution runs". This second one could enable some new and interesting features if it works as I hope.

@bernhard-42
Copy link
Owner

I understood and know about 7.8.1
But I needed caching already now in the tessellator, hence, due to the lack of a good hash function in OCCT, I implemented the object id as the BRep binary serialisation followed by sha256.
Brute force but surprisingly fast 😇

@bernhard-42 bernhard-42 added the wontfix This will not be worked on label Dec 10, 2024
@njourdane
Copy link

njourdane commented Dec 13, 2024

Interesting discussion here, as it's also something I wanted (and related to an issue I posted a few days ago).

For such a functionality to work properly, the face identifier (and any other object type interactive in this way) would need to be given an identifier that is consistent (or to some extent consistent) across multiple executions of the code.

Here is the "run-agnostic" hash function I use in a project, using ocp_tessellate:

import json
from ocp_tessellate import convert

def hash_shape(shape, tesselate_hash=False) -> int:
    if not tesselate_hash:
        return hash(shape)

    shapes = convert.tessellate_group(*convert.to_ocpgroup(shape))[1]
    return hash(json.dumps(convert.numpy_to_buffer_json(shapes)))

So as far as I understand, assuming I put the hashes as shape labels, the possibility to allow an interaction with the viewer, like getting the hash of the shape clicked might be useful.

@njourdane
Copy link

Can there be an interaction of selected objects in the viewer and build123d?

Yes

output

I started a new discussion here #133 to explain how it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

5 participants