Merge pull request #7440 from mlampert/refactor/path-module-naming-cleanup

[PATH]: Refactor/path module naming cleanup
This commit is contained in:
sliptonic
2022-10-12 09:14:39 -05:00
committed by GitHub
244 changed files with 3987 additions and 8778 deletions

View File

@@ -30,14 +30,8 @@
#include "CommandPy.h"
#include "Path.h"
#include "PathPy.h"
#include "Tool.h"
#include "Tooltable.h"
#include "ToolPy.h"
#include "TooltablePy.h"
#include "PropertyPath.h"
#include "FeaturePath.h"
#include "PropertyTool.h"
#include "PropertyTooltable.h"
#include "FeaturePathCompound.h"
#include "FeaturePathShape.h"
#include "AreaPy.h"
@@ -52,12 +46,12 @@
#include "VoronoiVertexPy.h"
namespace Path {
namespace PathApp {
extern PyObject* initModule();
}
/* Python entry */
PyMOD_INIT_FUNC(Path)
PyMOD_INIT_FUNC(PathApp)
{
// load dependent module
try {
@@ -68,7 +62,7 @@ PyMOD_INIT_FUNC(Path)
PyMOD_Return(nullptr);
}
PyObject* pathModule = Path::initModule();
PyObject* pathModule = PathApp::initModule();
Base::Console().Log("Loading Path module... done\n");
Py::Object module(pathModule);
@@ -76,8 +70,6 @@ PyMOD_INIT_FUNC(Path)
// 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(Path)
// This function is responsible for adding inherited slots from a type's base class.
Path::Command ::init();
Path::Toolpath ::init();
Path::Tool ::init();
Path::Tooltable ::init();
Path::PropertyPath ::init();
Path::Feature ::init();
Path::FeaturePython ::init();
Path::PropertyTool ::init();
Path::PropertyTooltable ::init();
Path::FeatureCompound ::init();
Path::FeatureCompoundPython ::init();
Path::FeatureShape ::init();

View File

@@ -90,7 +90,7 @@
PyErr_SetString(Base::PyExc_FC_GeneralError,e); \
} throw Py::Exception();
namespace Path {
namespace PathApp {
class VoronoiModule : public Py::ExtensionModule<VoronoiModule>
{
public:
@@ -106,7 +106,7 @@ namespace Path {
VoronoiModule voronoi;
public:
Module() : Py::ExtensionModule<Module>("Path")
Module() : Py::ExtensionModule<Module>("PathApp")
{
add_varargs_method("write",&Module::write,
"write(object,filename): Exports a given path object to a GCode file"
@@ -162,7 +162,7 @@ namespace Path {
if (PyObject_TypeCheck(pObj, &(App::DocumentObjectPy::Type))) {
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(pObj)->getDocumentObjectPtr();
if (obj->getTypeId().isDerivedFrom(Base::Type::fromName("Path::Feature"))) {
const Toolpath& path = static_cast<Path::Feature*>(obj)->Path.getValue();
const Path::Toolpath& path = static_cast<Path::Feature*>(obj)->Path.getValue();
std::string gcode = path.toGCode();
Base::ofstream ofile(file);
ofile << gcode;
@@ -204,7 +204,7 @@ namespace Path {
std::stringstream buffer;
buffer << filestr.rdbuf();
std::string gcode = buffer.str();
Toolpath path;
Path::Toolpath path;
path.setFromGCode(gcode);
Path::Feature *object = static_cast<Path::Feature *>(pcDoc->addObject("Path::Feature",file.fileNamePure().c_str()));
object->Path.setValue(path);
@@ -222,14 +222,14 @@ namespace Path {
{
PyObject *pcObj;
char *name = "Path";
if (!PyArg_ParseTuple(args.ptr(), "O!|s", &(PathPy::Type), &pcObj, &name))
if (!PyArg_ParseTuple(args.ptr(), "O!|s", &(Path::PathPy::Type), &pcObj, &name))
throw Py::Exception();
try {
App::Document *pcDoc = App::GetApplication().getActiveDocument();
if (!pcDoc)
pcDoc = App::GetApplication().newDocument();
PathPy* pPath = static_cast<PathPy*>(pcObj);
Path::PathPy* pPath = static_cast<Path::PathPy*>(pcObj);
Path::Feature *pcFeature = static_cast<Path::Feature*>(pcDoc->addObject("Path::Feature", name));
Path::Toolpath* pa = pPath->getToolpathPtr();
if (!pa) {
@@ -313,7 +313,7 @@ namespace Path {
}
ExpEdges.Next();
}
return Py::asObject(new PathPy(new Path::Toolpath(result)));
return Py::asObject(new Path::PathPy(new Path::Toolpath(result)));
} else {
throw Py::TypeError("the given shape must be a wire");
}
@@ -365,13 +365,13 @@ namespace Path {
try {
gp_Pnt pend;
std::unique_ptr<Toolpath> path(new Toolpath);
Area::toPath(*path,shapes,start?&pstart:nullptr, &pend,
std::unique_ptr<Path::Toolpath> path(new Path::Toolpath);
Path::Area::toPath(*path,shapes,start?&pstart:nullptr, &pend,
PARAM_PY_FIELDS(PARAM_FARG,AREA_PARAMS_PATH));
if (!Base::asBoolean(return_end))
return Py::asObject(new PathPy(path.release()));
return Py::asObject(new Path::PathPy(path.release()));
Py::Tuple tuple(2);
tuple.setItem(0, Py::asObject(new PathPy(path.release())));
tuple.setItem(0, Py::asObject(new Path::PathPy(path.release())));
tuple.setItem(1, Py::asObject(new Base::VectorPy(Base::Vector3d(pend.X(),pend.Y(),pend.Z()))));
return tuple;
} PATH_CATCH
@@ -419,8 +419,8 @@ namespace Path {
}
try {
bool need_arc_plane = arc_plane==Area::ArcPlaneAuto;
std::list<TopoDS_Shape> wires = Area::sortWires(shapes, start != nullptr, &pstart,
bool need_arc_plane = arc_plane == Path::Area::ArcPlaneAuto;
std::list<TopoDS_Shape> wires = Path::Area::sortWires(shapes, start != nullptr, &pstart,
&pend, nullptr, &arc_plane, PARAM_PY_FIELDS(PARAM_FARG,AREA_PARAMS_SORT));
Py::List list;
for(auto &wire : wires) {

View File

@@ -31,8 +31,6 @@ set(Path_LIBS
generate_from_xml(CommandPy)
generate_from_xml(PathPy)
generate_from_xml(ToolPy)
generate_from_xml(TooltablePy)
generate_from_xml(FeaturePathCompoundPy)
generate_from_xml(AreaPy)
generate_from_xml(FeatureAreaPy)
@@ -46,10 +44,6 @@ SET(Python_SRCS
CommandPyImp.cpp
PathPy.xml
PathPyImp.cpp
ToolPy.xml
ToolPyImp.cpp
TooltablePy.xml
TooltablePyImp.cpp
FeaturePathCompoundPy.xml
FeaturePathCompoundPyImp.cpp
AreaPy.xml
@@ -78,18 +72,10 @@ SET(Path_SRCS
Command.h
Path.cpp
Path.h
Tool.cpp
Tool.h
Tooltable.cpp
Tooltable.h
PropertyPath.cpp
PropertyPath.h
FeaturePath.cpp
FeaturePath.h
PropertyTool.cpp
PropertyTool.h
PropertyTooltable.cpp
PropertyTooltable.h
FeaturePathCompound.cpp
FeaturePathCompound.h
FeaturePathShape.cpp
@@ -163,7 +149,7 @@ if(FREECAD_USE_PCH)
endif(FREECAD_USE_PCH)
SET_BIN_DIR(Path Path /Mod/Path)
SET_BIN_DIR(Path PathApp /Mod/Path)
SET_PYTHON_PREFIX_SUFFIX(Path)
INSTALL(TARGETS Path DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

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

View File

@@ -1,75 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PROPERTYTOOL_H
#define PROPERTYTOOL_H
#include "Tool.h"
#include <App/Property.h>
namespace Path
{
/** The tool property class. */
class PathExport PropertyTool : public App::Property
{
TYPESYSTEM_HEADER();
public:
PropertyTool();
~PropertyTool();
/** @name Getter/setter */
//@{
/// set the part shape
void setValue(const Tool&);
/// get the part shape
const Tool &getValue(void) const;
//@}
/** @name Python interface */
//@{
PyObject* getPyObject(void);
void setPyObject(PyObject *value);
//@}
/** @name Save/restore */
//@{
void Save (Base::Writer &writer) const;
void Restore(Base::XMLReader &reader);
App::Property *Copy(void) const;
void Paste(const App::Property &from);
unsigned int getMemSize (void) const;
//@}
private:
Tool _Tool;
};
} //namespace Path
#endif // PROPERTYTOOL_H

View File

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

View File

@@ -1,75 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PROPERTYTOOLTABLE_H
#define PROPERTYTOOLTABLE_H
#include "Tooltable.h"
#include <App/Property.h>
namespace Path
{
/** The tooltable property class. */
class PathExport PropertyTooltable : public App::Property
{
TYPESYSTEM_HEADER();
public:
PropertyTooltable();
~PropertyTooltable();
/** @name Getter/setter */
//@{
/// set the part shape
void setValue(const Tooltable&);
/// get the part shape
const Tooltable &getValue(void) const;
//@}
/** @name Python interface */
//@{
PyObject* getPyObject(void);
void setPyObject(PyObject *value);
//@}
/** @name Save/restore */
//@{
void Save (Base::Writer &writer) const;
void Restore(Base::XMLReader &reader);
App::Property *Copy(void) const;
void Paste(const App::Property &from);
unsigned int getMemSize (void) const;
//@}
private:
Tooltable _Tooltable;
};
} //namespace Path
#endif // PROPERTYTOOLTABLE_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,8 +10,6 @@ set(Path_Scripts
Init.py
PathCommands.py
TestPathApp.py
PathMachineState.py
PathFeedRate.py
)
if(BUILD_GUI)
@@ -25,168 +23,210 @@ INSTALL(
Mod/Path
)
SET(PathPython_SRCS
Path/__init__.py
Path/Log.py
Path/Geom.py
Path/GuiInit.py
Path/Preferences.py
)
SET(PathPythonBase_SRCS
Path/Base/__init__.py
Path/Base//Drillable.py
Path/Base/MachineState.py
Path/Base/FeedRate.py
Path/Base/Property.py
Path/Base/PropertyBag.py
Path/Base/SetupSheet.py
Path/Base/SetupSheetOpPrototype.py
Path/Base/Util.py
)
SET(PathPythonBaseGui_SRCS
Path/Base/Gui/__init__.py
Path/Base/Gui/GetPoint.py
Path/Base/Gui/IconViewProvider.py
Path/Base/Gui/PreferencesAdvanced.py
Path/Base/Gui/PropertyBag.py
Path/Base/Gui/PropertyEditor.py
Path/Base/Gui/SetupSheet.py
Path/Base/Gui/SetupSheetOpPrototype.py
Path/Base/Gui/Util.py
)
SET(PathPythonDressup_SRCS
Path/Dressup/__init__.py
Path/Dressup/Utils.py
Path/Dressup/Boundary.py
Path/Dressup/Tags.py
)
SET(PathPythonDressupGui_SRCS
Path/Dressup/Gui/__init__.py
Path/Dressup/Gui/AxisMap.py
Path/Dressup/Gui/Dogbone.py
Path/Dressup/Gui/Dragknife.py
Path/Dressup/Gui/LeadInOut.py
Path/Dressup/Gui/Boundary.py
Path/Dressup/Gui/Preferences.py
Path/Dressup/Gui/RampEntry.py
Path/Dressup/Gui/Tags.py
Path/Dressup/Gui/TagPreferences.py
Path/Dressup/Gui/ZCorrect.py
)
SET(PathPythonMain_SRCS
Path/Main/__init__.py
Path/Main/Job.py
Path/Main/Stock.py
)
SET(PathPythonMainGui_SRCS
Path/Main/Gui/__init__.py
Path/Main/Gui/Camotics.py
Path/Main/Gui/Fixture.py
Path/Main/Gui/Inspect.py
Path/Main/Gui/Job.py
Path/Main/Gui/JobCmd.py
Path/Main/Gui/JobDlg.py
Path/Main/Gui/PreferencesJob.py
Path/Main/Gui/Sanity.py
Path/Main/Gui/Simulator.py
)
SET(PathPythonTools_SRCS
Path/Tool/__init__.py
Path/Tool/Bit.py
Path/Tool/Controller.py
)
SET(PathPythonToolsGui_SRCS
Path/Tool/Gui/__init__.py
Path/Tool/Gui/Bit.py
Path/Tool/Gui/BitCmd.py
Path/Tool/Gui/BitEdit.py
Path/Tool/Gui/BitLibraryCmd.py
Path/Tool/Gui/BitLibrary.py
Path/Tool/Gui/Controller.py
)
SET(PathPythonPost_SRCS
Path/Post/__init__.py
Path/Post/Command.py
Path/Post/Processor.py
Path/Post/Utils.py
Path/Post/UtilsArguments.py
Path/Post/UtilsExport.py
Path/Post/UtilsParse.py
)
SET(PathPythonPostScripts_SRCS
Path/Post/scripts/__init__.py
Path/Post/scripts/centroid_post.py
Path/Post/scripts/comparams_post.py
Path/Post/scripts/dxf_post.py
Path/Post/scripts/dynapath_post.py
Path/Post/scripts/example_pre.py
Path/Post/scripts/fablin_post.py
Path/Post/scripts/fanuc_post.py
Path/Post/scripts/gcode_pre.py
Path/Post/scripts/grbl_post.py
Path/Post/scripts/heidenhain_post.py
Path/Post/scripts/jtech_post.py
Path/Post/scripts/KineticNCBeamicon2_post.py
Path/Post/scripts/linuxcnc_post.py
Path/Post/scripts/mach3_mach4_post.py
Path/Post/scripts/marlin_post.py
Path/Post/scripts/nccad_post.py
Path/Post/scripts/opensbp_post.py
Path/Post/scripts/opensbp_pre.py
Path/Post/scripts/philips_post.py
Path/Post/scripts/refactored_centroid_post.py
Path/Post/scripts/refactored_grbl_post.py
Path/Post/scripts/refactored_linuxcnc_post.py
Path/Post/scripts/refactored_mach3_mach4_post.py
Path/Post/scripts/refactored_test_post.py
Path/Post/scripts/rml_post.py
Path/Post/scripts/rrf_post.py
Path/Post/scripts/slic3r_pre.py
Path/Post/scripts/smoothie_post.py
Path/Post/scripts/uccnc_post.py
)
SET(PathPythonOp_SRCS
Path/Op/__init__.py
Path/Op/Adaptive.py
Path/Op/Area.py
Path/Op/Base.py
Path/Op/CircularHoleBase.py
Path/Op/Custom.py
Path/Op/Deburr.py
Path/Op/Engrave.py
Path/Op/EngraveBase.py
Path/Op/FeatureExtension.py
Path/Op/Drilling.py
Path/Op/Helix.py
Path/Op/MillFace.py
Path/Op/Pocket.py
Path/Op/PocketBase.py
Path/Op/PocketShape.py
Path/Op/Probe.py
Path/Op/Profile.py
Path/Op/Slot.py
Path/Op/Surface.py
Path/Op/SurfaceSupport.py
Path/Op/ThreadMilling.py
Path/Op/Util.py
Path/Op/Vcarve.py
Path/Op/Waterline.py
)
SET(PathPythonOpGui_SRCS
Path/Op/Gui/__init__.py
Path/Op/Gui/Adaptive.py
Path/Op/Gui/Array.py
Path/Op/Gui/Base.py
Path/Op/Gui/CircularHoleBase.py
Path/Op/Gui/Comment.py
Path/Op/Gui/Copy.py
Path/Op/Gui/Custom.py
Path/Op/Gui/Deburr.py
Path/Op/Gui/Drilling.py
Path/Op/Gui/Engrave.py
Path/Op/Gui/FeatureExtension.py
Path/Op/Gui/Helix.py
Path/Op/Gui/Hop.py
Path/Op/Gui/MillFace.py
Path/Op/Gui/Pocket.py
Path/Op/Gui/PocketBase.py
Path/Op/Gui/PocketShape.py
Path/Op/Gui/Probe.py
Path/Op/Gui/Profile.py
Path/Op/Gui/Selection.py
Path/Op/Gui/SimpleCopy.py
Path/Op/Gui/Slot.py
Path/Op/Gui/Stop.py
Path/Op/Gui/Surface.py
Path/Op/Gui/ThreadMilling.py
Path/Op/Gui/Vcarve.py
Path/Op/Gui/Waterline.py
)
SET(PathScripts_SRCS
PathScripts/drillableLib.py
PathScripts/PathAdaptive.py
PathScripts/PathAdaptiveGui.py
PathScripts/PathAreaOp.py
PathScripts/PathArray.py
PathScripts/PathCircularHoleBase.py
PathScripts/PathCircularHoleBaseGui.py
PathScripts/PathCamoticsGui.py
PathScripts/PathComment.py
PathScripts/PathCopy.py
PathScripts/PathCustom.py
PathScripts/PathCustomGui.py
PathScripts/PathDeburr.py
PathScripts/PathDeburrGui.py
PathScripts/PathDressup.py
PathScripts/PathDressupAxisMap.py
PathScripts/PathDressupDogbone.py
PathScripts/PathDressupDragknife.py
PathScripts/PathDressupHoldingTags.py
PathScripts/PathDressupLeadInOut.py
PathScripts/PathDressupPathBoundary.py
PathScripts/PathDressupPathBoundaryGui.py
PathScripts/PathDressupRampEntry.py
PathScripts/PathDressupTag.py
PathScripts/PathDressupTagGui.py
PathScripts/PathDressupTagPreferences.py
PathScripts/PathDressupZCorrect.py
PathScripts/PathDrilling.py
PathScripts/PathDrillingGui.py
PathScripts/PathEngrave.py
PathScripts/PathEngraveBase.py
PathScripts/PathEngraveGui.py
PathScripts/PathFeatureExtensions.py
PathScripts/PathFeatureExtensionsGui.py
PathScripts/PathFixture.py
PathScripts/PathGeom.py
PathScripts/PathGetPoint.py
PathScripts/PathGui.py
PathScripts/PathGuiInit.py
PathScripts/PathHelix.py
PathScripts/PathHelixGui.py
PathScripts/PathHop.py
PathScripts/PathIconViewProvider.py
PathScripts/PathInspect.py
PathScripts/PathJob.py
PathScripts/PathJobCmd.py
PathScripts/PathJobDlg.py
PathScripts/PathJobGui.py
PathScripts/PathLog.py
PathScripts/PathMillFace.py
PathScripts/PathMillFaceGui.py
PathScripts/PathOp.py
PathScripts/PathOpGui.py
PathScripts/PathOpTools.py
PathScripts/PathPocket.py
PathScripts/PathPocketBase.py
PathScripts/PathPocketBaseGui.py
PathScripts/PathPocketGui.py
PathScripts/PathPocketShape.py
PathScripts/PathPocketShapeGui.py
PathScripts/PathPost.py
PathScripts/PathPostProcessor.py
PathScripts/PathPreferences.py
PathScripts/PathPreferencesAdvanced.py
PathScripts/PathPreferencesPathDressup.py
PathScripts/PathPreferencesPathJob.py
PathScripts/PathProbe.py
PathScripts/PathProbeGui.py
PathScripts/PathProfile.py
PathScripts/PathProfileContour.py
PathScripts/PathProfileContourGui.py
PathScripts/PathProfileEdges.py
PathScripts/PathProfileEdgesGui.py
PathScripts/PathProfileFaces.py
PathScripts/PathProfileFacesGui.py
PathScripts/PathProfileGui.py
PathScripts/PathProperty.py
PathScripts/PathPropertyBag.py
PathScripts/PathPropertyBagGui.py
PathScripts/PathPropertyEditor.py
PathScripts/PathSanity.py
PathScripts/PathSelection.py
PathScripts/PathSetupSheet.py
PathScripts/PathSetupSheetGui.py
PathScripts/PathSetupSheetOpPrototype.py
PathScripts/PathSetupSheetOpPrototypeGui.py
PathScripts/PathSimpleCopy.py
PathScripts/PathSimulatorGui.py
PathScripts/PathSlot.py
PathScripts/PathSlotGui.py
PathScripts/PathStock.py
PathScripts/PathStop.py
PathScripts/PathSurface.py
PathScripts/PathSurfaceGui.py
PathScripts/PathSurfaceSupport.py
PathScripts/PathThreadMilling.py
PathScripts/PathThreadMillingGui.py
PathScripts/PathToolBit.py
PathScripts/PathToolBitCmd.py
PathScripts/PathToolBitEdit.py
PathScripts/PathToolBitGui.py
PathScripts/PathToolBitLibraryCmd.py
PathScripts/PathToolBitLibraryGui.py
PathScripts/PathToolController.py
PathScripts/PathToolControllerGui.py
PathScripts/PathToolEdit.py
PathScripts/PathToolLibraryEditor.py
PathScripts/PathToolLibraryManager.py
PathScripts/PathUtil.py
PathScripts/PathUtils.py
PathScripts/PathUtilsGui.py
PathScripts/PathVcarve.py
PathScripts/PathVcarveGui.py
PathScripts/PathWaterline.py
PathScripts/PathWaterlineGui.py
PathScripts/PostUtils.py
PathScripts/PostUtilsArguments.py
PathScripts/PostUtilsExport.py
PathScripts/PostUtilsParse.py
PathScripts/PathPropertyBag.py
PathScripts/PathPropertyBagGui.py
PathScripts/__init__.py
)
SET(Generator_SRCS
Generators/drill_generator.py
Generators/helix_generator.py
Generators/rotation_generator.py
Generators/threadmilling_generator.py
Generators/toolchange_generator.py
)
SET(PathScripts_post_SRCS
PathScripts/post/__init__.py
PathScripts/post/centroid_post.py
PathScripts/post/comparams_post.py
PathScripts/post/dxf_post.py
PathScripts/post/dynapath_post.py
PathScripts/post/example_pre.py
PathScripts/post/fablin_post.py
PathScripts/post/fanuc_post.py
PathScripts/post/gcode_pre.py
PathScripts/post/grbl_post.py
PathScripts/post/heidenhain_post.py
PathScripts/post/jtech_post.py
PathScripts/post/KineticNCBeamicon2_post.py
PathScripts/post/linuxcnc_post.py
PathScripts/post/mach3_mach4_post.py
PathScripts/post/marlin_post.py
PathScripts/post/nccad_post.py
PathScripts/post/opensbp_post.py
PathScripts/post/opensbp_pre.py
PathScripts/post/philips_post.py
PathScripts/post/refactored_centroid_post.py
PathScripts/post/refactored_grbl_post.py
PathScripts/post/refactored_linuxcnc_post.py
PathScripts/post/refactored_mach3_mach4_post.py
PathScripts/post/refactored_test_post.py
PathScripts/post/rml_post.py
PathScripts/post/rrf_post.py
PathScripts/post/slic3r_pre.py
PathScripts/post/smoothie_post.py
PathScripts/post/uccnc_post.py
SET(PathPythonBaseGenerator_SRCS
Path/Base/Generator/drill.py
Path/Base/Generator/helix.py
Path/Base/Generator/rotation.py
Path/Base/Generator/threadmilling.py
Path/Base/Generator/toolchange.py
)
SET(PathPythonGui_SRCS
@@ -256,7 +296,7 @@ SET(PathTests_SRCS
PathTests/TestPathHelpers.py
PathTests/TestPathHelixGenerator.py
PathTests/TestPathLog.py
PathTests/TestPathOpTools.py
PathTests/TestPathOpUtil.py
PathTests/TestPathPost.py
PathTests/TestPathPreferences.py
PathTests/TestPathPropertyBag.py
@@ -265,10 +305,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
@@ -313,8 +351,20 @@ SET(Path_Data
SET(all_files
${PathScripts_SRCS}
${Generator_SRCS}
${PathScripts_post_SRCS}
${PathPython_SRCS}
${PathPythonBase_SRCS}
${PathPythonBaseGui_SRCS}
${PathPythonBaseGenerator_SRCS}
${PathPythonDressup_SRCS}
${PathPythonDressupGui_SRCS}
${PathPythonMain_SRCS}
${PathPythonMainGui_SRCS}
${PathPythonOp_SRCS}
${PathPythonOpGui_SRCS}
${PathPythonPost_SRCS}
${PathPythonPostScripts_SRCS}
${PathPythonTools_SRCS}
${PathPythonToolsGui_SRCS}
${PathPythonGui_SRCS}
${Tools_SRCS}
${Tools_Bit_SRCS}
@@ -349,9 +399,98 @@ INSTALL(
INSTALL(
FILES
${Generator_SRCS}
${PathPython_SRCS}
DESTINATION
Mod/Path/Generators
Mod/Path/Path
)
INSTALL(
FILES
${PathPythonBase_SRCS}
DESTINATION
Mod/Path/Path/Base
)
INSTALL(
FILES
${PathPythonBaseGenerator_SRCS}
DESTINATION
Mod/Path/Path/Base/Generator
)
INSTALL(
FILES
${PathPythonBaseGui_SRCS}
DESTINATION
Mod/Path/Path/Base/Gui
)
INSTALL(
FILES
${PathPythonDressup_SRCS}
DESTINATION
Mod/Path/Path/Dressup
)
INSTALL(
FILES
${PathPythonDressupGui_SRCS}
DESTINATION
Mod/Path/Path/Dressup/Gui
)
INSTALL(
FILES
${PathPythonMain_SRCS}
DESTINATION
Mod/Path/Path/Main
)
INSTALL(
FILES
${PathPythonMainGui_SRCS}
DESTINATION
Mod/Path/Path/Main/Gui
)
INSTALL(
FILES
${PathPythonOp_SRCS}
DESTINATION
Mod/Path/Path/Op
)
INSTALL(
FILES
${PathPythonOpGui_SRCS}
DESTINATION
Mod/Path/Path/Op/Gui
)
INSTALL(
FILES
${PathPythonPost_SRCS}
DESTINATION
Mod/Path/Path/Post
)
INSTALL(
FILES
${PathPythonPostScripts_SRCS}
DESTINATION
Mod/Path/Path/Post/scripts
)
INSTALL(
FILES
${PathPythonTools_SRCS}
DESTINATION
Mod/Path/Path/Tool
)
INSTALL(
FILES
${PathPythonToolsGui_SRCS}
DESTINATION
Mod/Path/Path/Tool/Gui
)
INSTALL(
@@ -369,13 +508,6 @@ INSTALL(
)
INSTALL(
FILES
${PathScripts_post_SRCS}
DESTINATION
Mod/Path/PathScripts/post
)
INSTALL(
FILES
${PathPythonGui_SRCS}

View File

@@ -82,7 +82,7 @@ private:
try {
std::string path = App::Application::getHomePath();
path += "Mod/Path/PathScripts/post/";
path += "Mod/Path/Path/Post/scripts/";
QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_pre.py"));
std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro")
->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str());
@@ -113,7 +113,7 @@ private:
QFileInfo fileInfo = list.at(i);
if (fileInfo.baseName().toStdString() == processor) {
if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) {
pre << "from PathScripts.post import " << processor;
pre << "from Path.Post.scripts import " << processor;
} else {
pre << "import " << processor;
}
@@ -149,7 +149,7 @@ private:
try {
std::string path = App::Application::getHomePath();
path += "Mod/Path/PathScripts/post/";
path += "Mod/Path/Path/Post/scripts/";
QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_pre.py"));
std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro")
->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str());
@@ -189,7 +189,7 @@ private:
QFileInfo fileInfo = list.at(i);
if (fileInfo.baseName().toStdString() == processor) {
if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) {
pre << "from PathScripts.post import " << processor;
pre << "from Path.Post.scripts import " << processor;
} else {
pre << "import " << processor;
}
@@ -225,7 +225,7 @@ private:
throw Py::RuntimeError("No object to export");
std::string path = App::Application::getHomePath();
path += "Mod/Path/PathScripts/post/";
path += "Mod/Path/Path/Post/scripts/";
QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_post.py"));
std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro")
->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str());
@@ -265,7 +265,7 @@ private:
QFileInfo fileInfo = list.at(i);
if (fileInfo.baseName().toStdString() == processor) {
if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) {
pre << "from PathScripts.post import " << processor;
pre << "from Path.Post.scripts import " << processor;
} else {
pre << "import " << processor;
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -59,7 +59,8 @@ class PathWorkbench(Workbench):
global PathCommandGroup
# Add preferences pages - before loading PathGui to properly order pages of Path group
from PathScripts import PathPreferencesPathJob, PathPreferencesPathDressup
import Path.Dressup.Gui.Preferences as PathPreferencesPathDressup
import Path.Main.Gui.PreferencesJob as PathPreferencesPathJob
translate = FreeCAD.Qt.translate
@@ -68,9 +69,6 @@ class PathWorkbench(Workbench):
PathPreferencesPathDressup.DressupPreferencesPage, "Path"
)
# Check enablement of experimental features
from PathScripts import PathPreferences
# load the builtin modules
import Path
import PathScripts
@@ -79,11 +77,11 @@ class PathWorkbench(Workbench):
FreeCADGui.addLanguagePath(":/translations")
FreeCADGui.addIconPath(":/icons")
from PathScripts import PathGuiInit
from PathScripts import PathJobCmd
import Path.GuiInit
from PathScripts import PathToolBitCmd
from PathScripts import PathToolBitLibraryCmd
from Path.Main.Gui import JobCmd as PathJobCmd
from Path.Tool.Gui import BitCmd as PathToolBitCmd
from Path.Tool.Gui import BitLibraryCmd as PathToolBitLibraryCmd
from PySide.QtCore import QT_TRANSLATE_NOOP
@@ -91,7 +89,7 @@ class PathWorkbench(Workbench):
import subprocess
from packaging.version import Version, parse
PathGuiInit.Startup()
Path.GuiInit.Startup()
# build commands list
projcmdlist = ["Path_Job", "Path_Post"]
@@ -134,12 +132,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(
@@ -151,14 +145,14 @@ class PathWorkbench(Workbench):
)
threedcmdgroup = threedopcmdlist
if PathPreferences.experimentalFeaturesEnabled():
if Path.Preferences.experimentalFeaturesEnabled():
projcmdlist.append("Path_Sanity")
prepcmdlist.append("Path_Shape")
extracmdlist.extend(["Path_Area", "Path_Area_Workplane"])
specialcmdlist.append("Path_ThreadMilling")
twodopcmdlist.append("Path_Slot")
if PathPreferences.advancedOCLFeaturesEnabled():
if Path.Preferences.advancedOCLFeaturesEnabled():
try:
r = subprocess.run(
["camotics", "--version"], capture_output=True, text=True
@@ -172,8 +166,8 @@ class PathWorkbench(Workbench):
try:
import ocl # pylint: disable=unused-variable
from PathScripts import PathSurfaceGui
from PathScripts import PathWaterlineGui
from Path.Op.Gui import Surface
from Path.Op.Gui import Waterline
threedopcmdlist.extend(["Path_Surface", "Path_Waterline"])
threedcmdgroup = ["Path_3dTools"]
@@ -185,7 +179,7 @@ class PathWorkbench(Workbench):
),
)
except ImportError:
if not PathPreferences.suppressOpenCamLibWarning():
if not Path.Preferences.suppressOpenCamLibWarning():
FreeCAD.Console.PrintError("OpenCamLib is not working!\n")
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench", "Project Setup"), projcmdlist)
@@ -258,13 +252,13 @@ class PathWorkbench(Workbench):
self.dressupcmds = dressupcmdlist
curveAccuracy = PathPreferences.defaultLibAreaCurveAccuracy()
curveAccuracy = Path.Preferences.defaultLibAreaCurveAccuracy()
if curveAccuracy:
Path.Area.setDefaultParams(Accuracy=curveAccuracy)
# keep this one the last entry in the preferences
import PathScripts.PathPreferencesAdvanced as PathPreferencesAdvanced
from PathScripts.PathPreferences import preferences
import Path.Base.Gui.PreferencesAdvanced as PathPreferencesAdvanced
from Path.Preferences import preferences
FreeCADGui.addPreferencePage(
PathPreferencesAdvanced.AdvancedPreferencesPage, "Path"
@@ -272,7 +266,7 @@ class PathWorkbench(Workbench):
Log("Loading Path workbench... done\n")
# Warn user if current schema doesn't use minute for time in velocity
if not PathPreferences.suppressVelocity():
if not Path.Preferences.suppressVelocity():
velString = FreeCAD.Units.Quantity(
1, FreeCAD.Units.Velocity
).getUserPreferred()[2][3:]
@@ -324,7 +318,7 @@ class PathWorkbench(Workbench):
"", ["Path_ExportTemplate"] + self.toolbitctxmenu
)
menuAppended = True
if isinstance(obj.Proxy, PathScripts.PathOp.ObjectOp):
if isinstance(obj.Proxy, Path.Op.Base.ObjectOp):
self.appendContextMenu(
"", ["Path_OperationCopy", "Path_OpActiveToggle"]
)
@@ -341,7 +335,7 @@ class PathWorkbench(Workbench):
for cmd in self.dressupcmds:
self.appendContextMenu("", [cmd])
menuAppended = True
if isinstance(obj.Proxy, PathScripts.PathToolBit.ToolBit):
if isinstance(obj.Proxy, Path.Tool.Bit.ToolBit):
self.appendContextMenu("", ["Path_ToolBitSave", "Path_ToolBitSaveAs"])
menuAppended = True
if menuAppended:

View File

@@ -1,14 +1,14 @@
import PathScripts.PathLog as PathLog
import FreeCAD as App
import Part
import Path
import numpy
import math
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
def checkForBlindHole(baseshape, selectedFace):
@@ -47,7 +47,7 @@ def isDrillableCylinder(obj, candidate, tooldiameter=None, vector=App.Vector(0,
matchToolDiameter = tooldiameter is not None
matchVector = vector is not None
PathLog.debug(
Path.Log.debug(
"\n match tool diameter {} \n match vector {}".format(
matchToolDiameter, matchVector
)
@@ -91,28 +91,28 @@ def isDrillableCylinder(obj, candidate, tooldiameter=None, vector=App.Vector(0,
raise TypeError("cylinder does not have 3 edges. Not supported yet")
if raisedFeature(obj, candidate):
PathLog.debug("The cylindrical face is a raised feature")
Path.Log.debug("The cylindrical face is a raised feature")
return False
if not matchToolDiameter and not matchVector:
return True
if matchToolDiameter and tooldiameter / 2 > candidate.Surface.Radius:
PathLog.debug("The tool is larger than the target")
Path.Log.debug("The tool is larger than the target")
return False
bottomface = checkForBlindHole(obj, candidate)
PathLog.track("candidate is a blind hole")
Path.Log.track("candidate is a blind hole")
if (
bottomface is not None and matchVector
): # blind holes only drillable at exact vector
result = compareVecs(bottomface.normalAt(0, 0), vector, exact=True)
PathLog.track(result)
Path.Log.track(result)
return result
elif matchVector and not (compareVecs(getSeam(candidate).Curve.Direction, vector)):
PathLog.debug("The feature is not aligned with the given vector")
Path.Log.debug("The feature is not aligned with the given vector")
return False
else:
return True
@@ -124,32 +124,32 @@ def isDrillableFace(obj, candidate, tooldiameter=None, vector=App.Vector(0, 0, 1
"""
matchToolDiameter = tooldiameter is not None
matchVector = vector is not None
PathLog.debug(
Path.Log.debug(
"\n match tool diameter {} \n match vector {}".format(
matchToolDiameter, matchVector
)
)
if not type(candidate.Surface) == Part.Plane:
PathLog.debug("Drilling on non-planar faces not supported")
Path.Log.debug("Drilling on non-planar faces not supported")
return False
if (
len(candidate.Edges) == 1 and type(candidate.Edges[0].Curve) == Part.Circle
): # Regular circular face
PathLog.debug("Face is circular - 1 edge")
Path.Log.debug("Face is circular - 1 edge")
edge = candidate.Edges[0]
elif (
len(candidate.Edges) == 2
and type(candidate.Edges[0].Curve) == Part.Circle
and type(candidate.Edges[1].Curve) == Part.Circle
): # process a donut
PathLog.debug("Face is a donut - 2 edges")
Path.Log.debug("Face is a donut - 2 edges")
e1 = candidate.Edges[0]
e2 = candidate.Edges[1]
edge = e1 if e1.Curve.Radius < e2.Curve.Radius else e2
else:
PathLog.debug(
Path.Log.debug(
"expected a Face with one or two circular edges got a face with {} edges".format(
len(candidate.Edges)
)
@@ -157,13 +157,13 @@ def isDrillableFace(obj, candidate, tooldiameter=None, vector=App.Vector(0, 0, 1
return False
if vector is not None: # Check for blind hole alignment
if not compareVecs(candidate.normalAt(0, 0), vector, exact=True):
PathLog.debug("Vector not aligned")
Path.Log.debug("Vector not aligned")
return False
if matchToolDiameter and edge.Curve.Radius < tooldiameter / 2:
PathLog.debug("Failed diameter check")
Path.Log.debug("Failed diameter check")
return False
else:
PathLog.debug("Face is drillable")
Path.Log.debug("Face is drillable")
return True
@@ -174,7 +174,7 @@ def isDrillableEdge(obj, candidate, tooldiameter=None, vector=App.Vector(0, 0, 1
matchToolDiameter = tooldiameter is not None
matchVector = vector is not None
PathLog.debug(
Path.Log.debug(
"\n match tool diameter {} \n match vector {}".format(
matchToolDiameter, matchVector
)
@@ -182,22 +182,22 @@ def isDrillableEdge(obj, candidate, tooldiameter=None, vector=App.Vector(0, 0, 1
edge = candidate
if not (isinstance(edge.Curve, Part.Circle) and edge.isClosed()):
PathLog.debug("expected a closed circular edge")
Path.Log.debug("expected a closed circular edge")
return False
if not hasattr(edge.Curve, "Radius"):
PathLog.debug("The Feature edge has no radius - Ellipse.")
Path.Log.debug("The Feature edge has no radius - Ellipse.")
return False
if not matchToolDiameter and not matchVector:
return True
if matchToolDiameter and tooldiameter / 2 > edge.Curve.Radius:
PathLog.debug("The tool is larger than the target")
Path.Log.debug("The tool is larger than the target")
return False
if matchVector and not (compareVecs(edge.Curve.Axis, vector)):
PathLog.debug("The feature is not aligned with the given vector")
Path.Log.debug("The feature is not aligned with the given vector")
return False
else:
return True
@@ -220,7 +220,7 @@ def isDrillable(obj, candidate, tooldiameter=None, vector=App.Vector(0, 0, 1)):
vector=App.Vector or None
"""
PathLog.debug(
Path.Log.debug(
"obj: {} candidate: {} tooldiameter {} vector {}".format(
obj, candidate, tooldiameter, vector
)
@@ -247,7 +247,7 @@ def isDrillable(obj, candidate, tooldiameter=None, vector=App.Vector(0, 0, 1)):
return False
except TypeError as e:
PathLog.debug(e)
Path.Log.debug(e)
return False
# raise TypeError("{}".format(e))
@@ -261,7 +261,7 @@ def compareVecs(vec1, vec2, exact=False):
angle = vec1.getAngle(vec2)
angle = 0 if math.isnan(angle) else math.degrees(angle)
PathLog.debug("vector angle: {}".format(angle))
Path.Log.debug("vector angle: {}".format(angle))
if exact:
return numpy.isclose(angle, 0, rtol=1e-05, atol=1e-06)
else:
@@ -285,7 +285,7 @@ def getDrillableTargets(obj, ToolDiameter=None, vector=App.Vector(0, 0, 1)):
results = []
for i in range(1, len(shp.Faces)):
fname = "Face{}".format(i)
PathLog.debug(fname)
Path.Log.debug(fname)
candidate = obj.getSubObject(fname)
if not isinstance(candidate.Surface, Part.Cylinder):
@@ -295,9 +295,9 @@ def getDrillableTargets(obj, ToolDiameter=None, vector=App.Vector(0, 0, 1)):
drillable = isDrillable(
shp, candidate, tooldiameter=ToolDiameter, vector=vector
)
PathLog.debug("fname: {} : drillable {}".format(fname, drillable))
Path.Log.debug("fname: {} : drillable {}".format(fname, drillable))
except Exception as e:
PathLog.debug(e)
Path.Log.debug(e)
continue
if drillable:

View File

@@ -21,11 +21,9 @@
# ***************************************************************************
import FreeCAD
import PathScripts.PathLog as PathLog
import PathMachineState
import PathScripts.PathGeom as PathGeom
import Path
import Path.Base.MachineState as PathMachineState
import Part
from PathScripts.PathGeom import CmdMoveRapid, CmdMoveAll
__title__ = "Feed Rate Helper Utility"
__author__ = "sliptonic (Brad Collette)"
@@ -37,10 +35,10 @@ TODO: This needs to be able to handle feedrates for axes other than X,Y,Z
"""
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
def setFeedRate(commandlist, ToolController):
@@ -67,26 +65,26 @@ def setFeedRate(commandlist, ToolController):
else currentposition.z
)
endpoint = FreeCAD.Vector(x, y, z)
if PathGeom.pointsCoincide(currentposition, endpoint):
if Path.Geom.pointsCoincide(currentposition, endpoint):
return True
return PathGeom.isVertical(Part.makeLine(currentposition, endpoint))
return Path.Geom.isVertical(Part.makeLine(currentposition, endpoint))
machine = PathMachineState.MachineState()
for command in commandlist:
if command.Name not in CmdMoveAll:
if command.Name not in Path.Geom.CmdMoveAll:
continue
if _isVertical(machine.getPosition(), command):
rate = (
ToolController.VertRapid.Value
if command.Name in CmdMoveRapid
if command.Name in Path.Geom.CmdMoveRapid
else ToolController.VertFeed.Value
)
else:
rate = (
ToolController.HorizRapid.Value
if command.Name in CmdMoveRapid
if command.Name in Path.Geom.CmdMoveRapid
else ToolController.HorizFeed.Value
)

View File

@@ -21,7 +21,6 @@
# ***************************************************************************
import PathScripts.PathLog as PathLog
import Path
import numpy
@@ -32,10 +31,10 @@ __doc__ = "Generates the drilling toolpath for a single spotshape"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
def generate(edge, dwelltime=0.0, peckdepth=0.0, repeat=1, retractheight=None, chipBreak=False):
@@ -62,12 +61,12 @@ def generate(edge, dwelltime=0.0, peckdepth=0.0, repeat=1, retractheight=None, c
startPoint = edge.Vertexes[0].Point
endPoint = edge.Vertexes[1].Point
PathLog.debug(startPoint)
PathLog.debug(endPoint)
Path.Log.debug(startPoint)
Path.Log.debug(endPoint)
PathLog.debug(numpy.isclose(startPoint.sub(endPoint).x, 0, rtol=1e-05, atol=1e-06))
PathLog.debug(numpy.isclose(startPoint.sub(endPoint).y, 0, rtol=1e-05, atol=1e-06))
PathLog.debug(endPoint)
Path.Log.debug(numpy.isclose(startPoint.sub(endPoint).x, 0, rtol=1e-05, atol=1e-06))
Path.Log.debug(numpy.isclose(startPoint.sub(endPoint).y, 0, rtol=1e-05, atol=1e-06))
Path.Log.debug(endPoint)
if dwelltime > 0.0 and peckdepth > 0.0:
raise ValueError("Peck and Dwell cannot be used together")

View File

@@ -23,7 +23,6 @@
from numpy import ceil, linspace, isclose
import Path
import PathScripts.PathLog as PathLog
__title__ = "Helix Path Generator"
__author__ = "sliptonic (Brad Collette)"
@@ -32,11 +31,11 @@ __doc__ = "Generates the helix for a single spot targetshape"
__contributors__ = "russ4262 (Russell Johnson), Lorenz Hüdepohl"
if True:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
if False:
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
def generate(
@@ -56,7 +55,7 @@ def generate(
startPoint = edge.Vertexes[0].Point
endPoint = edge.Vertexes[1].Point
PathLog.track(
Path.Log.track(
"(helix: <{}, {}>\n hole radius {}\n inner radius {}\n step over {}\n start point {}\n end point {}\n step_down {}\n tool diameter {}\n direction {}\n startAt {})".format(
startPoint.x,
startPoint.y,
@@ -121,7 +120,7 @@ def generate(
raise ValueError("start point is below end point")
if hole_radius <= tool_diameter:
PathLog.debug("(single helix mode)\n")
Path.Log.debug("(single helix mode)\n")
radii = [hole_radius - tool_diameter / 2]
if radii[0] <= 0:
raise ValueError(
@@ -132,7 +131,7 @@ def generate(
outer_radius = hole_radius
else: # inner_radius > 0:
PathLog.debug("(annulus mode / full hole)\n")
Path.Log.debug("(annulus mode / full hole)\n")
outer_radius = hole_radius - tool_diameter / 2
step_radius = inner_radius + tool_diameter / 2
if abs((outer_radius - step_radius) / step_over_distance) < 1e-5:
@@ -141,7 +140,7 @@ def generate(
nr = max(int(ceil((outer_radius - inner_radius) / step_over_distance)), 2)
radii = linspace(outer_radius, step_radius, nr)
PathLog.debug("Radii: {}".format(radii))
Path.Log.debug("Radii: {}".format(radii))
# calculate the number of full and partial turns required
# Each full turn is two 180 degree arcs. Zsteps is equally spaced step
# down values

View File

@@ -25,7 +25,6 @@
# The main generator function should be extended to include other flavors of 3+2
import PathScripts.PathLog as PathLog
import math
import Path
import FreeCAD
@@ -38,10 +37,10 @@ __doc__ = "Generates the rotation toolpath"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class refAxis(Enum):
@@ -56,7 +55,7 @@ def relAngle(vec, ref):
relative angle. The result is returned in degrees (plus or minus)
"""
PathLog.debug("vec: {} ref: {}".format(vec, ref))
Path.Log.debug("vec: {} ref: {}".format(vec, ref))
norm = vec * 1 # copy vec so we don't alter original
if ref == refAxis.x:
@@ -72,7 +71,7 @@ def relAngle(vec, ref):
rot = FreeCAD.Rotation(norm, ref)
ang = math.degrees(rot.Angle)
angle = ang * plane.dot(rot.Axis)
PathLog.debug("relative ang: {}".format(angle))
Path.Log.debug("relative ang: {}".format(angle))
return angle
@@ -83,7 +82,7 @@ def __getCRotation(normalVector, cMin=-360, cMax=360):
with either the +y or -y axis.
multiple poses may be possible. Returns a list of all valid poses
"""
PathLog.debug("normalVector: {} cMin: {} cMax: {}".format(normalVector, cMin, cMax))
Path.Log.debug("normalVector: {} cMin: {} cMax: {}".format(normalVector, cMin, cMax))
angle = relAngle(normalVector, refAxis.y)
@@ -152,7 +151,7 @@ def generate(normalVector, aMin=-360, aMax=360, cMin=-360, cMax=360, compound=Fa
normalVector = rot.multVec(n
"""
PathLog.track(
Path.Log.track(
"\n=============\n normalVector: {}\n aMin: {}\n aMax: {}\n cMin: {}\n cMax: {}".format(
normalVector, aMin, aMax, cMin, cMax
)
@@ -160,7 +159,7 @@ def generate(normalVector, aMin=-360, aMax=360, cMin=-360, cMax=360, compound=Fa
# Calculate C rotation
cResults = __getCRotation(normalVector, cMin, cMax)
PathLog.debug("C Rotation results {}".format(cResults))
Path.Log.debug("C Rotation results {}".format(cResults))
solutions = []
for result in cResults:
@@ -172,7 +171,7 @@ def generate(normalVector, aMin=-360, aMax=360, cMin=-360, cMax=360, compound=Fa
# Get the candidate A rotation for the new vector
aResult = __getARotation(newvec, aMin, aMax)
PathLog.debug(
Path.Log.debug(
"\n=====\nFor C Rotation: {}\n Calculated A {}\n".format(result, aResult)
)
@@ -191,7 +190,7 @@ def generate(normalVector, aMin=-360, aMax=360, cMin=-360, cMax=360, compound=Fa
best = solution
curlen = testlen
PathLog.debug("best result: {}".format(best))
Path.Log.debug("best result: {}".format(best))
# format and return rotation commands
commands = []

View File

@@ -24,8 +24,6 @@ from __future__ import print_function
import FreeCAD
import Path
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import math
from PySide.QtCore import QT_TRANSLATE_NOOP
@@ -35,10 +33,10 @@ __url__ = "http://www.freecadweb.org"
__doc__ = "Path thread milling operation."
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -153,7 +151,7 @@ def generate(center, cmd, zStart, zFinal, pitch, radius, leadInOut, elevator, st
z = thread.zStart
r = -radius
i = 0
while not PathGeom.isRoughly(z, thread.zFinal):
while not Path.Geom.isRoughly(z, thread.zFinal):
if thread.overshoots(z):
break
if 0 == (i & 0x01):
@@ -165,7 +163,7 @@ def generate(center, cmd, zStart, zFinal, pitch, radius, leadInOut, elevator, st
i = i + 1
z = z + thread.hPitch
if PathGeom.isRoughly(z, thread.zFinal):
if Path.Geom.isRoughly(z, thread.zFinal):
x = center.x
y = yMin if (i & 0x01) else yMax
else:
@@ -184,12 +182,12 @@ def generate(center, cmd, zStart, zFinal, pitch, radius, leadInOut, elevator, st
a = math.atan2(y - center.y, x - center.x)
dx = math.cos(a) * (radius - elevator)
dy = math.sin(a) * (radius - elevator)
PathLog.debug("")
PathLog.debug("a={}: dx={:.2f}, dy={:.2f}".format(a / math.pi * 180, dx, dy))
Path.Log.debug("")
Path.Log.debug("a={}: dx={:.2f}, dy={:.2f}".format(a / math.pi * 180, dx, dy))
elevatorX = x - dx
elevatorY = y - dy
PathLog.debug(
Path.Log.debug(
"({:.2f}, {:.2f}) -> ({:.2f}, {:.2f})".format(x, y, elevatorX, elevatorY)
)

View File

@@ -21,7 +21,6 @@
# ***************************************************************************
import PathScripts.PathLog as PathLog
import Path
from enum import Enum
@@ -32,10 +31,10 @@ __doc__ = "Generates the rotation toolpath"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class SpindleDirection(Enum):
@@ -52,7 +51,7 @@ def generate(
"""
PathLog.track(
Path.Log.track(
f"toolnumber:{toolnumber} toollabel: {toollabel} spindlespeed:{spindlespeed} spindledirection: {spindledirection}"
)
@@ -73,7 +72,7 @@ def generate(
else:
commands.append(Path.Command(spindledirection.value, {"S": spindlespeed}))
PathLog.track(commands)
Path.Log.track(commands)
return commands

View File

@@ -22,7 +22,7 @@
import FreeCAD
import FreeCADGui
import PathScripts.PathLog as PathLog
import Path
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -37,8 +37,8 @@ __author__ = "sliptonic (Brad Collette)"
__url__ = "https://www.freecadweb.org"
__doc__ = "Helper class to use FreeCADGUi.Snapper to let the user enter arbitrary points while the task panel is active."
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
# PathLog.track(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
# Path.Log.track(Path.Log.thisModule())
class TaskPanel:

View File

@@ -21,9 +21,9 @@
# ***************************************************************************
import FreeCAD
import Path
import Path.Base.Util as PathUtil
import PathGui
import PathScripts.PathLog as PathLog
import PathScripts.PathUtil as PathUtil
import importlib
__title__ = "Path Icon ViewProvider"
@@ -34,10 +34,10 @@ __doc__ = "ViewProvider who's main and only task is to assign an icon."
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class ViewProvider(object):
@@ -91,7 +91,7 @@ class ViewProvider(object):
self._onEditCallback(False)
def setupContextMenu(self, vobj, menu):
PathLog.track()
Path.Log.track()
from PySide import QtGui
edit = translate("Path", "Edit")
@@ -107,12 +107,12 @@ def Attach(vobj, name):
"""Attach(vobj, name) ... attach the appropriate view provider to the view object.
If no view provider was registered for the given name a default IconViewProvider is created."""
PathLog.track(vobj.Object.Label, name)
Path.Log.track(vobj.Object.Label, name)
global _factory
for key, value in PathUtil.keyValueIter(_factory):
if key == name:
return value(vobj, name)
PathLog.track(vobj.Object.Label, name, "PathIconViewProvider")
Path.Log.track(vobj.Object.Label, name, "PathIconViewProvider")
return ViewProvider(vobj, name)
@@ -120,6 +120,6 @@ def RegisterViewProvider(name, provider):
"""RegisterViewProvider(name, provider) ... if an IconViewProvider is created for an object with the given name
an instance of provider is used instead."""
PathLog.track(name)
Path.Log.track(name)
global _factory
_factory[name] = provider

View File

@@ -21,14 +21,13 @@
# ***************************************************************************
import FreeCADGui
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathLog as PathLog
import Path
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class AdvancedPreferencesPage:
@@ -38,7 +37,7 @@ class AdvancedPreferencesPage:
self.form.EnableAdvancedOCLFeatures.stateChanged.connect(self.updateSelection)
def saveSettings(self):
PathPreferences.setPreferencesAdvanced(
Path.Preferences.setPreferencesAdvanced(
self.form.EnableAdvancedOCLFeatures.isChecked(),
self.form.WarningSuppressAllSpeeds.isChecked(),
self.form.WarningSuppressRapidSpeeds.isChecked(),
@@ -48,23 +47,23 @@ class AdvancedPreferencesPage:
)
def loadSettings(self):
PathLog.track()
Path.Log.track()
self.form.WarningSuppressAllSpeeds.setChecked(
PathPreferences.suppressAllSpeedsWarning()
Path.Preferences.suppressAllSpeedsWarning()
)
self.form.WarningSuppressRapidSpeeds.setChecked(
PathPreferences.suppressRapidSpeedsWarning(False)
Path.Preferences.suppressRapidSpeedsWarning(False)
)
self.form.WarningSuppressSelectionMode.setChecked(
PathPreferences.suppressSelectionModeWarning()
Path.Preferences.suppressSelectionModeWarning()
)
self.form.EnableAdvancedOCLFeatures.setChecked(
PathPreferences.advancedOCLFeaturesEnabled()
Path.Preferences.advancedOCLFeaturesEnabled()
)
self.form.WarningSuppressOpenCamLib.setChecked(
PathPreferences.suppressOpenCamLibWarning()
Path.Preferences.suppressOpenCamLibWarning()
)
self.form.WarningSuppressVelocity.setChecked(PathPreferences.suppressVelocity())
self.form.WarningSuppressVelocity.setChecked(Path.Preferences.suppressVelocity())
self.updateSelection()
def updateSelection(self, state=None):

View File

@@ -0,0 +1,468 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * Copyright (c) 2020 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 PySide import QtCore, QtGui
import FreeCAD
import FreeCADGui
import Path
import Path.Base.Gui.IconViewProvider as PathIconViewProvider
import Path.Base.Gui.PropertyEditor as PathPropertyEditor
import Path.Base.PropertyBag as PathPropertyBag
import Path.Base.Util as PathUtil
import re
__title__ = "Property Bag Editor"
__author__ = "sliptonic (Brad Collette)"
__url__ = "https://www.freecadweb.org"
__doc__ = "Task panel editor for a PropertyBag"
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 ViewProvider(object):
"""ViewProvider for a PropertyBag.
It's sole job is to provide an icon and invoke the TaskPanel on edit."""
def __init__(self, vobj, name):
Path.Log.track(name)
vobj.Proxy = self
self.icon = name
# mode = 2
self.obj = None
self.vobj = None
def attach(self, vobj):
Path.Log.track()
self.vobj = vobj
self.obj = vobj.Object
def getIcon(self):
return ":/icons/Path-SetupSheet.svg"
def __getstate__(self):
return None
def __setstate__(self, state):
return None
def getDisplayMode(self, mode):
return "Default"
def setEdit(self, vobj, mode=0):
Path.Log.track()
taskPanel = TaskPanel(vobj)
FreeCADGui.Control.closeDialog()
FreeCADGui.Control.showDialog(taskPanel)
taskPanel.setupUi()
return True
def unsetEdit(self, vobj, mode):
FreeCADGui.Control.closeDialog()
return
def claimChildren(self):
return []
def doubleClicked(self, vobj):
self.setEdit(vobj)
class Delegate(QtGui.QStyledItemDelegate):
RoleObject = QtCore.Qt.UserRole + 1
RoleProperty = QtCore.Qt.UserRole + 2
RoleEditor = QtCore.Qt.UserRole + 3
# def paint(self, painter, option, index):
# #Path.Log.track(index.column(), type(option))
def createEditor(self, parent, option, index):
editor = PathPropertyEditor.Editor(
index.data(self.RoleObject), index.data(self.RoleProperty)
)
index.model().setData(index, editor, self.RoleEditor)
return editor.widget(parent)
def setEditorData(self, widget, index):
Path.Log.track(index.row(), index.column())
index.data(self.RoleEditor).setEditorData(widget)
def setModelData(self, widget, model, index):
Path.Log.track(index.row(), index.column())
editor = index.data(self.RoleEditor)
editor.setModelData(widget)
index.model().setData(index, editor.displayString(), QtCore.Qt.DisplayRole)
def updateEditorGeometry(self, widget, option, index):
widget.setGeometry(option.rect)
class PropertyCreate(object):
def __init__(self, obj, grp, typ, another):
self.obj = obj
self.form = FreeCADGui.PySideUic.loadUi(":panels/PropertyCreate.ui")
obj.Proxy.refreshCustomPropertyGroups()
for g in sorted(obj.CustomPropertyGroups):
self.form.propertyGroup.addItem(g)
if grp:
self.form.propertyGroup.setCurrentText(grp)
for t in sorted(PathPropertyBag.SupportedPropertyType):
self.form.propertyType.addItem(t)
if PathPropertyBag.SupportedPropertyType[t] == typ:
typ = t
if typ:
self.form.propertyType.setCurrentText(typ)
else:
self.form.propertyType.setCurrentText("String")
self.form.createAnother.setChecked(another)
self.form.propertyGroup.currentTextChanged.connect(self.updateUI)
self.form.propertyGroup.currentIndexChanged.connect(self.updateUI)
self.form.propertyName.textChanged.connect(self.updateUI)
self.form.propertyType.currentIndexChanged.connect(self.updateUI)
self.form.propertyEnum.textChanged.connect(self.updateUI)
def updateUI(self):
typeSet = True
if self.propertyIsEnumeration():
self.form.labelEnum.setEnabled(True)
self.form.propertyEnum.setEnabled(True)
typeSet = self.form.propertyEnum.text().strip() != ""
else:
self.form.labelEnum.setEnabled(False)
self.form.propertyEnum.setEnabled(False)
if self.form.propertyEnum.text().strip():
self.form.propertyEnum.setText("")
ok = self.form.buttonBox.button(QtGui.QDialogButtonBox.Ok)
if not re.match("^[A-Za-z0-9_]*$", self.form.propertyName.text()):
typeSet = False
if typeSet and self.propertyGroup():
ok.setEnabled(True)
else:
ok.setEnabled(False)
def propertyName(self):
return self.form.propertyName.text().strip()
def propertyGroup(self):
return self.form.propertyGroup.currentText().strip()
def propertyType(self):
return PathPropertyBag.SupportedPropertyType[
self.form.propertyType.currentText()
].strip()
def propertyInfo(self):
return self.form.propertyInfo.toPlainText().strip()
def createAnother(self):
return self.form.createAnother.isChecked()
def propertyEnumerations(self):
return [s.strip() for s in self.form.propertyEnum.text().strip().split(",")]
def propertyIsEnumeration(self):
return self.propertyType() == "App::PropertyEnumeration"
def exec_(self, name):
if name:
# property exists - this is an edit operation
self.form.propertyName.setText(name)
if self.propertyIsEnumeration():
self.form.propertyEnum.setText(
",".join(self.obj.getEnumerationsOfProperty(name))
)
self.form.propertyInfo.setText(self.obj.getDocumentationOfProperty(name))
self.form.labelName.setEnabled(False)
self.form.propertyName.setEnabled(False)
self.form.labelType.setEnabled(False)
self.form.propertyType.setEnabled(False)
self.form.createAnother.setEnabled(False)
else:
self.form.propertyName.setText("")
self.form.propertyInfo.setText("")
self.form.propertyEnum.setText("")
# self.form.propertyName.setFocus()
self.updateUI()
return self.form.exec_()
class TaskPanel(object):
ColumnName = 0
# ColumnType = 1
ColumnVal = 1
# TableHeaders = ['Property', 'Type', 'Value']
TableHeaders = ["Property", "Value"]
def __init__(self, vobj):
self.obj = vobj.Object
self.props = sorted(self.obj.Proxy.getCustomProperties())
self.form = FreeCADGui.PySideUic.loadUi(":panels/PropertyBag.ui")
# initialized later
self.model = None
self.delegate = None
FreeCAD.ActiveDocument.openTransaction("Edit PropertyBag")
def updateData(self, topLeft, bottomRight):
pass
def _setupProperty(self, i, name):
typ = PathPropertyBag.getPropertyTypeName(self.obj.getTypeIdOfProperty(name))
val = PathUtil.getPropertyValueString(self.obj, name)
info = self.obj.getDocumentationOfProperty(name)
self.model.setData(
self.model.index(i, self.ColumnName), name, QtCore.Qt.EditRole
)
# self.model.setData(self.model.index(i, self.ColumnType), typ, QtCore.Qt.EditRole)
self.model.setData(
self.model.index(i, self.ColumnVal), self.obj, Delegate.RoleObject
)
self.model.setData(
self.model.index(i, self.ColumnVal), name, Delegate.RoleProperty
)
self.model.setData(
self.model.index(i, self.ColumnVal), val, QtCore.Qt.DisplayRole
)
self.model.setData(
self.model.index(i, self.ColumnName), typ, QtCore.Qt.ToolTipRole
)
# self.model.setData(self.model.index(i, self.ColumnType), info, QtCore.Qt.ToolTipRole)
self.model.setData(
self.model.index(i, self.ColumnVal), info, QtCore.Qt.ToolTipRole
)
self.model.item(i, self.ColumnName).setEditable(False)
# self.model.item(i, self.ColumnType).setEditable(False)
def setupUi(self):
Path.Log.track()
self.delegate = Delegate(self.form)
self.model = QtGui.QStandardItemModel(
len(self.props), len(self.TableHeaders), self.form
)
self.model.setHorizontalHeaderLabels(self.TableHeaders)
for i, name in enumerate(self.props):
self._setupProperty(i, name)
self.form.table.setModel(self.model)
self.form.table.setItemDelegateForColumn(self.ColumnVal, self.delegate)
self.form.table.resizeColumnsToContents()
self.model.dataChanged.connect(self.updateData)
self.form.table.selectionModel().selectionChanged.connect(self.propertySelected)
self.form.add.clicked.connect(self.propertyAdd)
self.form.remove.clicked.connect(self.propertyRemove)
self.form.modify.clicked.connect(self.propertyModify)
self.form.table.doubleClicked.connect(self.propertyModifyIndex)
self.propertySelected([])
def accept(self):
FreeCAD.ActiveDocument.commitTransaction()
FreeCADGui.ActiveDocument.resetEdit()
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
def reject(self):
FreeCAD.ActiveDocument.abortTransaction()
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
def propertySelected(self, selection):
Path.Log.track()
if selection:
self.form.modify.setEnabled(True)
self.form.remove.setEnabled(True)
else:
self.form.modify.setEnabled(False)
self.form.remove.setEnabled(False)
def addCustomProperty(self, obj, dialog):
name = dialog.propertyName()
typ = dialog.propertyType()
grp = dialog.propertyGroup()
info = dialog.propertyInfo()
if name:
propname = self.obj.Proxy.addCustomProperty(typ, name, grp, info)
if dialog.propertyIsEnumeration():
setattr(self.obj, name, dialog.propertyEnumerations())
return (propname, info)
return (None, None)
def propertyAdd(self):
Path.Log.track()
more = False
grp = None
typ = None
while True:
dialog = PropertyCreate(self.obj, grp, typ, more)
if dialog.exec_(None):
# if we block signals the view doesn't get updated, surprise, surprise
# self.model.blockSignals(True)
name, info = self.addCustomProperty(self.obj, dialog)
if name:
index = 0
for i in range(self.model.rowCount()):
index = i
if (
self.model.item(i, self.ColumnName).data(QtCore.Qt.EditRole)
> dialog.propertyName()
):
break
self.model.insertRows(index, 1)
self._setupProperty(index, name)
self.form.table.selectionModel().setCurrentIndex(
self.model.index(index, 0), QtCore.QItemSelectionModel.Rows
)
# self.model.blockSignals(False)
more = dialog.createAnother()
else:
more = False
else:
more = False
if not more:
break
def propertyModifyIndex(self, index):
Path.Log.track(index.row(), index.column())
row = index.row()
obj = self.model.item(row, self.ColumnVal).data(Delegate.RoleObject)
nam = self.model.item(row, self.ColumnVal).data(Delegate.RoleProperty)
grp = obj.getGroupOfProperty(nam)
typ = obj.getTypeIdOfProperty(nam)
dialog = PropertyCreate(self.obj, grp, typ, False)
if dialog.exec_(nam):
val = getattr(obj, nam)
obj.removeProperty(nam)
name, info = self.addCustomProperty(self.obj, dialog)
try:
setattr(obj, nam, val)
except Exception:
# this can happen if the old enumeration value doesn't exist anymore
pass
newVal = PathUtil.getPropertyValueString(obj, nam)
self.model.setData(
self.model.index(row, self.ColumnVal), newVal, QtCore.Qt.DisplayRole
)
# self.model.setData(self.model.index(row, self.ColumnType), info, QtCore.Qt.ToolTipRole)
self.model.setData(
self.model.index(row, self.ColumnVal), info, QtCore.Qt.ToolTipRole
)
def propertyModify(self):
Path.Log.track()
rows = []
for index in self.form.table.selectionModel().selectedIndexes():
row = index.row()
if row in rows:
continue
rows.append(row)
self.propertyModifyIndex(index)
def propertyRemove(self):
Path.Log.track()
# first find all rows which need to be removed
rows = []
for index in self.form.table.selectionModel().selectedIndexes():
if not index.row() in rows:
rows.append(index.row())
# then remove them in reverse order so the indexes of the remaining rows
# to delete are still valid
for row in reversed(sorted(rows)):
self.obj.removeProperty(self.model.item(row).data(QtCore.Qt.EditRole))
self.model.removeRow(row)
def Create(name="PropertyBag"):
"""Create(name = 'PropertyBag') ... creates a new setup sheet"""
FreeCAD.ActiveDocument.openTransaction("Create PropertyBag")
pcont = PathPropertyBag.Create(name)
PathIconViewProvider.Attach(pcont.ViewObject, name)
return pcont
PathIconViewProvider.RegisterViewProvider("PropertyBag", ViewProvider)
class PropertyBagCreateCommand(object):
"""Command to create a property container object"""
def __init__(self):
pass
def GetResources(self):
return {
"MenuText": translate("Path_PropertyBag", "PropertyBag"),
"ToolTip": translate(
"Path_PropertyBag",
"Creates an object which can be used to store reference properties.",
),
}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def Activated(self):
sel = FreeCADGui.Selection.getSelectionEx()
obj = Create()
body = None
if sel:
if "PartDesign::Body" == sel[0].Object.TypeId:
body = sel[0].Object
elif hasattr(sel[0].Object, "getParentGeoFeatureGroup"):
body = sel[0].Object.getParentGeoFeatureGroup()
if body:
obj.Label = "Attributes"
group = body.Group
group.append(obj)
body.Group = group
if FreeCAD.GuiUp:
FreeCADGui.addCommand("Path_PropertyBag", PropertyBagCreateCommand())
FreeCAD.Console.PrintLog("Loading PathPropertyBagGui ... done\n")

View File

@@ -21,8 +21,8 @@
# ***************************************************************************
import FreeCAD
import PathScripts.PathLog as PathLog
import PathScripts.PathSetupSheetOpPrototype as PathSetupSheetOpPrototype
import Path
import Path.Base.SetupSheetOpPrototype as PathSetupSheetOpPrototype
from PySide import QtCore, QtGui
@@ -33,10 +33,10 @@ __doc__ = "Task panel editor for Properties"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class _PropertyEditor(object):

View File

@@ -22,13 +22,13 @@
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathGui as PathGui
import PathScripts.PathIconViewProvider as PathIconViewProvider
import PathScripts.PathLog as PathLog
import PathScripts.PathSetupSheet as PathSetupSheet
import PathScripts.PathSetupSheetOpPrototypeGui as PathSetupSheetOpPrototypeGui
import PathScripts.PathUtil as PathUtil
import Path
import Path.Base.Gui.IconViewProvider as PathIconViewProvider
import Path.Base.Gui.SetupSheetOpPrototype as PathSetupSheetOpPrototypeGui
import Path.Base.Gui.Util as PathGuiUtil
import Path.Base.SetupSheet as PathSetupSheet
import Path.Base.Util as PathUtil
import PathGui
from PySide import QtCore, QtGui
@@ -41,10 +41,10 @@ __doc__ = "Task panel editor for a SetupSheet"
LOGLEVEL = False
if LOGLEVEL:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class ViewProvider:
@@ -52,7 +52,7 @@ class ViewProvider:
It's sole job is to provide an icon and invoke the TaskPanel on edit."""
def __init__(self, vobj, name):
PathLog.track(name)
Path.Log.track(name)
vobj.Proxy = self
self.icon = name
# mode = 2
@@ -60,7 +60,7 @@ class ViewProvider:
self.vobj = None
def attach(self, vobj):
PathLog.track()
Path.Log.track()
self.vobj = vobj
self.obj = vobj.Object
@@ -77,7 +77,7 @@ class ViewProvider:
return "Default"
def setEdit(self, vobj, mode=0):
PathLog.track()
Path.Log.track()
taskPanel = TaskPanel(vobj)
FreeCADGui.Control.closeDialog()
FreeCADGui.Control.showDialog(taskPanel)
@@ -106,11 +106,11 @@ class Delegate(QtGui.QStyledItemDelegate):
return index.data(self.EditorRole).widget(parent)
def setEditorData(self, widget, index):
PathLog.track(index.row(), index.column())
Path.Log.track(index.row(), index.column())
index.data(self.EditorRole).setEditorData(widget)
def setModelData(self, widget, model, index):
PathLog.track(index.row(), index.column())
Path.Log.track(index.row(), index.column())
editor = index.data(self.EditorRole)
editor.setModelData(widget)
index.model().setData(index, editor.prop.displayString(), QtCore.Qt.DisplayRole)
@@ -150,7 +150,7 @@ class OpTaskPanel:
self.model.item(topLeft.row(), 2).setEnabled(isset)
def setupUi(self):
PathLog.track()
Path.Log.track()
self.delegate = Delegate(self.form)
self.model = QtGui.QStandardItemModel(len(self.props), 3, self.form)
@@ -242,7 +242,7 @@ class OpsDefaultEditor:
def accept(self):
if any([op.accept() for op in self.ops]):
PathLog.track()
Path.Log.track()
def getFields(self):
pass
@@ -259,7 +259,7 @@ class OpsDefaultEditor:
self.currentOp.form.show()
def updateModel(self, recomp=True):
PathLog.track()
Path.Log.track()
self.getFields()
self.updateUI()
if recomp:
@@ -324,7 +324,7 @@ class GlobalEditor(object):
combo.blockSignals(False)
def updateUI(self):
PathLog.track()
Path.Log.track()
self.form.setupStartDepthExpr.setText(self.obj.StartDepthExpression)
self.form.setupFinalDepthExpr.setText(self.obj.FinalDepthExpression)
self.form.setupStepDownExpr.setText(self.obj.StepDownExpression)
@@ -337,7 +337,7 @@ class GlobalEditor(object):
self.selectInComboBox(self.obj.CoolantMode, self.form.setupCoolantMode)
def updateModel(self, recomp=True):
PathLog.track()
Path.Log.track()
self.getFields()
self.updateUI()
if recomp:
@@ -347,16 +347,16 @@ class GlobalEditor(object):
self.updateUI()
def setupUi(self):
self.clearanceHeightOffs = PathGui.QuantitySpinBox(
self.clearanceHeightOffs = PathGuiUtil.QuantitySpinBox(
self.form.setupClearanceHeightOffs, self.obj, "ClearanceHeightOffset"
)
self.safeHeightOffs = PathGui.QuantitySpinBox(
self.safeHeightOffs = PathGuiUtil.QuantitySpinBox(
self.form.setupSafeHeightOffs, self.obj, "SafeHeightOffset"
)
self.rapidHorizontal = PathGui.QuantitySpinBox(
self.rapidHorizontal = PathGuiUtil.QuantitySpinBox(
self.form.setupRapidHorizontal, self.obj, "HorizRapid"
)
self.rapidVertical = PathGui.QuantitySpinBox(
self.rapidVertical = PathGuiUtil.QuantitySpinBox(
self.form.setupRapidVertical, self.obj, "VertRapid"
)
self.form.setupCoolantMode.addItems(self.obj.CoolantModes)
@@ -369,7 +369,7 @@ class TaskPanel:
def __init__(self, vobj):
self.vobj = vobj
self.obj = vobj.Object
PathLog.track(self.obj.Label)
Path.Log.track(self.obj.Label)
self.globalForm = FreeCADGui.PySideUic.loadUi(":/panels/SetupGlobal.ui")
self.globalEditor = GlobalEditor(self.obj, self.globalForm)
self.opsEditor = OpsDefaultEditor(self.obj, None)

View File

@@ -21,8 +21,8 @@
# ***************************************************************************
import FreeCAD
import PathScripts.PathLog as PathLog
import PathScripts.PathSetupSheetOpPrototype as PathSetupSheetOpPrototype
import Path
import Path.Base.SetupSheetOpPrototype as PathSetupSheetOpPrototype
from PySide import QtCore, QtGui
@@ -35,10 +35,10 @@ __doc__ = "Task panel editor for a SetupSheet"
LOGLEVEL = False
if LOGLEVEL:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class _PropertyEditor(object):
@@ -68,7 +68,7 @@ class _PropertyEnumEditor(_PropertyEditor):
"""Editor for enumeration values - uses a combo box."""
def widget(self, parent):
PathLog.track(self.prop.name, self.prop.getEnumValues())
Path.Log.track(self.prop.name, self.prop.getEnumValues())
return QtGui.QComboBox(parent)
def setEditorData(self, widget):

View File

@@ -22,9 +22,8 @@
import FreeCAD
import FreeCADGui
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathUtil as PathUtil
import Path
import Path.Base.Util as PathUtil
from PySide import QtGui, QtCore
from PySide import QtCore, QtGui
@@ -36,10 +35,10 @@ __doc__ = "A collection of helper and utility functions for the Path GUI."
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
def populateCombobox(form, enumTups, comboBoxesPropertyMap):
@@ -50,7 +49,7 @@ def populateCombobox(form, enumTups, comboBoxesPropertyMap):
enumTups = list of (translated_text, data_string) tuples
comboBoxesPropertyMap = list of (translated_text, data_string) tuples
"""
PathLog.track(enumTups)
Path.Log.track(enumTups)
# Load appropriate enumerations in each combobox
for cb, prop in comboBoxesPropertyMap:
@@ -70,12 +69,12 @@ def updateInputField(obj, prop, widget, onBeforeChange=None):
Returns True if a new value was assigned, False otherwise (new value is the same as the current).
"""
value = widget.property("rawValue")
PathLog.track("value: {}".format(value))
Path.Log.track("value: {}".format(value))
attr = PathUtil.getProperty(obj, prop)
attrValue = attr.Value if hasattr(attr, "Value") else attr
isDiff = False
if not PathGeom.isRoughly(attrValue, value):
if not Path.Geom.isRoughly(attrValue, value):
isDiff = True
else:
if hasattr(obj, "ExpressionEngine"):
@@ -83,9 +82,9 @@ def updateInputField(obj, prop, widget, onBeforeChange=None):
for (prp, expr) in obj.ExpressionEngine:
if prp == prop:
exprSet = True
PathLog.debug('prop = "expression": {} = "{}"'.format(prp, expr))
Path.Log.debug('prop = "expression": {} = "{}"'.format(prp, expr))
value = FreeCAD.Units.Quantity(obj.evalExpression(expr)).Value
if not PathGeom.isRoughly(attrValue, value):
if not Path.Geom.isRoughly(attrValue, value):
isDiff = True
break
if exprSet:
@@ -97,7 +96,7 @@ def updateInputField(obj, prop, widget, onBeforeChange=None):
widget.update()
if isDiff:
PathLog.debug(
Path.Log.debug(
"updateInputField(%s, %s): %.2f -> %.2f" % (obj.Label, prop, attr, value)
)
if onBeforeChange:
@@ -120,7 +119,7 @@ class QuantitySpinBox(QtCore.QObject):
def __init__(self, widget, obj, prop, onBeforeChange=None):
super().__init__()
PathLog.track(widget)
Path.Log.track(widget)
self.widget = widget
self.onBeforeChange = onBeforeChange
self.prop = None
@@ -150,7 +149,7 @@ class QuantitySpinBox(QtCore.QObject):
def attachTo(self, obj, prop=None):
"""attachTo(obj, prop=None) ... use an existing editor for the given object and property"""
PathLog.track(self.prop, prop)
Path.Log.track(self.prop, prop)
self.obj = obj
self.prop = prop
if obj and prop:
@@ -161,21 +160,21 @@ class QuantitySpinBox(QtCore.QObject):
self.widget.setProperty("binding", "%s.%s" % (obj.Name, prop))
self.valid = True
else:
PathLog.warning("Cannot find property {} of {}".format(prop, obj.Label))
Path.Log.warning("Cannot find property {} of {}".format(prop, obj.Label))
self.valid = False
else:
self.valid = False
def expression(self):
"""expression() ... returns the expression if one is bound to the property"""
PathLog.track(self.prop, self.valid)
Path.Log.track(self.prop, self.valid)
if self.valid:
return self.widget.property("expression")
return ""
def setMinimum(self, quantity):
"""setMinimum(quantity) ... set the minimum"""
PathLog.track(self.prop, self.valid)
Path.Log.track(self.prop, self.valid)
if self.valid:
value = quantity.Value if hasattr(quantity, "Value") else quantity
self.widget.setProperty("setMinimum", value)
@@ -184,7 +183,7 @@ class QuantitySpinBox(QtCore.QObject):
"""updateSpinBox(quantity=None) ... update the display value of the spin box.
If no value is provided the value of the bound property is used.
quantity can be of type Quantity or Float."""
PathLog.track(self.prop, self.valid, quantity)
Path.Log.track(self.prop, self.valid, quantity)
if self.valid:
expr = self._hasExpression()
@@ -205,7 +204,7 @@ class QuantitySpinBox(QtCore.QObject):
def updateProperty(self):
"""updateProperty() ... update the bound property with the value from the spin box"""
PathLog.track(self.prop, self.valid)
Path.Log.track(self.prop, self.valid)
if self.valid:
return updateInputField(
self.obj, self.prop, self.widget, self.onBeforeChange

View File

View File

@@ -26,15 +26,15 @@ __url__ = "https://www.freecadweb.org"
__doc__ = "Dataclass to implement a machinestate tracker"
__contributors__ = ""
import PathScripts.PathLog as PathLog
import Path
import FreeCAD
from PathScripts.PathGeom import CmdMoveRapid, CmdMoveAll, CmdMoveDrill
import Path
if True:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
if False:
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class MachineState:
@@ -92,7 +92,7 @@ class MachineState:
self.WCS = command.Name
return not oldstate == self.getState()
if command.Name in CmdMoveDrill:
if command.Name in Path.Geom.CmdMoveDrill:
oldZ = self.Z
for p in command.Parameters:
self.__setattr__(p, command.Parameters[p])

View File

@@ -20,7 +20,7 @@
# * *
# ***************************************************************************
import PathScripts.PathLog as PathLog
import Path
__title__ = "Property type abstraction for editing purposes"
__author__ = "sliptonic (Brad Collette)"
@@ -28,8 +28,8 @@ __url__ = "https://www.freecadweb.org"
__doc__ = "Prototype objects to allow extraction of setup sheet values and editing."
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
# PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
# Path.Log.trackModule(Path.Log.thisModule())
class Property(object):

View File

@@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * Copyright (c) 2020 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 PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import Path
import re
__title__ = "Generic property container to store some values."
__author__ = "sliptonic (Brad Collette)"
__url__ = "https://www.freecadweb.org"
__doc__ = "A generic container for typed properties in arbitrary categories."
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
SupportedPropertyType = {
"Angle": "App::PropertyAngle",
"Bool": "App::PropertyBool",
"Distance": "App::PropertyDistance",
"Enumeration": "App::PropertyEnumeration",
"File": "App::PropertyFile",
"Float": "App::PropertyFloat",
"Integer": "App::PropertyInteger",
"Length": "App::PropertyLength",
"Percent": "App::PropertyPercent",
"String": "App::PropertyString",
}
def getPropertyTypeName(o):
for typ in SupportedPropertyType:
if SupportedPropertyType[typ] == o:
return typ
raise IndexError()
class PropertyBag(object):
"""Property container object."""
CustomPropertyGroups = "CustomPropertyGroups"
CustomPropertyGroupDefault = "User"
def __init__(self, obj):
obj.addProperty(
"App::PropertyStringList",
self.CustomPropertyGroups,
"Base",
QT_TRANSLATE_NOOP("App::Property", "List of custom property groups"),
)
self.onDocumentRestored(obj)
def __getstate__(self):
return None
def __setstate__(self, state):
return None
def __sanitizePropertyName(self, name):
if len(name) == 0:
return
clean = name[0]
for i in range(1, len(name)):
if name[i] == " ":
clean += name[i + 1].upper()
i += 1
elif name[i - 1] != " ":
clean += name[i]
return clean
def onDocumentRestored(self, obj):
self.obj = obj
obj.setEditorMode(self.CustomPropertyGroups, 2) # hide
def getCustomProperties(self):
"""getCustomProperties() ... Return a list of all custom properties created in this container."""
return [
p
for p in self.obj.PropertiesList
if self.obj.getGroupOfProperty(p) in self.obj.CustomPropertyGroups
]
def addCustomProperty(self, propertyType, name, group=None, desc=None):
"""addCustomProperty(propertyType, name, group=None, desc=None) ... adds a custom property and tracks its group."""
if desc is None:
desc = ""
if group is None:
group = self.CustomPropertyGroupDefault
groups = self.obj.CustomPropertyGroups
name = self.__sanitizePropertyName(name)
if not re.match("^[A-Za-z0-9_]*$", name):
raise ValueError("Property Name can only contain letters and numbers")
if not group in groups:
groups.append(group)
self.obj.CustomPropertyGroups = groups
self.obj.addProperty(propertyType, name, group, desc)
return name
def refreshCustomPropertyGroups(self):
"""refreshCustomPropertyGroups() ... removes empty property groups, should be called after deleting properties."""
customGroups = []
for p in self.obj.PropertiesList:
group = self.obj.getGroupOfProperty(p)
if group in self.obj.CustomPropertyGroups and not group in customGroups:
customGroups.append(group)
self.obj.CustomPropertyGroups = customGroups
def Create(name="PropertyBag"):
obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython", name)
obj.Proxy = PropertyBag(obj)
return obj
def IsPropertyBag(obj):
"""Returns True if the supplied object is a property container (or its Proxy)."""
if type(obj) == PropertyBag:
return True
if hasattr(obj, "Proxy"):
return IsPropertyBag(obj.Proxy)
return False

View File

@@ -21,10 +21,9 @@
# ***************************************************************************
import FreeCAD
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathSetupSheetOpPrototype as PathSetupSheetOpPrototype
import PathScripts.PathUtil as PathUtil
import Path
import Path.Base.Util as PathUtil
import Path.Base.SetupSheetOpPrototype as PathSetupSheetOpPrototype
from PySide.QtCore import QT_TRANSLATE_NOOP
__title__ = "Setup Sheet for a Job."
@@ -36,10 +35,10 @@ _RegisteredOps: dict = {}
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class Template:
@@ -73,20 +72,20 @@ class Template:
def _traverseTemplateAttributes(attrs, codec):
PathLog.debug(attrs)
Path.Log.debug(attrs)
coded = {}
for key, value in PathUtil.keyValueIter(attrs):
if type(value) == dict:
PathLog.debug("%s is a dict" % key)
Path.Log.debug("%s is a dict" % key)
coded[key] = _traverseTemplateAttributes(value, codec)
elif type(value) == list:
PathLog.debug("%s is a list" % key)
Path.Log.debug("%s is a list" % key)
coded[key] = [_traverseTemplateAttributes(attr, codec) for attr in value]
elif PathUtil.isString(value):
PathLog.debug("%s is a string" % key)
Path.Log.debug("%s is a string" % key)
coded[key] = codec(value)
else:
PathLog.debug("%s is %s" % (key, type(value)))
Path.Log.debug("%s is %s" % (key, type(value)))
coded[key] = value
return coded
@@ -234,7 +233,7 @@ class SetupSheet:
return None
def hasDefaultToolRapids(self):
return PathGeom.isRoughly(self.obj.VertRapid.Value, 0) and PathGeom.isRoughly(
return Path.Geom.isRoughly(self.obj.VertRapid.Value, 0) and Path.Geom.isRoughly(
self.obj.HorizRapid.Value, 0
)
@@ -394,7 +393,7 @@ class SetupSheet:
return list(sorted(ops))
def setOperationProperties(self, obj, opName):
PathLog.track(obj.Label, opName)
Path.Log.track(obj.Label, opName)
try:
op = _RegisteredOps[opName]
for prop in op.properties():
@@ -402,7 +401,7 @@ class SetupSheet:
if hasattr(self.obj, propName):
setattr(obj, prop, getattr(self.obj, propName))
except Exception:
PathLog.info("SetupSheet has no support for {}".format(opName))
Path.Log.info("SetupSheet has no support for {}".format(opName))
def onDocumentRestored(self, obj):

View File

@@ -20,7 +20,7 @@
# * *
# ***************************************************************************
import PathScripts.PathLog as PathLog
import Path
__title__ = "Setup Sheet for a Job."
__author__ = "sliptonic (Brad Collette)"
@@ -28,8 +28,8 @@ __url__ = "https://www.freecadweb.org"
__doc__ = "Prototype objects to allow extraction of setup sheet values and editing."
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
# PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
# Path.Log.trackModule(Path.Log.thisModule())
class Property(object):
@@ -65,11 +65,11 @@ class Property(object):
def setupProperty(self, obj, name, category, value):
created = False
if not hasattr(obj, name):
PathLog.track('add', obj.Name, name, self.propType)
Path.Log.track('add', obj.Name, name, self.propType)
obj.addProperty(self.propType, name, category, self.info)
self.initProperty(obj, name)
created = True
PathLog.track('set', obj.Name, name, value, type(value))
Path.Log.track('set', obj.Name, name, value, type(value))
setattr(obj, name, value)
return created
@@ -127,7 +127,11 @@ class PropertyFloat(Property):
return "Float"
def valueFromString(self, string):
return float(string)
try:
return float(string)
except ValueError:
Path.Log.error(f"{self.category}.{self.name} [{self.propType}] : '{string}'")
raise
class PropertyInteger(Property):
@@ -135,7 +139,11 @@ class PropertyInteger(Property):
return "Integer"
def valueFromString(self, string):
return int(string)
try:
return int(string)
except ValueError:
Path.Log.error(f"{self.category}.{self.name} [{self.propType}] : '{string}'")
raise
class PropertyPercent(PropertyInteger):
@@ -148,7 +156,11 @@ class PropertyBool(Property):
return "Bool"
def valueFromString(self, string):
return bool(string)
try:
return bool(string)
except ValueError:
Path.Log.error(f"{self.category}.{self.name} [{self.propType}] : '{string}'")
raise
class PropertyString(Property):

View File

@@ -22,25 +22,25 @@
"""
The purpose of this file is to collect some handy functions. The reason they
are not in PathUtils (and there is this confusing naming going on) is that
are not in Path.Base.Utils (and there is this confusing naming going on) is that
PathUtils depends on PathJob. Which makes it impossible to use the functions
and classes defined there in PathJob.
So if you add to this file and think about importing anything from PathScripts
other than PathLog, then it probably doesn't belong here.
other than Path.Log, then it probably doesn't belong here.
"""
import FreeCAD
import six
import PathScripts.PathLog as PathLog
import Path
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
def _getProperty(obj, prop):
@@ -54,13 +54,13 @@ def _getProperty(obj, prop):
attr = getattr(o, name)
if o == attr:
PathLog.warning(
Path.Log.warning(
translate("PathGui", "%s has no property %s (%s))")
% (obj.Label, prop, name)
)
return (None, None, None)
# PathLog.debug("found property %s of %s (%s: %s)" % (prop, obj.Label, name, attr))
# Path.Log.debug("found property %s of %s (%s: %s)" % (prop, obj.Label, name, attr))
return (o, attr, name)
@@ -98,18 +98,18 @@ def isValidBaseObject(obj):
"""isValidBaseObject(obj) ... returns true if the object can be used as a base for a job."""
if hasattr(obj, "getParentGeoFeatureGroup") and obj.getParentGeoFeatureGroup():
# Can't link to anything inside a geo feature group anymore
PathLog.debug("%s is inside a geo feature group" % obj.Label)
Path.Log.debug("%s is inside a geo feature group" % obj.Label)
return False
if hasattr(obj, "BitBody") and hasattr(obj, "BitShape"):
# ToolBit's are not valid base objects
return False
if obj.TypeId in NotValidBaseTypeIds:
PathLog.debug("%s is blacklisted (%s)" % (obj.Label, obj.TypeId))
Path.Log.debug("%s is blacklisted (%s)" % (obj.Label, obj.TypeId))
return False
if hasattr(obj, "Sheets") or hasattr(
obj, "TagText"
): # Arch.Panels and Arch.PanelCut
PathLog.debug("%s is not an Arch.Panel" % (obj.Label))
Path.Log.debug("%s is not an Arch.Panel" % (obj.Label))
return False
import Part

View File

View File

@@ -23,18 +23,16 @@
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import Path
import PathScripts.PathDressup as PathDressup
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathStock as PathStock
import PathScripts.PathUtil as PathUtil
import Path.Base.Util as PathUtil
import Path.Dressup.Utils as PathDressup
import Path.Main.Stock as PathStock
import PathScripts.PathUtils as PathUtils
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -127,8 +125,8 @@ class PathBoundary:
self.strG0ZclearanceHeight = None
def boundaryCommands(self, begin, end, verticalFeed):
PathLog.track(_vstr(begin), _vstr(end))
if end and PathGeom.pointsCoincide(begin, end):
Path.Log.track(_vstr(begin), _vstr(end))
if end and Path.Geom.pointsCoincide(begin, end):
return []
cmds = []
if begin.z < self.safeHeight:
@@ -152,7 +150,7 @@ class PathBoundary:
return None
if len(self.baseOp.Path.Commands) == 0:
PathLog.warning("No Path Commands for %s" % self.baseOp.Label)
Path.Log.warning("No Path Commands for %s" % self.baseOp.Label)
return []
tc = PathDressup.toolController(self.baseOp)
@@ -173,12 +171,12 @@ class PathBoundary:
commands = [cmd]
lastExit = None
for cmd in self.baseOp.Path.Commands[1:]:
if cmd.Name in PathGeom.CmdMoveAll:
if cmd.Name in Path.Geom.CmdMoveAll:
if bogusX:
bogusX = "X" not in cmd.Parameters
if bogusY:
bogusY = "Y" not in cmd.Parameters
edge = PathGeom.edgeForCmd(cmd, pos)
edge = Path.Geom.edgeForCmd(cmd, pos)
if edge:
inside = edge.common(self.boundary).Edges
outside = edge.cut(self.boundary).Edges
@@ -189,7 +187,7 @@ class PathBoundary:
# it's really a shame that one cannot trust the sequence and/or
# orientation of edges
if 1 == len(inside) and 0 == len(outside):
PathLog.track(_vstr(pos), _vstr(lastExit), " + ", cmd)
Path.Log.track(_vstr(pos), _vstr(lastExit), " + ", cmd)
# cmd fully included by boundary
if lastExit:
if not (
@@ -202,25 +200,25 @@ class PathBoundary:
)
lastExit = None
commands.append(cmd)
pos = PathGeom.commandEndPoint(cmd, pos)
pos = Path.Geom.commandEndPoint(cmd, pos)
elif 0 == len(inside) and 1 == len(outside):
PathLog.track(_vstr(pos), _vstr(lastExit), " - ", cmd)
Path.Log.track(_vstr(pos), _vstr(lastExit), " - ", cmd)
# cmd fully excluded by boundary
if not lastExit:
lastExit = pos
pos = PathGeom.commandEndPoint(cmd, pos)
pos = Path.Geom.commandEndPoint(cmd, pos)
else:
PathLog.track(
Path.Log.track(
_vstr(pos), _vstr(lastExit), len(inside), len(outside), cmd
)
# cmd pierces boundary
while inside or outside:
ie = [e for e in inside if PathGeom.edgeConnectsTo(e, pos)]
PathLog.track(ie)
ie = [e for e in inside if Path.Geom.edgeConnectsTo(e, pos)]
Path.Log.track(ie)
if ie:
e = ie[0]
LastPt = e.valueAt(e.LastParameter)
flip = PathGeom.pointsCoincide(pos, LastPt)
flip = Path.Geom.pointsCoincide(pos, LastPt)
newPos = e.valueAt(e.FirstParameter) if flip else LastPt
# inside edges are taken at this point (see swap of inside/outside
# above - so we can just connect the dots ...
@@ -232,12 +230,12 @@ class PathBoundary:
)
)
lastExit = None
PathLog.track(e, flip)
Path.Log.track(e, flip)
if not (
bogusX or bogusY
): # don't insert false paths based on bogus m/c position
commands.extend(
PathGeom.cmdsForEdge(
Path.Geom.cmdsForEdge(
e,
flip,
False,
@@ -253,13 +251,13 @@ class PathBoundary:
oe = [
e
for e in outside
if PathGeom.edgeConnectsTo(e, pos)
if Path.Geom.edgeConnectsTo(e, pos)
]
PathLog.track(oe)
Path.Log.track(oe)
if oe:
e = oe[0]
ptL = e.valueAt(e.LastParameter)
flip = PathGeom.pointsCoincide(pos, ptL)
flip = Path.Geom.pointsCoincide(pos, ptL)
newPos = (
e.valueAt(e.FirstParameter) if flip else ptL
)
@@ -268,7 +266,7 @@ class PathBoundary:
outside.remove(e)
pos = newPos
else:
PathLog.error("huh?")
Path.Log.error("huh?")
import Part
Part.show(Part.Vertex(pos), "pos")
@@ -281,16 +279,16 @@ class PathBoundary:
# Eif
# Ewhile
# Eif
# pos = PathGeom.commandEndPoint(cmd, pos)
# pos = Path.Geom.commandEndPoint(cmd, pos)
# Eif
else:
PathLog.track("no-move", cmd)
Path.Log.track("no-move", cmd)
commands.append(cmd)
if lastExit:
commands.extend(self.boundaryCommands(lastExit, None, tc.VertFeed.Value))
lastExit = None
PathLog.track(commands)
Path.Log.track(commands)
return Path.Path(commands)
@@ -301,7 +299,7 @@ def Create(base, name="DressupPathBoundary"):
"""Create(base, name='DressupPathBoundary') ... creates a dressup limiting base's Path to a boundary."""
if not base.isDerivedFrom("Path::Feature"):
PathLog.error(
Path.Log.error(
translate("Path_DressupPathBoundary", "The selected object is not a path")
+ "\n"
)

View File

@@ -23,18 +23,15 @@
import FreeCAD
import Path
import math
import PathScripts.PathGeom as PathGeom
import Path.Base.Gui.Util as PathGuiUtil
import PathScripts.PathUtils as PathUtils
import PathScripts.PathGui as PathGui
import PathScripts.PathLog as PathLog
from PySide.QtCore import QT_TRANSLATE_NOOP
from PathScripts.PathGeom import CmdMoveArc
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
if FreeCAD.GuiUp:
@@ -89,11 +86,11 @@ class ObjectDressup:
currLocation = {"X": 0, "Y": 0, "Z": 0, "F": 0}
for p in path:
if p.Name in CmdMoveArc:
if p.Name in Path.Geom.CmdMoveArc:
curVec = FreeCAD.Vector(
currLocation["X"], currLocation["Y"], currLocation["Z"]
)
arcwire = PathGeom.edgeForCmd(p, curVec)
arcwire = Path.Geom.edgeForCmd(p, curVec)
pointlist = arcwire.discretize(Deflection=d)
for point in pointlist:
newcommand = Path.Command(
@@ -118,7 +115,7 @@ class ObjectDressup:
if obj.Base.Path:
if obj.Base.Path.Commands:
pp = obj.Base.Path.Commands
if len([i for i in pp if i.Name in CmdMoveArc]) == 0:
if len([i for i in pp if i.Name in Path.Geom.CmdMoveArc]) == 0:
pathlist = pp
else:
pathlist = self._stripArcs(pp, d)
@@ -171,7 +168,7 @@ class TaskPanel:
def __init__(self, obj):
self.obj = obj
self.form = FreeCADGui.PySideUic.loadUi(":/panels/AxisMapEdit.ui")
self.radius = PathGui.QuantitySpinBox(self.form.radius, obj, "Radius")
self.radius = PathGuiUtil.QuantitySpinBox(self.form.radius, obj, "Radius")
FreeCAD.ActiveDocument.openTransaction("Edit Dragknife Dress-up")
def reject(self):
@@ -299,19 +296,19 @@ class CommandPathDressup:
# everything ok!
FreeCAD.ActiveDocument.openTransaction("Create Dress-up")
FreeCADGui.addModule("PathScripts.PathDressupAxisMap")
FreeCADGui.addModule("Path.Dressup.Gui.AxisMap")
FreeCADGui.addModule("PathScripts.PathUtils")
FreeCADGui.doCommand(
'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "AxisMapDressup")'
)
FreeCADGui.doCommand("PathScripts.PathDressupAxisMap.ObjectDressup(obj)")
FreeCADGui.doCommand("Path.Dressup.Gui.AxisMap.ObjectDressup(obj)")
FreeCADGui.doCommand("base = FreeCAD.ActiveDocument." + selection[0].Name)
FreeCADGui.doCommand("job = PathScripts.PathUtils.findParentJob(base)")
FreeCADGui.doCommand("obj.Base = base")
FreeCADGui.doCommand("obj.Radius = 45")
FreeCADGui.doCommand("job.Proxy.addOperation(obj, base)")
FreeCADGui.doCommand(
"obj.ViewObject.Proxy = PathScripts.PathDressupAxisMap.ViewProviderDressup(obj.ViewObject)"
"obj.ViewObject.Proxy = Path.Dressup.Gui.AxisMap.ViewProviderDressup(obj.ViewObject)"
)
FreeCADGui.doCommand(
"Gui.ActiveDocument.getObject(base.Name).Visibility = False"

View File

@@ -24,15 +24,15 @@ from PySide import QtGui
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathDressupPathBoundary as PathDressupPathBoundary
import PathScripts.PathLog as PathLog
import Path
import Path.Dressup.Boundary as PathDressupPathBoundary
import PathGui
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -112,11 +112,11 @@ class TaskPanel(object):
self.setClean()
def updateStockEditor(self, index, force=False):
import PathScripts.PathJobGui as PathJobGui
import PathScripts.PathStock as PathStock
import Path.Main.Gui.Job as PathJobGui
import Path.Main.Stock as PathStock
def setupFromBaseEdit():
PathLog.track(index, force)
Path.Log.track(index, force)
if force or not self.stockFromBase:
self.stockFromBase = PathJobGui.StockFromBaseBoundBoxEdit(
self.obj, self.form, force
@@ -124,7 +124,7 @@ class TaskPanel(object):
self.stockEdit = self.stockFromBase
def setupCreateBoxEdit():
PathLog.track(index, force)
Path.Log.track(index, force)
if force or not self.stockCreateBox:
self.stockCreateBox = PathJobGui.StockCreateBoxEdit(
self.obj, self.form, force
@@ -132,7 +132,7 @@ class TaskPanel(object):
self.stockEdit = self.stockCreateBox
def setupCreateCylinderEdit():
PathLog.track(index, force)
Path.Log.track(index, force)
if force or not self.stockCreateCylinder:
self.stockCreateCylinder = PathJobGui.StockCreateCylinderEdit(
self.obj, self.form, force
@@ -140,7 +140,7 @@ class TaskPanel(object):
self.stockEdit = self.stockCreateCylinder
def setupFromExisting():
PathLog.track(index, force)
Path.Log.track(index, force)
if force or not self.stockFromExisting:
self.stockFromExisting = PathJobGui.StockFromExistingEdit(
self.obj, self.form, force
@@ -162,7 +162,7 @@ class TaskPanel(object):
elif PathJobGui.StockFromExistingEdit.IsStock(self.obj):
setupFromExisting()
else:
PathLog.error(
Path.Log.error(
translate("PathJob", "Unsupported stock object %s")
% self.obj.Stock.Label
)
@@ -178,7 +178,7 @@ class TaskPanel(object):
setupFromBaseEdit()
index = -1
else:
PathLog.error(
Path.Log.error(
translate("PathJob", "Unsupported stock type %s (%d)")
% (self.form.stock.currentText(), index)
)
@@ -280,7 +280,7 @@ class CommandPathDressupPathBoundary:
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelection()
if len(selection) != 1:
PathLog.error(
Path.Log.error(
translate("Path_DressupPathBoundary", "Please select one path object")
+ "\n"
)
@@ -289,9 +289,9 @@ class CommandPathDressupPathBoundary:
# everything ok!
FreeCAD.ActiveDocument.openTransaction("Create Path Boundary Dress-up")
FreeCADGui.addModule("PathScripts.PathDressupPathBoundaryGui")
FreeCADGui.addModule("Path.Dressup.Gui.Boundary")
FreeCADGui.doCommand(
"PathScripts.PathDressupPathBoundaryGui.Create(App.ActiveDocument.%s)"
"Path.Dressup.Gui.Boundary.Create(App.ActiveDocument.%s)"
% baseObject.Name
)
# FreeCAD.ActiveDocument.commitTransaction() # Final `commitTransaction()` called via TaskPanel.accept()
@@ -302,4 +302,4 @@ if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand("Path_DressupPathBoundary", CommandPathDressupPathBoundary())
PathLog.notice("Loading PathDressupPathBoundaryGui... done\n")
Path.Log.notice("Loading PathDressupPathBoundaryGui... done\n")

View File

@@ -26,13 +26,10 @@ from PySide import QtCore
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import Path
import PathScripts.PathDressup as PathDressup
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathUtil as PathUtil
import Path.Base.Util as PathUtil
import Path.Dressup.Utils as PathDressup
import PathScripts.PathUtils as PathUtils
import math
from PathScripts.PathGeom import CmdMoveCW, CmdMoveStraight, CmdMoveArc, CmdMoveRapid
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -42,20 +39,20 @@ Part = LazyLoader("Part", globals(), "Part")
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
movecommands = CmdMoveStraight + CmdMoveRapid + CmdMoveArc
movecommands = Path.Geom.CmdMoveStraight + Path.Geom.CmdMoveRapid + Path.Geom.CmdMoveArc
def debugMarker(vector, label, color=None, radius=0.5):
if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
if Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Sphere", label)
obj.Label = label
obj.Radius = radius
@@ -67,7 +64,7 @@ def debugMarker(vector, label, color=None, radius=0.5):
def debugCircle(vector, r, label, color=None):
if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
if Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Cylinder", label)
obj.Label = label
obj.Radius = r
@@ -119,9 +116,9 @@ def edgesForCommands(cmds, startPt):
for cmd in cmds:
if cmd.Name in movecommands:
pt = pointFromCommand(cmd, lastPt)
if cmd.Name in CmdMoveStraight:
if cmd.Name in Path.Geom.CmdMoveStraight:
edges.append(Part.Edge(Part.LineSegment(lastPt, pt)))
elif cmd.Name in CmdMoveArc:
elif cmd.Name in Path.Geom.CmdMoveArc:
center = lastPt + pointFromCommand(
cmd, FreeCAD.Vector(0, 0, 0), "I", "J", "K"
)
@@ -132,7 +129,7 @@ def edgesForCommands(cmds, startPt):
if d == 0:
# we're dealing with half a circle here
angle = getAngle(A) + math.pi / 2
if cmd.Name in CmdMoveCW:
if cmd.Name in Path.Geom.CmdMoveCW:
angle -= math.pi
else:
C = A + B
@@ -250,8 +247,8 @@ class Chord(object):
def getDirectionOfVector(self, B):
A = self.asDirection()
# if the 2 vectors are identical, they head in the same direction
PathLog.debug(" {}.getDirectionOfVector({})".format(A, B))
if PathGeom.pointsCoincide(A, B):
Path.Log.debug(" {}.getDirectionOfVector({})".format(A, B))
if Path.Geom.pointsCoincide(A, B):
return "Straight"
d = -A.x * B.y + A.y * B.x
if d < 0:
@@ -307,23 +304,23 @@ class Chord(object):
return self.arcCommand("G3", center, f)
def isAPlungeMove(self):
return not PathGeom.isRoughly(self.End.z, self.Start.z)
return not Path.Geom.isRoughly(self.End.z, self.Start.z)
def isANoopMove(self):
PathLog.debug(
Path.Log.debug(
"{}.isANoopMove(): {}".format(
self, PathGeom.pointsCoincide(self.Start, self.End)
self, Path.Geom.pointsCoincide(self.Start, self.End)
)
)
return PathGeom.pointsCoincide(self.Start, self.End)
return Path.Geom.pointsCoincide(self.Start, self.End)
def foldsBackOrTurns(self, chord, side):
direction = chord.getDirectionOf(self)
PathLog.info(" - direction = %s/%s" % (direction, side))
Path.Log.info(" - direction = %s/%s" % (direction, side))
return direction == "Back" or direction == side
def connectsTo(self, chord):
return PathGeom.pointsCoincide(self.End, chord.Start)
return Path.Geom.pointsCoincide(self.End, chord.Start)
class Bone(object):
@@ -378,9 +375,9 @@ class Bone(object):
# for some reason pi/2 is not equal to pi/2
if math.fabs(theta - boneAngle) < 0.00001:
# moving directly towards the corner
PathLog.debug("adaptive - on target: %.2f - %.2f" % (distance, toolRadius))
Path.Log.debug("adaptive - on target: %.2f - %.2f" % (distance, toolRadius))
return distance - toolRadius
PathLog.debug(
Path.Log.debug(
"adaptive - angles: corner=%.2f bone=%.2f diff=%.12f"
% (theta / math.pi, boneAngle / math.pi, theta - boneAngle)
)
@@ -394,11 +391,11 @@ class Bone(object):
beta = math.fabs(addAngle(boneAngle, -theta))
D = (distance / toolRadius) * math.sin(beta)
if D > 1: # no intersection
PathLog.debug("adaptive - no intersection - no bone")
Path.Log.debug("adaptive - no intersection - no bone")
return 0
gamma = math.asin(D)
alpha = math.pi - beta - gamma
if PathGeom.isRoughly(0.0, math.sin(beta)):
if Path.Geom.isRoughly(0.0, math.sin(beta)):
# it is not a good idea to divide by 0
length = 0.0
else:
@@ -410,7 +407,7 @@ class Bone(object):
length2 = toolRadius * math.sin(alpha2) / math.sin(beta2)
length = min(length, length2)
PathLog.debug(
Path.Log.debug(
"adaptive corner=%.2f * %.2f˚ -> bone=%.2f * %.2f˚"
% (distance, theta, length, boneAngle)
)
@@ -496,7 +493,7 @@ class ObjectDressup(object):
# Answer true if a dogbone could be on either end of the chord, given its command
def canAttachDogbone(self, cmd, chord):
return (
cmd.Name in CmdMoveStraight
cmd.Name in Path.Geom.CmdMoveStraight
and not chord.isAPlungeMove()
and not chord.isANoopMove()
)
@@ -505,7 +502,7 @@ class ObjectDressup(object):
return outChord.foldsBackOrTurns(inChord, self.theOtherSideOf(obj.Side))
def findPivotIntersection(self, pivot, pivotEdge, edge, refPt, d, color):
PathLog.track(
Path.Log.track(
"(%.2f, %.2f)^%.2f - [(%.2f, %.2f), (%.2f, %.2f)]"
% (
pivotEdge.Curve.Center.x,
@@ -522,22 +519,22 @@ class ObjectDressup(object):
for pt in DraftGeomUtils.findIntersection(edge, pivotEdge, dts=False):
# debugMarker(pt, "pti.%d-%s.in" % (self.boneId, d), color, 0.2)
distance = (pt - refPt).Length
PathLog.debug(" --> (%.2f, %.2f): %.2f" % (pt.x, pt.y, distance))
Path.Log.debug(" --> (%.2f, %.2f): %.2f" % (pt.x, pt.y, distance))
if not ppt or pptDistance < distance:
ppt = pt
pptDistance = distance
if not ppt:
tangent = DraftGeomUtils.findDistance(pivot, edge)
if tangent:
PathLog.debug("Taking tangent as intersect %s" % tangent)
Path.Log.debug("Taking tangent as intersect %s" % tangent)
ppt = pivot + tangent
else:
PathLog.debug(
Path.Log.debug(
"Taking chord start as intersect %s" % edge.Vertexes[0].Point
)
ppt = edge.Vertexes[0].Point
# debugMarker(ppt, "ptt.%d-%s.in" % (self.boneId, d), color, 0.2)
PathLog.debug(" --> (%.2f, %.2f)" % (ppt.x, ppt.y))
Path.Log.debug(" --> (%.2f, %.2f)" % (ppt.x, ppt.y))
return ppt
def pointIsOnEdge(self, point, edge):
@@ -548,7 +545,7 @@ class ObjectDressup(object):
self, bone, inChord, outChord, edge, wire, corner, smooth, color=None
):
if smooth == 0:
PathLog.info(" No smoothing requested")
Path.Log.info(" No smoothing requested")
return [bone.lastCommand, outChord.g1Command(bone.F)]
d = "in"
@@ -558,13 +555,13 @@ class ObjectDressup(object):
refPoint = outChord.End
if DraftGeomUtils.areColinear(inChord.asEdge(), outChord.asEdge()):
PathLog.info(" straight edge %s" % d)
Path.Log.info(" straight edge %s" % d)
return [outChord.g1Command(bone.F)]
pivot = None
pivotDistance = 0
PathLog.info(
Path.Log.info(
"smooth: (%.2f, %.2f)-(%.2f, %.2f)"
% (
edge.Vertexes[0].Point.x,
@@ -576,7 +573,7 @@ class ObjectDressup(object):
for e in wire.Edges:
self.dbg.append(e)
if type(e.Curve) == Part.LineSegment or type(e.Curve) == Part.Line:
PathLog.debug(
Path.Log.debug(
" (%.2f, %.2f)-(%.2f, %.2f)"
% (
e.Vertexes[0].Point.x,
@@ -586,22 +583,22 @@ class ObjectDressup(object):
)
)
else:
PathLog.debug(
Path.Log.debug(
" (%.2f, %.2f)^%.2f"
% (e.Curve.Center.x, e.Curve.Center.y, e.Curve.Radius)
)
for pt in DraftGeomUtils.findIntersection(edge, e, True, findAll=True):
if not PathGeom.pointsCoincide(pt, corner) and self.pointIsOnEdge(
if not Path.Geom.pointsCoincide(pt, corner) and self.pointIsOnEdge(
pt, e
):
# debugMarker(pt, "candidate-%d-%s" % (self.boneId, d), color, 0.05)
PathLog.debug(" -> candidate")
Path.Log.debug(" -> candidate")
distance = (pt - refPoint).Length
if not pivot or pivotDistance > distance:
pivot = pt
pivotDistance = distance
else:
PathLog.debug(" -> corner intersect")
Path.Log.debug(" -> corner intersect")
if pivot:
# debugCircle(pivot, self.toolRadius, "pivot.%d-%s" % (self.boneId, d), color)
@@ -617,20 +614,20 @@ class ObjectDressup(object):
)
commands = []
if not PathGeom.pointsCoincide(t1, inChord.Start):
PathLog.debug(" add lead in")
if not Path.Geom.pointsCoincide(t1, inChord.Start):
Path.Log.debug(" add lead in")
commands.append(Chord(inChord.Start, t1).g1Command(bone.F))
if bone.obj.Side == Side.Left:
PathLog.debug(" add g3 command")
Path.Log.debug(" add g3 command")
commands.append(Chord(t1, t2).g3Command(pivot, bone.F))
else:
PathLog.debug(
Path.Log.debug(
" add g2 command center=(%.2f, %.2f) -> from (%2f, %.2f) to (%.2f, %.2f"
% (pivot.x, pivot.y, t1.x, t1.y, t2.x, t2.y)
)
commands.append(Chord(t1, t2).g2Command(pivot, bone.F))
if not PathGeom.pointsCoincide(t2, outChord.End):
PathLog.debug(" add lead out")
if not Path.Geom.pointsCoincide(t2, outChord.End):
Path.Log.debug(" add lead out")
commands.append(Chord(t2, outChord.End).g1Command(bone.F))
# debugMarker(pivot, "pivot.%d-%s" % (self.boneId, d), color, 0.2)
@@ -639,7 +636,7 @@ class ObjectDressup(object):
return commands
PathLog.info(" no pivot found - straight command")
Path.Log.info(" no pivot found - straight command")
return [inChord.g1Command(bone.F), outChord.g1Command(bone.F)]
def inOutBoneCommands(self, bone, boneAngle, fixedLength):
@@ -647,7 +644,7 @@ class ObjectDressup(object):
bone.tip = bone.inChord.End # in case there is no bone
PathLog.debug("corner = (%.2f, %.2f)" % (corner.x, corner.y))
Path.Log.debug("corner = (%.2f, %.2f)" % (corner.x, corner.y))
# debugMarker(corner, 'corner', (1., 0., 1.), self.toolRadius)
length = fixedLength
@@ -657,7 +654,7 @@ class ObjectDressup(object):
length = bone.adaptiveLength(boneAngle, self.toolRadius)
if length == 0:
PathLog.info("no bone after all ..")
Path.Log.info("no bone after all ..")
return [bone.lastCommand, bone.outChord.g1Command(bone.F)]
# track length for marker visuals
@@ -746,7 +743,7 @@ class ObjectDressup(object):
def tboneVertical(self, bone):
angle = bone.angle()
boneAngle = math.pi / 2
if PathGeom.isRoughly(angle, math.pi) or angle < 0:
if Path.Geom.isRoughly(angle, math.pi) or angle < 0:
boneAngle = -boneAngle
return self.inOutBoneCommands(bone, boneAngle, self.toolRadius)
@@ -764,7 +761,7 @@ class ObjectDressup(object):
onInString = "out"
if onIn:
onInString = "in"
PathLog.debug(
Path.Log.debug(
"tboneEdge boneAngle[%s]=%.2f (in=%.2f, out=%.2f)"
% (
onInString,
@@ -815,7 +812,7 @@ class ObjectDressup(object):
return [bone.lastCommand, bone.outChord.g1Command(bone.F)]
def insertBone(self, bone):
PathLog.debug(
Path.Log.debug(
">----------------------------------- %d --------------------------------------"
% bone.boneId
)
@@ -826,7 +823,7 @@ class ObjectDressup(object):
self.boneId = bone.boneId
# Specific debugging `if` statement
# if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG and bone.boneId > 2:
# if Path.Log.getLevel(LOG_MODULE) == Path.Log.Level.DEBUG and bone.boneId > 2:
# commands = self.boneCommands(bone, False)
# else:
# commands = self.boneCommands(bone, enabled)
@@ -834,7 +831,7 @@ class ObjectDressup(object):
bone.commands = commands
self.shapes[bone.boneId] = self.boneShapes
PathLog.debug(
Path.Log.debug(
"<----------------------------------- %d --------------------------------------"
% bone.boneId
)
@@ -854,9 +851,9 @@ class ObjectDressup(object):
for pt in cutoff:
# debugCircle(e1.Curve.Center, e1.Curve.Radius, "bone.%d-1" % (self.boneId), (1.,0.,0.))
# debugCircle(e2.Curve.Center, e2.Curve.Radius, "bone.%d-2" % (self.boneId), (0.,1.,0.))
if PathGeom.pointsCoincide(
if Path.Geom.pointsCoincide(
pt, e1.valueAt(e1.LastParameter)
) or PathGeom.pointsCoincide(pt, e2.valueAt(e2.FirstParameter)):
) or Path.Geom.pointsCoincide(pt, e2.valueAt(e2.FirstParameter)):
continue
# debugMarker(pt, "it", (0.0, 1.0, 1.0))
# 1. remove all redundant commands
@@ -869,7 +866,7 @@ class ObjectDressup(object):
commands.append(c1)
# 3. change where c2 starts, this depends on the command itself
c2 = bone2.inCommands[j]
if c2.Name in CmdMoveArc:
if c2.Name in Path.Geom.CmdMoveArc:
center = e2.Curve.Center
offset = center - pt
c2Params = c2.Parameters
@@ -919,7 +916,7 @@ class ObjectDressup(object):
# lastCommand = None
# commands.append(thisCommand)
# continue
PathLog.info("%3d: %s" % (i, thisCommand))
Path.Log.info("%3d: %s" % (i, thisCommand))
if thisCommand.Name in movecommands:
thisChord = lastChord.moveToParameters(thisCommand.Parameters)
thisIsACandidate = self.canAttachDogbone(thisCommand, thisChord)
@@ -929,7 +926,7 @@ class ObjectDressup(object):
and lastCommand
and self.shouldInsertDogbone(obj, lastChord, thisChord)
):
PathLog.info(" Found bone corner: {}".format(lastChord.End))
Path.Log.info(" Found bone corner: {}".format(lastChord.End))
bone = Bone(
boneId,
obj,
@@ -942,7 +939,7 @@ class ObjectDressup(object):
bones = self.insertBone(bone)
boneId += 1
if lastBone:
PathLog.info(" removing potential path crossing")
Path.Log.info(" removing potential path crossing")
# debugMarker(thisChord.Start, "it", (1.0, 0.0, 1.0))
commands, bones = self.removePathCrossing(
commands, lastBone, bone
@@ -951,14 +948,14 @@ class ObjectDressup(object):
lastCommand = bones[-1]
lastBone = bone
elif lastCommand and thisChord.isAPlungeMove():
PathLog.info(" Looking for connection in odds and ends")
Path.Log.info(" Looking for connection in odds and ends")
haveNewLastCommand = False
for chord in (
chord for chord in oddsAndEnds if lastChord.connectsTo(chord)
):
if self.shouldInsertDogbone(obj, lastChord, chord):
PathLog.info(" and there is one")
PathLog.debug(
Path.Log.info(" and there is one")
Path.Log.debug(
" odd/end={} last={}".format(chord, lastChord)
)
bone = Bone(
@@ -973,7 +970,7 @@ class ObjectDressup(object):
bones = self.insertBone(bone)
boneId += 1
if lastBone:
PathLog.info(" removing potential path crossing")
Path.Log.info(" removing potential path crossing")
# debugMarker(chord.Start, "it", (0.0, 1.0, 1.0))
commands, bones = self.removePathCrossing(
commands, lastBone, bone
@@ -987,16 +984,16 @@ class ObjectDressup(object):
commands.append(thisCommand)
lastBone = None
elif thisIsACandidate:
PathLog.info(" is a candidate, keeping for later")
Path.Log.info(" is a candidate, keeping for later")
if lastCommand:
commands.append(lastCommand)
lastCommand = thisCommand
lastBone = None
elif thisChord.isANoopMove():
PathLog.info(" ignoring and dropping noop move")
Path.Log.info(" ignoring and dropping noop move")
continue
else:
PathLog.info(" nope")
Path.Log.info(" nope")
if lastCommand:
commands.append(lastCommand)
lastCommand = None
@@ -1004,43 +1001,43 @@ class ObjectDressup(object):
lastBone = None
if lastChord.isAPlungeMove() and thisIsACandidate:
PathLog.info(" adding to odds and ends")
Path.Log.info(" adding to odds and ends")
oddsAndEnds.append(thisChord)
lastChord = thisChord
else:
if thisCommand.Name[0] != "(":
PathLog.info(" Clean slate")
Path.Log.info(" Clean slate")
if lastCommand:
commands.append(lastCommand)
lastCommand = None
lastBone = None
commands.append(thisCommand)
# for cmd in commands:
# PathLog.debug("cmd = '%s'" % cmd)
# Path.Log.debug("cmd = '%s'" % cmd)
path = Path.Path(commands)
obj.Path = path
def setup(self, obj, initial):
PathLog.info("Here we go ... ")
Path.Log.info("Here we go ... ")
if initial:
if hasattr(obj.Base, "BoneBlacklist"):
# dressing up a bone dressup
obj.Side = obj.Base.Side
else:
PathLog.info("Default side = right")
Path.Log.info("Default side = right")
# otherwise dogbones are opposite of the base path's side
side = Side.Right
if hasattr(obj.Base, "Side") and obj.Base.Side == "Inside":
PathLog.info("inside -> side = left")
Path.Log.info("inside -> side = left")
side = Side.Left
else:
PathLog.info("not inside -> side stays right")
Path.Log.info("not inside -> side stays right")
if hasattr(obj.Base, "Direction") and obj.Base.Direction == "CCW":
PathLog.info("CCW -> switch sides")
Path.Log.info("CCW -> switch sides")
side = Side.oppositeOf(side)
else:
PathLog.info("CW -> stay on side")
Path.Log.info("CW -> stay on side")
obj.Side = side
self.toolRadius = 5
@@ -1074,7 +1071,7 @@ class ObjectDressup(object):
class Marker(object):
def __init__(self, pt, r, h):
if PathGeom.isRoughly(h, 0):
if Path.Geom.isRoughly(h, 0):
h = 0.1
self.pt = pt
self.r = r
@@ -1214,18 +1211,18 @@ class TaskPanel(object):
self.form.customLabel.setEnabled(customSelected)
self.updateBoneList()
if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
if Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG:
for obj in FreeCAD.ActiveDocument.Objects:
if obj.Name.startswith("Shape"):
FreeCAD.ActiveDocument.removeObject(obj.Name)
PathLog.info("object name %s" % self.obj.Name)
Path.Log.info("object name %s" % self.obj.Name)
if hasattr(self.obj.Proxy, "shapes"):
PathLog.info("showing shapes attribute")
Path.Log.info("showing shapes attribute")
for shapes in self.obj.Proxy.shapes.values():
for shape in shapes:
Part.show(shape)
else:
PathLog.info("no shapes attribute found")
Path.Log.info("no shapes attribute found")
def updateModel(self):
self.getFields()
@@ -1275,12 +1272,12 @@ class TaskPanel(object):
class SelObserver(object):
def __init__(self):
import PathScripts.PathSelection as PST
import Path.Op.Gui.Selection as PST
PST.eselect()
def __del__(self):
import PathScripts.PathSelection as PST
import Path.Op.Gui.Selection as PST
PST.clear()
@@ -1343,7 +1340,7 @@ class ViewProviderDressup(object):
def Create(base, name="DogboneDressup"):
"""
Create(obj, name='DogboneDressup') ... dresses the given PathProfile/PathContour object with dogbones.
Create(obj, name='DogboneDressup') ... dresses the given Path.Op.Profile/PathContour object with dogbones.
"""
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
dbo = ObjectDressup(obj, base)
@@ -1395,9 +1392,9 @@ class CommandDressupDogbone(object):
# everything ok!
FreeCAD.ActiveDocument.openTransaction("Create Dogbone Dress-up")
FreeCADGui.addModule("PathScripts.PathDressupDogbone")
FreeCADGui.addModule("Path.Dressup.Gui.Dogbone")
FreeCADGui.doCommand(
"PathScripts.PathDressupDogbone.Create(FreeCAD.ActiveDocument.%s)"
"Path.Dressup.Gui.Dogbone.Create(FreeCAD.ActiveDocument.%s)"
% baseObject.Name
)
# FreeCAD.ActiveDocument.commitTransaction() # Final `commitTransaction()` called via TaskPanel.accept()

View File

@@ -23,10 +23,10 @@
from __future__ import print_function
import FreeCAD
import Path
import Path.Base.Gui.Util as PathGuiUtil
from PySide import QtCore
import math
import PathScripts.PathUtils as PathUtils
import PathScripts.PathGui as PathGui
from PySide.QtCore import QT_TRANSLATE_NOOP
# lazily loaded modules
@@ -498,13 +498,13 @@ class TaskPanel:
def __init__(self, obj):
self.obj = obj
self.form = FreeCADGui.PySideUic.loadUi(":/panels/DragKnifeEdit.ui")
self.filterAngle = PathGui.QuantitySpinBox(
self.filterAngle = PathGuiUtil.QuantitySpinBox(
self.form.filterAngle, obj, "filterAngle"
)
self.offsetDistance = PathGui.QuantitySpinBox(
self.offsetDistance = PathGuiUtil.QuantitySpinBox(
self.form.offsetDistance, obj, "offset"
)
self.pivotHeight = PathGui.QuantitySpinBox(
self.pivotHeight = PathGuiUtil.QuantitySpinBox(
self.form.pivotHeight, obj, "pivotheight"
)
@@ -639,18 +639,18 @@ class CommandDressupDragknife:
# everything ok!
FreeCAD.ActiveDocument.openTransaction("Create Dress-up")
FreeCADGui.addModule("PathScripts.PathDressupDragknife")
FreeCADGui.addModule("Path.Dressup.Gui.Dragknife")
FreeCADGui.addModule("PathScripts.PathUtils")
FreeCADGui.doCommand(
'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","DragknifeDressup")'
)
FreeCADGui.doCommand("PathScripts.PathDressupDragknife.ObjectDressup(obj)")
FreeCADGui.doCommand("Path.Dressup.Gui.Dragknife.ObjectDressup(obj)")
FreeCADGui.doCommand("base = FreeCAD.ActiveDocument." + selection[0].Name)
FreeCADGui.doCommand("job = PathScripts.PathUtils.findParentJob(base)")
FreeCADGui.doCommand("obj.Base = base")
FreeCADGui.doCommand("job.Proxy.addOperation(obj, base)")
FreeCADGui.doCommand(
"obj.ViewObject.Proxy = PathScripts.PathDressupDragknife.ViewProviderDressup(obj.ViewObject)"
"obj.ViewObject.Proxy = Path.Dressup.Gui.Dragknife.ViewProviderDressup(obj.ViewObject)"
)
FreeCADGui.doCommand(
"Gui.ActiveDocument.getObject(base.Name).Visibility = False"

View File

@@ -26,9 +26,7 @@ from __future__ import print_function
import FreeCAD
import FreeCADGui
import Path
import PathScripts.PathDressup as PathDressup
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import Path.Dressup.Utils as PathDressup
import PathScripts.PathUtils as PathUtils
import math
import copy
@@ -42,10 +40,10 @@ from PathPythonGui.simple_edit_panel import SimpleEditPanel
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
movecommands = ["G1", "G01", "G2", "G02", "G3", "G03"]
@@ -186,12 +184,12 @@ class ObjectDressup:
if not obj.Base.Path:
return
if obj.Length < 0:
PathLog.error(
Path.Log.error(
translate("Path_DressupLeadInOut", "Length/Radius positive not Null")
+ "\n"
)
obj.Length = 0.1
self.wire, self.rapids = PathGeom.wireForPath(obj.Base.Path)
self.wire, self.rapids = Path.Geom.wireForPath(obj.Base.Path)
obj.Path = self.generateLeadInOutCurve(obj)
def getDirectionOfPath(self, obj):
@@ -268,12 +266,12 @@ class ObjectDressup:
p0 = queue[0].Placement.Base
p1 = queue[1].Placement.Base
v = self.normalize(p1.sub(p0))
PathLog.debug(" CURRENT_IN Line : P0 Z:{} p1 Z:{}".format(p0.z, p1.z))
Path.Log.debug(" CURRENT_IN Line : P0 Z:{} p1 Z:{}".format(p0.z, p1.z))
else:
p0 = queue[0].Placement.Base
p1 = queue[1].Placement.Base
v = self.normalize(p1.sub(p0))
PathLog.debug(
Path.Log.debug(
" CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format(
p0.x, p0.y, p1.x, p1.y
)
@@ -292,7 +290,7 @@ class ObjectDressup:
vec_n = self.normalize(vec)
vec_inv = self.invert(vec_n)
vec_off = self.multiply(vec_inv, obj.ExtendLeadIn)
PathLog.debug(
Path.Log.debug(
"LineCMD: {}, Vxinv: {}, Vyinv: {}, Vxoff: {}, Vyoff: {}".format(
queue[0].Name, vec_inv.x, vec_inv.y, vec_off.x, vec_off.y
)
@@ -423,7 +421,7 @@ class ObjectDressup:
extendcommand = Path.Command("G1", {"X": p0.x, "Y": p0.y, "F": horizFeed})
results.append(extendcommand)
else:
PathLog.debug(" CURRENT_IN Perp")
Path.Log.debug(" CURRENT_IN Perp")
currLocation.update(results[-1].Parameters)
currLocation["Z"] = p1.z
@@ -464,7 +462,7 @@ class ObjectDressup:
vec_n = self.normalize(vec)
vec_inv = self.invert(vec_n)
vec_off = self.multiply(vec_inv, obj.ExtendLeadOut)
PathLog.debug(
Path.Log.debug(
"LineCMD: {}, Vxinv: {}, Vyinv: {}, Vxoff: {}, Vyoff: {}".format(
queue[0].Name, vec_inv.x, vec_inv.y, vec_off.x, vec_off.y
)
@@ -540,7 +538,7 @@ class ObjectDressup:
)
results.append(extendcommand)
else:
PathLog.debug(" CURRENT_IN Perp")
Path.Log.debug(" CURRENT_IN Perp")
if obj.UseMachineCRC: # crc off
results.append(Path.Command("G40", {}))
@@ -560,7 +558,7 @@ class ObjectDressup:
# Read in all commands
for curCommand in obj.Base.Path.Commands:
PathLog.debug("CurCMD: {}".format(curCommand))
Path.Log.debug("CurCMD: {}".format(curCommand))
if curCommand.Name not in movecommands + rapidcommands:
# Don't worry about non-move commands, just add to output
newpath.append(curCommand)
@@ -587,7 +585,7 @@ class ObjectDressup:
and prevCmd.Name in movecommands
):
# Layer change within move cmds
PathLog.debug(
Path.Log.debug(
"Layer change in move: {}->{}".format(
currLocation["Z"], curCommand.z
)
@@ -608,14 +606,14 @@ class ObjectDressup:
# Go through each layer and add leadIn/Out
idx = 0
for layer in layers:
PathLog.debug("Layer {}".format(idx))
Path.Log.debug("Layer {}".format(idx))
if obj.LeadIn:
temp = self.getLeadStart(obj, layer, action)
newpath.extend(temp)
for cmd in layer:
PathLog.debug("CurLoc: {}, NewCmd: {}!!".format(currLocation, cmd))
Path.Log.debug("CurLoc: {}, NewCmd: {}!!".format(currLocation, cmd))
newpath.append(cmd)
if obj.LeadOut:
@@ -690,7 +688,7 @@ class ViewProviderDressup:
def onDelete(self, arg1=None, arg2=None):
"""this makes sure that the base operation is added back to the project and visible"""
PathLog.debug("Deleting Dressup")
Path.Log.debug("Deleting Dressup")
if arg1.Object and arg1.Object.Base:
FreeCADGui.ActiveDocument.getObject(arg1.Object.Base.Name).Visibility = True
job = PathUtils.findParentJob(self.obj)
@@ -730,33 +728,33 @@ class CommandPathDressupLeadInOut:
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelection()
if len(selection) != 1:
PathLog.error(
Path.Log.error(
translate("Path_DressupLeadInOut", "Please select one path object")
+ "\n"
)
return
baseObject = selection[0]
if not baseObject.isDerivedFrom("Path::Feature"):
PathLog.error(
Path.Log.error(
translate("Path_DressupLeadInOut", "The selected object is not a path")
+ "\n"
)
return
if baseObject.isDerivedFrom("Path::FeatureCompoundPython"):
PathLog.error(
Path.Log.error(
translate("Path_DressupLeadInOut", "Please select a Profile object")
)
return
# everything ok!
FreeCAD.ActiveDocument.openTransaction("Create LeadInOut Dressup")
FreeCADGui.addModule("PathScripts.PathDressupLeadInOut")
FreeCADGui.addModule("Path.Dressup.Gui.LeadInOut")
FreeCADGui.addModule("PathScripts.PathUtils")
FreeCADGui.doCommand(
'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "LeadInOutDressup")'
)
FreeCADGui.doCommand(
"dbo = PathScripts.PathDressupLeadInOut.ObjectDressup(obj)"
"dbo = Path.Dressup.Gui.LeadInOut.ObjectDressup(obj)"
)
FreeCADGui.doCommand("base = FreeCAD.ActiveDocument." + selection[0].Name)
FreeCADGui.doCommand("job = PathScripts.PathUtils.findParentJob(base)")
@@ -764,7 +762,7 @@ class CommandPathDressupLeadInOut:
FreeCADGui.doCommand("job.Proxy.addOperation(obj, base)")
FreeCADGui.doCommand("dbo.setup(obj)")
FreeCADGui.doCommand(
"obj.ViewObject.Proxy = PathScripts.PathDressupLeadInOut.ViewProviderDressup(obj.ViewObject)"
"obj.ViewObject.Proxy = Path.Dressup.Gui.LeadInOut.ViewProviderDressup(obj.ViewObject)"
)
FreeCADGui.doCommand(
"Gui.ActiveDocument.getObject(base.Name).Visibility = False"
@@ -777,4 +775,4 @@ if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand("Path_DressupLeadInOut", CommandPathDressupLeadInOut())
PathLog.notice("Loading Path_DressupLeadInOut... done\n")
Path.Log.notice("Loading Path_DressupLeadInOut... done\n")

View File

@@ -24,9 +24,7 @@ from PathScripts import PathUtils
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import Path
import PathScripts.PathDressup as PathDressup
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import Path.Dressup.Utils as PathDressup
import math
@@ -43,10 +41,10 @@ translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class ObjectDressup:
@@ -158,11 +156,11 @@ class ObjectDressup:
data = list()
idx = 0 if dataType == "translated" else 1
PathLog.debug(enums)
Path.Log.debug(enums)
for k, v in enumerate(enums):
data.append((v, [tup[idx] for tup in enums[v]]))
PathLog.debug(data)
Path.Log.debug(data)
return data
@@ -224,7 +222,7 @@ class ObjectDressup:
self.angle = obj.Angle
self.method = obj.Method
self.wire, self.rapids = PathGeom.wireForPath(obj.Base.Path)
self.wire, self.rapids = Path.Geom.wireForPath(obj.Base.Path)
if self.method in ["RampMethod1", "RampMethod2", "RampMethod3"]:
self.outedges = self.generateRamps()
else:
@@ -237,7 +235,7 @@ class ObjectDressup:
for edge in edges:
israpid = False
for redge in self.rapids:
if PathGeom.edgesMatch(edge, redge):
if Path.Geom.edgesMatch(edge, redge):
israpid = True
if not israpid:
bb = edge.BoundBox
@@ -263,7 +261,7 @@ class ObjectDressup:
projectionlen = plungelen * math.tan(
math.radians(rampangle)
) # length of the forthcoming ramp projected to XY plane
PathLog.debug(
Path.Log.debug(
"Found plunge move at X:{} Y:{} From Z:{} to Z{}, length of ramp: {}".format(
p0.x, p0.y, p0.z, p1.z, projectionlen
)
@@ -284,7 +282,7 @@ class ObjectDressup:
if abs(cp0.z - cp1.z) > 1e-6:
# this edge is not parallel to XY plane, not qualified for ramping.
break
# PathLog.debug("Next edge length {}".format(candidate.Length))
# Path.Log.debug("Next edge length {}".format(candidate.Length))
rampedges.append(candidate)
coveredlen = coveredlen + candidate.Length
@@ -294,7 +292,7 @@ class ObjectDressup:
if i >= len(edges):
break
if len(rampedges) == 0:
PathLog.debug(
Path.Log.debug(
"No suitable edges for ramping, plunge will remain as such"
)
outedges.append(edge)
@@ -310,13 +308,13 @@ class ObjectDressup:
)
else:
rampangle = math.degrees(math.atan(l / plungelen))
PathLog.warning(
Path.Log.warning(
"Cannot cover with desired angle, tightening angle to: {}".format(
rampangle
)
)
# PathLog.debug("Doing ramp to edges: {}".format(rampedges))
# Path.Log.debug("Doing ramp to edges: {}".format(rampedges))
if self.method == "RampMethod1":
outedges.extend(
self.createRampMethod1(
@@ -355,14 +353,14 @@ class ObjectDressup:
def generateHelix(self):
edges = self.wire.Edges
minZ = self.findMinZ(edges)
PathLog.debug("Minimum Z in this path is {}".format(minZ))
Path.Log.debug("Minimum Z in this path is {}".format(minZ))
outedges = []
i = 0
while i < len(edges):
edge = edges[i]
israpid = False
for redge in self.rapids:
if PathGeom.edgesMatch(edge, redge):
if Path.Geom.edgesMatch(edge, redge):
israpid = True
if not israpid:
bb = edge.BoundBox
@@ -375,7 +373,7 @@ class ObjectDressup:
and p0.z > p1.z
):
# plungelen = abs(p0.z-p1.z)
PathLog.debug(
Path.Log.debug(
"Found plunge move at X:{} Y:{} From Z:{} to Z{}, Searching for closed loop".format(
p0.x, p0.y, p0.z, p1.z
)
@@ -396,7 +394,7 @@ class ObjectDressup:
candidate = edges[j]
cp0 = candidate.Vertexes[0].Point
cp1 = candidate.Vertexes[1].Point
if PathGeom.pointsCoincide(p1, cp1):
if Path.Geom.pointsCoincide(p1, cp1):
# found closed loop
loopFound = True
rampedges.append(candidate)
@@ -404,17 +402,17 @@ class ObjectDressup:
if abs(cp0.z - cp1.z) > 1e-6:
# this edge is not parallel to XY plane, not qualified for ramping.
break
# PathLog.debug("Next edge length {}".format(candidate.Length))
# Path.Log.debug("Next edge length {}".format(candidate.Length))
rampedges.append(candidate)
j = j + 1
if j >= len(edges):
break
if len(rampedges) == 0 or not loopFound:
PathLog.debug("No suitable helix found")
Path.Log.debug("No suitable helix found")
outedges.append(edge)
else:
outedges.extend(self.createHelix(rampedges, p0, p1))
if not PathGeom.isRoughly(p1.z, minZ):
if not Path.Geom.isRoughly(p1.z, minZ):
# the edges covered by the helix not handled again,
# unless reached the bottom height
i = j
@@ -432,14 +430,14 @@ class ObjectDressup:
p1 = edge.Vertexes[1].Point
if p0.z > self.ignoreAbove and (
p1.z > self.ignoreAbove
or PathGeom.isRoughly(p1.z, self.ignoreAbove.Value)
or Path.Geom.isRoughly(p1.z, self.ignoreAbove.Value)
):
PathLog.debug("Whole plunge move above 'ignoreAbove', ignoring")
Path.Log.debug("Whole plunge move above 'ignoreAbove', ignoring")
return (edge, True)
elif p0.z > self.ignoreAbove and not PathGeom.isRoughly(
elif p0.z > self.ignoreAbove and not Path.Geom.isRoughly(
p0.z, self.ignoreAbove.Value
):
PathLog.debug(
Path.Log.debug(
"Plunge move partially above 'ignoreAbove', splitting into two"
)
newPoint = FreeCAD.Base.Vector(p0.x, p0.y, self.ignoreAbove)
@@ -474,7 +472,7 @@ class ObjectDressup:
return outedges
def createRampEdge(self, originalEdge, startPoint, endPoint):
# PathLog.debug("Create edge from [{},{},{}] to [{},{},{}]".format(startPoint.x,startPoint.y, startPoint.z, endPoint.x, endPoint.y, endPoint.z))
# Path.Log.debug("Create edge from [{},{},{}] to [{},{},{}]".format(startPoint.x,startPoint.y, startPoint.z, endPoint.x, endPoint.y, endPoint.z))
if (
type(originalEdge.Curve) == Part.Line
or type(originalEdge.Curve) == Part.LineSegment
@@ -487,7 +485,7 @@ class ObjectDressup:
arcMid.z = (startPoint.z + endPoint.z) / 2
return Part.Arc(startPoint, arcMid, endPoint).toShape()
else:
PathLog.error("Edge should not be helix")
Path.Log.error("Edge should not be helix")
def getreversed(self, edges):
"""
@@ -504,7 +502,7 @@ class ObjectDressup:
arcMid = edge.valueAt((edge.FirstParameter + edge.LastParameter) / 2)
outedges.append(Part.Arc(startPoint, arcMid, endPoint).toShape())
else:
PathLog.error("Edge should not be helix")
Path.Log.error("Edge should not be helix")
return outedges
def findMinZ(self, edges):
@@ -544,9 +542,9 @@ class ObjectDressup:
if redge.Length >= rampremaining:
# will reach end of ramp within this edge, needs to be split
p1 = self.getSplitPoint(redge, rampremaining)
splitEdge = PathGeom.splitEdgeAt(redge, p1)
PathLog.debug("Ramp remaining: {}".format(rampremaining))
PathLog.debug(
splitEdge = Path.Geom.splitEdgeAt(redge, p1)
Path.Log.debug("Ramp remaining: {}".format(rampremaining))
Path.Log.debug(
"Got split edge (index: {}) (total len: {}) with lengths: {}, {}".format(
i, redge.Length, splitEdge[0].Length, splitEdge[1].Length
)
@@ -585,7 +583,7 @@ class ObjectDressup:
if not done:
# we did not reach the end of the ramp going this direction, lets reverse.
rampedges = self.getreversed(rampedges)
PathLog.debug("Reversing")
Path.Log.debug("Reversing")
if goingForward:
goingForward = False
else:
@@ -627,8 +625,8 @@ class ObjectDressup:
if redge.Length >= rampremaining:
# will reach end of ramp within this edge, needs to be split
p1 = self.getSplitPoint(redge, rampremaining)
splitEdge = PathGeom.splitEdgeAt(redge, p1)
PathLog.debug(
splitEdge = Path.Geom.splitEdgeAt(redge, p1)
Path.Log.debug(
"Got split edge (index: {}) with lengths: {}, {}".format(
i, splitEdge[0].Length, splitEdge[1].Length
)
@@ -703,11 +701,11 @@ class ObjectDressup:
outedges = []
rampremaining = projectionlen
curPoint = p0 # start from the upper point of plunge
if PathGeom.pointsCoincide(
PathGeom.xy(p0),
PathGeom.xy(rampedges[-1].valueAt(rampedges[-1].LastParameter)),
if Path.Geom.pointsCoincide(
Path.Geom.xy(p0),
Path.Geom.xy(rampedges[-1].valueAt(rampedges[-1].LastParameter)),
):
PathLog.debug(
Path.Log.debug(
"The ramp forms a closed wire, needless to move on original Z height"
)
else:
@@ -715,8 +713,8 @@ class ObjectDressup:
if redge.Length >= rampremaining:
# this edge needs to be split
p1 = self.getSplitPoint(redge, rampremaining)
splitEdge = PathGeom.splitEdgeAt(redge, p1)
PathLog.debug(
splitEdge = Path.Geom.splitEdgeAt(redge, p1)
Path.Log.debug(
"Got split edges with lengths: {}, {}".format(
splitEdge[0].Length, splitEdge[1].Length
)
@@ -786,13 +784,13 @@ class ObjectDressup:
for edge in edges:
israpid = False
for redge in self.rapids:
if PathGeom.edgesMatch(edge, redge):
if Path.Geom.edgesMatch(edge, redge):
israpid = True
if israpid:
v = edge.valueAt(edge.LastParameter)
commands.append(Path.Command("G0", {"X": v.x, "Y": v.y, "Z": v.z}))
else:
commands.extend(PathGeom.cmdsForEdge(edge))
commands.extend(Path.Geom.cmdsForEdge(edge))
lastCmd = Path.Command("G0", {"X": 0.0, "Y": 0.0, "Z": 0.0})
@@ -831,7 +829,7 @@ class ObjectDressup:
if cmd.Name in ["G1", "G2", "G3", "G01", "G02", "G03"]:
if zVal is not None and zVal2 != zVal:
if PathGeom.isRoughly(xVal, xVal2) and PathGeom.isRoughly(
if Path.Geom.isRoughly(xVal, xVal2) and Path.Geom.isRoughly(
yVal, yVal2
):
# this is a straight plunge
@@ -877,7 +875,7 @@ class ViewProviderDressup:
def onDelete(self, arg1=None, arg2=None):
"""this makes sure that the base operation is added back to the project and visible"""
PathLog.debug("Deleting Dressup")
Path.Log.debug("Deleting Dressup")
if arg1.Object and arg1.Object.Base:
FreeCADGui.ActiveDocument.getObject(arg1.Object.Base.Name).Visibility = True
job = PathUtils.findParentJob(self.obj)
@@ -917,40 +915,40 @@ class CommandPathDressupRampEntry:
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelection()
if len(selection) != 1:
PathLog.error(
Path.Log.error(
translate("Path_DressupRampEntry", "Please select one path object")
+ "\n"
)
return
baseObject = selection[0]
if not baseObject.isDerivedFrom("Path::Feature"):
PathLog.error(
Path.Log.error(
translate("Path_DressupRampEntry", "The selected object is not a path")
+ "\n"
)
return
if baseObject.isDerivedFrom("Path::FeatureCompoundPython"):
PathLog.error(
Path.Log.error(
translate("Path_DressupRampEntry", "Please select a Profile object")
)
return
# everything ok!
FreeCAD.ActiveDocument.openTransaction("Create RampEntry Dress-up")
FreeCADGui.addModule("PathScripts.PathDressupRampEntry")
FreeCADGui.addModule("Path.Dressup.Gui.RampEntry")
FreeCADGui.addModule("PathScripts.PathUtils")
FreeCADGui.doCommand(
'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "RampEntryDressup")'
)
FreeCADGui.doCommand(
"dbo = PathScripts.PathDressupRampEntry.ObjectDressup(obj)"
"dbo = Path.Dressup.Gui.RampEntry.ObjectDressup(obj)"
)
FreeCADGui.doCommand("base = FreeCAD.ActiveDocument." + selection[0].Name)
FreeCADGui.doCommand("job = PathScripts.PathUtils.findParentJob(base)")
FreeCADGui.doCommand("obj.Base = base")
FreeCADGui.doCommand("job.Proxy.addOperation(obj, base)")
FreeCADGui.doCommand(
"obj.ViewObject.Proxy = PathScripts.PathDressupRampEntry.ViewProviderDressup(obj.ViewObject)"
"obj.ViewObject.Proxy = Path.Dressup.Gui.RampEntry.ViewProviderDressup(obj.ViewObject)"
)
FreeCADGui.doCommand(
"Gui.ActiveDocument.getObject(base.Name).Visibility = False"
@@ -964,4 +962,4 @@ if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand("Path_DressupRampEntry", CommandPathDressupRampEntry())
PathLog.notice("Loading Path_DressupRampEntry... done\n")
Path.Log.notice("Loading Path_DressupRampEntry... done\n")

View File

@@ -21,15 +21,14 @@
# ***************************************************************************
import FreeCAD
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathPreferencesPathDressup as PathPreferencesPathDressup
import Path
import Path.Dressup.Gui.Preferences as PathPreferencesPathDressup
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -43,7 +42,7 @@ class HoldingTagPreferences:
@classmethod
def defaultWidth(cls, ifNotSet):
value = PathPreferences.preferences().GetFloat(
value = Path.Preferences.preferences().GetFloat(
cls.DefaultHoldingTagWidth, ifNotSet
)
if value == 0.0:
@@ -52,7 +51,7 @@ class HoldingTagPreferences:
@classmethod
def defaultHeight(cls, ifNotSet):
value = PathPreferences.preferences().GetFloat(
value = Path.Preferences.preferences().GetFloat(
cls.DefaultHoldingTagHeight, ifNotSet
)
if value == 0.0:
@@ -61,7 +60,7 @@ class HoldingTagPreferences:
@classmethod
def defaultAngle(cls, ifNotSet=45.0):
value = PathPreferences.preferences().GetFloat(
value = Path.Preferences.preferences().GetFloat(
cls.DefaultHoldingTagAngle, ifNotSet
)
if value < 10.0:
@@ -70,7 +69,7 @@ class HoldingTagPreferences:
@classmethod
def defaultCount(cls, ifNotSet=4):
value = PathPreferences.preferences().GetUnsigned(
value = Path.Preferences.preferences().GetUnsigned(
cls.DefaultHoldingTagCount, ifNotSet
)
if value < 2:
@@ -79,7 +78,7 @@ class HoldingTagPreferences:
@classmethod
def defaultRadius(cls, ifNotSet=0.0):
return PathPreferences.preferences().GetFloat(
return Path.Preferences.preferences().GetFloat(
cls.DefaultHoldingTagRadius, ifNotSet
)
@@ -112,7 +111,7 @@ class HoldingTagPreferences:
self.form.sbCount.setValue(self.defaultCount())
def saveSettings(self):
pref = PathPreferences.preferences()
pref = Path.Preferences.preferences()
pref.SetFloat(
self.DefaultHoldingTagWidth,
FreeCAD.Units.Quantity(self.form.ifWidth.text()).Value,

View File

@@ -25,26 +25,24 @@ from PySide.QtCore import QT_TRANSLATE_NOOP
from pivy import coin
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathDressupHoldingTags as PathDressupTag
import PathScripts.PathGeom as PathGeom
import PathScripts.PathGetPoint as PathGetPoint
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import Path
import Path.Base.Gui.GetPoint as PathGetPoint
import Path.Dressup.Tags as PathDressupTag
import PathGui
import PathScripts.PathUtils as PathUtils
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
def addDebugDisplay():
return PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG
return Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG
class PathDressupTagTaskPanel:
@@ -164,7 +162,7 @@ class PathDressupTagTaskPanel:
self.isDirty = True
def updateTagsView(self):
PathLog.track()
Path.Log.track()
self.form.lwTags.blockSignals(True)
self.form.lwTags.clear()
for i, pos in enumerate(self.Positions):
@@ -189,7 +187,7 @@ class PathDressupTagTaskPanel:
def generateNewTags(self):
count = self.form.sbCount.value()
PathLog.track(count)
Path.Log.track(count)
if not self.obj.Proxy.generateTags(self.obj, count):
self.obj.Proxy.execute(self.obj)
self.Positions = self.obj.Positions
@@ -206,7 +204,7 @@ class PathDressupTagTaskPanel:
self.Disabled = self.obj.Disabled
self.updateTagsView()
else:
PathLog.error("Cannot copy tags - internal error")
Path.Log.error("Cannot copy tags - internal error")
def updateModel(self):
self.getFields()
@@ -218,7 +216,7 @@ class PathDressupTagTaskPanel:
self.form.pbGenerate.setEnabled(count)
def selectTagWithId(self, index):
PathLog.track(index)
Path.Log.track(index)
self.form.lwTags.setCurrentRow(index)
def whenTagSelectionChanged(self):
@@ -242,18 +240,18 @@ class PathDressupTagTaskPanel:
def addNewTagAt(self, point, obj):
if point and obj and self.obj.Proxy.pointIsOnPath(self.obj, point):
PathLog.info("addNewTagAt(%.2f, %.2f)" % (point.x, point.y))
Path.Log.info("addNewTagAt(%.2f, %.2f)" % (point.x, point.y))
self.Positions.append(FreeCAD.Vector(point.x, point.y, 0))
self.updateTagsView()
else:
PathLog.notice("ignore new tag at %s (obj=%s, on-path=%d" % (point, obj, 0))
Path.Log.notice("ignore new tag at %s (obj=%s, on-path=%d" % (point, obj, 0))
def addNewTag(self):
self.tags = self.getTags(True)
self.getPoint.getPoint(self.addNewTagAt)
def editTagAt(self, point, obj):
PathLog.track(point, obj)
Path.Log.track(point, obj)
if point and self.obj.Proxy.pointIsOnPath(self.obj, point):
tags = []
for i, (x, y, enabled) in enumerate(self.tags):
@@ -363,7 +361,7 @@ class HoldingTagMarker:
class PathDressupTagViewProvider:
def __init__(self, vobj):
PathLog.track()
Path.Log.track()
self.vobj = vobj
self.panel = None
@@ -395,7 +393,7 @@ class PathDressupTagViewProvider:
v = [((val >> n) & 0xFF) / 255.0 for n in [24, 16, 8, 0]]
return coin.SbColor(v[0], v[1], v[2])
pref = PathPreferences.preferences()
pref = Path.Preferences.preferences()
# R G B A
npc = pref.GetUnsigned(
"DefaultPathMarkerColor", ((85 * 256 + 255) * 256 + 0) * 256 + 255
@@ -413,7 +411,7 @@ class PathDressupTagViewProvider:
]
def attach(self, vobj):
PathLog.track()
Path.Log.track()
self.setupColors()
self.vobj = vobj
self.obj = vobj.Object
@@ -438,14 +436,14 @@ class PathDressupTagViewProvider:
self.switch.whichChild = sw
def claimChildren(self):
PathLog.track()
Path.Log.track()
# if self.debugDisplay():
# return [self.obj.Base, self.vobj.Debug]
return [self.obj.Base]
def onDelete(self, arg1=None, arg2=None):
"""this makes sure that the base operation is added back to the job and visible"""
PathLog.track()
Path.Log.track()
if self.obj.Base and self.obj.Base.ViewObject:
self.obj.Base.ViewObject.Visibility = True
job = PathUtils.findParentJob(self.obj)
@@ -472,12 +470,12 @@ class PathDressupTagViewProvider:
self.tags = tags
def updateData(self, obj, propName):
PathLog.track(propName)
Path.Log.track(propName)
if "Disabled" == propName:
self.updatePositions(obj.Positions, obj.Disabled)
def onModelChanged(self):
PathLog.track()
Path.Log.track()
# if self.debugDisplay():
# self.vobj.Debug.removeObjectsFromDocument()
# for solid in self.obj.Proxy.solids:
@@ -515,7 +513,7 @@ class PathDressupTagViewProvider:
# SelectionObserver interface
def selectTag(self, index):
PathLog.track(index)
Path.Log.track(index)
for i, tag in enumerate(self.tags):
tag.setSelected(i == index)
@@ -527,7 +525,7 @@ class PathDressupTagViewProvider:
z = self.tags[0].point.z
p = FreeCAD.Vector(x, y, z)
for i, tag in enumerate(self.tags):
if PathGeom.pointsCoincide(
if Path.Geom.pointsCoincide(
p, tag.point, tag.sphere.radius.getValue() * 1.3
):
return i
@@ -539,7 +537,7 @@ class PathDressupTagViewProvider:
return False
def addSelection(self, doc, obj, sub, point):
PathLog.track(doc, obj, sub, point)
Path.Log.track(doc, obj, sub, point)
if self.panel:
i = self.tagAtPoint(point, sub is None)
self.panel.selectTagWithId(i)
@@ -580,7 +578,7 @@ class CommandPathDressupTag:
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelection()
if len(selection) != 1:
PathLog.error(
Path.Log.error(
translate("Path_DressupTag", "Please select one path object") + "\n"
)
return
@@ -588,9 +586,9 @@ class CommandPathDressupTag:
# everything ok!
FreeCAD.ActiveDocument.openTransaction("Create Tag Dress-up")
FreeCADGui.addModule("PathScripts.PathDressupTagGui")
FreeCADGui.addModule("Path.Dressup.Gui.Tags")
FreeCADGui.doCommand(
"PathScripts.PathDressupTagGui.Create(App.ActiveDocument.%s)"
"Path.Dressup.Gui.Tags.Create(App.ActiveDocument.%s)"
% baseObject.Name
)
# FreeCAD.ActiveDocument.commitTransaction() # Final `commitTransaction()` called via TaskPanel.accept()
@@ -601,4 +599,4 @@ if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand("Path_DressupTag", CommandPathDressupTag())
PathLog.notice("Loading PathDressupTagGui... done\n")
Path.Log.notice("Loading PathDressupTagGui... done\n")

View File

@@ -26,13 +26,10 @@
import FreeCAD
import FreeCADGui
import Path
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathUtils as PathUtils
from PySide import QtGui
from PySide.QtCore import QT_TRANSLATE_NOOP
from PathScripts.PathGeom import CmdMoveArc, CmdMoveStraight
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -44,13 +41,13 @@ Part = LazyLoader("Part", globals(), "Part")
LOGLEVEL = False
LOG_MODULE = PathLog.thisModule()
LOG_MODULE = Path.Log.thisModule()
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -130,12 +127,12 @@ class ObjectDressup:
zval = round(float(w[2]), 2)
pointlist.append([xval, yval, zval])
PathLog.debug(pointlist)
Path.Log.debug(pointlist)
cols = list(zip(*pointlist))
PathLog.debug("cols: {}".format(cols))
Path.Log.debug("cols: {}".format(cols))
yindex = list(sorted(set(cols[1])))
PathLog.debug("yindex: {}".format(yindex))
Path.Log.debug("yindex: {}".format(yindex))
array = []
for y in yindex:
@@ -173,20 +170,20 @@ class ObjectDressup:
currLocation = {"X": 0, "Y": 0, "Z": 0, "F": 0}
for c in pathlist:
PathLog.debug(c)
PathLog.debug(" curLoc:{}".format(currLocation))
Path.Log.debug(c)
Path.Log.debug(" curLoc:{}".format(currLocation))
newparams = dict(c.Parameters)
zval = newparams.get("Z", currLocation["Z"])
if c.Name in CmdMoveStraight + CmdMoveArc:
if c.Name in Path.Geom.CmdMoveStraight + Path.Geom.CmdMoveArc:
curVec = FreeCAD.Vector(
currLocation["X"],
currLocation["Y"],
currLocation["Z"],
)
arcwire = PathGeom.edgeForCmd(c, curVec)
arcwire = Path.Geom.edgeForCmd(c, curVec)
if arcwire is None:
continue
if c.Name in CmdMoveArc:
if c.Name in Path.Geom.CmdMoveArc:
pointlist = arcwire.discretize(Deflection=curveD)
else:
disc_number = int(arcwire.Length / sampleD)
@@ -254,18 +251,18 @@ class TaskPanel:
def updateUI(self):
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
if Path.Log.getLevel(LOG_MODULE) == Path.Log.Level.DEBUG:
for obj in FreeCAD.ActiveDocument.Objects:
if obj.Name.startswith("Shape"):
FreeCAD.ActiveDocument.removeObject(obj.Name)
print("object name %s" % self.obj.Name)
if hasattr(self.obj.Proxy, "shapes"):
PathLog.info("showing shapes attribute")
Path.Log.info("showing shapes attribute")
for shapes in self.obj.Proxy.shapes.itervalues():
for shape in shapes:
Part.show(shape)
else:
PathLog.info("no shapes attribute found")
Path.Log.info("no shapes attribute found")
def updateModel(self):
self.getFields()
@@ -381,15 +378,15 @@ class CommandPathDressup:
# everything ok!
FreeCAD.ActiveDocument.openTransaction("Create Dress-up")
FreeCADGui.addModule("PathScripts.PathDressupZCorrect")
FreeCADGui.addModule("Path.Dressup.Gui.ZCorrect")
FreeCADGui.addModule("PathScripts.PathUtils")
FreeCADGui.doCommand(
'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "ZCorrectDressup")'
)
FreeCADGui.doCommand("PathScripts.PathDressupZCorrect.ObjectDressup(obj)")
FreeCADGui.doCommand("Path.Dressup.Gui.ZCorrect.ObjectDressup(obj)")
FreeCADGui.doCommand("obj.Base = FreeCAD.ActiveDocument." + selection[0].Name)
FreeCADGui.doCommand(
"PathScripts.PathDressupZCorrect.ViewProviderDressup(obj.ViewObject)"
"Path.Dressup.Gui.ZCorrect.ViewProviderDressup(obj.ViewObject)"
)
FreeCADGui.doCommand("PathScripts.PathUtils.addToJob(obj)")
FreeCADGui.doCommand(

View File

@@ -20,15 +20,13 @@
# * *
# ***************************************************************************
from PathScripts.PathDressupTagPreferences import HoldingTagPreferences
from Path.Dressup.Gui.TagPreferences import HoldingTagPreferences
from PathScripts.PathUtils import waiting_effects
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import Path
import PathScripts.PathDressup as PathDressup
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathUtil as PathUtil
import Path.Base.Util as PathUtil
import Path.Dressup.Utils as PathDressup
import PathScripts.PathUtils as PathUtils
import copy
import math
@@ -40,16 +38,16 @@ from lazy_loader.lazy_loader import LazyLoader
Part = LazyLoader("Part", globals(), "Part")
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
def debugEdge(edge, prefix, force=False):
if force or PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
if force or Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG:
pf = edge.valueAt(edge.FirstParameter)
pl = edge.valueAt(edge.LastParameter)
if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment:
@@ -78,7 +76,7 @@ def debugEdge(edge, prefix, force=False):
def debugMarker(vector, label, color=None, radius=0.5):
if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
if Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Sphere", label)
obj.Label = label
obj.Radius = radius
@@ -90,7 +88,7 @@ def debugMarker(vector, label, color=None, radius=0.5):
def debugCylinder(vector, r, height, label, color=None):
if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
if Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Cylinder", label)
obj.Label = label
obj.Radius = r
@@ -104,7 +102,7 @@ def debugCylinder(vector, r, height, label, color=None):
def debugCone(vector, r1, r2, height, label, color=None):
if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
if Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Cone", label)
obj.Label = label
obj.Radius1 = r1
@@ -120,7 +118,7 @@ def debugCone(vector, r1, r2, height, label, color=None):
class Tag:
def __init__(self, nr, x, y, width, height, angle, radius, enabled=True):
PathLog.track(
Path.Log.track(
"%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d"
% (x, y, width, height, angle, radius, enabled)
)
@@ -165,12 +163,12 @@ class Tag:
self.r2 = r1
height = self.height * 1.01
radius = 0
if PathGeom.isRoughly(90, self.angle) and height > 0:
if Path.Geom.isRoughly(90, self.angle) and height > 0:
# cylinder
self.isSquare = True
self.solid = Part.makeCylinder(r1, height)
radius = min(min(self.radius, r1), self.height)
PathLog.debug("Part.makeCylinder(%f, %f)" % (r1, height))
Path.Log.debug("Part.makeCylinder(%f, %f)" % (r1, height))
elif self.angle > 0.0 and height > 0.0:
# cone
rad = math.radians(self.angle)
@@ -187,25 +185,25 @@ class Tag:
height = r1 * tangens * 1.01
self.actualHeight = height
self.r2 = r2
PathLog.debug("Part.makeCone(%f, %f, %f)" % (r1, r2, height))
Path.Log.debug("Part.makeCone(%f, %f, %f)" % (r1, r2, height))
self.solid = Part.makeCone(r1, r2, height)
else:
# degenerated case - no tag
PathLog.debug("Part.makeSphere(%f / 10000)" % (r1))
Path.Log.debug("Part.makeSphere(%f / 10000)" % (r1))
self.solid = Part.makeSphere(r1 / 10000)
if not PathGeom.isRoughly(
if not Path.Geom.isRoughly(
0, R
): # testing is easier if the solid is not rotated
angle = -PathGeom.getAngle(self.originAt(0)) * 180 / math.pi
PathLog.debug("solid.rotate(%f)" % angle)
angle = -Path.Geom.getAngle(self.originAt(0)) * 180 / math.pi
Path.Log.debug("solid.rotate(%f)" % angle)
self.solid.rotate(FreeCAD.Vector(0, 0, 0), FreeCAD.Vector(0, 0, 1), angle)
orig = self.originAt(z - 0.01 * self.actualHeight)
PathLog.debug("solid.translate(%s)" % orig)
Path.Log.debug("solid.translate(%s)" % orig)
self.solid.translate(orig)
radius = min(self.radius, radius)
self.realRadius = radius
if not PathGeom.isRoughly(0, radius):
PathLog.debug("makeFillet(%.4f)" % radius)
if not Path.Geom.isRoughly(0, radius):
Path.Log.debug("makeFillet(%.4f)" % radius)
self.solid = self.solid.makeFillet(radius, [self.solid.Edges[0]])
def filterIntersections(self, pts, face):
@@ -214,12 +212,12 @@ class Tag:
or type(face.Surface) == Part.Cylinder
or type(face.Surface) == Part.Toroid
):
PathLog.track("it's a cone/cylinder, checking z")
Path.Log.track("it's a cone/cylinder, checking z")
return list(
[pt for pt in pts if pt.z >= self.bottom() and pt.z <= self.top()]
)
if type(face.Surface) == Part.Plane:
PathLog.track("it's a plane, checking R")
Path.Log.track("it's a plane, checking R")
c = face.Edges[0].Curve
if type(c) == Part.Circle:
return list(
@@ -227,10 +225,10 @@ class Tag:
pt
for pt in pts
if (pt - c.Center).Length <= c.Radius
or PathGeom.isRoughly((pt - c.Center).Length, c.Radius)
or Path.Geom.isRoughly((pt - c.Center).Length, c.Radius)
]
)
PathLog.error("==== we got a %s" % face.Surface)
Path.Log.error("==== we got a %s" % face.Surface)
def isPointOnEdge(self, pt, edge):
param = edge.Curve.parameter(pt)
@@ -238,7 +236,7 @@ class Tag:
return True
if edge.LastParameter <= param <= edge.FirstParameter:
return True
if PathGeom.isRoughly(edge.FirstParameter, param) or PathGeom.isRoughly(
if Path.Geom.isRoughly(edge.FirstParameter, param) or Path.Geom.isRoughly(
edge.LastParameter, param
):
return True
@@ -266,7 +264,7 @@ class Tag:
def intersects(self, edge, param):
def isDefinitelySmaller(z, zRef):
# Eliminate false positives of edges that just brush along the top of the tag
return z < zRef and not PathGeom.isRoughly(z, zRef, 0.01)
return z < zRef and not Path.Geom.isRoughly(z, zRef, 0.01)
if self.enabled:
zFirst = edge.valueAt(edge.FirstParameter).z
@@ -298,20 +296,20 @@ class MapWireToTag:
self.maxZ = maxZ
self.hSpeed = hSpeed
self.vSpeed = vSpeed
if PathGeom.pointsCoincide(edge.valueAt(edge.FirstParameter), i):
if Path.Geom.pointsCoincide(edge.valueAt(edge.FirstParameter), i):
tail = edge
self.commands = []
debugEdge(tail, ".........=")
elif PathGeom.pointsCoincide(edge.valueAt(edge.LastParameter), i):
elif Path.Geom.pointsCoincide(edge.valueAt(edge.LastParameter), i):
debugEdge(edge, "++++++++ .")
self.commands = PathGeom.cmdsForEdge(
self.commands = Path.Geom.cmdsForEdge(
edge, segm=segm, hSpeed=self.hSpeed, vSpeed=self.vSpeed
)
tail = None
else:
e, tail = PathGeom.splitEdgeAt(edge, i)
e, tail = Path.Geom.splitEdgeAt(edge, i)
debugEdge(e, "++++++++ .")
self.commands = PathGeom.cmdsForEdge(
self.commands = Path.Geom.cmdsForEdge(
e, segm=segm, hSpeed=self.hSpeed, vSpeed=self.vSpeed
)
debugEdge(tail, ".........-")
@@ -320,11 +318,11 @@ class MapWireToTag:
self.edges = []
self.entry = i
if tail:
PathLog.debug(
Path.Log.debug(
"MapWireToTag(%s - %s)" % (i, tail.valueAt(tail.FirstParameter))
)
else:
PathLog.debug("MapWireToTag(%s - )" % i)
Path.Log.debug("MapWireToTag(%s - )" % i)
self.complete = False
self.haveProblem = False
@@ -345,32 +343,32 @@ class MapWireToTag:
self.edges.append(edge)
def needToFlipEdge(self, edge, p):
if PathGeom.pointsCoincide(edge.valueAt(edge.LastParameter), p):
if Path.Geom.pointsCoincide(edge.valueAt(edge.LastParameter), p):
return True, edge.valueAt(edge.FirstParameter)
return False, edge.valueAt(edge.LastParameter)
def isEntryOrExitStrut(self, e):
p1 = e.valueAt(e.FirstParameter)
p2 = e.valueAt(e.LastParameter)
if PathGeom.pointsCoincide(p1, self.entry) and p2.z >= self.entry.z:
if Path.Geom.pointsCoincide(p1, self.entry) and p2.z >= self.entry.z:
return 1
if PathGeom.pointsCoincide(p2, self.entry) and p1.z >= self.entry.z:
if Path.Geom.pointsCoincide(p2, self.entry) and p1.z >= self.entry.z:
return 1
if PathGeom.pointsCoincide(p1, self.exit) and p2.z >= self.exit.z:
if Path.Geom.pointsCoincide(p1, self.exit) and p2.z >= self.exit.z:
return 2
if PathGeom.pointsCoincide(p2, self.exit) and p1.z >= self.exit.z:
if Path.Geom.pointsCoincide(p2, self.exit) and p1.z >= self.exit.z:
return 2
return 0
def cleanupEdges(self, edges):
# want to remove all edges from the wire itself, and all internal struts
PathLog.track("+cleanupEdges")
PathLog.debug(" edges:")
Path.Log.track("+cleanupEdges")
Path.Log.debug(" edges:")
if not edges:
return edges
for e in edges:
debugEdge(e, " ")
PathLog.debug(":")
Path.Log.debug(":")
self.edgesCleanup = [copy.copy(edges)]
# remove any edge that has a point inside the tag solid
@@ -384,16 +382,16 @@ class MapWireToTag:
self.edgePoints.append(p1)
self.edgePoints.append(p2)
if self.tag.solid.isInside(
p1, PathGeom.Tolerance, False
) or self.tag.solid.isInside(p2, PathGeom.Tolerance, False):
p1, Path.Geom.Tolerance, False
) or self.tag.solid.isInside(p2, Path.Geom.Tolerance, False):
edges.remove(e)
debugEdge(e, "......... X0", False)
else:
if PathGeom.pointsCoincide(p1, self.entry) or PathGeom.pointsCoincide(
if Path.Geom.pointsCoincide(p1, self.entry) or Path.Geom.pointsCoincide(
p2, self.entry
):
self.entryEdges.append(e)
if PathGeom.pointsCoincide(p1, self.exit) or PathGeom.pointsCoincide(
if Path.Geom.pointsCoincide(p1, self.exit) or Path.Geom.pointsCoincide(
p2, self.exit
):
self.exitEdges.append(e)
@@ -402,23 +400,23 @@ class MapWireToTag:
# if there are no edges connected to entry/exit, it means the plunge in/out is vertical
# we need to add in the missing segment and collect the new entry/exit edges.
if not self.entryEdges:
PathLog.debug("fill entryEdges ...")
Path.Log.debug("fill entryEdges ...")
self.realEntry = sorted(
self.edgePoints, key=lambda p: (p - self.entry).Length
)[0]
self.entryEdges = list(
[e for e in edges if PathGeom.edgeConnectsTo(e, self.realEntry)]
[e for e in edges if Path.Geom.edgeConnectsTo(e, self.realEntry)]
)
edges.append(Part.Edge(Part.LineSegment(self.entry, self.realEntry)))
else:
self.realEntry = None
if not self.exitEdges:
PathLog.debug("fill exitEdges ...")
Path.Log.debug("fill exitEdges ...")
self.realExit = sorted(
self.edgePoints, key=lambda p: (p - self.exit).Length
)[0]
self.exitEdges = list(
[e for e in edges if PathGeom.edgeConnectsTo(e, self.realExit)]
[e for e in edges if Path.Geom.edgeConnectsTo(e, self.realExit)]
)
edges.append(Part.Edge(Part.LineSegment(self.realExit, self.exit)))
else:
@@ -451,7 +449,7 @@ class MapWireToTag:
return edges
def orderAndFlipEdges(self, inputEdges):
PathLog.track(
Path.Log.track(
"entry(%.2f, %.2f, %.2f), exit(%.2f, %.2f, %.2f)"
% (
self.entry.x,
@@ -472,15 +470,15 @@ class MapWireToTag:
for e in copy.copy(edges):
p1 = e.valueAt(e.FirstParameter)
p2 = e.valueAt(e.LastParameter)
if PathGeom.pointsCoincide(p1, p0):
if Path.Geom.pointsCoincide(p1, p0):
outputEdges.append((e, False))
edges.remove(e)
lastP = None
p0 = p2
debugEdge(e, ">>>>> no flip")
break
elif PathGeom.pointsCoincide(p2, p0):
flipped = PathGeom.flipEdge(e)
elif Path.Geom.pointsCoincide(p2, p0):
flipped = Path.Geom.flipEdge(e)
if not flipped is None:
outputEdges.append((flipped, True))
else:
@@ -493,7 +491,7 @@ class MapWireToTag:
)
cnt = cnt + 1
p0 = p
PathLog.info("replaced edge with %d straight segments" % cnt)
Path.Log.info("replaced edge with %d straight segments" % cnt)
edges.remove(e)
lastP = None
p0 = p1
@@ -505,43 +503,43 @@ class MapWireToTag:
if lastP == p0:
self.edgesOrder.append(outputEdges)
self.edgesOrder.append(edges)
PathLog.debug("input edges:")
Path.Log.debug("input edges:")
for e in inputEdges:
debugEdge(e, " ", False)
PathLog.debug("ordered edges:")
Path.Log.debug("ordered edges:")
for e, flip in outputEdges:
debugEdge(e, " %c " % ("<" if flip else ">"), False)
PathLog.debug("remaining edges:")
Path.Log.debug("remaining edges:")
for e in edges:
debugEdge(e, " ", False)
raise ValueError("No connection to %s" % (p0))
elif lastP:
PathLog.debug(
Path.Log.debug(
"xxxxxx (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f)"
% (p0.x, p0.y, p0.z, lastP.x, lastP.y, lastP.z)
)
else:
PathLog.debug("xxxxxx (%.2f, %.2f, %.2f) -" % (p0.x, p0.y, p0.z))
Path.Log.debug("xxxxxx (%.2f, %.2f, %.2f) -" % (p0.x, p0.y, p0.z))
lastP = p0
PathLog.track("-")
Path.Log.track("-")
return outputEdges
def isStrut(self, edge):
p1 = PathGeom.xy(edge.valueAt(edge.FirstParameter))
p2 = PathGeom.xy(edge.valueAt(edge.LastParameter))
return PathGeom.pointsCoincide(p1, p2)
p1 = Path.Geom.xy(edge.valueAt(edge.FirstParameter))
p2 = Path.Geom.xy(edge.valueAt(edge.LastParameter))
return Path.Geom.pointsCoincide(p1, p2)
def shell(self):
if len(self.edges) > 1:
wire = Part.Wire(self.initialEdge)
else:
edge = self.edges[0]
if PathGeom.pointsCoincide(
if Path.Geom.pointsCoincide(
edge.valueAt(edge.FirstParameter),
self.finalEdge.valueAt(self.finalEdge.FirstParameter),
):
wire = Part.Wire(self.finalEdge)
elif hasattr(self, "initialEdge") and PathGeom.pointsCoincide(
elif hasattr(self, "initialEdge") and Path.Geom.pointsCoincide(
edge.valueAt(edge.FirstParameter),
self.initialEdge.valueAt(self.initialEdge.FirstParameter),
):
@@ -550,7 +548,7 @@ class MapWireToTag:
wire = Part.Wire(edge)
for edge in self.edges[1:]:
if PathGeom.pointsCoincide(
if Path.Geom.pointsCoincide(
edge.valueAt(edge.FirstParameter),
self.finalEdge.valueAt(self.finalEdge.FirstParameter),
):
@@ -559,7 +557,7 @@ class MapWireToTag:
wire.add(edge)
shell = wire.extrude(FreeCAD.Vector(0, 0, self.tag.height + 1))
nullFaces = list([f for f in shell.Faces if PathGeom.isRoughly(f.Area, 0)])
nullFaces = list([f for f in shell.Faces if Path.Geom.isRoughly(f.Area, 0)])
if nullFaces:
return shell.removeShape(nullFaces)
return shell
@@ -576,8 +574,8 @@ class MapWireToTag:
p2 = e.valueAt(e.LastParameter)
if (
self.tag.isSquare
and (PathGeom.isRoughly(p1.z, self.maxZ) or p1.z > self.maxZ)
and (PathGeom.isRoughly(p2.z, self.maxZ) or p2.z > self.maxZ)
and (Path.Geom.isRoughly(p1.z, self.maxZ) or p1.z > self.maxZ)
and (Path.Geom.isRoughly(p2.z, self.maxZ) or p2.z > self.maxZ)
):
rapid = p1 if flip else p2
else:
@@ -589,7 +587,7 @@ class MapWireToTag:
)
rapid = None
commands.extend(
PathGeom.cmdsForEdge(
Path.Geom.cmdsForEdge(
e,
False,
False,
@@ -605,7 +603,7 @@ class MapWireToTag:
# rapid = None # commented out per LGTM suggestion
return commands
except Exception as e:
PathLog.error(
Path.Log.error(
"Exception during processing tag @(%.2f, %.2f) (%s) - disabling the tag"
% (self.tag.x, self.tag.y, e.args[0])
)
@@ -613,7 +611,7 @@ class MapWireToTag:
commands = []
for e in self.edges:
commands.extend(
PathGeom.cmdsForEdge(e, hSpeed=self.hSpeed, vSpeed=self.vSpeed)
Path.Geom.cmdsForEdge(e, hSpeed=self.hSpeed, vSpeed=self.vSpeed)
)
return commands
return []
@@ -622,9 +620,9 @@ class MapWireToTag:
self.tail = None
self.finalEdge = edge
if self.tag.solid.isInside(
edge.valueAt(edge.LastParameter), PathGeom.Tolerance, True
edge.valueAt(edge.LastParameter), Path.Geom.Tolerance, True
):
PathLog.track("solid.isInside")
Path.Log.track("solid.isInside")
self.addEdge(edge)
else:
i = self.tag.intersects(edge, edge.LastParameter)
@@ -632,14 +630,14 @@ class MapWireToTag:
self.offendingEdge = edge
debugEdge(edge, "offending Edge:", False)
o = self.tag.originAt(self.tag.z)
PathLog.debug("originAt: (%.2f, %.2f, %.2f)" % (o.x, o.y, o.z))
Path.Log.debug("originAt: (%.2f, %.2f, %.2f)" % (o.x, o.y, o.z))
i = edge.valueAt(edge.FirstParameter)
if PathGeom.pointsCoincide(i, edge.valueAt(edge.FirstParameter)):
PathLog.track("tail")
if Path.Geom.pointsCoincide(i, edge.valueAt(edge.FirstParameter)):
Path.Log.track("tail")
self.tail = edge
else:
PathLog.track("split")
e, tail = PathGeom.splitEdgeAt(edge, i)
Path.Log.track("split")
e, tail = Path.Geom.splitEdgeAt(edge, i)
self.addEdge(e)
self.tail = tail
self.exit = i
@@ -662,12 +660,12 @@ class _RapidEdges:
r0 = r.Vertexes[0]
r1 = r.Vertexes[1]
if (
PathGeom.isRoughly(r0.X, v0.X)
and PathGeom.isRoughly(r0.Y, v0.Y)
and PathGeom.isRoughly(r0.Z, v0.Z)
and PathGeom.isRoughly(r1.X, v1.X)
and PathGeom.isRoughly(r1.Y, v1.Y)
and PathGeom.isRoughly(r1.Z, v1.Z)
Path.Geom.isRoughly(r0.X, v0.X)
and Path.Geom.isRoughly(r0.Y, v0.Y)
and Path.Geom.isRoughly(r0.Z, v0.Z)
and Path.Geom.isRoughly(r1.X, v1.X)
and Path.Geom.isRoughly(r1.Y, v1.Y)
and Path.Geom.isRoughly(r1.Z, v1.Z)
):
return True
return False
@@ -675,9 +673,9 @@ class _RapidEdges:
class PathData:
def __init__(self, obj):
PathLog.track(obj.Base.Name)
Path.Log.track(obj.Base.Name)
self.obj = obj
self.wire, rapid = PathGeom.wireForPath(obj.Base.Path)
self.wire, rapid = Path.Geom.wireForPath(obj.Base.Path)
self.rapid = _RapidEdges(rapid)
if self.wire:
self.edges = self.wire.Edges
@@ -692,8 +690,8 @@ class PathData:
bottom = [
e
for e in edges
if PathGeom.isRoughly(e.Vertexes[0].Point.z, minZ)
and PathGeom.isRoughly(e.Vertexes[1].Point.z, minZ)
if Path.Geom.isRoughly(e.Vertexes[0].Point.z, minZ)
and Path.Geom.isRoughly(e.Vertexes[1].Point.z, minZ)
]
self.bottomEdges = bottom
try:
@@ -727,7 +725,7 @@ class PathData:
def generateTags(
self, obj, count, width=None, height=None, angle=None, radius=None, spacing=None
):
PathLog.track(count, width, height, angle, spacing)
Path.Log.track(count, width, height, angle, spacing)
# for e in self.baseWire.Edges:
# debugMarker(e.Vertexes[0].Point, 'base', (0.0, 1.0, 1.0), 0.2)
@@ -746,8 +744,8 @@ class PathData:
startIndex = 0
for i in range(0, len(self.baseWire.Edges)):
edge = self.baseWire.Edges[i]
PathLog.debug(" %d: %.2f" % (i, edge.Length))
if PathGeom.isRoughly(edge.Length, longestEdge.Length):
Path.Log.debug(" %d: %.2f" % (i, edge.Length))
if Path.Geom.isRoughly(edge.Length, longestEdge.Length):
startIndex = i
break
@@ -761,7 +759,7 @@ class PathData:
minLength = min(2.0 * W, longestEdge.Length)
PathLog.debug(
Path.Log.debug(
"length=%.2f shortestEdge=%.2f(%.2f) longestEdge=%.2f(%.2f) minLength=%.2f"
% (
self.baseWire.Length,
@@ -772,12 +770,12 @@ class PathData:
minLength,
)
)
PathLog.debug(
Path.Log.debug(
" start: index=%-2d count=%d (length=%.2f, distance=%.2f)"
% (startIndex, startCount, startEdge.Length, tagDistance)
)
PathLog.debug(" -> lastTagLength=%.2f)" % lastTagLength)
PathLog.debug(" -> currentLength=%.2f)" % currentLength)
Path.Log.debug(" -> lastTagLength=%.2f)" % lastTagLength)
Path.Log.debug(" -> currentLength=%.2f)" % currentLength)
edgeDict = {startIndex: startCount}
@@ -796,7 +794,7 @@ class PathData:
for (i, count) in PathUtil.keyValueIter(edgeDict):
edge = self.baseWire.Edges[i]
PathLog.debug(" %d: %d" % (i, count))
Path.Log.debug(" %d: %d" % (i, count))
# debugMarker(edge.Vertexes[0].Point, 'base', (1.0, 0.0, 0.0), 0.2)
# debugMarker(edge.Vertexes[1].Point, 'base', (0.0, 1.0, 0.0), 0.2)
if 0 != count:
@@ -836,12 +834,12 @@ class PathData:
tags.append(Tag(j, at.x, at.y, W, H, A, R, True))
j += 1
else:
PathLog.warning(
Path.Log.warning(
"Tag[%d] (%.2f, %.2f, %.2f) is too far away to copy: %.2f (%.2f)"
% (i, pos.x, pos.y, self.minZ, dist[0], W)
)
else:
PathLog.info("tag[%d]: not enabled, skipping" % i)
Path.Log.info("tag[%d]: not enabled, skipping" % i)
print("copied %d tags" % len(tags))
return tags
@@ -862,10 +860,10 @@ class PathData:
tagCount += 1
lastTagLength += tagDistance
if tagCount > 0:
PathLog.debug(" index=%d -> count=%d" % (index, tagCount))
Path.Log.debug(" index=%d -> count=%d" % (index, tagCount))
edgeDict[index] = tagCount
else:
PathLog.debug(" skipping=%-2d (%.2f)" % (index, edge.Length))
Path.Log.debug(" skipping=%-2d (%.2f)" % (index, edge.Length))
return (currentLength, lastTagLength)
@@ -899,7 +897,7 @@ class PathData:
ts = [
t
for t in tags
if PathGeom.isRoughly(
if Path.Geom.isRoughly(
0, Part.Vertex(t.originAt(self.minZ)).distToShape(edge)[0], 0.1
)
]
@@ -913,7 +911,7 @@ class PathData:
ordered.append(t)
# disable all tags that are not on the base wire.
for tag in tags:
PathLog.info(
Path.Log.info(
"Tag #%d (%.2f, %.2f, %.2f) not on base wire - disabling\n"
% (len(ordered), tag.x, tag.y, self.minZ)
)
@@ -923,11 +921,11 @@ class PathData:
def pointIsOnPath(self, p):
v = Part.Vertex(self.pointAtBottom(p))
PathLog.debug("pt = (%f, %f, %f)" % (v.X, v.Y, v.Z))
Path.Log.debug("pt = (%f, %f, %f)" % (v.X, v.Y, v.Z))
for e in self.bottomEdges:
indent = "{} ".format(e.distToShape(v)[0])
debugEdge(e, indent, True)
if PathGeom.isRoughly(0.0, v.distToShape(e)[0], 0.1):
if Path.Geom.isRoughly(0.0, v.distToShape(e)[0], 0.1):
return True
return False
@@ -1060,18 +1058,18 @@ class ObjectTagDressup:
return False
def isValidTagStartIntersection(self, edge, i):
if PathGeom.pointsCoincide(i, edge.valueAt(edge.LastParameter)):
if Path.Geom.pointsCoincide(i, edge.valueAt(edge.LastParameter)):
return False
p1 = edge.valueAt(edge.FirstParameter)
p2 = edge.valueAt(edge.LastParameter)
if PathGeom.pointsCoincide(PathGeom.xy(p1), PathGeom.xy(p2)):
if Path.Geom.pointsCoincide(Path.Geom.xy(p1), Path.Geom.xy(p2)):
# if this vertical goes up, it can't be the start of a tag intersection
if p1.z < p2.z:
return False
return True
def createPath(self, obj, pathData, tags):
PathLog.track()
Path.Log.track()
commands = []
lastEdge = 0
lastTag = 0
@@ -1097,7 +1095,7 @@ class ObjectTagDressup:
vertRapid = tc.VertRapid.Value
while edge or lastEdge < len(pathData.edges):
PathLog.debug(
Path.Log.debug(
"------- lastEdge = %d/%d.%d/%d" % (lastEdge, lastTag, t, len(tags))
)
if not edge:
@@ -1142,9 +1140,9 @@ class ObjectTagDressup:
v = edge.Vertexes[1]
if (
not commands
and PathGeom.isRoughly(0, v.X)
and PathGeom.isRoughly(0, v.Y)
and not PathGeom.isRoughly(0, v.Z)
and Path.Geom.isRoughly(0, v.X)
and Path.Geom.isRoughly(0, v.Y)
and not Path.Geom.isRoughly(0, v.Z)
):
# The very first move is just to move to ClearanceHeight
commands.append(
@@ -1158,7 +1156,7 @@ class ObjectTagDressup:
)
else:
commands.extend(
PathGeom.cmdsForEdge(
Path.Geom.cmdsForEdge(
edge, segm=segm, hSpeed=horizFeed, vSpeed=vertFeed
)
)
@@ -1194,26 +1192,26 @@ class ObjectTagDressup:
if tag.enabled:
if prev:
if prev.solid.common(tag.solid).Faces:
PathLog.info(
Path.Log.info(
"Tag #%d intersects with previous tag - disabling\n" % i
)
PathLog.debug("this tag = %d [%s]" % (i, tag.solid.BoundBox))
Path.Log.debug("this tag = %d [%s]" % (i, tag.solid.BoundBox))
tag.enabled = False
elif self.pathData.edges:
e = self.pathData.edges[0]
p0 = e.valueAt(e.FirstParameter)
p1 = e.valueAt(e.LastParameter)
if tag.solid.isInside(
p0, PathGeom.Tolerance, True
) or tag.solid.isInside(p1, PathGeom.Tolerance, True):
PathLog.info(
p0, Path.Geom.Tolerance, True
) or tag.solid.isInside(p1, Path.Geom.Tolerance, True):
Path.Log.info(
"Tag #%d intersects with starting point - disabling\n" % i
)
tag.enabled = False
if tag.enabled:
prev = tag
PathLog.debug("previousTag = %d [%s]" % (i, prev))
Path.Log.debug("previousTag = %d [%s]" % (i, prev))
else:
disabled.append(i)
tag.nr = i # assign final nr
@@ -1241,7 +1239,7 @@ class ObjectTagDressup:
pathData = self.setup(obj)
if not pathData:
PathLog.debug("execute - no pathData")
Path.Log.debug("execute - no pathData")
return
self.tags = []
@@ -1250,21 +1248,21 @@ class ObjectTagDressup:
obj, obj.Positions, obj.Disabled
)
if obj.Disabled != disabled:
PathLog.debug(
Path.Log.debug(
"Updating properties.... %s vs. %s" % (obj.Disabled, disabled)
)
obj.Positions = positions
obj.Disabled = disabled
if not self.tags:
PathLog.debug("execute - no tags")
Path.Log.debug("execute - no tags")
obj.Path = obj.Base.Path
return
try:
self.processTags(obj)
except Exception as e:
PathLog.error(
Path.Log.error(
"processing tags failed clearing all tags ... '%s'" % (e.args[0])
)
obj.Path = obj.Base.Path
@@ -1283,15 +1281,15 @@ class ObjectTagDressup:
@waiting_effects
def processTags(self, obj):
tagID = 0
if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
if Path.Log.getLevel(Path.Log.thisModule()) == Path.Log.Level.DEBUG:
for tag in self.tags:
tagID += 1
if tag.enabled:
PathLog.debug(
Path.Log.debug(
"x=%s, y=%s, z=%s" % (tag.x, tag.y, self.pathData.minZ)
)
# debugMarker(FreeCAD.Vector(tag.x, tag.y, self.pathData.minZ), "tag-%02d" % tagID , (1.0, 0.0, 1.0), 0.5)
# if not PathGeom.isRoughly(90, tag.angle):
# if not Path.Geom.isRoughly(90, tag.angle):
# debugCone(tag.originAt(self.pathData.minZ), tag.r1, tag.r2, tag.actualHeight, "tag-%02d" % tagID)
# else:
# debugCylinder(tag.originAt(self.pathData.minZ), tag.fullWidth()/2, tag.actualHeight, "tag-%02d" % tagID)
@@ -1299,12 +1297,12 @@ class ObjectTagDressup:
obj.Path = self.createPath(obj, self.pathData, self.tags)
def setup(self, obj, generate=False):
PathLog.debug("setup")
Path.Log.debug("setup")
self.obj = obj
try:
pathData = PathData(obj)
except ValueError:
PathLog.error(
Path.Log.error(
translate(
"Path_DressupTag",
"Cannot insert holding tags for this path - please select a Profile path",
@@ -1325,7 +1323,7 @@ class ObjectTagDressup:
return self.pathData
def setXyEnabled(self, triples):
PathLog.track()
Path.Log.track()
if not self.pathData:
self.setup(self.obj)
positions = []
@@ -1358,13 +1356,13 @@ def Create(baseObject, name="DressupTag"):
Create(basePath, name='DressupTag') ... create tag dressup object for the given base path.
"""
if not baseObject.isDerivedFrom("Path::Feature"):
PathLog.error(
Path.Log.error(
translate("Path_DressupTag", "The selected object is not a path") + "\n"
)
return None
if baseObject.isDerivedFrom("Path::FeatureCompoundPython"):
PathLog.error(translate("Path_DressupTag", "Please select a Profile object"))
Path.Log.error(translate("Path_DressupTag", "Please select a Profile object"))
return None
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
@@ -1375,4 +1373,4 @@ def Create(baseObject, name="DressupTag"):
return obj
PathLog.notice("Loading Path_DressupTag... done\n")
Path.Log.notice("Loading Path_DressupTag... done\n")

View File

@@ -21,7 +21,7 @@
# ***************************************************************************
import FreeCAD
import PathScripts.PathJob as PathJob
import Path.Main.Job as PathJob
def selection():

View File

View File

@@ -23,7 +23,6 @@
import FreeCAD
import Path
import PathScripts.PathLog as PathLog
import math
from FreeCAD import Vector
@@ -34,7 +33,7 @@ from lazy_loader.lazy_loader import LazyLoader
Part = LazyLoader("Part", globals(), "Part")
__title__ = "PathGeom - geometry utilities for Path"
__title__ = "Geom - geometry utilities for Path"
__author__ = "sliptonic (Brad Collette)"
__url__ = "https://www.freecadweb.org"
__doc__ = "Functions to extract and convert between Path.Command and Part.Edge and utility functions to reason about them."
@@ -44,10 +43,10 @@ Tolerance = 0.000001
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class Side:
@@ -170,7 +169,7 @@ def isVertical(obj):
if type(obj.Surface) == Part.SurfaceOfRevolution:
return isHorizontal(obj.Surface.Direction)
if type(obj.Surface) != Part.BSplineSurface:
PathLog.info(
Path.Log.info(
translate("PathGeom", "face %s not handled, assuming not vertical")
% type(obj.Surface)
)
@@ -187,13 +186,13 @@ def isVertical(obj):
# the current assumption is that a bezier curve is vertical if its end points are vertical
return isVertical(obj.Curve.EndPoint - obj.Curve.StartPoint)
if type(obj.Curve) != Part.BSplineCurve:
PathLog.info(
Path.Log.info(
translate("PathGeom", "edge %s not handled, assuming not vertical")
% type(obj.Curve)
)
return None
PathLog.error(translate("PathGeom", "isVertical(%s) not supported") % obj)
Path.Log.error(translate("PathGeom", "isVertical(%s) not supported") % obj)
return None
@@ -224,7 +223,7 @@ def isHorizontal(obj):
return isVertical(obj.Curve.Axis)
return isRoughly(obj.BoundBox.ZLength, 0.0)
PathLog.error(translate("PathGeom", "isHorizontal(%s) not supported") % obj)
Path.Log.error(translate("PathGeom", "isHorizontal(%s) not supported") % obj)
return None
@@ -258,7 +257,7 @@ def speedBetweenPoints(p0, p1, hSpeed, vSpeed):
pitch = pitch + 1
while pitch > 1:
pitch = pitch - 1
PathLog.debug(
Path.Log.debug(
" pitch = %g %g (%.2f, %.2f, %.2f) -> %.2f"
% (pitch, math.atan2(xy(d).Length, d.z), d.x, d.y, d.z, xy(d).Length)
)
@@ -322,7 +321,7 @@ def cmdsForEdge(edge, flip=False, useHelixForBSpline=True, segm=50, hSpeed=0, vS
offset = edge.Curve.Center - pt
else:
pd = Part.Circle(xy(p1), xy(p2), xy(p3)).Center
PathLog.debug(
Path.Log.debug(
"**** %s.%d: (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) -> center=(%.2f, %.2f)"
% (
cmd,
@@ -347,15 +346,15 @@ def cmdsForEdge(edge, flip=False, useHelixForBSpline=True, segm=50, hSpeed=0, vS
pc = xy(p3)
offset = Part.Circle(pa, pb, pc).Center - pa
PathLog.debug(
Path.Log.debug(
"**** (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f)"
% (pa.x, pa.y, pa.z, pc.x, pc.y, pc.z)
)
PathLog.debug(
Path.Log.debug(
"**** (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f)"
% (pb.x, pb.y, pb.z, pd.x, pd.y, pd.z)
)
PathLog.debug("**** (%.2f, %.2f, %.2f)" % (offset.x, offset.y, offset.z))
Path.Log.debug("**** (%.2f, %.2f, %.2f)" % (offset.x, offset.y, offset.z))
params.update({"I": offset.x, "J": offset.y, "K": (p3.z - p1.z) / 2})
# G2/G3 commands are always performed at hSpeed
@@ -389,8 +388,8 @@ def edgeForCmd(cmd, startPoint):
"""edgeForCmd(cmd, startPoint).
Returns an Edge representing the given command, assuming a given startPoint."""
PathLog.debug("cmd: {}".format(cmd))
PathLog.debug("startpoint {}".format(startPoint))
Path.Log.debug("cmd: {}".format(cmd))
Path.Log.debug("startpoint {}".format(startPoint))
endPoint = commandEndPoint(cmd, startPoint)
if (cmd.Name in CmdMoveStraight) or (cmd.Name in CmdMoveRapid):
@@ -405,7 +404,7 @@ def edgeForCmd(cmd, startPoint):
d = -B.x * A.y + B.y * A.x
if isRoughly(d, 0, 0.005):
PathLog.debug(
Path.Log.debug(
"Half circle arc at: (%.2f, %.2f, %.2f)"
% (center.x, center.y, center.z)
)
@@ -416,23 +415,23 @@ def edgeForCmd(cmd, startPoint):
else:
C = A + B
angle = getAngle(C)
PathLog.debug(
Path.Log.debug(
"Arc (%8f) at: (%.2f, %.2f, %.2f) -> angle=%f"
% (d, center.x, center.y, center.z, angle / math.pi)
)
R = A.Length
PathLog.debug(
Path.Log.debug(
"arc: p1=(%.2f, %.2f) p2=(%.2f, %.2f) -> center=(%.2f, %.2f)"
% (startPoint.x, startPoint.y, endPoint.x, endPoint.y, center.x, center.y)
)
PathLog.debug(
Path.Log.debug(
"arc: A=(%.2f, %.2f) B=(%.2f, %.2f) -> d=%.2f" % (A.x, A.y, B.x, B.y, d)
)
PathLog.debug("arc: R=%.2f angle=%.2f" % (R, angle / math.pi))
Path.Log.debug("arc: R=%.2f angle=%.2f" % (R, angle / math.pi))
if isRoughly(startPoint.z, endPoint.z):
midPoint = center + Vector(math.cos(angle), math.sin(angle), 0) * R
PathLog.debug(
Path.Log.debug(
"arc: (%.2f, %.2f) -> (%.2f, %.2f) -> (%.2f, %.2f)"
% (
startPoint.x,
@@ -443,9 +442,9 @@ def edgeForCmd(cmd, startPoint):
endPoint.y,
)
)
PathLog.debug("StartPoint:{}".format(startPoint))
PathLog.debug("MidPoint:{}".format(midPoint))
PathLog.debug("EndPoint:{}".format(endPoint))
Path.Log.debug("StartPoint:{}".format(startPoint))
Path.Log.debug("MidPoint:{}".format(midPoint))
Path.Log.debug("EndPoint:{}".format(endPoint))
if pointsCoincide(startPoint, endPoint, 0.001):
return Part.makeCircle(R, center, FreeCAD.Vector(0, 0, 1))
@@ -582,10 +581,10 @@ def combineConnectedShapes(shapes):
while not done:
done = True
combined = []
PathLog.debug("shapes: {}".format(shapes))
Path.Log.debug("shapes: {}".format(shapes))
for shape in shapes:
connected = [f for f in combined if isRoughly(shape.distToShape(f)[0], 0.0)]
PathLog.debug(
Path.Log.debug(
" {}: connected: {} dist: {}".format(
len(combined),
connected,
@@ -672,7 +671,7 @@ def flipEdge(edge):
elif type(edge.Curve) == Part.OffsetCurve:
return edge.reversed()
PathLog.warning(
Path.Log.warning(
translate("PathGeom", "%s not supported for flipping") % type(edge.Curve)
)
@@ -681,7 +680,7 @@ def flipWire(wire):
"""Flip the entire wire and all its edges so it is being processed the other way around."""
edges = [flipEdge(e) for e in wire.Edges]
edges.reverse()
PathLog.debug(edges)
Path.Log.debug(edges)
return Part.Wire(edges)
@@ -710,7 +709,7 @@ def combineHorizontalFaces(faces):
The Adaptive op is not concerned with which hole edges belong to which face.
Attempts to do the same shape connecting failed with TechDraw.findShapeOutline() and
PathGeom.combineConnectedShapes(), so this algorithm was created.
Path.Geom.combineConnectedShapes(), so this algorithm was created.
"""
horizontal = list()
offset = 10.0
@@ -729,7 +728,7 @@ def combineHorizontalFaces(faces):
"PathGeom",
"Zero working area to process. Check your selection and settings.",
)
PathLog.info(msg)
Path.Log.info(msg)
return horizontal
afbb = allFaces.BoundBox

View File

@@ -20,16 +20,16 @@
# * *
# ***************************************************************************
import PathScripts.PathLog as PathLog
import Path
import subprocess
LOGLEVEL = False
if LOGLEVEL:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
Processed = False
@@ -37,46 +37,47 @@ Processed = False
def Startup():
global Processed
if not Processed:
PathLog.debug("Initializing PathGui")
from PathScripts import PathAdaptiveGui
from PathScripts import PathArray
from PathScripts import PathComment
from PathScripts import PathCustomGui
from PathScripts import PathDeburrGui
from PathScripts import PathDressupAxisMap
from PathScripts import PathDressupDogbone
from PathScripts import PathDressupDragknife
from PathScripts import PathDressupLeadInOut
from PathScripts import PathDressupPathBoundaryGui
from PathScripts import PathDressupRampEntry
from PathScripts import PathDressupTagGui
from PathScripts import PathDressupZCorrect
from PathScripts import PathDrillingGui
from PathScripts import PathEngraveGui
from PathScripts import PathFixture
from PathScripts import PathHelixGui
from PathScripts import PathHop
from PathScripts import PathInspect
from PathScripts import PathMillFaceGui
from PathScripts import PathPocketGui
from PathScripts import PathPocketShapeGui
from PathScripts import PathPost
from PathScripts import PathProbeGui
from PathScripts import PathProfileGui
from PathScripts import PathPropertyBagGui
from PathScripts import PathSanity
from PathScripts import PathSetupSheetGui
from PathScripts import PathSimpleCopy
from PathScripts import PathSimulatorGui
from PathScripts import PathSlotGui
from PathScripts import PathStop
from PathScripts import PathThreadMillingGui
from PathScripts import PathToolController
from PathScripts import PathToolControllerGui
from PathScripts import PathToolLibraryEditor
from PathScripts import PathToolLibraryManager
Path.Log.debug("Initializing PathGui")
from Path.Base.Gui import PropertyBag
from Path.Base.Gui import SetupSheet
from Path.Dressup.Gui import AxisMap
from Path.Dressup.Gui import Dogbone
from Path.Dressup.Gui import Dragknife
from Path.Dressup.Gui import LeadInOut
from Path.Dressup.Gui import Boundary
from Path.Dressup.Gui import RampEntry
from Path.Dressup.Gui import Tags
from Path.Dressup.Gui import ZCorrect
from Path.Main.Gui import Fixture
from Path.Main.Gui import Inspect
from Path.Main.Gui import Sanity
from Path.Main.Gui import Simulator
from Path.Op.Gui import Adaptive
from Path.Op.Gui import Array
from Path.Op.Gui import Comment
from Path.Op.Gui import Custom
from Path.Op.Gui import Deburr
from Path.Op.Gui import Drilling
from Path.Op.Gui import Engrave
from Path.Op.Gui import Helix
from Path.Op.Gui import Hop
from Path.Op.Gui import MillFace
from Path.Op.Gui import Pocket
from Path.Op.Gui import PocketShape
from Path.Op.Gui import Probe
from Path.Op.Gui import Profile
from Path.Op.Gui import SimpleCopy
from Path.Op.Gui import Slot
from Path.Op.Gui import Stop
from Path.Op.Gui import ThreadMilling
from Path.Op.Gui import Vcarve
from Path.Post import Command
from Path.Tool import Controller
from Path.Tool.Gui import Controller
from PathScripts import PathUtilsGui
from PathScripts import PathVcarveGui
from packaging.version import Version, parse
@@ -92,10 +93,10 @@ def Startup():
v = parse(r.decode("utf-8"))
if v >= Version("1.2.2"):
from PathScripts import PathCamoticsGui
from Path.Main.Gui import Camotics
except (FileNotFoundError, ModuleNotFoundError):
pass
Processed = True
else:
PathLog.debug("Skipping PathGui initialisation")
Path.Log.debug("Skipping PathGui initialisation")

View File

@@ -26,9 +26,9 @@ from threading import Thread, Lock
import FreeCAD
import FreeCADGui
import Mesh
import Path
import PathScripts
import PathScripts.PathLog as PathLog
import PathScripts.PathPost as PathPost
import Path.Post.Command as PathPost
import camotics
import io
import json
@@ -43,10 +43,10 @@ __url__ = "https://www.freecadweb.org"
__doc__ = "Task panel for Camotics Simulation"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -76,7 +76,7 @@ class CAMoticsUI:
subprocess.Popen(["camotics", filename])
def makeCamoticsFile(self):
PathLog.track()
Path.Log.track()
filename = QtGui.QFileDialog.getSaveFileName(
self.form,
translate("Path", "Save Project As"),
@@ -139,7 +139,7 @@ class CamoticsSimulation(QtCore.QObject):
def worker(self, lock):
while True:
item = self.q.get()
PathLog.debug("worker processing: {}".format(item))
Path.Log.debug("worker processing: {}".format(item))
with lock:
if item["TYPE"] == "STATUS":
self.statusChange.emit(item["VALUE"])
@@ -199,7 +199,7 @@ class CamoticsSimulation(QtCore.QObject):
)
postlist = PathPost.buildPostList(self.job)
PathLog.track(postlist)
Path.Log.track(postlist)
# self.filenames = [PathPost.resolveFileName(self.job)]
success = True
@@ -217,7 +217,7 @@ class CamoticsSimulation(QtCore.QObject):
extraargs="--no-show-editor",
)
self.filenames.append(name)
PathLog.track(result, gcode, name)
Path.Log.track(result, gcode, name)
if result is None:
success = False
@@ -231,11 +231,11 @@ class CamoticsSimulation(QtCore.QObject):
self.SIM.wait()
tot = sum([step["time"] for step in self.SIM.get_path()])
PathLog.debug("sim time: {}".format(tot))
Path.Log.debug("sim time: {}".format(tot))
self.taskForm.setRunTime(tot)
def execute(self, timeIndex):
PathLog.track()
Path.Log.track()
self.SIM.start(self.callback, time=timeIndex, done=self.isDone)
def accept(self):
@@ -245,7 +245,7 @@ class CamoticsSimulation(QtCore.QObject):
pass
def buildproject(self): # , files=[]):
PathLog.track()
Path.Log.track()
job = self.job
@@ -322,7 +322,7 @@ class CommandCamoticsSimulate:
return False
try:
job = FreeCADGui.Selection.getSelectionEx()[0].Object
return isinstance(job.Proxy, PathScripts.PathJob.ObjectJob)
return isinstance(job.Proxy, Path.Main.Job.ObjectJob)
except:
return False

View File

@@ -165,16 +165,16 @@ class CommandPathFixture:
def Activated(self):
FreeCAD.ActiveDocument.openTransaction("Create a Fixture Offset")
FreeCADGui.addModule("PathScripts.PathFixture")
FreeCADGui.addModule("Path.Main.Gui.Fixture")
snippet = """
import Path
import PathScripts
from PathScripts import PathUtils
prjexists = False
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Fixture")
PathScripts.PathFixture.Fixture(obj)
Path.Main.Gui.Fixture.Fixture(obj)
obj.Active = True
PathScripts.PathFixture._ViewProviderFixture(obj.ViewObject)
Path.Main.Gui.Fixture._ViewProviderFixture(obj.ViewObject)
PathUtils.addToJob(obj)

View File

@@ -285,9 +285,9 @@ class CommandPathInspect:
return
# if everything is ok, execute
FreeCADGui.addModule("PathScripts.PathInspect")
FreeCADGui.addModule("Path.Main.Gui.Inspect")
FreeCADGui.doCommand(
"PathScripts.PathInspect.show(FreeCAD.ActiveDocument."
"Path.Main.Gui.Inspect.show(FreeCAD.ActiveDocument."
+ selection[0].Name
+ ")"
)

View File

@@ -27,19 +27,16 @@ from contextlib import contextmanager
from pivy import coin
import FreeCAD
import FreeCADGui
import PathScripts.PathGeom as PathGeom
import PathScripts.PathGuiInit as PathGuiInit
import PathScripts.PathJob as PathJob
import PathScripts.PathJobCmd as PathJobCmd
import PathScripts.PathJobDlg as PathJobDlg
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathSetupSheetGui as PathSetupSheetGui
import PathScripts.PathStock as PathStock
import PathScripts.PathToolBitGui as PathToolBitGui
import PathScripts.PathToolControllerGui as PathToolControllerGui
import PathScripts.PathToolLibraryEditor as PathToolLibraryEditor
import PathScripts.PathUtil as PathUtil
import Path
import Path.Base.Gui.SetupSheet as PathSetupSheetGui
import Path.Base.Util as PathUtil
import Path.GuiInit as PathGuiInit
import Path.Main.Gui.JobCmd as PathJobCmd
import Path.Main.Gui.JobDlg as PathJobDlg
import Path.Main.Job as PathJob
import Path.Main.Stock as PathStock
import Path.Tool.Gui.Bit as PathToolBitGui
import Path.Tool.Gui.Controller as PathToolControllerGui
import PathScripts.PathUtils as PathUtils
import json
import math
@@ -55,10 +52,10 @@ DraftVecUtils = LazyLoader("DraftVecUtils", globals(), "DraftVecUtils")
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
def _OpenCloseResourceEditor(obj, vobj, edit):
@@ -74,7 +71,7 @@ def _OpenCloseResourceEditor(obj, vobj, edit):
missing = "ViewObject"
if job.ViewObject:
missing = "Proxy"
PathLog.warning("Cannot edit %s - no %s" % (obj.Label, missing))
Path.Log.warning("Cannot edit %s - no %s" % (obj.Label, missing))
@contextmanager
@@ -162,7 +159,7 @@ class ViewProvider:
return hasattr(self, "deleteOnReject") and self.deleteOnReject
def setEdit(self, vobj=None, mode=0):
PathLog.track(mode)
Path.Log.track(mode)
if 0 == mode:
job = self.vobj.Object
if not job.Proxy.integrityCheck(job):
@@ -192,7 +189,7 @@ class ViewProvider:
return self.openTaskPanel("Model")
if obj == self.obj.Stock:
return self.openTaskPanel("Stock")
PathLog.info(
Path.Log.info(
"Expected a specific object to edit - %s not recognized" % obj.Label
)
return self.openTaskPanel()
@@ -221,12 +218,12 @@ class ViewProvider:
return children
def onDelete(self, vobj, arg2=None):
PathLog.track(vobj.Object.Label, arg2)
Path.Log.track(vobj.Object.Label, arg2)
self.obj.Proxy.onDelete(self.obj, arg2)
return True
def updateData(self, obj, prop):
PathLog.track(obj.Label, prop)
Path.Log.track(obj.Label, prop)
# make sure the resource view providers are setup properly
if prop == "Model" and self.obj.Model:
for base in self.obj.Model.Group:
@@ -241,7 +238,7 @@ class ViewProvider:
self.obj.Stock.ViewObject.Proxy.onEdit(_OpenCloseResourceEditor)
def rememberBaseVisibility(self, obj, base):
PathLog.track()
Path.Log.track()
if base.ViewObject:
orig = PathUtil.getPublicObject(obj.Proxy.baseObject(obj, base))
self.baseVisibility[base.Name] = (
@@ -254,7 +251,7 @@ class ViewProvider:
base.ViewObject.Visibility = True
def forgetBaseVisibility(self, obj, base):
PathLog.track()
Path.Log.track()
if self.baseVisibility.get(base.Name):
visibility = self.baseVisibility[base.Name]
visibility[0].ViewObject.Visibility = visibility[1]
@@ -262,7 +259,7 @@ class ViewProvider:
del self.baseVisibility[base.Name]
def setupEditVisibility(self, obj):
PathLog.track()
Path.Log.track()
self.baseVisibility = {}
for base in obj.Model.Group:
self.rememberBaseVisibility(obj, base)
@@ -273,14 +270,14 @@ class ViewProvider:
self.obj.Stock.ViewObject.Visibility = True
def resetEditVisibility(self, obj):
PathLog.track()
Path.Log.track()
for base in obj.Model.Group:
self.forgetBaseVisibility(obj, base)
if obj.Stock and obj.Stock.ViewObject:
obj.Stock.ViewObject.Visibility = self.stockVisibility
def setupContextMenu(self, vobj, menu):
PathLog.track()
Path.Log.track()
for action in menu.actions():
menu.removeAction(action)
action = QtGui.QAction(translate("Path_Job", "Edit"), menu)
@@ -293,7 +290,7 @@ class StockEdit(object):
StockType = PathStock.StockType.Unknown
def __init__(self, obj, form, force):
PathLog.track(obj.Label, force)
Path.Log.track(obj.Label, force)
self.obj = obj
self.form = form
self.force = force
@@ -304,7 +301,7 @@ class StockEdit(object):
return PathStock.StockType.FromStock(obj.Stock) == cls.StockType
def activate(self, obj, select=False):
PathLog.track(obj.Label, select)
Path.Log.track(obj.Label, select)
def showHide(widget, activeWidget):
if widget == activeWidget:
@@ -322,11 +319,11 @@ class StockEdit(object):
self.setFields(obj)
def setStock(self, obj, stock):
PathLog.track(obj.Label, stock)
Path.Log.track(obj.Label, stock)
if obj.Stock:
PathLog.track(obj.Stock.Name)
Path.Log.track(obj.Stock.Name)
obj.Document.removeObject(obj.Stock.Name)
PathLog.track(stock.Name)
Path.Log.track(stock.Name)
obj.Stock = stock
if stock.ViewObject and stock.ViewObject.Proxy:
stock.ViewObject.Proxy.onEdit(_OpenCloseResourceEditor)
@@ -359,7 +356,7 @@ class StockFromBaseBoundBoxEdit(StockEdit):
self.trackZpos = None
def editorFrame(self):
PathLog.track()
Path.Log.track()
return self.form.stockFromBase
def getFieldsStock(self, stock, fields=None):
@@ -384,16 +381,16 @@ class StockFromBaseBoundBoxEdit(StockEdit):
def getFields(self, obj, fields=None):
if fields is None:
fields = ["xneg", "xpos", "yneg", "ypos", "zneg", "zpos"]
PathLog.track(obj.Label, fields)
Path.Log.track(obj.Label, fields)
if self.IsStock(obj):
self.getFieldsStock(obj.Stock, fields)
else:
PathLog.error("Stock not from Base bound box!")
Path.Log.error("Stock not from Base bound box!")
def setFields(self, obj):
PathLog.track()
Path.Log.track()
if self.force or not self.IsStock(obj):
PathLog.track()
Path.Log.track()
stock = PathStock.CreateFromBase(obj)
if self.force and self.editorFrame().isVisible():
self.getFieldsStock(stock)
@@ -407,7 +404,7 @@ class StockFromBaseBoundBoxEdit(StockEdit):
self.setLengthField(self.form.stockExtZpos, obj.Stock.ExtZpos)
def setupUi(self, obj):
PathLog.track()
Path.Log.track()
self.setFields(obj)
self.checkXpos()
self.checkYpos()
@@ -480,7 +477,7 @@ class StockCreateBoxEdit(StockEdit):
self.form.stockBoxHeight.text()
)
else:
PathLog.error("Stock not a box!")
Path.Log.error("Stock not a box!")
except Exception:
pass
@@ -526,7 +523,7 @@ class StockCreateCylinderEdit(StockEdit):
self.form.stockCylinderHeight.text()
)
else:
PathLog.error(translate("Path_Job", "Stock not a cylinder!"))
Path.Log.error(translate("Path_Job", "Stock not a cylinder!"))
except Exception:
pass
@@ -637,7 +634,7 @@ class TaskPanel:
self.form.toolControllerList.resizeColumnsToContents()
currentPostProcessor = self.obj.PostProcessor
postProcessors = PathPreferences.allEnabledPostProcessors(
postProcessors = Path.Preferences.allEnabledPostProcessors(
["", currentPostProcessor]
)
for post in postProcessors:
@@ -687,13 +684,13 @@ class TaskPanel:
box.addItem(text, data)
def preCleanup(self):
PathLog.track()
Path.Log.track()
FreeCADGui.Selection.removeObserver(self)
self.vproxy.resetEditVisibility(self.obj)
self.vproxy.resetTaskPanel()
def accept(self, resetEdit=True):
PathLog.track()
Path.Log.track()
self._jobIntegrityCheck() # Check existence of Model and Tools
self.preCleanup()
self.getFields()
@@ -703,19 +700,19 @@ class TaskPanel:
self.cleanup(resetEdit)
def reject(self, resetEdit=True):
PathLog.track()
Path.Log.track()
self.preCleanup()
self.setupGlobal.reject()
self.setupOps.reject()
FreeCAD.ActiveDocument.abortTransaction()
if self.deleteOnReject and FreeCAD.ActiveDocument.getObject(self.name):
PathLog.info("Uncreate Job")
Path.Log.info("Uncreate Job")
FreeCAD.ActiveDocument.openTransaction("Uncreate Job")
if self.obj.ViewObject.Proxy.onDelete(self.obj.ViewObject, None):
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
FreeCAD.ActiveDocument.commitTransaction()
else:
PathLog.track(
Path.Log.track(
self.name,
self.deleteOnReject,
FreeCAD.ActiveDocument.getObject(self.name),
@@ -724,7 +721,7 @@ class TaskPanel:
return True
def cleanup(self, resetEdit):
PathLog.track()
Path.Log.track()
FreeCADGui.Control.closeDialog()
if resetEdit:
FreeCADGui.ActiveDocument.resetEdit()
@@ -779,7 +776,7 @@ class TaskPanel:
flist.append(self.form.wcslist.item(i).text())
self.obj.Fixtures = flist
except Exception as e:
PathLog.debug(e)
Path.Log.debug(e)
FreeCAD.Console.PrintWarning(
"The Job was created without fixture support. Please delete and recreate the job\r\n"
)
@@ -999,35 +996,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 = Path.Preferences.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)
@@ -1083,17 +1075,17 @@ class TaskPanel:
self.template.updateUI()
def modelSetAxis(self, axis):
PathLog.track(axis)
Path.Log.track(axis)
def alignSel(sel, normal, flip=False):
PathLog.track(
Path.Log.track(
"Vector(%.2f, %.2f, %.2f)" % (normal.x, normal.y, normal.z), flip
)
v = axis
if flip:
v = axis.negative()
if PathGeom.pointsCoincide(abs(v), abs(normal)):
if Path.Geom.pointsCoincide(abs(v), abs(normal)):
# Selection is already aligned with the axis of rotation leading
# to a (0,0,0) cross product for rotation.
# --> Need to flip the object around one of the "other" axis.
@@ -1104,7 +1096,7 @@ class TaskPanel:
else:
r = v.cross(normal) # rotation axis
a = DraftVecUtils.angle(normal, v, r) * 180 / math.pi
PathLog.debug(
Path.Log.debug(
"oh boy: (%.2f, %.2f, %.2f) x (%.2f, %.2f, %.2f) -> (%.2f, %.2f, %.2f) -> %.2f"
% (v.x, v.y, v.z, normal.x, normal.y, normal.z, r.x, r.y, r.z, a)
)
@@ -1117,26 +1109,26 @@ class TaskPanel:
selObject = sel.Object
for feature in sel.SubElementNames:
selFeature = feature
PathLog.track(selObject.Label, feature)
Path.Log.track(selObject.Label, feature)
sub = sel.Object.Shape.getElement(feature)
if "Face" == sub.ShapeType:
normal = sub.normalAt(0, 0)
if sub.Orientation == "Reversed":
normal = FreeCAD.Vector() - normal
PathLog.debug(
Path.Log.debug(
"(%.2f, %.2f, %.2f) -> reversed (%s)"
% (normal.x, normal.y, normal.z, sub.Orientation)
)
else:
PathLog.debug(
Path.Log.debug(
"(%.2f, %.2f, %.2f) -> forward (%s)"
% (normal.x, normal.y, normal.z, sub.Orientation)
)
if PathGeom.pointsCoincide(axis, normal):
if Path.Geom.pointsCoincide(axis, normal):
alignSel(sel, normal, True)
elif PathGeom.pointsCoincide(axis, FreeCAD.Vector() - normal):
elif Path.Geom.pointsCoincide(axis, FreeCAD.Vector() - normal):
alignSel(sel, FreeCAD.Vector() - normal, True)
else:
alignSel(sel, normal)
@@ -1145,9 +1137,9 @@ class TaskPanel:
normal = (
sub.Vertexes[1].Point - sub.Vertexes[0].Point
).normalize()
if PathGeom.pointsCoincide(
if Path.Geom.pointsCoincide(
axis, normal
) or PathGeom.pointsCoincide(axis, FreeCAD.Vector() - normal):
) or Path.Geom.pointsCoincide(axis, FreeCAD.Vector() - normal):
# Don't really know the orientation of an edge, so let's just flip the object
# and if the user doesn't like it they can flip again
alignSel(sel, normal, True)
@@ -1155,7 +1147,7 @@ class TaskPanel:
alignSel(sel, normal)
else:
PathLog.track(sub.ShapeType)
Path.Log.track(sub.ShapeType)
if selObject and selFeature:
FreeCADGui.Selection.clearSelection()
@@ -1167,19 +1159,19 @@ class TaskPanel:
FreeCADGui.Selection.addSelection(sel.Object, sel.SubElementNames)
def modelSet0(self, axis):
PathLog.track(axis)
Path.Log.track(axis)
with selectionEx() as selection:
for sel in selection:
selObject = sel.Object
PathLog.track(selObject.Label)
Path.Log.track(selObject.Label)
for name in sel.SubElementNames:
PathLog.track(selObject.Label, name)
Path.Log.track(selObject.Label, name)
feature = selObject.Shape.getElement(name)
bb = feature.BoundBox
offset = FreeCAD.Vector(
axis.x * bb.XMax, axis.y * bb.YMax, axis.z * bb.ZMax
)
PathLog.track(feature.BoundBox.ZMax, offset)
Path.Log.track(feature.BoundBox.ZMax, offset)
p = selObject.Placement
p.move(offset)
selObject.Placement = p
@@ -1254,7 +1246,7 @@ class TaskPanel:
def updateStockEditor(self, index, force=False):
def setupFromBaseEdit():
PathLog.track(index, force)
Path.Log.track(index, force)
if force or not self.stockFromBase:
self.stockFromBase = StockFromBaseBoundBoxEdit(
self.obj, self.form, force
@@ -1262,13 +1254,13 @@ class TaskPanel:
self.stockEdit = self.stockFromBase
def setupCreateBoxEdit():
PathLog.track(index, force)
Path.Log.track(index, force)
if force or not self.stockCreateBox:
self.stockCreateBox = StockCreateBoxEdit(self.obj, self.form, force)
self.stockEdit = self.stockCreateBox
def setupCreateCylinderEdit():
PathLog.track(index, force)
Path.Log.track(index, force)
if force or not self.stockCreateCylinder:
self.stockCreateCylinder = StockCreateCylinderEdit(
self.obj, self.form, force
@@ -1276,7 +1268,7 @@ class TaskPanel:
self.stockEdit = self.stockCreateCylinder
def setupFromExisting():
PathLog.track(index, force)
Path.Log.track(index, force)
if force or not self.stockFromExisting:
self.stockFromExisting = StockFromExistingEdit(
self.obj, self.form, force
@@ -1296,7 +1288,7 @@ class TaskPanel:
elif StockFromExistingEdit.IsStock(self.obj):
setupFromExisting()
else:
PathLog.error(
Path.Log.error(
translate("Path_Job", "Unsupported stock object %s")
% self.obj.Stock.Label
)
@@ -1312,7 +1304,7 @@ class TaskPanel:
setupFromBaseEdit()
index = -1
else:
PathLog.error(
Path.Log.error(
translate("Path_Job", "Unsupported stock type %s (%d)")
% (self.form.stock.currentText(), index)
)
@@ -1443,7 +1435,7 @@ class TaskPanel:
if obsolete or additions:
self.setFields()
else:
PathLog.track("no changes to model")
Path.Log.track("no changes to model")
def tabPageChanged(self, index):
if index == 0:
@@ -1459,7 +1451,7 @@ class TaskPanel:
try:
self.setupOps.setupUi()
except Exception as ee:
PathLog.error(str(ee))
Path.Log.error(str(ee))
self.updateStockEditor(-1, False)
self.setFields()
@@ -1635,7 +1627,7 @@ class TaskPanel:
def Create(base, template=None, openTaskPanel=True):
"""Create(base, template) ... creates a job instance for the given base object
using template to configure it."""
FreeCADGui.addModule("PathScripts.PathJob")
FreeCADGui.addModule("Path.Main.Job")
FreeCAD.ActiveDocument.openTransaction("Create Job")
try:
obj = PathJob.Create("Job", base, template)
@@ -1649,7 +1641,7 @@ def Create(base, template=None, openTaskPanel=True):
obj.ViewObject.Proxy.deleteOnReject = False
return obj
except Exception as exc:
PathLog.error(exc)
Path.Log.error(exc)
traceback.print_exc()
FreeCAD.ActiveDocument.abortTransaction()

View File

@@ -24,12 +24,11 @@ from PySide import QtCore, QtGui
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import FreeCADGui
import PathScripts.PathJob as PathJob
import PathScripts.PathJobDlg as PathJobDlg
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathStock as PathStock
import PathScripts.PathUtil as PathUtil
import Path
import Path.Base.Util as PathUtil
import Path.Main.Gui.JobDlg as PathJobDlg
import Path.Main.Job as PathJob
import Path.Main.Stock as PathStock
import json
import os
@@ -37,10 +36,10 @@ import os
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class CommandJobCreate:
@@ -76,13 +75,13 @@ class CommandJobCreate:
@classmethod
def Execute(cls, base, template):
FreeCADGui.addModule("PathScripts.PathJobGui")
FreeCADGui.addModule("Path.Main.Gui.Job")
if template:
template = "'%s'" % template
else:
template = "None"
FreeCADGui.doCommand(
"PathScripts.PathJobGui.Create(%s, %s)" % ([o.Name for o in base], template)
"Path.Main.Gui.Job.Create(%s, %s)" % ([o.Name for o in base], template)
)
@@ -136,7 +135,7 @@ class CommandJobTemplateExport:
foo = QtGui.QFileDialog.getSaveFileName(
QtGui.QApplication.activeWindow(),
"Path - Job Template",
PathPreferences.filePath(),
Path.Preferences.filePath(),
"job_*.json",
)[0]
if foo:

View File

@@ -24,11 +24,10 @@ from PySide import QtCore, QtGui
from collections import Counter
import FreeCAD
import FreeCADGui
import PathScripts.PathJob as PathJob
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathStock as PathStock
import PathScripts.PathUtil as PathUtil
import Path
import Path.Base.Util as PathUtil
import Path.Main.Job as PathJob
import Path.Main.Stock as PathStock
import glob
import os
@@ -36,10 +35,10 @@ translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class _ItemDelegate(QtGui.QStyledItemDelegate):
@@ -223,7 +222,7 @@ class JobCreate:
def setupTemplate(self):
templateFiles = []
for path in PathPreferences.searchPaths():
for path in Path.Preferences.searchPaths():
cleanPaths = [
f.replace("\\", "/") for f in self.templateFilesIn(path)
] # Standardize slashes used across os platforms
@@ -238,9 +237,9 @@ class JobCreate:
while name in template:
i = i + 1
name = basename + " (%s)" % i
PathLog.track(name, tFile)
Path.Log.track(name, tFile)
template[name] = tFile
selectTemplate = PathPreferences.defaultJobTemplate()
selectTemplate = Path.Preferences.defaultJobTemplate()
index = 0
self.dialog.jobTemplate.addItem("<none>", "")
for name in sorted(template.keys()):
@@ -253,7 +252,7 @@ class JobCreate:
def templateFilesIn(self, path):
"""templateFilesIn(path) ... answer all file in the given directory which fit the job template naming convention.
PathJob template files are name job_*.json"""
PathLog.track(path)
Path.Log.track(path)
return glob.glob(path + "/job_*.json")
def getModels(self):
@@ -353,7 +352,7 @@ class JobTemplateExport:
else: # Existing Solid
seHint = "-"
PathLog.error(translate("Path_Job", "Unsupported stock type"))
Path.Log.error(translate("Path_Job", "Unsupported stock type"))
self.dialog.stockExtentHint.setText(seHint)
spHint = "%s" % job.Stock.Placement
self.dialog.stockPlacementHint.setText(spHint)

View File

@@ -22,17 +22,15 @@
import FreeCAD
import Path
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathStock as PathStock
import Path.Main.Stock as PathStock
import Path.Post.Processor as PostProcessor
import json
from FreeCAD import Units
from PySide import QtCore, QtGui
from PathScripts.PathPostProcessor import PostProcessor
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class JobPreferencesPage:
@@ -53,7 +51,7 @@ class JobPreferencesPage:
jobTemplate = self.form.leDefaultJobTemplate.text()
geometryTolerance = Units.Quantity(self.form.geometryTolerance.text())
curveAccuracy = Units.Quantity(self.form.curveAccuracy.text())
PathPreferences.setJobDefaults(
Path.Preferences.setJobDefaults(
filePath, jobTemplate, geometryTolerance, curveAccuracy
)
@@ -67,11 +65,11 @@ class JobPreferencesPage:
item = self.form.postProcessorList.item(i)
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
blacklist.append(item.text())
PathPreferences.setPostProcessorDefaults(processor, args, blacklist)
Path.Preferences.setPostProcessorDefaults(processor, args, blacklist)
path = str(self.form.leOutputFile.text())
policy = str(self.form.cboOutputPolicy.currentText())
PathPreferences.setOutputFileDefaults(path, policy)
Path.Preferences.setOutputFileDefaults(path, policy)
self.saveStockSettings()
self.saveToolsSettings()
@@ -142,14 +140,13 @@ class JobPreferencesPage:
attrs["posZ"] = FreeCAD.Units.Quantity(
self.form.stockPositionZ.text()
).Value
PathPreferences.setDefaultStockTemplate(json.dumps(attrs))
Path.Preferences.setDefaultStockTemplate(json.dumps(attrs))
else:
PathPreferences.setDefaultStockTemplate("")
Path.Preferences.setDefaultStockTemplate("")
def saveToolsSettings(self):
PathPreferences.setToolsSettings(
self.form.toolsUseLegacy.isChecked(),
self.form.toolsAbsolutePaths.isChecked(),
Path.Preferences.setToolsSettings(
self.form.toolsAbsolutePaths.isChecked()
)
def selectComboEntry(self, widget, text):
@@ -183,11 +180,11 @@ class JobPreferencesPage:
)
def loadSettings(self):
self.form.leDefaultFilePath.setText(PathPreferences.defaultFilePath())
self.form.leDefaultJobTemplate.setText(PathPreferences.defaultJobTemplate())
self.form.leDefaultFilePath.setText(Path.Preferences.defaultFilePath())
self.form.leDefaultJobTemplate.setText(Path.Preferences.defaultJobTemplate())
blacklist = PathPreferences.postProcessorBlacklist()
for processor in PathPreferences.allAvailablePostProcessors():
blacklist = Path.Preferences.postProcessorBlacklist()
for processor in Path.Preferences.allAvailablePostProcessors():
item = QtGui.QListWidgetItem(processor)
if processor in blacklist:
item.setCheckState(QtCore.Qt.CheckState.Unchecked)
@@ -200,26 +197,26 @@ class JobPreferencesPage:
)
self.form.postProcessorList.addItem(item)
self.verifyAndUpdateDefaultPostProcessorWith(
PathPreferences.defaultPostProcessor()
Path.Preferences.defaultPostProcessor()
)
self.form.defaultPostProcessorArgs.setText(
PathPreferences.defaultPostProcessorArgs()
Path.Preferences.defaultPostProcessorArgs()
)
geomTol = Units.Quantity(
PathPreferences.defaultGeometryTolerance(), Units.Length
Path.Preferences.defaultGeometryTolerance(), Units.Length
)
self.form.geometryTolerance.setText(geomTol.UserString)
self.form.curveAccuracy.setText(
Units.Quantity(
PathPreferences.defaultLibAreaCurveAccuracy(), Units.Length
Path.Preferences.defaultLibAreaCurveAccuracy(), Units.Length
).UserString
)
self.form.leOutputFile.setText(PathPreferences.defaultOutputFile())
self.form.leOutputFile.setText(Path.Preferences.defaultOutputFile())
self.selectComboEntry(
self.form.cboOutputPolicy, PathPreferences.defaultOutputPolicy()
self.form.cboOutputPolicy, Path.Preferences.defaultOutputPolicy()
)
self.form.tbDefaultFilePath.clicked.connect(self.browseDefaultFilePath)
@@ -237,7 +234,7 @@ class JobPreferencesPage:
self.loadToolSettings()
def loadStockSettings(self):
stock = PathPreferences.defaultStockTemplate()
stock = Path.Preferences.defaultStockTemplate()
index = -1
if stock:
attrs = json.loads(stock)
@@ -329,9 +326,8 @@ class JobPreferencesPage:
self.form.stockCreateCylinder.hide()
def loadToolSettings(self):
self.form.toolsUseLegacy.setChecked(PathPreferences.toolsUseLegacyTools())
self.form.toolsAbsolutePaths.setChecked(
PathPreferences.toolsStoreAbsolutePaths()
Path.Preferences.toolsStoreAbsolutePaths()
)
def getPostProcessor(self, name):
@@ -373,7 +369,7 @@ class JobPreferencesPage:
def bestGuessForFilePath(self):
path = self.form.leDefaultFilePath.text()
if not path:
path = PathPreferences.filePath()
path = Path.Preferences.filePath()
return path
def browseDefaultJobTemplate(self):

View File

@@ -32,10 +32,9 @@ from __future__ import print_function
from PySide import QtCore, QtGui
import FreeCAD
import FreeCADGui
import Path
import Path.Base.Util as PathUtil
import PathScripts
import PathScripts.PathLog as PathLog
import PathScripts.PathUtil as PathUtil
import PathScripts.PathPreferences as PathPreferences
from collections import Counter
from datetime import datetime
import os
@@ -47,18 +46,18 @@ translate = FreeCAD.Qt.translate
LOG_MODULE = "PathSanity"
# PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
# PathLog.trackModule('PathSanity')
# Path.Log.setLevel(Path.Log.Level.INFO, LOG_MODULE)
# Path.Log.trackModule('PathSanity')
class CommandPathSanity:
def resolveOutputPath(self, job):
if job.PostProcessorOutputFile != "":
filepath = job.PostProcessorOutputFile
elif PathPreferences.defaultOutputFile() != "":
filepath = PathPreferences.defaultOutputFile()
elif Path.Preferences.defaultOutputFile() != "":
filepath = Path.Preferences.defaultOutputFile()
else:
filepath = PathPreferences.macroFilePath()
filepath = Path.Preferences.macroFilePath()
if "%D" in filepath:
D = FreeCAD.ActiveDocument.FileName
@@ -87,14 +86,14 @@ class CommandPathSanity:
M = pref.GetString("MacroPath", FreeCAD.getUserAppDataDir())
filepath = filepath.replace("%M", M)
PathLog.debug("filepath: {}".format(filepath))
Path.Log.debug("filepath: {}".format(filepath))
# starting at the derived filename, iterate up until we have a valid
# directory to write to
while not os.path.isdir(filepath):
filepath = os.path.dirname(filepath)
PathLog.debug("filepath: {}".format(filepath))
Path.Log.debug("filepath: {}".format(filepath))
return filepath + os.sep
def GetResources(self):
@@ -111,7 +110,7 @@ class CommandPathSanity:
def IsActive(self):
obj = FreeCADGui.Selection.getSelectionEx()[0].Object
return isinstance(obj.Proxy, PathScripts.PathJob.ObjectJob)
return isinstance(obj.Proxy, Path.Main.Job.ObjectJob)
def Activated(self):
# if everything is ok, execute
@@ -552,7 +551,7 @@ class CommandPathSanity:
m = 0
for i in obj.Document.Objects:
if hasattr(i, "Proxy"):
if isinstance(i.Proxy, PathScripts.PathJob.ObjectJob):
if isinstance(i.Proxy, Path.Main.Job.ObjectJob):
m += 1
if i is obj:
n = m
@@ -820,7 +819,7 @@ class CommandPathSanity:
fname = obj.PostProcessorOutputFile
data["outputfilename"] = os.path.splitext(os.path.basename(fname))[0]
for op in obj.Operations.Group:
if isinstance(op.Proxy, PathScripts.PathStop.Stop) and op.Stop is True:
if isinstance(op.Proxy, Path.Op.Gui.Stop.Stop) and op.Stop is True:
data["optionalstops"] = "True"
if obj.LastPostProcessOutput == "":

View File

@@ -22,12 +22,10 @@
import FreeCAD
import Path
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathDressup as PathDressup
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathUtil as PathUtil
import PathScripts.PathJob as PathJob
import Path.Base.Util as PathUtil
import Path.Dressup.Utils as PathDressup
import Path.Main.Job as PathJob
import PathGui
import PathSimulator
import math
import os
@@ -189,20 +187,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()
@@ -413,14 +398,14 @@ class PathSimulation:
self.PerformCutBoolean()
def RapidMove(self, cmd, curpos):
path = PathGeom.edgeForCmd(cmd, curpos) # hack to overcome occ bug
path = Path.Geom.edgeForCmd(cmd, curpos) # hack to overcome occ bug
if path is None:
return curpos
return path.valueAt(path.LastParameter)
# get a solid representation of a tool going along path
def GetPathSolid(self, tool, cmd, pos):
toolPath = PathGeom.edgeForCmd(cmd, pos)
toolPath = Path.Geom.edgeForCmd(cmd, pos)
startDir = toolPath.tangentAt(0)
startDir[2] = 0.0
endPos = toolPath.valueAt(toolPath.LastParameter)
@@ -475,7 +460,7 @@ class PathSimulation:
h = tool.CuttingEdgeHeight
if h <= 0.0: # set default if user fails to avoid freeze
h = 1.0
PathLog.error("SET Tool Length")
Path.Log.error("SET Tool Length")
# common to all tools
vTR = Vector(xp + yf, yp - xf, zp + h)
vTC = Vector(xp, yp, zp + h)

View File

View File

@@ -20,19 +20,17 @@
# * *
# ***************************************************************************
from PathScripts.PathPostProcessor import PostProcessor
from Path.Post.Processor import PostProcessor
from PySide import QtCore
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathSetupSheet as PathSetupSheet
import PathScripts.PathStock as PathStock
import PathScripts.PathToolController as PathToolController
import PathScripts.PathUtil as PathUtil
import Path
import Path.Base.SetupSheet as PathSetupSheet
import Path.Base.Util as PathUtil
import Path.Main.Stock as PathStock
import Path.Tool.Controller as PathToolController
import json
import time
import Path
# lazily loaded modules
@@ -42,10 +40,10 @@ Draft = LazyLoader("Draft", globals(), "Draft")
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -83,9 +81,9 @@ def createResourceClone(obj, orig, name, icon):
clone.addProperty("App::PropertyString", "PathResource")
clone.PathResource = name
if clone.ViewObject:
import PathScripts.PathIconViewProvider
import Path.Base.Gui.IconViewProvider
PathScripts.PathIconViewProvider.Attach(clone.ViewObject, icon)
Path.Base.Gui.IconViewProvider.Attach(clone.ViewObject, icon)
clone.ViewObject.Visibility = False
clone.ViewObject.Transparency = 80
obj.Document.recompute() # necessary to create the clone shape
@@ -223,16 +221,16 @@ class ObjectJob:
for n in self.propertyEnumerations():
setattr(obj, n[0], n[1])
obj.PostProcessorOutputFile = PathPreferences.defaultOutputFile()
obj.PostProcessor = postProcessors = PathPreferences.allEnabledPostProcessors()
defaultPostProcessor = PathPreferences.defaultPostProcessor()
obj.PostProcessorOutputFile = Path.Preferences.defaultOutputFile()
obj.PostProcessor = postProcessors = Path.Preferences.allEnabledPostProcessors()
defaultPostProcessor = Path.Preferences.defaultPostProcessor()
# Check to see if default post processor hasn't been 'lost' (This can happen when Macro dir has changed)
if defaultPostProcessor in postProcessors:
obj.PostProcessor = defaultPostProcessor
else:
obj.PostProcessor = postProcessors[0]
obj.PostProcessorArgs = PathPreferences.defaultPostProcessorArgs()
obj.GeometryTolerance = PathPreferences.defaultGeometryTolerance()
obj.PostProcessorArgs = Path.Preferences.defaultPostProcessorArgs()
obj.GeometryTolerance = Path.Preferences.defaultGeometryTolerance()
self.setupOperations(obj)
self.setupSetupSheet(obj)
@@ -272,11 +270,11 @@ class ObjectJob:
data = list()
idx = 0 if dataType == "translated" else 1
PathLog.debug(enums)
Path.Log.debug(enums)
for k, v in enumerate(enums):
data.append((v, [tup[idx] for tup in enums[v]]))
PathLog.debug(data)
Path.Log.debug(data)
return data
@@ -307,16 +305,16 @@ class ObjectJob:
)
obj.SetupSheet = PathSetupSheet.Create()
if obj.SetupSheet.ViewObject:
import PathScripts.PathIconViewProvider
import Path.Base.Gui.IconViewProvider
PathScripts.PathIconViewProvider.Attach(
Path.Base.Gui.IconViewProvider.Attach(
obj.SetupSheet.ViewObject, "SetupSheet"
)
obj.SetupSheet.Label = "SetupSheet"
self.setupSheet = obj.SetupSheet.Proxy
def setupBaseModel(self, obj, models=None):
PathLog.track(obj.Label, models)
Path.Log.track(obj.Label, models)
addModels = False
if not hasattr(obj, "Model"):
@@ -346,7 +344,7 @@ class ObjectJob:
obj.Model.Label = "Model"
if hasattr(obj, "Base"):
PathLog.info(
Path.Log.info(
"Converting Job.Base to new Job.Model for {}".format(obj.Label)
)
obj.Model.addObject(obj.Base)
@@ -383,7 +381,7 @@ class ObjectJob:
def setupStock(self, obj):
"""setupStock(obj)... setup the Stock for the Job object."""
if not obj.Stock:
stockTemplate = PathPreferences.defaultStockTemplate()
stockTemplate = Path.Preferences.defaultStockTemplate()
if stockTemplate:
obj.Stock = PathStock.CreateFromTemplate(obj, json.loads(stockTemplate))
if not obj.Stock:
@@ -403,12 +401,12 @@ class ObjectJob:
def onDelete(self, obj, arg2=None):
"""Called by the view provider, there doesn't seem to be a callback on the obj itself."""
PathLog.track(obj.Label, arg2)
Path.Log.track(obj.Label, arg2)
doc = obj.Document
if getattr(obj, "Operations", None):
# the first to tear down are the ops, they depend on other resources
PathLog.debug(
Path.Log.debug(
"taking down ops: %s" % [o.Name for o in self.allOperations()]
)
while obj.Operations.Group:
@@ -426,7 +424,7 @@ class ObjectJob:
# stock could depend on Model, so delete it first
if getattr(obj, "Stock", None):
PathLog.debug("taking down stock")
Path.Log.debug("taking down stock")
PathUtil.clearExpressionEngine(obj.Stock)
doc.removeObject(obj.Stock.Name)
obj.Stock = None
@@ -434,7 +432,7 @@ class ObjectJob:
# base doesn't depend on anything inside job
if getattr(obj, "Model", None):
for base in obj.Model.Group:
PathLog.debug("taking down base %s" % base.Label)
Path.Log.debug("taking down base %s" % base.Label)
self.removeBase(obj, base, False)
obj.Model.Group = []
doc.removeObject(obj.Model.Name)
@@ -442,7 +440,7 @@ class ObjectJob:
# Tool controllers might refer to either legacy tool or toolbit
if getattr(obj, "Tools", None):
PathLog.debug("taking down tool controller")
Path.Log.debug("taking down tool controller")
for tc in obj.Tools.Group:
if hasattr(tc.Tool, "Proxy"):
PathUtil.clearExpressionEngine(tc.Tool)
@@ -549,14 +547,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)
@@ -614,7 +604,11 @@ class ObjectJob:
if attrs.get(JobTemplate.ToolController):
for tc in attrs.get(JobTemplate.ToolController):
tcs.append(PathToolController.FromTemplate(tc))
ctrl = PathToolController.FromTemplate(tc)
if ctrl:
tcs.append(ctrl)
else:
Path.Log.debug(f"skipping TC {tc['name']}")
if attrs.get(JobTemplate.Stock):
obj.Stock = PathStock.CreateFromTemplate(
obj, attrs.get(JobTemplate.Stock)
@@ -631,10 +625,11 @@ class ObjectJob:
if attrs.get(JobTemplate.SplitOutput):
obj.SplitOutput = attrs.get(JobTemplate.SplitOutput)
PathLog.debug("setting tool controllers (%d)" % len(tcs))
obj.Tools.Group = tcs
Path.Log.debug("setting tool controllers (%d)" % len(tcs))
if tcs:
obj.Tools.Group = tcs
else:
PathLog.error(
Path.Log.error(
"Unsupported PathJob template version {}".format(
attrs.get(JobTemplate.Version)
)
@@ -719,7 +714,7 @@ class ObjectJob:
if removeBefore:
group.remove(before)
except Exception as e:
PathLog.error(e)
Path.Log.error(e)
group.append(op)
else:
group.append(op)
@@ -736,7 +731,7 @@ class ObjectJob:
def addToolController(self, tc):
group = self.obj.Tools.Group
PathLog.debug(
Path.Log.debug(
"addToolController(%s): %s" % (tc.Label, [t.Label for t in group])
)
if tc.Name not in [str(t.Name) for t in group]:
@@ -795,7 +790,7 @@ class ObjectJob:
suffix = job.Name[3:]
def errorMessage(grp, job):
PathLog.error("{} corrupt in {} job.".format(grp, job.Name))
Path.Log.error("{} corrupt in {} job.".format(grp, job.Name))
if not job.Operations:
self.setupOperations(job)

View File

@@ -23,7 +23,7 @@
"""Used to create material stock around a machined part - for visualization"""
import FreeCAD
import PathScripts.PathLog as PathLog
import Path
import math
from PySide.QtCore import QT_TRANSLATE_NOOP
from PySide import QtCore
@@ -36,10 +36,10 @@ Part = LazyLoader("Part", globals(), "Part")
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class StockType:
@@ -69,7 +69,7 @@ class StockType:
def shapeBoundBox(obj):
PathLog.track(type(obj))
Path.Log.track(type(obj))
if list == type(obj) and obj:
bb = FreeCAD.BoundBox()
for o in obj:
@@ -86,7 +86,7 @@ def shapeBoundBox(obj):
bb = bb.united(b)
return bb
if obj:
PathLog.error(
Path.Log.error(
translate("PathStock", "Invalid base object %s - no shape found") % obj.Name
)
return None
@@ -185,7 +185,7 @@ class StockFromBase(Stock):
FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin), FreeCAD.Rotation()
)
else:
PathLog.track(obj.Label, base.Label)
Path.Log.track(obj.Label, base.Label)
obj.Proxy = self
# debugging aids
@@ -206,7 +206,7 @@ class StockFromBase(Stock):
if obj.Base and hasattr(obj.Base, "Group")
else None
)
PathLog.track(obj.Label, bb)
Path.Log.track(obj.Label, bb)
# Sometimes, when the Base changes it's temporarily not assigned when
# Stock.execute is triggered - it'll be set correctly the next time around.
@@ -325,9 +325,8 @@ class StockCreateCylinder(Stock):
if prop in ["Radius", "Height"] and not "Restore" in obj.State:
self.execute(obj)
def SetupStockObject(obj, stockType):
PathLog.track(obj.Label, stockType)
Path.Log.track(obj.Label, stockType)
if FreeCAD.GuiUp and obj.ViewObject:
obj.addProperty(
"App::PropertyString",
@@ -338,9 +337,15 @@ def SetupStockObject(obj, stockType):
obj.StockType = stockType
obj.setEditorMode("StockType", 2) # hide
import PathScripts.PathIconViewProvider
# If I don't rename the module then usage as Path.Base.Gui.IconViewProvider below
# 'causes above Path.Log.track(...) to fail with - claiming that Path is accessed
# before it's assigned.
# Alternative _another_ `import Path` statement in front of `Path.Log.track(...)`
# also prevents the issue from happening.
# Go figure.
import Path.Base.Gui.IconViewProvider as PathIconViewProvider
PathScripts.PathIconViewProvider.ViewProvider(obj.ViewObject, "Stock")
PathIconViewProvider.ViewProvider(obj.ViewObject, "Stock")
obj.ViewObject.Transparency = 90
obj.ViewObject.DisplayMode = "Wireframe"
@@ -362,7 +367,7 @@ def _getBase(job):
def CreateFromBase(job, neg=None, pos=None, placement=None):
PathLog.track(job.Label, neg, pos, placement)
Path.Log.track(job.Label, neg, pos, placement)
base = _getBase(job)
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "Stock")
obj.Proxy = StockFromBase(obj, base)
@@ -512,7 +517,7 @@ def CreateFromTemplate(job, template):
or rotZ is not None
or rotW is not None
):
PathLog.warning(
Path.Log.warning(
"Corrupted or incomplete placement information in template - ignoring"
)
@@ -551,30 +556,30 @@ def CreateFromTemplate(job, template):
or zneg is not None
or zpos is not None
):
PathLog.error(
Path.Log.error(
"Corrupted or incomplete specification for creating stock from base - ignoring extent"
)
return CreateFromBase(job, neg, pos, placement)
if stockType == StockType.CreateBox:
PathLog.track(" create box")
Path.Log.track(" create box")
length = template.get("length")
width = template.get("width")
height = template.get("height")
extent = None
if length is not None and width is not None and height is not None:
PathLog.track(" have extent")
Path.Log.track(" have extent")
extent = FreeCAD.Vector(
FreeCAD.Units.Quantity(length).Value,
FreeCAD.Units.Quantity(width).Value,
FreeCAD.Units.Quantity(height).Value,
)
elif length is not None or width is not None or height is not None:
PathLog.error(
Path.Log.error(
"Corrupted or incomplete size for creating a stock box - ignoring size"
)
else:
PathLog.track(
Path.Log.track(
" take placement (%s) and extent (%s) from model"
% (placement, extent)
)
@@ -588,18 +593,18 @@ def CreateFromTemplate(job, template):
elif radius is not None or height is not None:
radius = None
height = None
PathLog.error(
Path.Log.error(
"Corrupted or incomplete size for creating a stock cylinder - ignoring size"
)
return CreateCylinder(job, radius, height, placement)
PathLog.error(
Path.Log.error(
translate("PathStock", "Unsupported stock type named {}").format(
stockType
)
)
else:
PathLog.error(
Path.Log.error(
translate(
"PathStock", "Unsupported PathStock template version {}"
).format(template.get("version"))

View File

View File

@@ -22,11 +22,9 @@
# * *
# ***************************************************************************
import PathScripts.PathOp as PathOp
import PathScripts.PathUtils as PathUtils
import PathScripts.PathLog as PathLog
import PathScripts.PathGeom as PathGeom
import Path
import Path.Op.Base as PathOp
import PathScripts.PathUtils as PathUtils
import FreeCAD
import time
import json
@@ -46,16 +44,16 @@ from lazy_loader.lazy_loader import LazyLoader
Part = LazyLoader("Part", globals(), "Part")
# TechDraw = LazyLoader('TechDraw', globals(), 'TechDraw')
FeatureExtensions = LazyLoader(
"PathScripts.PathFeatureExtensions", globals(), "PathScripts.PathFeatureExtensions"
"Path.Op.FeatureExtension", globals(), "Path.Op.FeatureExtension"
)
DraftGeomUtils = LazyLoader("DraftGeomUtils", globals(), "DraftGeomUtils")
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -653,7 +651,7 @@ def Execute(op, obj):
if FreeCAD.GuiUp:
sceneGraph = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
PathLog.info("*** Adaptive toolpath processing started...\n")
Path.Log.info("*** Adaptive toolpath processing started...\n")
# hide old toolpaths during recalculation
obj.Path = Path.Path("(Calculating...)")
@@ -680,7 +678,7 @@ def Execute(op, obj):
# Get list of working edges for adaptive algorithm
pathArray = op.pathArray
if not pathArray:
PathLog.error("No wire data returned.")
Path.Log.error("No wire data returned.")
return
path2d = convertTo2d(pathArray)
@@ -798,12 +796,12 @@ def Execute(op, obj):
GenerateGCode(op, obj, adaptiveResults, helixDiameter)
if not obj.StopProcessing:
PathLog.info("*** Done. Elapsed time: %f sec\n\n" % (time.time() - start))
Path.Log.info("*** Done. Elapsed time: %f sec\n\n" % (time.time() - start))
obj.AdaptiveOutputState = adaptiveResults
obj.AdaptiveInputState = inputStateObject
else:
PathLog.info(
Path.Log.info(
"*** Processing cancelled (after: %f sec).\n\n" % (time.time() - start)
)
@@ -870,7 +868,7 @@ def _get_working_edges(op, obj):
all_regions.append(f)
# Second face-combining method attempted
horizontal = PathGeom.combineHorizontalFaces(all_regions)
horizontal = Path.Geom.combineHorizontalFaces(all_regions)
if horizontal:
obj.removalshape = Part.makeCompound(horizontal)
for f in horizontal:
@@ -927,11 +925,11 @@ class PathAdaptive(PathOp.ObjectOp):
data = list()
idx = 0 if dataType == "translated" else 1
PathLog.debug(enums)
Path.Log.debug(enums)
for k, v in enumerate(enums):
data.append((v, [tup[idx] for tup in enums[v]]))
PathLog.debug(data)
Path.Log.debug(data)
return data

View File

@@ -23,8 +23,7 @@
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import Path
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import Path.Op.Base as PathOp
import PathScripts.PathUtils as PathUtils
@@ -33,7 +32,6 @@ from lazy_loader.lazy_loader import LazyLoader
Draft = LazyLoader("Draft", globals(), "Draft")
Part = LazyLoader("Part", globals(), "Part")
PathGeom = LazyLoader("PathScripts.PathGeom", globals(), "PathScripts.PathGeom")
__title__ = "Base class for PathArea based operations."
@@ -44,10 +42,10 @@ __contributors__ = "russ4262 (Russell Johnson)"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -82,7 +80,7 @@ class ObjectOp(PathOp.ObjectOp):
def initOperation(self, obj):
"""initOperation(obj) ... sets up standard Path.Area properties and calls initAreaOp().
Do not overwrite, overwrite initAreaOp(obj) instead."""
PathLog.track()
Path.Log.track()
# Debugging
obj.addProperty("App::PropertyString", "AreaParams", "Path")
@@ -113,16 +111,16 @@ class ObjectOp(PathOp.ObjectOp):
The default implementation returns the job's Base.Shape"""
if job:
if job.Stock:
PathLog.debug(
Path.Log.debug(
"job=%s base=%s shape=%s" % (job, job.Stock, job.Stock.Shape)
)
return job.Stock.Shape
else:
PathLog.warning(
Path.Log.warning(
translate("PathAreaOp", "job %s has no Base.") % job.Label
)
else:
PathLog.warning(
Path.Log.warning(
translate("PathAreaOp", "no job for op %s found.") % obj.Label
)
return None
@@ -137,7 +135,7 @@ class ObjectOp(PathOp.ObjectOp):
The base implementation takes a stab at determining Heights and Depths if the operations's Base
changes.
Do not overwrite, overwrite areaOpOnChanged(obj, prop) instead."""
# PathLog.track(obj.Label, prop)
# Path.Log.track(obj.Label, prop)
if prop in ["AreaParams", "PathParams", "removalshape"]:
obj.setEditorMode(prop, 2)
@@ -156,7 +154,7 @@ class ObjectOp(PathOp.ObjectOp):
self.areaOpOnChanged(obj, prop)
def opOnDocumentRestored(self, obj):
PathLog.track()
Path.Log.track()
for prop in ["AreaParams", "PathParams", "removalshape"]:
if hasattr(obj, prop):
obj.setEditorMode(prop, 2)
@@ -179,18 +177,18 @@ class ObjectOp(PathOp.ObjectOp):
The base implementation sets the depths and heights based on the
areaOpShapeForDepths() return value.
Do not overwrite, overwrite areaOpSetDefaultValues(obj, job) instead."""
PathLog.debug("opSetDefaultValues(%s, %s)" % (obj.Label, job.Label))
Path.Log.debug("opSetDefaultValues(%s, %s)" % (obj.Label, job.Label))
if PathOp.FeatureDepths & self.opFeatures(obj):
try:
shape = self.areaOpShapeForDepths(obj, job)
except Exception as ee:
PathLog.error(ee)
Path.Log.error(ee)
shape = None
# Set initial start and final depths
if shape is None:
PathLog.debug("shape is None")
Path.Log.debug("shape is None")
startDepth = 1.0
finalDepth = 0.0
else:
@@ -203,12 +201,12 @@ class ObjectOp(PathOp.ObjectOp):
obj.OpStartDepth.Value = startDepth
obj.OpFinalDepth.Value = finalDepth
PathLog.debug(
Path.Log.debug(
"Default OpDepths are Start: {}, and Final: {}".format(
obj.OpStartDepth.Value, obj.OpFinalDepth.Value
)
)
PathLog.debug(
Path.Log.debug(
"Default Depths are Start: {}, and Final: {}".format(
startDepth, finalDepth
)
@@ -223,7 +221,7 @@ class ObjectOp(PathOp.ObjectOp):
def _buildPathArea(self, obj, baseobject, isHole, start, getsim):
"""_buildPathArea(obj, baseobject, isHole, start, getsim) ... internal function."""
PathLog.track()
Path.Log.track()
area = Path.Area()
area.setPlane(PathUtils.makeWorkplane(baseobject))
area.add(baseobject)
@@ -232,18 +230,18 @@ class ObjectOp(PathOp.ObjectOp):
areaParams['SectionTolerance'] = 1e-07
heights = [i for i in self.depthparams]
PathLog.debug("depths: {}".format(heights))
Path.Log.debug("depths: {}".format(heights))
area.setParams(**areaParams)
obj.AreaParams = str(area.getParams())
PathLog.debug("Area with params: {}".format(area.getParams()))
Path.Log.debug("Area with params: {}".format(area.getParams()))
sections = area.makeSections(
mode=0, project=self.areaOpUseProjection(obj), heights=heights
)
PathLog.debug("sections = %s" % sections)
Path.Log.debug("sections = %s" % sections)
shapelist = [sec.getShape() for sec in sections]
PathLog.debug("shapelist = %s" % shapelist)
Path.Log.debug("shapelist = %s" % shapelist)
pathParams = self.areaOpPathParams(obj, isHole)
pathParams["shapes"] = shapelist
@@ -267,10 +265,10 @@ class ObjectOp(PathOp.ObjectOp):
obj.PathParams = str(
{key: value for key, value in pathParams.items() if key != "shapes"}
)
PathLog.debug("Path with params: {}".format(obj.PathParams))
Path.Log.debug("Path with params: {}".format(obj.PathParams))
(pp, end_vector) = Path.fromShapes(**pathParams)
PathLog.debug("pp: {}, end vector: {}".format(pp, end_vector))
Path.Log.debug("pp: {}, end vector: {}".format(pp, end_vector))
self.endVector = end_vector
simobj = None
@@ -287,11 +285,11 @@ class ObjectOp(PathOp.ObjectOp):
def _buildProfileOpenEdges(self, obj, edgeList, isHole, start, getsim):
"""_buildPathArea(obj, edgeList, isHole, start, getsim) ... internal function."""
PathLog.track()
Path.Log.track()
paths = []
heights = [i for i in self.depthparams]
PathLog.debug("depths: {}".format(heights))
Path.Log.debug("depths: {}".format(heights))
for i in range(0, len(heights)):
for baseShape in edgeList:
hWire = Part.Wire(Part.__sortEdges__(baseShape.Edges))
@@ -316,9 +314,9 @@ class ObjectOp(PathOp.ObjectOp):
x = verts[idx].X
y = verts[idx].Y
# Zero start value adjustments for Path.fromShapes() bug
if PathGeom.isRoughly(x, 0.0):
if Path.Geom.isRoughly(x, 0.0):
x = 0.00001
if PathGeom.isRoughly(y, 0.0):
if Path.Geom.isRoughly(y, 0.0):
y = 0.00001
pathParams["start"] = FreeCAD.Vector(x, y, verts[0].Z)
else:
@@ -327,11 +325,11 @@ class ObjectOp(PathOp.ObjectOp):
obj.PathParams = str(
{key: value for key, value in pathParams.items() if key != "shapes"}
)
PathLog.debug("Path with params: {}".format(obj.PathParams))
Path.Log.debug("Path with params: {}".format(obj.PathParams))
(pp, end_vector) = Path.fromShapes(**pathParams)
paths.extend(pp.Commands)
PathLog.debug("pp: {}, end vector: {}".format(pp, end_vector))
Path.Log.debug("pp: {}, end vector: {}".format(pp, end_vector))
self.endVector = end_vector
simobj = None
@@ -347,7 +345,7 @@ class ObjectOp(PathOp.ObjectOp):
areaOpShapes(obj) ... the shape for path area to process
areaOpUseProjection(obj) ... return true if operation can use projection
instead."""
PathLog.track()
Path.Log.track()
# Instantiate class variables for operation reference
self.endVector = None
@@ -445,7 +443,7 @@ class ObjectOp(PathOp.ObjectOp):
)
)
PathLog.debug("obj.Name: " + str(obj.Name) + "\n\n")
Path.Log.debug("obj.Name: " + str(obj.Name) + "\n\n")
return sims
def areaOpRetractTool(self, obj):

View File

@@ -24,10 +24,7 @@ import FreeCAD
from PathScripts.PathUtils import waiting_effects
from PySide.QtCore import QT_TRANSLATE_NOOP
import Path
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathUtil as PathUtil
import Path.Base.Util as PathUtil
import PathScripts.PathUtils as PathUtils
import math
import time
@@ -44,10 +41,10 @@ __url__ = "https://www.freecadweb.org"
__doc__ = "Base class and properties implementation for all Path operations."
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -164,7 +161,7 @@ class ObjectOp(object):
obj.setEditorMode("OpStockZMin", 1) # read-only
def __init__(self, obj, name, parentJob=None):
PathLog.track()
Path.Log.track()
obj.addProperty(
"App::PropertyBool",
@@ -336,8 +333,8 @@ class ObjectOp(object):
)
for n in self.opPropertyEnumerations():
PathLog.debug("n: {}".format(n))
PathLog.debug("n[0]: {} n[1]: {}".format(n[0], n[1]))
Path.Log.debug("n: {}".format(n))
Path.Log.debug("n[0]: {} n[1]: {}".format(n[0], n[1]))
if hasattr(obj, n[0]):
setattr(obj, n[0], n[1])
@@ -390,11 +387,11 @@ class ObjectOp(object):
data = list()
idx = 0 if dataType == "translated" else 1
PathLog.debug(enums)
Path.Log.debug(enums)
for k, v in enumerate(enums):
data.append((v, [tup[idx] for tup in enums[v]]))
PathLog.debug(data)
Path.Log.debug(data)
return data
@@ -410,13 +407,13 @@ class ObjectOp(object):
obj.setEditorMode("OpFinalDepth", 2)
def onDocumentRestored(self, obj):
PathLog.track()
Path.Log.track()
features = self.opFeatures(obj)
if (
FeatureBaseGeometry & features
and "App::PropertyLinkSubList" == obj.getTypeIdOfProperty("Base")
):
PathLog.info("Replacing link property with global link (%s)." % obj.State)
Path.Log.info("Replacing link property with global link (%s)." % obj.State)
base = obj.Base
obj.removeProperty("Base")
self.addBaseProperty(obj)
@@ -580,8 +577,8 @@ class ObjectOp(object):
obj.OpToolDiameter = obj.ToolController.Tool.Diameter
if FeatureCoolant & features:
PathLog.track()
PathLog.debug(obj.getEnumerationsOfProperty("CoolantMode"))
Path.Log.track()
Path.Log.debug(obj.getEnumerationsOfProperty("CoolantMode"))
obj.CoolantMode = job.SetupSheet.CoolantMode
if FeatureDepths & features:
@@ -635,11 +632,11 @@ class ObjectOp(object):
if not job:
if not ignoreErrors:
PathLog.error(translate("Path", "No parent job found for operation."))
Path.Log.error(translate("Path", "No parent job found for operation."))
return False
if not job.Model.Group:
if not ignoreErrors:
PathLog.error(
Path.Log.error(
translate("Path", "Parent job %s doesn't have a base object")
% job.Label
)
@@ -694,7 +691,7 @@ class ObjectOp(object):
zmin = max(zmin, faceZmin(bb, fbb))
zmax = max(zmax, fbb.ZMax)
except Part.OCCError as e:
PathLog.error(e)
Path.Log.error(e)
else:
# clearing with stock boundaries
@@ -704,12 +701,12 @@ class ObjectOp(object):
if FeatureDepths & self.opFeatures(obj):
# first set update final depth, it's value is not negotiable
if not PathGeom.isRoughly(obj.OpFinalDepth.Value, zmin):
if not Path.Geom.isRoughly(obj.OpFinalDepth.Value, zmin):
obj.OpFinalDepth = zmin
zmin = obj.OpFinalDepth.Value
def minZmax(z):
if hasattr(obj, "StepDown") and not PathGeom.isRoughly(
if hasattr(obj, "StepDown") and not Path.Geom.isRoughly(
obj.StepDown.Value, 0
):
return z + obj.StepDown.Value
@@ -721,7 +718,7 @@ class ObjectOp(object):
zmax = minZmax(zmin)
# update start depth if requested and required
if not PathGeom.isRoughly(obj.OpStartDepth.Value, zmax):
if not Path.Geom.isRoughly(obj.OpStartDepth.Value, zmax):
obj.OpStartDepth = zmax
else:
# every obj has a StartDepth
@@ -738,7 +735,7 @@ class ObjectOp(object):
for sub in sublist:
o.Shape.getElement(sub)
except Part.OCCError:
PathLog.error(
Path.Log.error(
"{} - stale base geometry detected - clearing.".format(obj.Label)
)
obj.Base = []
@@ -766,7 +763,7 @@ class ObjectOp(object):
Finally the base implementation adds a rapid move to clearance height and assigns
the receiver's Path property from the command list.
"""
PathLog.track()
Path.Log.track()
if not obj.Active:
path = Path.Path("(inactive operation)")
@@ -782,7 +779,7 @@ class ObjectOp(object):
if FeatureTool & self.opFeatures(obj):
tc = obj.ToolController
if tc is None or tc.ToolNumber == 0:
PathLog.error(
Path.Log.error(
translate(
"Path",
"No Tool Controller is selected. We need a tool to build a Path.",
@@ -796,7 +793,7 @@ class ObjectOp(object):
self.horizRapid = tc.HorizRapid.Value
tool = tc.Proxy.getTool(tc)
if not tool or float(tool.Diameter) == 0:
PathLog.error(
Path.Log.error(
translate(
"Path",
"No Tool found or diameter is zero. We need a tool to build a Path.",
@@ -836,7 +833,7 @@ class ObjectOp(object):
tc = obj.ToolController
if tc is None or tc.ToolNumber == 0:
PathLog.error(translate("Path", "No Tool Controller selected."))
Path.Log.error(translate("Path", "No Tool Controller selected."))
return translate("Path", "Tool Error")
hFeedrate = tc.HorizFeed.Value
@@ -846,8 +843,8 @@ class ObjectOp(object):
if (
hFeedrate == 0 or vFeedrate == 0
) and not PathPreferences.suppressAllSpeedsWarning():
PathLog.warning(
) and not Path.Preferences.suppressAllSpeedsWarning():
Path.Log.warning(
translate(
"Path",
"Tool Controller feedrates required to calculate the cycle time.",
@@ -857,8 +854,8 @@ class ObjectOp(object):
if (
hRapidrate == 0 or vRapidrate == 0
) and not PathPreferences.suppressRapidSpeedsWarning():
PathLog.warning(
) and not Path.Preferences.suppressRapidSpeedsWarning():
Path.Log.warning(
translate(
"Path",
"Add Tool Controller Rapid Speeds on the SetupSheet for more accurate cycle times.",
@@ -877,7 +874,7 @@ class ObjectOp(object):
return cycleTime
def addBase(self, obj, base, sub):
PathLog.track(obj, base, sub)
Path.Log.track(obj, base, sub)
base = PathUtil.getPublicObject(base)
if self._setBaseAndStock(obj):
@@ -892,7 +889,7 @@ class ObjectOp(object):
for p, el in baselist:
if p == base and sub in el:
PathLog.notice(
Path.Log.notice(
(
translate("Path", "Base object %s.%s already in the list")
+ "\n"
@@ -905,7 +902,7 @@ class ObjectOp(object):
baselist.append((base, sub))
obj.Base = baselist
else:
PathLog.notice(
Path.Log.notice(
(
translate("Path", "Base object %s.%s rejected by operation")
+ "\n"

View File

@@ -22,9 +22,9 @@
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import PathScripts.drillableLib as drillableLib
import Path
import Path.Op.Base as PathOp
import Path.Base.Drillable as Drillable
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -44,10 +44,10 @@ translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class ObjectOp(PathOp.ObjectOp):
@@ -109,7 +109,7 @@ class ObjectOp(PathOp.ObjectOp):
# for all other shapes the diameter is just the dimension in X.
# This may be inaccurate as the BoundBox is calculated on the tessellated geometry
PathLog.warning(
Path.Log.warning(
translate(
"Path",
"Hole diameter may be inaccurate due to tessellation on face. Consider selecting hole edge.",
@@ -117,7 +117,7 @@ class ObjectOp(PathOp.ObjectOp):
)
return shape.BoundBox.XLength
except Part.OCCError as e:
PathLog.error(e)
Path.Log.error(e)
return 0
@@ -141,9 +141,9 @@ class ObjectOp(PathOp.ObjectOp):
if len(shape.Edges) == 1 and type(shape.Edges[0].Curve) == Part.Circle:
return shape.Edges[0].Curve.Center
except Part.OCCError as e:
PathLog.error(e)
Path.Log.error(e)
PathLog.error(
Path.Log.error(
translate(
"Path",
"Feature %s.%s cannot be processed as a circular hole - please remove from Base geometry list.",
@@ -164,7 +164,7 @@ class ObjectOp(PathOp.ObjectOp):
drillable features are added to Base. In this case appropriate values for depths are also
calculated and assigned.
Do not overwrite, implement circularHoleExecute(obj, holes) instead."""
PathLog.track()
Path.Log.track()
def haveLocations(self, obj):
if PathOp.FeatureLocations & self.opFeatures(obj):
@@ -174,7 +174,7 @@ class ObjectOp(PathOp.ObjectOp):
holes = []
for base, subs in obj.Base:
for sub in subs:
PathLog.debug("processing {} in {}".format(sub, base.Name))
Path.Log.debug("processing {} in {}".format(sub, base.Name))
if self.isHoleEnabled(obj, base, sub):
pos = self.holePosition(obj, base, sub)
if pos:
@@ -202,7 +202,7 @@ class ObjectOp(PathOp.ObjectOp):
def findAllHoles(self, obj):
"""findAllHoles(obj) ... find all holes of all base models and assign as features."""
PathLog.track()
Path.Log.track()
job = self.getJob(obj)
if not job:
return
@@ -213,7 +213,7 @@ class ObjectOp(PathOp.ObjectOp):
features = []
for base in self.model:
features.extend(
drillableLib.getDrillableTargets(
Drillable.getDrillableTargets(
base, ToolDiameter=tooldiameter, vector=matchvector
)
)

View File

@@ -22,9 +22,7 @@
import FreeCAD
import Path
import PathScripts.PathOp as PathOp
import PathScripts.PathLog as PathLog
import Path.Op.Base as PathOp
from PySide.QtCore import QT_TRANSLATE_NOOP
@@ -35,10 +33,10 @@ __doc__ = "Path Custom object and FreeCAD command"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate

View File

@@ -22,11 +22,10 @@
# ***************************************************************************
import FreeCAD
import PathScripts.PathEngraveBase as PathEngraveBase
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import PathScripts.PathOpTools as PathOpTools
import Path
import Path.Op.Base as PathOp
import Path.Op.EngraveBase as PathEngraveBase
import Path.Op.Util as PathOpUtil
import math
from PySide.QtCore import QT_TRANSLATE_NOOP
@@ -43,10 +42,10 @@ __doc__ = "Deburr operation."
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -61,7 +60,7 @@ def toolDepthAndOffset(width, extraDepth, tool, printInfo):
suppressInfo = False
if hasattr(tool, "CuttingEdgeAngle"):
angle = float(tool.CuttingEdgeAngle)
if PathGeom.isRoughly(angle, 180) or PathGeom.isRoughly(angle, 0):
if Path.Geom.isRoughly(angle, 180) or Path.Geom.isRoughly(angle, 0):
angle = 180
toolOffset = float(tool.Diameter) / 2
else:
@@ -95,7 +94,7 @@ def toolDepthAndOffset(width, extraDepth, tool, printInfo):
tan = math.tan(math.radians(angle / 2))
toolDepth = 0 if PathGeom.isRoughly(tan, 0) else width / tan
toolDepth = 0 if Path.Geom.isRoughly(tan, 0) else width / tan
depth = toolDepth + extraDepth
extraOffset = -width if angle == 180 else (extraDepth / tan)
offset = toolOffset + extraOffset
@@ -118,7 +117,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
)
def initOperation(self, obj):
PathLog.track(obj.Label)
Path.Log.track(obj.Label)
obj.addProperty(
"App::PropertyDistance",
"Width",
@@ -197,12 +196,12 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
data = list()
idx = 0 if dataType == "translated" else 1
PathLog.debug(enums)
Path.Log.debug(enums)
for k, v in enumerate(enums):
# data[k] = [tup[idx] for tup in v]
data.append((v, [tup[idx] for tup in enums[v]]))
PathLog.debug(data)
Path.Log.debug(data)
return data
@@ -210,7 +209,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
obj.setEditorMode("Join", 2) # hide for now
def opExecute(self, obj):
PathLog.track(obj.Label)
Path.Log.track(obj.Label)
if not hasattr(self, "printInfo"):
self.printInfo = True
try:
@@ -224,7 +223,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
# QtGui.QMessageBox.information(None, "Tool Error", msg)
# return
PathLog.track(obj.Label, depth, offset)
Path.Log.track(obj.Label, depth, offset)
self.basewires = []
self.adjusted_basewires = []
@@ -410,7 +409,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
for w in basewires:
self.adjusted_basewires.append(w)
wire = PathOpTools.offsetWire(w, base.Shape, offset, True, side)
wire = PathOpUtil.offsetWire(w, base.Shape, offset, True, side)
if wire:
wires.append(wire)
@@ -431,7 +430,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
zValues.append(z)
zValues.append(depth)
PathLog.track(obj.Label, depth, zValues)
Path.Log.track(obj.Label, depth, zValues)
if obj.EntryPoint < 0:
obj.EntryPoint = 0
@@ -444,7 +443,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
return base not in self.model
def opSetDefaultValues(self, obj, job):
PathLog.track(obj.Label, job.Label)
Path.Log.track(obj.Label, job.Label)
obj.Width = "1 mm"
obj.ExtraDepth = "0.5 mm"
obj.Join = "Round"

View File

@@ -24,15 +24,14 @@
from __future__ import print_function
from Generators import drill_generator as generator
import FreeCAD
import Part
import Path
import PathFeedRate
import PathMachineState
import PathScripts.PathCircularHoleBase as PathCircularHoleBase
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import Path.Base.FeedRate as PathFeedRate
import Path.Base.Generator.drill as drill
import Path.Base.MachineState as PathMachineState
import Path.Op.Base as PathOp
import Path.Op.CircularHoleBase as PathCircularHoleBase
import PathScripts.PathUtils as PathUtils
from PySide.QtCore import QT_TRANSLATE_NOOP
@@ -43,10 +42,10 @@ __doc__ = "Path Drilling operation."
__contributors__ = "IMBack!"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -84,11 +83,11 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp):
data = list()
idx = 0 if dataType == "translated" else 1
PathLog.debug(enums)
Path.Log.debug(enums)
for k, v in enumerate(enums):
data.append((v, [tup[idx] for tup in enums[v]]))
PathLog.debug(data)
Path.Log.debug(data)
return data
@@ -180,7 +179,7 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp):
def circularHoleExecute(self, obj, holes):
"""circularHoleExecute(obj, holes) ... generate drill operation for each hole in holes."""
PathLog.track()
Path.Log.track()
machine = PathMachineState.MachineState()
self.commandlist.append(Path.Command("(Begin Drilling)"))
@@ -220,7 +219,7 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp):
# iterate the edgelist and generate gcode
for edge in edgelist:
PathLog.debug(edge)
Path.Log.debug(edge)
# move to hole location
@@ -249,7 +248,7 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp):
chipBreak = (obj.chipBreakEnabled and obj.PeckEnabled)
try:
drillcommands = generator.generate(
drillcommands = drill.generate(
edge,
dwelltime,
peckdepth,
@@ -259,7 +258,7 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp):
)
except ValueError as e: # any targets that fail the generator are ignored
PathLog.info(e)
Path.Log.info(e)
continue
for command in drillcommands:

View File

@@ -22,9 +22,8 @@
import FreeCAD
import Path
import PathScripts.PathEngraveBase as PathEngraveBase
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import Path.Op.Base as PathOp
import Path.Op.EngraveBase as PathEngraveBase
import PathScripts.PathUtils as PathUtils
from PySide.QtCore import QT_TRANSLATE_NOOP
@@ -32,10 +31,10 @@ from PySide.QtCore import QT_TRANSLATE_NOOP
__doc__ = "Class and implementation of Path Engrave operation"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -101,12 +100,12 @@ class ObjectEngrave(PathEngraveBase.ObjectOp):
def opExecute(self, obj):
"""opExecute(obj) ... process engraving operation"""
PathLog.track()
Path.Log.track()
jobshapes = []
if len(obj.Base) >= 1: # user has selected specific subelements
PathLog.track(len(obj.Base))
Path.Log.track(len(obj.Base))
wires = []
for base, subs in obj.Base:
edges = []
@@ -129,9 +128,9 @@ class ObjectEngrave(PathEngraveBase.ObjectOp):
elif len(obj.BaseShapes) > 0: # user added specific shapes
jobshapes.extend([base.Shape for base in obj.BaseShapes])
else:
PathLog.track(self.model)
Path.Log.track(self.model)
for base in self.model:
PathLog.track(base.Label)
Path.Log.track(base.Label)
if base.isDerivedFrom("Part::Part2DObject"):
jobshapes.append(base.Shape)
elif base.isDerivedFrom("Sketcher::SketchObject"):
@@ -140,11 +139,11 @@ class ObjectEngrave(PathEngraveBase.ObjectOp):
jobshapes.append(base.Shape)
if len(jobshapes) > 0:
PathLog.debug("processing {} jobshapes".format(len(jobshapes)))
Path.Log.debug("processing {} jobshapes".format(len(jobshapes)))
wires = []
for shape in jobshapes:
shapeWires = shape.Wires
PathLog.debug("jobshape has {} edges".format(len(shape.Edges)))
Path.Log.debug("jobshape has {} edges".format(len(shape.Edges)))
self.commandlist.append(
Path.Command(
"G0", {"Z": obj.ClearanceHeight.Value, "F": self.vertRapid}
@@ -153,7 +152,7 @@ class ObjectEngrave(PathEngraveBase.ObjectOp):
self.buildpathocc(obj, shapeWires, self.getZValues(obj))
wires.extend(shapeWires)
self.wires = wires
PathLog.debug(
Path.Log.debug(
"processing {} jobshapes -> {} wires".format(len(jobshapes), len(wires))
)
# the last command is a move to clearance, which is automatically added by PathOp

View File

@@ -22,10 +22,8 @@
from lazy_loader.lazy_loader import LazyLoader
import Path
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import PathScripts.PathOpTools as PathOpTools
import Path.Op.Base as PathOp
import Path.Op.Util as PathOpUtil
import copy
__doc__ = "Base class for all ops in the engrave family."
@@ -35,10 +33,10 @@ DraftGeomUtils = LazyLoader("DraftGeomUtils", globals(), "DraftGeomUtils")
Part = LazyLoader("Part", globals(), "Part")
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class ObjectOp(PathOp.ObjectOp):
@@ -61,11 +59,11 @@ class ObjectOp(PathOp.ObjectOp):
def buildpathocc(self, obj, wires, zValues, relZ=False, forward=True, start_idx=0):
"""buildpathocc(obj, wires, zValues, relZ=False) ... internal helper function to generate engraving commands."""
PathLog.track(obj.Label, len(wires), zValues)
Path.Log.track(obj.Label, len(wires), zValues)
decomposewires = []
for wire in wires:
decomposewires.extend(PathOpTools.makeWires(wire.Edges))
decomposewires.extend(PathOpUtil.makeWires(wire.Edges))
wires = decomposewires
for wire in wires:
@@ -76,15 +74,15 @@ class ObjectOp(PathOp.ObjectOp):
start_idx = obj.StartVertex
edges = wire.Edges
# edges = copy.copy(PathOpTools.orientWire(offset, forward).Edges)
# PathLog.track("wire: {} offset: {}".format(len(wire.Edges), len(edges)))
# edges = copy.copy(PathOpUtil.orientWire(offset, forward).Edges)
# Path.Log.track("wire: {} offset: {}".format(len(wire.Edges), len(edges)))
# edges = Part.sortEdges(edges)[0]
# PathLog.track("edges: {}".format(len(edges)))
# Path.Log.track("edges: {}".format(len(edges)))
last = None
for z in zValues:
PathLog.debug(z)
Path.Log.debug(z)
if last:
self.appendCommand(
Path.Command("G1", {"X": last.x, "Y": last.y, "Z": last.z}),
@@ -99,19 +97,19 @@ class ObjectOp(PathOp.ObjectOp):
edges = edges[start_idx:] + edges[:start_idx]
for edge in edges:
PathLog.debug(
Path.Log.debug(
"points: {} -> {}".format(
edge.Vertexes[0].Point, edge.Vertexes[-1].Point
)
)
PathLog.debug(
Path.Log.debug(
"valueat {} -> {}".format(
edge.valueAt(edge.FirstParameter),
edge.valueAt(edge.LastParameter),
)
)
if first and (not last or not wire.isClosed()):
PathLog.debug("processing first edge entry")
Path.Log.debug("processing first edge entry")
# we set the first move to our first point
last = edge.Vertexes[0].Point
@@ -139,13 +137,13 @@ class ObjectOp(PathOp.ObjectOp):
)
first = False
if PathGeom.pointsCoincide(last, edge.valueAt(edge.FirstParameter)):
# if PathGeom.pointsCoincide(last, edge.Vertexes[0].Point):
for cmd in PathGeom.cmdsForEdge(edge):
if Path.Geom.pointsCoincide(last, edge.valueAt(edge.FirstParameter)):
# if Path.Geom.pointsCoincide(last, edge.Vertexes[0].Point):
for cmd in Path.Geom.cmdsForEdge(edge):
self.appendCommand(cmd, z, relZ, self.horizFeed)
last = edge.Vertexes[-1].Point
else:
for cmd in PathGeom.cmdsForEdge(edge, True):
for cmd in Path.Geom.cmdsForEdge(edge, True):
self.appendCommand(cmd, z, relZ, self.horizFeed)
last = edge.Vertexes[0].Point
self.commandlist.append(

View File

@@ -23,8 +23,7 @@
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD
import Part
import PathScripts.PathGeom as PathGeom
import PathScripts.PathLog as PathLog
import Path
import math
# lazily loaded modules
@@ -40,10 +39,10 @@ __doc__ = "Class and implementation of face extensions features."
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -56,7 +55,7 @@ def endPoints(edgeOrWire):
pts.extend([e.valueAt(e.LastParameter) for e in edgeOrWire.Edges])
unique = []
for p in pts:
cnt = len([p2 for p2 in pts if PathGeom.pointsCoincide(p, p2)])
cnt = len([p2 for p2 in pts if Path.Geom.pointsCoincide(p, p2)])
if 1 == cnt:
unique.append(p)
@@ -64,7 +63,7 @@ def endPoints(edgeOrWire):
pfirst = edgeOrWire.valueAt(edgeOrWire.FirstParameter)
plast = edgeOrWire.valueAt(edgeOrWire.LastParameter)
if PathGeom.pointsCoincide(pfirst, plast):
if Path.Geom.pointsCoincide(pfirst, plast):
return None
return [pfirst, plast]
@@ -73,7 +72,7 @@ def endPoints(edgeOrWire):
def includesPoint(p, pts):
"""includesPoint(p, pts) ... answer True if the collection of pts includes the point p"""
for pt in pts:
if PathGeom.pointsCoincide(p, pt):
if Path.Geom.pointsCoincide(p, pt):
return True
return False
@@ -95,7 +94,7 @@ def selectOffsetWire(feature, wires):
def extendWire(feature, wire, length):
"""extendWire(wire, length) ... return a closed Wire which extends wire by length"""
PathLog.track(length)
Path.Log.track(length)
if not length or length == 0:
return None
@@ -103,7 +102,7 @@ def extendWire(feature, wire, length):
try:
off2D = wire.makeOffset2D(length)
except FreeCAD.Base.FreeCADError as ee:
PathLog.debug(ee)
Path.Log.debug(ee)
return None
endPts = endPoints(wire) # Assumes wire is NOT closed
if endPts:
@@ -157,7 +156,7 @@ def readObjExtensionFeature(obj):
def getExtensions(obj):
PathLog.debug("getExtenstions()")
Path.Log.debug("getExtenstions()")
extensions = []
i = 0
@@ -170,7 +169,7 @@ def getExtensions(obj):
def setExtensions(obj, extensions):
PathLog.track(obj.Label, len(extensions))
Path.Log.track(obj.Label, len(extensions))
obj.ExtensionFeature = [(ext.obj, ext.getSubLink()) for ext in extensions]
@@ -218,7 +217,7 @@ class Extension(object):
DirectionY = 2
def __init__(self, op, obj, feature, sub, length, direction):
PathLog.debug(
Path.Log.debug(
"Extension(%s, %s, %s, %.2f, %s"
% (obj.Label, feature, sub, length, direction)
)
@@ -229,7 +228,7 @@ class Extension(object):
self.length = length
self.direction = direction
self.extFaces = None
self.isDebug = True if PathLog.getLevel(PathLog.thisModule()) == 4 else False
self.isDebug = True if Path.Log.getLevel(Path.Log.thisModule()) == 4 else False
self.avoid = False
if sub.startswith("Avoid_"):
@@ -241,12 +240,12 @@ class Extension(object):
return "%s:%s" % (self.feature, self.sub)
def _extendEdge(self, feature, e0, direction):
PathLog.track(feature, e0, direction)
Path.Log.track(feature, e0, direction)
if isinstance(e0.Curve, Part.Line) or isinstance(e0.Curve, Part.LineSegment):
e2 = e0.copy()
off = self.length.Value * direction
e2.translate(off)
e2 = PathGeom.flipEdge(e2)
e2 = Path.Geom.flipEdge(e2)
e1 = Part.Edge(
Part.LineSegment(
e0.valueAt(e0.LastParameter), e2.valueAt(e2.FirstParameter)
@@ -269,7 +268,7 @@ class Extension(object):
else:
numbers = [self.sub[4:]]
PathLog.debug("_getEdgeNumbers() -> %s" % numbers)
Path.Log.debug("_getEdgeNumbers() -> %s" % numbers)
return numbers
def _getEdgeNames(self):
@@ -293,9 +292,9 @@ class Extension(object):
e0 = wire.Edges[0]
midparam = e0.FirstParameter + 0.5 * (e0.LastParameter - e0.FirstParameter)
tangent = e0.tangentAt(midparam)
PathLog.track("tangent", tangent, self.feature, self.sub)
Path.Log.track("tangent", tangent, self.feature, self.sub)
normal = tangent.cross(FreeCAD.Vector(0, 0, 1))
if PathGeom.pointsCoincide(normal, FreeCAD.Vector(0, 0, 0)):
if Path.Geom.pointsCoincide(normal, FreeCAD.Vector(0, 0, 0)):
return None
return self._getDirectedNormal(e0.valueAt(midparam), normal.normalize())
@@ -323,11 +322,11 @@ class Extension(object):
"""_getRegularWire()... Private method to retrieve the extension area, pertaining to the feature
and sub element provided at class instantiation, as a closed wire. If no closed wire
is possible, a `None` value is returned."""
PathLog.track()
Path.Log.track()
length = self.length.Value
if PathGeom.isRoughly(0, length) or not self.sub:
PathLog.debug("no extension, length=%.2f, sub=%s" % (length, self.sub))
if Path.Geom.isRoughly(0, length) or not self.sub:
Path.Log.debug("no extension, length=%.2f, sub=%s" % (length, self.sub))
return None
feature = self.obj.Shape.getElement(self.feature)
@@ -335,10 +334,10 @@ class Extension(object):
sub = Part.Wire(Part.sortEdges(edges)[0])
if 1 == len(edges):
PathLog.debug("Extending single edge wire")
Path.Log.debug("Extending single edge wire")
edge = edges[0]
if Part.Circle == type(edge.Curve):
PathLog.debug("is Part.Circle")
Path.Log.debug("is Part.Circle")
circle = edge.Curve
# for a circle we have to figure out if it's a hole or a cylinder
p0 = edge.valueAt(edge.FirstParameter)
@@ -347,14 +346,14 @@ class Extension(object):
if direction is None:
return None
if PathGeom.pointsCoincide(normal, direction):
if Path.Geom.pointsCoincide(normal, direction):
r = circle.Radius - length
else:
r = circle.Radius + length
# assuming the offset produces a valid circle - go for it
if r > 0:
PathLog.debug("radius > 0 - extend outward")
Path.Log.debug("radius > 0 - extend outward")
e3 = Part.makeCircle(
r,
circle.Center,
@@ -365,7 +364,7 @@ class Extension(object):
# Determine if rotational alignment is necessary for new arc
rotationAdjustment = arcAdjustmentAngle(edge, e3)
if not PathGeom.isRoughly(rotationAdjustment, 0.0):
if not Path.Geom.isRoughly(rotationAdjustment, 0.0):
e3.rotate(
edge.Curve.Center,
FreeCAD.Vector(0.0, 0.0, 1.0),
@@ -373,7 +372,7 @@ class Extension(object):
)
if endPoints(edge):
PathLog.debug("Make section of donut")
Path.Log.debug("Make section of donut")
# need to construct the arc slice
e0 = Part.makeLine(
edge.valueAt(edge.FirstParameter),
@@ -397,22 +396,22 @@ class Extension(object):
self.extFaces = [self._makeCircularExtFace(edge, extWire)]
return extWire
PathLog.debug("radius < 0 - extend inward")
Path.Log.debug("radius < 0 - extend inward")
# the extension is bigger than the hole - so let's just cover the whole hole
if endPoints(edge):
# if the resulting arc is smaller than the radius, create a pie slice
PathLog.track()
Path.Log.track()
center = circle.Center
e0 = Part.makeLine(center, edge.valueAt(edge.FirstParameter))
e2 = Part.makeLine(edge.valueAt(edge.LastParameter), center)
return Part.Wire([e0, edge, e2])
PathLog.track()
Path.Log.track()
return Part.Wire([edge])
else:
PathLog.debug("else is NOT Part.Circle")
PathLog.track(self.feature, self.sub, type(edge.Curve), endPoints(edge))
Path.Log.debug("else is NOT Part.Circle")
Path.Log.track(self.feature, self.sub, type(edge.Curve), endPoints(edge))
direction = self._getDirection(sub)
if direction is None:
return None
@@ -420,18 +419,18 @@ class Extension(object):
return self._extendEdge(feature, edges[0], direction)
elif sub.isClosed():
PathLog.debug("Extending multi-edge closed wire")
Path.Log.debug("Extending multi-edge closed wire")
subFace = Part.Face(sub)
featFace = Part.Face(feature.Wires[0])
isOutside = True
if not PathGeom.isRoughly(featFace.Area, subFace.Area):
if not Path.Geom.isRoughly(featFace.Area, subFace.Area):
length = -1.0 * length
isOutside = False
try:
off2D = sub.makeOffset2D(length)
except FreeCAD.Base.FreeCADError as ee:
PathLog.debug(ee)
Path.Log.debug(ee)
return None
if isOutside:
@@ -440,7 +439,7 @@ class Extension(object):
self.extFaces = [subFace.cut(Part.Face(off2D))]
return off2D
PathLog.debug("Extending multi-edge open wire")
Path.Log.debug("Extending multi-edge open wire")
extendedWire = extendWire(feature, sub, length)
if extendedWire is None:
return extendedWire
@@ -538,7 +537,7 @@ def getExtendOutlineFace(
face, extension, removeHoles=remHoles, plane=face, tolerance=offset_tolerance
)
if not offset_face:
PathLog.error("Failed to offset a selected face.")
Path.Log.error("Failed to offset a selected face.")
return None
# Apply collision detection by limiting extended face using base shape
@@ -560,9 +559,9 @@ def getExtendOutlineFace(
bbx = f.BoundBox
zNorm = abs(f.normalAt(0.0, 0.0).z)
if (
PathGeom.isRoughly(zNorm, 1.0)
and PathGeom.isRoughly(bbx.ZMax - bbx.ZMin, 0.0)
and PathGeom.isRoughly(bbx.ZMin, face.BoundBox.ZMin)
Path.Geom.isRoughly(zNorm, 1.0)
and Path.Geom.isRoughly(bbx.ZMax - bbx.ZMin, 0.0)
and Path.Geom.isRoughly(bbx.ZMin, face.BoundBox.ZMin)
):
if bbx.ZMin < zmin:
bottom_faces.append(f)
@@ -579,7 +578,7 @@ def getExtendOutlineFace(
return extended
PathLog.error("No bottom face for extend outline.")
Path.Log.error("No bottom face for extend outline.")
return None
@@ -610,7 +609,7 @@ def getWaterlineFace(base_shape, face):
# Get top face(s) of envelope at face height
rawList = list()
for f in env.Faces:
if PathGeom.isRoughly(f.BoundBox.ZMin, faceHeight):
if Path.Geom.isRoughly(f.BoundBox.ZMin, faceHeight):
rawList.append(f)
# make compound and extrude downward
rawComp = Part.makeCompound(rawList)

View File

@@ -21,11 +21,11 @@
# * *
# ***************************************************************************
import PathScripts.PathOpGui as PathOpGui
from PySide import QtCore
import PathScripts.PathAdaptive as PathAdaptive
import PathScripts.PathFeatureExtensionsGui as PathFeatureExtensionsGui
import FreeCADGui
import Path.Op.Adaptive as PathAdaptive
import Path.Op.Gui.Base as PathOpGui
import Path.Op.Gui.FeatureExtension as PathFeatureExtensionsGui
from PySide import QtCore
class TaskPanelOpPage(PathOpGui.TaskPanelPage):

View File

@@ -24,8 +24,7 @@ import FreeCAD
import FreeCADGui
import Path
import PathScripts
from PathScripts import PathLog
from PathScripts.PathDressup import toolController
from Path.Dressup.Utils import toolController
from PySide import QtCore
import math
import random
@@ -373,7 +372,7 @@ class PathArray:
path data for the requested path array."""
if len(self.baseList) == 0:
PathLog.error(translate("PathArray", "No base objects for PathArray."))
Path.Log.error(translate("PathArray", "No base objects for PathArray."))
return None
base = self.baseList
@@ -389,7 +388,7 @@ class PathArray:
if b_tool_controller != toolController(base[0]):
# this may be important if Job output is split by tool controller
PathLog.warning(
Path.Log.warning(
translate(
"PathArray",
"Arrays of paths having different tool controllers are handled according to the tool controller of the first path.",
@@ -540,14 +539,14 @@ class CommandPathArray:
# if everything is ok, execute and register the transaction in the
# undo/redo stack
FreeCAD.ActiveDocument.openTransaction("Create Array")
FreeCADGui.addModule("PathScripts.PathArray")
FreeCADGui.addModule("Path.Op.Gui.Array")
FreeCADGui.addModule("PathScripts.PathUtils")
FreeCADGui.doCommand(
'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Array")'
)
FreeCADGui.doCommand("PathScripts.PathArray.ObjectArray(obj)")
FreeCADGui.doCommand("Path.Op.Gui.Array.ObjectArray(obj)")
baseString = "[%s]" % ",".join(
["FreeCAD.ActiveDocument.%s" % sel.Name for sel in selection]

View File

@@ -22,17 +22,15 @@
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathGeom as PathGeom
import PathScripts.PathGetPoint as PathGetPoint
import PathScripts.PathGui as PathGui
import PathScripts.PathJob as PathJob
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathSelection as PathSelection
import PathScripts.PathSetupSheet as PathSetupSheet
import PathScripts.PathUtil as PathUtil
import Path
import Path.Base.Gui.GetPoint as PathGetPoint
import Path.Base.Gui.Util as PathGuiUtil
import Path.Base.SetupSheet as PathSetupSheet
import Path.Base.Util as PathUtil
import Path.Main.Job as PathJob
import Path.Op.Base as PathOp
import Path.Op.Gui.Selection as PathSelection
import PathGui
import PathScripts.PathUtils as PathUtils
import importlib
from PySide.QtCore import QT_TRANSLATE_NOOP
@@ -47,10 +45,10 @@ __doc__ = "Base classes and framework for Path operation's UI"
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class ViewProvider(object):
@@ -62,7 +60,7 @@ class ViewProvider(object):
"""
def __init__(self, vobj, resources):
PathLog.track()
Path.Log.track()
self.deleteOnReject = True
self.OpIcon = ":/icons/%s.svg" % resources.pixmap
self.OpName = resources.name
@@ -75,7 +73,7 @@ class ViewProvider(object):
self.panel = None
def attach(self, vobj):
PathLog.track()
Path.Log.track()
self.vobj = vobj
self.Object = vobj.Object
self.panel = None
@@ -88,17 +86,17 @@ class ViewProvider(object):
edit session, if the user does not press OK, it is assumed they've
changed their mind about creating the operation.
"""
PathLog.track()
Path.Log.track()
return hasattr(self, "deleteOnReject") and self.deleteOnReject
def setDeleteObjectsOnReject(self, state=False):
PathLog.track()
Path.Log.track()
self.deleteOnReject = state
return self.deleteOnReject
def setEdit(self, vobj=None, mode=0):
"""setEdit(vobj, mode=0) ... initiate editing of receivers model."""
PathLog.track()
Path.Log.track()
if 0 == mode:
if vobj is None:
vobj = self.vobj
@@ -124,7 +122,7 @@ class ViewProvider(object):
if job:
job.ViewObject.Proxy.setupEditVisibility(job)
else:
PathLog.info("did not find no job")
Path.Log.info("did not find no job")
def clearTaskPanel(self):
"""clearTaskPanel() ... internal callback function when editing has finished."""
@@ -140,7 +138,7 @@ class ViewProvider(object):
def __getstate__(self):
"""__getstate__() ... callback before receiver is saved to a file.
Returns a dictionary with the receiver's resources as strings."""
PathLog.track()
Path.Log.track()
state = {}
state["OpName"] = self.OpName
state["OpIcon"] = self.OpIcon
@@ -176,7 +174,7 @@ class ViewProvider(object):
def updateData(self, obj, prop):
"""updateData(obj, prop) ... callback whenever a property of the receiver's model is assigned.
The callback is forwarded to the task panel - in case an editing session is ongoing."""
# PathLog.track(obj.Label, prop) # Creates a lot of noise
# Path.Log.track(obj.Label, prop) # Creates a lot of noise
if self.panel:
self.panel.updateData(obj, prop)
@@ -185,7 +183,7 @@ class ViewProvider(object):
return True
def setupContextMenu(self, vobj, menu):
PathLog.track()
Path.Log.track()
for action in menu.actions():
menu.removeAction(action)
action = QtGui.QAction(translate("PathOp", "Edit"), menu)
@@ -376,8 +374,8 @@ class TaskPanelPage(object):
return
def populateCombobox(self, form, enumTups, comboBoxesPropertyMap):
"""populateCombobox(form, enumTups, comboBoxesPropertyMap) ... proxy for PathGui.populateCombobox()"""
PathGui.populateCombobox(form, enumTups, comboBoxesPropertyMap)
"""populateCombobox(form, enumTups, comboBoxesPropertyMap) ... proxy for PathGuiUtil.populateCombobox()"""
PathGuiUtil.populateCombobox(form, enumTups, comboBoxesPropertyMap)
def resetToolController(self, job, tc):
if self.obj is not None:
@@ -548,7 +546,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
"Please select %s from a single solid" % self.featureName(),
)
FreeCAD.Console.PrintError(msg + "\n")
PathLog.debug(msg)
Path.Log.debug(msg)
return False
sel = selection[0]
if sel.HasSubObjects:
@@ -557,26 +555,26 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
and selection[0].SubObjects[0].ShapeType == "Vertex"
):
if not ignoreErrors:
PathLog.error(translate("PathOp", "Vertexes are not supported"))
Path.Log.error(translate("PathOp", "Vertexes are not supported"))
return False
if (
not self.supportsEdges()
and selection[0].SubObjects[0].ShapeType == "Edge"
):
if not ignoreErrors:
PathLog.error(translate("PathOp", "Edges are not supported"))
Path.Log.error(translate("PathOp", "Edges are not supported"))
return False
if (
not self.supportsFaces()
and selection[0].SubObjects[0].ShapeType == "Face"
):
if not ignoreErrors:
PathLog.error(translate("PathOp", "Faces are not supported"))
Path.Log.error(translate("PathOp", "Faces are not supported"))
return False
else:
if not self.supportsPanels() or "Panel" not in sel.Object.Name:
if not ignoreErrors:
PathLog.error(
Path.Log.error(
translate(
"PathOp",
"Please select %s of a solid" % self.featureName(),
@@ -586,7 +584,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
return True
def addBaseGeometry(self, selection):
PathLog.track(selection)
Path.Log.track(selection)
if self.selectionSupportedAsBaseGeometry(selection, False):
sel = selection[0]
for sub in sel.SubElementNames:
@@ -595,7 +593,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
return False
def addBase(self):
PathLog.track()
Path.Log.track()
if self.addBaseGeometry(FreeCADGui.Selection.getSelectionEx()):
# self.obj.Proxy.execute(self.obj)
self.setFields(self.obj)
@@ -603,7 +601,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
self.updatePanelVisibility("Operation", self.obj)
def deleteBase(self):
PathLog.track()
Path.Log.track()
selected = self.form.baseList.selectedItems()
for item in selected:
self.form.baseList.takeItem(self.form.baseList.row(item))
@@ -621,7 +619,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
if sub:
base = (obj, str(sub))
newlist.append(base)
PathLog.debug("Setting new base: %s -> %s" % (self.obj.Base, newlist))
Path.Log.debug("Setting new base: %s -> %s" % (self.obj.Base, newlist))
self.obj.Base = newlist
# self.obj.Proxy.execute(self.obj)
@@ -677,7 +675,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
qList = self.form.baseList
row = (qList.count() + qList.frameWidth()) * 15
# qList.setMinimumHeight(row)
PathLog.debug(
Path.Log.debug(
"baseList({}, {}) {} * {}".format(
qList.size(), row, qList.count(), qList.sizeHintForRow(0)
)
@@ -748,7 +746,7 @@ class TaskPanelBaseLocationPage(TaskPanelPage):
FreeCAD.ActiveDocument.recompute()
def updateLocations(self):
PathLog.track()
Path.Log.track()
locations = []
for i in range(self.formLoc.baseList.rowCount()):
x = self.formLoc.baseList.item(i, 0).data(self.DataLocation)
@@ -824,10 +822,10 @@ class TaskPanelHeightsPage(TaskPanelPage):
return FreeCADGui.PySideUic.loadUi(":/panels/PageHeightsEdit.ui")
def initPage(self, obj):
self.safeHeight = PathGui.QuantitySpinBox(
self.safeHeight = PathGuiUtil.QuantitySpinBox(
self.form.safeHeight, obj, "SafeHeight"
)
self.clearanceHeight = PathGui.QuantitySpinBox(
self.clearanceHeight = PathGuiUtil.QuantitySpinBox(
self.form.clearanceHeight, obj, "ClearanceHeight"
)
@@ -892,7 +890,7 @@ class TaskPanelDepthsPage(TaskPanelPage):
def initPage(self, obj):
if self.haveStartDepth():
self.startDepth = PathGui.QuantitySpinBox(
self.startDepth = PathGuiUtil.QuantitySpinBox(
self.form.startDepth, obj, "StartDepth"
)
else:
@@ -901,7 +899,7 @@ class TaskPanelDepthsPage(TaskPanelPage):
self.form.startDepthSet.hide()
if self.haveFinalDepth():
self.finalDepth = PathGui.QuantitySpinBox(
self.finalDepth = PathGuiUtil.QuantitySpinBox(
self.form.finalDepth, obj, "FinalDepth"
)
else:
@@ -919,13 +917,13 @@ class TaskPanelDepthsPage(TaskPanelPage):
self.form.finalDepthSet.hide()
if self.haveStepDown():
self.stepDown = PathGui.QuantitySpinBox(self.form.stepDown, obj, "StepDown")
self.stepDown = PathGuiUtil.QuantitySpinBox(self.form.stepDown, obj, "StepDown")
else:
self.form.stepDown.hide()
self.form.stepDownLabel.hide()
if self.haveFinishDepth():
self.finishDepth = PathGui.QuantitySpinBox(
self.finishDepth = PathGuiUtil.QuantitySpinBox(
self.form.finishDepth, obj, "FinishDepth"
)
else:
@@ -985,7 +983,7 @@ class TaskPanelDepthsPage(TaskPanelPage):
def depthSet(self, obj, spinbox, prop):
z = self.selectionZLevel(FreeCADGui.Selection.getSelectionEx())
if z is not None:
PathLog.debug("depthSet(%s, %s, %.2f)" % (obj.Label, prop, z))
Path.Log.debug("depthSet(%s, %s, %.2f)" % (obj.Label, prop, z))
if spinbox.expression():
obj.setExpression(prop, None)
self.setDirty()
@@ -993,14 +991,14 @@ class TaskPanelDepthsPage(TaskPanelPage):
if spinbox.updateProperty():
self.setDirty()
else:
PathLog.info("depthSet(-)")
Path.Log.info("depthSet(-)")
def selectionZLevel(self, sel):
if len(sel) == 1 and len(sel[0].SubObjects) == 1:
sub = sel[0].SubObjects[0]
if "Vertex" == sub.ShapeType:
return sub.Z
if PathGeom.isHorizontal(sub):
if Path.Geom.isHorizontal(sub):
if "Edge" == sub.ShapeType:
return sub.Vertexes[0].Z
if "Face" == sub.ShapeType:
@@ -1030,10 +1028,10 @@ class TaskPanelDiametersPage(TaskPanelPage):
return FreeCADGui.PySideUic.loadUi(":/panels/PageDiametersEdit.ui")
def initPage(self, obj):
self.minDiameter = PathGui.QuantitySpinBox(
self.minDiameter = PathGuiUtil.QuantitySpinBox(
self.form.minDiameter, obj, "MinDiameter"
)
self.maxDiameter = PathGui.QuantitySpinBox(
self.maxDiameter = PathGuiUtil.QuantitySpinBox(
self.form.maxDiameter, obj, "MaxDiameter"
)
@@ -1071,7 +1069,7 @@ class TaskPanel(object):
"""
def __init__(self, obj, deleteOnReject, opPage, selectionFactory):
PathLog.track(obj.Label, deleteOnReject, opPage, selectionFactory)
Path.Log.track(obj.Label, deleteOnReject, opPage, selectionFactory)
FreeCAD.ActiveDocument.openTransaction(translate("PathOp", "AreaOp Operation"))
self.obj = obj
self.deleteOnReject = deleteOnReject
@@ -1133,7 +1131,7 @@ class TaskPanel(object):
page.initPage(obj)
page.onDirtyChanged(self.pageDirtyChanged)
taskPanelLayout = PathPreferences.defaultTaskPanelLayout()
taskPanelLayout = Path.Preferences.defaultTaskPanelLayout()
if taskPanelLayout < 2:
opTitle = opPage.getTitle(obj)
@@ -1209,7 +1207,7 @@ class TaskPanel(object):
PathUtil.clearExpressionEngine(self.obj)
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
except Exception as ee:
PathLog.debug("{}\n".format(ee))
Path.Log.debug("{}\n".format(ee))
FreeCAD.ActiveDocument.commitTransaction()
self.cleanup(resetEdit)
return True
@@ -1250,20 +1248,20 @@ class TaskPanel(object):
def panelGetFields(self):
"""panelGetFields() ... invoked to trigger a complete transfer of UI data to the model."""
PathLog.track()
Path.Log.track()
for page in self.featurePages:
page.pageGetFields()
def panelSetFields(self):
"""panelSetFields() ... invoked to trigger a complete transfer of the model's properties to the UI."""
PathLog.track()
Path.Log.track()
self.obj.Proxy.sanitizeBase(self.obj)
for page in self.featurePages:
page.pageSetFields()
def panelCleanup(self):
"""panelCleanup() ... invoked before the receiver is destroyed."""
PathLog.track()
Path.Log.track()
for page in self.featurePages:
page.pageCleanup()
@@ -1282,7 +1280,7 @@ class TaskPanel(object):
def setupUi(self):
"""setupUi() ... internal function to initialise all pages."""
PathLog.track(self.deleteOnReject)
Path.Log.track(self.deleteOnReject)
if (
self.deleteOnReject
@@ -1311,7 +1309,7 @@ class TaskPanel(object):
def updateData(self, obj, prop):
"""updateDate(obj, prop) ... callback invoked whenever a model's property is assigned a value."""
# PathLog.track(obj.Label, prop) # creates a lot of noise
# Path.Log.track(obj.Label, prop) # creates a lot of noise
for page in self.featurePages:
page.pageUpdateData(obj, prop)
@@ -1391,7 +1389,7 @@ def Create(res):
diag.setWindowModality(QtCore.Qt.ApplicationModal)
diag.exec_()
except PathOp.PathNoTCException:
PathLog.warning(translate("PathOp", "No tool controller, aborting op creation"))
Path.Log.warning(translate("PathOp", "No tool controller, aborting op creation"))
FreeCAD.ActiveDocument.abortTransaction()
FreeCAD.ActiveDocument.recompute()

View File

@@ -22,9 +22,9 @@
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathLog as PathLog
import PathScripts.PathOpGui as PathOpGui
import Path
import Path.Op.Gui.Base as PathOpGui
import PathGui
from PySide import QtCore, QtGui
@@ -36,10 +36,10 @@ __doc__ = "Implementation of circular hole specific base geometry page controlle
LOGLEVEL = False
if LOGLEVEL:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.NOTICE, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.NOTICE, Path.Log.thisModule())
class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
@@ -63,7 +63,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
def setFields(self, obj):
"""setFields(obj) ... fill form with values from obj"""
PathLog.track()
Path.Log.track()
self.form.baseList.blockSignals(True)
self.form.baseList.clearContents()
self.form.baseList.setRowCount(0)
@@ -98,7 +98,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
def itemActivated(self):
"""itemActivated() ... callback when item in table is selected"""
PathLog.track()
Path.Log.track()
if self.form.baseList.selectedItems():
self.form.deleteBase.setEnabled(True)
FreeCADGui.Selection.clearSelection()
@@ -109,7 +109,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
activatedRows.append(row)
obj = item.data(self.DataObject)
sub = str(item.data(self.DataObjectSub))
PathLog.debug("itemActivated() -> %s.%s" % (obj.Label, sub))
Path.Log.debug("itemActivated() -> %s.%s" % (obj.Label, sub))
if sub:
FreeCADGui.Selection.addSelection(obj, sub)
else:
@@ -119,7 +119,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
def deleteBase(self):
"""deleteBase() ... callback for push button"""
PathLog.track()
Path.Log.track()
selected = [
self.form.baseList.row(item) for item in self.form.baseList.selectedItems()
]
@@ -135,23 +135,23 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
def updateBase(self):
"""updateBase() ... helper function to transfer current table to obj"""
PathLog.track()
Path.Log.track()
newlist = []
for i in range(self.form.baseList.rowCount()):
item = self.form.baseList.item(i, 0)
obj = item.data(self.DataObject)
sub = str(item.data(self.DataObjectSub))
base = (obj, sub)
PathLog.debug("keeping (%s.%s)" % (obj.Label, sub))
Path.Log.debug("keeping (%s.%s)" % (obj.Label, sub))
newlist.append(base)
PathLog.debug("obj.Base=%s newlist=%s" % (self.obj.Base, newlist))
Path.Log.debug("obj.Base=%s newlist=%s" % (self.obj.Base, newlist))
self.updating = True
self.obj.Base = newlist
self.updating = False
def checkedChanged(self):
"""checkeChanged() ... callback when checked status of a base feature changed"""
PathLog.track()
Path.Log.track()
disabled = []
for i in range(0, self.form.baseList.rowCount()):
item = self.form.baseList.item(i, 0)

View File

@@ -115,14 +115,14 @@ class CommandPathComment:
def Activated(self):
FreeCAD.ActiveDocument.openTransaction("Create a Comment in your CNC program")
FreeCADGui.addModule("PathScripts.PathComment")
FreeCADGui.addModule("Path.Op.Gui.Comment")
snippet = """
import Path
import PathScripts
from PathScripts import PathUtils
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Comment")
PathScripts.PathComment.Comment(obj)
PathScripts.PathComment._ViewProviderComment(obj.ViewObject)
Path.Op.Gui.Comment.Comment(obj)
Path.Op.Gui.Comment._ViewProviderComment(obj.ViewObject)
PathUtils.addToJob(obj)
"""

View File

@@ -104,12 +104,11 @@ class CommandPathCopy:
def Activated(self):
FreeCAD.ActiveDocument.openTransaction("Create Copy")
FreeCADGui.addModule("PathScripts.PathCopy")
FreeCADGui.addModule("Path.Op.Gui.Copy")
consolecode = """
import Path
import PathScripts
from PathScripts import PathCopy
import Path.Op.Gui.Copy
selGood = True
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelection()
@@ -125,8 +124,8 @@ if not selection[0].isDerivedFrom("Path::Feature"):
if selGood:
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", str(selection[0].Name)+'_Copy')
PathScripts.PathCopy.ObjectPathCopy(obj)
PathScripts.PathCopy.ViewProviderPathCopy(obj.ViewObject)
Path.Op.Gui.Copy.ObjectPathCopy(obj)
Path.Op.Gui.Copy.ViewProviderPathCopy(obj.ViewObject)
obj.Base = FreeCAD.ActiveDocument.getObject(selection[0].Name)
if hasattr(obj.Base, 'ToolController'):
obj.ToolController = obj.Base.ToolController

View File

@@ -22,8 +22,8 @@
import FreeCAD
import FreeCADGui
import PathScripts.PathCustom as PathCustom
import PathScripts.PathOpGui as PathOpGui
import Path.Op.Custom as PathCustom
import Path.Op.Gui.Base as PathOpGui
from PySide.QtCore import QT_TRANSLATE_NOOP

View File

@@ -22,10 +22,10 @@
import FreeCAD
import FreeCADGui
import PathScripts.PathDeburr as PathDeburr
import PathScripts.PathGui as PathGui
import PathScripts.PathLog as PathLog
import PathScripts.PathOpGui as PathOpGui
import Path
import Path.Base.Gui.Util as PathGuiUtil
import Path.Op.Deburr as PathDeburr
import Path.Op.Gui.Base as PathOpGui
from PySide import QtCore, QtGui
from PySide.QtCore import QT_TRANSLATE_NOOP
@@ -36,10 +36,10 @@ __doc__ = "Deburr operation page controller and command implementation."
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -83,8 +83,8 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
self.form.joinRound.setIcon(iconRound)
def getFields(self, obj):
PathGui.updateInputField(obj, "Width", self.form.value_W)
PathGui.updateInputField(obj, "ExtraDepth", self.form.value_h)
PathGuiUtil.updateInputField(obj, "Width", self.form.value_W)
PathGuiUtil.updateInputField(obj, "ExtraDepth", self.form.value_h)
if self.form.joinRound.isChecked():
obj.Join = "Round"
elif self.form.joinMiter.isChecked():
@@ -113,10 +113,10 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
self.selectInComboBox(obj.Direction, self.form.direction)
def updateWidth(self):
PathGui.updateInputField(self.obj, "Width", self.form.value_W)
PathGuiUtil.updateInputField(self.obj, "Width", self.form.value_W)
def updateExtraDepth(self):
PathGui.updateInputField(self.obj, "ExtraDepth", self.form.value_h)
PathGuiUtil.updateInputField(self.obj, "ExtraDepth", self.form.value_h)
def getSignalsForUpdate(self, obj):
signals = []

View File

@@ -22,12 +22,12 @@
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathCircularHoleBaseGui as PathCircularHoleBaseGui
import PathScripts.PathDrilling as PathDrilling
import PathScripts.PathGui as PathGui
import PathScripts.PathLog as PathLog
import PathScripts.PathOpGui as PathOpGui
import Path
import Path.Base.Gui.Util as PathGuiUtil
import Path.Op.Drilling as PathDrilling
import Path.Op.Gui.Base as PathOpGui
import Path.Op.Gui.CircularHoleBase as PathCircularHoleBaseGui
import PathGui
from PySide import QtCore
@@ -38,23 +38,23 @@ __doc__ = "UI and Command for Path Drilling Operation."
__contributors__ = "IMBack!"
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
"""Controller for the drilling operation's page"""
def initPage(self, obj):
self.peckDepthSpinBox = PathGui.QuantitySpinBox(
self.peckDepthSpinBox = PathGuiUtil.QuantitySpinBox(
self.form.peckDepth, obj, "PeckDepth"
)
self.peckRetractSpinBox = PathGui.QuantitySpinBox(
self.peckRetractSpinBox = PathGuiUtil.QuantitySpinBox(
self.form.peckRetractHeight, obj, "RetractHeight"
)
self.dwellTimeSpinBox = PathGui.QuantitySpinBox(
self.dwellTimeSpinBox = PathGuiUtil.QuantitySpinBox(
self.form.dwellTime, obj, "DwellTime"
)
self.form.chipBreakEnabled.setEnabled(False)
@@ -105,7 +105,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
def getFields(self, obj):
"""setFields(obj) ... update obj's properties with values from the UI"""
PathLog.track()
Path.Log.track()
self.peckDepthSpinBox.updateProperty()
self.peckRetractSpinBox.updateProperty()
self.dwellTimeSpinBox.updateProperty()
@@ -124,7 +124,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
def setFields(self, obj):
"""setFields(obj) ... update UI with obj properties' values"""
PathLog.track()
Path.Log.track()
self.updateQuantitySpinBoxes()
if obj.DwellEnabled:

View File

@@ -22,10 +22,10 @@
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathEngrave as PathEngrave
import PathScripts.PathLog as PathLog
import PathScripts.PathOpGui as PathOpGui
import Path
import Path.Op.Engrave as PathEngrave
import Path.Op.Gui.Base as PathOpGui
import PathGui
import PathScripts.PathUtils as PathUtils
from PySide import QtCore, QtGui
@@ -37,10 +37,10 @@ __url__ = "https://www.freecadweb.org"
__doc__ = "Engrave operation page controller and command implementation."
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
translate = FreeCAD.Qt.translate
@@ -70,7 +70,7 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
job = PathUtils.findParentJob(self.obj)
base = job.Proxy.resourceClone(job, sel.Object)
if not base:
PathLog.notice(
Path.Log.notice(
(
translate("Path", "%s is not a Base Model object of the job %s")
+ "\n"
@@ -79,7 +79,7 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
)
continue
if base in shapes:
PathLog.notice(
Path.Log.notice(
(translate("Path", "Base shape %s already in the list") + "\n")
% (sel.Object.Label)
)
@@ -89,7 +89,7 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
# selectively add some elements of the drawing to the Base
for sub in sel.SubElementNames:
if "Vertex" in sub:
PathLog.info("Ignoring vertex")
Path.Log.info("Ignoring vertex")
else:
self.obj.Proxy.addBase(self.obj, base, sub)
else:
@@ -116,7 +116,7 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
self.form.baseList.blockSignals(False)
def updateBase(self):
PathLog.track()
Path.Log.track()
shapes = []
for i in range(self.form.baseList.count()):
item = self.form.baseList.item(i)
@@ -124,7 +124,7 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
sub = item.data(self.super().DataObjectSub)
if not sub:
shapes.append(obj)
PathLog.debug(
Path.Log.debug(
"Setting new base shapes: %s -> %s" % (self.obj.BaseShapes, shapes)
)
self.obj.BaseShapes = shapes

View File

@@ -24,11 +24,10 @@ from PySide import QtCore, QtGui
from pivy import coin
import FreeCAD
import FreeCADGui
import PathScripts.PathFeatureExtensions as FeatureExtensions
import PathScripts.PathGeom as PathGeom
import PathScripts.PathGui as PathGui
import PathScripts.PathLog as PathLog
import PathScripts.PathOpGui as PathOpGui
import Path
import Path.Base.Gui.Util as PathGuiUtil
import Path.Op.FeatureExtension as FeatureExtensions
import Path.Op.Gui.Base as PathOpGui
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -44,10 +43,10 @@ __doc__ = "Extensions feature page controller."
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
class _Extension(object):
@@ -198,7 +197,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self.extensions = list()
self.defaultLength = PathGui.QuantitySpinBox(
self.defaultLength = PathGuiUtil.QuantitySpinBox(
self.form.defaultLength, obj, "ExtensionLengthDefault"
)
@@ -229,7 +228,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
try:
self.obj.ViewObject.RootNode.removeChild(self.switch)
except ReferenceError:
PathLog.debug("obj already destroyed - no cleanup required")
Path.Log.debug("obj already destroyed - no cleanup required")
def getForm(self):
form = FreeCADGui.PySideUic.loadUi(":/panels/PageOpPocketExtEdit.ui")
@@ -246,7 +245,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
cb(item, ext)
def currentExtensions(self):
PathLog.debug("currentExtensions()")
Path.Log.debug("currentExtensions()")
extensions = []
def extractExtension(item, ext):
@@ -255,16 +254,16 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
if self.form.enableExtensions.isChecked():
self.forAllItemsCall(extractExtension)
PathLog.track("extensions", extensions)
Path.Log.track("extensions", extensions)
return extensions
def updateProxyExtensions(self, obj):
PathLog.debug("updateProxyExtensions()")
Path.Log.debug("updateProxyExtensions()")
self.extensions = self.currentExtensions()
FeatureExtensions.setExtensions(obj, self.extensions)
def getFields(self, obj):
PathLog.track(obj.Label, self.model.rowCount(), self.model.columnCount())
Path.Log.track(obj.Label, self.model.rowCount(), self.model.columnCount())
self.blockUpdateData = True
if obj.ExtensionCorners != self.form.extendCorners.isChecked():
@@ -275,8 +274,8 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self.blockUpdateData = False
def setFields(self, obj):
PathLog.track(obj.Label)
# PathLog.debug("setFields()")
Path.Log.track(obj.Label)
# Path.Log.debug("setFields()")
if obj.ExtensionCorners != self.form.extendCorners.isChecked():
self.form.extendCorners.toggle()
@@ -312,10 +311,10 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self._enableExtensions() # Recalculate extensions
def createItemForBaseModel(self, base, sub, edges, extensions):
PathLog.track(
Path.Log.track(
base.Label, sub, "+", len(edges), len(base.Shape.getElement(sub).Edges)
)
# PathLog.debug("createItemForBaseModel() label: {}, sub: {}, {}, edgeCnt: {}, subEdges: {}".format(base.Label, sub, '+', len(edges), len(base.Shape.getElement(sub).Edges)))
# Path.Log.debug("createItemForBaseModel() label: {}, sub: {}, {}, edgeCnt: {}, subEdges: {}".format(base.Label, sub, '+', len(edges), len(base.Shape.getElement(sub).Edges)))
extendCorners = self.form.extendCorners.isChecked()
subShape = base.Shape.getElement(sub)
@@ -361,16 +360,16 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
if extendCorners:
def edgesMatchShape(e0, e1):
flipped = PathGeom.flipEdge(e1)
flipped = Path.Geom.flipEdge(e1)
if flipped:
return PathGeom.edgesMatch(e0, e1) or PathGeom.edgesMatch(
return Path.Geom.edgesMatch(e0, e1) or Path.Geom.edgesMatch(
e0, flipped
)
else:
return PathGeom.edgesMatch(e0, e1)
return Path.Geom.edgesMatch(e0, e1)
self.extensionEdges = extensionEdges
PathLog.debug("extensionEdges.values(): {}".format(extensionEdges.values()))
Path.Log.debug("extensionEdges.values(): {}".format(extensionEdges.values()))
for edgeList in Part.sortEdges(
list(extensionEdges.keys())
): # Identify connected edges that form wires
@@ -402,11 +401,11 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
return item
def setExtensions(self, extensions):
PathLog.track(len(extensions))
PathLog.debug("setExtensions()")
Path.Log.track(len(extensions))
Path.Log.debug("setExtensions()")
if self.extensionsReady:
PathLog.debug("setExtensions() returning per `extensionsReady` flag")
Path.Log.debug("setExtensions() returning per `extensionsReady` flag")
return
self.form.extensionTree.blockSignals(True)
@@ -482,11 +481,11 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self.form.extensionTree.blockSignals(False)
self.extensionsReady = True
PathLog.debug(" setExtensions() finished and setting `extensionsReady=True`")
Path.Log.debug(" setExtensions() finished and setting `extensionsReady=True`")
def updateData(self, obj, prop):
PathLog.track(obj.Label, prop, self.blockUpdateData)
# PathLog.debug("updateData({})".format(prop))
Path.Log.track(obj.Label, prop, self.blockUpdateData)
# Path.Log.debug("updateData({})".format(prop))
if not self.blockUpdateData:
if self.fieldsSet:
@@ -503,10 +502,10 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self.extensionsReady = False
def restoreSelection(self, selection):
PathLog.debug("restoreSelection()")
PathLog.track()
Path.Log.debug("restoreSelection()")
Path.Log.track()
if 0 == self.model.rowCount():
PathLog.track("-")
Path.Log.track("-")
self.form.buttonClear.setEnabled(False)
self.form.buttonDisable.setEnabled(False)
self.form.buttonEnable.setEnabled(False)
@@ -549,11 +548,11 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self.forAllItemsCall(setSelectionVisuals)
def selectionChanged(self):
PathLog.debug("selectionChanged()")
Path.Log.debug("selectionChanged()")
self.restoreSelection([])
def extensionsClear(self):
PathLog.debug("extensionsClear()")
Path.Log.debug("extensionsClear()")
def disableItem(item, ext):
item.setCheckState(QtCore.Qt.Unchecked)
@@ -563,8 +562,8 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self.setDirty()
def _extensionsSetState(self, state):
PathLog.debug("_extensionsSetState()")
PathLog.track(state)
Path.Log.debug("_extensionsSetState()")
Path.Log.track(state)
for index in self.selectionModel.selectedIndexes():
item = self.model.itemFromIndex(index)
ext = item.data(self.DataObject)
@@ -580,7 +579,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self._extensionsSetState(QtCore.Qt.Checked)
def updateItemEnabled(self, item):
PathLog.track(item)
Path.Log.track(item)
ext = item.data(self.DataObject)
if item.checkState() == QtCore.Qt.Checked:
ext.enable()
@@ -606,8 +605,8 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
# self.setDirty()
def toggleExtensionCorners(self):
PathLog.debug("toggleExtensionCorners()")
PathLog.track()
Path.Log.debug("toggleExtensionCorners()")
Path.Log.track()
self.extensionsReady = False
extensions = FeatureExtensions.getExtensions(self.obj)
self.setExtensions(extensions)
@@ -615,7 +614,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
self.setDirty()
def getSignalsForUpdate(self, obj):
PathLog.track(obj.Label)
Path.Log.track(obj.Label)
signals = []
signals.append(self.form.defaultLength.editingFinished)
signals.append(self.form.enableExtensions.toggled)
@@ -654,7 +653,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
if page.panelTitle == "Operation" and hasattr(
page.form, "useOutline"
):
PathLog.debug("Found useOutline checkbox")
Path.Log.debug("Found useOutline checkbox")
self.useOutlineCheckbox = page.form.useOutline
if page.form.useOutline.isChecked():
self.useOutline = 1
@@ -682,7 +681,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
if self.form.enableExtensions.isChecked():
enabled = True
PathLog.debug("_autoEnableExtensions() is {}".format(enabled))
Path.Log.debug("_autoEnableExtensions() is {}".format(enabled))
self.enabled = enabled
def _enableExtensions(self):
@@ -691,7 +690,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
This method manages the enabled or disabled state of the extensionsEdit
Task Panel input group.
"""
PathLog.debug("_enableExtensions()")
Path.Log.debug("_enableExtensions()")
if self.form.enableExtensions.isChecked():
self.enabled = True
@@ -709,7 +708,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
This method manages the state of the button and the message thereof.
"""
self._getUseOutlineState() # Find `useOutline` checkbox and get its boolean value
PathLog.debug("_includeEdgesAndWires()")
Path.Log.debug("_includeEdgesAndWires()")
self.extensionsReady = False
self._enableExtensions()
@@ -725,16 +724,16 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
cacheLabel = base.Name + "_" + sub + "_None"
if cacheLabel in self.extensionsCache.keys():
# PathLog.debug("return _cachedExtension({})".format(cacheLabel))
# Path.Log.debug("return _cachedExtension({})".format(cacheLabel))
return self.extensionsCache[cacheLabel]
else:
# PathLog.debug("_cachedExtension({}) created".format(cacheLabel))
# Path.Log.debug("_cachedExtension({}) created".format(cacheLabel))
_ext = _Extension(obj, base, sub, label)
self.extensionsCache[cacheLabel] = _ext # cache the extension
return _ext
def _resetCachedExtensions(self):
PathLog.debug("_resetCachedExtensions()")
Path.Log.debug("_resetCachedExtensions()")
reset = dict()
self.extensionsCache = reset
self.extensionsReady = False

View File

@@ -22,12 +22,12 @@
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathCircularHoleBaseGui as PathCircularHoleBaseGui
import PathScripts.PathHelix as PathHelix
import PathScripts.PathLog as PathLog
import PathScripts.PathOpGui as PathOpGui
import PathScripts.PathGui as PathGui
import Path
import Path.Base.Gui.Util as PathGuiUtil
import Path.Op.Gui.Base as PathOpGui
import Path.Op.Gui.CircularHoleBase as PathCircularHoleBaseGui
import Path.Op.Helix as PathHelix
import PathGui
from PySide.QtCore import QT_TRANSLATE_NOOP
translate = FreeCAD.Qt.translate
@@ -39,10 +39,10 @@ __doc__ = "Helix operation page controller and command implementation."
LOGLEVEL = False
if LOGLEVEL:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
else:
PathLog.setLevel(PathLog.Level.NOTICE, PathLog.thisModule())
Path.Log.setLevel(Path.Log.Level.NOTICE, Path.Log.thisModule())
class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
@@ -61,21 +61,21 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
def getFields(self, obj):
"""getFields(obj) ... transfers values from UI to obj's proprties"""
PathLog.track()
Path.Log.track()
if obj.Direction != str(self.form.direction.currentData()):
obj.Direction = str(self.form.direction.currentData())
if obj.StartSide != str(self.form.startSide.currentData()):
obj.StartSide = str(self.form.startSide.currentData())
if obj.StepOver != self.form.stepOverPercent.value():
obj.StepOver = self.form.stepOverPercent.value()
PathGui.updateInputField(obj, "OffsetExtra", self.form.extraOffset)
PathGuiUtil.updateInputField(obj, "OffsetExtra", self.form.extraOffset)
self.updateToolController(obj, self.form.toolController)
self.updateCoolant(obj, self.form.coolantController)
def setFields(self, obj):
"""setFields(obj) ... transfers obj's property values to UI"""
PathLog.track()
Path.Log.track()
self.form.stepOverPercent.setValue(obj.StepOver)
self.selectInComboBox(obj.Direction, self.form.direction)

View File

@@ -125,13 +125,13 @@ class CommandPathHop:
return
FreeCAD.ActiveDocument.openTransaction("Create Hop")
FreeCADGui.addModule("PathScripts.PathHop")
FreeCADGui.addModule("Path.Op.Gui.Hop")
FreeCADGui.addModule("PathScripts.PathUtils")
FreeCADGui.doCommand(
'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Hop")'
)
FreeCADGui.doCommand("PathScripts.PathHop.ObjectHop(obj)")
FreeCADGui.doCommand("PathScripts.PathHop.ViewProviderPathHop(obj.ViewObject)")
FreeCADGui.doCommand("Path.Op.Gui.Hop.ObjectHop(obj)")
FreeCADGui.doCommand("Path.Op.Gui.Hop.ViewProviderPathHop(obj.ViewObject)")
FreeCADGui.doCommand(
"obj.NextObject = FreeCAD.ActiveDocument." + selection[0].Name
)

Some files were not shown because too many files have changed in this diff Show More