A I beam python feature

Info about new community or project announcements, implemented features, classes, modules or APIs. Might get technical!
PLEASE DO NOT POST HELP REQUESTS OR OTHER DISCUSSIONS HERE!
Post Reply
User avatar
GlouGlou
Posts: 2620
Joined: Sun Apr 05, 2015 9:02 am
Location: La Rochelle, France

A I beam python feature

Post by GlouGlou » Wed Sep 16, 2020 9:00 pm

For quickly design a beam.
True IPE HEA IPN profile.
Bevel able at the start and end of the beam.
Can be manually handle or attached on a edge. (first select the edge then call the macro)
Raw programming, i'm a beginner. ;)

Code: Select all

import FreeCAD, Part, Draft, math
from FreeCAD import Base
v = FreeCAD.Base.Vector



class IH:
   def __init__(self, obj, linksub, lenobj=0):
              
      # print (linksub)
      # print (lenobj)
          
      obj.addProperty("App::PropertyFloat","Width","Parameters","").Width = 42
      obj.addProperty("App::PropertyFloat","Height","Parameters","").Height = 80
      obj.addProperty("App::PropertyFloat","FlangeThickness","Parameters").FlangeThickness = 5.9
      obj.addProperty("App::PropertyFloat","FlangeAngle","Parameters").FlangeAngle = 8
      obj.addProperty("App::PropertyFloat","WebThickness","Parameters").WebThickness = 3.8
      obj.addProperty("App::PropertyFloat","FilletRadius","Parameters","Fillet radius").FilletRadius = 4
      obj.addProperty("App::PropertyFloat","Length","Parameters","Extrude Length").Length = lenobj
      obj.addProperty("App::PropertyFloat","Bevel1","Parameters","First bevel cut").Bevel1 = 0
      obj.addProperty("App::PropertyFloat","Bevel2","Parameters","Second bevel cut").Bevel2 = 0
      obj.addProperty("App::PropertyFloat","BevelRotate","Parameters","Angle of bevel around his axle").BevelRotate = 0
      obj.addProperty("App::PropertyBool","MakeFillet","Parameters","Wheter to draw the fillets or not").MakeFillet = True
      obj.addProperty("App::PropertyBool","Centered","Parameters","Choose corner or profile centre as origin").Centered = False
      obj.addProperty("App::PropertyBool","IPN","Parameters","IPE HEA style or IPN style").IPN = True
      if linksub:
        obj.addProperty("App::PropertyLinkSub","Target","Base","Target face").Target = linksub
       
      obj.Proxy = self
 
   def onChanged(self, obj, prop):
      
      if prop == "Width" or prop == "Height" or prop == "FlangeThickness" or prop == "WebThickness" or prop == "FilletRadius" or prop == "Length" or prop == "Bevel1" or prop == "Bevel2" or prop == "Centered" or prop == "BevelRotate":
        self.execute(obj)

   def execute(self, obj):
           
        try:
            L = obj.Target[0].getSubObject(obj.Target[1][0]).Length
        except:   
            L = obj.Length 
     
        pl = obj.Placement
        TF = obj.FlangeThickness
        TW = obj.WebThickness
        W = obj.Width
        H = obj.Height
        R = obj.FilletRadius
        r = 0
        d = v(0,0,1)
        B1 = obj.Bevel1
        B2 = obj.Bevel2
        A = obj.BevelRotate
        w = 0
        h = 0
        k = 2 * round (max (H/W,W/H),2)  # coeff pour depasser l'objet (rotation bevel)
        XA1 = W/2-TW/2                   # face gauche du web
        XA2 = W/2+TW/2                   # face droite du web
                    
        if obj.Centered == True:
            w = -W/2
            h = -H/2
            
        if obj.MakeFillet == False:                          # IPE ou IPN sans arrondis
       
            Yd = 0
            if obj.IPN == True:
                Yd = (W/4)*math.tan(math.pi*obj.FlangeAngle/180)  
            
            p1 =  v(0+w,0+h,0)
            p2 =  v(0+w,TF+h-Yd,0)
            p3 =  v(XA1+w,TF+h+Yd,0)
            p4 =  v(XA1+w,H-TF+h-Yd,0)
            p5 =  v(0+w,H-TF+h+Yd,0)
            p6 =  v(0+w,H+h,0)
            p7 =  v(W+w,H+h,0)
            p8 =  v(W+w,H-TF+h+Yd,0)
            p9 =  v(XA2+w,H-TF+h-Yd,0)
            p10 = v(XA2+w,TF+h+Yd,0)
            p11 = v(W+w,TF+h-Yd,0)
            p12 = v(W+w,0+h,0)
            
            L1 = Part.makeLine(p1, p2)
            L2 = Part.makeLine(p2, p3)
            L3 = Part.makeLine(p3, p4)
            L4 = Part.makeLine(p4, p5)
            L5 = Part.makeLine(p5, p6)
            L6 = Part.makeLine(p6, p7)
            L7 = Part.makeLine(p7, p8)
            L8 = Part.makeLine(p8, p9)
            L9 = Part.makeLine(p9, p10)
            L10 = Part.makeLine(p10,p11)
            L11 = Part.makeLine(p11,p12)
            L12 = Part.makeLine(p12,p1)
                
            wire = Part.Wire([L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12])
            
        if obj.MakeFillet == True and obj.IPN == False:      # IPE avec arrondis
                
            p1 =  v(0+w,0+h,0)
            p2 =  v(0+w,TF+h,0)
            p3 =  v(XA1-R+w,TF+h,0)
            p4 =  v(XA1+w,TF+R+h,0)
            p5 =  v(XA1+w,H-TF-R+h,0)
            p6 =  v(XA1-R+w,H-TF+h,0)
            p7 =  v(0+w,H-TF+h,0)
            p8 =  v(0+w,H+h,0)
            p9 =  v(W+w,H+h,0)
            p10 = v(W+w,H-TF+h,0)
            p11 = v(XA2+R+w,H-TF+h,0)
            p12 = v(XA2+w,H-TF-R+h,0)
            p13 = v(XA2+w,TF+R+h,0)
            p14 = v(XA2+R+w,TF+h,0)
            p15 = v(W+w,TF+h,0)
            p16 = v(W+w,0+h,0)
            
            c1 = v(XA1-R+w,TF+R+h,0)
            c2 = v(XA1-R+w,H-TF-R+h,0)
            c3 = v(XA2+R+w,H-TF-R+h,0)
            c4 = v(XA2+R+w,TF+R+h,0)
            
            L1 = Part.makeLine(p1, p2)
            L2 = Part.makeLine(p2, p3)
            L3 = Part.makeLine(p4, p5)
            L4 = Part.makeLine(p6, p7)
            L5 = Part.makeLine(p7, p8)
            L6 = Part.makeLine(p8, p9)
            L7 = Part.makeLine(p9, p10)
            L8 = Part.makeLine(p10, p11)
            L9 = Part.makeLine(p12, p13)
            L10 = Part.makeLine(p14, p15)
            L11 = Part.makeLine(p15, p16)
            L12 = Part.makeLine(p16, p1)
            
            A1 = Part.makeCircle(R,c1,d,270,0)
            A2 = Part.makeCircle(R,c2,d,0,90)
            A3 = Part.makeCircle(R,c3,d,90,180)
            A4 = Part.makeCircle(R,c4,d,180,270)
               
            wire = Part.Wire([L1,L2,A1,L3,A2,L4,L5,L6,L7,L8,A3,L9,A4,L10,L11,L12])
        
        if obj.MakeFillet == True and obj.IPN == True:       # IPN avec arrondis
        
            r = R/2
            angarc = obj.FlangeAngle
            angrad = math.pi*angarc/180
            sina = math.sin(angrad)
            cosa = math.cos(angrad)
            tana = math.tan(angrad)
            cot1 = W/4*tana     #1,47
            cot2 = TF-cot1      #4,42
            cot3 = r*cosa       #1,98
            cot4 = r-cot3*tana  #1,72
            cot5 = cot4*tana    #0,24
            cot5 = cot2+cot5    #4,66
            cot6 = R*sina       #0,55
            cot7 = W/4-R-TW/2   #4,6
            cot8 = cot6+cot7    #5,15
            cot9 = cot7*tana    #0,72
            cot10 = R*cosa      #3,96
            
            xc1 = r
            yc1 = cot5-cot3
            c1 = v(xc1+w,yc1+h,0)
            
            xc2 = W/2-TW/2-R
            yc2 = cot9+TF+cot10
            c2 = v(xc2+w,yc2+h,0)
            
            xc3 = xc2
            yc3 = H-yc2
            c3 = v(xc3+w,yc3+h,0)
            
            xc4 = xc1
            yc4 = H-yc1
            c4 = v(xc4+w,yc4+h,0)
               
            xc5 = W-xc1
            yc5 = yc4
            c5 = v(xc5+w,yc5+h,0)
            
            xc6 = W-xc2
            yc6 = yc3
            c6 = v(xc6+w,yc6+h,0)
            
            xc7 = xc6
            yc7 = yc2
            c7 = v(xc7+w,yc7+h,0)
            
            xc8 = xc5
            yc8 = yc1
            c8 = v(xc8+w,yc8+h,0)
            
            A1 = Part.makeCircle(r,c1,d,90+angarc,180)
            A2 = Part.makeCircle(R,c2,d,270+angarc,0)
            A3 = Part.makeCircle(R,c3,d,0,90-angarc)
            A4 = Part.makeCircle(r,c4,d,180,270-angarc)
            A5 = Part.makeCircle(r,c5,d,270+angarc,0)
            A6 = Part.makeCircle(R,c6,d,90+angarc,180)
            A7 = Part.makeCircle(R,c7,d,180,270-angarc)
            A8 = Part.makeCircle(r,c8,d,0,90-angarc)
            
            xp1 = 0
            yp1 = 0
            p1 = v(xp1+w,yp1+h,0)
            
            xp2 = 0
            yp2 = cot5-cot3
            p2  = v(xp2+w,yp2+h,0)
            
            xp3 = cot4
            yp3 = cot5
            p3 = v(xp3+w,yp3+h,0)
            
            xp4 = W/4+cot8
            yp4 = TF+cot9
            p4 = v(xp4+w,yp4+h,0)
            
            xp5 = W/2-TW/2
            yp5 = yc2
            p5 = v(xp5+w,yp5+h,0)
            
            xp6 = xp5
            yp6 = H-yp5
            p6 = v(xp6+w,yp6+h,0)
            
            xp7 = xp4
            yp7 = H-yp4
            p7 = v(xp7+w,yp7+h,0)
            
            xp8 = xp3
            yp8 = H-yp3
            p8 = v(xp8+w,yp8+h,0)
            
            xp9 = xp2
            yp9 = H - yp2
            p9 = v(xp9+w,yp9+h,0)
            
            xp10 = xp1
            yp10 = H
            p10 = v(xp10+w,yp10+h,0)
            
            xp11 = W
            yp11 = H
            p11 = v(xp11+w,yp11+h,0)
            
            xp12 = xp11
            yp12 = yp9
            p12 = v(xp12+w,yp12+h,0)
            
            xp13 = W-xp8
            yp13 = yp8
            p13 = v(xp13+w,yp13+h,0)
            
            xp14 = W-xp7
            yp14 = yp7
            p14 = v(xp14+w,yp14+h,0)
            
            xp15 = W-xp6
            yp15 = yp6
            p15 = v(xp15+w,yp15+h,0)
            
            xp16 = W-xp5
            yp16 = yp5
            p16 = v(xp16+w,yp16+h,0)
            
            xp17 = W-xp4
            yp17 = yp4
            p17 = v(xp17+w,yp17+h,0)
            
            xp18 = W-xp3
            yp18 = yp3
            p18 = v(xp18+w,yp18+h,0)
            
            xp19 = W-xp2
            yp19 = yp2
            p19 = v(xp19+w,yp19+h,0)
            
            xp20 = W
            yp20 = 0
            p20 = v(xp20+w,yp20+h,0)
              
            L1 = Part.makeLine(p1, p2)
            L2 = Part.makeLine(p3, p4)
            L3 = Part.makeLine(p5, p6)
            L4 = Part.makeLine(p7, p8)
            L5 = Part.makeLine(p9, p10)
            L6 = Part.makeLine(p10, p11)
            L7 = Part.makeLine(p11, p12)
            L8 = Part.makeLine(p13, p14)
            L9 = Part.makeLine(p15, p16)
            L10 = Part.makeLine(p17, p18)
            L11 = Part.makeLine(p19, p20)
            L12 = Part.makeLine(p20, p1)
                
            wire = Part.Wire([L1,A1,L2,A2,L3,A3,L4,A4,L5,L6,L7,A5,L8,A6,L9,A7,L10,A8,L11,L12])
         
        obj.Shape = wire    
        p = Part.Face(wire)   
           
        if L:                                       # si on extrude
            ProfileFull = p.extrude(v(0,0,L))
            obj.Shape = ProfileFull
            YA1 = W*math.tan(math.pi*B1/180)
            YA2 = W*math.tan(math.pi*B2/180)
                
            if B1 or B2:                            # couper les extrémités
                if B1 and not B2: 
                    p1 = v(w,h,0)
                    p2 = v(k*W+w,k*h,0)
                    p3 = v(k*W+w,k*h,k*YA1)
                    obj.Shape  = ProfileFull.cut(self.SubtractiveCoin(p1,p2,p3,H,A,d,k))
                if B2 and not B1: 
                    p1 = v(w,h,L)
                    p2 = v(k*W+w,k*h,L)
                    p3 = v(k*W+w,k*h,L-k*YA2)
                    obj.Shape  = ProfileFull.cut(self.SubtractiveCoin(p1,p2,p3,H,A,d,k))
                if B1 and B2 :  
                    p1 = v(w,h,0)
                    p2 = v(k*W+w,k*h,0)
                    p3 = v(k*W+w,k*h,k*YA1)
                    Profiledemicut = ProfileFull.cut(self.SubtractiveCoin(p1,p2,p3,H,A,d,k))
                    p1 = v(w,h,L)
                    p2 = v(k*W+w,k*h,L)
                    p3 = v(k*W+w,k*h,L-k*YA2)
                    obj.Shape  = Profiledemicut.cut(self.SubtractiveCoin(p1,p2,p3,H,A,d,k))   
        else:   
            obj.Shape = p
            
        obj.Placement = pl
        obj.positionBySupport()
        
   def SubtractiveCoin(obj,p1,p2,p3,H,A,d,k):
        WireCoin = Part.makePolygon([p1,p2,p3,p1])
        FaceCoin = Part.Face(WireCoin)
        coin1 = FaceCoin.extrude(v(0,k*H,0))
        coin2 = FaceCoin.extrude(v(0,-k*H,0))
        if A:
            coin1.rotate (p1,d,A)
            coin2.rotate (p1,d,A)
        fuse = coin1.fuse(coin2)
        return fuse        
        
def MakeIH():
    doc = FreeCAD.activeDocument()
    if doc == None:
        doc = FreeCAD.newDocument()
        
    obj=doc.addObject("Part::FeaturePython","I_Beam") 
    obj.addExtension("Part::AttachExtensionPython","obj")
   
    selobj = ""
    selsubobj = ""
    linksub = ""
    lenobj = 0 
    
    try:
       
        selobj = Gui.Selection.getSelectionEx()[0]
        linksub = (selobj.Object, (selobj.SubElementNames[0]))
        selsubobj = selobj.SubObjects[0]
        feature = selobj.Object
        edgeName = selobj.SubElementNames[0]
        lenobj = selsubobj.Length
        
        obj.MapMode = "NormalToEdge"
        obj.Support =  (feature, edgeName)
        obj.MapPathParameter = 1
       
    except:
        print ("no selection")
   
    IH(obj,linksub,lenobj)
    
    obj.ViewObject.Proxy=0
    viewObject = Gui.ActiveDocument.getObject(obj.Name)
    viewObject.DisplayMode = "Flat Lines"
  

MakeIH()
Attachments
Capture.JPG
Capture.JPG (50.98 KiB) Viewed 991 times
test.FCStd
(76.74 KiB) Downloaded 14 times
User avatar
bernd
Posts: 10956
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: A I beam python feature

Post by bernd » Thu Sep 17, 2020 4:50 am

similar to the way it is done in BOLTSFC for years already ... 8-) https://github.com/boltsparts/BOLTS/blo ... ofile_i.py
carlopav
Posts: 1568
Joined: Mon Dec 31, 2018 1:49 pm
Location: Venice, Italy

Re: A I beam python feature

Post by carlopav » Fri Sep 18, 2020 8:13 pm

nice script anyway!
follow my experiments on BIM modelling for architecture design
User avatar
bitacovir
Posts: 1156
Joined: Sat Apr 19, 2014 6:23 am
Contact:

Re: A I beam python feature

Post by bitacovir » Sat Sep 19, 2020 7:22 pm

GlouGlou wrote:
Wed Sep 16, 2020 9:00 pm
For quickly design a beam.
well done. Keep learning!
::bitacovir::
===================================
One must be absolutely modern.
Arthur Rimbaud (A Season in Hell -1873)

My personal web site
My GitHub repository
My old Blog
Mini Airflow Tunnel Project
User avatar
GlouGlou
Posts: 2620
Joined: Sun Apr 05, 2015 9:02 am
Location: La Rochelle, France

Re: A I beam python feature

Post by GlouGlou » Sat Sep 19, 2020 9:37 pm

Thanks.
I've made the L profile and the Square profile as well.
Attachments
Capture.JPG
Capture.JPG (58.52 KiB) Viewed 648 times
mario52
Posts: 3222
Joined: Wed May 16, 2012 2:13 pm

Re: A I beam python feature

Post by mario52 » Sun Sep 27, 2020 11:07 am

hi

mais q'c'est biau

and the GUI and the wiki

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting, Dialog creation. My macros on Gist.github.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest