Arch: Added edit mode task panel to arch profiles + added American Wide Flange (W) profiles
This commit is contained in:
@@ -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))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user