Removed deprecated and obsolete Path.Tool and Path.Tooltable

This commit is contained in:
Markus Lampert
2022-08-12 23:34:05 -07:00
parent 9b7e50ba07
commit 29255f0ffd
42 changed files with 93 additions and 4011 deletions

View File

@@ -30,14 +30,8 @@
#include "CommandPy.h"
#include "Path.h"
#include "PathPy.h"
#include "Tool.h"
#include "Tooltable.h"
#include "ToolPy.h"
#include "TooltablePy.h"
#include "PropertyPath.h"
#include "FeaturePath.h"
#include "PropertyTool.h"
#include "PropertyTooltable.h"
#include "FeaturePathCompound.h"
#include "FeaturePathShape.h"
#include "AreaPy.h"
@@ -76,8 +70,6 @@ PyMOD_INIT_FUNC(PathApp)
// Add Types to module
Base::Interpreter().addType(&Path::CommandPy ::Type, pathModule, "Command");
Base::Interpreter().addType(&Path::PathPy ::Type, pathModule, "Path");
Base::Interpreter().addType(&Path::ToolPy ::Type, pathModule, "Tool");
Base::Interpreter().addType(&Path::TooltablePy ::Type, pathModule, "Tooltable");
Base::Interpreter().addType(&Path::AreaPy ::Type, pathModule, "Area");
PyObject* voronoiModule(module.getAttr("Voronoi").ptr());
@@ -91,13 +83,9 @@ PyMOD_INIT_FUNC(PathApp)
// This function is responsible for adding inherited slots from a type's base class.
Path::Command ::init();
Path::Toolpath ::init();
Path::Tool ::init();
Path::Tooltable ::init();
Path::PropertyPath ::init();
Path::Feature ::init();
Path::FeaturePython ::init();
Path::PropertyTool ::init();
Path::PropertyTooltable ::init();
Path::FeatureCompound ::init();
Path::FeatureCompoundPython ::init();
Path::FeatureShape ::init();

View File

@@ -31,8 +31,6 @@ set(Path_LIBS
generate_from_xml(CommandPy)
generate_from_xml(PathPy)
generate_from_xml(ToolPy)
generate_from_xml(TooltablePy)
generate_from_xml(FeaturePathCompoundPy)
generate_from_xml(AreaPy)
generate_from_xml(FeatureAreaPy)
@@ -46,10 +44,6 @@ SET(Python_SRCS
CommandPyImp.cpp
PathPy.xml
PathPyImp.cpp
ToolPy.xml
ToolPyImp.cpp
TooltablePy.xml
TooltablePyImp.cpp
FeaturePathCompoundPy.xml
FeaturePathCompoundPyImp.cpp
AreaPy.xml
@@ -78,18 +72,10 @@ SET(Path_SRCS
Command.h
Path.cpp
Path.h
Tool.cpp
Tool.h
Tooltable.cpp
Tooltable.h
PropertyPath.cpp
PropertyPath.h
FeaturePath.cpp
FeaturePath.h
PropertyTool.cpp
PropertyTool.h
PropertyTooltable.cpp
PropertyTooltable.h
FeaturePathCompound.cpp
FeaturePathCompound.h
FeaturePathShape.cpp

View File

@@ -1,116 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
#endif
#include <Base/Console.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include <Base/FileInfo.h>
#include <Base/Stream.h>
#include "PropertyTool.h"
#include "ToolPy.h"
using namespace Path;
TYPESYSTEM_SOURCE(Path::PropertyTool, App::Property)
PropertyTool::PropertyTool()
{
}
PropertyTool::~PropertyTool()
{
}
void PropertyTool::setValue(const Tool& tt)
{
aboutToSetValue();
_Tool = tt;
hasSetValue();
}
const Tool &PropertyTool::getValue()const
{
return _Tool;
}
PyObject *PropertyTool::getPyObject()
{
return new ToolPy(new Tool(_Tool));
}
void PropertyTool::setPyObject(PyObject *value)
{
if (PyObject_TypeCheck(value, &(ToolPy::Type))) {
ToolPy *pcObject = static_cast<ToolPy*>(value);
setValue(*pcObject->getToolPtr());
}
else {
std::string error = std::string("type must be 'Tool', not ");
error += value->ob_type->tp_name;
throw Base::TypeError(error);
}
}
App::Property *PropertyTool::Copy() const
{
PropertyTool *prop = new PropertyTool();
prop->_Tool = this->_Tool;
return prop;
}
void PropertyTool::Paste(const App::Property &from)
{
aboutToSetValue();
_Tool = dynamic_cast<const PropertyTool&>(from)._Tool;
hasSetValue();
}
unsigned int PropertyTool::getMemSize () const
{
return _Tool.getMemSize();
}
void PropertyTool::Save (Base::Writer &writer) const
{
_Tool.Save(writer);
}
void PropertyTool::Restore(Base::XMLReader &reader)
{
Path::Tool temp;
temp.Restore(reader);
setValue(temp);
}

View File

@@ -1,75 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PROPERTYTOOL_H
#define PROPERTYTOOL_H
#include "Tool.h"
#include <App/Property.h>
namespace Path
{
/** The tool property class. */
class PathExport PropertyTool : public App::Property
{
TYPESYSTEM_HEADER();
public:
PropertyTool();
~PropertyTool();
/** @name Getter/setter */
//@{
/// set the part shape
void setValue(const Tool&);
/// get the part shape
const Tool &getValue(void) const;
//@}
/** @name Python interface */
//@{
PyObject* getPyObject(void);
void setPyObject(PyObject *value);
//@}
/** @name Save/restore */
//@{
void Save (Base::Writer &writer) const;
void Restore(Base::XMLReader &reader);
App::Property *Copy(void) const;
void Paste(const App::Property &from);
unsigned int getMemSize (void) const;
//@}
private:
Tool _Tool;
};
} //namespace Path
#endif // PROPERTYTOOL_H

View File

@@ -1,116 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
#endif
#include <Base/Console.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include <Base/FileInfo.h>
#include <Base/Stream.h>
#include "PropertyTooltable.h"
#include "TooltablePy.h"
using namespace Path;
TYPESYSTEM_SOURCE(Path::PropertyTooltable, App::Property)
PropertyTooltable::PropertyTooltable()
{
}
PropertyTooltable::~PropertyTooltable()
{
}
void PropertyTooltable::setValue(const Tooltable& tt)
{
aboutToSetValue();
_Tooltable = tt;
hasSetValue();
}
const Tooltable &PropertyTooltable::getValue()const
{
return _Tooltable;
}
PyObject *PropertyTooltable::getPyObject()
{
return new TooltablePy(new Tooltable(_Tooltable));
}
void PropertyTooltable::setPyObject(PyObject *value)
{
if (PyObject_TypeCheck(value, &(TooltablePy::Type))) {
TooltablePy *pcObject = static_cast<TooltablePy*>(value);
setValue(*pcObject->getTooltablePtr());
}
else {
std::string error = std::string("type must be 'Tooltable', not ");
error += value->ob_type->tp_name;
throw Base::TypeError(error);
}
}
App::Property *PropertyTooltable::Copy() const
{
PropertyTooltable *prop = new PropertyTooltable();
prop->_Tooltable = this->_Tooltable;
return prop;
}
void PropertyTooltable::Paste(const App::Property &from)
{
aboutToSetValue();
_Tooltable = dynamic_cast<const PropertyTooltable&>(from)._Tooltable;
hasSetValue();
}
unsigned int PropertyTooltable::getMemSize () const
{
return _Tooltable.getMemSize();
}
void PropertyTooltable::Save (Base::Writer &writer) const
{
_Tooltable.Save(writer);
}
void PropertyTooltable::Restore(Base::XMLReader &reader)
{
Path::Tooltable temp;
temp.Restore(reader);
setValue(temp);
}

View File

@@ -1,75 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PROPERTYTOOLTABLE_H
#define PROPERTYTOOLTABLE_H
#include "Tooltable.h"
#include <App/Property.h>
namespace Path
{
/** The tooltable property class. */
class PathExport PropertyTooltable : public App::Property
{
TYPESYSTEM_HEADER();
public:
PropertyTooltable();
~PropertyTooltable();
/** @name Getter/setter */
//@{
/// set the part shape
void setValue(const Tooltable&);
/// get the part shape
const Tooltable &getValue(void) const;
//@}
/** @name Python interface */
//@{
PyObject* getPyObject(void);
void setPyObject(PyObject *value);
//@}
/** @name Save/restore */
//@{
void Save (Base::Writer &writer) const;
void Restore(Base::XMLReader &reader);
App::Property *Copy(void) const;
void Paste(const App::Property &from);
unsigned int getMemSize (void) const;
//@}
private:
Tooltable _Tooltable;
};
} //namespace Path
#endif // PROPERTYTOOLTABLE_H

View File

@@ -1,258 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include "Tool.h"
using namespace Base;
using namespace Path;
TYPESYSTEM_SOURCE(Path::Tool , Base::Persistence)
// Constructors & destructors
Tool::Tool(const char* name,
ToolType type,
ToolMaterial /*material*/,
double diameter,
double lengthoffset,
double flatradius,
double cornerradius,
double cuttingedgeangle,
double cuttingedgeheight)
:Name(name),Type(type),Material(MATUNDEFINED),Diameter(diameter),LengthOffset(lengthoffset),
FlatRadius(flatradius),CornerRadius(cornerradius),CuttingEdgeAngle(cuttingedgeangle),
CuttingEdgeHeight(cuttingedgeheight)
{
}
Tool::Tool()
{
Type = UNDEFINED;
Material = MATUNDEFINED;
Diameter = 0;
LengthOffset = 0;
FlatRadius = 0;
CornerRadius = 0;
CuttingEdgeAngle = 180;
CuttingEdgeHeight = 0;
}
Tool::~Tool()
{
}
// Reimplemented from base class
unsigned int Tool::getMemSize () const
{
return 0;
}
void Tool::Save (Writer &writer) const
{
writer.Stream() << writer.ind() << "<Tool "
<< "name=\"" << encodeAttribute(Name) << "\" "
<< "diameter=\"" << Diameter << "\" "
<< "length=\"" << LengthOffset << "\" "
<< "flat=\"" << FlatRadius << "\" "
<< "corner=\"" << CornerRadius << "\" "
<< "angle=\"" << CuttingEdgeAngle << "\" "
<< "height=\"" << CuttingEdgeHeight << "\" "
<< "type=\"" << TypeName(Type) << "\" "
<< "mat=\"" << MaterialName(Material) << "\" "
<< "/>" << std::endl;
}
void Tool::Restore(XMLReader &reader)
{
reader.readElement("Tool");
Name = reader.getAttribute("name");
Diameter = reader.hasAttribute("diameter") ? (double) reader.getAttributeAsFloat("diameter") : 0.0;
LengthOffset = reader.hasAttribute("length") ? (double) reader.getAttributeAsFloat("length") : 0.0;
FlatRadius = reader.hasAttribute("flat") ? (double) reader.getAttributeAsFloat("flat") : 0.0;
CornerRadius = reader.hasAttribute("corner") ? (double) reader.getAttributeAsFloat("corner") : 0.0;
CuttingEdgeAngle = reader.hasAttribute("angle") ? (double) reader.getAttributeAsFloat("angle") : 180.0;
CuttingEdgeHeight = reader.hasAttribute("height") ? (double) reader.getAttributeAsFloat("height") : 0.0;
std::string type = reader.hasAttribute("type") ? reader.getAttribute("type") : "";
std::string mat = reader.hasAttribute("mat") ? reader.getAttribute("mat") : "";
Type = getToolType(type);
Material = getToolMaterial(mat);
}
const std::vector<std::string> Tool::ToolTypes()
{
std::vector<std::string> toolTypes(13);
toolTypes[0] ="EndMill";
toolTypes[1] ="Drill";
toolTypes[2] ="CenterDrill";
toolTypes[3] ="CounterSink";
toolTypes[4] ="CounterBore";
toolTypes[5] ="FlyCutter";
toolTypes[6] ="Reamer";
toolTypes[7] ="Tap";
toolTypes[8] ="SlotCutter";
toolTypes[9] ="BallEndMill";
toolTypes[10] ="ChamferMill";
toolTypes[11] ="CornerRound";
toolTypes[12] ="Engraver";
return toolTypes;
}
const std::vector<std::string> Tool::ToolMaterials()
{
std::vector<std::string> toolMat(7);
toolMat[0] ="Carbide";
toolMat[1] ="HighSpeedSteel";
toolMat[2] ="HighCarbonToolSteel";
toolMat[3] ="CastAlloy";
toolMat[4] ="Ceramics";
toolMat[5] ="Diamond";
toolMat[6] ="Sialon";
return toolMat;
}
Tool::ToolType Tool::getToolType(std::string type)
{
Tool::ToolType Type;
if(type=="EndMill")
Type = Tool::ENDMILL;
else if(type=="Drill")
Type = Tool::DRILL;
else if(type=="CenterDrill")
Type = Tool::CENTERDRILL;
else if(type=="CounterSink")
Type = Tool::COUNTERSINK;
else if(type=="CounterBore")
Type = Tool::COUNTERBORE;
else if(type=="FlyCutter")
Type = Tool::FLYCUTTER;
else if(type=="Reamer")
Type = Tool::REAMER;
else if(type=="Tap")
Type = Tool::TAP;
else if(type=="SlotCutter")
Type = Tool::SLOTCUTTER;
else if(type=="BallEndMill")
Type = Tool::BALLENDMILL;
else if(type=="ChamferMill")
Type = Tool::CHAMFERMILL;
else if(type=="CornerRound")
Type = Tool::CORNERROUND;
else if(type=="Engraver")
Type = Tool::ENGRAVER;
else
Type = Tool::UNDEFINED;
return Type;
}
Tool::ToolMaterial Tool::getToolMaterial(std::string mat)
{
Tool::ToolMaterial Material;
if(mat=="Carbide")
Material = Tool::CARBIDE;
else if(mat=="HighSpeedSteel")
Material = Tool::HIGHSPEEDSTEEL;
else if(mat=="HighCarbonToolSteel")
Material = Tool::HIGHCARBONTOOLSTEEL;
else if(mat=="CastAlloy")
Material = Tool::CASTALLOY;
else if(mat=="Ceramics")
Material = Tool::CERAMICS;
else if(mat=="Diamond")
Material = Tool::DIAMOND;
else if(mat=="Sialon")
Material = Tool::SIALON;
else
Material = Tool::MATUNDEFINED;
return Material;
}
const char* Tool::TypeName(Tool::ToolType typ) {
switch (typ) {
case Tool::DRILL:
return "Drill";
case Tool::CENTERDRILL:
return "CenterDrill";
case Tool::COUNTERSINK:
return "CounterSink";
case Tool::COUNTERBORE:
return "CounterBore";
case Tool::FLYCUTTER:
return "FlyCutter";
case Tool::REAMER:
return "Reamer";
case Tool::TAP:
return "Tap";
case Tool::ENDMILL:
return "EndMill";
case Tool::SLOTCUTTER:
return "SlotCutter";
case Tool::BALLENDMILL:
return "BallEndMill";
case Tool::CHAMFERMILL:
return "ChamferMill";
case Tool::CORNERROUND:
return "CornerRound";
case Tool::ENGRAVER:
return "Engraver";
case Tool::UNDEFINED:
return "Undefined";
}
return "Undefined";
}
const char* Tool::MaterialName(Tool::ToolMaterial mat)
{
switch (mat) {
case Tool::HIGHSPEEDSTEEL:
return "HighSpeedSteel";
case Tool::CARBIDE:
return "Carbide";
case Tool::HIGHCARBONTOOLSTEEL:
return "HighCarbonToolSteel";
case Tool::CASTALLOY:
return "CastAlloy";
case Tool::CERAMICS:
return "Ceramics";
case Tool::DIAMOND:
return "Diamond";
case Tool::SIALON:
return "Sialon";
case Tool::MATUNDEFINED:
return "Undefined";
}
return "Undefined";
}

View File

@@ -1,107 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PATH_TOOL_H
#define PATH_TOOL_H
#include <memory>
#include <vector>
#include <string>
#include <map>
#include <Base/Persistence.h>
namespace Path
{
/** The representation of a single tool */
class PathExport Tool : public Base::Persistence
{
TYPESYSTEM_HEADER();
public:
enum ToolType {
UNDEFINED,
DRILL,
CENTERDRILL,
COUNTERSINK,
COUNTERBORE,
FLYCUTTER,
REAMER,
TAP,
ENDMILL,
SLOTCUTTER,
BALLENDMILL,
CHAMFERMILL,
CORNERROUND,
ENGRAVER };
enum ToolMaterial {
MATUNDEFINED,
HIGHSPEEDSTEEL,
HIGHCARBONTOOLSTEEL,
CASTALLOY,
CARBIDE,
CERAMICS,
DIAMOND,
SIALON };
//constructors
Tool();
Tool(const char* name,
ToolType type=Tool::UNDEFINED,
ToolMaterial material=Tool::MATUNDEFINED,
double diameter=10.0,
double lengthoffset=100,
double flatradius=0,
double cornerradius=0,
double cuttingedgeangle=0,
double cuttingedgeheight=0);
~Tool();
// from base class
virtual unsigned int getMemSize (void) const;
virtual void Save (Base::Writer &/*writer*/) const;
virtual void Restore(Base::XMLReader &/*reader*/);
// attributes
std::string Name;
ToolType Type;
ToolMaterial Material;
double Diameter;
double LengthOffset;
double FlatRadius;
double CornerRadius;
double CuttingEdgeAngle;
double CuttingEdgeHeight;
static const std::vector<std::string> ToolTypes(void);
static const std::vector<std::string> ToolMaterials(void);
static const char* TypeName(ToolType typ);
static ToolType getToolType(std::string type);
static ToolMaterial getToolMaterial(std::string mat);
static const char* MaterialName(ToolMaterial mat);
};
using ToolPtr = std::shared_ptr<Tool>;
} //namespace Path
#endif // PATH_TOOL_H

View File

@@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="PersistencePy"
Name="ToolPy"
Twin="Tool"
TwinPointer="Tool"
Include="Mod/Path/App/Tool.h"
Namespace="Path"
FatherInclude="Base/PersistencePy.h"
FatherNamespace="Base"
Constructor="true"
Delete="true">
<Documentation>
<Author Licence="LGPL" Name="Yorik van Havre" EMail="yorik@uncreated.net" />
<UserDocu>The Tool objects holds the properties of a CNC tool.
optional attributes:
name: a user-defined name for this tool
tooltype: Drill, CenterDrill, CounterSink, CounterBore, Reamer, Tap, EndMill, SlotCutter, BallEndMill, ChamferMill, CornerRound, Engraver or Undefined
material: HighSpeedSteel, HighCarbonToolSteel, Carbide, CastAlloy, Ceramics, Diamond, Sialon or Undefined
diameter : the diameter of this tool
lengthOffset
flatRadius
cornerRadius
cuttingEdgeAngle
cuttingEdgeHeight</UserDocu>
</Documentation>
<Attribute Name="Name" ReadOnly="false">
<Documentation>
<UserDocu>the name of this tool in mm</UserDocu>
</Documentation>
<Parameter Name="Name" Type="String"/>
</Attribute>
<Attribute Name="ToolType" ReadOnly="false">
<Documentation>
<UserDocu>the type of this tool: Drill, CenterDrill, CounterSink, CounterBore, Reamer, Tap,
EndMill, SlotCutter, BallEndMill, ChamferMill, CornerRound, Engraver or Undefined</UserDocu>
</Documentation>
<Parameter Name="ToolType" Type="String"/>
</Attribute>
<Attribute Name="Material" ReadOnly="false">
<Documentation>
<UserDocu>the material of this tool: Steel, Carbide, HighSpeedSteel,
HighCarbonToolSteel CastAlloy, Ceramics, Diamond, Sialon or Undefined</UserDocu>
</Documentation>
<Parameter Name="Material" Type="String"/>
</Attribute>
<Attribute Name="Diameter" ReadOnly="false">
<Documentation>
<UserDocu>the diameter of this tool in mm</UserDocu>
</Documentation>
<Parameter Name="Diameter" Type="Float"/>
</Attribute>
<Attribute Name="LengthOffset" ReadOnly="false">
<Documentation>
<UserDocu>the length offset of this tool in mm</UserDocu>
</Documentation>
<Parameter Name="LengthOffset" Type="Float"/>
</Attribute>
<Attribute Name="FlatRadius" ReadOnly="false">
<Documentation>
<UserDocu>the flat radius of this tool in mm</UserDocu>
</Documentation>
<Parameter Name="FlatRadius" Type="Float"/>
</Attribute>
<Attribute Name="CornerRadius" ReadOnly="false">
<Documentation>
<UserDocu>the corner radius of this tool in mm</UserDocu>
</Documentation>
<Parameter Name="CornerRadius" Type="Float"/>
</Attribute>
<Attribute Name="CuttingEdgeAngle" ReadOnly="false">
<Documentation>
<UserDocu>the cutting edge angle of this tool</UserDocu>
</Documentation>
<Parameter Name="CuttingEdgeAngle" Type="Float"/>
</Attribute>
<Attribute Name="CuttingEdgeHeight" ReadOnly="false">
<Documentation>
<UserDocu>the cutting edge height of this tool in mm</UserDocu>
</Documentation>
<Parameter Name="CuttingEdgeHeight" Type="Float"/>
</Attribute>
<Methode Name="copy">
<Documentation>
<UserDocu>returns a copy of this tool</UserDocu>
</Documentation>
</Methode>
<Methode Name="getToolTypes">
<Documentation>
<UserDocu>returns all available tool types</UserDocu>
</Documentation>
</Methode>
<Methode Name="getToolMaterials">
<Documentation>
<UserDocu>returns all available tool materials</UserDocu>
</Documentation>
</Methode>
<Methode Name="setFromTemplate">
<Documentation>
<UserDocu>setFromTemplate(xmlString|dictionary) ... fills receiver with values from the template string or dictionary</UserDocu>
</Documentation>
</Methode>
<Methode Name="templateAttrs" Const="true">
<Documentation>
<UserDocu>templateAttrs() ... returns a dictionary with all attributes</UserDocu>
</Documentation>
</Methode>
<!--<ClassDeclarations>
bool touched;
</ClassDeclarations>-->
</PythonExport>
</GenerateModel>

View File

@@ -1,295 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#include "Base/Reader.h"
#include "Mod/Path/App/Tool.h"
#include "Mod/Path/App/Tooltable.h"
// inclusion of the generated files (generated out of ToolPy.xml and TooltablePy.xml)
#include "ToolPy.h"
#include "ToolPy.cpp"
using namespace Path;
#define PYSTRING_FROMSTRING(str) PyUnicode_FromString(str)
#define PYINT_TYPE PyLong_Type
#define PYINT_FROMLONG(l) PyLong_FromLong(l)
#define PYINT_ASLONG(o) PyLong_AsLong(o)
// returns a string which represents the object e.g. when printed in python
std::string ToolPy::representation() const
{
std::stringstream str;
str.precision(5);
str << "Tool ";
str << getToolPtr()->Name;
return str.str();
}
PyObject *ToolPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
{
// create a new instance of ToolPy and the Twin object
return new ToolPy(new Tool);
}
// constructor method
int ToolPy::PyInit(PyObject* args, PyObject* kwd)
{
char *name="Default tool";
char *type = "Undefined";
char *mat = "Undefined";
PyObject *dia = nullptr;
PyObject *len = nullptr;
PyObject *fla = nullptr;
PyObject *cor = nullptr;
PyObject *ang = nullptr;
PyObject *hei = nullptr;
int version = 1;
static char *kwlist[] = {"name", "tooltype", "material", "diameter", "lengthOffset", "flatRadius", "cornerRadius", "cuttingEdgeAngle", "cuttingEdgeHeight" , "version", nullptr};
PyObject *dict = nullptr;
if (!kwd && (PyObject_TypeCheck(args, &PyDict_Type) || PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))) {
static PyObject *arg = PyTuple_New(0);
if (PyObject_TypeCheck(args, &PyDict_Type)) {
dict = args;
}
if (!PyArg_ParseTupleAndKeywords(arg, dict, "|sssOOOOOOi", kwlist, &name, &type, &mat, &dia, &len, &fla, &cor, &ang, &hei, &version)) {
return -1;
}
} else {
PyErr_Clear();
if (!PyArg_ParseTupleAndKeywords(args, kwd, "|sssOOOOOO", kwlist, &name, &type, &mat, &dia, &len, &fla, &cor, &ang, &hei)) {
return -1;
}
}
if (1 != version) {
PyErr_SetString(PyExc_TypeError, "Unsupported Tool template version");
return -1;
}
getToolPtr()->Name = name;
std::string typeStr(type);
getToolPtr()->Type = Tool::getToolType(typeStr);
std::string matStr(mat);
getToolPtr()->Material = Tool::getToolMaterial(matStr);
getToolPtr()->Diameter = dia ? PyFloat_AsDouble(dia) : 0.0;
getToolPtr()->LengthOffset = len ? PyFloat_AsDouble(len) : 0.0;
getToolPtr()->FlatRadius = fla ? PyFloat_AsDouble(fla) : 0.0;
getToolPtr()->CornerRadius = cor ? PyFloat_AsDouble(cor) : 0.0;
getToolPtr()->CuttingEdgeAngle = ang ? PyFloat_AsDouble(ang) : 180.0;
getToolPtr()->CuttingEdgeHeight = hei ? PyFloat_AsDouble(hei) : 0.0;
return 0;
}
// attributes get/setters
Py::String ToolPy::getName() const
{
return Py::String(getToolPtr()->Name.c_str());
}
void ToolPy::setName(Py::String arg)
{
std::string name = arg.as_std_string();
getToolPtr()->Name = name;
}
Py::String ToolPy::getToolType() const
{
return Py::String(Tool::TypeName(getToolPtr()->Type));
}
void ToolPy::setToolType(Py::String arg)
{
std::string typeStr(arg.as_std_string());
getToolPtr()->Type = Tool::getToolType(typeStr);
}
Py::String ToolPy::getMaterial() const
{
return Py::String(Tool::MaterialName(getToolPtr()->Material));
}
void ToolPy::setMaterial(Py::String arg)
{
std::string matStr(arg.as_std_string());
getToolPtr()->Material = Tool::getToolMaterial(matStr);
}
Py::Float ToolPy::getDiameter() const
{
return Py::Float(getToolPtr()->Diameter);
}
void ToolPy::setDiameter(Py::Float arg)
{
getToolPtr()->Diameter = arg.operator double();
}
Py::Float ToolPy::getLengthOffset() const
{
return Py::Float(getToolPtr()->LengthOffset);
}
void ToolPy::setLengthOffset(Py::Float arg)
{
getToolPtr()->LengthOffset = arg.operator double();
}
Py::Float ToolPy::getFlatRadius() const
{
return Py::Float(getToolPtr()->FlatRadius);
}
void ToolPy::setFlatRadius(Py::Float arg)
{
getToolPtr()->FlatRadius = arg.operator double();
}
Py::Float ToolPy::getCornerRadius() const
{
return Py::Float(getToolPtr()->CornerRadius);
}
void ToolPy::setCornerRadius(Py::Float arg)
{
getToolPtr()->CornerRadius = arg.operator double();
}
Py::Float ToolPy::getCuttingEdgeAngle() const
{
return Py::Float(getToolPtr()->CuttingEdgeAngle);
}
void ToolPy::setCuttingEdgeAngle(Py::Float arg)
{
getToolPtr()->CuttingEdgeAngle = arg.operator double();
}
Py::Float ToolPy::getCuttingEdgeHeight() const
{
return Py::Float(getToolPtr()->CuttingEdgeHeight);
}
void ToolPy::setCuttingEdgeHeight(Py::Float arg)
{
getToolPtr()->CuttingEdgeHeight = arg.operator double();
}
// custom attributes get/set
PyObject *ToolPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}
int ToolPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}
PyObject* ToolPy::copy(PyObject * args)
{
if (PyArg_ParseTuple(args, "")) {
return new ToolPy(new Path::Tool(*getToolPtr()));
}
throw Py::TypeError("This method accepts no argument");
}
PyObject* ToolPy::setFromTemplate(PyObject * args)
{
char *pstr = nullptr;
if (PyArg_ParseTuple(args, "s", &pstr)) {
// embed actual string in dummy tag so XMLReader can consume that on construction
std::ostringstream os;
os << "<snippet>" << pstr << "</snippet>";
std::istringstream is(os.str());
Base::XMLReader reader("", is);
getToolPtr()->Restore(reader);
Py_Return ;
}
PyErr_Clear();
if (!PyInit(args, nullptr)) {
Py_Return ;
}
PyErr_SetString(PyExc_TypeError, "argument must be a string or dictionary");
return nullptr;
}
PyObject* ToolPy::templateAttrs(PyObject * args)
{
if (!args || PyArg_ParseTuple(args, "")) {
PyObject *dict = PyDict_New();
PyDict_SetItemString(dict, "version", PYINT_FROMLONG(1));
PyDict_SetItemString(dict, "name", PYSTRING_FROMSTRING(getToolPtr()->Name.c_str()));
PyDict_SetItemString(dict, "tooltype",PYSTRING_FROMSTRING(Tool::TypeName(getToolPtr()->Type)));
PyDict_SetItemString(dict, "material", PYSTRING_FROMSTRING(Tool::MaterialName(getToolPtr()->Material)));
PyDict_SetItemString(dict, "diameter", PyFloat_FromDouble(getToolPtr()->Diameter));
PyDict_SetItemString(dict, "lengthOffset", PyFloat_FromDouble(getToolPtr()->LengthOffset));
PyDict_SetItemString(dict, "flatRadius", PyFloat_FromDouble(getToolPtr()->FlatRadius));
PyDict_SetItemString(dict, "cornerRadius", PyFloat_FromDouble(getToolPtr()->CornerRadius));
PyDict_SetItemString(dict, "cuttingEdgeAngle", PyFloat_FromDouble(getToolPtr()->CuttingEdgeAngle));
PyDict_SetItemString(dict, "cuttingEdgeHeight", PyFloat_FromDouble(getToolPtr()->CuttingEdgeHeight));
return dict;
}
throw Py::TypeError("This method accepts no argument");
}
PyObject* ToolPy::getToolTypes(PyObject * args)
{
if (PyArg_ParseTuple(args, "")) {
std::vector<std::string> toolTypes = Tool::ToolTypes();
Py::List list;
for(unsigned i = 0; i != toolTypes.size(); i++) {
list.append(Py::asObject(PYSTRING_FROMSTRING(toolTypes[i].c_str())));
}
return Py::new_reference_to(list);
}
throw Py::TypeError("This method accepts no argument");
}
PyObject* ToolPy::getToolMaterials(PyObject * args)
{
if (PyArg_ParseTuple(args, "")) {
std::vector<std::string> toolMaterials = Tool::ToolMaterials();
Py::List list;;
for(unsigned i = 0; i != toolMaterials.size(); i++) {
list.append(Py::asObject(PYSTRING_FROMSTRING(toolMaterials[i].c_str())));
}
return Py::new_reference_to(list);
}
throw Py::TypeError("This method accepts no argument");
}

View File

@@ -1,117 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include "Tooltable.h"
using namespace Base;
using namespace Path;
TYPESYSTEM_SOURCE(Path::Tooltable , Base::Persistence)
Tooltable::Tooltable()
{
Version = 0;
}
Tooltable::~Tooltable()
{
}
void Tooltable::addTool(const Tool &tool)
{
ToolPtr tmp = std::make_shared<Tool>(tool);
if (!Tools.empty()) {
int max = 0;
for(std::map<int,ToolPtr>::const_iterator i = Tools.begin(); i != Tools.end(); ++i) {
int k = i->first;
if (k > max)
max = k;
}
Tools[max+1]= tmp;
} else
Tools[1] = tmp;
}
void Tooltable::setTool(const Tool &tool, int pos)
{
if (pos == -1) {
addTool(tool);
} else {
ToolPtr tmp = std::make_shared<Tool>(tool);
Tools[pos] = tmp;
}
}
void Tooltable::deleteTool(int pos)
{
if (Tools.find(pos) != Tools.end()) {
Tools.erase(pos);
} else {
throw Base::IndexError("Index not found");
}
}
unsigned int Tooltable::getMemSize () const
{
return 0;
}
void Tooltable::Save (Writer &writer) const
{
writer.Stream() << writer.ind() << "<Tooltable count=\"" << getSize() <<"\">" << std::endl;
writer.incInd();
for(std::map<int,ToolPtr>::const_iterator i = Tools.begin(); i != Tools.end(); ++i) {
int k = i->first;
ToolPtr v = i->second;
writer.Stream() << writer.ind() << "<Toolslot number=\"" << k << "\">" << std::endl;
writer.incInd();
v->Save(writer);
writer.decInd();
writer.Stream() << writer.ind() << "</Toolslot>" << std::endl;
}
writer.decInd();
writer.Stream() << writer.ind() << "</Tooltable>" << std::endl ;
}
void Tooltable::Restore (XMLReader &reader)
{
Tools.clear();
reader.readElement("Tooltable");
int count = reader.getAttributeAsInteger("count");
for (int i = 0; i < count; i++) {
reader.readElement("Toolslot");
int id = reader.getAttributeAsInteger("number");
ToolPtr tmp = std::make_shared<Tool>();
tmp->Restore(reader);
Tools[id] = tmp;
}
}

View File

@@ -1,68 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PATH_TOOLTABLE_H
#define PATH_TOOLTABLE_H
#include <vector>
#include <string>
#include <map>
#include <Base/Persistence.h>
#include "Tool.h"
namespace Path
{ /** The representation of a table of tools */
class PathExport Tooltable : public Base::Persistence
{
TYPESYSTEM_HEADER();
public:
//constructors
Tooltable();
~Tooltable();
// from base class
virtual unsigned int getMemSize (void) const;
virtual void Save (Base::Writer &/*writer*/) const;
virtual void Restore(Base::XMLReader &/*reader*/);
// new functions
void addTool(const Tool &tool); // adds a tool at the end
void setTool(const Tool &tool, int); // inserts a tool
void deleteTool(int); // deletes a tool
// auto
unsigned int getSize(void) const {return Tools.size();}
const Tool &getTool(int pos) {return *Tools.at(pos);}
const std::map<int,ToolPtr> &getTools(void) const {return Tools;}
bool hasTool(int pos) const {return (Tools.count(pos) != 0);}
// attributes
std::map<int,ToolPtr> Tools;
int Version;
std::string Name;
};
} //namespace Path
#endif // PATH_TOOLTABLE_H

View File

@@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="PersistencePy"
Name="TooltablePy"
Twin="Tooltable"
TwinPointer="Tooltable"
Include="Mod/Path/App/Tooltable.h"
Namespace="Path"
FatherInclude="Base/PersistencePy.h"
FatherNamespace="Base"
Constructor="true"
Delete="true">
<Documentation>
<Author Licence="LGPL" Name="Yorik van Havre" EMail="yorik@uncreated.net" />
<UserDocu>The Tooltable object holds a table of CNC tools</UserDocu>
</Documentation>
<Attribute Name="Name" ReadOnly="false">
<Documentation>
<UserDocu>the name of this tool table</UserDocu>
</Documentation>
<Parameter Name="Name" Type="String"/>
</Attribute>
<Attribute Name="Version" ReadOnly="false">
<Documentation>
<UserDocu>the version of this tooltable</UserDocu>
</Documentation>
<Parameter Name="Version" Type="Int"/>
</Attribute>
<Attribute Name="Tools" ReadOnly="false">
<Documentation>
<UserDocu>the dictionary of tools of this table</UserDocu>
</Documentation>
<Parameter Name="Tools" Type="Dict"/>
</Attribute>
<Methode Name="copy">
<Documentation>
<UserDocu>returns a copy of this tooltable</UserDocu>
</Documentation>
</Methode>
<Methode Name="addTools">
<Documentation>
<UserDocu>adds a tool or a list of tools at the end of the table</UserDocu>
</Documentation>
</Methode>
<Methode Name="getTool">
<Documentation>
<UserDocu>getTool(int):
returns the tool found at the given position, or None</UserDocu>
</Documentation>
</Methode>
<Methode Name="setTool">
<Documentation>
<UserDocu>setTool(int,tool):
adds a tool at the given position</UserDocu>
</Documentation>
</Methode>
<Methode Name="deleteTool">
<Documentation>
<UserDocu>deleteTool(int):
deletes the tool found at the given position</UserDocu>
</Documentation>
</Methode>
<!--<ClassDeclarations>
bool touched;
</ClassDeclarations>-->
<Methode Name="setFromTemplate">
<Documentation>
<UserDocu>setFromTemplate(dict) ... restores receiver from given template attribute dictionary</UserDocu>
</Documentation>
</Methode>
<Methode Name="templateAttrs" Const="true">
<Documentation>
<UserDocu>templateAttrs() ... returns a dictionary representing the receivers attributes for a template</UserDocu>
</Documentation>
</Methode>
</PythonExport>
</GenerateModel>

View File

@@ -1,281 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#include "Base/Reader.h"
#include "Mod/Path/App/Tool.h"
#include "Mod/Path/App/Tooltable.h"
// inclusion of the generated files (generated out of ToolPy.xml and TooltablePy.xml)
#include "ToolPy.h"
#include "TooltablePy.h"
#include "TooltablePy.cpp"
using namespace Path;
#define PYSTRING_FROMSTRING(str) PyUnicode_FromString(str)
#define PYINT_TYPE PyLong_Type
#define PYINT_FROMLONG(l) PyLong_FromLong(l)
#define PYINT_ASLONG(o) PyLong_AsLong(o)
// returns a string which represents the object e.g. when printed in python
std::string TooltablePy::representation() const
{
std::stringstream str;
str.precision(5);
str << "Tooltable containing ";
str << getTooltablePtr()->getSize() << " tools";
return str.str();
}
PyObject *TooltablePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
{
return new TooltablePy(new Tooltable);
}
// constructor method
int TooltablePy::PyInit(PyObject* args, PyObject* /*kwd*/)
{
//char *name="Tooltable";
//int version = 1;
if (PyArg_ParseTuple(args, "")) {
return 0;
}
PyErr_Clear(); // set by PyArg_ParseTuple()
PyObject *pcObj;
if (PyArg_ParseTuple(args, "O!", &(PyDict_Type), &pcObj)) {
try {
Py::Dict dict(pcObj);
setTools(dict);
} catch(...) {
PyErr_SetString(PyExc_TypeError, "The dictionary can only contain int:tool pairs");
return -1;
}
return 0;
}
PyErr_Clear(); // set by PyArg_ParseTuple()
if (PyArg_ParseTuple(args, "O!", &(PyList_Type), &pcObj)) {
Py::List list(pcObj);
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
if (PyObject_TypeCheck((*it).ptr(), &(Path::ToolPy::Type))) {
Path::Tool &tool = *static_cast<Path::ToolPy*>((*it).ptr())->getToolPtr();
getTooltablePtr()->addTool(tool);
}
}
return 0;
}
PyErr_SetString(PyExc_TypeError, "Argument must be either empty or a list or a dictionary");
return -1;
}
// Commands get/set
Py::Dict TooltablePy::getTools() const
{
Py::Dict dict;
for(std::map<int,Path::ToolPtr>::iterator i = getTooltablePtr()->Tools.begin(); i != getTooltablePtr()->Tools.end(); ++i) {
PyObject *tool = new Path::ToolPy(new Tool(*i->second));
dict.setItem(Py::Long(i->first), Py::asObject(tool));
}
return dict;
}
void TooltablePy::setTools(Py::Dict arg)
{
getTooltablePtr()->Tools.clear();
PyObject* dict_copy = PyDict_Copy(arg.ptr());
PyObject *key, *value;
Py_ssize_t pos = 0;
while (PyDict_Next(dict_copy, &pos, &key, &value)) {
if ( PyObject_TypeCheck(key,&(PYINT_TYPE)) && ((PyObject_TypeCheck(value, &(Path::ToolPy::Type))) || PyObject_TypeCheck(value, &PyDict_Type))) {
int ckey = (int)PYINT_ASLONG(key);
if (PyObject_TypeCheck(value, &(Path::ToolPy::Type))) {
Path::Tool &tool = *static_cast<Path::ToolPy*>(value)->getToolPtr();
getTooltablePtr()->setTool(tool, ckey);
} else {
PyErr_Clear();
Path::Tool *tool = new Path::Tool;
// The 'pyTool' object must be created on the heap otherwise Python
// will fail to properly track the reference counts and aborts
// in debug mode.
Path::ToolPy* pyTool = new Path::ToolPy(tool);
PyObject* success = pyTool->setFromTemplate(value);
if (!success) {
Py_DECREF(pyTool);
throw Py::Exception();
}
getTooltablePtr()->setTool(*tool, ckey);
Py_DECREF(pyTool);
Py_DECREF(success);
}
} else {
throw Py::TypeError("The dictionary can only contain int:tool pairs");
}
}
}
// specific methods
PyObject* TooltablePy::copy(PyObject * args)
{
if (PyArg_ParseTuple(args, "")) {
return new TooltablePy(new Path::Tooltable(*getTooltablePtr()));
}
throw Py::TypeError("This method accepts no argument");
}
PyObject* TooltablePy::addTools(PyObject * args)
{
PyObject* o;
if (PyArg_ParseTuple(args, "O!", &(Path::ToolPy::Type), &o)) {
Path::Tool &tool = *static_cast<Path::ToolPy*>(o)->getToolPtr();
getTooltablePtr()->addTool(tool);
//return new TooltablePy(new Path::Tooltable(*getTooltablePtr()));
Py_INCREF(Py_None);
return Py_None;
}
PyErr_Clear();
if (PyArg_ParseTuple(args, "O!", &(PyList_Type), &o)) {
Py::List list(o);
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
if (PyObject_TypeCheck((*it).ptr(), &(Path::ToolPy::Type))) {
Path::Tool &tool = *static_cast<Path::ToolPy*>((*it).ptr())->getToolPtr();
getTooltablePtr()->addTool(tool);
}
}
//return new TooltablePy(new Path::Tooltable(*getTooltablePtr()));
Py_INCREF(Py_None);
return Py_None;
}
Py_Error(PyExc_TypeError, "Wrong parameters - tool or list of tools expected");
}
PyObject* TooltablePy::setTool(PyObject * args)
{
PyObject* o;
int pos = -1;
if (PyArg_ParseTuple(args, "iO!", &pos, &(Path::ToolPy::Type), &o)) {
Path::Tool &tool = *static_cast<Path::ToolPy*>(o)->getToolPtr();
getTooltablePtr()->setTool(tool,pos);
//return new TooltablePy(new Path::Tooltable(*getTooltablePtr()));
Py_INCREF(Py_None);
return Py_None;
}
Py_Error(PyExc_TypeError, "Wrong parameters - expected tool and optional integer");
}
PyObject* TooltablePy::getTool(PyObject * args)
{
int pos = -1;
if (PyArg_ParseTuple(args, "i", &pos)) {
if (getTooltablePtr()->hasTool(pos))
{
Path::Tool tool = getTooltablePtr()->getTool(pos);
return new ToolPy(new Path::Tool(tool));
}
else
{
Py_INCREF(Py_None);
return Py_None;
}
}
Py_Error(PyExc_TypeError, "Argument must be integer");
}
PyObject* TooltablePy::deleteTool(PyObject * args)
{
int pos = -1;
if (PyArg_ParseTuple(args, "|i", &pos)) {
getTooltablePtr()->deleteTool(pos);
//return new TooltablePy(new Path::Tooltable(*getTooltablePtr()));
Py_INCREF(Py_None);
return Py_None;
}
Py_Error(PyExc_TypeError, "Wrong parameters - expected an integer (optional)");
}
// custom attributes get/set
PyObject *TooltablePy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}
int TooltablePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}
Py::Int TooltablePy::getVersion() const
{
return Py::Int(getTooltablePtr()->Version);
}
void TooltablePy::setVersion(Py::Int version) {
getTooltablePtr()->Version = version;
}
Py::String TooltablePy::getName() const
{
return Py::String(getTooltablePtr()->Name.c_str());
}
void TooltablePy::setName(Py::String arg)
{
std::string name = arg.as_std_string();
getTooltablePtr()->Name = name;
}
PyObject* TooltablePy::setFromTemplate(PyObject * args)
{
PyObject *dict = nullptr;
if (PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict)) {
Py::Dict d(dict);
setTools(d);
Py_Return ;
}
PyErr_SetString(PyExc_TypeError, "argument must be a dictionary returned from templateAttrs()");
return nullptr;
}
PyObject* TooltablePy::templateAttrs(PyObject * args)
{
(void)args;
PyObject *dict = PyDict_New();
for(std::map<int,Path::ToolPtr>::iterator i = getTooltablePtr()->Tools.begin(); i != getTooltablePtr()->Tools.end(); ++i) {
// The 'tool' object must be created on the heap otherwise Python
// will fail to properly track the reference counts and aborts
// in debug mode.
Path::ToolPy* tool = new Path::ToolPy(new Path::Tool(*i->second));
PyObject *attrs = tool->templateAttrs(nullptr);
PyDict_SetItem(dict, PYINT_FROMLONG(i->first), attrs);
Py_DECREF(tool);
}
return dict;
}

View File

@@ -197,9 +197,6 @@ SET(PathScripts_SRCS
PathScripts/PathSimulatorGui.py
PathScripts/PathStock.py
PathScripts/PathStop.py
PathScripts/PathToolEdit.py
PathScripts/PathToolLibraryEditor.py
PathScripts/PathToolLibraryManager.py
PathScripts/PathUtil.py
PathScripts/PathUtils.py
PathScripts/PathUtilsGui.py
@@ -290,10 +287,8 @@ SET(PathTests_SRCS
PathTests/TestPathToolChangeGenerator.py
PathTests/TestPathThreadMilling.py
PathTests/TestPathThreadMillingGenerator.py
PathTests/TestPathTool.py
PathTests/TestPathToolBit.py
PathTests/TestPathToolController.py
PathTests/TestPathTooltable.py
PathTests/TestPathUtil.py
PathTests/TestPathVcarve.py
PathTests/TestPathVoronoi.py

View File

@@ -129,8 +129,6 @@
<file>panels/ToolBitEditor.ui</file>
<file>panels/ToolBitLibraryEdit.ui</file>
<file>panels/ToolBitSelector.ui</file>
<file>panels/ToolEditor.ui</file>
<file>panels/ToolLibraryEditor.ui</file>
<file>panels/TaskPathCamoticsSim.ui</file>
<file>panels/TaskPathSimulator.ui</file>
<file>panels/ZCorrectEdit.ui</file>

View File

@@ -1,429 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ToolLibrary</class>
<widget class="QDialog" name="ToolLibrary">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>946</width>
<height>614</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Tool Library</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="ButtonImport">
<property name="text">
<string>Import...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonExport">
<property name="text">
<string>Export...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QWidget" name="widget">
<property name="maximumSize">
<size>
<width>225</width>
<height>16777215</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Tool Tables</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="ButtonRenameToolTable">
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="edit-edit.svg" resource="../../../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/edit-edit.svg</normaloff>:/icons/edit-edit.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonRemoveToolTable">
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/list-remove.svg</normalon>
</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonAddToolTable">
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/list-add.svg</normalon>
</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="TableList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::NoDragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::IgnoreAction</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="iconSize">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTableView" name="ToolsList">
<property name="dragEnabled">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::IgnoreAction</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="ButtonNewTool">
<property name="text">
<string>New Tool</string>
</property>
<property name="icon">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path_ToolController.svg</normaloff>:/icons/Path_ToolController.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonDelete">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Delete</string>
</property>
<property name="icon">
<iconset resource="../../../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/delete.svg</normaloff>:/icons/delete.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>Edit</string>
</property>
<property name="icon">
<iconset resource="../../../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/edit-edit.svg</normaloff>:/icons/edit-edit.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonDuplicate">
<property name="enabled">
<bool>false</bool>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>Duplicate</string>
</property>
<property name="icon">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path_ToolDuplicate.svg</normaloff>:/icons/Path_ToolDuplicate.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonUp">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Move up</string>
</property>
<property name="icon">
<iconset resource="../../../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/button_up.svg</normaloff>:/icons/button_up.svg</iconset>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonDown">
<property name="enabled">
<bool>false</bool>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>Move down</string>
</property>
<property name="icon">
<iconset resource="../../../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/button_down.svg</normaloff>:/icons/button_down.svg</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="btnCopyTools">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Create Tool Controllers for the selected tools</string>
</property>
<property name="text">
<string>Create Tool Controller(s)</string>
</property>
<property name="icon">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path_LengthOffset.svg</normaloff>:/icons/Path_LengthOffset.svg</iconset>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../../../../Gui/Icons/resource.qrc"/>
<include location="../Path.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ToolLibrary</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ToolLibrary</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -633,16 +633,6 @@
<string>Tools</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="toolsUseLegacy">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Legacy Tools have no accurate shape representation and are stored in the user preferences of FreeCAD.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use Legacy Tools</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="toolsAbsolutePaths">
<property name="toolTip">

View File

@@ -40,9 +40,6 @@
#include <Gui/BitmapFactory.h>
#include <Gui/Command.h>
#include <Mod/Path/App/Tooltable.h>
using namespace PathGui;
using namespace Gui;

View File

@@ -135,12 +135,8 @@ class PathWorkbench(Workbench):
# remotecmdlist = ["Path_Remote"]
specialcmdlist = []
if PathPreferences.toolsUseLegacyTools():
toolcmdlist.append("Path_ToolLibraryEdit")
toolbitcmdlist = []
else:
toolcmdlist.extend(PathToolBitLibraryCmd.BarList)
toolbitcmdlist = PathToolBitLibraryCmd.MenuList
toolcmdlist.extend(PathToolBitLibraryCmd.BarList)
toolbitcmdlist = PathToolBitLibraryCmd.MenuList
engravecmdgroup = ["Path_EngraveTools"]
FreeCADGui.addCommand(

View File

@@ -2473,8 +2473,8 @@ class FindUnifiedRegions:
class OCL_Tool:
"""The OCL_Tool class is designed to translate a FreeCAD standard ToolBit shape,
or Legacy tool type, in the active Tool Controller, into an OCL tool type."""
"""The OCL_Tool class is designed to translate a FreeCAD standard ToolBit shape
in the active Tool Controller, into an OCL tool type."""
def __init__(self, ocl, obj, safe=False):
self.ocl = ocl
@@ -2501,9 +2501,6 @@ class OCL_Tool:
if hasattr(self.tool, "ShapeName"):
self.toolType = self.tool.ShapeName # Indicates ToolBit tool
self.toolMode = "ToolBit"
elif hasattr(self.tool, "ToolType"):
self.toolType = self.tool.ToolType # Indicates Legacy tool
self.toolMode = "Legacy"
if self.toolType:
Path.Log.debug(
"OCL_Tool tool mode, type: {}, {}".format(self.toolMode, self.toolType)
@@ -2726,25 +2723,7 @@ class OCL_Tool:
def _setToolMethod(self):
toolMap = dict()
if self.toolMode == "Legacy":
# Set cutter details
# https://www.freecadweb.org/api/dd/dfe/classPath_1_1Tool.html#details
toolMap = {
"EndMill": "CylCutter",
"BallEndMill": "BallCutter",
"SlotCutter": "CylCutter",
"Engraver": "ConeCutter",
"Drill": "ConeCutter",
"CounterSink": "ConeCutter",
"FlyCutter": "CylCutter",
"CenterDrill": "None",
"CounterBore": "None",
"Reamer": "None",
"Tap": "None",
"ChamferMill": "None",
"CornerRound": "None",
}
elif self.toolMode == "ToolBit":
if self.toolMode == "ToolBit":
toolMap = {
"endmill": "CylCutter",
"ballend": "BallCutter",

View File

@@ -445,7 +445,7 @@ class ToolBit(object):
def templateAttrs(self, obj):
attrs = {}
attrs["version"] = 2 # Path.Tool is version 1
attrs["version"] = 2
attrs["name"] = obj.Label
if PathPreferences.toolsStoreAbsolutePaths():
attrs["shape"] = obj.BitShape

View File

@@ -60,8 +60,8 @@ class ToolControllerTemplate:
class ToolController:
def __init__(self, obj, legacyTool=False, createTool=True):
Path.Log.track("tool: {}".format(legacyTool))
def __init__(self, obj, createTool=True):
Path.Log.track("tool: ")
obj.addProperty(
"App::PropertyIntegerConstraint",
@@ -114,7 +114,7 @@ class ToolController:
setattr(obj, n[0], n[1])
if createTool:
self.ensureUseLegacyTool(obj, legacyTool)
self.ensureToolBit(obj)
@classmethod
def propertyEnumerations(self, dataType="data"):
@@ -154,10 +154,9 @@ class ToolController:
obj.setEditorMode("Placement", 2)
def onDelete(self, obj, arg2=None):
if not self.usesLegacyTool(obj):
if hasattr(obj.Tool, "InList") and len(obj.Tool.InList) == 1:
if hasattr(obj.Tool.Proxy, "onDelete"):
obj.Tool.Proxy.onDelete(obj.Tool)
if hasattr(obj.Tool, "InList") and len(obj.Tool.InList) == 1:
if hasattr(obj.Tool.Proxy, "onDelete"):
obj.Tool.Proxy.onDelete(obj.Tool)
def setFromTemplate(self, obj, template):
"""
@@ -193,22 +192,16 @@ class ToolController:
toolVersion = template.get(ToolControllerTemplate.Tool).get(
ToolControllerTemplate.Version
)
if toolVersion == 1:
self.ensureUseLegacyTool(obj, True)
obj.Tool.setFromTemplate(
template.get(ToolControllerTemplate.Tool)
)
else:
self.ensureUseLegacyTool(obj, False)
obj.Tool = PathToolBit.Factory.CreateFromAttrs(
template.get(ToolControllerTemplate.Tool)
)
if (
obj.Tool
and obj.Tool.ViewObject
and obj.Tool.ViewObject.Visibility
):
obj.Tool.ViewObject.Visibility = False
self.ensureToolBit(obj)
obj.Tool = PathToolBit.Factory.CreateFromAttrs(
template.get(ToolControllerTemplate.Tool)
)
if (
obj.Tool
and obj.Tool.ViewObject
and obj.Tool.ViewObject.Visibility
):
obj.Tool.ViewObject.Visibility = False
if template.get(ToolControllerTemplate.Expressions):
for exprDef in template.get(ToolControllerTemplate.Expressions):
if exprDef[ToolControllerTemplate.ExprExpr]:
@@ -240,10 +233,7 @@ class ToolController:
attrs[ToolControllerTemplate.HorizRapid] = "%s" % (obj.HorizRapid)
attrs[ToolControllerTemplate.SpindleSpeed] = obj.SpindleSpeed
attrs[ToolControllerTemplate.SpindleDir] = obj.SpindleDir
if self.usesLegacyTool(obj):
attrs[ToolControllerTemplate.Tool] = obj.Tool.templateAttrs()
else:
attrs[ToolControllerTemplate.Tool] = obj.Tool.Proxy.templateAttrs(obj.Tool)
attrs[ToolControllerTemplate.Tool] = obj.Tool.Proxy.templateAttrs(obj.Tool)
expressions = []
for expr in obj.ExpressionEngine:
Path.Log.debug("%s: %s" % (expr[0], expr[1]))
@@ -296,38 +286,16 @@ class ToolController:
Path.Log.track()
return obj.Tool
def usesLegacyTool(self, obj):
"""returns True if the tool being controlled is a legacy tool"""
return isinstance(obj.Tool, Path.Tool)
def ensureUseLegacyTool(self, obj, legacy):
if not hasattr(obj, "Tool") or (legacy != self.usesLegacyTool(obj)):
if legacy and hasattr(obj, "Tool") and len(obj.Tool.InList) == 1:
if hasattr(obj.Tool.Proxy, "onDelete"):
obj.Tool.Proxy.onDelete(obj.Tool)
obj.Document.removeObject(obj.Tool.Name)
if hasattr(obj, "Tool"):
obj.removeProperty("Tool")
if legacy:
obj.addProperty(
"Path::PropertyTool",
"Tool",
"Base",
QT_TRANSLATE_NOOP(
"App::Property", "The tool used by this controller"
),
)
else:
obj.addProperty(
"App::PropertyLink",
"Tool",
"Base",
QT_TRANSLATE_NOOP(
"App::Property", "The tool used by this controller"
),
)
def ensureToolBit(self, obj):
if not hasattr(obj, "Tool"):
obj.addProperty(
"App::PropertyLink",
"Tool",
"Base",
QT_TRANSLATE_NOOP(
"App::Property", "The tool used by this controller"
),
)
def Create(
@@ -337,34 +305,21 @@ def Create(
assignViewProvider=True,
assignTool=True,
):
legacyTool = (
PathPreferences.toolsUseLegacyTools()
if tool is None
else isinstance(tool, Path.Tool)
)
Path.Log.track(tool, toolNumber, legacyTool)
Path.Log.track(tool, toolNumber)
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
obj.Label = name
obj.Proxy = ToolController(obj, legacyTool, assignTool)
obj.Proxy = ToolController(obj, assignTool)
if FreeCAD.GuiUp and assignViewProvider:
ViewProvider(obj.ViewObject)
if assignTool:
if not tool:
if legacyTool:
tool = Path.Tool()
tool.Diameter = 5.0
tool.Name = "Default Tool"
tool.CuttingEdgeHeight = 15.0
tool.ToolType = "EndMill"
tool.Material = "HighSpeedSteel"
else:
tool = PathToolBit.Factory.Create()
if tool.ViewObject:
tool.ViewObject.Visibility = False
tool = PathToolBit.Factory.Create()
if tool.ViewObject:
tool.ViewObject.Visibility = False
obj.Tool = tool
if hasattr(obj.Tool, "SpindleDirection"):

View File

@@ -29,7 +29,6 @@ import Path.Tools.Controller as PathToolController
import Path.Tools.Gui.Bit as PathToolBitGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathGui as PathGui
import PathScripts.PathToolEdit as PathToolEdit
import PathScripts.PathUtil as PathUtil
# lazily loaded modules
@@ -120,7 +119,7 @@ class ViewProvider:
def claimChildren(self):
obj = self.vobj.Object
if obj and obj.Proxy and not obj.Proxy.usesLegacyTool(obj):
if obj and obj.Proxy:
return [obj.Tool]
return []
@@ -130,10 +129,9 @@ def Create(name="Default Tool", tool=None, toolNumber=1):
obj = PathToolController.Create(name, tool, toolNumber)
ViewProvider(obj.ViewObject)
if not obj.Proxy.usesLegacyTool(obj):
# ToolBits are visible by default, which is typically not what the user wants
if tool and tool.ViewObject and tool.ViewObject.Visibility:
tool.ViewObject.Visibility = False
# ToolBits are visible by default, which is typically not what the user wants
if tool and tool.ViewObject and tool.ViewObject.Visibility:
tool.ViewObject.Visibility = False
return obj
@@ -198,12 +196,9 @@ class ToolControllerEditor(object):
self.form.horizRapid, obj, "HorizRapid"
)
if obj.Proxy.usesLegacyTool(obj):
self.editor = PathToolEdit.ToolEditor(obj.Tool, self.form.toolEditor)
else:
self.editor = None
self.form.toolBox.widget(1).hide()
self.form.toolBox.removeItem(1)
self.editor = None
self.form.toolBox.widget(1).hide()
self.form.toolBox.removeItem(1)
def selectInComboBox(self, name, combo):
"""selectInComboBox(name, combo) ...

View File

@@ -74,8 +74,6 @@ def Startup():
from PathScripts import PathSimpleCopy
from PathScripts import PathSimulatorGui
from PathScripts import PathStop
from PathScripts import PathToolLibraryEditor
from PathScripts import PathToolLibraryManager
from PathScripts import PathUtilsGui
from packaging.version import Version, parse

View File

@@ -549,14 +549,6 @@ class ObjectJob:
for n in self.propertyEnumerations():
setattr(obj, n[0], n[1])
if True in [isinstance(t.Tool, Path.Tool) for t in obj.Tools.Group]:
FreeCAD.Console.PrintWarning(
translate(
"Path",
"This job contains Legacy tools. Legacy tools are deprecated. They will be removed after version 0.20",
)
)
def onChanged(self, obj, prop):
if prop == "PostProcessor" and obj.PostProcessor:
processor = PostProcessor.load(obj.PostProcessor)

View File

@@ -38,7 +38,6 @@ import PathScripts.PathJobDlg as PathJobDlg
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathSetupSheetGui as PathSetupSheetGui
import PathScripts.PathStock as PathStock
import PathScripts.PathToolLibraryEditor as PathToolLibraryEditor
import PathScripts.PathUtil as PathUtil
import PathScripts.PathUtils as PathUtils
import json
@@ -999,35 +998,30 @@ class TaskPanel:
# Try to find a tool number from the currently selected lib. Otherwise
# use next available number
if PathPreferences.toolsUseLegacyTools():
PathToolLibraryEditor.CommandToolLibraryEdit().edit(
self.obj, self.updateToolController
tools = PathToolBitGui.LoadTools()
curLib = PathPreferences.lastFileToolLibrary()
library = None
if curLib is not None:
with open(curLib) as fp:
library = json.load(fp)
for tool in tools:
toolNum = self.obj.Proxy.nextToolNumber()
if library is not None:
for toolBit in library["tools"]:
if toolBit["path"] == tool.File:
toolNum = toolBit["nr"]
tc = PathToolControllerGui.Create(
name=tool.Label, tool=tool, toolNumber=toolNum
)
else:
tools = PathToolBitGui.LoadTools()
self.obj.Proxy.addToolController(tc)
curLib = PathPreferences.lastFileToolLibrary()
library = None
if curLib is not None:
with open(curLib) as fp:
library = json.load(fp)
for tool in tools:
toolNum = self.obj.Proxy.nextToolNumber()
if library is not None:
for toolBit in library["tools"]:
if toolBit["path"] == tool.File:
toolNum = toolBit["nr"]
tc = PathToolControllerGui.Create(
name=tool.Label, tool=tool, toolNumber=toolNum
)
self.obj.Proxy.addToolController(tc)
FreeCAD.ActiveDocument.recompute()
self.updateToolController()
FreeCAD.ActiveDocument.recompute()
self.updateToolController()
def toolControllerDelete(self):
self.objectDelete(self.form.toolControllerList)

View File

@@ -54,7 +54,6 @@ LastFileToolBit = "LastFileToolBit"
LastFileToolLibrary = "LastFileToolLibrary"
LastFileToolShape = "LastFileToolShape"
UseLegacyTools = "UseLegacyTools"
UseAbsoluteToolPaths = "UseAbsoluteToolPaths"
# OpenLastLibrary = "OpenLastLibrary"
@@ -171,9 +170,6 @@ def searchPathsTool(sub):
return paths
def toolsUseLegacyTools():
return preferences().GetBool(UseLegacyTools, False)
def toolsStoreAbsolutePaths():
return preferences().GetBool(UseAbsoluteToolPaths, False)
@@ -183,19 +179,8 @@ def toolsStoreAbsolutePaths():
# return preferences().GetBool(OpenLastLibrary, False)
def setToolsSettings(legacy, relative):
def setToolsSettings(relative):
pref = preferences()
if legacy:
msgBox = QMessageBox()
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText(
translate(
"Path",
"Legacy tools are deprecated. They will be removed after version 0.20",
)
)
msgBox.exec_()
pref.SetBool(UseLegacyTools, legacy)
pref.SetBool(UseAbsoluteToolPaths, relative)
# pref.SetBool(OpenLastLibrary, lastlibrary)

View File

@@ -147,8 +147,7 @@ class JobPreferencesPage:
def saveToolsSettings(self):
PathPreferences.setToolsSettings(
self.form.toolsUseLegacy.isChecked(),
self.form.toolsAbsolutePaths.isChecked(),
self.form.toolsAbsolutePaths.isChecked()
)
def selectComboEntry(self, widget, text):
@@ -328,7 +327,6 @@ class JobPreferencesPage:
self.form.stockCreateCylinder.hide()
def loadToolSettings(self):
self.form.toolsUseLegacy.setChecked(PathPreferences.toolsUseLegacyTools())
self.form.toolsAbsolutePaths.setChecked(
PathPreferences.toolsStoreAbsolutePaths()
)

View File

@@ -188,20 +188,7 @@ class PathSimulation:
self.tool = None
if self.tool is not None:
if isinstance(self.tool, Path.Tool):
# handle legacy tools
toolProf = self.CreateToolProfile(
self.tool,
Vector(0, 1, 0),
Vector(0, 0, 0),
float(self.tool.Diameter) / 2.0,
)
self.cutTool.Shape = Part.makeSolid(
toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1))
)
else:
# handle tool bits
self.cutTool.Shape = self.tool.Shape
self.cutTool.Shape = self.tool.Shape
if not self.cutTool.Shape.isValid() or self.cutTool.Shape.isNull():
self.EndSimulation()

View File

@@ -1,352 +0,0 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * Copyright (c) 2018 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 FreeCAD
import FreeCADGui
import Path
import math
from PySide import QtGui
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
# Path.Log.trackModule(Path.Log.thisModule())
class ToolEditorDefault:
"""Generic Tool parameter editor for all Tools that don't have a customized edit function.
Let's the user enter the raw internal data. Not the best approach but this is the starting point."""
def __init__(self, editor):
self.editor = editor
self.form = editor.form
def setupUI(self):
self.form.paramImage.hide()
self.form.paramGeneric.show()
def updateUI(self):
self.form.toolDiameter.setText(
FreeCAD.Units.Quantity(
self.editor.tool.Diameter, FreeCAD.Units.Length
).UserString
)
self.form.toolFlatRadius.setText(
FreeCAD.Units.Quantity(
self.editor.tool.FlatRadius, FreeCAD.Units.Length
).UserString
)
self.form.toolCornerRadius.setText(
FreeCAD.Units.Quantity(
self.editor.tool.CornerRadius, FreeCAD.Units.Length
).UserString
)
self.form.toolCuttingEdgeHeight.setText(
FreeCAD.Units.Quantity(
self.editor.tool.CuttingEdgeHeight, FreeCAD.Units.Length
).UserString
)
self.form.toolCuttingEdgeAngle.setText(
FreeCAD.Units.Quantity(
self.editor.tool.CuttingEdgeAngle, FreeCAD.Units.Angle
).UserString
)
def updateTool(self):
self.editor.tool.Diameter = FreeCAD.Units.parseQuantity(
self.form.toolDiameter.text()
)
self.editor.tool.FlatRadius = FreeCAD.Units.parseQuantity(
self.form.toolFlatRadius.text()
)
self.editor.tool.CornerRadius = FreeCAD.Units.parseQuantity(
self.form.toolCornerRadius.text()
)
self.editor.tool.CuttingEdgeAngle = FreeCAD.Units.Quantity(
self.form.toolCuttingEdgeAngle.text()
)
self.editor.tool.CuttingEdgeHeight = FreeCAD.Units.parseQuantity(
self.form.toolCuttingEdgeHeight.text()
)
class ToolEditorImage(object):
"""Base implementation for all customized Tool parameter editors.
While not required it is simplest to subclass specific editors."""
def __init__(self, editor, imageFile, hide="", disable=""):
self.editor = editor
self.form = editor.form
self.imagePath = "{}Mod/Path/Images/Tools/{}".format(
FreeCAD.getHomePath(), imageFile
)
self.image = QtGui.QPixmap(self.imagePath)
self.hide = hide
self.disable = disable
form = editor.form
self.widgets = {
"D": (form.label_D, form.value_D),
"d": (form.label_d, form.value_d),
"H": (form.label_H, form.value_H),
"a": (form.label_a, form.value_a),
"S": (form.label_S, form.value_S),
}
def setupUI(self):
Path.Log.track()
self.form.paramGeneric.hide()
self.form.paramImage.show()
for key, widgets in self.widgets.items():
hide = key in self.hide
disable = key in self.disable
for w in widgets:
w.setHidden(hide)
w.setDisabled(disable)
if not hide and not disable:
widgets[1].editingFinished.connect(self.editor.refresh)
self.form.image.setPixmap(self.image)
def updateUI(self):
Path.Log.track()
self.form.value_D.setText(self.quantityDiameter(True).UserString)
self.form.value_d.setText(self.quantityFlatRadius(True).UserString)
self.form.value_a.setText(self.quantityCuttingEdgeAngle(True).UserString)
self.form.value_H.setText(self.quantityCuttingEdgeHeight(True).UserString)
def updateTool(self):
Path.Log.track()
toolDefault = Path.Tool()
if "D" in self.hide:
self.editor.tool.Diameter = toolDefault.Diameter
else:
self.editor.tool.Diameter = self.quantityDiameter(False)
if "d" in self.hide:
self.editor.tool.FlatRadius = toolDefault.FlatRadius
else:
self.editor.tool.FlatRadius = self.quantityFlatRadius(False)
if "a" in self.hide:
self.editor.tool.CuttingEdgeAngle = toolDefault.CuttingEdgeAngle
else:
self.editor.tool.CuttingEdgeAngle = self.quantityCuttingEdgeAngle(False)
if "H" in self.hide:
self.editor.tool.CuttingEdgeHeight = toolDefault.CuttingEdgeHeight
else:
self.editor.tool.CuttingEdgeHeight = self.quantityCuttingEdgeHeight(False)
self.editor.tool.CornerRadius = toolDefault.CornerRadius
def quantityDiameter(self, propertyToDisplay):
if propertyToDisplay:
return FreeCAD.Units.Quantity(
self.editor.tool.Diameter, FreeCAD.Units.Length
)
return FreeCAD.Units.parseQuantity(self.form.value_D.text())
def quantityFlatRadius(self, propertyToDisplay):
if propertyToDisplay:
return (
FreeCAD.Units.Quantity(
self.editor.tool.FlatRadius, FreeCAD.Units.Length
)
* 2
)
return FreeCAD.Units.parseQuantity(self.form.value_d.text()) / 2
def quantityCuttingEdgeAngle(self, propertyToDisplay):
if propertyToDisplay:
return FreeCAD.Units.Quantity(
self.editor.tool.CuttingEdgeAngle, FreeCAD.Units.Angle
)
return FreeCAD.Units.parseQuantity(self.form.value_a.text())
def quantityCuttingEdgeHeight(self, propertyToDisplay):
if propertyToDisplay:
return FreeCAD.Units.Quantity(
self.editor.tool.CuttingEdgeHeight, FreeCAD.Units.Length
)
return FreeCAD.Units.parseQuantity(self.form.value_H.text())
class ToolEditorEndmill(ToolEditorImage):
"""Tool parameter editor for endmills."""
def __init__(self, editor):
super(ToolEditorEndmill, self).__init__(editor, "endmill.svg", "da", "S")
class ToolEditorReamer(ToolEditorImage):
"""Tool parameter editor for reamers."""
def __init__(self, editor):
super(ToolEditorReamer, self).__init__(editor, "reamer.svg", "da", "S")
class ToolEditorDrill(ToolEditorImage):
"""Tool parameter editor for drills."""
def __init__(self, editor):
super(ToolEditorDrill, self).__init__(editor, "drill.svg", "dS", "")
def quantityCuttingEdgeAngle(self, propertyToDisplay):
if propertyToDisplay:
return FreeCAD.Units.Quantity(
self.editor.tool.CuttingEdgeAngle, FreeCAD.Units.Angle
)
return FreeCAD.Units.parseQuantity(self.form.value_a.text())
class ToolEditorEngrave(ToolEditorImage):
"""Tool parameter editor for v-bits."""
def __init__(self, editor):
super(ToolEditorEngrave, self).__init__(editor, "v-bit.svg", "", "dS")
def quantityCuttingEdgeHeight(self, propertyToDisplay):
Path.Log.track()
dr = (self.quantityDiameter(False) - self.quantityFlatRadius(False)) / 2
da = self.quantityCuttingEdgeAngle(False).Value
return dr / math.tan(math.radians(da) / 2)
class ToolEditor:
"""UI and controller for editing a Tool.
The controller embeds the UI to the parentWidget which has to have a layout attached to it.
The editor maintains two Tools, self.tool and self.Tool. The former is the one being edited
and always reflects the current state. self.Tool on the other hand is the "official" Tool
which should be used externally. The state is transferred between the two with accept and
reject.
The editor uses instances of ToolEditorDefault and ToolEditorImage to deal with the changes
of the actual parameters. For any ToolType not mapped in ToolTypeImage the editor uses
an instance of ToolEditorDefault.
"""
ToolTypeImage = {
"EndMill": ToolEditorEndmill,
"Drill": ToolEditorDrill,
"Engraver": ToolEditorEngrave,
"Reamer": ToolEditorReamer,
}
def __init__(self, tool, parentWidget, parent=None):
self.Parent = parent
self.Tool = tool
self.tool = tool.copy()
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolEditor.ui")
self.form.setParent(parentWidget)
parentWidget.layout().addWidget(self.form)
for tooltype in Path.Tool.getToolTypes(tool):
self.form.toolType.addItem(tooltype)
for material in Path.Tool.getToolMaterials(tool):
self.form.toolMaterial.addItem(material)
self.setupToolType(self.tool.ToolType)
def accept(self):
self.refresh()
self.Tool = self.tool
def reject(self):
self.tool = self.Tool
def getType(self, tooltype):
"gets a combobox index number for a given type or vice versa"
toolslist = Path.Tool.getToolTypes(Path.Tool())
if isinstance(tooltype, str):
if tooltype in toolslist:
return toolslist.index(tooltype)
else:
return 0
return toolslist[tooltype]
def getMaterial(self, material):
"gets a combobox index number for a given material or vice versa"
matslist = Path.Tool.getToolMaterials(Path.Tool())
if isinstance(material, str):
if material in matslist:
return matslist.index(material)
else:
return 0
return matslist[material]
def updateUI(self):
Path.Log.track()
self.form.toolName.setText(self.tool.Name)
self.form.toolType.setCurrentIndex(self.getType(self.tool.ToolType))
self.form.toolMaterial.setCurrentIndex(self.getMaterial(self.tool.Material))
self.form.toolLengthOffset.setText(
FreeCAD.Units.Quantity(
self.tool.LengthOffset, FreeCAD.Units.Length
).UserString
)
self.editor.updateUI()
def updateToolType(self):
Path.Log.track()
self.form.blockSignals(True)
self.tool.ToolType = self.getType(self.form.toolType.currentIndex())
self.setupToolType(self.tool.ToolType)
self.updateUI()
self.form.blockSignals(False)
def setupToolType(self, tt):
Path.Log.track()
print("Tool type: %s" % (tt))
if "Undefined" == tt:
tt = Path.Tool.getToolTypes(Path.Tool())[0]
if tt in self.ToolTypeImage:
self.editor = self.ToolTypeImage[tt](self)
else:
Path.Log.debug("weak supported ToolType = %s" % (tt))
self.editor = ToolEditorDefault(self)
self.editor.setupUI()
def updateTool(self):
Path.Log.track()
self.tool.Name = str(self.form.toolName.text())
self.tool.Material = self.getMaterial(self.form.toolMaterial.currentIndex())
self.tool.LengthOffset = FreeCAD.Units.parseQuantity(
self.form.toolLengthOffset.text()
)
self.editor.updateTool()
def refresh(self):
Path.Log.track()
self.form.blockSignals(True)
self.updateTool()
self.updateUI()
self.form.blockSignals(False)
def setupUI(self):
Path.Log.track()
self.updateUI()
self.form.toolName.editingFinished.connect(self.refresh)
self.form.toolType.currentIndexChanged.connect(self.updateToolType)

View File

@@ -1,515 +0,0 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * Copyright (c) 2014 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 *
# * *
# ***************************************************************************
from __future__ import print_function
from PySide import QtCore, QtGui
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import FreeCADGui
import Path
import Path.Tools.Controller as PathToolController
import Path.Tools.Gui.BitLibraryCmd as PathToolBitLibraryCmd
import PathScripts
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathToolEdit as PathToolEdit
import PathScripts.PathToolLibraryManager as ToolLibraryManager
import PathScripts.PathUtils as PathUtils
if False:
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
class EditorPanel:
def __init__(self, job, cb):
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolLibraryEditor.ui")
self.TLM = ToolLibraryManager.ToolLibraryManager()
listname = self.TLM.getCurrentTableName()
if listname:
self.loadToolTables()
self.job = job
self.cb = cb
def toolEditor(self, tool):
dialog = FreeCADGui.PySideUic.loadUi(":/panels/DlgToolEdit.ui")
editor = PathToolEdit.ToolEditor(tool, dialog.toolEditor, dialog)
editor.setupUI()
return editor
def accept(self):
pass
def reject(self):
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
def getFields(self):
pass
def setFields(self):
pass
def open(self):
pass
def getType(self, tooltype):
"gets a combobox index number for a given type or vice versa"
toolslist = Path.Tool.getToolTypes(Path.Tool())
if isinstance(tooltype, str):
if tooltype in toolslist:
return toolslist.index(tooltype)
else:
return 0
else:
return toolslist[tooltype]
def getMaterial(self, material):
"""gets a combobox index number for a given material or vice versa"""
matslist = Path.Tool.getToolMaterials(Path.Tool())
if isinstance(material, str):
if material in matslist:
return matslist.index(material)
else:
return 0
else:
return matslist[material]
def addTool(self):
"""adds new tool to the current tool table"""
tool = Path.Tool()
editor = self.toolEditor(tool)
r = editor.Parent.exec_()
if r:
editor.accept()
listname = self.TLM.getCurrentTableName()
self.TLM.addnew(listname, editor.Tool)
self.loadTable(listname)
def delete(self):
"""deletes the selected tool"""
listname = self.TLM.getCurrentTableName()
model = self.form.ToolsList.model()
for i in range(model.rowCount()):
item = model.item(i, 0)
if item.checkState():
t = model.index(i, 1)
self.TLM.delete(int(t.data()), listname)
self.loadTable(listname)
self.toolSelectionChanged()
def editTool(self, currItem):
"""load the tool edit dialog"""
if not currItem:
currItem = self.form.ToolsList.selectedIndexes()[1]
row = currItem.row()
value = currItem.sibling(row, 1).data()
listname = self.TLM.getCurrentTableName()
toolnum = int(value)
tool = self.TLM.getTool(listname, toolnum)
editor = self.toolEditor(tool)
r = editor.Parent.exec_()
if r:
editor.accept()
if self.TLM.updateTool(listname, toolnum, editor.Tool) is True:
self.loadTable(listname)
def moveUp(self):
"""moves a tool to a lower number, if possible"""
item = self.form.ToolsList.selectedIndexes()[1].data()
if item:
number = int(item)
listname = self.TLM.getCurrentTableName()
success, newNum = self.TLM.moveup(number, listname)
if success:
self.loadTable(listname)
self.updateSelection(newNum)
def moveDown(self):
"""moves a tool to a higher number, if possible"""
item = self.form.ToolsList.selectedIndexes()[1].data()
if item:
number = int(item)
listname = self.TLM.getCurrentTableName()
success, newNum = self.TLM.movedown(number, listname)
if success:
self.loadTable(listname)
self.updateSelection(newNum)
def duplicate(self):
"""duplicated the selected tool in the current tool table"""
item = self.form.ToolsList.selectedIndexes()[1].data()
if item:
number = int(item)
listname = self.TLM.getCurrentTableName()
success, newNum = self.TLM.duplicate(number, listname)
if success:
self.loadTable(listname)
self.updateSelection(newNum)
def updateSelection(self, number):
"""update the tool list selection to track moves"""
model = self.form.ToolsList.model()
for i in range(model.rowCount()):
if int(model.index(i, 1).data()) == number:
self.form.ToolsList.selectRow(i)
self.form.ToolsList.model().item(i, 0).setCheckState(QtCore.Qt.Checked)
return
def importFile(self):
"""imports a tooltable from a file"""
filename = QtGui.QFileDialog.getOpenFileName(
self.form,
translate("Path_ToolTable", "Open tooltable"),
None,
"{};;{};;{}".format(
self.TLM.TooltableTypeJSON,
self.TLM.TooltableTypeXML,
self.TLM.TooltableTypeHeekscad,
),
)
if filename[0]:
listname = self.TLM.getNextToolTableName()
if self.TLM.read(filename, listname):
self.loadToolTables()
def exportFile(self):
"""export a tooltable to a file"""
filename = QtGui.QFileDialog.getSaveFileName(
self.form,
translate("Path_ToolTable", "Save tooltable"),
None,
"{};;{};;{}".format(
self.TLM.TooltableTypeJSON,
self.TLM.TooltableTypeXML,
self.TLM.TooltableTypeLinuxCNC,
),
)
if filename[0]:
listname = self.TLM.getCurrentTableName()
self.TLM.write(filename, listname)
def toolSelectionChanged(self, index=None):
"""updates the ui when tools are selected"""
if index:
self.form.ToolsList.selectRow(index.row())
self.form.btnCopyTools.setEnabled(False)
self.form.ButtonDelete.setEnabled(False)
self.form.ButtonUp.setEnabled(False)
self.form.ButtonDown.setEnabled(False)
self.form.ButtonEdit.setEnabled(False)
self.form.ButtonDuplicate.setEnabled(False)
model = self.form.ToolsList.model()
checkCount = 0
checkList = []
for i in range(model.rowCount()):
item = model.item(i, 0)
if item.checkState():
checkCount += 1
checkList.append(i)
self.form.btnCopyTools.setEnabled(True)
# only allow moving or deleting a single tool at a time.
if checkCount == 1:
# make sure the row is highlighted when the check box gets ticked
self.form.ToolsList.selectRow(checkList[0])
self.form.ButtonDelete.setEnabled(True)
self.form.ButtonUp.setEnabled(True)
self.form.ButtonDown.setEnabled(True)
self.form.ButtonEdit.setEnabled(True)
self.form.ButtonDuplicate.setEnabled(True)
if len(PathUtils.GetJobs()) == 0:
self.form.btnCopyTools.setEnabled(False)
def copyTools(self):
"""copy selected tool"""
tools = []
model = self.form.ToolsList.model()
for i in range(model.rowCount()):
item = model.item(i, 0)
if item.checkState():
item = model.index(i, 1)
tools.append(item.data())
if len(tools) == 0:
return
targets = self.TLM.getJobList()
currList = self.TLM.getCurrentTableName()
for target in targets:
if target == currList:
targets.remove(target)
if len(targets) == 0:
FreeCAD.Console.PrintWarning("No Path Jobs in current document")
return
elif len(targets) == 1:
targetlist = targets[0]
else:
form = FreeCADGui.PySideUic.loadUi(":/panels/DlgToolCopy.ui")
form.cboTarget.addItems(targets)
r = form.exec_()
if r is False:
return None
else:
targetlist = form.cboTarget.currentText()
for toolnum in tools:
tool = self.TLM.getTool(currList, int(toolnum))
Path.Log.debug("tool: {}, toolnum: {}".format(tool, toolnum))
if self.job:
label = "T{}: {}".format(toolnum, tool.Name)
tc = PathToolController.Create(
label, tool=tool, toolNumber=int(toolnum)
)
self.job.Proxy.addToolController(tc)
else:
for job in FreeCAD.ActiveDocument.findObjects("Path::Feature"):
if (
isinstance(job.Proxy, PathScripts.PathJob.ObjectJob)
and job.Label == targetlist
):
label = "T{}: {}".format(toolnum, tool.Name)
tc = PathToolController.Create(
label, tool=tool, toolNumber=int(toolnum)
)
job.Proxy.addToolController(tc)
if self.cb:
self.cb()
FreeCAD.ActiveDocument.recompute()
def tableSelected(self, index):
"""loads the tools for the selected tool table"""
name = self.form.TableList.itemWidget(
self.form.TableList.itemFromIndex(index)
).getTableName()
self.loadTable(name)
def loadTable(self, name):
"""loads the tools for the selected tool table"""
tooldata = self.TLM.getTools(name)
if tooldata:
self.form.ToolsList.setModel(tooldata)
self.form.ToolsList.resizeColumnsToContents()
self.form.ToolsList.horizontalHeader().setResizeMode(
self.form.ToolsList.model().columnCount() - 1, QtGui.QHeaderView.Stretch
)
self.setCurrentToolTableByName(name)
def addNewToolTable(self):
"""adds new tool to selected tool table"""
name = self.TLM.addNewToolTable()
self.loadToolTables()
self.loadTable(name)
def loadToolTables(self):
"""Load list of available tool tables"""
self.form.TableList.clear()
model = self.form.ToolsList.model()
if model:
model.clear()
if len(self.TLM.getToolTables()) > 0:
for table in self.TLM.getToolTables():
listWidgetItem = QtGui.QListWidgetItem()
listItem = ToolTableListWidgetItem(self.TLM)
listItem.setTableName(table.Name)
listItem.setIcon(QtGui.QPixmap(":/icons/Path_ToolTable.svg"))
listItem.toolMoved.connect(self.reloadReset)
listWidgetItem.setSizeHint(QtCore.QSize(0, 40))
self.form.TableList.addItem(listWidgetItem)
self.form.TableList.setItemWidget(listWidgetItem, listItem)
# Load the first tooltable
self.loadTable(self.TLM.getCurrentTableName())
def reloadReset(self):
"""reloads the current tooltable"""
name = self.TLM.getCurrentTableName()
self.loadTable(name)
def setCurrentToolTableByName(self, name):
"""get the current tool table"""
item = self.getToolTableByName(name)
if item:
self.form.TableList.setCurrentItem(item)
def getToolTableByName(self, name):
"""returns the listWidgetItem for the selected name"""
for i in range(self.form.TableList.count()):
tableName = self.form.TableList.itemWidget(
self.form.TableList.item(i)
).getTableName()
if tableName == name:
return self.form.TableList.item(i)
return False
def removeToolTable(self):
"""delete the selected tool table"""
self.TLM.deleteToolTable()
self.loadToolTables()
def renameTable(self):
"""provides dialog for new tablename and renames the selected tool table"""
name = self.TLM.getCurrentTableName()
newName, ok = QtGui.QInputDialog.getText(
None,
translate("Path_ToolTable", "Rename Tooltable"),
translate("Path_ToolTable", "Enter Name:"),
QtGui.QLineEdit.Normal,
name,
)
if ok and newName:
index = self.form.TableList.indexFromItem(
self.getToolTableByName(name)
).row()
reloadTables = self.TLM.renameToolTable(newName, index)
if reloadTables:
self.loadToolTables()
self.loadTable(newName)
def getStandardButtons(self):
return int(QtGui.QDialogButtonBox.Ok)
def setupUi(self):
# Connect Signals and Slots
self.form.ButtonNewTool.clicked.connect(self.addTool)
self.form.ButtonImport.clicked.connect(self.importFile)
self.form.ButtonExport.clicked.connect(self.exportFile)
self.form.ButtonDown.clicked.connect(self.moveDown)
self.form.ButtonUp.clicked.connect(self.moveUp)
self.form.ButtonDelete.clicked.connect(self.delete)
self.form.ButtonEdit.clicked.connect(self.editTool)
self.form.ButtonDuplicate.clicked.connect(self.duplicate)
self.form.btnCopyTools.clicked.connect(self.copyTools)
self.form.ToolsList.doubleClicked.connect(self.editTool)
self.form.ToolsList.clicked.connect(self.toolSelectionChanged)
self.form.TableList.clicked.connect(self.tableSelected)
self.form.TableList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.form.TableList.itemChanged.connect(self.renameTable)
self.form.ButtonAddToolTable.clicked.connect(self.addNewToolTable)
self.form.ButtonAddToolTable.setToolTip(
translate("Path_ToolTable", "Add New Tool Table")
)
self.form.ButtonRemoveToolTable.clicked.connect(self.removeToolTable)
self.form.ButtonRemoveToolTable.setToolTip(
translate("Path_ToolTable", "Delete Selected Tool Table")
)
self.form.ButtonRenameToolTable.clicked.connect(self.renameTable)
self.form.ButtonRenameToolTable.setToolTip(
translate("Path_ToolTable", "Rename Selected Tool Table")
)
self.setFields()
class ToolTableListWidgetItem(QtGui.QWidget):
toolMoved = QtCore.Signal()
def __init__(self, TLM):
super(ToolTableListWidgetItem, self).__init__()
self.tlm = TLM
self.setAcceptDrops(True)
self.mainLayout = QtGui.QHBoxLayout()
self.iconQLabel = QtGui.QLabel()
self.tableNameLabel = QtGui.QLabel()
self.mainLayout.addWidget(self.iconQLabel, 0)
self.mainLayout.addWidget(self.tableNameLabel, 1)
self.setLayout(self.mainLayout)
def setTableName(self, text):
self.tableNameLabel.setText(text)
def getTableName(self):
return self.tableNameLabel.text()
def setIcon(self, icon):
icon = icon.scaled(24, 24)
self.iconQLabel.setPixmap(icon)
def dragEnterEvent(self, e):
currentToolTable = self.tlm.getCurrentTableName()
thisToolTable = self.getTableName()
if not currentToolTable == thisToolTable:
e.accept()
else:
e.ignore()
def dropEvent(self, e):
selectedTools = e.source().selectedIndexes()
if selectedTools:
toolData = selectedTools[1].data()
if toolData:
self.tlm.moveToTable(int(toolData), self.getTableName())
self.toolMoved.emit()
class CommandToolLibraryEdit:
def __init__(self):
pass
def edit(self, job=None, cb=None):
if PathPreferences.toolsUseLegacyTools():
editor = EditorPanel(job, cb)
editor.setupUi()
editor.form.exec_()
else:
if PathToolBitLibraryCmd.CommandToolBitLibraryLoad.Execute(job):
if cb:
cb()
def GetResources(self):
return {
"Pixmap": "Path_ToolTable",
"MenuText": QT_TRANSLATE_NOOP("Path_ToolTable", "Tool Manager"),
"Accel": "P, T",
"ToolTip": QT_TRANSLATE_NOOP("Path_ToolTable", "Tool Manager"),
}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def Activated(self):
self.edit()
if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand("Path_ToolLibraryEdit", CommandToolLibraryEdit())

View File

@@ -1,561 +0,0 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * Copyright (c) 2014 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 *
# * *
# ***************************************************************************
from __future__ import print_function
import FreeCAD
import Path
import PathScripts
import PathScripts.PathUtil as PathUtil
import json
import os
import xml.sax
from PySide import QtGui
if False:
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
# Tooltable XML readers
class FreeCADTooltableHandler(xml.sax.ContentHandler):
# http://www.tutorialspoint.com/python/python_xml_processing.htm
def __init__(self):
xml.sax.ContentHandler.__init__(self)
self.tooltable = None
self.tool = None
self.number = None
# Call when an element is found
def startElement(self, name, attrs):
if name == "Tooltable":
self.tooltable = Path.Tooltable()
elif name == "Toolslot":
self.number = int(attrs["number"])
elif name == "Tool":
self.tool = Path.Tool()
self.tool.Name = str(attrs["name"])
self.tool.ToolType = str(attrs["type"])
self.tool.Material = str(attrs["mat"])
# for some reason without the following line I get an error
# print attrs["diameter"]
self.tool.Diameter = float(attrs["diameter"])
self.tool.LengthOffset = float(attrs["length"])
self.tool.FlatRadius = float(attrs["flat"])
self.tool.CornerRadius = float(attrs["corner"])
self.tool.CuttingEdgeAngle = float(attrs["angle"])
self.tool.CuttingEdgeHeight = float(attrs["height"])
# Call when an elements ends
def endElement(self, name):
if name == "Toolslot":
if self.tooltable and self.tool and self.number:
self.tooltable.setTool(self.number, self.tool)
self.number = None
self.tool = None
class HeeksTooltableHandler(xml.sax.ContentHandler):
def __init__(self):
xml.sax.ContentHandler.__init__(self)
self.tooltable = Path.Tooltable()
self.tool = None
self.number = None
# Call when an element is found
def startElement(self, name, attrs):
if name == "Tool":
self.tool = Path.Tool()
self.number = int(attrs["tool_number"])
self.tool.Name = str(attrs["title"])
elif name == "params":
t = str(attrs["type"])
if t == "drill":
self.tool.ToolType = "Drill"
elif t == "center_drill_bit":
self.tool.ToolType = "CenterDrill"
elif t == "end_mill":
self.tool.ToolType = "EndMill"
elif t == "slot_cutter":
self.tool.ToolType = "SlotCutter"
elif t == "ball_end_mill":
self.tool.ToolType = "BallEndMill"
elif t == "chamfer":
self.tool.ToolType = "Chamfer"
elif t == "engraving_bit":
self.tool.ToolType = "Engraver"
m = str(attrs["material"])
if m == "0":
self.tool.Material = "HighSpeedSteel"
elif m == "1":
self.tool.Material = "Carbide"
# for some reason without the following line I get an error
# print attrs["diameter"]
self.tool.Diameter = float(attrs["diameter"])
self.tool.LengthOffset = float(attrs["tool_length_offset"])
self.tool.FlatRadius = float(attrs["flat_radius"])
self.tool.CornerRadius = float(attrs["corner_radius"])
self.tool.CuttingEdgeAngle = float(attrs["cutting_edge_angle"])
self.tool.CuttingEdgeHeight = float(attrs["cutting_edge_height"])
# Call when an elements ends
def endElement(self, name):
if name == "Tool":
if self.tooltable and self.tool and self.number:
self.tooltable.setTool(self.number, self.tool)
self.number = None
self.tool = None
class ToolLibraryManager:
"""
The Tool Library is a list of individual tool tables. Each
Tool Table can contain n tools. The tool library will be persisted to user
preferences and all or part of the library can be exported to other formats
"""
TooltableTypeJSON = translate("PathToolLibraryManager", "Tooltable JSON (*.json)")
TooltableTypeXML = translate("PathToolLibraryManager", "Tooltable XML (*.xml)")
TooltableTypeHeekscad = translate(
"PathToolLibraryManager", "HeeksCAD tooltable (*.tooltable)"
)
TooltableTypeLinuxCNC = translate(
"PathToolLibraryManager", "LinuxCNC tooltable (*.tbl)"
)
PreferenceMainLibraryXML = "ToolLibrary"
PreferenceMainLibraryJSON = "ToolLibrary-Main"
def __init__(self):
self.prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
self.toolTables = []
self.currentTableName = None
self.loadToolTables()
def getToolTables(self):
"""Return tool table list"""
return self.toolTables
def getCurrentTableName(self):
"""return the name of the currently loaded tool table"""
return self.currentTableName
def getCurrentTable(self):
"""returns an object of the current tool table"""
return self.getTableFromName(self.currentTableName)
def getTableFromName(self, name):
"""get the tool table object from the name"""
for table in self.toolTables:
if table.Name == name:
return table
def getNextToolTableName(self, tableName="Tool Table"):
"""get a unique name for a new tool table"""
iter = 1
tempName = tableName[-2:]
if tempName[0] == "-" and tempName[-1].isdigit():
tableName = tableName[:-2]
while any(
table.Name == tableName + "-" + str(iter) for table in self.toolTables
):
iter += 1
return tableName + "-" + str(iter)
def addNewToolTable(self):
"""creates a new tool table"""
tt = Path.Tooltable()
tt.Version = 1
name = self.getNextToolTableName()
tt.Name = name
self.toolTables.append(tt)
self.saveMainLibrary()
return name
def deleteToolTable(self):
"""deletes the selected tool table"""
if len(self.toolTables):
index = next(
(
index
for (index, d) in enumerate(self.toolTables)
if d.Name == self.currentTableName
),
None,
)
self.toolTables.pop(index)
self.saveMainLibrary()
def renameToolTable(self, newName, index):
"""renames a tool table with the new name"""
currentTableName = self.toolTables[index].Name
if newName == currentTableName:
Path.Log.error(translate("PathToolLibraryManager", "Tool Table Same Name"))
return False
if newName in self.toolTables:
Path.Log.error(translate("PathToolLibraryManager", "Tool Table Name Exists"))
return False
tt = self.getTableFromName(currentTableName)
if tt:
tt.Name = newName
self.saveMainLibrary()
return True
def templateAttrs(self):
"""gets the tool table arributes"""
toolTables = []
for tt in self.toolTables:
tableData = {}
tableData["Version"] = 1
tableData["TableName"] = tt.Name
toolData = {}
for tool in tt.Tools:
toolData[tool] = tt.Tools[tool].templateAttrs()
tableData["Tools"] = toolData
toolTables.append(tableData)
return toolTables
def tooltableFromAttrs(self, stringattrs):
if stringattrs.get("Version") and 1 == int(stringattrs["Version"]):
tt = Path.Tooltable()
tt.Version = 1
tt.Name = self.getNextToolTableName()
if stringattrs.get("Version"):
tt.Version = stringattrs.get("Version")
if stringattrs.get("TableName"):
tt.Name = stringattrs.get("TableName")
if any(table.Name == tt.Name for table in self.toolTables):
tt.Name = self.getNextToolTableName(tt.Name)
for key, attrs in PathUtil.keyValueIter(stringattrs["Tools"]):
tool = Path.Tool()
tool.Name = str(attrs["name"])
tool.ToolType = str(attrs["tooltype"])
tool.Material = str(attrs["material"])
tool.Diameter = float(attrs["diameter"])
tool.LengthOffset = float(attrs["lengthOffset"])
tool.FlatRadius = float(attrs["flatRadius"])
tool.CornerRadius = float(attrs["cornerRadius"])
tool.CuttingEdgeAngle = float(attrs["cuttingEdgeAngle"])
tool.CuttingEdgeHeight = float(attrs["cuttingEdgeHeight"])
tt.setTool(int(key), tool)
return tt
else:
Path.Log.error(
translate(
"PathToolLibraryManager",
"Unsupported Path tooltable template version %s",
)
% stringattrs.get("Version")
)
return None
def loadToolTables(self):
"""loads the tool tables from the stored data"""
self.toolTables = []
self.currentTableName = ""
def addTable(tt):
if tt:
self.toolTables.append(tt)
else:
Path.Log.error(
translate("PathToolLibraryManager", "Unsupported Path tooltable")
)
prefString = self.prefs.GetString(self.PreferenceMainLibraryJSON, "")
if not prefString:
return
prefsData = json.loads(prefString)
if isinstance(prefsData, dict):
tt = self.tooltableFromAttrs(prefsData)
addTable(tt)
if isinstance(prefsData, list):
for table in prefsData:
tt = self.tooltableFromAttrs(table)
addTable(tt)
if len(self.toolTables):
self.currentTableName = self.toolTables[0].Name
def saveMainLibrary(self):
"""Persists the permanent library to FreeCAD user preferences"""
tmpstring = json.dumps(self.templateAttrs())
self.prefs.SetString(self.PreferenceMainLibraryJSON, tmpstring)
self.loadToolTables()
return True
def getJobList(self):
"""Builds the list of all Tool Table lists"""
tablelist = []
for o in FreeCAD.ActiveDocument.Objects:
if hasattr(o, "Proxy"):
if isinstance(o.Proxy, PathScripts.PathJob.ObjectJob):
tablelist.append(o.Label)
return tablelist
def getTool(self, listname, toolnum):
"""gets the tool object"""
tt = self.getTableFromName(listname)
return tt.getTool(toolnum)
def getTools(self, tablename):
"""returns the tool data for a given table"""
tooldata = []
tableExists = any(table.Name == tablename for table in self.toolTables)
if tableExists:
self.currentTableName = tablename
else:
return None
tt = self.getTableFromName(tablename)
headers = ["", "Tool Num.", "Name", "Tool Type", "Diameter"]
model = QtGui.QStandardItemModel()
model.setHorizontalHeaderLabels(headers)
def unitconv(ivalue):
val = FreeCAD.Units.Quantity(ivalue, FreeCAD.Units.Length)
displayed_val = (
val.UserString
) # just the displayed value-not the internal one
return displayed_val
if tt:
if len(tt.Tools) == 0:
tooldata.append([])
for number, t in PathUtil.keyValueIter(tt.Tools):
itemcheck = QtGui.QStandardItem()
itemcheck.setCheckable(True)
itemNumber = QtGui.QStandardItem(str(number))
itemName = QtGui.QStandardItem(t.Name)
itemToolType = QtGui.QStandardItem(t.ToolType)
itemDiameter = QtGui.QStandardItem(unitconv(t.Diameter))
row = [itemcheck, itemNumber, itemName, itemToolType, itemDiameter]
model.appendRow(row)
return model
# methods for importing and exporting
def read(self, filename, listname):
"imports a tooltable from a file"
importedTables = []
try:
fileExtension = os.path.splitext(filename[0])[1].lower()
xmlHandler = None
if fileExtension == ".tooltable":
xmlHandler = HeeksTooltableHandler()
if fileExtension == ".xml":
xmlHandler = FreeCADTooltableHandler()
if xmlHandler:
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
parser.setContentHandler(xmlHandler)
parser.parse(PathUtil.toUnicode(filename[0]))
if not xmlHandler.tooltable:
return None
ht = xmlHandler.tooltable
else:
with open(PathUtil.toUnicode(filename[0]), "rb") as fp:
tableData = json.load(fp)
if isinstance(tableData, dict):
ht = self.tooltableFromAttrs(tableData)
if ht:
importedTables.append(ht)
if isinstance(tableData, list):
for table in tableData:
ht = self.tooltableFromAttrs(table)
if ht:
importedTables.append(ht)
if importedTables:
for tt in importedTables:
self.toolTables.append(tt)
self.saveMainLibrary()
return True
else:
return False
except Exception as e:
print("could not parse file", e)
def write(self, filename, listname):
"exports the tooltable to a file"
tt = self.getTableFromName(listname)
if tt:
try:
def openFileWithExtension(name, ext):
fext = os.path.splitext(name)[1].lower()
if fext != ext:
name = "{}{}".format(name, ext)
return (open(PathUtil.toUnicode(name), "w"), name)
if filename[1] == self.TooltableTypeXML:
fp, fname = openFileWithExtension(filename[0], ".xml")
fp.write('<?xml version="1.0" encoding="UTF-8"?>\n')
fp.write(tt.Content)
elif filename[1] == self.TooltableTypeLinuxCNC:
fp, fname = openFileWithExtension(filename[0], ".tbl")
for key in tt.Tools:
t = tt.Tools[key]
fp.write(
"T{0} P{0} Y{1} Z{2} A{3} B{4} C{5} U{6} V{7} W{8} D{9} I{10} J{11} Q{12} ;{13}\n".format(
key,
0,
t.LengthOffset,
0,
0,
0,
0,
0,
0,
t.Diameter,
0,
0,
0,
t.Name,
)
)
else:
fp, fname = openFileWithExtension(filename[0], ".json")
json.dump(self.templateAttrs(), fp, sort_keys=True, indent=2)
fp.close()
print("Written ", PathUtil.toUnicode(fname))
except Exception as e:
print("Could not write file:", e)
def addnew(self, listname, tool, position=None):
"adds a new tool at the end of the table"
tt = self.getTableFromName(listname)
if not tt:
tt = Path.Tooltable()
if position is None:
tt.addTools(tool)
newID = list(tt.Tools)[-1]
else:
tt.setTool(position, tool)
newID = position
if listname == self.getCurrentTableName():
self.saveMainLibrary()
return newID
def updateTool(self, listname, toolnum, tool):
"""updates tool data"""
tt = self.getTableFromName(listname)
tt.deleteTool(toolnum)
tt.setTool(toolnum, tool)
if listname == self.getCurrentTableName():
return self.saveMainLibrary()
return True
def moveup(self, number, listname):
"moves a tool to a lower number, if possible"
target = number - 1
if number < 2:
return False, target
target = number - 1
tt = self.getTableFromName(listname)
t1 = tt.getTool(number).copy()
tt.deleteTool(number)
if target in tt.Tools.keys():
t2 = tt.getTool(target).copy()
tt.deleteTool(target)
tt.setTool(number, t2)
tt.setTool(target, t1)
if listname == self.getCurrentTableName():
self.saveMainLibrary()
return True, target
def movedown(self, number, listname):
"moves a tool to a higher number, if possible"
tt = self.getTableFromName(listname)
target = number + 1
t1 = tt.getTool(number).copy()
tt.deleteTool(number)
if target in tt.Tools.keys():
t2 = tt.getTool(target).copy()
tt.deleteTool(target)
tt.setTool(number, t2)
tt.setTool(target, t1)
if listname == self.getCurrentTableName():
self.saveMainLibrary()
return True, target
def duplicate(self, number, listname):
"""duplicates the selected tool in the selected tool table"""
tt = self.getTableFromName(listname)
tool = tt.getTool(number).copy()
tt.addTools(tool)
newID = list(tt.Tools)[-1]
if listname == self.getCurrentTableName():
self.saveMainLibrary()
return True, newID
def moveToTable(self, number, listname):
"""Moves the tool to selected tool table"""
fromTable = self.getTableFromName(self.getCurrentTableName())
toTable = self.getTableFromName(listname)
tool = fromTable.getTool(number).copy()
toTable.addTools(tool)
fromTable.deleteTool(number)
def delete(self, number, listname):
"""deletes a tool from the current list"""
tt = self.getTableFromName(listname)
tt.deleteTool(number)
if listname == self.getCurrentTableName():
self.saveMainLibrary()
return True

View File

@@ -541,10 +541,6 @@ def guessDepths(objshape, subs=None):
def drillTipLength(tool):
"""returns the length of the drillbit tip."""
if isinstance(tool, Path.Tool):
Path.Log.error(translate("Path", "Legacy Tools not supported"))
return 0.0
if not hasattr(tool, "TipAngle"):
Path.Log.error(translate("Path", "Selected tool is not a drill"))
return 0.0

View File

@@ -22,7 +22,6 @@
#include "PreCompiled.h"
#include <Mod/Path/App/ToolPy.h>
#include <Base/PlacementPy.h>
#include <Base/VectorPy.h>
#include <Mod/Part/App/TopoShapePy.h>

View File

@@ -130,40 +130,6 @@ G0 Z0.500000
p.setFromGCode(lines)
self.assertEqual(p.toGCode(), output)
def test20(self):
"""Test Path Tool and ToolTable object core functionality"""
t1 = Path.Tool()
self.assertIsInstance(t1, Path.Tool)
t1.Name = "12.7mm Drill Bit"
self.assertEqual(t1.Name, "12.7mm Drill Bit")
self.assertEqual(t1.ToolType, "Undefined")
t1.ToolType = "Drill"
self.assertEqual(t1.ToolType, "Drill")
t1.Diameter = 12.7
t1.LengthOffset = 127
t1.CuttingEdgeAngle = 59
t1.CuttingEdgeHeight = 50.8
self.assertEqual(t1.Diameter, 12.7)
self.assertEqual(t1.LengthOffset, 127)
self.assertEqual(t1.CuttingEdgeAngle, 59)
self.assertEqual(t1.CuttingEdgeHeight, 50.8)
t2 = Path.Tool("my other tool", tooltype="EndMill", diameter=10)
table = Path.Tooltable()
self.assertIsInstance(table, Path.Tooltable)
table.addTools(t1)
table.addTools(t2)
self.assertEqual(len(table.Tools), 2)
# gcc7 build needs some special treatment (makes 1L out of a 1) ...
if str(table.Tools) != "{1L: Tool 12.7mm Drill Bit, 2L: Tool my other tool}":
self.assertEqual(
str(table.Tools), "{1: Tool 12.7mm Drill Bit, 2: Tool my other tool}"
)
def test50(self):
"""Test Path.Length calculation"""
commands = []

View File

@@ -22,16 +22,23 @@
import Path
import Path.Op.Deburr as PathDeburr
import Path.Tools.Bit as PathToolBit
import PathTests.PathTestUtils as PathTestUtils
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
# Path.Log.trackModule(Path.Log.thisModule())
class MockToolBit(object):
def __init__(self, name="t1", diameter=5.0):
self.Diameter = diameter
self.FlatRadius = 0
self.CuttingEdgeAngle = 60
class TestPathDeburr(PathTestUtils.PathTestBase):
def test00(self):
"""Verify chamfer depth and offset for an end mill."""
tool = Path.Tool()
tool = MockToolBit()
tool.Diameter = 20
tool.FlatRadius = 0
tool.CuttingEdgeAngle = 180
@@ -51,7 +58,7 @@ class TestPathDeburr(PathTestUtils.PathTestBase):
def test01(self):
"""Verify chamfer depth and offset for a 90 deg v-bit."""
tool = Path.Tool()
tool = MockToolBit()
tool.FlatRadius = 0
tool.CuttingEdgeAngle = 90
@@ -67,7 +74,7 @@ class TestPathDeburr(PathTestUtils.PathTestBase):
def test02(self):
"""Verify chamfer depth and offset for a 90 deg v-bit with non 0 flat radius."""
tool = Path.Tool()
tool = MockToolBit()
tool.FlatRadius = 0.3
tool.CuttingEdgeAngle = 90
@@ -83,7 +90,7 @@ class TestPathDeburr(PathTestUtils.PathTestBase):
def test03(self):
"""Verify chamfer depth and offset for a 60 deg v-bit with non 0 flat radius."""
tool = Path.Tool()
tool = MockToolBit()
tool.FlatRadius = 10
tool.CuttingEdgeAngle = 60

View File

@@ -23,6 +23,7 @@
import FreeCAD
import Part
import Path
import Path.Tools.Bit as PathToolBit
import Path.Tools.Controller as PathToolController
import PathFeedRate
import PathMachineState
@@ -32,6 +33,15 @@ import PathScripts.PathUtils as PathUtils
from PathTests.PathTestUtils import PathTestBase
def createTool(name="t1", diameter=1.75):
attrs = {
"shape": None,
"name": name,
"parameter": {"Diameter": diameter},
"attribute": [],
}
return PathToolBit.Factory.CreateFromAttrs(attrs, name)
class TestPathHelpers(PathTestBase):
def setUp(self):
self.doc = FreeCAD.newDocument("TestPathUtils")
@@ -48,7 +58,7 @@ class TestPathHelpers(PathTestBase):
def test00(self):
"""Test that FeedRate Helper populates horiz and vert feed rate based on TC"""
t = Path.Tool("test", "5.0")
t = createTool("test", 5.0)
tc = PathToolController.Create("TC0", t)
tc.VertRapid = 5
tc.HorizRapid = 10

View File

@@ -1,96 +0,0 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * Copyright (c) 2017 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 Path
from PathTests.PathTestUtils import PathTestBase
class TestPathTool(PathTestBase):
def test00(self):
"""Verify templateAttrs"""
name = "tool 1"
mat = "Carbide"
typ = "EndMill"
dia = 1.7
flat = 7.2
offset = 3.2
corner = 4
height = 45.3
angle = 118
tool = Path.Tool()
tool.Name = name
tool.ToolType = typ
tool.Material = mat
tool.Diameter = dia
tool.LengthOffset = offset
tool.FlatRadius = flat
tool.CornerRadius = corner
tool.CuttingEdgeAngle = angle
tool.CuttingEdgeHeight = height
attrs = tool.templateAttrs()
self.assertEqual(attrs["name"], name)
self.assertEqual(attrs["diameter"], dia)
self.assertEqual(attrs["material"], mat)
self.assertEqual(attrs["tooltype"], typ)
self.assertEqual(attrs["lengthOffset"], offset)
self.assertEqual(attrs["flatRadius"], flat)
self.assertEqual(attrs["cornerRadius"], corner)
self.assertEqual(attrs["cuttingEdgeAngle"], angle)
self.assertEqual(attrs["cuttingEdgeHeight"], height)
return tool
def test01(self):
"""Verify template roundtrip"""
t0 = self.test00()
t1 = Path.Tool()
t1.setFromTemplate(t0.templateAttrs())
self.assertEqual(t0.Name, t1.Name)
self.assertEqual(t0.ToolType, t1.ToolType)
self.assertEqual(t0.Material, t1.Material)
self.assertEqual(t0.Diameter, t1.Diameter)
self.assertEqual(t0.LengthOffset, t1.LengthOffset)
self.assertEqual(t0.FlatRadius, t1.FlatRadius)
self.assertEqual(t0.CornerRadius, t1.CornerRadius)
self.assertEqual(t0.CuttingEdgeAngle, t1.CuttingEdgeAngle)
self.assertEqual(t0.CuttingEdgeHeight, t1.CuttingEdgeHeight)
def test02(self):
"""Verify template dictionary construction"""
t0 = self.test00()
t1 = Path.Tool(t0.templateAttrs())
self.assertEqual(t0.Name, t1.Name)
self.assertEqual(t0.ToolType, t1.ToolType)
self.assertEqual(t0.Material, t1.Material)
self.assertEqual(t0.Diameter, t1.Diameter)
self.assertEqual(t0.LengthOffset, t1.LengthOffset)
self.assertEqual(t0.FlatRadius, t1.FlatRadius)
self.assertEqual(t0.CornerRadius, t1.CornerRadius)
self.assertEqual(t0.CuttingEdgeAngle, t1.CuttingEdgeAngle)
self.assertEqual(t0.CuttingEdgeHeight, t1.CuttingEdgeHeight)

View File

@@ -37,8 +37,6 @@ class TestPathToolController(PathTestBase):
FreeCAD.closeDocument(self.doc.Name)
def createTool(self, name="t1", diameter=1.75):
if PathPreferences.toolsUseLegacyTools():
return Path.Tool(name=name, diameter=diameter)
attrs = {
"shape": None,
"name": name,
@@ -73,10 +71,7 @@ class TestPathToolController(PathTestBase):
self.assertEqual(attrs["hrapid"], "28.0 mm/s")
self.assertEqual(attrs["dir"], "Reverse")
self.assertEqual(attrs["speed"], 12000)
if PathPreferences.toolsUseLegacyTools():
self.assertEqual(attrs["tool"], t.templateAttrs())
else:
self.assertEqual(attrs["tool"], t.Proxy.templateAttrs(t))
self.assertEqual(attrs["tool"], t.Proxy.templateAttrs(t))
return tc

View File

@@ -1,68 +0,0 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * Copyright (c) 2017 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 Path
from PathTests.PathTestUtils import PathTestBase
class TestPathTooltable(PathTestBase):
def test00(self):
"""Verify templateAttrs"""
t = Path.Tool(name="t", diameter=1.2)
u = Path.Tool(name="u", diameter=3.4)
v = Path.Tool(name="v", diameter=5.6)
tt = Path.Tooltable()
tt.setTool(3, t)
tt.setTool(1, u)
tt.addTools(v)
attrs = tt.templateAttrs()
self.assertEqual(3, len(attrs))
self.assertTrue(1 in attrs)
self.assertFalse(2 in attrs)
self.assertTrue(3 in attrs)
self.assertTrue(4 in attrs)
self.assertEqual(attrs[1]["name"], "u")
self.assertEqual(attrs[1]["diameter"], 3.4)
self.assertEqual(attrs[3]["name"], "t")
self.assertEqual(attrs[3]["diameter"], 1.2)
self.assertEqual(attrs[4]["name"], "v")
self.assertEqual(attrs[4]["diameter"], 5.6)
return tt
def test01(self):
"""Verify setFromTemplate roundtrip."""
tt = self.test00()
uu = Path.Tooltable()
uu.setFromTemplate(tt.templateAttrs())
self.assertEqual(tt.Content, uu.Content)
def test02(self):
"""Verify template constructor."""
tt = self.test00()
uu = Path.Tooltable(tt.templateAttrs())
self.assertEqual(tt.Content, uu.Content)

View File

@@ -50,11 +50,9 @@ from PathTests.TestPathSetupSheet import TestPathSetupSheet
from PathTests.TestPathStock import TestPathStock
from PathTests.TestPathThreadMilling import TestPathThreadMilling
from PathTests.TestPathThreadMillingGenerator import TestPathThreadMillingGenerator
from PathTests.TestPathTool import TestPathTool
from PathTests.TestPathToolBit import TestPathToolBit
from PathTests.TestPathToolChangeGenerator import TestPathToolChangeGenerator
from PathTests.TestPathToolController import TestPathToolController
from PathTests.TestPathTooltable import TestPathTooltable
from PathTests.TestPathUtil import TestPathUtil
from PathTests.TestPathVcarve import TestPathVcarve
from PathTests.TestPathVoronoi import TestPathVoronoi
@@ -94,11 +92,9 @@ False if TestPathSetupSheet.__name__ else True
False if TestPathStock.__name__ else True
False if TestPathThreadMilling.__name__ else True
False if TestPathThreadMillingGenerator.__name__ else True
False if TestPathTool.__name__ else True
False if TestPathToolBit.__name__ else True
False if TestPathToolChangeGenerator.__name__ else True
False if TestPathToolController.__name__ else True
False if TestPathTooltable.__name__ else True
False if TestPathUtil.__name__ else True
False if TestPathVcarve.__name__ else True
False if TestPathVoronoi.__name__ else True