first attempt to write FreeCAD code (for Arch module)

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!
lambda
Posts: 91
Joined: Sat Feb 25, 2017 3:10 pm
Contact:

first attempt to write FreeCAD code (for Arch module)

Post by lambda »

Hi,

not sure if this belongs here or into the Arch-subforum. Since my questions isn't really Arch related, I try here.

I'm playing with the following trivial patch, which allows me to create ladder style staircases often built from wood:

Code: Select all

diff --git a/src/Mod/Arch/ArchStairs.py b/src/Mod/Arch/ArchStairs.py
index 15f2196..30a831d 100644
--- a/src/Mod/Arch/ArchStairs.py
+++ b/src/Mod/Arch/ArchStairs.py
@@ -128,6 +128,7 @@ class _Stairs(ArchComponent.Component):
         obj.addProperty("App::PropertyLength","StructureThickness","Structure",QT_TRANSLATE_NOOP("App::Property","The thickness of the massive structure or of the stringers"))
         obj.addProperty("App::PropertyLength","StringerWidth","Structure",QT_TRANSLATE_NOOP("App::Property","The width of the stringers"))
         obj.addProperty("App::PropertyLength","StructureOffset","Structure",QT_TRANSLATE_NOOP("App::Property","The offset between the border of the stairs and the structure"))
+        obj.addProperty("App::PropertyLength","StringerOverlap","Structure",QT_TRANSLATE_NOOP("App::Property","The overlap of the stringers above the bottom of the treads"))
 
         obj.Align = ['Left','Right','Center']
         obj.Landings = ["None","At center","At each corner"]
@@ -417,7 +418,7 @@ class _Stairs(ArchComponent.Component):
             if obj.StringerWidth.Value and obj.StructureThickness.Value:
                 hyp = math.sqrt(vHeight.Length**2 + vLength.Length**2)
                 l1 = Vector(vLength).multiply(numberofsteps-1)
-                h1 = Vector(vHeight).multiply(numberofsteps-1).add(Vector(0,0,-abs(obj.TreadThickness.Value)))
+                h1 = Vector(vHeight).multiply(numberofsteps-1).add(Vector(0,0,-abs(obj.TreadThickness.Value)+obj.StringerOverlap.Value))
                 p1 = vBase.add(l1).add(h1)
                 p1 = self.align(p1,obj.Align,vWidth)
                 lProfile.append(p1)
This mostly works, but when loading an old file with a staircase into my patched version of FreeCAD, I get an exception because the StringerOverlap property is missing. What is the FreeCAD way to ensure that objects are extended with new properties in such situations?
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: first attempt to write FreeCAD code (for Arch module)

Post by yorik »

Hi,
basically you must check that the property exists, everywhere you are using it. Unfortunately there is not much other way. You can do that like this:

Code: Select all

if hasattr(myObj,"MyProperty"):
or

Code: Select all

if "MyProperty" in myObj.PropertiesList:
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: first attempt to write FreeCAD code (for Arch module)

Post by yorik »

But indeed one day we should think of an uniform way to upgrade missing properties in python objects...
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: first attempt to write FreeCAD code (for Arch module)

Post by Kunda1 »

yorik wrote:But indeed one day we should think of an uniform way to upgrade missing properties in python objects...
Created issue #2977 to keep track of this :)
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
lambda
Posts: 91
Joined: Sat Feb 25, 2017 3:10 pm
Contact:

Re: first attempt to write FreeCAD code (for Arch module)

Post by lambda »

Thanks for the answers. I will upgrade my code as suggested and open a PR.

I note there are two possible semantics for StringerOverlap - vertical as I chose or normal to the stringer. Vertical seems more natural to me, because it then relates to the thickness of the treads easily, but let me know if you prefer the other.

I will ask my local python guru, how the problem might be solved in a general way.
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: first attempt to write FreeCAD code (for Arch module)

Post by Kunda1 »

lambda wrote: Tue Mar 21, 2017 10:08 am Thanks for the answers. I will upgrade my code as suggested and open a PR.

I note there are two possible semantics for StringerOverlap - vertical as I chose or normal to the stringer. Vertical seems more natural to me, because it then relates to the thickness of the treads easily, but let me know if you prefer the other.

I will ask my local python guru, how the problem might be solved in a general way.
@lambda any progress?
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
lambda
Posts: 91
Joined: Sat Feb 25, 2017 3:10 pm
Contact:

Re: first attempt to write FreeCAD code (for Arch module)

Post by lambda »

Kunda1 wrote: Fri Jun 16, 2017 8:06 pm
lambda wrote: Tue Mar 21, 2017 10:08 am I will ask my local python guru, how the problem might be solved in a general way.
@lambda any progress?
Not really. My python guru pointed out that freecad is a horrible piece of code, not following proper object oriented semantics - or rather inventing its own rather then using what python provides natively. Claiming that everything would be trivial if things were done the python way...

So I tried to do some experiments on my own, realizing that existing objects can be used to initialize new objects, but so far nothing came from that either. The idea is to use a broken object as template for a new object and then delete/replace the broken object. Maybe it is a good idea, and only my python skills are not up to it, but maybe there is some reason why this can't work. I have very little time for software work during the warm season, so I won't work on this in the next few month, if ever.
ezzieyguywuf
Posts: 656
Joined: Tue May 19, 2015 1:11 am

Re: first attempt to write FreeCAD code (for Arch module)

Post by ezzieyguywuf »

lambda wrote: Sat Mar 18, 2017 7:26 pm This mostly works, but when loading an old file with a staircase into my patched version of FreeCAD, I get an exception because the StringerOverlap property is missing. What is the FreeCAD way to ensure that objects are extended with new properties in such situations?
There is no way to ensure this. What you would have to do is create a converter from the old-style _Stairs to the new-style _Stairs. Then, you could add a check whenever a file is opened: if the object is old-style, pass it through the converter to upgrade it to the new-style.

This is a standard procedure that I would expect to deal with when extending any piece of software, not just FreeCAD.
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: first attempt to write FreeCAD code (for Arch module)

Post by yorik »

lambda wrote: Fri Jul 28, 2017 4:17 pmNot really. My python guru pointed out that freecad is a horrible piece of code, not following proper object oriented semantics - or rather inventing its own rather then using what python provides natively. Claiming that everything would be trivial if things were done the python way...
I MUST reply this :) There are indeed a couple of things that don't follow the python standards (there are several ongoing discussions to fix that), but saying that "freecad is a horrible piece of code" is just silly, I don't think your guru looked very far. The FreeCAD code is pretty nice and clean,actually. FreeCAD is a C++ app with python bindings, not a pure python app. Every C++ app with python bindings out there has the same "particularities" (Blender, Inkscape, Gimp, any of them). I guess you must put that on the fact that people who coded it didn't really take the time to read and apply all the python codes of conduct... But FreeCAD has a very large part and hundreds of external scripts and tools, all written in python, and nobody complained that it's horrible or that it would be trivial if things were done differently.

Programming for 3D parametric modeling is difficult, there are a lot of different and complex software libraries involved. There is no magical way out of that. And working on stairs, you have chosen quite a complex subject too ;)
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: first attempt to write FreeCAD code (for Arch module)

Post by yorik »

About the "missing" properties when loading an old document, I am beginning to use this technique, I think it works quite well, it's to add an onDocumentRestored function to objects, and, in it, check if all the properties are there and create them if needed. So the python object becomes:

Code: Select all

def __init__(self,obj):
    obj.Proxy = self
    self.addProperties(self,obj)

def onDocumentRestored(self, obj):
    self.addProperties(self,obj)

def addProperties(self,obj):
    if not "LineColor" in obj.PropertiesList:
        obj.addProperty("App::PropertyColor","LineColor")
Post Reply