From ff21c1b95d3551edd14fcfbc519bd2d72bde5232 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sat, 21 Jul 2018 22:50:07 -0300 Subject: [PATCH] Arch: Added edit mode task panel to arch profiles + added American Wide Flange (W) profiles --- src/Mod/Arch/ArchProfile.py | 155 +++++- src/Mod/Arch/ArchStructure.py | 9 +- src/Mod/Arch/Presets/profiles.csv | 139 +++++ src/Mod/Arch/Resources/Arch.qrc | 1 + src/Mod/Arch/Resources/icons/Arch_Profile.svg | 477 ++++++++++++++++++ 5 files changed, 771 insertions(+), 10 deletions(-) create mode 100644 src/Mod/Arch/Resources/icons/Arch_Profile.svg diff --git a/src/Mod/Arch/ArchProfile.py b/src/Mod/Arch/ArchProfile.py index 552e01b10e..e4a42fc646 100644 --- a/src/Mod/Arch/ArchProfile.py +++ b/src/Mod/Arch/ArchProfile.py @@ -54,7 +54,9 @@ __url__ = "http://www.freecadweb.org" profilefiles = [os.path.join(FreeCAD.getResourceDir(),"Mod","Arch","Presets","profiles.csv"), os.path.join(os.path.dirname(__file__),"Presets","profiles.csv")] + def readPresets(): + Presets=[] for profilefile in profilefiles: if os.path.exists(profilefile): @@ -63,7 +65,7 @@ def readPresets(): beamreader = csv.reader(csvfile) bid=1 #Unique index for row in beamreader: - if row[0].startswith("#"): + if (not row) or row[0].startswith("#"): continue try: r=[bid, row[0], row[1], row[2]] @@ -79,12 +81,14 @@ def readPresets(): return Presets def makeProfile(profile=[0,'REC','REC100x100','R',100,100]): + '''makeProfile(profile): returns a shape with the face defined by the profile data''' + if not FreeCAD.ActiveDocument: FreeCAD.Console.PrintError("No active document. Aborting\n") return obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython",profile[2]) - obj.Label = translate("Arch",profile[2]) + obj.Label = profile[2] if profile[3]=="C": _ProfileC(obj, profile) elif profile[3]=="H": @@ -98,18 +102,21 @@ def makeProfile(profile=[0,'REC','REC100x100','R',100,100]): else : print("Profile not supported") if FreeCAD.GuiUp: - Draft._ViewProviderDraft(obj.ViewObject) + ViewProviderProfile(obj.ViewObject) return obj + class _Profile(Draft._DraftObject): + '''Superclass for Profile classes''' def __init__(self,obj, profile): self.Profile=profile Draft._DraftObject.__init__(self,obj,"Profile") - - + + class _ProfileC(_Profile): + '''A parametric circular tubeprofile. Profile data: [Outside diameter, Inside diameter]''' def __init__(self,obj, profile): @@ -129,8 +136,10 @@ class _ProfileC(_Profile): p=Part.makeRuledSurface(cs2,cs1) obj.Shape = p obj.Placement = pl - + + class _ProfileH(_Profile): + '''A parametric H or I beam profile. Profile data: [width, height, web thickness, flange thickness] (see http://en.wikipedia.org/wiki/I-beam for reference)''' def __init__(self,obj, profile): @@ -161,7 +170,9 @@ class _ProfileH(_Profile): obj.Shape = p obj.Placement = pl + class _ProfileR(_Profile): + '''A parametric rectangular beam profile based on [Width, Height]''' def __init__(self,obj, profile): @@ -182,7 +193,9 @@ class _ProfileR(_Profile): obj.Shape = p obj.Placement = pl + class _ProfileRH(_Profile): + '''A parametric Rectangular hollow beam profile. Profile data: [width, height, thickness]''' def __init__(self,obj, profile): @@ -211,8 +224,10 @@ class _ProfileRH(_Profile): r = p.cut(q) obj.Shape = r obj.Placement = pl - + + class _ProfileU(_Profile): + '''A parametric H or I beam profile. Profile data: [width, height, web thickness, flange thickness] (see http://en.wikipedia.org/wiki/I-beam forreference)''' def __init__(self,obj, profile): @@ -238,5 +253,129 @@ class _ProfileU(_Profile): #p.reverse() obj.Shape = p obj.Placement = pl - + +class ViewProviderProfile(Draft._ViewProviderDraft): + + '''General view provider for Profile classes''' + + def __init__(self,vobj): + + Draft._ViewProviderDraft.__init__(self,vobj) + + def getIcon(self): + + import Arch_rc + return ":/icons/Arch_Profile.svg" + + def setEdit(self,vobj,mode): + + taskd = ProfileTaskPanel(vobj.Object) + FreeCADGui.Control.showDialog(taskd) + return True + + def unsetEdit(self,vobj,mode): + + FreeCADGui.Control.closeDialog() + FreeCAD.ActiveDocument.recompute() + return + + +class ProfileTaskPanel: + + '''The editmode TaskPanel for Profile objects''' + + def __init__(self,obj): + + self.obj = obj + self.profile = None + if isinstance(self.obj.Proxy,_ProfileC): + self.type = "C" + elif isinstance(self.obj.Proxy,_ProfileH): + self.type = "H" + elif isinstance(self.obj.Proxy,_ProfileR): + self.type = "R" + elif isinstance(self.obj.Proxy,_ProfileRH): + self.type = "RH" + elif isinstance(self.obj.Proxy,_ProfileU): + self.type = "U" + else: + self.type = "Undefined" + self.form = QtGui.QWidget() + layout = QtGui.QVBoxLayout(self.form) + self.comboCategory = QtGui.QComboBox(self.form) + layout.addWidget(self.comboCategory) + self.comboProfile = QtGui.QComboBox(self.form) + layout.addWidget(self.comboProfile) + QtCore.QObject.connect(self.comboCategory, QtCore.SIGNAL("currentIndexChanged(QString)"), self.changeCategory) + QtCore.QObject.connect(self.comboProfile, QtCore.SIGNAL("currentIndexChanged(int)"), self.changeProfile) + # Read preset profiles and add relevant ones + self.categories=[] + self.presets=readPresets() + for pre in self.presets: + if pre[3] == self.type: + if pre[1] not in self.categories: + self.categories.append(pre[1]) + self.comboCategory.addItem(" ") + if self.categories: + self.comboCategory.addItems(self.categories) + # Find current profile by label + for pre in self.presets: + if self.obj.Label in pre[2]: + self.profile = pre + break + if not self.profile: + # try to find by size + if hasattr(self.obj,"Width") and hasattr(self.obj,"Height"): + for pre in self.presets: + if abs(self.obj.Width - self.Profile[4]) < 0.1 and \ + abs(self.obj.Height - self.Profile[5]) < 0.1: + self.profile = pre + break + if self.profile: + origprofile = list(self.profile) # the operation below will change self.profile + self.comboCategory.setCurrentIndex(1+self.categories.index(origprofile[1])) + self.changeCategory(origprofile[1]) + self.comboProfile.setCurrentIndex(self.currentpresets.index(origprofile)) + self.retranslateUi(self.form) + + def changeCategory(self,text): + + self.comboProfile.clear() + self.currentpresets = [] + for pre in self.presets: + if pre[1] == text: + self.currentpresets.append(pre) + f = FreeCAD.Units.Quantity(pre[4],FreeCAD.Units.Length).getUserPreferred() + d = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt("Decimals",2) + s1 = str(round(pre[4]/f[1],d)) + s2 = str(round(pre[5]/f[1],d)) + s3 = str(f[2]) + self.comboProfile.addItem(pre[2]+" ("+s1+"x"+s2+s3+")") + + def changeProfile(self,idx): + + self.profile = self.currentpresets[idx] + + def accept(self): + + if self.profile: + self.obj.Label = self.profile[2] + if self.type in ["H","R","RH","U"]: + self.obj.Width = self.profile[4] + self.obj.Height = self.profile[5] + if self.type in ["H","U"]: + self.obj.WebThickness = self.profile[6] + self.obj.FlangeThickness = self.profile[7] + elif self.type == "RH": + self.obj.Thickness = self.profile[6] + elif self.type == "C": + self.obj.OutDiameter = self.profile[4] + self.obj.Thickness = self.profile[5] + FreeCAD.ActiveDocument.recompute() + FreeCADGui.ActiveDocument.resetEdit() + return True + + def retranslateUi(self, TaskPanel): + + self.form.setWindowTitle(self.type+" "+QtGui.QApplication.translate("Arch", "Profile", None)) diff --git a/src/Mod/Arch/ArchStructure.py b/src/Mod/Arch/ArchStructure.py index d8d2c4b64c..bbf467ca31 100644 --- a/src/Mod/Arch/ArchStructure.py +++ b/src/Mod/Arch/ArchStructure.py @@ -238,7 +238,7 @@ class _CommandStructure: else: # metal profile FreeCADGui.doCommand('p = Arch.makeProfile('+str(self.Profile)+')') - if self.Length == self.Profile[4]: + if abs(self.Length - self.Profile[4]) < 0.1: # forgive rounding errors # vertical FreeCADGui.doCommand('s = Arch.makeStructure(p,height='+str(self.Height)+')') else: @@ -269,7 +269,12 @@ class _CommandStructure: ilist=[] for p in baselist: - ilist.append(p[2]+" ("+str(p[4])+"x"+str(p[5])+"mm)") + f = FreeCAD.Units.Quantity(p[4],FreeCAD.Units.Length).getUserPreferred() + d = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt("Decimals",2) + s1 = str(round(p[4]/f[1],d)) + s2 = str(round(p[5]/f[1],d)) + s3 = str(f[2]) + ilist.append(p[2]+" ("+s1+"x"+s2+s3+")") return ilist def taskbox(self): diff --git a/src/Mod/Arch/Presets/profiles.csv b/src/Mod/Arch/Presets/profiles.csv index 4ab49dd82b..9b1a076a4f 100644 --- a/src/Mod/Arch/Presets/profiles.csv +++ b/src/Mod/Arch/Presets/profiles.csv @@ -1,5 +1,6 @@ #Data structure: #Category, Name, Profile class, geometric data... +#All measures must be in millimeters #Possible profile classes are: #C=Circular tube #H= H- or I-profile @@ -12,6 +13,7 @@ CTH,CTH423,C,42.4,3.2 #H- or I-profile #Category,Name,H,width,height,web thickness,flange thickness +# HEA profiles HEA,HEA100,H,100,96,5,8 HEA,HEA120,H,120,114,5,8 HEA,HEA140,H,140,133,5.5,8.5 @@ -60,6 +62,7 @@ HEA,HEAA700,H,300,670,13,17 HEA,HEAA800,H,300,770,14,18 HEA,HEAA900,H,300,870,15,20 HEA,HEAA1000,H,300,970,16,21 +# HEB profiles HEB,HEB100,H,100,100,6,10 HEB,HEB120,H,120,120,6.5,11 HEB,HEB140,H,140,140,7,12 @@ -84,6 +87,7 @@ HEB,HEB700,H,300,700,17,32 HEB,HEB800,H,300,800,17.5,33 HEB,HEB900,H,300,900,18.5,35 HEB,HEB1000,H,300,1000,19,36 +# HEM profiles HEM,HEM160,H,166,180,14,23 HEM,HEM180,H,186,200,14.5,24 HEM,HEM200,H,206,220,15,25 @@ -105,6 +109,7 @@ HEM,HEM700,H,304,716,21,40 HEM,HEM800,H,303,814,21,40 HEM,HEM900,H,302,910,21,40 HEM,HEM1000,H,302,1008,21,40 +# INP profiles INP,INP80,H,42,80,3.9,5.9 INP,INP100,H,50,100,4.5,6.8 INP,INP120,H,58,120,5.1,7.7 @@ -122,6 +127,7 @@ INP,INP340,H,137,340,12.2,18.3 INP,INP360,H,143,360,13,19.5 INP,INP380,H,149,380,13.7,20.5 INP,INP400,H,155,400,14.4,21.6 +# IPE profiles IPE,IPE100,H,55,100,4.1,5.7 IPE,IPE120,H,64,120,4.4,6.3 IPE,IPE140,H,73,140,4.7,6.9 @@ -197,6 +203,139 @@ IPE,IPE750x185,H,267,766,14.9,23.6 IPE,IPE750x196,H,268,770,15.6,25.4 IPE,IPE750x210,H,268,775,16,28 IPE,IPE750x222,H,269,778,17,29.5 +# American Wide Flange W profiles +W,W4x13,H,103.124,105.664,7.112,8.763 +W,W5x16,H,127,127.254,6.096,9.144 +W,W5x19,H,127.762,130.81,6.858,10.922 +W,W6x9,H,100.076,149.86,4.318,5.461 +W,W6x12,H,101.6,153.162,5.842,7.112 +W,W6x15,H,152.146,152.146,5.842,6.604 +W,W6x16,H,102.362,159.512,6.604,10.287 +W,W6x20,H,152.908,157.48,6.604,9.271 +W,W6x25,H,154.432,162.052,8.128,11.557 +W,W8x10,H,100.076,200.406,4.318,5.207 +W,W8x13,H,101.6,202.946,5.842,6.477 +W,W8x15,H,101.981,205.994,6.223,8.001 +W,W8x18,H,133.35,206.756,5.842,8.382 +W,W8x21,H,133.858,210.312,6.35,10.16 +W,W8x24,H,164.973,201.422,6.223,10.16 +W,W8x28,H,165.989,204.724,7.239,11.811 +W,W8x31,H,203.073,203.2,7.239,11.049 +W,W8x35,H,203.708,206.248,7.874,12.573 +W,W8x40,H,204.978,209.55,9.144,14.224 +W,W8x48,H,205.994,215.9,10.16,17.399 +W,W8x58,H,208.788,222.25,12.954,20.574 +W,W8x67,H,210.312,228.6,14.478,23.749 +W,W10x12,H,100.584,250.698,4.826,5.334 +W,W10x15,H,101.6,253.746,5.842,6.858 +W,W10x17,H,101.854,256.794,6.096,8.382 +W,W10x19,H,102.108,260.096,6.35,10.033 +W,W10x22,H,146.05,258.318,6.096,9.144 +W,W10x26,H,146.558,262.382,6.604,11.176 +W,W10x30,H,147.574,265.938,7.62,12.954 +W,W10x33,H,202.184,247.142,7.366,11.049 +W,W10x39,H,202.819,251.968,8.001,13.462 +W,W10x45,H,203.708,256.54,8.89,15.748 +W,W10x49,H,254,253.492,8.636,14.224 +W,W10x54,H,254.762,256.286,9.398,15.621 +W,W10x60,H,256.032,259.588,10.668,17.272 +W,W10x68,H,257.302,264.16,11.938,19.558 +W,W10x77,H,258.826,269.24,13.462,22.098 +W,W10x88,H,260.731,275.336,15.367,25.146 +W,W10x100,H,262.636,281.94,17.272,28.2448 +W,W10x112,H,264.541,288.544,19.177,31.75 +W,W12x14,H,100.838,302.514,5.08,5.715 +W,W12x16,H,101.346,304.546,5.588,6.731 +W,W12x19,H,101.727,308.864,5.969,8.89 +W,W12x22,H,102.362,312.674,6.604,10.795 +W,W12x26,H,164.846,310.388,5.842,9.652 +W,W12x30,H,165.608,313.436,6.604,11.176 +W,W12x35,H,166.624,317.5,7.62,13.208 +W,W12x40,H,203.327,303.276,7.493,13.081 +W,W12x45,H,204.343,306.324,8.509,14.605 +W,W12x50,H,205.232,309.626,9.398,16.256 +W,W12x53,H,253.873,306.324,8.763,14.605 +W,W12x58,H,254.254,309.626,9.144,16.256 +W,W12x65,H,304.8,307.848,9.906,15.367 +W,W12x72,H,305.816,311.15,10.922,17.018 +W,W12x79,H,306.832,314.452,11.938,18.669 +W,W12x87,H,307.975,318.262,13.081,20.574 +W,W12x96,H,308.864,322.834,13.97,22.86 +W,W12x106,H,310.388,327.406,15.494,25.146 +W,W12x120,H,312.928,333.248,18.034,28.067 +W,W12x136,H,314.96,340.614,20.066,31.75 +W,W14x22,H,127,348.996,5.842,8.509 +W,W14x26,H,127.635,353.314,6.477,10.668 +W,W14x30,H,170.942,351.536,6.858,9.779 +W,W14x34,H,171.323,355.092,7.239,11.557 +W,W14x38,H,171.958,358.14,7.874,13.081 +W,W14x43,H,203.073,346.964,7.747,13.462 +W,W14x48,H,203.962,350.266,8.636,15.113 +W,W14x53,H,204.724,353.568,9.398,16.764 +W,W14x61,H,253.873,352.806,9.525,16.383 +W,W14x68,H,254.889,356.616,10.541,18.288 +W,W14x74,H,255.778,359.918,11.43,19.939 +W,W14x82,H,257.302,363.474,12.954,21.717 +W,W14x90,H,368.808,356.108,11.176,18.034 +W,W14x99,H,369.951,359.664,12.319,19.812 +W,W14x109,H,370.967,363.728,13.335,21.844 +W,W14x120,H,372.618,367.792,14.986,23.876 +W,W14x132,H,374.015,372.364,16.383,26.162 +W,W16x26,H,139.7,398.526,6.35,8.763 +W,W16x31,H,140.335,403.352,6.985,11.176 +W,W16x36,H,177.419,402.844,7.493,10.922 +W,W16x40,H,177.673,406.654,7.747,12.827 +W,W16x45,H,178.689,409.702,8.763,14.351 +W,W16x50,H,179.578,413.004,9.652,16.002 +W,W16x57,H,180.848,417.322,10.922,18.161 +W,W16x67,H,259.969,414.782,10.033,16.891 +W,W16x77,H,261.493,419.608,11.557,19.304 +W,W16x89,H,263.271,425.45,13.335,22.225 +W,W16x100,H,264.795,431.038,14.859,25.019 +W,W18x35,H,152.4,449.58,7.62,10.795 +W,W18x40,H,152.908,454.66,8.001,13.335 +W,W18x46,H,153.924,459.74,9.144,15.367 +W,W18x50,H,190.5,457.2,9.017,14.478 +W,W18x55,H,191.262,459.74,9.906,16.002 +W,W18x60,H,192.024,462.28,10.541,17.653 +W,W18x65,H,192.786,467.36,11.43,19.05 +W,W18x71,H,194.056,469.9,12.573,20.574 +W,W18x76,H,280.416,462.28,10.795,17.272 +W,W18x86,H,281.686,467.36,12.192,19.558 +W,W18x97,H,283.21,472.44,13.589,22.098 +W,W18x106,H,284.48,474.98,14.986,23.876 +W,W18x119,H,286.258,482.6,16.637,26.924 +W,W21x44,H,165.1,525.78,8.89,11.43 +W,W21x50,H,165.862,528.32,9.652,13.589 +W,W21x57,H,166.624,535.94,10.287,16.51 +W,W21x62,H,209.296,533.4,10.16,15.621 +W,W21x68,H,210.058,535.94,10.922,17.399 +W,W21x73,H,210.82,538.48,11.557,18.796 +W,W21x83,H,212.344,543.56,13.081,21.209 +W,W21x93,H,213.868,548.64,14.732,23.622 +W,W21x101,H,312.166,543.56,12.7,20.32 +W,W21x111,H,313.436,546.1,13.97,22.225 +W,W21x122,H,314.706,551.18,15.24,24.384 +W,W21x132,H,315.976,553.72,16.51,26.289 +W,W21x147,H,317.754,561.34,18.288,29.21 +W,W24x55,H,178.054,599.44,10.033,12.827 +W,W24x62,H,178.816,601.98,10.922,14.986 +W,W24x68,H,227.838,601.98,10.541,14.859 +W,W24x76,H,228.6,607.06,11.176,17.272 +W,W24x84,H,229.108,612.14,11.938,19.558 +W,W24x94,H,230.378,612.14,13.081,22.225 +W,W24x104,H,323.85,612.14,12.7,19.05 +W,W24x117,H,325.12,617.22,13.97,21.59 +W,W24x131,H,327.66,622.3,15.367,24.384 +W,W24x146,H,327.66,627.38,16.51,27.686 +W,W24x162,H,330.2,635,17.907,30.988 +W,W27x84,H,252.984,678.18,11.684,16.256 +W,W27x94,H,254,683.26,12.446,18.923 +W,W27x102,H,254.508,688.34,13.081,21.082 +W,W27x114,H,255.778,693.42,14.478,23.622 +W,W27x146,H,355.6,695.96,15.367,24.765 +W,W27x161,H,356.108,701.04,16.764,27.432 +W,W27x178,H,357.886,706.12,18.415,30.226 #Rectangular #Category,Name,R,width,height REC,1x2in,R,19,28 diff --git a/src/Mod/Arch/Resources/Arch.qrc b/src/Mod/Arch/Resources/Arch.qrc index 87c4137286..911ca057dc 100644 --- a/src/Mod/Arch/Resources/Arch.qrc +++ b/src/Mod/Arch/Resources/Arch.qrc @@ -85,6 +85,7 @@ icons/Arch_Grid.svg icons/Arch_BuildingPart.svg icons/Arch_BuildingPart_Tree.svg + icons/Arch_Profile.svg ui/ParametersWindowDouble.svg ui/ParametersWindowSimple.svg ui/ParametersWindowFixed.svg diff --git a/src/Mod/Arch/Resources/icons/Arch_Profile.svg b/src/Mod/Arch/Resources/icons/Arch_Profile.svg new file mode 100644 index 0000000000..9c84a8baf6 --- /dev/null +++ b/src/Mod/Arch/Resources/icons/Arch_Profile.svg @@ -0,0 +1,477 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [wmayer] + + + Arch_Floor + 2011-10-10 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/Arch/Resources/icons/Arch_ + + + FreeCAD LGPL2+ + + + https://www.gnu.org/copyleft/lesser.html + + + [agryson] Alexander Gryson + + + + + + + + + + +