diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/area_funcs.py heekscnc-1.0.1-1/area_funcs.py --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/area_funcs.py 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/area_funcs.py 2020-06-14 10:19:34.000000000 +0000 @@ -17,9 +17,9 @@ def check_ramp_angle(): if ramp_angle < 0.1: - raise Exception, 'Invalid Ramp Angle: ' + str(ramp_angle) + ', must be at least 0.1 degrees!' + raise Exception('Invalid Ramp Angle: ' + str(ramp_angle) + ', must be at least 0.1 degrees!') if ramp_angle > 89.9: - raise Exception, 'Invalid Ramp Angle: ' + str(ramp_angle) + ', must be no more than 89.9 degrees!' + raise Exception('Invalid Ramp Angle: ' + str(ramp_angle) + ', must be no more than 89.9 degrees!') def GetRampStartGivenAngle(p, h_angle, ramp_depth): ramp_length = ramp_depth / math.tan(math.radians(float(ramp_angle))) @@ -44,7 +44,7 @@ ramp_depth = float(ramp_start_above_height) + current_start_depth - final_depth ramp_start_point = GetRampStart(p, ramp_depth) if ramp_start_point == None: - raise Exception, 'could not fit ramp entry in pocket operation at X' + str(p.x) + ' Y' + str(p.y) + raise Exception('could not fit ramp entry in pocket operation at X' + str(p.x) + ' Y' + str(p.y)) else: # rapid across rapid(ramp_start_point.x, ramp_start_point.y) @@ -57,9 +57,9 @@ def GetHelixRampCircleCentreGivenAngle(p, h_angle, circle_radius): if helix_diameter_factor < 0.1: - raise Exception, 'Invalid helix_diameter_factor: ' + str(helix_diameter_factor) + ', must be at least 0.1' + raise Exception('Invalid helix_diameter_factor: ' + str(helix_diameter_factor) + ', must be at least 0.1') if helix_diameter_factor > 1.0: - raise Exception, 'Invalid helix_diameter_factor: ' + str(helix_diameter_factor) + ', must be no more than 1.0' + raise Exception('Invalid helix_diameter_factor: ' + str(helix_diameter_factor) + ', must be no more than 1.0') centre = p + area.Point(math.cos(math.radians(helix_diameter_factor)), math.sin(math.radians(helix_diameter_factor))) * circle_radius circle = make_circle(centre, circle_radius + tool_radius_for_pocket) a = area.Area(area_for_feed_possible) @@ -80,7 +80,7 @@ circle_radius = float(helix_diameter_factor) * tool_radius_for_pocket circle_centre = GetHelixRampCircleCentre(p, circle_radius) if circle_centre == None: - raise Exception, 'could not fit helical ramp entry in pocket operation at X' + str(p.x) + ' Y' + str(p.y) + raise Exception('could not fit helical ramp entry in pocket operation at X' + str(p.x) + ' Y' + str(p.y)) ramp_depth = float(ramp_start_above_height) + current_start_depth - final_depth ramp_length = ramp_depth / math.tan(math.radians(float(ramp_angle))) circle_circumference = 2 * math.pi * circle_radius diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/CMakeLists.txt heekscnc-1.0.1-1/CMakeLists.txt --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/CMakeLists.txt 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/CMakeLists.txt 2020-06-14 10:19:34.000000000 +0000 @@ -1,9 +1,5 @@ project( HeeksCNC ) cmake_minimum_required( VERSION 2.6 ) -if( ${CMAKE_VERSION} STREQUAL "2.8.2" ) - # bug http://vtk.org/Bug/view.php?id=11020 - message( WARNING "CMake/CPack version 2.8.2 will not create working .deb packages!") -endif( ${CMAKE_VERSION} STREQUAL "2.8.2" ) set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/bzr-builder.manifest heekscnc-1.0.1-1/debian/bzr-builder.manifest --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/bzr-builder.manifest 2020-06-14 00:42:32.000000000 +0000 +++ heekscnc-1.0.1-1/debian/bzr-builder.manifest 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -# bzr-builder format 0.4 deb-version 1.0.0.1169+git7ee31b7+202006140042 -lp:heekscnc revid:git-v1:7ee31b744674258be228d9f755d5adea285d2f64 diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/changelog heekscnc-1.0.1-1/debian/changelog --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/changelog 2020-06-14 00:42:32.000000000 +0000 +++ heekscnc-1.0.1-1/debian/changelog 2020-06-14 10:19:34.000000000 +0000 @@ -1,8 +1,15 @@ -heekscnc (1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1) trusty; urgency=low +heekscnc (1.0.1-1-1+git202006141004~ubuntu14.04.1) trusty; urgency=low * Auto build. - -- neomilium Sun, 14 Jun 2020 00:42:32 +0000 + -- neomilium Sun, 14 Jun 2020 10:19:34 +0000 + +heekscnc (1.0.1-1) unstable; urgency=low + + * Update compat + * Attempt to support more recent Debian-based target + + -- Romuald Conty Sun, 14 Jun 2020 12:01:42 +0200 heekscnc (1.0.0-1) unstable; urgency=low diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/compat heekscnc-1.0.1-1/debian/compat --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/compat 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/debian/compat 2020-06-14 10:19:34.000000000 +0000 @@ -1 +1 @@ -7 +9 diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/control heekscnc-1.0.1-1/debian/control --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/control 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/debian/control 2020-06-14 10:19:34.000000000 +0000 @@ -1,17 +1,17 @@ Source: heekscnc Priority: extra Maintainer: Romuald Conty -Build-Depends: debhelper (>= 7.0.0), cmake, libwxgtk2.8-dev | libwxgtk3.0-dev, libgtkglext1-dev, libopencascade-visualization-dev | liboce-visualization-dev, libheekstinyxml-dev, heekscad-dev +Build-Depends: debhelper (>= 9.0.0), cmake, libwxgtk2.8-dev | libwxgtk3.0-dev | libwxgtk3.0-gtk3-dev, libgtkglext1-dev, libopencascade-visualization-dev | liboce-visualization-dev, libheekstinyxml-dev, heekscad-dev Standards-Version: 3.9.3 Section: libs -Homepage: https://code.google.com/p/heekscnc/ -Vcs-Svn: http://heekscnc.googlecode.com/svn/trunk/ -Vcs-Browser: https://code.google.com/p/heekscnc/source/browse/ +Homepage: https://github.com/Heeks/heekscnc +Vcs-Git: https://github.com/Heeks/heekscnc.git +Vcs-Browser: https://github.com/Heeks/heekscnc Package: heekscnc Section: libs Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.5), python-area, python-ocl, heekscad (>= 1.0.0) +Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.5), python-area, python-ocl, heekscad (>= 1.5.0) Enhances: heekscad Description: CAM add-on for HeeksCAD HeeksCNC adds machining features to HeeksCAD. diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/git-build-recipe.manifest heekscnc-1.0.1-1/debian/git-build-recipe.manifest --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/debian/git-build-recipe.manifest 1970-01-01 00:00:00.000000000 +0000 +++ heekscnc-1.0.1-1/debian/git-build-recipe.manifest 2020-06-14 10:19:34.000000000 +0000 @@ -0,0 +1,2 @@ +# git-build-recipe format 0.4 deb-version {debversion}-1+git202006141004 +lp:heekscnc git-commit:fc344ec3b5c7cb0747d94ce8b8773c8418fd6dd3 diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/nc/hxml_writer.py heekscnc-1.0.1-1/nc/hxml_writer.py --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/nc/hxml_writer.py 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/nc/hxml_writer.py 2020-06-14 10:19:34.000000000 +0000 @@ -114,13 +114,13 @@ if (z != None) : self.file_out.write(' z="%.6f"' % z) if (i != None): - if self.oldx == None: print 'arc move "i" without x set!' + if self.oldx == None: print('arc move "i" without x set!') else: self.file_out.write(' i="%.6f"' % (i - self.oldx)) if (j != None): - if self.oldy == None: print 'arc move "j" without y set!' + if self.oldy == None: print('arc move "j" without y set!') else: self.file_out.write(' j="%.6f"' % (j - self.oldy)) if (k != None): - if self.oldz == None: print 'arc move "k" without z set!' + if self.oldz == None: print('arc move "k" without z set!') else: self.file_out.write(' k="%.6f"' % (k - self.oldz)) if (r != None) : self.file_out.write(' r="%.6f"' % r) if (d != None) : self.file_out.write(' d="%i"' % d) diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/CMakeLists.txt heekscnc-1.0.1-1/src/CMakeLists.txt --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/CMakeLists.txt 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/src/CMakeLists.txt 2020-06-14 10:19:34.000000000 +0000 @@ -109,7 +109,7 @@ ${HeeksCAD_SRC_DIR}/interface/MarkedObject.cpp ${HeeksCAD_SRC_DIR}/interface/NiceTextCtrl.cpp ${HeeksCAD_SRC_DIR}/interface/ObjList.cpp - ${HeeksCAD_SRC_DIR}/src/Picking.cpp + ${HeeksCAD_SRC_DIR}/interface/Picking.cpp ${HeeksCAD_SRC_DIR}/interface/PictureFrame.cpp ${HeeksCAD_SRC_DIR}/interface/PropertyCheck.cpp ${HeeksCAD_SRC_DIR}/interface/PropertyChoice.cpp diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/NCCode.cpp heekscnc-1.0.1-1/src/NCCode.cpp --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/NCCode.cpp 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/src/NCCode.cpp 2020-06-14 10:19:34.000000000 +0000 @@ -11,14 +11,14 @@ #include "OutputCanvas.h" #include "interface/Geom.h" #include "interface/MarkedObject.h" +#include "interface/Picking.h" #include "interface/PropertyColor.h" -#include "interface/PropertyList.h" #include "interface/PropertyInt.h" +#include "interface/PropertyList.h" #include "interface/Tool.h" #include "CNCConfig.h" #include "CTool.h" #include "Program.h" -#include "src/Picking.h" #include #include diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/NCCode.h heekscnc-1.0.1-1/src/NCCode.h --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/NCCode.h 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/src/NCCode.h 2020-06-14 10:19:34.000000000 +0000 @@ -151,7 +151,7 @@ void GetBox(CBox &box); void WriteXML(TiXmlNode *root); void SetClickMarkPoint(MarkedObject* marked_object, const double* ray_start, const double* ray_direction); - + int PickPriority(){ return 2; }; // 2 for edges static HeeksObj* ReadFromXMLElement(TiXmlElement* pElem); void AppendText(wxString& str); void FormatText(wxTextCtrl *textCtrl, bool highlighted, bool force_format); diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/Program.cpp heekscnc-1.0.1-1/src/Program.cpp --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/Program.cpp 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/src/Program.cpp 2020-06-14 10:19:34.000000000 +0000 @@ -10,12 +10,13 @@ #include "NCCode.h" #include "interface/Geom.h" #include "interface/MarkedObject.h" -#include "interface/PropertyString.h" -#include "interface/PropertyFile.h" +#include "interface/Picking.h" +#include "interface/PropertyCheck.h" #include "interface/PropertyChoice.h" #include "interface/PropertyDouble.h" +#include "interface/PropertyFile.h" #include "interface/PropertyLength.h" -#include "interface/PropertyCheck.h" +#include "interface/PropertyString.h" #include "interface/Tool.h" #include "Profile.h" #include "Pocket.h" @@ -34,7 +35,6 @@ #include "Surface.h" #include "Stock.h" #include "ProgramDlg.h" -#include "src/Picking.h" #include #include @@ -714,12 +714,12 @@ #ifdef RUNINPLACE python << _T("sys.path.insert(0,'") << theApp.GetResFolder() << _T("/')\n"); #else - python << _T("sys.path.insert(0,'/usr/@LIB_INSTALL_DIR@/heekscnc/')\n"); + python << _T("sys.path.insert(0,'/usr/lib/heekscnc/')\n"); #endif #else #ifndef WIN32 #ifndef RUNINPLACE - python << _T("sys.path.insert(0,") << PythonString(_T("/usr/local/@LIB_INSTALL_DIR@/heekscnc/")) << _T(")\n"); + python << _T("sys.path.insert(0,") << PythonString(_T("/usr/local/lib/heekscnc/")) << _T(")\n"); #endif #endif python << _T("sys.path.insert(0,") << PythonString(theApp.GetResFolder()) << _T(")\n"); diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/Program.cpp.in heekscnc-1.0.1-1/src/Program.cpp.in --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/Program.cpp.in 1970-01-01 00:00:00.000000000 +0000 +++ heekscnc-1.0.1-1/src/Program.cpp.in 2020-06-14 10:19:34.000000000 +0000 @@ -0,0 +1,1261 @@ +// Program.cpp +// Copyright (c) 2009, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. + +#include "stdafx.h" +#include "Program.h" +#include "PythonStuff.h" +#include "tinyxml/tinyxml.h" +#include "ProgramCanvas.h" +#include "NCCode.h" +#include "interface/Geom.h" +#include "interface/MarkedObject.h" +#include "interface/Picking.h" +#include "interface/PropertyCheck.h" +#include "interface/PropertyChoice.h" +#include "interface/PropertyDouble.h" +#include "interface/PropertyFile.h" +#include "interface/PropertyLength.h" +#include "interface/PropertyString.h" +#include "interface/Tool.h" +#include "Profile.h" +#include "Pocket.h" +#include "Drilling.h" +#include "CTool.h" +#include "Op.h" +#include "CNCConfig.h" +#include "SpeedOp.h" +#include "Operations.h" +#include "Tools.h" +#include "Patterns.h" +#include "Surfaces.h" +#include "Stocks.h" +#include "interface/strconv.h" +#include "Pattern.h" +#include "Surface.h" +#include "Stock.h" +#include "ProgramDlg.h" + +#include +#include + +#include +#include +#include +#include +using namespace std; + +wxString CProgram::alternative_machines_file = _T(""); + +CProgram::CProgram():m_nc_code(NULL), m_operations(NULL), m_tools(NULL), m_patterns(NULL), m_surfaces(NULL), m_stocks(NULL) +, m_script_edited(false) +{ + ReadDefaultValues(); +} + +CProgram::CProgram( const CProgram & rhs ) : IdNamedObjList(rhs) +{ + m_nc_code = NULL; + m_operations = NULL; + m_tools = NULL; + m_patterns = NULL; + m_surfaces = NULL; + m_stocks = NULL; + m_script_edited = false; + m_machine = rhs.m_machine; + m_output_file = rhs.m_output_file; + m_output_file_name_follows_data_file_name = rhs.m_output_file_name_follows_data_file_name; + + m_script_edited = rhs.m_script_edited; + m_units = rhs.m_units; + + m_path_control_mode = rhs.m_path_control_mode; + m_motion_blending_tolerance = rhs.m_motion_blending_tolerance; + m_naive_cam_tolerance = rhs.m_naive_cam_tolerance; + + ReloadPointers(); + AddMissingChildren(); + + if ((m_nc_code != NULL) && (rhs.m_nc_code != NULL)) *m_nc_code = *(rhs.m_nc_code); + if ((m_operations != NULL) && (rhs.m_operations != NULL)) *m_operations = *(rhs.m_operations); + if ((m_tools != NULL) && (rhs.m_tools != NULL)) *m_tools = *(rhs.m_tools); + if ((m_patterns != NULL) && (rhs.m_patterns != NULL)) *m_patterns = *(rhs.m_patterns); + if ((m_surfaces != NULL) && (rhs.m_surfaces != NULL)) *m_surfaces = *(rhs.m_surfaces); + if ((m_stocks != NULL) && (rhs.m_stocks != NULL)) *m_stocks = *(rhs.m_stocks); +} + +CProgram::~CProgram() +{ + // Only remove the global pointer if 'we are the one'. When a file is imported, extra + // CProgram objects exist temporarily. They're not all used as the master data pointer. + if (theApp.m_program == this) + { + theApp.m_program = NULL; + } +} + +const wxBitmap &CProgram::GetIcon() +{ + static wxBitmap* icon = NULL; + if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/program.png"))); + return *icon; +} + +void CProgram::glCommands(bool select, bool marked, bool no_color) +{ + if (m_nc_code != NULL) + { + m_nc_code->glCommands(select, marked, no_color); + } + if (!select) + { + if (m_tools != NULL)m_tools->glCommands(select, marked, no_color); + } + + if (m_operations != NULL)m_operations->glCommands(select, false, no_color); +} + +HeeksObj *CProgram::MakeACopy(void)const +{ + return new CProgram(*this); +} + +/** + This is ALMOST the same as the assignment operator. The difference is that + this, and its subordinate methods, augment themselves with the contents + of the object passed in rather than replacing their own copies. + */ +void CProgram::CopyFrom(const HeeksObj* object) +{ + if (object->GetType() == GetType()) + { + CProgram *rhs = (CProgram *) object; + // IdNamedObjList::operator=(*rhs); // I don't think this will do anything in this case. But it might one day. + + if ((m_nc_code != NULL) && (rhs->m_nc_code != NULL)) m_nc_code->CopyFrom( rhs->m_nc_code ); + if ((m_operations != NULL) && (rhs->m_operations != NULL)) m_operations->CopyFrom( rhs->m_operations ); + if ((m_tools != NULL) && (rhs->m_tools != NULL)) m_tools->CopyFrom( rhs->m_tools ); + if ((m_patterns != NULL) && (rhs->m_patterns != NULL)) m_patterns->CopyFrom( rhs->m_patterns ); + if ((m_surfaces != NULL) && (rhs->m_surfaces != NULL)) m_surfaces->CopyFrom( rhs->m_surfaces ); + if ((m_stocks != NULL) && (rhs->m_stocks != NULL)) m_stocks->CopyFrom( rhs->m_stocks ); + + m_machine = rhs->m_machine; + m_output_file = rhs->m_output_file; + m_output_file_name_follows_data_file_name = rhs->m_output_file_name_follows_data_file_name; + + m_script_edited = rhs->m_script_edited; + m_units = rhs->m_units; + + m_path_control_mode = rhs->m_path_control_mode; + m_motion_blending_tolerance = rhs->m_motion_blending_tolerance; + m_naive_cam_tolerance = rhs->m_naive_cam_tolerance; + } +} + +void CProgram::Clear() +{ + if (m_nc_code != NULL)m_nc_code->Clear(); + if (m_operations != NULL)m_operations->Clear(); + if (m_tools != NULL)m_tools->Clear(); + if (m_patterns != NULL)m_patterns->Clear(); + if (m_surfaces != NULL)m_surfaces->Clear(); + if (m_stocks != NULL)m_stocks->Clear(); +} + +CProgram & CProgram::operator= ( const CProgram & rhs ) +{ + if (this != &rhs) + { + IdNamedObjList::operator=(rhs); + ReloadPointers(); + + if ((m_nc_code != NULL) && (rhs.m_nc_code != NULL)) *m_nc_code = *(rhs.m_nc_code); + if ((m_operations != NULL) && (rhs.m_operations != NULL)) *m_operations = *(rhs.m_operations); + if ((m_tools != NULL) && (rhs.m_tools != NULL)) *m_tools = *(rhs.m_tools); + if ((m_patterns != NULL) && (rhs.m_patterns != NULL)) *m_patterns = *(rhs.m_patterns); + if ((m_surfaces != NULL) && (rhs.m_surfaces != NULL)) *m_surfaces = *(rhs.m_surfaces); + if ((m_stocks != NULL) && (rhs.m_stocks != NULL)) *m_stocks = *(rhs.m_stocks); + + m_machine = rhs.m_machine; + m_output_file = rhs.m_output_file; + m_output_file_name_follows_data_file_name = rhs.m_output_file_name_follows_data_file_name; + + m_script_edited = rhs.m_script_edited; + m_units = rhs.m_units; + + m_path_control_mode = rhs.m_path_control_mode; + m_motion_blending_tolerance = rhs.m_motion_blending_tolerance; + m_naive_cam_tolerance = rhs.m_naive_cam_tolerance; + } + + return(*this); +} + + +CMachine::CMachine() +{ +} + +CMachine::CMachine( const CMachine & rhs ) +{ + *this = rhs; // call the assignment operator +} + + +CMachine & CMachine::operator= ( const CMachine & rhs ) +{ + if (this != &rhs) + { + post = rhs.post; + reader = rhs.reader; + suffix = rhs.suffix; + description = rhs.description; + py_params = rhs.py_params; + } // End if - then + + return(*this); +} // End assignment operator. + + +static void on_set_machine(int value, HeeksObj* object, bool from_undo_redo) +{ + std::vector machines; + CProgram::GetMachines(machines); + ((CProgram*)object)->m_machine = machines[value]; + ((CProgram*)object)->WriteDefaultValues(); + heeksCAD->RefreshProperties(); +} + +static void on_set_output_file(const wxChar* value, HeeksObj* object) +{ + ((CProgram*)object)->m_output_file = value; + ((CProgram*)object)->WriteDefaultValues(); +} + +static void on_set_units(int value, HeeksObj* object, bool from_undo_redo) +{ + ((CProgram*)object)->m_units = ((value == 0) ? 1.0:25.4); + + object->WriteDefaultValues(); + + if (heeksCAD->GetViewUnits() != ((CProgram*)object)->m_units) + { + int response; + response = wxMessageBox( _("Would you like to change the HeeksCAD view units too?"), _("Change Units"), wxYES_NO ); + if (response == wxYES) + { + heeksCAD->SetViewUnits(((CProgram*)object)->m_units, true); + heeksCAD->RefreshOptions(); + } + } + heeksCAD->RefreshProperties(); +} + +static void on_set_output_file_name_follows_data_file_name(int zero_based_choice, HeeksObj *object, bool from_undo_redo) +{ + CProgram *pProgram = (CProgram *) object; + pProgram->m_output_file_name_follows_data_file_name = (zero_based_choice != 0); + object->WriteDefaultValues(); + heeksCAD->RefreshProperties(); +} + +static void on_set_path_control_mode(int zero_based_choice, HeeksObj *object, bool from_undo_redo) +{ + CProgram *pProgram = (CProgram *) object; + pProgram->m_path_control_mode = CProgram::ePathControlMode_t(zero_based_choice); + object->WriteDefaultValues(); +} + +static void on_set_motion_blending_tolerance(double value, HeeksObj *object) +{ + CProgram *pProgram = (CProgram *) object; + pProgram->m_motion_blending_tolerance = value; + object->WriteDefaultValues(); + +} + +static void on_set_naive_cam_tolerance(double value, HeeksObj *object) +{ + CProgram *pProgram = (CProgram *) object; + pProgram->m_naive_cam_tolerance = value; + object->WriteDefaultValues(); +} + + +void CProgram::GetProperties(std::list *list) +{ + { + std::vector machines; + GetMachines(machines); + + std::list< wxString > choices; + int choice = 0; + for(unsigned int i = 0; i < machines.size(); i++) + { + CMachine& machine = machines[i]; + choices.push_back(machine.description); + if(machine.description == m_machine.description)choice = i; + } + list->push_back ( new PropertyChoice ( _("machine"), choices, choice, this, on_set_machine ) ); + } + + { + std::list choices; + int choice = int(m_output_file_name_follows_data_file_name?1:0); + choices.push_back(_T("False")); + choices.push_back(_T("True")); + + list->push_back(new PropertyChoice(_("output file name follows data file name"), choices, choice, this, on_set_output_file_name_follows_data_file_name)); + } + + if (m_output_file_name_follows_data_file_name == false) + { + list->push_back(new PropertyFile(_("output file"), m_output_file, this, on_set_output_file)); + } // End if - then + + { + std::list< wxString > choices; + choices.push_back ( wxString ( _("mm") ) ); + choices.push_back ( wxString ( _("inch") ) ); + int choice = 0; + if(m_units > 25.0)choice = 1; + list->push_back ( new PropertyChoice ( _("units for nc output"), choices, choice, this, on_set_units ) ); + } + + m_machine.GetProperties(this, list); + + { + std::list< wxString > choices; + choices.push_back(_("Exact Path Mode")); + choices.push_back(_("Exact Stop Mode")); + choices.push_back(_("Best Possible Speed")); + choices.push_back(_("Undefined")); + + list->push_back ( new PropertyChoice ( _("Path Control Mode"), choices, (int) m_path_control_mode, this, on_set_path_control_mode ) ); + + if (m_path_control_mode == eBestPossibleSpeed) + { + list->push_back( new PropertyLength( _("Motion Blending Tolerance"), m_motion_blending_tolerance, this, on_set_motion_blending_tolerance ) ); + list->push_back( new PropertyLength( _("Naive CAM Tolerance"), m_naive_cam_tolerance, this, on_set_naive_cam_tolerance ) ); + } // End if - then + } + + IdNamedObjList::GetProperties(list); +} + +void CMachine::GetProperties(CProgram *parent, std::list *list) +{ +} // End GetProperties() method + + + +bool CProgram::CanAdd(HeeksObj* object) +{ + if (object == NULL) return(false); + + return object->GetType() == NCCodeType || + object->GetType() == OperationsType || + object->GetType() == ToolsType || + object->GetType() == PatternsType || + object->GetType() == SurfacesType || + object->GetType() == StocksType + ; +} + +bool CProgram::CanAddTo(HeeksObj* owner) +{ + return ((owner != NULL) && (owner->GetType() == DocumentType)); +} + +void CProgram::SetClickMarkPoint(MarkedObject* marked_object, const double* ray_start, const double* ray_direction) +{ + if(marked_object->m_map.size() > 0) + { + HeeksObj* object = marked_object->m_map.begin()->first; + if(object) + { + switch(object->GetType()) + { + case NCCodeType: + ((CNCCode*)object)->SetClickMarkPoint(marked_object, ray_start, ray_direction); + break; + case NCCodeBlockType: + ((CNCCodeBlock*)object)->SetClickMarkPoint(marked_object, ray_start, ray_direction); + break; + } + } + } +} + +void CProgram::WriteXML(TiXmlNode *root) +{ + TiXmlElement * element; + element = heeksCAD->NewXMLElement( "Program" ); + heeksCAD->LinkXMLEndChild( root, element ); + element->SetAttribute( "machine", m_machine.description.utf8_str()); + element->SetAttribute( "output_file", m_output_file.utf8_str()); + element->SetAttribute( "output_file_name_follows_data_file_name", (int) (m_output_file_name_follows_data_file_name?1:0)); + + element->SetAttribute( "program", theApp.m_program_canvas->m_textCtrl->GetValue().utf8_str()); + element->SetDoubleAttribute( "units", m_units); + + element->SetAttribute( "ProgramPathControlMode", int(m_path_control_mode)); + element->SetDoubleAttribute( "ProgramMotionBlendingTolerance", m_motion_blending_tolerance); + element->SetDoubleAttribute( "ProgramNaiveCamTolerance", m_naive_cam_tolerance); + + m_machine.WriteBaseXML(element); + WriteBaseXML(element); +} + +bool CProgram::Add(HeeksObj* object, HeeksObj* prev_object) +{ + switch(object->GetType()) + { + case NCCodeType: + m_nc_code = (CNCCode*)object; + break; + + case OperationsType: + m_operations = (COperations*)object; + break; + + case ToolsType: + m_tools = (CTools*)object; + break; + + case PatternsType: + m_patterns = (CPatterns*)object; + break; + + case SurfacesType: + m_surfaces = (CSurfaces*)object; + break; + + case StocksType: + m_stocks = (CStocks*)object; + break; + } + + return IdNamedObjList::Add(object, prev_object); +} + +void CProgram::Remove(HeeksObj* object) +{ + // This occurs when the HeeksCAD application performs a 'Reset()'. This, in turn, deletes + // the whole of the master data tree. With this tree's destruction, we must ensure that + // we delete ourselves cleanly so that this plugin doesn't end up with pointers to + // deallocated memory. + // + // Since these pointes are also stored as children, the ObjList::~ObjList() destructor will + // delete the children but our pointers to them won't get cleaned up. That's what this + // method is all about. + + if(object == m_nc_code)m_nc_code = NULL; + else if(object == m_operations)m_operations = NULL; + else if(object == m_tools)m_tools = NULL; + else if(object == m_patterns)m_patterns = NULL; + else if(object == m_surfaces)m_surfaces = NULL; + else if(object == m_stocks)m_stocks = NULL; + + IdNamedObjList::Remove(object); +} + +// static member function +HeeksObj* CProgram::ReadFromXMLElement(TiXmlElement* pElem) +{ + CProgram* new_object = new CProgram; + if (theApp.m_program == NULL) + { + theApp.m_program = new_object; + } + + // get the attributes + for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next()) + { + std::string name(a->Name()); + if(name == "machine")new_object->m_machine = GetMachine(Ctt(a->Value())); + else if(name == "output_file"){new_object->m_output_file.assign(Ctt(a->Value()));} + else if(name == "output_file_name_follows_data_file_name"){new_object->m_output_file_name_follows_data_file_name = (atoi(a->Value()) != 0); } + else if(name == "program"){theApp.m_program_canvas->m_textCtrl->SetValue(Ctt(a->Value()));} + else if(name == "units"){new_object->m_units = a->DoubleValue();} + else if(name == "ProgramPathControlMode"){new_object->m_path_control_mode = ePathControlMode_t(atoi(a->Value()));} + else if(name == "ProgramMotionBlendingTolerance"){new_object->m_motion_blending_tolerance = a->DoubleValue();} + else if(name == "ProgramNaiveCamTolerance"){new_object->m_naive_cam_tolerance = a->DoubleValue();} + } + + new_object->ReadBaseXML(pElem); + new_object->m_machine.ReadBaseXML(pElem); + + new_object->AddMissingChildren(); + + return new_object; +} + + +void CMachine::WriteBaseXML(TiXmlElement *element) +{ +} // End WriteBaseXML() method + +void CMachine::ReadBaseXML(TiXmlElement* element) +{ +} // End ReadBaseXML() method + +void ApplyPatternToText(Python &python, int p, std::set &patterns_written) +{ + CPattern* pattern = (CPattern*)heeksCAD->GetIDObject(PatternType, p); + if(pattern) + { + // if pattern not already written + if(patterns_written.find(p) == patterns_written.end()) + { + // write a pattern definition + python << _T("pattern") << p << _T(" = ["); + std::list matrices; + pattern->GetMatrices(matrices); + for(std::list::iterator It = matrices.begin(); It != matrices.end(); It++) + { + if(It != matrices.begin())python << _T(", "); + gp_Trsf &mat = *It; + python << _T("area.Matrix(["); + double m[16]; + extract(mat, m); + for(int i = 0; i<16; i++) + { + if(i>0)python<<_T(", "); + python< &surfaces_written) +{ + if(surfaces_written.find(surface) == surfaces_written.end()) + { + surfaces_written.insert(surface); + // get the solids list + std::list solids; + for (std::list::iterator It = surface->m_solids.begin(); It != surface->m_solids.end(); It++) + { + HeeksObj* object = heeksCAD->GetIDObject(SolidType, *It); + if (object != NULL)solids.push_back(object); + } // End for + +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + wxFileName filepath(standard_paths.GetTempDir().c_str(), wxString::Format(_T("surface%d.stl"), CSurface::number_for_stl_file).c_str()); + CSurface::number_for_stl_file++; + + //write stl file + heeksCAD->SaveSTLFile(solids, filepath.GetFullPath(), 0.01); + + python << _T("stl") << (int)(surface->m_id) << _T(" = ocl_funcs.STLSurfFromFile(") << PythonString(filepath.GetFullPath()) << _T(")\n"); + } + + python << _T("attach.units = ") << theApp.m_program->m_units << _T("\n"); + python << _T("attach.attach_begin()\n"); + python << _T("nc.creator.stl = stl") << (int)(surface->m_id) << _T("\n"); + python << _T("nc.creator.minz = -10000.0\n"); + python << _T("nc.creator.material_allowance = ") << surface->m_material_allowance << _T("\n"); + + theApp.m_attached_to_surface = surface; +} + +Python CProgram::RewritePythonProgram() +{ + Python python; + + theApp.m_program_canvas->m_textCtrl->Clear(); + theApp.m_attached_to_surface = NULL; + CSurface::number_for_stl_file = 1; + theApp.m_tool_number = 0; + + // call any OnRewritePython functions from other plugins + for(std::list< void(*)() >::iterator It = theApp.m_OnRewritePython_list.begin(); It != theApp.m_OnRewritePython_list.end(); It++) + { + void(*callbackfunc)() = *It; + (*callbackfunc)(); + } + + bool kurve_funcs_needed = false; + bool area_module_needed = true; // area module could be used anywhere + bool area_funcs_needed = false; + bool ocl_module_needed = false; + bool ocl_funcs_needed = false; + bool nc_attach_needed = false; + bool transform_module_needed = false; + bool depths_needed = false; + + typedef std::vector< COp * > OperationsMap_t; + OperationsMap_t operations; + + if (m_operations == NULL) + { + // If there are no operations then there is no GCode. + // No socks, no shirt, no service. + return(python); + } // End if - then + + for(HeeksObj* object = m_operations->GetFirstChild(); object; object = m_operations->GetNextChild()) + { + operations.push_back( (COp *) object ); + + if(((COp*)object)->m_active) + { + if(((COp*)object)->m_pattern != 0)transform_module_needed = true; + if(((COp*)object)->m_surface != 0){nc_attach_needed = true; ocl_module_needed = true; ocl_funcs_needed = true;} + + switch(object->GetType()) + { + case ProfileType: + kurve_funcs_needed = true; + depths_needed = true; + break; + + case PocketType: + area_funcs_needed = true; + depths_needed = true; + break; + + case DrillingType: + depths_needed = true; + break; + + case ScriptOpType: + ocl_module_needed = true; + nc_attach_needed = true; + ocl_funcs_needed = true; + depths_needed = true; + break; + } + } + } + + // Language and Windows codepage detection and correction + #ifndef WIN32 + python << _T("# coding=UTF8\n"); + python << _T("# No troubled Microsoft Windows detected\n"); + #else + switch((wxLocale::GetSystemLanguage())) + { + case wxLANGUAGE_SLOVAK : + python << _T("# coding=CP1250\n"); + python << _T("# Slovak language detected in Microsoft Windows\n"); + break; + case wxLANGUAGE_GERMAN: + case wxLANGUAGE_GERMAN_AUSTRIAN: + case wxLANGUAGE_GERMAN_BELGIUM: + case wxLANGUAGE_GERMAN_LIECHTENSTEIN: + case wxLANGUAGE_GERMAN_LUXEMBOURG: + case wxLANGUAGE_GERMAN_SWISS : + python << _T("# coding=CP1252\n"); + python << _T("# German language or it's variant detected in Microsoft Windows\n"); + break; + case wxLANGUAGE_DUTCH : + case wxLANGUAGE_DUTCH_BELGIAN : + python << _T("# coding=CP1252\n"); + python << _T("# Dutch language or it's variant detected in Microsoft Windows\n"); + break; + case wxLANGUAGE_FRENCH: + case wxLANGUAGE_FRENCH_BELGIAN: + case wxLANGUAGE_FRENCH_CANADIAN: + case wxLANGUAGE_FRENCH_LUXEMBOURG: + case wxLANGUAGE_FRENCH_MONACO: + case wxLANGUAGE_FRENCH_SWISS: + python << _T("# coding=CP1252\n"); + python << _T("# French language or it's variant detected in Microsoft Windows\n"); + break; + case wxLANGUAGE_ITALIAN: + case wxLANGUAGE_ITALIAN_SWISS : + python << _T("# coding=CP1252\n"); + python << _T("#Italian language or it's variant detected in Microsoft Windows\n"); + break; + case wxLANGUAGE_ENGLISH: + case wxLANGUAGE_ENGLISH_UK: + case wxLANGUAGE_ENGLISH_US: + case wxLANGUAGE_ENGLISH_AUSTRALIA: + case wxLANGUAGE_ENGLISH_BELIZE: + case wxLANGUAGE_ENGLISH_BOTSWANA: + case wxLANGUAGE_ENGLISH_CANADA: + case wxLANGUAGE_ENGLISH_CARIBBEAN: + case wxLANGUAGE_ENGLISH_DENMARK: + case wxLANGUAGE_ENGLISH_EIRE: + case wxLANGUAGE_ENGLISH_JAMAICA: + case wxLANGUAGE_ENGLISH_NEW_ZEALAND: + case wxLANGUAGE_ENGLISH_PHILIPPINES: + case wxLANGUAGE_ENGLISH_SOUTH_AFRICA: + case wxLANGUAGE_ENGLISH_TRINIDAD: + case wxLANGUAGE_ENGLISH_ZIMBABWE: + python << _T("# coding=CP1252\n"); + python << _T("#English language or it's variant detected in Microsoft Windows\n"); + break; + default: + python << _T("# coding=CP1252\n"); + python << _T("#Not supported language detected in Microsoft Windows. Assuming English alphabet\n"); + break; + } + #endif + // add standard stuff at the top + //hackhack, make it work on unix with FHS + python << _T("import sys\n"); + +#ifdef CMAKE_UNIX + #ifdef RUNINPLACE + python << _T("sys.path.insert(0,'") << theApp.GetResFolder() << _T("/')\n"); + #else + python << _T("sys.path.insert(0,'/usr/@LIB_INSTALL_DIR@/heekscnc/')\n"); + #endif +#else +#ifndef WIN32 +#ifndef RUNINPLACE + python << _T("sys.path.insert(0,") << PythonString(_T("/usr/local/@LIB_INSTALL_DIR@/heekscnc/")) << _T(")\n"); +#endif +#endif + python << _T("sys.path.insert(0,") << PythonString(theApp.GetResFolder()) << _T(")\n"); +#endif + python << _T("import math\n"); + + // area related things + if(area_module_needed) + { +#ifdef WIN32 + python << _T("sys.path.insert(0,") << PythonString(theApp.GetResFolder() + (theApp.m_use_Clipper_not_Boolean ? _T("/Clipper"):_T("/Boolean"))) << _T(")\n"); +#endif + + python << _T("import area\n"); + python << _T("area.set_units(") << m_units << _T(")\n"); + } + + // kurve related things + if(kurve_funcs_needed) + { + python << _T("import kurve_funcs\n"); + } + + if(area_funcs_needed) + { + python << _T("import area_funcs\n"); + } + + // attach operations + if(nc_attach_needed) + { + python << _T("import nc.attach as attach\n"); + } + + // OpenCamLib stuff + if(ocl_module_needed) + { + python << _T("import ocl\n"); + } + if(ocl_funcs_needed) + { + python << _T("import ocl_funcs\n"); + } + + if(transform_module_needed) + { + python << _T("import nc.transform as transform\n"); + python << _T("\n"); + } + + if(depths_needed) + { + python << _T("from depth_params import depth_params as depth_params\n"); + python << _T("\n"); + } + + // machine general stuff + python << _T("from nc.nc import *\n"); + + // specific machine + if (m_machine.post == _T("not found")) + { + wxMessageBox(_T("Machine post processor name (defined in Program Properties) not found")); + } // End if - then + else + + { + python << _T("from nc.") + m_machine.post + _T(" import *\n"); + python << _T("\n"); + } // End if - else + + // write the machine's parameters + for(std::list::iterator It = m_machine.py_params.begin(); It != m_machine.py_params.end(); It++) + { + PyParam &p = *It; + python << _T("nc.creator.") << Ctt(p.m_name.c_str()) << _T(" = ") << Ctt(p.m_value.c_str()) << _T("\n"); + } + + // output file + python << _T("output(") << PythonString(GetOutputFileName()) << _T(")\n"); + + +#ifdef FREE_VERSION + python << _T("comment('MADE WITH FREE VERSION OF HEEKSCNC. Please buy full version to remove this text\\n')\n"); + python << _T("comment('*********** MADE WITH FREE VERSION OF HEEKSCNC! ***********\\n')\n"); + python << _T("comment('*********** MADE WITH FREE VERSION OF HEEKSCNC! ***********\\n')\n"); + python << _T("comment('*********** MADE WITH FREE VERSION OF HEEKSCNC! ***********\\n')\n"); + python << _T("comment('*********** MADE WITH FREE VERSION OF HEEKSCNC! ***********\\n')\n"); + python << _T("comment('*********** MADE WITH FREE VERSION OF HEEKSCNC! ***********\\n')\n"); + python << _T("comment('*********** MADE WITH FREE VERSION OF HEEKSCNC! ***********\\n')\n"); + python << _T("comment('*********** ***********\\n')\n"); + python << _T("comment('*********** http://sites.google.com/site/heekscad/home ***********\\n')\n"); + python << _T("comment('*********** ***********\\n')\n"); +#endif + + // begin program + python << _T("program_begin(") << wxString::Format(_T("%d"), m_id) << _T(", ") << PythonString(GetShortString()) << _T(")\n"); + + // add any stock commands + std::set stock_ids; + m_stocks->GetSolidIds(stock_ids); + for(std::set::iterator It = stock_ids.begin(); It != stock_ids.end(); It++) + { + int id = *It; + HeeksObj* object = heeksCAD->GetIDObject(SolidType, id); + if(object) + { + CBox box; + object->GetBox(box); + python << _T("add_stock('BLOCK',[") << box.Width() << _T(", ") << box.Height() << _T(", ") << box.Depth() << _T(", ") << -box.MinX() << _T(", ") << -box.MinY() << _T(", ") << -box.MinZ() << _T("])\n"); + } + } + + python << _T("absolute()\n"); + if(m_units > 25.0) + { + python << _T("imperial()\n"); + } + else + { + python << _T("metric()\n"); + } + python << _T("set_plane(0)\n"); + python << _T("\n"); + + if (m_path_control_mode != ePathControlUndefined) + { + python << _T("set_path_control_mode(") << (int) m_path_control_mode << _T(",") << m_motion_blending_tolerance << _T(",") << m_naive_cam_tolerance << _T(")\n"); + } + + // write the tools setup code. + if (m_tools != NULL) + { + // Write the new tool table entries first. + for(HeeksObj* object = m_tools->GetFirstChild(); object; object = m_tools->GetNextChild()) + { + switch(object->GetType()) + { + case ToolType: + python << ((CTool*)object)->AppendTextToProgram(); + break; + } + } // End for + } // End if - then + + // Write all the operations + + std::set surfaces_written; + std::set patterns_written; + + for (OperationsMap_t::const_iterator l_itOperation = operations.begin(); l_itOperation != operations.end(); l_itOperation++) + { + HeeksObj *object = (HeeksObj *) *l_itOperation; + if (object == NULL) continue; + + if(COperations::IsAnOperation(object->GetType())) + { + COp* op = (COp*)object; + if(op->m_active) + { + CSurface* surface = (CSurface*)heeksCAD->GetIDObject(SurfaceType, op->m_surface); + if(surface && !surface->m_same_for_each_pattern_position)ApplySurfaceToText(python, surface, surfaces_written); + ApplyPatternToText(python, op->m_pattern, patterns_written); + if(surface && surface->m_same_for_each_pattern_position)ApplySurfaceToText(python, surface, surfaces_written); + + python << op->AppendTextToProgram(); + + // end surface attach + if(surface && surface->m_same_for_each_pattern_position)python << _T("attach.attach_end()\n"); + if(op->m_pattern != 0)python << _T("transform.transform_end()\n"); + if(surface && !surface->m_same_for_each_pattern_position)python << _T("attach.attach_end()\n"); + theApp.m_attached_to_surface = NULL; + } + } + } // End for - operation + + python << _T("program_end()\n"); + m_python_program = python; + theApp.m_program_canvas->m_textCtrl->AppendText(python); + if (python.Length() > theApp.m_program_canvas->m_textCtrl->GetValue().Length()) + { + // The python program is longer than the text control object can handle. The maximum + // length of the text control objects changes depending on the operating system (and its + // implementation of wxWidgets). Rather than showing the truncated program, tell the + // user that it has been truncated and where to find it. + +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + wxFileName file_str(standard_paths.GetTempDir().c_str(), _T("post.py")); + + theApp.m_program_canvas->m_textCtrl->Clear(); + theApp.m_program_canvas->m_textCtrl->AppendText(_("The Python program is too long \n")); + theApp.m_program_canvas->m_textCtrl->AppendText(_("to display in this window.\n")); + theApp.m_program_canvas->m_textCtrl->AppendText(_("Please edit the python program directly at \n")); + theApp.m_program_canvas->m_textCtrl->AppendText(file_str.GetFullPath()); + } + + return(python); +} + +ProgramUserType CProgram::GetUserType() +{ + if((m_nc_code != NULL) && (m_nc_code->m_user_edited)) return ProgramUserTypeNC; + if(m_script_edited)return ProgramUserTypeScript; + if((m_operations != NULL) && (m_operations->GetFirstChild()))return ProgramUserTypeTree; + return ProgramUserTypeUnkown; +} + +void CProgram::UpdateFromUserType() +{ +#if 0 + switch(GetUserType()) + { + case ProgramUserTypeUnkown: + + case tree: + Enable "Operations" icon in tree + editing the tree, recreates the python script + Read only "Program" window + pressing "Post-process" creates the NC code ( and backplots it ) + Read only "Output" window + Disable all buttons on "Output" window + + } +#endif +} + +// static +void CProgram::GetMachines(std::vector &machines) +{ + wxString machines_file = CProgram::alternative_machines_file; +#ifdef CMAKE_UNIX + #ifdef RUNINPLACE + if(machines_file.Len() == 0)machines_file = theApp.GetResFolder() + _T("/nc/machines.xml"); + #else + if(machines_file.Len() == 0)machines_file = theApp.GetResourceFilename(wxT("machines.xml")); + #endif +#else + if(machines_file.Len() == 0)machines_file = theApp.GetResFolder() + _T("/nc/machines.xml"); +#endif + + TiXmlDocument doc(Ttc(machines_file.c_str())); + if (!doc.LoadFile()) + { + if(doc.Error()) + { + wxString msg(machines_file); + msg << Ctt(": ") << Ctt(doc.ErrorDesc()); + wxMessageBox(msg); + } + return; + } + + char oldlocale[1000]; + strcpy(oldlocale, setlocale(LC_NUMERIC, "C")); + + TiXmlHandle hDoc(&doc); + TiXmlElement* element; + TiXmlNode* root = &doc; + + for(element = root->FirstChildElement(); element; element = element->NextSiblingElement()) + { + CMachine m; + for(TiXmlAttribute* a = element->FirstAttribute(); a; a = a->Next()) + { + std::string name(a->Name()); + if(name == "post")m.post = wxString(Ctt(a->Value())); + else if(name == "reader")m.reader = wxString(Ctt(a->Value())); + else if(name == "suffix")m.suffix = wxString(Ctt(a->Value())); + else if(name == "description")m.description = wxString(Ctt(a->Value())); + else m.py_params.push_back(PyParam(a->Name(), a->Value())); + } + machines.push_back(m); + } + + setlocale(LC_NUMERIC, oldlocale); +} + +// static +void CProgram::GetScriptOps(std::vector< CXmlScriptOp > &script_ops) +{ + wxString script_op_file = theApp.GetResourceFilename(wxT("script_ops.xml")); + + TiXmlDocument doc(Ttc(script_op_file.c_str())); + if (!doc.LoadFile()) + { + if(doc.Error()) + { + wxString msg(script_op_file); + msg << Ctt(": ") << Ctt(doc.ErrorDesc()); + wxMessageBox(msg); + } + return; + } + + char oldlocale[1000]; + strcpy(oldlocale, setlocale(LC_NUMERIC, "C")); + + TiXmlHandle hDoc(&doc); + TiXmlElement* element; + TiXmlNode* root = &doc; + + for(element = root->FirstChildElement(); element; element = element->NextSiblingElement()) + { + wxString label; + wxString bitmap; + wxString icon; + wxString script; + + for(TiXmlAttribute* a = element->FirstAttribute(); a; a = a->Next()) + { + std::string name(a->Name()); + if(name == "name")label = wxString(Ctt(a->Value())); + else if(name == "bitmap")bitmap = wxString(Ctt(a->Value())); + else if(name == "icon")icon = wxString(Ctt(a->Value())); + else if(name == "script")script = wxString(Ctt(a->Value())); + } + script_ops.push_back(CXmlScriptOp(label, bitmap, icon, script)); + } + + setlocale(LC_NUMERIC, oldlocale); +} + +// static +CMachine CProgram::GetMachine(const wxString& description) +{ + std::vector machines; + GetMachines(machines); + for(unsigned int i = 0; i 0)return machines[0]; + + CMachine machine; + machine.post = _T("not found"); + machine.reader = _T("not found"); + machine.description = _T("not found"); + + return machine; +} + +/** + If the m_output_file_name_follows_data_file_name flag is true then + we don't want to use the temporary directory. + */ +wxString CProgram::GetOutputFileName() const +{ + if (m_output_file_name_follows_data_file_name) + { + wxFileName project_file_name = heeksCAD->GetProjectFileName(); + + if(project_file_name.IsOk()) + { + wxString return_str; +#ifdef WIN32 + return_str = project_file_name.GetVolume() + _T(":"); +#endif + return_str.append(project_file_name.GetPath(wxPATH_GET_SEPARATOR) + project_file_name.GetName() + m_machine.suffix); + return return_str; + } + else + { +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + return wxFileName(standard_paths.GetTempDir(), heeksCAD->GetProjectTitle() + m_machine.suffix).GetFullPath(); + } + } + else + { + return(m_output_file); + } // End if - else +} // End GetOutputFileName() method + +wxString CProgram::GetBackplotFilePath() const +{ + // The xml file is created in the temporary folder +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + wxFileName file_str(standard_paths.GetTempDir().c_str(), _T("backplot.xml")); + return file_str.GetFullPath(); +} + +CNCCode* CProgram::NCCode() +{ + if (m_nc_code == NULL) ReloadPointers(); + return m_nc_code; +} + +COperations* CProgram::Operations() +{ + if (m_operations == NULL) ReloadPointers(); + return m_operations; +} + +CTools* CProgram::Tools() +{ + if (m_tools == NULL) ReloadPointers(); + return m_tools; +} + +CPatterns* CProgram::Patterns() +{ + if (m_patterns == NULL) ReloadPointers(); + return m_patterns; +} + +CSurfaces* CProgram::Surfaces() +{ + if (m_surfaces == NULL) ReloadPointers(); + return m_surfaces; +} + +CStocks* CProgram::Stocks() +{ + if (m_stocks == NULL) ReloadPointers(); + return m_stocks; +} + +void CProgram::ReloadPointers() +{ + for (HeeksObj *child = GetFirstChild(); child != NULL; child = GetNextChild()) + { + if (child->GetType() == ToolsType) m_tools = (CTools *) child; + if (child->GetType() == PatternsType) m_patterns = (CPatterns *) child; + if (child->GetType() == SurfacesType) m_surfaces = (CSurfaces *) child; + if (child->GetType() == StocksType) m_stocks = (CStocks *) child; + if (child->GetType() == OperationsType) m_operations = (COperations *) child; + if (child->GetType() == NCCodeType) m_nc_code = (CNCCode *) child; + } // End for +} + +void CProgram::AddMissingChildren() +{ + // Make sure the pointers are not already amongst existing children. + ReloadPointers(); + + // make sure tools, operations, fixtures, etc. exist + if(m_tools == NULL){m_tools = new CTools; Add( m_tools, NULL );} + if(m_patterns == NULL){m_patterns = new CPatterns; Add( m_patterns, NULL );} + if(m_surfaces == NULL){m_surfaces = new CSurfaces; Add( m_surfaces, NULL );} + if(m_stocks == NULL){m_stocks = new CStocks; Add( m_stocks, NULL );} + if(m_operations == NULL){m_operations = new COperations; Add( m_operations, NULL );} + if(m_nc_code == NULL){m_nc_code = new CNCCode; Add( m_nc_code, NULL );} +} + +bool CProgram::operator==( const CProgram & rhs ) const +{ + if (m_machine != rhs.m_machine) return(false); + if (m_output_file != rhs.m_output_file) return(false); + if (m_output_file_name_follows_data_file_name != rhs.m_output_file_name_follows_data_file_name) return(false); + if (m_script_edited != rhs.m_script_edited) return(false); + if (m_units != rhs.m_units) return(false); + + return(IdNamedObjList::operator==(rhs)); +} + +bool CMachine::operator==( const CMachine & rhs ) const +{ + if (post != rhs.post) return(false); + if (reader != rhs.reader) return(false); + if (suffix != rhs.suffix) return(false); + if (description != rhs.description) return(false); + if (py_params.size() != rhs.py_params.size())return false; + std::list::const_iterator It = py_params.begin(), It2 = rhs.py_params.begin(); + for(;It != py_params.end(); It++, It2++){ + if(!((*It) == (*It2)))return false; + } + + return(true); +} + +void CProgram::WriteDefaultValues() +{ + CNCConfig config; + + config.Write(_T("ProgramMachine"), m_machine.description); + config.Write(_T("OutputFileNameFollowsDataFileName"), m_output_file_name_follows_data_file_name ); + config.Write(_T("ProgramOutputFile"), m_output_file); + config.Write(_T("ProgramUnits"), m_units); + config.Write(_T("ProgramPathControlMode"), (int) m_path_control_mode ); + config.Write(_T("ProgramMotionBlendingTolerance"), m_motion_blending_tolerance ); + config.Write(_T("ProgramNaiveCamTolerance"), m_naive_cam_tolerance ); +} + +wxString CProgram::GetDefaultOutputFilePath()const + { +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + wxFileName default_path = wxFileName::CreateTempFileName(standard_paths.GetTempDir() + wxT("/heekscnc-")) + m_machine.suffix; + return default_path.GetFullPath(); +} + +void CProgram::ReadDefaultValues() +{ + CNCConfig config; + + wxString machine_description; + config.Read(_T("ProgramMachine"), &machine_description, _T("LinuxCNC")); + m_machine = CProgram::GetMachine(machine_description); + config.Read(_T("OutputFileNameFollowsDataFileName"), &m_output_file_name_follows_data_file_name, true); + config.Read(_T("ProgramOutputFile"), &m_output_file, GetDefaultOutputFilePath().c_str()); + config.Read(_T("ProgramUnits"), &m_units, 1.0); + config.Read(_T("ProgramPathControlMode"), (int *) &m_path_control_mode, (int) ePathControlUndefined ); + config.Read(_T("ProgramMotionBlendingTolerance"), &m_motion_blending_tolerance, 0.0001); + config.Read(_T("ProgramNaiveCamTolerance"), &m_naive_cam_tolerance, 0.0001); +} + +static bool OnEdit(HeeksObj* object) +{ + ProgramDlg dlg(heeksCAD->GetMainFrame(), (CProgram*)object); + if(dlg.ShowModal() == wxID_OK) + { + dlg.GetData((CProgram*)object); + return true; + } + return false; +} + +void CProgram::GetOnEdit(bool(**callback)(HeeksObj*)) +{ + *callback = OnEdit; +} diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/PythonStuff.cpp heekscnc-1.0.1-1/src/PythonStuff.cpp --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/PythonStuff.cpp 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/src/PythonStuff.cpp 2020-06-14 10:19:34.000000000 +0000 @@ -233,7 +233,7 @@ wxString path(theApp.GetDllFolder() +_T("/")); #else #ifdef CMAKE_UNIX - wxString path(_T("/usr/@LIB_INSTALL_DIR@/heekscnc/")); + wxString path(_T("/usr/lib/heekscnc/")); #else wxString path(theApp.GetDllFolder() + _T("/../heekscnc/")); #endif diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/PythonStuff.cpp.in heekscnc-1.0.1-1/src/PythonStuff.cpp.in --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/PythonStuff.cpp.in 1970-01-01 00:00:00.000000000 +0000 +++ heekscnc-1.0.1-1/src/PythonStuff.cpp.in 2020-06-14 10:19:34.000000000 +0000 @@ -0,0 +1,510 @@ +// PythonStuff.cpp +// Copyright (c) 2009, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. + +#include "stdafx.h" +#include +#include +#include +#include +#include +#include +#include "PythonStuff.h" +#include "ProgramCanvas.h" +#include "OutputCanvas.h" +#include "Program.h" +#include "CNCConfig.h" +#include "interface/PropertyString.h" + +//static +bool CPyProcess::redirect = false; + +CPyProcess::CPyProcess(void) +{ + m_pid = 0; + wxProcess(heeksCAD->GetMainFrame()); + Connect(wxEVT_TIMER, wxTimerEventHandler(CPyProcess::OnTimer)); + m_timer.SetOwner(this); + +} + +void CPyProcess::OnTimer(wxTimerEvent& event) +{ + HandleInput(); +} + +void CPyProcess::HandleInput(void) { + wxInputStream *m_in, *m_err; + + m_in = GetInputStream(); + m_err = GetErrorStream(); + + if (m_in) { + wxString s; + while (m_in->CanRead()) { + char buffer[4096]; + m_in->Read(buffer, sizeof(buffer)); + s += wxString::From8BitData(buffer, m_in->LastRead()); + } + if (s.Length() > 0) { + theApp.m_print_canvas->m_textCtrl->AppendText(s); + } + } + if (m_err) { + wxString s; + while (m_err->CanRead()) { + char buffer[4096]; + m_err->Read(buffer, sizeof(buffer)); + s += wxString::From8BitData(buffer, m_err->LastRead()); + } + if (s.Length() > 0) { + wxLogMessage(_T("%s"), s.c_str()); + } + } +} + +void CPyProcess::Execute(const wxChar* cmd) +{ + if(redirect) { + Redirect(); + } + // make process group leader so Cancel kan terminate process including children + m_pid = wxExecute(cmd, wxEXEC_ASYNC|wxEXEC_MAKE_GROUP_LEADER, this); + if (!m_pid) { + wxLogMessage(_T("could not execute '%s'"),cmd); + } + + if (redirect) { + m_timer.Start(100); //msec + } +} + +void CPyProcess::Cancel(void) +{ + if (m_pid) + { + wxKillError kerror; + wxSignal sig = wxSIGTERM; + int retcode; + + if ( wxProcess::Exists(m_pid) ) { + retcode = wxKill(m_pid, sig, &kerror, wxKILL_CHILDREN); + switch (kerror) { + case wxKILL_OK: + wxLogMessage(_T("sent signal %d to process %d"),sig, m_pid); + break; + case wxKILL_NO_PROCESS: + wxLogMessage(_T("process %d already exited"),m_pid); + break; + case wxKILL_ACCESS_DENIED: + wxLogMessage(_T("sending signal %d to process %d - access denied"),sig, m_pid); + break; + case wxKILL_BAD_SIGNAL: // no such signal + wxLogMessage(_T("no such signal: %d"),sig); + break; + case wxKILL_ERROR: // another, unspecified error + wxLogMessage(_T("unspecified error sending signal %d to process %d"),sig, m_pid); + break; + } + } else { + wxLogMessage(_T("process %d has gone away"), m_pid); + } + m_pid = 0; + } +} + +void CPyProcess::OnTerminate(int pid, int status) +{ + if (pid == m_pid) + { + if (redirect) { + m_timer.Stop(); + HandleInput(); // anything left? + } + + m_pid = 0; + ThenDo(); + } + // else: the process already was already treated with Cancel() so m_pid is 0 +} + +//////////////////////////////////////////////////////// + +static void ClearErrorAndOutputFiles() +{ + #if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); + #else + wxStandardPaths standard_paths; + #endif + wxFileName errors_path(standard_paths.GetTempDir().c_str(), _T(ERRORS_TXT_FILE_NAME)); + wxFileName output_path(standard_paths.GetTempDir().c_str(), _T(OUTPUT_TXT_FILE_NAME)); + + // clear the error and output files + { + ofstream ofs(Ttc(errors_path.GetFullPath().c_str())); + } + { + ofstream ofs(Ttc(output_path.GetFullPath().c_str())); + } +} + +static bool ProcessErrorAndOutputFiles() +{ +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + wxFileName errors_path(standard_paths.GetTempDir().c_str(), _T(ERRORS_TXT_FILE_NAME)); + wxFileName output_path(standard_paths.GetTempDir().c_str(), _T(OUTPUT_TXT_FILE_NAME)); + + ifstream ifs(Ttc(errors_path.GetFullPath().c_str())); + if (!ifs) + { +#ifdef UNICODE + std::wostringstream l_ossMessage; +#else + std::ostringstream l_ossMessage; +#endif + + l_ossMessage << "Could not open '" << errors_path.GetFullPath().c_str() << "' for reading"; + wxMessageBox(l_ossMessage.str().c_str()); + return false; + } + + char str[1024] = ""; + + bool there_were_errors = false; + while (!(ifs.eof())) + { + ifs.getline(str, 1024); + if (strlen(str) > 0) + { + there_were_errors = true; + theApp.m_output_canvas->m_textCtrl->AppendText(Ctt(str)); + theApp.m_output_canvas->m_textCtrl->AppendText(_T("\n")); + } + } + + if (there_were_errors) + { + wxFont font(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, _T("Lucida Console"), wxFONTENCODING_SYSTEM); + theApp.m_output_canvas->m_textCtrl->SetFont(font); + wxMessageBox(_("There were errors!, see Output window")); + return false; + } + + return true; +} + +class CPyBackPlot : public CPyProcess +{ +protected: + const CProgram* m_program; + HeeksObj* m_into; + wxString m_filename; + wxBusyCursor *m_busy_cursor; + + static CPyBackPlot* m_object; + +public: + CPyBackPlot(const CProgram* program, HeeksObj* into, const wxChar* filename): m_program(program), m_into(into),m_filename(filename),m_busy_cursor(NULL) { m_object = this; } + ~CPyBackPlot(void) { m_object = NULL; } + + static void StaticCancel(void) { if (m_object) m_object->Cancel(); } + + void Do(void) + { + ClearErrorAndOutputFiles(); + + if (m_busy_cursor == NULL)m_busy_cursor = new wxBusyCursor(); + + if (m_program->m_machine.reader == _T("not found")) + { + wxMessageBox(_T("Machine reader name (defined in Program Properties) not found")); + } // End if - then + else + { + #ifdef WIN32 + Execute(wxString(_T("\"")) + theApp.GetDllFolder() + _T("\\nc_read.bat\" ") + m_program->m_machine.reader + _T(" \"") + m_filename + _T("\"")); + #else + #ifdef RUNINPLACE + wxString path(theApp.GetDllFolder() +_T("/")); + #else + #ifdef CMAKE_UNIX + wxString path(_T("/usr/@LIB_INSTALL_DIR@/heekscnc/")); + #else + wxString path(theApp.GetDllFolder() + _T("/../heekscnc/")); + #endif + #endif + + Execute(wxString(_T("python \"")) + path + wxString(_T("backplot.py\" \"")) + m_program->m_machine.reader + wxString(_T("\" \"")) + m_filename + wxString(_T("\"")) ); + #endif + } // End if - else + } + void ThenDo(void) + { + if (!ProcessErrorAndOutputFiles()) + return; + + // there should now be an xml file written + wxString xml_file_str = theApp.m_program->GetBackplotFilePath(); + wxFile ofs(xml_file_str.c_str()); + if(!ofs.IsOpened()) + { + wxMessageBox(wxString(_("Couldn't open file")) + _T(" - ") + xml_file_str); + return; + } + + // read the xml file, just like paste, into the program + heeksCAD->OpenXMLFile(xml_file_str, m_into); + heeksCAD->Repaint(); + + // in Windows, at least, executing the bat file was making HeeksCAD change it's Z order + heeksCAD->GetMainFrame()->Raise(); + + delete m_busy_cursor; + m_busy_cursor = NULL; + } +}; + +CPyBackPlot* CPyBackPlot::m_object = NULL; + +class CPyPostProcess : public CPyProcess +{ +protected: + const CProgram* m_program; + wxString m_filename; + bool m_include_backplot_processing; + + static CPyPostProcess* m_object; + +public: + CPyPostProcess(const CProgram* program, + const wxChar* filename, + const bool include_backplot_processing = true ) : + m_program(program), m_filename(filename), m_include_backplot_processing(include_backplot_processing) + { + m_object = this; + } + + ~CPyPostProcess(void) { m_object = NULL; } + + static void StaticCancel(void) { if (m_object) m_object->Cancel(); } + + void Do(void) + { + ClearErrorAndOutputFiles(); + + wxBusyCursor wait; // show an hour glass until the end of this function + +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + wxFileName path(standard_paths.GetTempDir().c_str(), _T("post.py")); + +#ifdef WIN32 + Execute(wxString(_T("\"")) + theApp.GetDllFolder() + wxString(_T("\\post.bat\" \"")) + path.GetFullPath() + wxString(_T("\""))); +#else + + wxString post_path = wxString(_T("python ")) + path.GetFullPath(); + Execute(post_path); +#endif + } + void ThenDo(void) + { + if (!ProcessErrorAndOutputFiles()) + return; + + if (m_include_backplot_processing) + { + CPyBackPlot::redirect = true; + (new CPyBackPlot(m_program, (HeeksObj*)m_program, m_filename))->Do(); + } + } +}; + +CPyPostProcess* CPyPostProcess::m_object = NULL; + +//////////////////////////////////////////////////////// + +static bool write_python_file(const wxString& python_file_path) +{ + wxFile ofs(python_file_path.c_str(), wxFile::write); + if(!ofs.IsOpened())return false; + + ofs.Write(theApp.m_program->m_python_program.c_str()); + + return true; +} + +bool HeeksPyPostProcess(const CProgram* program, const wxString &filepath, const bool include_backplot_processing) +{ + try{ + theApp.m_output_canvas->m_textCtrl->Clear(); // clear the output window + theApp.m_print_canvas->m_textCtrl->Clear(); // clear the output window + + // write the python file +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + wxFileName file_str(standard_paths.GetTempDir().c_str(), _T("post.py")); + + if(!write_python_file(file_str.GetFullPath())) + { + wxString error; + error << _T("couldn't write ") << file_str.GetFullPath(); + wxMessageBox(error.c_str()); + } + else + { +#ifdef WIN32 + // Set the working directory to the area that contains the DLL so that + // the system can find the post.bat file correctly. + ::wxSetWorkingDirectory(theApp.GetDllFolder()); +#else + ::wxSetWorkingDirectory(standard_paths.GetTempDir()); +#endif + + // call the python file + CPyPostProcess::redirect = true; + CPyPostProcess* p = new CPyPostProcess(program, filepath, include_backplot_processing); + p->Do(); + + return true; + } + } + catch(...) + { + wxMessageBox(_T("Error while post-processing the program!")); + } + return false; +} + +bool HeeksPyBackplot(const CProgram* program, HeeksObj* into, const wxString &filepath) +{ + try{ + theApp.m_output_canvas->m_textCtrl->Clear(); // clear the output window + theApp.m_print_canvas->m_textCtrl->Clear(); // clear the output window + + ::wxSetWorkingDirectory(theApp.GetDllFolder()); + + // call the python file + CPyBackPlot::redirect = true; + CPyBackPlot* p = new CPyBackPlot(program, into, filepath); + p->Do(); + + // in Windows, at least, executing the bat file was making HeeksCAD change it's Z order + //heeksCAD->GetMainFrame()->Raise(); + + return true; + } + catch(...) + { + wxMessageBox(_T("Error while backplotting the program!")); + } + return false; +} + +void HeeksPyCancel(void) +{ + CPyBackPlot::StaticCancel(); + CPyPostProcess::StaticCancel(); +} + + +// create a temporary ngc file +// make your favorite machine load it +void CSendToMachine::Cancel(void) { CPyProcess::Cancel(); } +void CSendToMachine::SendGCode(const wxChar *gcode) + { + wxBusyCursor wait; // show an hour glass until the end of this function + +#if wxCHECK_VERSION(3, 0, 0) + wxStandardPaths& standard_paths = wxStandardPaths::Get(); +#else + wxStandardPaths standard_paths; +#endif + wxFileName ngcpath(theApp.m_program->GetOutputFileName()); + ngcpath.SetPath(standard_paths.GetTempDir()); + + // Append a number to 'prevent' from overwriting a file on machine + // FIXME Reset m_serial on new project (or opened) + if(m_serial) + { + ngcpath.SetName(ngcpath.GetName() + wxString::Format(wxT("-%d"), m_serial)); + } + m_serial++; + + // write the ngc file + { + wxFile ofs(ngcpath.GetFullPath(), wxFile::write); + if(!ofs.IsOpened()) + { + wxMessageBox(wxString(_("Couldn't open file")) + _T(" - ") + ngcpath.GetFullPath()); + return; + } + ofs.Write(theApp.m_output_canvas->m_textCtrl->GetValue()); + } + wxLogDebug(_T("created '%s')"), ngcpath.GetFullPath().c_str()); + +#ifdef WIN32 + Execute(wxString(_T("\"")) + theApp.GetDllFolder() +wxString(_T("\\")) + m_command + wxString(_T("\" \"")) + ngcpath.GetFullPath() + wxString(_T("\""))); +#else + wxString sendto_cmdline = m_command + wxT(" \"") + ngcpath.GetFullPath() + wxT("\""); + wxLogDebug(_T("executing '%s')"), sendto_cmdline.c_str()); + Execute(sendto_cmdline); +#endif + } + + +int CSendToMachine::m_serial; +wxString CSendToMachine::m_command; + +static void on_set_to_machine_command(const wxChar *value, HeeksObj* object) +{ + CSendToMachine::m_command = value; + CSendToMachine::WriteToConfig(); +} + +// static +void CSendToMachine::GetOptions(std::list *list) +{ +#ifndef WIN32 + list->push_back(new PropertyString(_("send-to-machine command"), m_command, NULL, on_set_to_machine_command)); +#endif +} + +// static +void CSendToMachine::ReadFromConfig() +{ + CNCConfig config; + config.Read(_T("SendToMachineCommand"), &m_command , _T("axis-remote")); +} +// static +void CSendToMachine::WriteToConfig() +{ + CNCConfig config; + config.Write(_T("SendToMachineCommand"), m_command); +} + + +static CSendToMachine *send_to; + +bool HeeksSendToMachine(const wxString &gcode) +{ + if (send_to != NULL) { + send_to->Cancel(); + delete send_to; + } + send_to = new CSendToMachine; + send_to->SendGCode(gcode); + + return false; +} + diff -Nru heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/SketchOp.cpp heekscnc-1.0.1-1/src/SketchOp.cpp --- heekscnc-1.0.0.1169+git7ee31b7+202006140042~ubuntu14.04.1/src/SketchOp.cpp 2020-06-14 00:42:30.000000000 +0000 +++ heekscnc-1.0.1-1/src/SketchOp.cpp 2020-06-14 10:19:34.000000000 +0000 @@ -10,15 +10,15 @@ #include "CNCConfig.h" #include "ProgramCanvas.h" #include "Program.h" -#include "interface/PropertyInt.h" +#include "interface/Picking.h" #include "interface/PropertyDouble.h" +#include "interface/PropertyInt.h" #include "interface/PropertyLength.h" #include "interface/PropertyString.h" #include "tinyxml/tinyxml.h" #include "interface/Tool.h" #include "CTool.h" #include "Reselect.h" -#include "src/Picking.h" CSketchOp & CSketchOp::operator= ( const CSketchOp & rhs ) { @@ -57,8 +57,9 @@ HeeksObj* sketch = heeksCAD->GetIDObject(SketchType, m_sketch); if (sketch) { - if(select)SetPickingColor(sketch->GetIndex()); - sketch->glCommands(select, marked, no_color); + if(!no_color)// test to see if this sketch gets drawn over the actual sketch + glColor3ub(0,0,255); + sketch->glCommands(false, marked, true); // don't mark the lines and arcs as selectable objects } } }