Merge branch 'refs/heads/WizardShaft'
This commit is contained in:
commit
eb6d7cedbc
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue
Block a user