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

Edge annotations in sketcher and filter scripts #51

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

SuzanneSoy
Copy link

Hi :)

This MR is too much of a draft to be merged, and it is based on an ugly hack to annotated the edges of a sketch with custom information, but I thought you might find the use case and solution interesting. Lattice2 already provided most of the tools I needed, which saved me a lot of work, so thanks!

My use case for Lattice2 is to draw the net of a 3D object using the Sketcher, and then add slots and tabs to cut it out of paper (I use the Silhouette paper cutters), mark the folds (using an embossing tool or dull blade, also via the same CNC paper cutter) and assemble. Since these slots and tabs are very repetitive, I needed a way to automatically add tabs to specific edges, slots to other edges, and to extract the fold lines and cut lines into two separate shapes.

I tried using a SubLink to select the desired edges and a TopoSeries. This worked, but the selection of edges is very sensitive to changes in the sketch, just flipping an edge can completely change the order of the edges in the sketch's shape.

A hack to annotate edges in the sketcher was already in my drafts (it stores annotations inside the name of a dummy de-activated block constraint; unfortunately edges don't have names themselves nor any free-form field that could be repurposed, and their numbering changes all the time, so it's hard to keep track using a separate data structure; the sketcher correctly updates constraints and they do have a free-form name, so that's what I used).

This PR adds a new SketchEdges mode to the Downgrade tool, and an extra field containing a filtering script. The script is written in a silly but easy to implement stack-based language (just for this proof of concept, to avoid having to add a dependency on an interpreter for an existing script language). In retrospect, it would have been better to add this filtering mode to the Compound Filter tool, but I didn't know my way around Lattice2 yet when I started writing this a couple of days ago. Adding an embedded scripting language to the Compound Filter tool would be quite useful I think, regardless of the ability to annotate edges (which cannot be done without hacks of modifying FreeCAD's core, as far as I understand).

This PR also remembers the annotations present on the copies of the ObjectToTake of a TopoSeries, and makes these annotations available for filtering the result of the TopoSeries. My use case for this is to map a slot or tab on a set of edges, and extract the cut lines and fold lines of all copies of slots and tabs. Forwarding these annotations would be useful for all compounds, though I hope a cleaner solution will be available (native attributes of edges in FreeCAD) instead of having to manually copy this information.

Using a couple of helper macros which provide a simple UI to annotate edges and to automate the use of tools as described above, one can go from this
before
to this, in one step:
after

This capability to filter edges by their annotation already allowed me to attach a TopoSeries to some edges, but also to attach one-off features to one or more edges, i.e. it can be used as a form of named external geometry which is robust to changes in the original sketch.

By adding a few more math utilities to the script language and by granting access to a few more safe properties, I hope to be able to chain features in a way which is robust to the topological naming problem, and to some more significant changes in the topology than one would get with simple names, e.g. select the topmost edge on the Y axis, edge furthest from another etc.

Here's the FreeCAD document shown in the screenshots (of course it requires using this branch to recompute): pointy dodecahedron 003.FCStd.zip

🎄 ☃️

@DeepSOIC
Copy link
Owner

DeepSOIC commented Jan 1, 2021

This looks pretty cool! I hope to review it eventually, right now i'm traveling with my family and don't really have time for the stuff!

Is this only for realthunder's branch? Or for mainline FreeCAD?

@SuzanneSoy
Copy link
Author

SuzanneSoy commented Jan 2, 2021

Is this only for realthunder's branch? Or for mainline FreeCAD?

It's for mainline FreeCAD. Hopefully this hack will become obsolete at some point, but I didn't check if @realthunder's branch introduces names/annotations for sketch edges.

I doubt it would be a good idea to merge as-is, it's a proof of concept. My main issues with it are:

  • the hack using de-activated named block constraints to attach data to the edges (there seems to be several bugs where these constraints aren't properly de-activated and cause warnings or prevent modification of the sketch; it would be possible to use another constraint instead of the block one to circumvent that I think).
  • the scripting language which is really a minimal Turing tarpit; any embedded language that allows execution in a sandbox would be a better pick.

Enjoy your holidays :)

@DeepSOIC
Copy link
Owner

I have finally looked through the code.

Shape annotations look like a toponaming support that is limited to Lattice2. Since we have a working freecad-wide toponaming in realthunder's branch, i would really prefer to focus on that instead. Inventing an independent system will only lead to future incompatibility and confusion. So i'm sorry, but i'm not looking forward to this implementation.

As for this limited scripting language for filtering, it's an interesting idea. But making up a new language for that is indeed ugly, in my opinion. For toponaming-based filtering, we could simply support regular-expressions, i suppose. For more advanced filtering, FreeCAD's expressions are a potential fit. It would be nice if we could use it, but currently, the python bindings for them are quite limited, and i don't think it is possible right now.

@SuzanneSoy
Copy link
Author

Thanks a lot for the replies 😃 !

I quite agree the edge naming hack is not something that would be good to merge anywhere, it's just a hack for my personal use (the stuff I'm modelling really needs to extract sets of edges from a single sketch, and I don't want to be blocked until realthunder's branch gets merged into mainline FreeCAD).

For the filtering language, that was just to get a POC running. Since then I've spent a few hours looking for an embeddable language that would have no external dependencies, and found none. If I understand correctly, the requirements would be:

  • written in Python (I found plenty of embeddable scripting languages written in C or other languages, which would require having a C compiler on the user's machine, or to ship binaries with all the GLIB and platform compatibility problems that come with that)
  • have no external dependencies, not even Pip other python package managers, because a FreeCAD workbench cannot declare such dependencies (I found a few embeddable scripting languages written in Python but they all had some dependencies via a Pip or other; I guess it would be possible to copy-paste the dependencies as subfolders, I can make a short list of candidates if you think that's an okay solution).
  • have a compatible license (I don't want to hire a lawyer to understand what happens if one copy-pastes a GPL codebase into an LGPL one…)
  • safe (doesn't give access to the filesystem, doesn't have raw pointers etc. since scripts can be executed on document load / on document refresh, for untrusted documents).

Unfortunately I didn't find any existing project matching both of the first two requirements 😞.

Re-using FreeCAD's expressions is a nice idea, but currently these are very lacking in features. For example, I'd like to filter an array of shapes to select the ones smaller than a certain area, and enlarge them, leaving the others unchanged. This is not possible to do with FreeCAD's expressions, I doubt they give access to a shape's area, they definitely don't allow transforming shapes, and don't have any kind of loop construct.

Tonight or tomorrow night I'm going to replace that dummy POC language with a small implementation of Scheme (easy to write, easy to extend), but if you think the requirements I assumed above are misguided, I can try to use a third-party implementation of whatever language instead 😃.

@DeepSOIC
Copy link
Owner

For example, I'd like to filter an array of shapes to select the ones smaller than a certain area, and enlarge them, leaving the others unchanged. This is not possible to do with FreeCAD's expressions, I doubt they give access to a shape's area,

They actually do allow to query just about any attribute that is visible to python

@realthunder
Copy link

For the filtering language, that was just to get a POC running. Since then I've spent a few hours looking for an embeddable language that would have no external dependencies, and found none.

You can check out my FreeCAD expression extension here. You can try that using my release here.

I intend to merge this into upstream some time in the future. But due to security concern, calling Python functions is likely to be disabled by default. Accessing read only Python attributes should have no problem. Right now what's implemented in my branch is for every Python function call through expression to check its belonging module. Only a limited set of modules are allowed by default. User can white/black list modules.

@SuzanneSoy
Copy link
Author

For example, I'd like to filter an array of shapes to select the ones smaller than a certain area, and enlarge them, leaving the others unchanged. This is not possible to do with FreeCAD's expressions, I doubt they give access to a shape's area,

They actually do allow to query just about any attribute that is visible to python

Indeed, my bad, I underestimated what can be accessed in expressions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants