GSoC Proposal: Extended functionality of Rebar Addon
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
Re: GSoC Proposal: Extended functionality of Rebar Addon
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...
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...
- Suraj Dadral
- Posts: 307
- Joined: Fri Sep 07, 2018 5:32 pm
- Contact:
Re: GSoC Proposal: Extended functionality of Rebar Addon
Thanks @yorik
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.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,
- Suraj Dadral
- Posts: 307
- Joined: Fri Sep 07, 2018 5:32 pm
- Contact:
Re: GSoC Proposal: Extended functionality of Rebar Addon
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()
Code: Select all
doc_observer = BOMDocumentObserver()
FreeCAD.addDocumentObserver(doc_observer)
Going to start implementing user template for BOM using TechDraw objects.
Thanks,
Re: GSoC Proposal: Extended functionality of Rebar Addon
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.
- Suraj Dadral
- Posts: 307
- Joined: Fri Sep 07, 2018 5:32 pm
- Contact:
Re: GSoC Proposal: Extended functionality of Rebar Addon
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,
Re: GSoC Proposal: Extended functionality of Rebar Addon
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).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.
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.And we can use DocumentObserver to check for property change and perform required actions as here.
Here is code snippet for the same:We can add following lines in initialization file of rebar addon RebarTools.py to automatically add document observer.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()
Please let me know if there is any better way to do this.Code: Select all
doc_observer = BOMDocumentObserver() FreeCAD.addDocumentObserver(doc_observer)
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
- Suraj Dadral
- Posts: 307
- Joined: Fri Sep 07, 2018 5:32 pm
- Contact:
Re: GSoC Proposal: Extended functionality of Rebar Addon
+1
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
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,
Re: GSoC Proposal: Extended functionality of Rebar Addon
this is the way we normally extend objects in FreeCAD. You should go for this.
- Suraj Dadral
- Posts: 307
- Joined: Fri Sep 07, 2018 5:32 pm
- Contact:
Re: GSoC Proposal: Extended functionality of Rebar Addon
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,
Re: GSoC Proposal: Extended functionality of Rebar Addon
good idea the logs on the wiki.