GSoC Proposal: Extended functionality of Rebar Addon

A forum dedicated to the Draft, Arch and BIM workbenches development.
User avatar
yorik
Site Admin
Posts: 12034
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels, Belgium
Contact:

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby yorik » Wed May 06, 2020 11:09 am

Great work so far @Suraj!

I would also like the user to be able to use their own SVG template. One might want completely different layouts, for ex. with the logo left, or at the bottom, etc... I think a good way would be to format your code so that it inserts an SVG chunk inside an existing SVG doc, for example the same way as TechDraw works (there is a <!--drawingcontent--> tag inside the SVG file, TechDraw just locates it and replaces it with its contents.

Then you can still keep your current tool to create a new SVG file if the user doesn't provide one...
User avatar
Suraj Dadral
Posts: 292
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby Suraj Dadral » Thu May 07, 2020 3:28 am

yorik wrote:
Wed May 06, 2020 11:09 am
Great work so far @Suraj!
Thanks @yorik
yorik wrote:
Wed May 06, 2020 11:09 am
I would also like the user to be able to use their own SVG template. One might want completely different layouts, for ex. with the logo left, or at the bottom, etc... I think a good way would be to format your code so that it inserts an SVG chunk inside an existing SVG doc, for example the same way as TechDraw works (there is a <!--drawingcontent--> tag inside the SVG file, TechDraw just locates it and replaces it with its contents.

Then you can still keep your current tool to create a new SVG file if the user doesn't provide one...
Thanks for your guidance. I will use TechDraw objects for this. Thus user will be also able to edit template after creation of BOM. It will be implemented soon.

Thanks,
User avatar
Suraj Dadral
Posts: 292
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby Suraj Dadral » Thu May 07, 2020 4:17 am

amrit3701 wrote:
Tue May 05, 2020 6:22 pm

The output looks awesome!. Related to adding missing properties to TechDraw objects, here I am not sure because TechDraw objects have no Proxy. Don't know we can extend TechDraw objects to python scripted object or not. Please test it.
Hi @amrit3701, you are right that we can't extend TechDraw objects to python scripted object (atleast I am unable to find it).

But I found a way to achieve what we want.
In FreeCAD 0.19, as I found here:, there is addProperty method available for objects, which can be used to add properties to objects dynamically.
And we can use DocumentObserver to check for property change and perform required actions as here.

Here is code snippet for the same:

Code: Select all

from PySide2.QtCore import QT_TRANSLATE_NOOP
import FreeCAD


class BOMDocumentObserver:
    def slotChangedObject(self, obj, prop):
        if hasattr(obj, "BOMContent"):
            if prop == "FontStyle":
                print("Perform task for bom content font change", obj.FontStyle)


def addBOMContentProperties(svg_symbol_obj):
    if hasattr(svg_symbol_obj, "TypeId"):
        if svg_symbol_obj.TypeId != "TechDraw::DrawViewSymbol":
            FreeCAD.Console.PrintError(
                'TypeError: object of type "TechDraw::DrawViewSymbol" is '
                "expected.\n"
            )
            return

    pl = svg_symbol_obj.PropertiesList

    if "BOM_content" not in pl:
        svg_symbol_obj.addProperty(
            "App::PropertyBool", "BOMContent", "BOM content"
        )
        svg_symbol_obj.setEditorMode("BOMContent", 2)

    if "FontStyle" not in pl:
        svg_symbol_obj.addProperty(
            "App::PropertyFont",
            "FontStyle",
            "BOM content",
            QT_TRANSLATE_NOOP(
                "App::Property", "The font style of bill of material content.",
            ),
        )

    doc_observer = BOMDocumentObserver()
    FreeCAD.addDocumentObserver(doc_observer)


bom_content = FreeCAD.ActiveDocument.addObject('TechDraw::DrawViewSymbol','BOM_content')
addBOMContentProperties(bom_content)
FreeCAD.ActiveDocument.recompute()
We can add following lines in initialization file of rebar addon RebarTools.py to automatically add document observer.

Code: Select all

doc_observer = BOMDocumentObserver()
FreeCAD.addDocumentObserver(doc_observer)
Please let me know if there is any better way to do this.
Going to start implementing user template for BOM using TechDraw objects.

Thanks,
User avatar
bernd
Posts: 10806
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby bernd » Thu May 07, 2020 5:24 am

have you tested without the observer? In FEM I do similar adding of attributes but without an observer. Since I have never used TechDraw I am not sure but its worth a try.
User avatar
Suraj Dadral
Posts: 292
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby Suraj Dadral » Thu May 07, 2020 10:23 am

bernd wrote:
Thu May 07, 2020 5:24 am
have you tested without the observer? In FEM I do similar adding of attributes but without an observer. Since I have never used TechDraw I am not sure but its worth a try.
Hi @bernd

I tried after your suggestion. Properties added fine, but font does not change in BOM content ("TechDraw::DrawViewSymbol"), when changing its font property.
Or I am doing something wrong?

Thanks,
User avatar
amrit3701
Posts: 306
Joined: Mon Jun 13, 2016 5:37 pm

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby amrit3701 » Thu May 07, 2020 10:55 am

Suraj Dadral wrote:
Thu May 07, 2020 4:17 am
Hi @amrit3701, you are right that we can't extend TechDraw objects to python scripted object (atleast I am unable to find it).

But I found a way to achieve what we want.
In FreeCAD 0.19, as I found here:, there is addProperty method available for objects, which can be used to add properties to objects dynamically.
Yes, that's normal. Because TechDraw objects are created in C++ and to C++ objects we can add attributes/property dynamically. In Python, we can add any stuff to object dynamically (For eg. create an object, then add attribute).
And we can use DocumentObserver to check for property change and perform required actions as here.

Here is code snippet for the same:

Code: Select all

from PySide2.QtCore import QT_TRANSLATE_NOOP
import FreeCAD


class BOMDocumentObserver:
    def slotChangedObject(self, obj, prop):
        if hasattr(obj, "BOMContent"):
            if prop == "FontStyle":
                print("Perform task for bom content font change", obj.FontStyle)


def addBOMContentProperties(svg_symbol_obj):
    if hasattr(svg_symbol_obj, "TypeId"):
        if svg_symbol_obj.TypeId != "TechDraw::DrawViewSymbol":
            FreeCAD.Console.PrintError(
                'TypeError: object of type "TechDraw::DrawViewSymbol" is '
                "expected.\n"
            )
            return

    pl = svg_symbol_obj.PropertiesList

    if "BOM_content" not in pl:
        svg_symbol_obj.addProperty(
            "App::PropertyBool", "BOMContent", "BOM content"
        )
        svg_symbol_obj.setEditorMode("BOMContent", 2)

    if "FontStyle" not in pl:
        svg_symbol_obj.addProperty(
            "App::PropertyFont",
            "FontStyle",
            "BOM content",
            QT_TRANSLATE_NOOP(
                "App::Property", "The font style of bill of material content.",
            ),
        )

    doc_observer = BOMDocumentObserver()
    FreeCAD.addDocumentObserver(doc_observer)


bom_content = FreeCAD.ActiveDocument.addObject('TechDraw::DrawViewSymbol','BOM_content')
addBOMContentProperties(bom_content)
FreeCAD.ActiveDocument.recompute()
We can add following lines in initialization file of rebar addon RebarTools.py to automatically add document observer.

Code: Select all

doc_observer = BOMDocumentObserver()
FreeCAD.addDocumentObserver(doc_observer)
Please let me know if there is any better way to do this.
I don't think this is a good way. Add observers to FreeCAD slow down each FreeCAD process. Assume you add this document observer in FreeCAD and the FreeCAD document has 100 objects, then it triggers for each object which is not good.

The best way to use Python object of TechDraw workbench (TechDraw::DrawPagePython, TechDraw::DrawSVGTemplatePython) but as these objects has no Proxy in there view providers and I don't know how much complex this is...

Maybe @Bernd and @Yorik help here.

thanks
User avatar
Suraj Dadral
Posts: 292
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby Suraj Dadral » Thu May 07, 2020 1:06 pm

amrit3701 wrote:
Thu May 07, 2020 10:55 am
I don't think this is a good way. Add observers to FreeCAD slow down each FreeCAD process. Assume you add this document observer in FreeCAD and the FreeCAD document has 100 objects, then it triggers for each object which is not good.
+1
amrit3701 wrote:
Thu May 07, 2020 10:55 am
The best way to add Python object to TechDraw workbench (TechDraw::DrawPagePython, TechDraw::DrawSVGTemplatePython) so by using these objects we can create our own Python scripted object. But I don't know how much complex this is...
Thanks @amrit3701
Fortunately, these objects exists: TechDraw::DrawViewSymbolPython, TechDraw::DrawPagePython and TechDraw::DrawTemplatePython.

And here is an example for adding "FontStyle" property to BOM_content (TechDraw::DrawViewSymbolPython):

Code: Select all

from PySide2.QtCore import QT_TRANSLATE_NOOP
import FreeCAD


class BOMContent:
    "A Rebars Bill of Material SVG Content object."

    def __init__(self, obj_name):
        bom_content = FreeCAD.ActiveDocument.addObject(
            "TechDraw::DrawViewSymbolPython", obj_name
        )
        self.setProperties(bom_content)
        bom_content.Proxy = self

    def setProperties(self, obj):
        self.Type = "BOMContent"
        pl = obj.PropertiesList
        if "FontStyle" not in pl:
            obj.addProperty(
                "App::PropertyFont",
                "FontStyle",
                "BOM content",
                QT_TRANSLATE_NOOP(
                    "App::Property",
                    "The font style of bill of material content.",
                ),
            )

    def onChanged(self, fp, prop):
        """Do something when a property has changed"""
        FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")

    def onDocumentRestored(self, obj):
        pass

    def execute(self, obj):
        pass
And example file:
test_obj.FCStd
(18.42 KiB) Downloaded 8 times
For this file to work, you may need to place above code in file: BillOfMaterial/new_obj.py

Before actually implementing user template, I am planning to improve svg code for BOM using "xml" library of python. So, it will be easier to do modifications after that.

Thanks,
User avatar
bernd
Posts: 10806
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby bernd » Thu May 07, 2020 3:09 pm

this is the way we normally extend objects in FreeCAD. You should go for this.
User avatar
Suraj Dadral
Posts: 292
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby Suraj Dadral » Thu May 07, 2020 6:23 pm

bernd wrote:
Thu May 07, 2020 3:09 pm
this is the way we normally extend objects in FreeCAD. You should go for this.
OK. Presently, I am modifying code to use "xml" python library. Hope, it will be finished before morning.
I will start implementing the above after that.

BTW, I created a page on freecad wiki to keep logs as we did previous year: https://wiki.freecadweb.org/User:Suraj_ ... SoC20/logs

Thanks,
User avatar
bernd
Posts: 10806
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: GSoC Proposal: Extended functionality of Rebar Addon

Postby bernd » Thu May 07, 2020 6:27 pm

good idea the logs on the wiki.