Part Geometry Extensions

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
abdullah
Posts: 2818
Joined: Sun May 04, 2014 3:16 pm

Re: Part Geometry Extensions

Postby abdullah » Tue Jan 15, 2019 6:29 pm

wmayer wrote:
Tue Jan 15, 2019 2:27 pm
The code looks OK to me (but I didn't test it).
I am rather new to all this c++11 concepts so I expect corrections
Me too. I made my first C++11 experiences when working for v0.17.
I think this one is a good example where smart pointers may be useful.

Realthunder uses several concepts that are new to me, for example the move constructor. As I plan to find common ground with him in sketcher development, I am in the learning, which is always a good thing.

Let's see if I manage to provide a decent Python implementation. ;)
abdullah
Posts: 2818
Joined: Sun May 04, 2014 3:16 pm

Re: Part Geometry Extensions

Postby abdullah » Thu Jan 17, 2019 8:31 am

I managed to make some python wrappers work (no python extension yet), but now extensions are operable from Python like this:

Code: Select all

>>> geo0 = ActiveSketch.Geometry[0]
>>> geo1 = ActiveSketch.Geometry[1]
>>> geo0.getExtension("Sketcher::SketchGeometryExtension")
<SketchGeometryExtension (5) >
>>> ext0 = geo0.getExtension("Sketcher::SketchGeometryExtension")
>>> ext1 = geo1.getExtension("Sketcher::SketchGeometryExtension")
>>> ext1
<SketchGeometryExtension (5) >
>>> ext1.Id = 10
>>> ext1
<SketchGeometryExtension (10) >
>>> geo1.setExtension(ext1)
>>> geo1.getExtension("Sketcher::SketchGeometryExtension")
<SketchGeometryExtension (10) >
>>>
paullee
Posts: 1306
Joined: Wed May 04, 2016 3:58 pm

Re: Part Geometry Extensions

Postby paullee » Sat Jan 19, 2019 7:08 am

Hi, noted this discussion from https://forum.freecadweb.org/viewtopic. ... 20#p280687

Expecting this would be very useful!

Anywhere can download a compiled version for testing?

Seems target to be available in v0.19, right? Any chance for v0.18?

Thanks!
abdullah
Posts: 2818
Joined: Sun May 04, 2014 3:16 pm

Re: Part Geometry Extensions

Postby abdullah » Sun Jan 20, 2019 11:07 am

Welcome!
paullee wrote:
Sat Jan 19, 2019 7:08 am
Anywhere can download a compiled version for testing?
Not there yet. ATM the python interface is not even in my public FreeCAD fork. I have to review and restructure parts of my code.

Because there is no way yet to construct python extensions, the usability is also reduced to what is in c++, i.e. a single sketch extension allowing to store an id, which may be useful, but not that cool anyway.

It is likely that there will never be a compiled version for testing before it makes into master. When it works reasonably well, I will ask for a merge.
paullee wrote:
Sat Jan 19, 2019 7:08 am
Seems target to be available in v0.19, right? Any chance for v0.18?
No chance at all it will make it into v0.18. First it will not be finished in time. Second even if it were, it makes no sense to last-minute-push an poorly tested feature. That is the aim of development cycles. v0.19 development cycle has begun. For me v0.18 development cycle is closed, other than major bug fixing if one would be found.
paullee
Posts: 1306
Joined: Wed May 04, 2016 3:58 pm

Re: Part Geometry Extensions

Postby paullee » Wed Jan 23, 2019 3:19 pm

Thanks for the information, hope to test it soon :)
DeepSOIC
Posts: 6387
Joined: Fri Aug 29, 2014 12:45 am
Location: Saint-Petersburg, Russia

Re: Part Geometry Extensions

Postby DeepSOIC » Wed Jan 23, 2019 7:22 pm

I wonder if extension mechanism is the right tool for the job. I feel like you'd be better off implementing a Sketcher::Geometry base class from scratch, that will contain a Part::Geometry object as a py pointer/smart pointer. What's the benefit behind using extensions instead? Seems overly convoluted to me...
abdullah
Posts: 2818
Joined: Sun May 04, 2014 3:16 pm

Re: Part Geometry Extensions

Postby abdullah » Fri Jan 25, 2019 5:01 pm

DeepSOIC wrote:
Wed Jan 23, 2019 7:22 pm
I wonder if extension mechanism is the right tool for the job. I feel like you'd be better off implementing a Sketcher::Geometry base class from scratch, that will contain a Part::Geometry object as a py pointer/smart pointer. What's the benefit behind using extensions instead? Seems overly convoluted to me...
Hi there!

Composition or public inheritance were the first options I considered. Compatibility is the major drawback. It hits the user quite hard.

Because you are right about it being convoluted, at least for the very flexible implementation I described at the beginning of the thread, I am considering splitting the implementation into two stages. Stage1 would include only c++ defined extensions. Stage2 would include the option to have user-defined Python extensions.

To partly compensate for the basic needs of Python power users, Stage1 would include two very basic extensions, one for an int and another for a string. This should allow power users to reasonably increase flexibility in their designs at a low cost.

Now replying to your question in more detail:

The main advantage of the extension approach over Sketcher::Geometry is backward and forward compatibility with the sketcher. A (minor) additional advantage is to enable Python power users / WB developers to extend their geometries. The latter may be proved interesting for the Civil Engineering WB, for example.

Creating a Sketcher::Geometry implemented as a Part::Geometry (as composition, as you describe, no public inheritance therebetween), would lead to a non compatible serialisation format. In a good design, you may be able to get away with backwards compatibility, but not with forward, i.e. you may be able to redirect the old property to the new property (this has been done before in many places), but older FC would not understand the new property at all, so all the geometry stored with a new version will not be processed when read with an old version. This means an empty sketch on load. Of course, when loading in an older version there may be limitations of functionality, but it would read the sketch within the functionality that was available at that older version.

Additionally Part::Geometry is used in the Sketcher via Part::PropertyGeometryList, that is the property that implements serialisation, by calling the virtual function that every geometry inheriting from Part::Geometry has. You would need to create a Sketcher::PropertySketcherGeometryList as a list of Sketcher::Geometry and make this new property the one in the sketch. All this is not a lesser amount of work than a stage1 implementation of Geometry Extensions, and would be sketcher specific.

Considering Python geometry extensions (stage 2) is indeed a more convoluted implementation. It offers great flexibility indeed. However, here my current level of understanding of Python and its c++ interfacing is surpassed. I have an idea that I need a special extension to store a proxy object created by the python user and redirect the virtual methods to the python proxy object. I still get lost in the internals.

At this moment, I have just finished working on stage 1, which appears to work. I will release this code so that the community can check the code, the implementation and have a saying. You are more than welcome to have a look to the code, compile it, play with it and let me know what you think.

Code:
Branch

Usage (do forgive please my crappy Python skills, :oops:, I do it step by step, a pro can probably produce a one liner, :ugeek:, not me ;) ):

Example 1: adding an Int geometry extension to the first geometry of the sketch with a integer value 9:
>>> geometrylist = ActiveSketch.Geometry
>>> geo1 = geometrylist[0]
>>> gie = Part.GeometryIntExtension(9)
>>> geo1.setExtension(gie)
>>> geometrylist[0]=geo1
>>> ActiveSketch.Geometry = geometrylist
This can be read back:
>>> geometrylist = ActiveSketch.Geometry
>>> geo1 = geometrylist[0]
>>> geo1.getExtension('Part::GeometryIntExtension')
<GeometryIntExtension (9) >
NOTE: You may use "Value" on the extension to get the integer 9.

Example 2: modifying a string to a geometry object
>>> geometrylist = ActiveSketch.Geometry
>>> geo0 = geometrylist[0]
>>> gse = geo0.getExtension('Part::GeometryStringExtension')
>>> gse
<GeometryStringExtension (MyDearCircle) >
>>> gse.Value
'MyDearCircle'
>>> gse.Value = 'OhGoshMyPerfectCircle'
>>> geo0.setExtension(gse)
>>> geometrylist[0] = geo0
>>> ActiveSketch.Geometry = geometrylist
When saved, the xml looks like this (example with 3 extensions on a sketch having a single geometry):

Code: Select all

<Property name="Geometry" type="Part::PropertyGeometryList">
  <GeometryList count="1">
    <Geometry type="Part::GeomCircle">
      <GeoExtensions count="3">
        <GeoExtension type="Sketcher::SketchGeometryExtension" id="5"/>
        <GeoExtension type="Part::GeometryIntExtension" value="9"/>
        <GeoExtension type="Part::GeometryStringExtension" value="OhGoshMyPerfectCircle"/>
      </GeoExtensions>
      <Construction value="1"/>
      <Circle CenterX="11" CenterY="0" CenterZ="0" NormalX="0" NormalY="0" NormalZ="1" AngleXU="0" Radius="30"/>
    </Geometry>
  </GeometryList>
</Property>
Note, the SketchGeometryExtension is just a placeholder at this time.
abdullah
Posts: 2818
Joined: Sun May 04, 2014 3:16 pm

Re: Part Geometry Extensions

Postby abdullah » Fri Jan 25, 2019 6:50 pm

paullee wrote:
Sat Jan 19, 2019 7:08 am
Hi, noted this discussion from https://forum.freecadweb.org/viewtopic. ... 20#p280687

Expecting this would be very useful!

Anywhere can download a compiled version for testing?

Seems target to be available in v0.19, right? Any chance for v0.18?

Thanks!
Just in case you do not follow the thread. Now you have something to compile and test :)
paullee
Posts: 1306
Joined: Wed May 04, 2016 3:58 pm

Re: Part Geometry Extensions

Postby paullee » Sat Jan 26, 2019 12:36 am

abdullah wrote:
Fri Jan 25, 2019 6:50 pm
paullee wrote:
Sat Jan 19, 2019 7:08 am
Hi, noted this discussion from https://forum.freecadweb.org/viewtopic. ... 20#p280687

Expecting this would be very useful!

Anywhere can download a compiled version for testing?

Seems target to be available in v0.19, right? Any chance for v0.18?

Thanks!
Just in case you do not follow the thread. Now you have something to compile and test :)
Thanks:) Though I have very limited experience in compiling (once or twice for testing FC earlier), I would attempt when there is a gap :D

I guess (absolutely do not understand the discussion about C++, programming etc in above posts) the 'extension' approach allow user to 'arbitrary attributes' and hope it would be useful for me.
abdullah
Posts: 2818
Joined: Sun May 04, 2014 3:16 pm

Re: Part Geometry Extensions

Postby abdullah » Sat Jan 26, 2019 2:30 pm

paullee wrote:
Sat Jan 26, 2019 12:36 am
abdullah wrote:
Fri Jan 25, 2019 6:50 pm
paullee wrote:
Sat Jan 19, 2019 7:08 am
Hi, noted this discussion from https://forum.freecadweb.org/viewtopic. ... 20#p280687

Expecting this would be very useful!

Anywhere can download a compiled version for testing?

Seems target to be available in v0.19, right? Any chance for v0.18?

Thanks!
Just in case you do not follow the thread. Now you have something to compile and test :)
Thanks:) Though I have very limited experience in compiling (once or twice for testing FC earlier), I would attempt when there is a gap :D

I guess (absolutely do not understand the discussion about C++, programming etc in above posts) the 'extension' approach allow user to 'arbitrary attributes' and hope it would be useful for me.
As it is now, in that branch, you may store:
1) One int of your choice using a Part::GeometryIntExtension, as in the first example above
2) One string of your choice using a Part::GeometryStringExtension

As it is implemented now, you may store one extension of a given type maximum. So 1 GeometryIntExtension and 1 GeometryStringExtension.

You decide what you put there. Let me know if you have problems with it or just to let me know some feedback.