Removed deprecated and obsolete Path.Tool and Path.Tooltable
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -633,16 +633,6 @@
|
||||
<string>Tools</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toolsUseLegacy">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Legacy Tools have no accurate shape representation and are stored in the user preferences of FreeCAD.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Legacy Tools</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toolsAbsolutePaths">
|
||||
<property name="toolTip">
|
||||
|
||||
@@ -40,9 +40,6 @@
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
|
||||
#include <Mod/Path/App/Tooltable.h>
|
||||
|
||||
|
||||
using namespace PathGui;
|
||||
using namespace Gui;
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"):
|
||||
|
||||
@@ -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) ...
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -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())
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user