How does FreeCAD create objects from the FreeCAD document

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
simsiem
Posts: 46
Joined: Tue Feb 02, 2016 7:19 am

How does FreeCAD create objects from the FreeCAD document

Post by simsiem »

Hi,

let me introduce myself first. I am working on a detailed architectural model with FreeCAD. Lukily, I am familiar with both, Python and C++, from past projects. I worked on internal projects but also contributed to some open source projects (one of them, e.g., is the traffic simulator SUMO). At the moment, I add line and fill color for drawing views of Arch section planes. These colors should become configurable by the user. The feature branch is https://github.com/simsiem/FreeCAD/tree ... ction-view. Basically, it already works (see attachment).

When I add a new property to a FreeCAD object, this will certainly result in an additional value in the file format for persistence.
  • How does FreeCAD read document and create the 3D objects from it?
  • How can I ensure that the created FreeCAD object has the additional property when it is read from an older document, which does not yet contain the new property value?
Thanks for your support

Simon
Attachments
color_for_section_view.png
color_for_section_view.png (45.27 KiB) Viewed 1384 times
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: How does FreeCAD create objects from the FreeCAD document

Post by DeepSOIC »

simsiem wrote:How can I ensure that the created FreeCAD object has the additional property when it is read from an older document, which does not yet contain the new property value?
Hi! You need to test if the property exists (use hasattr for example) and create it if missing. I find it convenient to do in execute(), but it can be done immediately upon project load, by implementing onDocumentRestored(self, selfobj).
simsiem
Posts: 46
Joined: Tue Feb 02, 2016 7:19 am

Re: How does FreeCAD create objects from the FreeCAD document

Post by simsiem »

Hi DeepSOIC,

thanks for the very quick answer.

I've seen hasattrib distributed all over the code. Thus file format conversion (from old to new format) is actually distributed all over the code. Makes it hard to read the real algorithm and maintain the file format conversion right. Thus I would like to do the conversion once and maintain a clear object (as defined by its state (attributes) and functionality).

I'll take a look at onDocumentRestored. The name sounds promising.

Is there any document describing the state machine behind onDocumentRestored, Python's __init__, execute, ...?
simsiem
Posts: 46
Joined: Tue Feb 02, 2016 7:19 am

Re: How does FreeCAD create objects from the FreeCAD document

Post by simsiem »

I crawled through the code for a couple of hours with the following result. I think I could identify the problem as described in the "Consequences" section below.

Analysis
  1. The document starts reading from the XML file in void Document::Restore(Base::XMLReader &reader).
  2. In there, features are created with addObject(type.c_str(), name.c_str(), /*isNew=*/ false). In the case of an Arch section plane, the type is App::FeaturePython. For an Arch drawing view, the type is Drawing::FeatureViewPython.
  3. Later, the document's restore function calls the restore the function of each feature: pObj->Restore(reader). In both cases, thus for both feature types above, this simply restores the dynamic properties.

    Code: Select all

    void Restore(Base::XMLReader &reader) {
        props->Restore(reader);
    }
    ...
    DynamicProperty* props;
  4. In turn, the dynamic property class create the property objects and calls the restore function of each property object.

    Code: Select all

    prop = addDynamicProperty(TypeName, PropName, group, doc, attribute, readonly, hidden);
    ...
    prop->Restore(reader);
  5. Of special interest is the property Proxy for Python features. It refers to the Python implementation of the feature/view. This property is defined in FeaturePythonT as

    Code: Select all

    PropertyPythonObject Proxy;
    
    The save and restore functions of this property type use the Python pickle module, which features sophisticated serialization/deserialization with, e.g., __getstate__ and __setstate__. In this way, the developers has full control over the serialization and deserialization.
Consequences
  1. A property has full control to decide about its serialization/deserialization.
  2. A feature nearly has full control over serialization/deserialization too. The tricky thing is, when a property is renamed or substituted by, e.g., two connected new properties. But even this is realizable. For example, Part::Box does something like this. The comment for the restore function explains it well.
    This method was added for backward-compatibility. In former versions of Box we had the properties x,y,z and l,h,w which have changed to Location -- as replacement for x,y and z and Length, Height and Width.
  3. However, when implementing a feature in Python, you create properties in FeaturePython objects. These objects do not know the properties but are responsible for the serialization/deserialization. The Python code has no influence on the property creation. This is in contrast to Python properties, which solved the issue cleanly.
The last point looks like a design bug to me. FeaturePython should (optionally) delegate the serialization/deserialization into the Python code like the PropertyPythonObject does. There are many many hasattr branches in the Python code to get around this problem. They would not be necessary, when serialization/deserialization would be robust across versions of a feature.

In another project, we had a similar problem. It impeded continuous refactoring and code improvement, until we removed the impediment (broke backwards compatibility once). After that, we could evolve with backwards compatibility.

What do you think?

Simon
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: How does FreeCAD create objects from the FreeCAD document

Post by DeepSOIC »

I think FCTeleport.
Post Reply