Added search path and preferences support for tools
This commit is contained in:
@@ -136,6 +136,17 @@ SET(PathScripts_post_SRCS
|
||||
PathScripts/post/smoothie_post.py
|
||||
)
|
||||
|
||||
SET(Tools_Bit_SRCS
|
||||
)
|
||||
|
||||
SET(Tools_Library_SRCS
|
||||
)
|
||||
|
||||
SET(Tools_Template_SRCS
|
||||
Tools/Template/drill-straight.fcstd
|
||||
Tools/Template/endmill-straight.fcstd
|
||||
Tools/Template/v-bit.fcstd
|
||||
)
|
||||
|
||||
SET(PathTests_SRCS
|
||||
PathTests/__init__.py
|
||||
@@ -181,6 +192,9 @@ SET(Path_Images
|
||||
SET(all_files
|
||||
${PathScripts_SRCS}
|
||||
${PathScripts_post_SRCS}
|
||||
${Tools_Bit_SRCS}
|
||||
${Tools_Library_SRCS}
|
||||
${Tools_Template_SRCS}
|
||||
${Path_Images}
|
||||
)
|
||||
|
||||
@@ -221,6 +235,27 @@ INSTALL(
|
||||
Mod/Path/PathScripts/post
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${Tools_Bit_SRCS}
|
||||
DESTINATION
|
||||
Mod/Path/Tools/Bit
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${Tools_Library_SRCS}
|
||||
DESTINATION
|
||||
Mod/Path/Tools/Library
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${Tools_Template_SRCS}
|
||||
DESTINATION
|
||||
Mod/Path/Tools/Template
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${PathImages_Ops}
|
||||
|
||||
@@ -38,7 +38,7 @@ class PostProcessor:
|
||||
def load(cls, processor):
|
||||
PathLog.track(processor)
|
||||
syspath = sys.path
|
||||
paths = PathPreferences.searchPaths()
|
||||
paths = PathPreferences.searchPathsPost()
|
||||
paths.extend(sys.path)
|
||||
sys.path = paths
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ PostProcessorBlacklist = "PostProcessorBlacklist"
|
||||
PostProcessorOutputFile = "PostProcessorOutputFile"
|
||||
PostProcessorOutputPolicy = "PostProcessorOutputPolicy"
|
||||
|
||||
LastPathToolBit = "LastPathToolBit"
|
||||
LastPathToolLibrary = "LastPathToolLibrary"
|
||||
LastPathToolTemplate = "LastPathToolTemplate"
|
||||
|
||||
# Linear tolerance to use when generating Paths, eg when tessellating geometry
|
||||
GeometryTolerance = "GeometryTolerance"
|
||||
LibAreaCurveAccuracy = "LibAreaCurveAccuarcy"
|
||||
@@ -52,14 +56,16 @@ def preferences():
|
||||
return FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
|
||||
def pathScriptsSourcePath():
|
||||
return FreeCAD.getHomePath() + ("Mod/Path/PathScripts/")
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/PathScripts/")
|
||||
|
||||
def pathScriptsPostSourcePath():
|
||||
return pathScriptsSourcePath() + ("/post/")
|
||||
def pathDefaultToolsPath(sub=None):
|
||||
if sub:
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/Tools/", sub)
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/Tools/")
|
||||
|
||||
def allAvailablePostProcessors():
|
||||
allposts = []
|
||||
for path in searchPaths():
|
||||
for path in searchPathsPost():
|
||||
posts = [ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in glob.glob(path + '/*_post.py')]
|
||||
allposts.extend(posts)
|
||||
allposts.sort()
|
||||
@@ -108,10 +114,38 @@ def searchPaths():
|
||||
if p:
|
||||
paths.append(p)
|
||||
paths.append(macroFilePath())
|
||||
paths.append(pathScriptsPostSourcePath())
|
||||
return paths
|
||||
|
||||
def searchPathsPost():
|
||||
paths = []
|
||||
p = defaultFilePath()
|
||||
if p:
|
||||
paths.append(p)
|
||||
paths.append(macroFilePath())
|
||||
paths.append(os.path.join(pathScriptsSourcePath(), "post/"))
|
||||
paths.append(pathScriptsSourcePath())
|
||||
return paths
|
||||
|
||||
def searchPathsTool(sub='Bit'):
|
||||
paths = []
|
||||
|
||||
if 'Bit' == sub:
|
||||
paths.append(lastPathToolBit())
|
||||
if 'Library' == sub:
|
||||
paths.append(lastPathToolLibrary())
|
||||
if 'Template' == sub:
|
||||
paths.append(lastPathToolTemplate())
|
||||
|
||||
def appendPath(p, sub):
|
||||
if p:
|
||||
paths.append(os.path.join(p, 'Tools', sub))
|
||||
paths.append(os.path.join(p, sub))
|
||||
paths.append(p)
|
||||
appendPath(defaultFilePath(), sub)
|
||||
appendPath(macroFilePath(), sub)
|
||||
appendPath(os.path.join(FreeCAD.getHomePath(), "Mod/Path/"), sub)
|
||||
return paths
|
||||
|
||||
def defaultJobTemplate():
|
||||
template = preferences().GetString(DefaultJobTemplate)
|
||||
if 'xml' not in template:
|
||||
@@ -165,3 +199,19 @@ def setDefaultTaskPanelLayout(style):
|
||||
|
||||
def experimentalFeaturesEnabled():
|
||||
return preferences().GetBool(EnableExperimentalFeatures, False)
|
||||
|
||||
def lastPathToolBit():
|
||||
return preferences().GetString(LastPathToolBit, pathDefaultToolsPath('Bit'))
|
||||
def setLastPathToolBit(path):
|
||||
return preferences().SetString(LastPathToolBit, path)
|
||||
|
||||
def lastPathToolLibrary():
|
||||
return preferences().GetString(LastPathToolLibrary, pathDefaultToolsPath('Library'))
|
||||
def setLastPathToolLibrary(path):
|
||||
return preferences().SetString(LastPathToolLibrary, path)
|
||||
|
||||
def lastPathToolTemplate():
|
||||
return preferences().GetString(LastPathToolTemplate, pathDefaultToolsPath('Template'))
|
||||
def setLastPathToolTemplate(path):
|
||||
return preferences().SetString(LastPathToolTemplate, path)
|
||||
|
||||
|
||||
@@ -26,12 +26,14 @@ import FreeCAD
|
||||
import Part
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathPreferences as PathPreferences
|
||||
import PathScripts.PathSetupSheetOpPrototype as PathSetupSheetOpPrototype
|
||||
import PathScripts.PathUtil as PathUtil
|
||||
import PySide
|
||||
import Sketcher
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import zipfile
|
||||
|
||||
__title__ = "Tool bits."
|
||||
@@ -54,6 +56,28 @@ ParameterTypeConstraint = {
|
||||
}
|
||||
|
||||
|
||||
def _findTool(path, typ):
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
|
||||
def searchFor(pname, fname):
|
||||
if fname:
|
||||
for p in PathPreferences.searchPathsTool(typ):
|
||||
f = os.path.join(p, fname)
|
||||
if os.path.exists(f):
|
||||
return f
|
||||
if pname and '/' != pname:
|
||||
ppname, pfname = os.path.split(pname)
|
||||
ffname = os.path.join(pfname, fname) if fname else pfname
|
||||
return searchFor(ppname, ffname)
|
||||
return None
|
||||
|
||||
return searchFor(path, '')
|
||||
|
||||
def findTemplate(path):
|
||||
'''findTemplate(path) ... search for path, full and partially in all known template directories.'''
|
||||
return _findTool(path, 'Template')
|
||||
|
||||
def updateConstraint(sketch, name, value):
|
||||
for i, constraint in enumerate(sketch.Constraints):
|
||||
if constraint.Name.split(';')[0] == name:
|
||||
@@ -136,16 +160,18 @@ class ToolBit(object):
|
||||
obj.Shape = Part.Shape()
|
||||
|
||||
def _loadBitBody(self, obj, path=None):
|
||||
if not path:
|
||||
path = obj.BitTemplate
|
||||
p = path if path else obj.BitTemplate
|
||||
docOpened = False
|
||||
doc = None
|
||||
for d in FreeCAD.listDocuments():
|
||||
if FreeCAD.getDocument(d).FileName == path:
|
||||
if FreeCAD.getDocument(d).FileName == p:
|
||||
doc = FreeCAD.getDocument(d)
|
||||
break
|
||||
if doc is None:
|
||||
doc = FreeCAD.open(path)
|
||||
p = findTemplate(p)
|
||||
if not path and p != obj.BitTemplate:
|
||||
obj.BitTemplate = p
|
||||
doc = FreeCAD.open(p)
|
||||
docOpened = True
|
||||
return (doc, docOpened)
|
||||
|
||||
|
||||
60
src/Mod/Path/PathTests/TestPathPreferences.py
Normal file
60
src/Mod/Path/PathTests/TestPathPreferences.py
Normal file
@@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2019 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import PathScripts.PathPreferences as PathPreferences
|
||||
import PathTests.PathTestUtils as PathTestUtils
|
||||
|
||||
class TestPathPreferences(PathTestUtils.PathTestBase):
|
||||
|
||||
def test00(self):
|
||||
'''There is at least one search path.'''
|
||||
|
||||
paths = PathPreferences.searchPaths()
|
||||
self.assertGreater(len(paths), 0)
|
||||
|
||||
def test01(self):
|
||||
'''PathScripts is part of the posts search path.'''
|
||||
paths = PathPreferences.searchPathsPost()
|
||||
self.assertEqual(len([p for p in paths if p.endswith('/PathScripts/')]), 1)
|
||||
|
||||
def test02(self):
|
||||
'''PathScripts/post is part of the posts search path.'''
|
||||
paths = PathPreferences.searchPathsPost()
|
||||
self.assertEqual(len([p for p in paths if p.endswith('/PathScripts/post/')]), 1)
|
||||
|
||||
def test03(self):
|
||||
'''Available post processors include linuxcnc, grbl and opensbp.'''
|
||||
posts = PathPreferences.allAvailablePostProcessors()
|
||||
self.assertTrue('linuxcnc' in posts)
|
||||
self.assertTrue('grbl' in posts)
|
||||
self.assertTrue('opensbp' in posts)
|
||||
|
||||
|
||||
def test10(self):
|
||||
'''Default paths for tools are resolved correctly'''
|
||||
|
||||
self.assertTrue(PathPreferences.pathDefaultToolsPath().endswith('/Path/Tools/'))
|
||||
self.assertTrue(PathPreferences.pathDefaultToolsPath('Bit').endswith('/Path/Tools/Bit'))
|
||||
self.assertTrue(PathPreferences.pathDefaultToolsPath('Library').endswith('/Path/Tools/Library'))
|
||||
self.assertTrue(PathPreferences.pathDefaultToolsPath('Template').endswith('/Path/Tools/Template'))
|
||||
45
src/Mod/Path/PathTests/TestPathToolBit.py
Normal file
45
src/Mod/Path/PathTests/TestPathToolBit.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2019 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import PathScripts.PathToolBit as PathToolBit
|
||||
import PathTests.PathTestUtils as PathTestUtils
|
||||
|
||||
|
||||
class TestPathToolBit(PathTestUtils.PathTestBase):
|
||||
|
||||
def test00(self):
|
||||
'''Find a tool template from file name'''
|
||||
|
||||
path = PathToolBit.findTemplate('endmill-straight.fcstd')
|
||||
self.assertIsNot(path, None)
|
||||
self.assertNotEqual(path, 'endmill-straight.fcstd')
|
||||
|
||||
def test01(self):
|
||||
'''Find a tool template from an invalid absolute path.'''
|
||||
|
||||
path = PathToolBit.findTemplate('/this/is/unlikely/a/valid/path/v-bit.fcstd')
|
||||
self.assertIsNot(path, None)
|
||||
self.assertNotEqual(path, '/this/is/unlikely/a/valid/path/v-bit.fcstd')
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
import TestApp
|
||||
|
||||
from PathTests.TestPathLog import TestPathLog
|
||||
from PathTests.TestPathPreferences import TestPathPreferences
|
||||
from PathTests.TestPathCore import TestPathCore
|
||||
#from PathTests.TestPathPost import PathPostTestCases
|
||||
from PathTests.TestPathGeom import TestPathGeom
|
||||
@@ -35,6 +36,7 @@ from PathTests.TestPathDressupHoldingTags import TestHoldingTags
|
||||
from PathTests.TestPathDressupDogbone import TestDressupDogbone
|
||||
from PathTests.TestPathStock import TestPathStock
|
||||
from PathTests.TestPathTool import TestPathTool
|
||||
from PathTests.TestPathToolBit import TestPathToolBit
|
||||
from PathTests.TestPathTooltable import TestPathTooltable
|
||||
from PathTests.TestPathToolController import TestPathToolController
|
||||
from PathTests.TestPathSetupSheet import TestPathSetupSheet
|
||||
@@ -58,4 +60,6 @@ False if TestPathToolController.__name__ else True
|
||||
False if TestPathSetupSheet.__name__ else True
|
||||
False if TestPathDeburr.__name__ else True
|
||||
False if TestPathHelix.__name__ else True
|
||||
False if TestPathPreferences.__name__ else True
|
||||
False if TestPathToolBit.__name__ else True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user