Arch Parametric Objects

A forum dedicated to the Draft, Arch and BIM workbenches development.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
rockn
Veteran
Posts: 1791
Joined: Wed Sep 28, 2011 10:39 am
Location: Toulouse, France
Contact:

Arch Parametric Objects

Post by rockn »

Hi everyone !

I try to make an Arch Structure parametric object.
See and test this sript for example.
You can change the Pergola Value in Structure Object and the PergolaFusion will change automatically.
3dwood_Pergola01_NotAZip.FCMacro.zip
It's not a zip file, just renamme it and remove .zip.
(6.96 KiB) Downloaded 202 times

Code: Select all

#***************************************************************************
#*                                                                         *
#*   Copyright (c) 2013                                                    *  
#*   Jonathan Wiedemann <j.wiedemann@wood3dservices.fr>                    *  
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU Lesser General Public License (LGPL)    *
#*   as published by the Free Software Foundation; either version 2 of     *
#*   the License, or (at your option) any later version.                   *
#*   for detail see the LICENCE text file.                                 *
#*                                                                         *
#*   This program is distributed in the hope that it will be useful,       *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU Library General Public License for more details.                  *
#*                                                                         *
#*   You should have received a copy of the GNU Library General Public     *
#*   License along with this program; if not, write to the Free Software   *
#*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
#*   USA                                                                   *
#*                                                                         *
#***************************************************************************

import FreeCAD, Part, Draft, Arch, math, ArchComponent, DraftVecUtils, ArchCommands

class Pergola:
    '''retourne une pergola'''
    def __init__(self,obj, longueurPergola = 4000, largeurPergola = 2000):
        obj.addProperty("App::PropertyLength","longueurPergola","Pergola","Longueur de la Pergola").longueurPergola = longueurPergola
        obj.addProperty("App::PropertyLength","largeurPergola","Pergola","Largeur de la Pergola").largeurPergola = largeurPergola
        obj.Proxy = self
        
    def onChanged(self, fp, prop):
		"Do something when a property has changed"
		FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
    
    def execute(self, fp):
        if FreeCAD.ActiveDocument.getObject("PoteauxFusion"):
        	FreeCAD.ActiveDocument.removeObject("Poteau001")
        	FreeCAD.ActiveDocument.removeObject("Poteau002")
        	FreeCAD.ActiveDocument.removeObject("Poteau003")
        	FreeCAD.ActiveDocument.removeObject("Poteau004")
        	FreeCAD.ActiveDocument.removeObject("PoteauxFusion")
        if FreeCAD.ActiveDocument.getObject("SolivesFusion"):
            FreeCAD.ActiveDocument.removeObject("Solive")
            for i in range(0,9):
                name = str("Solive00")+str(i+1)
                if FreeCAD.ActiveDocument.getObject(name):
                    FreeCAD.ActiveDocument.removeObject(name)
        	for i in range(9,98):
        	    name = str("Solive0")+str(i+1)
        	    if FreeCAD.ActiveDocument.getObject(name):
        	        FreeCAD.ActiveDocument.removeObject(name)
            for i in range(99,998):
                name = str("Solive")+str(i+1)
                if FreeCAD.ActiveDocument.getObject(name):
                    FreeCAD.ActiveDocument.removeObject(name)
            FreeCAD.ActiveDocument.removeObject("SolivesFusion")
            if FreeCAD.ActiveDocument.getObject("PergolaFusion"):
                FreeCAD.ActiveDocument.removeObject("PergolaFusion")
                
        #fp.Shape = Pergola.buildshape(fp.largeurPergola, fp.longueurPergola)
        Arch.addComponents(fp, Pergola.buildshape(fp.largeurPergola, fp.longueurPergola))
    
    @staticmethod            
    def buildshape(lg_perg, Lg_perg):
        #lg_perg = fp.largeurPergola
        #Lg_perg = fp.longueurPergola
        poteau001 = FreeCAD.ActiveDocument.addObject("Part::Box","Poteau001")
        poteau001.Length = 2400
        poteau001.Width = 160
        poteau001.Height = 160
        poteau001.Placement = App.Placement(FreeCAD.Vector(0,0,0),App.Rotation(0,-0.707107,0,0.707107))
        poteau002 = FreeCAD.ActiveDocument.addObject("Part::Box","Poteau002")
        poteau002.Length = 2400
        poteau002.Width = 160
        poteau002.Height = 160
        poteau002.Placement = App.Placement(FreeCAD.Vector(0,lg_perg,0),App.Rotation(0,-0.707107,0,0.707107))
        poteau003 = FreeCAD.ActiveDocument.addObject("Part::Box","Poteau003")
        poteau003.Length = 2400
        poteau003.Width = 160
        poteau003.Height = 160
        poteau003.Placement = App.Placement(FreeCAD.Vector(Lg_perg,lg_perg,0),App.Rotation(0,-0.707107,0,0.707107))
        poteau004 = FreeCAD.ActiveDocument.addObject("Part::Box","Poteau004")
        poteau004.Length = 2400
        poteau004.Width = 160
        poteau004.Height = 160
        poteau004.Placement = App.Placement(FreeCAD.Vector(Lg_perg,0,0),App.Rotation(0,-0.707107,0,0.707107))
        poteauxFusion = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","PoteauxFusion")
        poteauxFusion.Shapes = [poteau001,poteau003,poteau002,poteau004,]
        
        solivesFusion = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","SolivesFusion")
        solivesListe = []
        solivesQuantite = int(math.ceil((Lg_perg) / 400 )) + 1
        print solivesQuantite
        pos_x = 0
        for solive in range(solivesQuantite):
            solive = FreeCAD.ActiveDocument.addObject("Part::Box","Solive")
            solive.Length = lg_perg
            solive.Width = 80
            solive.Height = 80
            solive.Placement = App.Placement(FreeCAD.Vector(pos_x,0,2400),App.Rotation(0,0,0.707107,0.707107))
            solivesListe.append(solive)
            pos_x = pos_x + 400
        solivesFusion.Shapes = solivesListe
        
        #pergolaListe = Part.Compound([poteauxFusion.Shape, solivesFusion.Shape])
        pergolaListe =  [poteauxFusion, solivesFusion]
        pergolaFusion = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","PergolaFusion")
        pergolaFusion.Shapes = pergolaListe
        """
        #pergolaFusionCopy = 
        pergolaFusionCopy = FreeCAD.ActiveDocument.addObject('Part::Feature','PergolaFusionCopy')
        pergolaFusionCopy.Shape = pergolaFusion.Shape
        shape = pergolaFusionCopy.Shape
        App.ActiveDocument.PergolaFusion.Shape
        """
        return pergolaFusion

		
def fairePergola(longueurPergola, largeurPergola, doc=None):
    doc = doc or FreeCAD.ActiveDocument
    #obj=doc.addObject("Part::FeaturePython","MurOssaBois")
    #obj=doc.addObject("Part::FeaturePython","Pergola")
    obj = Arch.makeStructure()
    #MurOssaBois(obj)
    #obj.ViewObject.Proxy=0 # just set it to something different from None (this assignment is needed to run an internal notification)
    #Arch.makeWall(obj)
    #Arch.makeStructure()
    Pergola(obj)
    return obj
            
if __name__ == '__main__':
    fairePergola(4000, 2000)
There is a way to make the FusionPergola be a child of Structure object ?
If it's possible have you a little example ?
It could be awesome to have some parametric object like that ;)
Formations - Assistance - Développement : https://freecad-france.com
User avatar
yorik
Founder
Posts: 13664
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: Arch Parametric Objects

Post by yorik »

Hm this is not easy... instead of using Arch.addComponents on line 63, you could use fp.Base = Pergola.buildshape(fp.largeurPergola, fp.longueurPergola)
But the problem is that you are overwriting the execute() function defined in the Arch Structure object by yours, so it won't recalculate the shape...

I think what you should do is derive a new class from the Arch Structure. Basically you do like this:

Code: Select all

from ArchStructure import _Structure
class Pergola(_Structure):
   def __init__(self):
        _Structure.__init__(self)
        # add your own stuff here...

    def execute(self,fp):
        # add your stuff here, or after, depending on the desired result
        _Structure.execute(self,fp)
But I am not sure that such object, defined in a macro, can be saved and restored correctly, you'll have to test...
Post Reply