Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2016
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.22 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. # ***************************************************************************
  4. # * *
  5. # * Copyright (c) 2014 sliptonic <shopinthewoods@gmail.com> *
  6. # * *
  7. # * This program is free software; you can redistribute it and/or modify *
  8. # * it under the terms of the GNU Lesser General Public License (LGPL) *
  9. # * as published by the Free Software Foundation; either version 2 of *
  10. # * the License, or (at your option) any later version. *
  11. # * for detail see the LICENCE text file. *
  12. # * *
  13. # * This program is distributed in the hope that it will be useful, *
  14. # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. # * GNU Library General Public License for more details. *
  17. # * *
  18. # * You should have received a copy of the GNU Library General Public *
  19. # * License along with this program; if not, write to the Free Software *
  20. # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
  21. # * USA *
  22. # * *
  23. # ***************************************************************************
  24.  
  25. import FreeCAD
  26. import xml.sax
  27. import FreeCADGui
  28. import Path
  29. import os
  30. from PySide import QtCore, QtGui
  31.  
  32. try:
  33. _encoding = QtGui.QApplication.UnicodeUTF8
  34.  
  35. def _translate(context, text, disambig):
  36. return QtGui.QApplication.translate(context, text, disambig, _encoding)
  37. except AttributeError:
  38. def _translate(context, text, disambig):
  39. return QtGui.QApplication.translate(context, text, disambig)
  40.  
  41.  
  42. # Tooltable XML readers
  43. class FreeCADTooltableHandler(xml.sax.ContentHandler):
  44. # http://www.tutorialspoint.com/python/python_xml_processing.htm
  45.  
  46. def __init__(self):
  47. self.tooltable = None
  48. self.tool = None
  49. self.number = None
  50.  
  51. # Call when an element is found
  52. def startElement(self, tag, attributes):
  53. if tag == "Tooltable":
  54. self.tooltable = Path.Tooltable()
  55. elif tag == "Toolslot":
  56. self.number = int(attributes["number"])
  57. elif tag == "Tool":
  58. self.tool = Path.Tool()
  59. self.tool.Name = str(attributes["name"])
  60. self.tool.ToolType = str(attributes["type"])
  61. self.tool.Material = str(attributes["mat"])
  62. # for some reason without the following line I get an error
  63. #print attributes["diameter"]
  64. self.tool.Diameter = float(attributes["diameter"])
  65. self.tool.LengthOffset = float(attributes["length"])
  66. self.tool.FlatRadius = float(attributes["flat"])
  67. self.tool.CornerRadius = float(attributes["corner"])
  68. self.tool.CuttingEdgeAngle = float(attributes["angle"])
  69. self.tool.CuttingEdgeHeight = float(attributes["height"])
  70.  
  71. # Call when an elements ends
  72. def endElement(self, tag):
  73. if tag == "Toolslot":
  74. if self.tooltable and self.tool and self.number:
  75. self.tooltable.setTool(self.number, self.tool)
  76. self.number = None
  77. self.tool = None
  78.  
  79.  
  80. class HeeksTooltableHandler(xml.sax.ContentHandler):
  81.  
  82. def __init__(self):
  83. self.tooltable = Path.Tooltable()
  84. self.tool = None
  85. self.number = None
  86.  
  87. # Call when an element is found
  88. def startElement(self, tag, attributes):
  89. if tag == "Tool":
  90. self.tool = Path.Tool()
  91. self.number = int(attributes["tool_number"])
  92. self.tool.Name = str(attributes["title"])
  93. elif tag == "params":
  94. t = str(attributes["type"])
  95. if t == "drill":
  96. self.tool.ToolType = "Drill"
  97. elif t == "center_drill_bit":
  98. self.tool.ToolType = "CenterDrill"
  99. elif t == "end_mill":
  100. self.tool.ToolType = "EndMill"
  101. elif t == "slot_cutter":
  102. self.tool.ToolType = "SlotCutter"
  103. elif t == "ball_end_mill":
  104. self.tool.ToolType = "BallEndMill"
  105. elif t == "chamfer":
  106. self.tool.ToolType = "Chamfer"
  107. elif t == "engraving_bit":
  108. self.tool.ToolType = "Engraver"
  109. m = str(attributes["material"])
  110. if m == "0":
  111. self.tool.Material = "HighSpeedSteel"
  112. elif m == "1":
  113. self.tool.Material = "Carbide"
  114. # for some reason without the following line I get an error
  115. #print attributes["diameter"]
  116. self.tool.Diameter = float(attributes["diameter"])
  117. self.tool.LengthOffset = float(attributes["tool_length_offset"])
  118. self.tool.FlatRadius = float(attributes["flat_radius"])
  119. self.tool.CornerRadius = float(attributes["corner_radius"])
  120. self.tool.CuttingEdgeAngle = float(
  121. attributes["cutting_edge_angle"])
  122. self.tool.CuttingEdgeHeight = float(
  123. attributes["cutting_edge_height"])
  124.  
  125. # Call when an elements ends
  126. def endElement(self, tag):
  127. if tag == "Tool":
  128. if self.tooltable and self.tool and self.number:
  129. self.tooltable.setTool(self.number, self.tool)
  130. self.number = None
  131. self.tool = None
  132.  
  133.  
  134. class ToolLibraryManager():
  135. '''
  136. The Tool Library is a list of individual tool tables. Each
  137. Tool Table can contain n tools. The tool library will be persisted to user
  138. preferences and all or part of the library can be exported to other formats
  139. '''
  140.  
  141. def __init__(self):
  142. self.ToolLibrary = []
  143. self.prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
  144. return
  145.  
  146. def saveMainLibrary(self, tooltable):
  147. '''Persists the permanent library to FreeCAD user preferences'''
  148. tmpstring = tooltable.Content
  149. self.prefs.SetString("ToolLibrary", tmpstring)
  150. return True
  151.  
  152. def getLists(self):
  153. '''Builds the list of all Tool Table lists'''
  154. tablelist = []
  155. # tmpstring = self.prefs.GetString("ToolLibrary", "")
  156. # if tmpstring != "":
  157. # Handler = FreeCADTooltableHandler()
  158. # xml.sax.parseString(tmpstring, Handler)
  159. # tt = Handler.tooltable
  160. toollist = {'name': "<Main>", 'listtype': "User"}
  161. tablelist.append(toollist)
  162.  
  163. # Get ToolTables from any open CNC jobs
  164. for o in FreeCAD.ActiveDocument.Objects:
  165. if "Proxy" in o.PropertiesList:
  166. if hasattr(o, "Tooltable"):
  167. toollist = {'name': o.Label,'listtype': "Job"}
  168. tablelist.append(toollist)
  169. return tablelist
  170.  
  171. # methods for lists
  172.  
  173. # def addList(self, tablename, listtype="User", TL=None):
  174. # '''Add a new tooltable to the user library'''
  175. # if TL is None:
  176. # TL = Path.Tooltable()
  177. # toollist = {'name': tablename, 'listtype': listtype, 'list': TL}
  178. # self.ToolLibrary.append(toollist)
  179. # return TL
  180.  
  181. # def deleteList(self, tablename):
  182. # '''Delete all lists from the user library with the given listname'''
  183. # for l in self.ToolLibrary:
  184. # if l['name'] == tablename:
  185. # # maybe check if tools exist in list
  186. # self.ToolLibrary.remove(l)
  187. # return
  188.  
  189. def _findList(self, listname):
  190. tt = None
  191. if listname == "<Main>":
  192. print listname
  193. tmpstring = self.prefs.GetString("ToolLibrary", "")
  194. if tmpstring != "":
  195. Handler = FreeCADTooltableHandler()
  196. xml.sax.parseString(tmpstring, Handler)
  197. tt = Handler.tooltable
  198. else:
  199. tt = Path.Tooltable()
  200. else:
  201. for o in FreeCAD.ActiveDocument.Objects:
  202. if o.Label == listname:
  203. tt = o.Tooltable
  204. return tt
  205.  
  206.  
  207. def getTool(self, listname, toolnum):
  208. tt = self._findList(listname)
  209. return tt.getTool(toolnum)
  210.  
  211. def getTools(self, tablename):
  212. '''returns the tool data for a given table'''
  213. tooldata = []
  214. tt = self._findList(tablename)
  215. if tt:
  216. for number, t in tt.Tools.iteritems():
  217. tooldata.append((number, t.Name, t.ToolType, t.Material, t.Diameter, t.LengthOffset, t.FlatRadius, t.CornerRadius, t.CuttingEdgeAngle, t.CuttingEdgeHeight))
  218. return tooldata
  219.  
  220. # methods for importing and exporting
  221. def read(self, filename, listname):
  222. "imports a tooltable from a file"
  223. parser = xml.sax.make_parser()
  224. parser.setFeature(xml.sax.handler.feature_namespaces, 0)
  225. if os.path.splitext(filename[0])[1].lower() == ".tooltable":
  226. Handler = HeeksTooltableHandler()
  227. else:
  228. Handler = FreeCADTooltableHandler()
  229. parser.setContentHandler(Handler)
  230. parser.parse(str(filename[0]))
  231. if not Handler.tooltable:
  232. return None
  233.  
  234. ht = Handler.tooltable
  235. tl = self._findList(listname)[0]["list"]
  236. for t in ht.Tools:
  237. newt = ht.getTool(t).copy()
  238. tl.addTools(newt)
  239. self.saveLibrary()
  240.  
  241. def write(self, filename, listname):
  242. "exports the tooltable to a file"
  243. tt = self._findList(listname)
  244. if tt:
  245. fil = open(str(filename[0]), "wb")
  246. fil.write('<?xml version="1.0" encoding="UTF-8"?>\n')
  247. fil.write(tt.Content)
  248. fil.close()
  249. print "Written ", filename[0]
  250.  
  251. def addnew(self, listname, tool):
  252. "adds a new tool at the end of the table"
  253. tt = self._findList(listname)
  254. tt.addTools(tool)
  255.  
  256. if listname == "<Main>":
  257. return self.saveMainLibrary(tt)
  258. return True
  259.  
  260. def updateTool(self, listname, toolnum, tool):
  261. '''updates tool data'''
  262. tt = self._findList(listname)
  263. tt.deleteTool(toolnum)
  264. tt.setTool(toolnum, tool)
  265. if listname == "<Main>":
  266. return self.saveMainLibrary(tt)
  267. return True
  268.  
  269.  
  270. def moveup(self, number, listname):
  271. "moves a tool to a lower number, if possible"
  272. if number < 2:
  273. return False
  274. target = number - 1
  275. tt = self._findList(listname)
  276.  
  277. t1 = tt.getTool(number).copy()
  278. tt.deleteTool(number)
  279. if target in tt.Tools.keys():
  280. t2 = tt.getTool(target).copy()
  281. tt.deleteTool(target)
  282. tt.setTool(number, t2)
  283. tt.setTool(target, t1)
  284. if listname == "<Main>":
  285. self.saveMainLibrary(tt)
  286. return True
  287.  
  288. def movedown(self, number, listname):
  289. "moves a tool to a higher number, if possible"
  290. tt = self._findList(listname)
  291. target = number + 1
  292. t1 = tt.getTool(number).copy()
  293. tt.deleteTool(number)
  294. if target in tt.Tools.keys():
  295. t2 = tt.getTool(target).copy()
  296. tt.deleteTool(target)
  297. tt.setTool(number, t2)
  298. tt.setTool(target, t1)
  299. if listname == "<Main>":
  300. self.saveMainLibrary(tt)
  301. return True
  302.  
  303. def delete(self, number, listname):
  304. '''deletes a tool from the current list'''
  305. tt = self._findList(listname)
  306. tt.deleteTool(number)
  307. if listname == "<Main>":
  308. self.saveMainLibrary(tt)
  309. return True
  310.  
  311. def createToolController(self, job, tool):
  312. pass
  313.  
  314. def exportListHeeks(self, tooltable):
  315. '''exports one or more Lists as a HeeksCNC tooltable'''
  316. pass
  317.  
  318. def exportListLinuxCNC(self, tooltable):
  319. '''exports one or more Lists as a LinuxCNC tooltable'''
  320. pass
  321.  
  322. def exportListXML(self, tooltable):
  323. '''exports one or more Lists as an XML file'''
  324. pass
  325.  
  326. class EditorPanel():
  327. Header = ['ToolNumber', 'Name','Type','Material', 'Diameter','Length Offset','Flat Radius','Corner Radius','Cutting Edge Angle','Cutting Edge Height']
  328.  
  329. def __init__(self):
  330. self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolLibraryEditor.ui")
  331. self.editform = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolEdit.ui")
  332. self.TLM = ToolLibraryManager()
  333.  
  334. def accept(self):
  335. pass
  336.  
  337. def reject(self):
  338. FreeCADGui.Control.closeDialog()
  339. FreeCAD.ActiveDocument.recompute()
  340.  
  341. def getFields(self):
  342. pass
  343.  
  344. def getType(self, tooltype):
  345. "gets a combobox index number for a given type or viceversa"
  346. toolslist = ["Drill", "CenterDrill", "CounterSink", "CounterBore",
  347. "Reamer", "Tap", "EndMill", "SlotCutter", "BallEndMill",
  348. "ChamferMill", "CornerRound", "Engraver"]
  349. if isinstance(tooltype, str):
  350. if tooltype in toolslist:
  351. return toolslist.index(tooltype) + 1
  352. else:
  353. return 0
  354. else:
  355. if tooltype == 0:
  356. return "Undefined"
  357. else:
  358. return toolslist[tooltype - 1]
  359.  
  360. def getMaterial(self, material):
  361. "gets a combobox index number for a given material or viceversa"
  362. matslist = ["HighSpeedSteel", "HighCarbonToolSteel", "CastAlloy",
  363. "Carbide", "Ceramics", "Diamond", "Sialon"]
  364. if isinstance(material, str):
  365. if material in matslist:
  366. return matslist.index(material) + 1
  367. else:
  368. return 0
  369. else:
  370. if material == 0:
  371. return "Undefined"
  372. else:
  373. return matslist[material - 1]
  374.  
  375. def addTool(self):
  376. t = Path.Tool()
  377. print t
  378. editform = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolEdit.ui")
  379. r = editform.exec_()
  380. if r:
  381. if editform.NameField.text():
  382. t.Name = str(editform.NameField.text())
  383. t.ToolType = self.getType(editform.TypeField.currentIndex())
  384. t.Material = self.getMaterial(editform.MaterialField.currentIndex())
  385. t.Diameter = editform.DiameterField.value()
  386. t.LengthOffset = editform.LengthOffsetField.value()
  387. t.FlatRadius = editform.FlatRadiusField.value()
  388. t.CornerRadius = editform.CornerRadiusField.value()
  389. t.CuttingEdgeAngle = editform.CuttingEdgeAngleField.value()
  390. t.CuttingEdgeHeight = editform.CuttingEdgeHeightField.value()
  391.  
  392. listname = self.form.listWidget.currentItem().text()
  393. if self.TLM.addnew(listname, t) is True:
  394. self.loadTable(self.form.listWidget.currentItem())
  395.  
  396. def setFields(self):
  397. pass
  398.  
  399. def open(self):
  400. pass
  401.  
  402. def buildlist(self):
  403. # pbrush = QtGui.QBrush(QtGui.QColor(142,142,255))
  404. # jbrush = QtGui.QBrush(QtGui.QColor(154,255,152))
  405.  
  406. liblist = self.TLM.getLists()
  407. if len (liblist) > 0:
  408. for i in liblist:
  409. item = QtGui.QListWidgetItem(i["name"])
  410. # if i['listtype'] == "User":
  411. # item.setBackground(pbrush)
  412. # else:
  413. # item.setBackground(jbrush)
  414. self.form.listWidget.addItem(item)
  415.  
  416. def loadTable(self, curr):
  417. tooldata = self.TLM.getTools(curr.text())
  418. self.form.ToolsList.clear()
  419. for i in tooldata: #number, tool in tt.Tools.iteritems():
  420. item = QtGui.QTreeWidgetItem(self.form.ToolsList)
  421. item.setText(0, str(i[0]))
  422. item.setText(1, i[1])
  423.  
  424. def moveUp(self):
  425. "moves a tool to a lower number, if possible"
  426. item = self.form.ToolsList.currentItem()
  427. if item:
  428. number = int(item.text(0))
  429. listname = self.form.listWidget.currentItem().text()
  430. if self.TLM.moveup(number, listname) is True:
  431. self.loadTable(self.form.listWidget.currentItem())
  432.  
  433. def moveDown(self):
  434. "moves a tool to a higher number, if possible"
  435. item = self.form.ToolsList.currentItem()
  436. if item:
  437. number = int(item.text(0))
  438. listname = self.form.listWidget.currentItem().text()
  439. if self.TLM.movedown(number, listname) is True:
  440. self.loadTable(self.form.listWidget.currentItem())
  441.  
  442. def delete(self):
  443. '''deletes a tool'''
  444. item = self.form.ToolsList.currentItem()
  445. if item:
  446. number = int(item.text(0))
  447. listname = self.form.listWidget.currentItem().text()
  448. if self.TLM.delete(number, listname) is True:
  449. self.loadTable(self.form.listWidget.currentItem())
  450.  
  451. def editTool(self, currItem):
  452. listname = self.form.listWidget.currentItem().text()
  453. toolnum = int(currItem.text(0))
  454. tool = self.TLM.getTool(listname, toolnum)
  455. editform = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolEdit.ui")
  456.  
  457. editform.NameField.setText(tool.Name)
  458. editform.TypeField.setCurrentIndex(self.getType(tool.ToolType))
  459. editform.MaterialField.setCurrentIndex(self.getMaterial(tool.Material))
  460. editform.DiameterField.setValue(tool.Diameter)
  461. editform.LengthOffsetField.setValue(tool.LengthOffset)
  462. editform.FlatRadiusField.setValue(tool.FlatRadius)
  463. editform.CornerRadiusField.setValue(tool.CornerRadius)
  464. editform.CuttingEdgeAngleField.setValue(tool.CuttingEdgeAngle)
  465. editform.CuttingEdgeHeightField.setValue(tool.CuttingEdgeHeight)
  466.  
  467. r = editform.exec_()
  468. if r:
  469. if editform.NameField.text():
  470. tool.Name = str(editform.NameField.text())
  471. tool.ToolType = self.getType(editform.TypeField.currentIndex())
  472. tool.Material = self.getMaterial(editform.MaterialField.currentIndex())
  473. tool.Diameter = editform.DiameterField.value()
  474. tool.LengthOffset = editform.LengthOffsetField.value()
  475. tool.FlatRadius = editform.FlatRadiusField.value()
  476. tool.CornerRadius = editform.CornerRadiusField.value()
  477. tool.CuttingEdgeAngle = editform.CuttingEdgeAngleField.value()
  478. tool.CuttingEdgeHeight = editform.CuttingEdgeHeightField.value()
  479.  
  480. if self.TLM.updateTool(listname, toolnum, tool) is True:
  481. self.loadTable(self.form.listWidget.currentItem())
  482. def toolcopy(self, item):
  483. print item
  484.  
  485. def importFile(self):
  486. "imports a tooltable from a file"
  487. filename = QtGui.QFileDialog.getOpenFileName(self.form, _translate(
  488. "TooltableEditor", "Open tooltable", None), None, _translate("TooltableEditor", "Tooltable XML (*.xml);;HeeksCAD tooltable (*.tooltable)", None))
  489. if filename:
  490. self.TLM.read(filename, self.form.listWidget.currentItem().text())
  491.  
  492. def exportFile(self):
  493. "imports a tooltable from a file"
  494. filename = QtGui.QFileDialog.getSaveFileName(self.form, _translate("TooltableEditor", "Save tooltable", None), None, _translate("TooltableEditor", "Tooltable XML (*.xml)", None))
  495.  
  496. if filename:
  497. self.TLM.write(filename, self.form.listWidget.currentItem().text())
  498.  
  499.  
  500. def getStandardButtons(self):
  501. return int(QtGui.QDialogButtonBox.Ok)
  502.  
  503. def setupUi(self):
  504. # Connect Signals and Slots
  505. self.form.ButtonNewTool.clicked.connect(self.addTool)
  506. self.form.listWidget.currentItemChanged.connect(self.loadTable)
  507. self.form.ButtonImport.clicked.connect(self.importFile)
  508. self.form.ButtonExport.clicked.connect(self.exportFile)
  509. self.form.ButtonDown.clicked.connect(self.moveDown)
  510. self.form.ButtonUp.clicked.connect(self.moveUp)
  511. self.form.ButtonDelete.clicked.connect(self.delete)
  512. self.form.ToolsList.itemDoubleClicked.connect(self.editTool)
  513. self.form.listWidget.dropEvent.connect(self.toolcopy)
  514.  
  515. self.buildlist()
  516. self.form.listWidget.setCurrentRow(0)
  517.  
  518. self.setFields()
  519.  
  520. class CommandToolLibraryEdit():
  521. def edit(self):
  522. editor = EditorPanel()
  523. editor.setupUi()
  524.  
  525. r = editor.form.exec_()
  526. if r:
  527. pass
  528.  
  529. def GetResources(self):
  530. return {'Pixmap' : 'Path-ToolTable',
  531. 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_ToolTable","Edit the Tool Library"),
  532. 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_ToolTable","Edit the Tool Library")}
  533.  
  534. def IsActive(self):
  535. return not FreeCAD.ActiveDocument is None
  536.  
  537. def Activated(self):
  538.  
  539. self.edit()
  540.  
  541.  
  542. if FreeCAD.GuiUp:
  543. # register the FreeCAD command
  544. FreeCADGui.addCommand('Path_ToolLibraryEdit',CommandToolLibraryEdit())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement