[New feature] Shapestrings in PartDesign or Sketcher

About the development of the Part Design module/workbench. PLEASE DO NOT POST HELP REQUESTS HERE!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by abdullah »

davidosterberg wrote: Fri Jan 08, 2021 12:30 am I am ok, with closing this one, in favor of a Sketcher based tool. Oh well. I was hoping for a quick fix and on to the next one.
I have been working on an idea yesterday, the third alternative that I did not quite explain, using a Geometry Extension in the sketcher TextGeometryExtension (it exists in my computer, will publish later on).

The advantages of this idea are:
1. Transparent to the solver - no solver support for new geometry/constraints needed.
2. Rather translucid to the Sketcher in General - almost every tool works as before on "text objects" (small letter below). Most of the implementation concentrates on a single object, requiring 2 modifications outside this class (Sketch::toShape in Sketch.cpp and ViewProviderSketch::draw) and minor additions to command to create the text object. At a second phase maybe some minor handling of a new Sketcher internal alignment constraint (to derive the height of the font and make it "more parametric").
2. Low entry point (from a code point of view), enabling successive improvements (no need to produce lots of code at once)

Description of the basic idea

1. A geometry object defines the path to be followed by the text (similar to the screenshots shown in this thread). In my mind can be any object (preferably not a geom point, although it can be treated as a special case). We might talk here about a line, but it could be a B-Spline or an arc. Let's call this Base-Path.

2. This Part::Geometry object is added an extension to (TextGeometryExtension). This extension concentrates all font data members (type of font, tracking, italic,...). All this is exposed to Python, in the most basic idea, by the extension twin object, TextGeometryExtensionPy. In the most basic implementation, it also has the height of the font (but this I would really like to extend so that this aspect is controlled by the Sketcher via constraints, more below) and derives length and other parameters from the length of the path. This object is capable of two functions:
2.1. Create a TopoDS_Shape, preferably a plurality of Wires (but could also be a plurality of TopoDS_Edges), having the "profile" of the fonts along the path defined by the geometry. I have not seen your code, but you should have this somewhere.
2.2. Be able to draw the font profile into the scenography, into a SoLineSet or provide a way so that ViewProvider::draw can easily draw whatever is provided into a SoLineSet (more on this below).
3. The basic idea draws to the scenograph in the "information layer" (green layer used for B-Splines for curvature, poles, knot multiplicity). From there, we can evolve further then (in fact you may choose to first just output the shape and draw nothing, which would be similar in appearance to your sketch).

Showing something following this basic idea should have a relatively low entry point, with:
1. Creating the extension and configuring the parameters from Python
2. Adding the extension to a geometry from Python
3. Causing ViewProvider::draw to draw in the scenograph of any Geometry having a TextGeometryExtension.
4. Causing Sketch::toShape to add to the profile the wires of a Geometry having a TextGeometryExtension.

The end. You get a sketch with the profile of the shapes. This could be the "First milestone".

Parametric Height

Probably the best addition towards having the text substantially parametric, is to allow to have a line that one could constraint to a height. An image better that a thousand words:
Screenshot_20210109_083749.png
Screenshot_20210109_083749.png (37.42 KiB) Viewed 5844 times
Those are two fully constrained "Text Placeholders". The place holder should allow to constraint the text from the sketcher point of view (height and length).

Here you need to imagine two things:
1) that you see a green profile of the text in the information layer following the Base-Path.
2) that the perpendicular line defining the height is not blue, but yellow (internal geometry)

Point 2) is the important bit here:
2.1. The alignment constraint should be added a new Alignment type (HeightAlignment), and the corresponding alignment to the InternalGeometryType status (status is controlled by constraint life time, there are tons of examples of this, like the major axis of a ellipse, for example).
2.2. Sketch.cpp is modified to implement this constraint of the aligmnentconstraint as a perpendicular to a the Base-Path at its starting point (basically all this is available, is putting some glue in).
2.3. In TextGeometryExtension, you need to get the dimension of that line (this needs to solve the challenge that a Geometry extension has no knowledge of the SketchObject, and a dependency here from sketch is probably not acceptable, so some helper object would need to convey this information). Identifying the line is easy, because it is the one having the alignment constraint of alignment type "HeightAlignment" to the base geometry.

Creation of the text

The text creating tool is CommandSketcherTool (in that .cpp). One basic option can be to take the Base-Path object, click the tool, get a pop-up with text editor information (similar to the Datum Edit Dialog, but for text, with the text properties), add the "HeightAlignment" line with the alignment constraint.

In addition or instead, there can be a lot of commands under a single icon (as all the conics that appear when clicking the arrow), one icon per each supported sketcher geometry, and from there a "text placeholder" is created. Probably not a great idea. But a good incentive so that the community things how they want it. They excel at that :D.

Other forms of sketcher text representation and possibilities - advanced

Above I selected to draw the letters on the information layer. This has advantages:
- If one does lines, one interferes with the line selection mechanism and the mapping of ViewProvider "CurveId" to GeoId, basically is a sandbox where one only needs to take care not to interfere with other information layer... information, which basically only happens with B-Splines.

And disadvantages? (not sure if they are features, time will tell):
- No possibility of having the edges as geometry (external geometry or real geometry) and be able to edit them individually.

If drawing to the SoLineSet is done properly, it should be possible to just switch from one layer to the other. At the end Coin representation in the Sketcher, is similar for the normal layer and the information layer.

There is one thing I would like to know: Are you in for the challenge?
davidosterberg
Posts: 529
Joined: Fri Sep 18, 2020 5:40 pm

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by davidosterberg »

Fantastic Abdullah. You have drawn up a Roadmap and convinced me that it is feasible to implement without too large a disruption for Sketcher.

abdullah wrote: Sat Jan 09, 2021 8:06 am Probably the best addition towards having the text substantially parametric, is to allow to have a line that one could constraint to a height.
This is the one thing I disagree with. This sounds tedious to me (create line, constrain perpendicular, create dimension, enter size) , compared to entering a simple number (that also will have a name and be bound to the Expression engine.). It is also counterintuitive as every user has preconceived ideas of how to enter font size.

abdullah wrote: Sat Jan 09, 2021 8:06 am
There is one thing I would like to know: Are you in for the challenge?
I am, but it will be a longer term project. I was hoping to get the PD text utility in for 0.19. This sounds like 0.2 to me.
chrisb
Veteran
Posts: 53786
Joined: Tue Mar 17, 2015 9:14 am

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by chrisb »

abdullah wrote: Sat Jan 09, 2021 8:06 am 2.1. The alignment constraint should be added a new Alignment type (HeightAlignment), and the corresponding alignment to the InternalGeometryType status (status is controlled by constraint life time,
Thanks for this clarification what a ShapeString can be outside of Draft together with a plan for its implementation!

Does it really need a new constraint? Or could this be achieved with the already existing length constraint? When we handle ShapeStrings as a whole, I see two major usecases of how to constrain it inside of a sketch: constrain the height of the ShapeString, which is what your proposal describes; this would automatically adapt the width. And the other use case: constrain the width, which would automatically adapt the height. To get both together with the position and the angle, we could use internal construction geometry in the form of a rectangle. It would not be possible to constrain both height and width, because they depend on each other.

It has to be decided if such a rectangle should be the bounding box or depend on the geometry of the ShapeString with all its kerning stuff.
davidosterberg wrote: Sat Jan 09, 2021 8:29 am This sounds tedious to me (create line, constrain perpendicular, create dimension, enter size) , compared to entering a simple number (that also will have a name and be bound to the Expression engine.). It is also counterintuitive as every user has preconceived ideas of how to enter font size.
It may be easier to enter a simple number, but then we don't really take much advantage of integrating it into sketcher. The Draft ShapeStrings can do it, and then only the allignment is left.

It supports the workflow where you have a certain ShapeString and model the rest around it. It doesn't really support the other way, where you may have certain geometric limitations, such as the height of a box, to which you want the ShapeString to adapt.

In many cases the height could be derived by some expression, but as we advocate using as few measures as possible for good reasons this wouldn't really improve things. Furthermore, if driven measures are involved, that may require an additional sketch.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
davidosterberg
Posts: 529
Joined: Fri Sep 18, 2020 5:40 pm

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by davidosterberg »

chrisb wrote: Sat Jan 09, 2021 9:49 am It may be easier to enter a simple number, but then we don't really take much advantage of integrating it into sketcher. The Draft ShapeStrings can do it, and then only the allignment is left.

It supports the workflow where you have a certain ShapeString and model the rest around it. It doesn't really support the other way, where you may have certain geometric limitations, such as the height of a box, to which you want the ShapeString to adapt.
It is not that it is difficult to implement, or without merits. I am meerly saying that it might not be what the user wants :)
In the PD text tool, I planned to set the inital text size based on the line length. But provide the spin box for the user to set what he wants or an expression.

There could be a checkbox to say "Scale font size with line length" or similar. Default of this checkbox is TBD.
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by abdullah »

davidosterberg wrote: Sat Jan 09, 2021 8:29 am Fantastic Abdullah. You have drawn up a Roadmap and convinced me that it is feasible to implement without too large a disruption for Sketcher.

I am, but it will be a longer term project. I was hoping to get the PD text utility in for 0.19. This sounds like 0.2 to me.
Happy to see you in. I am not sure whether it will be 0.19 or 0.20. It will be ready when it is.

Because development master in FC is rather stable, we get a reasonable amount of testers for a development release. I would dare to say that unless somebody is doing a big project, people tend to use the development release. It is not such a big deal whether it is 0.19 or 0.20 to me. I will be using 0.20 the day after the release :)
davidosterberg wrote: Sat Jan 09, 2021 8:29 am
abdullah wrote: Sat Jan 09, 2021 8:06 am Probably the best addition towards having the text substantially parametric, is to allow to have a line that one could constraint to a height.
This is the one thing I disagree with. This sounds tedious to me (create line, constrain perpendicular, create dimension, enter size) , compared to entering a simple number (that also will have a name and be bound to the Expression engine.). It is also counterintuitive as every user has preconceived ideas of how to enter font size.
I did not mean you had to do all that. Rather I intended that all that was provided for by the tool. You would not see a perpendicular constraint either, because that would be "embedded" in the internal alignment constraint (at solver level). This is, it would not be a new sketcher constraint, rather a new alignment type of the internal alignment constraint. But somehow I did not realise this leads to an overconstrained system. Shame on me. Nevermind. Let this be a second stage. We can start with a line and constraint the length. Then we will see how it looks like and whether other ways make sense or not.
chrisb wrote: Sat Jan 09, 2021 9:49 am Does it really need a new constraint? Or could this be achieved with the already existing length constraint? When we handle ShapeStrings as a whole, I see two major usecases of how to constrain it inside of a sketch: constrain the height of the ShapeString, which is what your proposal describes; this would automatically adapt the width. And the other use case: constrain the width, which would automatically adapt the height. To get both together with the position and the angle, we could use internal construction geometry in the form of a rectangle. It would not be possible to constrain both height and width, because they depend on each other.

It has to be decided if such a rectangle should be the bounding box or depend on the geometry of the ShapeString with all its kerning stuff.
The thing with constraining both, length and height, is that they are related. The relation not known to the solver. This would require to model it in the solver. I would say we start with the line like David had in his screenshot. Then from there we decide if we want to create two modes. One restraining the height and another the length. Then, we could even do some trick, like providing both, but one been blocked (with the new block constrain), while the other move and a way to switch from one to the other. Maybe the switch of mode then could be automatic. If the user constraints the length, he would get conflicting constraint when trying to constraint the height, and if he constraints the heights first, he would get the conflicting constraint when trying to set the length. Those are small things that can be adjusted on a second phase. The bounding box could also be provided in the information layer if appropriate.
davidosterberg wrote: Sat Jan 09, 2021 11:35 am It is not that it is difficult to implement, or without merits. I am meerly saying that it might not be what the user wants :)
In the PD text tool, I planned to set the inital text size based on the line length. But provide the spin box for the user to set what he wants or an expression.

There could be a checkbox to say "Scale font size with line length" or similar. Default of this checkbox is TBD.
If we are providing a Sketcher object, I think it makes sense it operates as other objects. Also think that Geometry Extensions are not DocumentObjects and they do not have properties (in the sense of FreeCAD). Anyway, first milestone, we constraint with the length of the line.

So, today I have been away from the computer, so I have not advanced. I have just merged the a refactor of Geometry Extensions which allows us to get a pointer to the Part::Geometry container. Tomorrow, I will rebase the TextGeometryExtension on the current master and will set a development branch. Organise the work and then, we can work on it together. Yup, sounds like a plan. :D
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by abdullah »

So branch:
https://github.com/abdullahtahiriyo/Fre ... xtgeometry_

I have invited you granting write access to that branch. So you may push commits directly there if you wish (it should be more agile than cherry-picking range of commits and rebasing).

What is that branch?

Basically one Geometry Extension, TextGeometryExtension, its Python twin, some code to process wires and compounds into the Sketcher profile and a demo placeholder for a Coin representation.

How can I add an extension and test the framework?

1. Draw a line in a Sketch (it can be any geometry)

Code: Select all

gfs = ActiveSketch.GeometryFacadeList
bsp = gfs[0]
ext=Sketcher.TextGeometryExtension(True)
bsp.setExtension(ext)
gfs[0] = bsp
ActiveSketch.GeometryFacadeList = gfs
With that code you create an extension for the geometry with GeoId=0, which is enabled (True) and will produce a non-empty shape if toShape() called.

2. List the geometry extensions of a geometry (GeoId = 0)

Code: Select all

gfs = ActiveSketch.GeometryFacadeList
bsp = gfs[0]
bsp.getExtensions()
3. Make Coin representation for Text geometries visible:

Code: Select all

hgrp = App.ParamGet('User parameter:BaseApp/Preferences/Mod/Sketcher/General')
hgrp.GetBool('TextGeometryVisible')
hgrp.SetBool('TextGeometryVisible',True)
You should see this:
Screenshot_20210110_080207.png
Screenshot_20210110_080207.png (5.87 KiB) Viewed 5680 times
First assignment: Generate the profile

I think it makes sense to start from the easiest lower entry point. As you have code to produce a profile, it goes like this:

Goal 1: Produce a profile for a string.

Modify TextGeometryVisible to store what you need to produce a string. TextGeometryExtension::toShape() must produce a Wire or a compound of Wires. Take a look at Sketch::toShape() to see how this information will be interpreted and inserted in the sketcher profile.

Goal 2: Produce a profile following the path of the geometry, geometry/orientation and possibly using the length of the geometry

Remember you have a pointer to the geometry. From that pointer you can ask OCCT the path, position and length. References for further reading (ViewProvider::draw() and Part::Geometry).

Second assignment: Coin representation

By this moment, you would be fed-up of seeing that awful 3 lines (yes, they are awful to motivate you :mrgreen: ).

Goal 3: Show text profiles in information layer.

ViewProvider::draw() needs a refactoring. One of the reasons to introduce GeometryExtensions was to facilitate this refactor, by delegating drawing to geometry extensions. But we are not refactoring it right now.

We are painting using linesets. A SoLineSet is a set of lines in a single object. We discretise arcs (there is a variable telling you how many segments per geometry are used, which is a preference, so that individual curves get discretised to the same extent arcs, for example are). The SoLineSet has coordinates and index, the later basically indicates how many coordinates the line takes, so if you set 2 it will be a line segment taking two coordinates. If you set 50, it will consume 50 coordinates producing a polygon (hopefully approximating that line you want).

Discussion/Doubts/Help

Probably you will be able to do this without help, but ping me here if you have doubts or want to discuss an issue.
Svet
Posts: 42
Joined: Fri Feb 12, 2021 1:00 am
Location: USA, Texas

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by Svet »

Just curios is this idea in work/postponed/dead? Link to the branch looks like broken or branch not exists anymore... For me having dedicated tool for text is very good idea, BTW!

Thanks for your effort!
User avatar
iplayfast
Posts: 256
Joined: Sat Sep 07, 2019 6:55 am

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by iplayfast »

Bump? I too have had to relearn draft shape to part design again. (it is very unintuitive)
The idea of a way to enter text directly in sketcher is very appealing.
kisolre
Veteran
Posts: 4159
Joined: Wed Nov 21, 2018 1:13 pm

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by kisolre »

As always late for the show... But what is the actual problem that has to be solved here? Currently Shapestring has attachment property by default. And can be just dragged over a body,, then mapped as any sketch, and used for any PD feature that accepts faces/edges/... as input.
Having good default font, ability to directly create it under a body from PD WB with attachment (as sketch does), some extra shapestring properties (scale, stretch, skew, alignment, ...) would be better additions IMO.
Attachments
PD shape string.JPG
PD shape string.JPG (110.69 KiB) Viewed 2821 times
User avatar
Pauvres_honteux
Posts: 728
Joined: Sun Feb 16, 2014 12:05 am
Location: Far side of the moon

Re: [New feature] Shapestrings in PartDesign or Sketcher

Post by Pauvres_honteux »

abdullah wrote:
Hi guys!
How about this principle?
User start a tool (text?) and fill in his/hers desired text.

The tool then:
- creates a new sketch per letter/symbol.
- register and stores them sketches positions and orientations.
- tool indentifies problematic sketches.
- user can now easily fix any problematic/offending letter/symbol on per letter/symbol basis.
- tool can now place and orientate each sketch to users liking, e.g. along a 3D curve on a double curved surface.
- tool extrudes all sketches in a single direction or per surface normal per sketch.
- user will be fully accountable for making extrudes manufacturable. Though tool may give a hint about intersecting extrudes.
Post Reply