This commit is contained in:
wmayer
2017-11-01 14:14:23 +01:00
8 changed files with 352 additions and 453 deletions

View File

@@ -987,7 +987,8 @@ class Snapper:
self.radius = 0
self.setCursor()
if hideSnapBar or Draft.getParam("hideSnapBar",False):
self.toolbar.hide()
if hasattr(self,"toolbar") and self.toolbar:
self.toolbar.hide()
self.mask = None
self.lastArchPoint = None
self.selectMode = False

View File

@@ -67,6 +67,9 @@
<property name="prefEntry" stdset="0">
<cstring>WorkingDir</cstring>
</property>
<property name="mode">
<enum>Gui::FileChooser::Directory</enum>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Fem/General</cstring>
</property>

View File

@@ -345,7 +345,8 @@ class _TaskPanelFemMaterial:
ym_new_unit = "MPa"
ym = FreeCAD.Units.Quantity(matmap['YoungsModulus'])
ym_with_new_unit = ym.getValueAs(ym_new_unit)
self.form.input_fd_young_modulus.setText("{} {}".format(ym_with_new_unit, ym_new_unit))
q = FreeCAD.Units.Quantity("{} {}".format(ym_with_new_unit, ym_new_unit))
self.form.input_fd_young_modulus.setText(q.UserString)
if 'PoissonRatio' in matmap:
self.form.spinBox_poisson_ratio.setValue(float(matmap['PoissonRatio']))
# Fluidic properties
@@ -353,35 +354,41 @@ class _TaskPanelFemMaterial:
nu_new_unit = "m^2/s"
nu = FreeCAD.Units.Quantity(matmap['KinematicViscosity'])
nu_with_new_unit = nu.getValueAs(nu_new_unit)
self.form.input_fd_kinematic_viscosity.setText("{} {}".format(nu_with_new_unit, nu_new_unit))
q = FreeCAD.Units.Quantity("{} {}".format(nu_with_new_unit, nu_new_unit))
self.form.input_fd_kinematic_viscosity.setText(q.UserString)
# For isotropic materials the volumetric thermal expansion coefficient is three times the linear coefficient:
if 'VolumetricThermalExpansionCoefficient' in matmap: # linear, only for solid
vtec_new_unit = "m/m/K"
vtec = FreeCAD.Units.Quantity(matmap['VolumetricThermalExpansionCoefficient'])
vtec_with_new_unit = vtec.getValueAs(vtec_new_unit)
self.form.input_fd_vol_expansion_coefficient.setText("{} {}".format(vtec_with_new_unit, vtec_new_unit))
q = FreeCAD.Units.Quantity("{} {}".format(vtec_with_new_unit, vtec_new_unit))
self.form.input_fd_vol_expansion_coefficient.setText(q.UserString)
if 'Density' in matmap:
density_new_unit = "kg/m^3"
density = FreeCAD.Units.Quantity(matmap['Density'])
density_with_new_unit = density.getValueAs(density_new_unit)
self.form.input_fd_density.setText("{} {}".format(density_with_new_unit, density_new_unit))
#self.form.input_fd_density.setText("{} {}".format(density_with_new_unit, density_new_unit))
q = FreeCAD.Units.Quantity("{} {}".format(density_with_new_unit, density_new_unit))
self.form.input_fd_density.setText(q.UserString)
# thermal properties
if 'ThermalConductivity' in matmap:
tc_new_unit = "W/m/K"
tc = FreeCAD.Units.Quantity(matmap['ThermalConductivity'])
tc_with_new_unit = tc.getValueAs(tc_new_unit)
self.form.input_fd_thermal_conductivity.setText("{} {}".format(tc_with_new_unit, tc_new_unit))
q = FreeCAD.Units.Quantity("{} {}".format(tc_with_new_unit, tc_new_unit))
self.form.input_fd_thermal_conductivity.setText(q.UserString)
if 'ThermalExpansionCoefficient' in matmap: # linear, only for solid
tec_new_unit = "um/m/K"
tec = FreeCAD.Units.Quantity(matmap['ThermalExpansionCoefficient'])
tec_with_new_unit = tec.getValueAs(tec_new_unit)
self.form.input_fd_expansion_coefficient.setText("{} {}".format(tec_with_new_unit, tec_new_unit))
q = FreeCAD.Units.Quantity("{} {}".format(tec_with_new_unit, tec_new_unit))
self.form.input_fd_expansion_coefficient.setText(q.UserString)
if 'SpecificHeat' in matmap:
sh_new_unit = "J/kg/K"
sh = FreeCAD.Units.Quantity(matmap['SpecificHeat'])
sh_with_new_unit = sh.getValueAs(sh_new_unit)
self.form.input_fd_specific_heat.setText("{} {}".format(sh_with_new_unit, sh_new_unit))
q = FreeCAD.Units.Quantity("{} {}".format(sh_with_new_unit, sh_new_unit))
self.form.input_fd_specific_heat.setText(q.UserString)
def add_transient_material(self, material):
material_name = self.get_material_name(material)

View File

@@ -15,187 +15,156 @@
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QToolBox" name="toolBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<widget class="QWidget" name="removeEditAddGroup" native="true">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="2">
<widget class="QPushButton" name="pbAdd">
<property name="text">
<string>Add...</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pbDelete">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pbEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Edit...</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QGroupBox" name="cbTagGeneration">
<property name="title">
<string>Auto Generate</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="1">
<widget class="QSpinBox" name="sbCount">
<property name="minimum">
<number>2</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pbGenerate">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Replace All</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Number of Tags</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QListWidget" name="lwTags">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;List of current tags. Edit coordinates by double click or Edit button.&lt;/p&gt;&lt;p&gt;Tags are automatically disabled if they overlap with the previous tag, or don't lie on the base wire.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tbpTags">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>381</width>
<height>528</height>
</rect>
</widget>
</item>
<item row="0" column="0">
<widget class="QWidget" name="parameterGroup" native="true">
<layout class="QFormLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<attribute name="label">
<string>Tags</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QFormLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Width</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Height</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Angle </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::InputField" name="ifWidth">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Width of the resulting holding tag.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::InputField" name="ifHeight">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Height of holding tag.&lt;/p&gt;&lt;p&gt;Note that resulting tag might be smaller if the tag's width and angle result in a triangular shape.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="dsbAngle">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Plunge angle for ascent and descent of holding tag.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<double>5.000000000000000</double>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
<property name="singleStep">
<double>15.000000000000000</double>
</property>
<property name="value">
<double>45.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Radius</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::InputField" name="ifRadius">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Radius of the fillet at the top.&lt;/p&gt;&lt;p&gt;If the radius is too big for the tag shape it gets reduced to the maximum possible radius - resulting in a spherical shape.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QListWidget" name="lwTags">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;List of current tags. Edit coordinates by double click or Edit button.&lt;/p&gt;&lt;p&gt;Tags are automatically disabled if they overlap with the previous tag, or don't lie on the base wire.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QPushButton" name="pbDelete">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pbAdd">
<property name="text">
<string>Add...</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pbEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Edit...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="cbTagGeneration">
<property name="title">
<string>Auto Generate</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="1">
<widget class="QSpinBox" name="sbCount">
<property name="minimum">
<number>2</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pbGenerate">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Replace All</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Number of Tags</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Width</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Height</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Angle </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::InputField" name="ifWidth">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Width of the resulting holding tag.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::InputField" name="ifHeight">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Height of holding tag.&lt;/p&gt;&lt;p&gt;Note that resulting tag might be smaller if the tag's width and angle result in a triangular shape.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="dsbAngle">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Plunge angle for ascent and descent of holding tag.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<double>5.000000000000000</double>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
<property name="singleStep">
<double>15.000000000000000</double>
</property>
<property name="value">
<double>45.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Radius</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::InputField" name="ifRadius">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Radius of the fillet at the top.&lt;/p&gt;&lt;p&gt;If the radius is too big for the tag shape it gets reduced to the maximum possible radius - resulting in a spherical shape.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>

View File

@@ -42,8 +42,11 @@ from PySide import QtCore
"""Holding Tags Dressup object and FreeCAD command"""
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
#PathLog.trackModule()
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule()
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
# Qt tanslation handling
def translate(context, text, disambig=None):
@@ -643,14 +646,18 @@ class PathData:
ordered.append(t)
# disable all tags that are not on the base wire.
for tag in tags:
PathLog.notice("Tag #%d not on base wire - disabling\n" % len(ordered))
PathLog.info("Tag #%d (%.2f, %.2f) not on base wire - disabling\n" % (len(ordered), tag.x, tag.y))
tag.enabled = False
ordered.append(tag)
return ordered
def pointIsOnPath(self, p):
for e in self.edges:
if DraftGeomUtils.isPtOnEdge(p, e):
v = Part.Vertex(FreeCAD.Vector(p.x, p.y, self.minZ))
PathLog.debug("pt = (%f, %f, %f)" % (v.X, v.Y, v.Z))
for e in self.bottomEdges:
indent = "{} ".format(e.distToShape(v)[0])
debugEdge(e, indent, True)
if PathGeom.isRoughly(v.distToShape(e)[0], 0.0, 1.0):
return True
return False
@@ -788,7 +795,7 @@ class ObjectTagDressup:
zVal2 = zVal2 and round(zVal2, 8)
if cmd.Name in ['G1', 'G2', 'G3', 'G01', 'G02', 'G03']:
if zVal is not None and zVal2 != zVal:
if False and zVal is not None and zVal2 != zVal:
params['F'] = vertFeed
else:
params['F'] = horizFeed
@@ -823,7 +830,7 @@ class ObjectTagDressup:
if tag.enabled:
if prev:
if prev.solid.common(tag.solid).Faces:
PathLog.notice("Tag #%d intersects with previous tag - disabling\n" % i)
PathLog.info("Tag #%d intersects with previous tag - disabling\n" % i)
PathLog.debug("this tag = %d [%s]" % (i, tag.solid.BoundBox))
tag.enabled = False
elif self.pathData.edges:
@@ -831,7 +838,7 @@ class ObjectTagDressup:
p0 = e.valueAt(e.FirstParameter)
p1 = e.valueAt(e.LastParameter)
if tag.solid.isInside(p0, PathGeom.Tolerance, True) or tag.solid.isInside(p1, PathGeom.Tolerance, True):
PathLog.notice("Tag #%d intersects with starting point - disabling\n" % i)
PathLog.info("Tag #%d intersects with starting point - disabling\n" % i)
tag.enabled = False
if tag.enabled:

View File

@@ -27,6 +27,7 @@ import FreeCADGui
import Path
import PathScripts
#import PathScripts.PathDressupTag as PathDressupTag
import PathScripts.PathGetPoint as PathGetPoint
import PathScripts.PathDressupHoldingTags as PathDressupTag
import PathScripts.PathLog as PathLog
import PathScripts.PathUtils as PathUtils
@@ -56,18 +57,8 @@ class PathDressupTagTaskPanel:
self.obj = obj
self.obj.Proxy.obj = obj
self.viewProvider = viewProvider
self.form = QtGui.QWidget()
self.formTags = FreeCADGui.PySideUic.loadUi(":/panels/HoldingTagsEdit.ui")
self.formPoint = FreeCADGui.PySideUic.loadUi(":/panels/PointEdit.ui")
self.layout = QtGui.QVBoxLayout(self.form)
#self.form.setGeometry(self.formTags.geometry())
self.form.setWindowTitle(self.formTags.windowTitle())
self.form.setSizePolicy(self.formTags.sizePolicy())
self.formTags.setParent(self.form)
self.formPoint.setParent(self.form)
self.layout.addWidget(self.formTags)
self.layout.addWidget(self.formPoint)
self.formPoint.hide()
self.form = FreeCADGui.PySideUic.loadUi(":/panels/HoldingTagsEdit.ui")
self.getPoint = PathGetPoint.TaskPanel(self.form.removeEditAddGroup, True)
self.jvo = PathUtils.findParentJob(obj).ViewObject
if jvoVisibility is None:
FreeCAD.ActiveDocument.openTransaction(translate("PathDressup_HoldingTags", "Edit HoldingTags Dress-up"))
@@ -78,9 +69,6 @@ class PathDressupTagTaskPanel:
self.jvoVisible = jvoVisibility
self.pt = FreeCAD.Vector(0, 0, 0)
closeButton = self.formPoint.buttonBox.button(QtGui.QDialogButtonBox.StandardButton.Close)
closeButton.setText(translate("PathDressup_HoldingTags", "Done"))
self.isDirty = True
def getStandardButtons(self):
@@ -92,22 +80,9 @@ class PathDressupTagTaskPanel:
self.obj.Proxy.execute(self.obj)
self.isDirty = False
def addEscapeShortcut(self):
# The only way I could get to intercept the escape key, or really any key was
# by creating an action with a shortcut .....
self.escape = QtGui.QAction(self.formPoint)
self.escape.setText('Done')
self.escape.setShortcut(QtGui.QKeySequence.fromString('Esc'))
QtCore.QObject.connect(self.escape, QtCore.SIGNAL('triggered()'), self.pointDone)
self.formPoint.addAction(self.escape)
def removeEscapeShortcut(self):
if self.escape:
self.formPoint.removeAction(self.escape)
self.escape = None
def modifyStandardButtons(self, buttonBox):
self.buttonBox = buttonBox
self.getPoint.buttonBox = buttonBox
def abort(self):
FreeCAD.ActiveDocument.abortTransaction()
@@ -136,9 +111,9 @@ class PathDressupTagTaskPanel:
def getTags(self, includeCurrent):
tags = []
index = self.formTags.lwTags.currentRow()
for i in range(0, self.formTags.lwTags.count()):
item = self.formTags.lwTags.item(i)
index = self.form.lwTags.currentRow()
for i in range(0, self.form.lwTags.count()):
item = self.form.lwTags.item(i)
enabled = item.checkState() == QtCore.Qt.CheckState.Checked
x = item.data(self.DataX)
y = item.data(self.DataY)
@@ -148,10 +123,10 @@ class PathDressupTagTaskPanel:
return tags
def getFields(self):
width = FreeCAD.Units.Quantity(self.formTags.ifWidth.text()).Value
height = FreeCAD.Units.Quantity(self.formTags.ifHeight.text()).Value
angle = self.formTags.dsbAngle.value()
radius = FreeCAD.Units.Quantity(self.formTags.ifRadius.text()).Value
width = FreeCAD.Units.Quantity(self.form.ifWidth.text()).Value
height = FreeCAD.Units.Quantity(self.form.ifHeight.text()).Value
angle = self.form.dsbAngle.value()
radius = FreeCAD.Units.Quantity(self.form.ifRadius.text()).Value
tags = self.getTags(True)
positions = []
@@ -183,8 +158,8 @@ class PathDressupTagTaskPanel:
def updateTagsView(self):
PathLog.track()
self.formTags.lwTags.blockSignals(True)
self.formTags.lwTags.clear()
self.form.lwTags.blockSignals(True)
self.form.lwTags.clear()
for i, pos in enumerate(self.Positions):
lbl = "%d: (%.2f, %.2f)" % (i, pos.x, pos.y)
item = QtGui.QListWidgetItem(lbl)
@@ -200,41 +175,36 @@ class PathDressupTagTaskPanel:
flags |= QtCore.Qt.ItemFlag.ItemIsEnabled
flags |= QtCore.Qt.ItemFlag.ItemIsUserCheckable
item.setFlags(flags)
self.formTags.lwTags.addItem(item)
self.formTags.lwTags.blockSignals(False)
self.form.lwTags.addItem(item)
self.form.lwTags.blockSignals(False)
self.whenTagSelectionChanged()
self.viewProvider.updatePositions(self.Positions, self.Disabled)
def generateNewTags(self):
count = self.formTags.sbCount.value()
count = self.form.sbCount.value()
if not self.obj.Proxy.generateTags(self.obj, count):
self.obj.Proxy.execute(self.obj)
self.updateTagsView()
#if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
# # this causes a big of an echo and a double click on the spin buttons, don't know why though
# FreeCAD.ActiveDocument.recompute()
def updateModel(self):
self.getFields()
self.updateTagsView()
self.isDirty = True
#FreeCAD.ActiveDocument.recompute()
def whenCountChanged(self):
count = self.formTags.sbCount.value()
self.formTags.pbGenerate.setEnabled(count)
count = self.form.sbCount.value()
self.form.pbGenerate.setEnabled(count)
def selectTagWithId(self, index):
PathLog.track(index)
self.formTags.lwTags.setCurrentRow(index)
self.form.lwTags.setCurrentRow(index)
def whenTagSelectionChanged(self):
index = self.formTags.lwTags.currentRow()
count = self.formTags.lwTags.count()
self.formTags.pbDelete.setEnabled(index != -1 and count > 2)
self.formTags.pbEdit.setEnabled(index != -1)
index = self.form.lwTags.currentRow()
count = self.form.lwTags.count()
self.form.pbDelete.setEnabled(index != -1 and count > 2)
self.form.pbEdit.setEnabled(index != -1)
self.viewProvider.selectTag(index)
def whenTagsViewChanged(self):
@@ -255,11 +225,11 @@ class PathDressupTagTaskPanel:
self.Positions.append(FreeCAD.Vector(point.x, point.y, 0))
self.updateTagsView()
else:
print("ignore new tag at %s" % (point))
print("ignore new tag at %s (obj=%s, on-path=%d" % (point, obj, 0))
def addNewTag(self):
self.tags = self.getTags(True)
self.getPoint(self.addNewTagAt)
self.getPoint.getPoint(self.addNewTagAt)
def editTagAt(self, point, obj):
if point and obj and (obj or point != FreeCAD.Vector()) and self.obj.Proxy.pointIsOnPath(self.obj, point):
@@ -278,10 +248,10 @@ class PathDressupTagTaskPanel:
x = item.data(self.DataX)
y = item.data(self.DataY)
z = item.data(self.DataZ)
self.getPoint(self.editTagAt, FreeCAD.Vector(x, y, z))
self.getPoint.getPoint(self.editTagAt, FreeCAD.Vector(x, y, z))
def editSelectedTag(self):
self.editTag(self.formTags.lwTags.currentItem())
self.editTag(self.form.lwTags.currentItem())
def removeGlobalCallbacks(self):
if hasattr(self, 'view') and self.view:
@@ -293,54 +263,6 @@ class PathDressupTagTaskPanel:
self.pointCbMove = None
self.view = None
def getPoint(self, whenDone, start=None):
def displayPoint(p):
self.formPoint.ifValueX.setText(FreeCAD.Units.Quantity(p.x, FreeCAD.Units.Length).UserString)
self.formPoint.ifValueY.setText(FreeCAD.Units.Quantity(p.y, FreeCAD.Units.Length).UserString)
self.formPoint.ifValueZ.setText(FreeCAD.Units.Quantity(p.z, FreeCAD.Units.Length).UserString)
self.formPoint.ifValueX.setFocus()
self.formPoint.ifValueX.selectAll()
def mouseMove(cb):
event = cb.getEvent()
pos = event.getPosition()
cntrl = event.wasCtrlDown()
shift = event.wasShiftDown()
self.pt = FreeCADGui.Snapper.snap(pos, lastpoint=start, active=cntrl, constrain=shift)
plane = FreeCAD.DraftWorkingPlane
p = plane.getLocalCoords(self.pt)
displayPoint(p)
def click(cb):
event = cb.getEvent()
if event.getButton() == 1 and event.getState() == coin.SoMouseButtonEvent.DOWN:
accept()
def accept():
if start:
self.pointAccept()
else:
self.pointAcceptAndContinue()
def cancel():
self.pointReject()
self.pointWhenDone = whenDone
self.formTags.hide()
self.formPoint.show()
self.addEscapeShortcut()
if start:
displayPoint(start)
else:
displayPoint(FreeCAD.Vector(0,0,0))
self.view = Draft.get3DView()
self.pointCbClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), click)
self.pointCbMove = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(), mouseMove)
self.buttonBox.setEnabled(False)
def setupSpinBox(self, widget, val, decimals = 2):
if decimals:
widget.setDecimals(decimals)
@@ -348,11 +270,11 @@ class PathDressupTagTaskPanel:
def setFields(self):
self.updateTagsView()
self.formTags.sbCount.setValue(len(self.Positions))
self.formTags.ifHeight.setText(FreeCAD.Units.Quantity(self.obj.Height, FreeCAD.Units.Length).UserString)
self.formTags.ifWidth.setText(FreeCAD.Units.Quantity(self.obj.Width, FreeCAD.Units.Length).UserString)
self.formTags.dsbAngle.setValue(self.obj.Angle)
self.formTags.ifRadius.setText(FreeCAD.Units.Quantity(self.obj.Radius, FreeCAD.Units.Length).UserString)
self.form.sbCount.setValue(len(self.Positions))
self.form.ifHeight.setText(FreeCAD.Units.Quantity(self.obj.Height, FreeCAD.Units.Length).UserString)
self.form.ifWidth.setText(FreeCAD.Units.Quantity(self.obj.Width, FreeCAD.Units.Length).UserString)
self.form.dsbAngle.setValue(self.obj.Angle)
self.form.ifRadius.setText(FreeCAD.Units.Quantity(self.obj.Radius, FreeCAD.Units.Length).UserString)
def setupUi(self):
self.Positions = self.obj.Positions
@@ -362,62 +284,22 @@ class PathDressupTagTaskPanel:
self.whenCountChanged()
if self.obj.Proxy.supportsTagGeneration(self.obj):
self.formTags.sbCount.valueChanged.connect(self.whenCountChanged)
self.formTags.pbGenerate.clicked.connect(self.generateNewTags)
self.form.sbCount.valueChanged.connect(self.whenCountChanged)
self.form.pbGenerate.clicked.connect(self.generateNewTags)
else:
self.formTags.cbTagGeneration.setEnabled(False)
self.form.cbTagGeneration.setEnabled(False)
self.formTags.lwTags.itemChanged.connect(self.whenTagsViewChanged)
self.formTags.lwTags.itemSelectionChanged.connect(self.whenTagSelectionChanged)
self.formTags.lwTags.itemActivated.connect(self.editTag)
self.form.lwTags.itemChanged.connect(self.whenTagsViewChanged)
self.form.lwTags.itemSelectionChanged.connect(self.whenTagSelectionChanged)
self.form.lwTags.itemActivated.connect(self.editTag)
self.formTags.pbDelete.clicked.connect(self.deleteSelectedTag)
self.formTags.pbEdit.clicked.connect(self.editSelectedTag)
self.formTags.pbAdd.clicked.connect(self.addNewTag)
self.formPoint.buttonBox.accepted.connect(self.pointAccept)
self.formPoint.buttonBox.rejected.connect(self.pointReject)
self.formPoint.ifValueX.editingFinished.connect(self.updatePoint)
self.formPoint.ifValueY.editingFinished.connect(self.updatePoint)
self.formPoint.ifValueZ.editingFinished.connect(self.updatePoint)
self.form.pbDelete.clicked.connect(self.deleteSelectedTag)
self.form.pbEdit.clicked.connect(self.editSelectedTag)
self.form.pbAdd.clicked.connect(self.addNewTag)
self.viewProvider.turnMarkerDisplayOn(True)
def pointFinish(self, ok, cleanup = True):
obj = FreeCADGui.Snapper.lastSnappedObject
if cleanup:
self.removeGlobalCallbacks();
FreeCADGui.Snapper.off()
self.buttonBox.setEnabled(True)
self.removeEscapeShortcut()
self.formPoint.hide()
self.formTags.show()
self.formTags.setFocus()
if ok:
self.pointWhenDone(self.pt, obj)
else:
self.pointWhenDone(None, None)
def pointDone(self):
self.pointFinish(False)
def pointReject(self):
self.pointFinish(False)
def pointAccept(self):
self.pointFinish(True)
def pointAcceptAndContinue(self):
self.pointFinish(True, False)
def updatePoint(self):
x = FreeCAD.Units.Quantity(self.formPoint.ifValueX.text()).Value
y = FreeCAD.Units.Quantity(self.formPoint.ifValueY.text()).Value
z = FreeCAD.Units.Quantity(self.formPoint.ifValueZ.text()).Value
self.pt = FreeCAD.Vector(x, y, z)
class HoldingTagMarker:
def __init__(self, point, colors):

View File

@@ -25,6 +25,7 @@
import Draft
import FreeCAD
import FreeCADGui
import PathScripts.PathLog as PathLog
from PySide import QtCore, QtGui
from pivy import coin
@@ -34,6 +35,8 @@ __author__ = "sliptonic (Brad Collette)"
__url__ = "http://www.freecadweb.org"
__doc__ = "Helper class to use FreeCADGUi.Snapper to let the user enter arbitray points while the task panel is active."
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
class TaskPanel:
'''Use an instance of this class in another TaskPanel to invoke the snapper.
Create the instance in the TaskPanel's constructors and invoke getPoint(whenDone, start) whenever a new point is
@@ -41,7 +44,7 @@ class TaskPanel:
provided in the constructor.
The (only) public API function other than the constructor is getPoint(whenDone, start).
'''
def __init__(self, form):
def __init__(self, form, onPath=False):
'''__init___(form) ... form will be replaced by PointEdit.ui while the Snapper is active.'''
self.formOrig = form
self.formPoint = FreeCADGui.PySideUic.loadUi(":/panels/PointEdit.ui")
@@ -52,6 +55,8 @@ class TaskPanel:
self.setupUi()
self.buttonBox = None
self.onPath = onPath
self.obj = None
def setupUi(self):
'''setupUi() ... internal function - do not call.'''
@@ -95,19 +100,38 @@ class TaskPanel:
self.formPoint.ifValueX.selectAll()
def mouseMove(cb):
p = None
event = cb.getEvent()
pos = event.getPosition()
cntrl = event.wasCtrlDown()
shift = event.wasShiftDown()
self.pt = FreeCADGui.Snapper.snap(pos, lastpoint=start, active=cntrl, constrain=shift)
plane = FreeCAD.DraftWorkingPlane
p = plane.getLocalCoords(self.pt)
displayPoint(p)
if self.onPath:
# There should not be a dependency from Draft->Path, so handle Path "snapping"
# directly, at least for now. Simple enough because there isn't really any
# "snapping" going on other than what getObjectInfo() provides.
screenpos = tuple(pos.getValue())
snapInfo = Draft.get3DView().getObjectInfo(screenpos)
if snapInfo:
obj = FreeCAD.ActiveDocument.getObject(snapInfo['Object'])
if hasattr(obj, 'Path'):
self.obj = obj
p = FreeCAD.Vector(snapInfo['x'], snapInfo['y'], snapInfo['z'])
else:
self.obj = None
else:
# Snapper handles regular objects just fine
cntrl = event.wasCtrlDown()
shift = event.wasShiftDown()
self.pt = FreeCADGui.Snapper.snap(pos, lastpoint=start, active=cntrl, constrain=shift)
plane = FreeCAD.DraftWorkingPlane
p = plane.getLocalCoords(self.pt)
self.obj = FreeCADGui.Snapper.lastSnappedObject
if p:
displayPoint(p)
def click(cb):
event = cb.getEvent()
if event.getButton() == 1 and event.getState() == coin.SoMouseButtonEvent.DOWN:
accept()
if self.obj:
accept()
def accept():
if start:
@@ -137,7 +161,6 @@ class TaskPanel:
def pointFinish(self, ok, cleanup = True):
'''pointFinish(ok, cleanup=True) ... internal function - do not call.'''
obj = FreeCADGui.Snapper.lastSnappedObject
if cleanup:
self.removeGlobalCallbacks()
@@ -150,7 +173,7 @@ class TaskPanel:
self.formOrig.setFocus()
if ok:
self.pointWhenDone(self.pt, obj)
self.pointWhenDone(self.pt, self.obj)
else:
self.pointWhenDone(None, None)

View File

@@ -52,98 +52,11 @@ class CommandPathSanity:
def IsActive(self):
obj = FreeCADGui.Selection.getSelectionEx()[0].Object
if (obj.TypeId == "Path::FeatureCompoundPython"):
if hasattr(obj, 'Operations') and hasattr(obj, 'ToolController'):
return True
return False
def __review(self, obj):
"checks the selected job for common errors"
toolcontrolcount = 0
operationcount = 0
#global baseobj
# if obj.X_Max == obj.X_Min or obj.Y_Max == obj.Y_Min:
# FreeCAD.Console.PrintWarning(translate("Path_Sanity", "It appears the machine limits haven't been set. Not able to check path extents.\n"))
if obj.PostProcessor == '':
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Postprocessor has not been selected.\n"))
if obj.PostProcessorOutputFile == '':
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "No output file is named. You'll be prompted during postprocessing.\n"))
for item in obj.Group:
print("Checking: " + item.Label)
if isinstance(item.Proxy, PathScripts.PathToolController.ToolController):
toolcontrolcount += 1
self.__checkTC(item)
if isinstance(item.Proxy, PathScripts.PathProfileContour.ObjectContour):
if item.Active:
operationcount +=1
# simobj = item.Proxy.execute(item, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
if isinstance(item.Proxy, PathScripts.PathProfileFaces.ObjectProfile):
if item.Active:
operationcount +=1
# simobj = item.Proxy.execute(item, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
if isinstance(item.Proxy, PathScripts.PathProfileEdges.ObjectProfile):
if item.Active:
operationcount +=1
# simobj = item.Proxy.execute(item, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
if isinstance(item.Proxy, PathScripts.PathPocket.ObjectPocket):
if item.Active:
operationcount +=1
# simobj = item.Proxy.execute(item, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
if isinstance(item.Proxy, PathScripts.PathDrilling.ObjectDrilling):
if item.Active:
operationcount +=1
if isinstance(item.Proxy, PathScripts.PathMillFace.ObjectFace):
if item.Active:
operationcount +=1
if isinstance(item.Proxy, PathScripts.PathHelix.ObjectHelix):
if item.Active:
operationcount +=1
if isinstance(item.Proxy, PathScripts.PathSurface.ObjectSurface):
if item.Active:
operationcount +=1
if operationcount == 0: #no active operations
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Tool Controller was not found. Default values are used which is dangerous. Please add a Tool Controller.\n"))
if toolcontrolcount == 0: #need at least one active TC
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Tool Controller was not found. Default values are used which is dangerous. Please add a Tool Controller.\n"))
def __checkTC(self, item):
if item.ToolNumber == 0:
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(item.Label) + " is using ID 0 which the undefined default. Please set a real tool.\n"))
if item.HorizFeed == 0:
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(item.Label) + " has a 0 value for the Horizontal feed rate\n"))
if item.VertFeed == 0:
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(item.Label) + " has a 0 value for the Vertical feed rate\n"))
if item.SpindleSpeed == 0:
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(item.Label) + " has a 0 value for the spindle speed\n"))
def Activated(self):
#global baseobj
# if everything is ok, execute
obj = FreeCADGui.Selection.getSelectionEx()[0].Object
self.baseobj = obj.Base
@@ -152,6 +65,100 @@ class CommandPathSanity:
return
self.__review(obj)
def __review(self, obj):
"checks the selected job for common errors"
clean = True
# if obj.X_Max == obj.X_Min or obj.Y_Max == obj.Y_Min:
# FreeCAD.Console.PrintWarning(translate("Path_Sanity", "It appears the machine limits haven't been set. Not able to check path extents.\n"))
if obj.PostProcessor == '':
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Postprocessor has not been selected.\n"))
clean = False
if obj.PostProcessorOutputFile == '':
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "No output file is named. You'll be prompted during postprocessing.\n"))
clean = False
for tc in obj.ToolController:
PathLog.info("Checking: {}.{}".format(obj.Label, tc.Label))
clean &= self.__checkTC(tc)
for op in obj.Operations.Group:
PathLog.info("Checking: {}.{}".format(obj.Label, op.Label))
if isinstance(op.Proxy, PathScripts.PathProfileContour.ObjectContour):
if op.Active:
# simobj = op.Proxy.execute(op, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
# clean = False
pass
if isinstance(op.Proxy, PathScripts.PathProfileFaces.ObjectProfile):
if op.Active:
# simobj = op.Proxy.execute(op, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
# clean = False
pass
if isinstance(op.Proxy, PathScripts.PathProfileEdges.ObjectProfile):
if op.Active:
# simobj = op.Proxy.execute(op, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
# clean = False
pass
if isinstance(op.Proxy, PathScripts.PathPocket.ObjectPocket):
if op.Active:
# simobj = op.Proxy.execute(op, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
# clean = False
pass
if isinstance(op.Proxy, PathScripts.PathPocketShape.ObjectPocket):
if op.Active:
# simobj = op.Proxy.execute(op, getsim=True)
# if simobj is not None:
# print ('collision detected')
# PC.getCollisionObject(self.baseobj, simobj)
# clean = False
pass
if not any(op.Active for op in obj.Operations.Group): #no active operations
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "No active operations was found. Post processing will not result in any tooling."))
clean = False
if len(obj.ToolController) == 0: #need at least one active TC
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Tool Controller was not found. Default values are used which is dangerous. Please add a Tool Controller.\n"))
clean = False
if clean:
FreeCAD.Console.PrintMessage(translate("Path_Sanity", "No issues detected, {} has passed basic sanity check.").format(obj.Label))
def __checkTC(self, tc):
clean = True
if tc.ToolNumber == 0:
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(tc.Label) + " is using ID 0 which the undefined default. Please set a real tool.\n"))
clean = False
if tc.HorizFeed == 0:
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(tc.Label) + " has a 0 value for the Horizontal feed rate\n"))
clean = False
if tc.VertFeed == 0:
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(tc.Label) + " has a 0 value for the Vertical feed rate\n"))
clean = False
if tc.SpindleSpeed == 0:
FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(tc.Label) + " has a 0 value for the spindle speed\n"))
clean = False
return clean
if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand('Path_Sanity',CommandPathSanity())