Added search path and preferences support for tools

This commit is contained in:
Markus Lampert
2019-10-17 22:25:49 -07:00
parent 9178c670c4
commit 3a23ea25bb
7 changed files with 230 additions and 10 deletions

View File

@@ -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}

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View 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'))

View 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')

View File

@@ -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