Merge branch 'refs/heads/WizardShaft'

This commit is contained in:
jriegel 2013-03-26 13:23:27 +01:00
commit eb6d7cedbc
7 changed files with 44 additions and 87 deletions

View File

@ -56,7 +56,6 @@ ViewProviderFemConstraintBearing::~ViewProviderFemConstraintBearing()
bool ViewProviderFemConstraintBearing::setEdit(int ModNum)
{
Base::Console().Error("ViewProviderFemConstraintBearing::setEdit()\n");
Base::Console().Error("Active dialog: %s\n", Gui::Control().activeDialog()->objectName().toStdString().c_str());
if (ModNum == ViewProvider::Default ) {
// When double-clicking on the item for this constraint the

View File

@ -25,11 +25,7 @@ import numpy as np
class SegmentFunctionSegment:
"One segment of a segment function"
start = 0
variable = "x"
coefficient = 0
exponent = 0
def __init__(self, st, var, coeff, exp):
self.start = st
self.variable = var
@ -74,9 +70,6 @@ class SegmentFunctionSegment:
class SegmentFunction:
"Function that is defined segment-wise"
variable = "x"
segments = []
name = "f(x)"
def __init__(self, name = "f(x)"):
self.variable = "x"
@ -202,8 +195,6 @@ class SegmentFunction:
class IntervalFunction:
"Function defined in intervals"
intervals = [] # vector of tuples (begin, length)
values = [] # vector of constant values applicable for this interval
def __init__(self):
self.intervals = []
@ -244,13 +235,11 @@ class IntervalFunction:
class StressFunction:
"Specialization for segment-wise display of stresses"
# The hairy thing about this is that the segments of the segfunc usually do not correspond with the intervals of the intfunc!
segfunc = None # The segment function for the force/moment
intfunc = None # The divisors, an interval function giving a specific value for each interval
name = "sigma"
def __init__(self, f, i):
self.segfunc = f
self.intfunc = i
self.segfunc = f # The segment function for the force/moment
self.intfunc = i # The divisors, an interval function giving a specific value for each interval
name = "sigma"
def isZero(self):
return self.segfunc.isZero()
@ -281,20 +270,15 @@ class StressFunction:
class TranslationFunction:
"Specialization for segment-wise display of translations"
tangfunc = None # The segment function for the tangent to the bending line
transfunc = None # The segment function for translations of the shaft (the bending line)
intfunc = None # The divisors, a vector of tuples (location, divisor)
boundaries = {} # The boundary conditions, dictionary of location:[left boundary, right boundary]
module = 2.1E12
name = "w"
def __init__(self, f, E, d, tangents, translations):
if f.isZero():
self.transfunc = None
return
# Note: Integration has to be segment-wise because the area moment is not constant in different segments. But this only becomes relevant
# when boundary conditions are being applied
# E I_i w_i'(x) = tangfunc + C_i0
self.tangfunc = f.integrated()
self.tangfunc = f.integrated() # The segment function for the tangent to the bending line
self.tangfunc.name = "w'"
self.tangfunc.output()
# E I_i w_i(x) = transfunc + C_i0 x + C_i1
@ -303,6 +287,7 @@ class TranslationFunction:
self.transfunc.output()
self.module = E
self.intfunc = d
self.name = "w"
# Solve boundary conditions. There are two types:
# External boundary conditions, e.g. a given tangent direction or translation value at a given x-value

View File

@ -28,33 +28,15 @@ from ShaftDiagram import Diagram
import math
class ShaftSegment:
length = 0.0
diameter = 0.0
innerdiameter = 0.0
constraintType = "None"
constraint = None
def __init__(self, l, d, di):
self.length = l
self.diameter = d
self.innerdiameter = di
self.constraintType = "None"
self.constraint = None
class Shaft:
"The axis of the shaft is always assumed to correspond to the X-axis"
parent = None
doc = None
# List of shaft segments (each segment has a different diameter)
segments = []
# The feature
feature = 0
# The diagrams
diagrams = {} # map of function name against Diagram object
# Calculation of shaft
F = [None, None, None] # force in direction of [x,y,z]-axis
M = [None, None, None] # bending moment around [x,z,y]-axis
w = [None, None, None] # Shaft translation due to bending
sigmaN = [None, None, None] # normal stress in direction of x-axis, shear stress in direction of [y,z]-axis
sigmaB = [None, None, None] # # torque stress around x-axis, maximum bending stress in direction of [y,z]-axis
# Names (note Qy corresponds with Mz, and Qz with My)
Fstr = ["Nx","Qy","Qz"] # Forces
Mstr = ["Mx","Mz","My"] # Moments
@ -82,6 +64,16 @@ class Shaft:
self.parent = parent
self.doc = parent.doc
self.feature = ShaftFeature(self.doc)
# List of shaft segments (each segment has a different diameter)
self.segments = []
# The diagrams
self.diagrams = {} # map of function name against Diagram object
# Calculation of shaft
self.F = [None, None, None] # force in direction of [x,y,z]-axis
self.M = [None, None, None] # bending moment around [x,z,y]-axis
self.w = [None, None, None] # Shaft translation due to bending
self.sigmaN = [None, None, None] # normal stress in direction of x-axis, shear stress in direction of [y,z]-axis
self.sigmaB = [None, None, None] # # torque stress around x-axis, maximum bending stress in direction of [y,z]-axis
def getLengthTo(self, index):
"Get the total length of all segments up to the given one"

View File

@ -24,27 +24,11 @@ from PyQt4 import QtCore, QtGui
import FreeCAD, FreeCADGui
class Diagram:
function = 0 # This is assumed to be always a SegmentFunction
fname = "y(x)"
xlength = 0.0
xname = "x"
xunit = ""
xscale = 1.0
yname = "y"
yunit = ""
yscale = 1.0
numxpoints = 10
xpoints = []
ypoints = []
# Plot object
thePlot = None
win = None
def create(self, title, function, xlength, xname, xunit, xscale, yname, yunit, yscale, numxpoints):
# Initialize
import Plot
self.title = title
self.function = function
self.function = function # This is assumed to be always a SegmentFunction
self.xlength = xlength
self.xname = xname
self.xunit = xunit

View File

@ -25,14 +25,8 @@ import Part, Sketcher
class ShaftFeature:
"Creates and updates the feature of the shaft"
Doc = 0
App = FreeCAD
Gui = FreeCADGui
sketch = 0
feature = 0
segments = 0 # number of segments
totalLength = 0 # total length of all segments
lastRadius = 0 # radius of last segment (required for adding segments)
def __init__(self, doc):
"Create new feature"
@ -41,6 +35,11 @@ class ShaftFeature:
# TODO: Discover existing sketch and get data from it
self.sketch = self.Doc.addObject("Sketcher::SketchObject","SketchShaft")
self.sketch.Placement = self.App.Placement(self.App.Vector(0,0,0),self.App.Rotation(0,0,0,1))
self.feature = 0
self.segments = 0 # number of segments
self.totalLength = 0 # total length of all segments
self.lastRadius = 0 # radius of last segment (required for adding segments)
def addSegment(self, length, diameter, innerdiameter):
"Add a segment at the end of the shaft"

View File

@ -27,19 +27,9 @@ from Shaft import Shaft
class TaskWizardShaft:
"Shaft Wizard"
# GUI
App = FreeCAD
Gui = FreeCADGui
# Table and widget
table = 0
form = 0
# Shaft
shaft = 0
# Feature
featureWindow = 0
# Buttons
buttons = [[None, None, None], [None, None, None], [None, None, None], [None, None, None], [None, None, None], [None, None, None]]
def __init__(self, doc):
mw = QtGui.qApp.activeWindow()
cw = mw.centralWidget() # This is a qmdiarea widget
@ -57,7 +47,7 @@ class TaskWizardShaft:
featureWindow = cw.activeSubWindow()
# Buttons for diagram display
buttons = QtGui.QGridLayout()
buttonLayout = QtGui.QGridLayout()
bnames = [["All [x]", "All [y]", "All [z]" ],
["N [x]", "Q [y]", "Q [z]"],
["Mt [x]", "Mb [z]", "Mb [y]"],
@ -70,10 +60,12 @@ class TaskWizardShaft:
[self.slotNone, self.slotWy, self.slotWz],
[self.slotSigmax, self.slotSigmay, self.slotSigmaz],
[self.slotTaut, self.slotSigmabz, self.slotSigmaby]]
self.buttons = [[None, None, None], [None, None, None], [None, None, None], [None, None, None], [None, None, None], [None, None, None]]
for col in range(3):
for row in range(6):
button = QtGui.QPushButton(bnames[row][col])
buttons.addWidget(button, row, col)
buttonLayout.addWidget(button, row, col)
self.buttons[row][col] = button
button.clicked.connect(slots[row][col])
@ -89,7 +81,7 @@ class TaskWizardShaft:
sublayout = QtGui.QVBoxLayout()
sublayout.setObjectName("ShaftWizardLayout") # Do not change or translate
sublayout.addWidget(self.table.widget)
sublayout.addLayout(buttons)
sublayout.addLayout(buttonLayout)
layout.addLayout(sublayout)
self.form.setLayout(layout)
@ -157,6 +149,9 @@ class TaskWizardShaft:
if self.form:
del self.form
return True
def isAllowedAlterDocument(self):
return False
# Work-around to allow a callback
# Problem: From the FemConstraint ViewProvider, we need to tell the Shaft instance that the user finished editing the constraint

View File

@ -47,12 +47,7 @@ class WizardShaftTable:
"Start edge size",
"End edge type",
"End edge size"
]
widget = 0
wizard = 0
shaft = 0
editedRow = None
editedColumn = None
]
def __init__(self, w, s):
for key in self.rowDict.iterkeys():
@ -65,6 +60,8 @@ class WizardShaftTable:
self.widget.setObjectName("ShaftWizardTable") # Do not change or translate: Used in ViewProviderFemConstraintXXX
self.widget.setWindowTitle("Shaft wizard")
self.widget.resize(QtCore.QSize(300,200))
self.editedRow = None
self.editedColumn = None
# Label rows and columns
self.widget.setVerticalHeaderLabels(self.headers)
@ -76,13 +73,15 @@ class WizardShaftTable:
action.triggered.connect(self.slotInsertColumn)
self.widget.addAction(action)
self.widget.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.widget.horizontalHeader().addAction(action)
self.widget.horizontalHeader().setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
# Set some default data
# Section 1
self.addColumn()
self.setLength(0, 40.0)
self.setDiameter(0, 50.0)
self.setConstraintType(0, "Bearing")
self.setConstraintType(0, "Fixed")
# Section 2
self.addColumn()
self.setLength(1, 80.0)
@ -164,6 +163,7 @@ class WizardShaftTable:
widget.insertItem(2, "Fillet")
self.widget.setCellWidget(self.rowDict["StartEdgeType"],index, widget)
widget.setCurrentIndex(0)
widget.setEnabled(False)
#self.widget.connect(widget, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.slotLoadType)
# Start edge size
widget = QtGui.QDoubleSpinBox(self.widget)
@ -173,6 +173,7 @@ class WizardShaftTable:
widget.setValue(1)
widget.valueChanged.connect(self.slotValueChanged)
widget.editingFinished.connect(self.slotEditingFinished)
widget.setEnabled(False)
# End edge type
widget = QtGui.QComboBox(self.widget)
widget.insertItem(0, "None",)
@ -180,6 +181,7 @@ class WizardShaftTable:
widget.insertItem(2, "Fillet")
self.widget.setCellWidget(self.rowDict["EndEdgeType"],index, widget)
widget.setCurrentIndex(0)
widget.setEnabled(False)
#self.widget.connect(widget, QtCore.SIGNAL("currentIndexChanged(const QString&)"), self.slotLoadType)
# End edge size
widget = QtGui.QDoubleSpinBox(self.widget)
@ -189,6 +191,7 @@ class WizardShaftTable:
widget.setValue(1)
widget.valueChanged.connect(self.slotValueChanged)
widget.editingFinished.connect(self.slotEditingFinished)
widget.setEnabled(False)
def slotValueChanged(self, value):
(self.editedRow, self.editedColumn) = self.getFocusedCell()