Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FormerLurker/ArcWelderLib.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'PyArcWelder/py_arc_welder.cpp')
-rw-r--r--PyArcWelder/py_arc_welder.cpp507
1 files changed, 411 insertions, 96 deletions
diff --git a/PyArcWelder/py_arc_welder.cpp b/PyArcWelder/py_arc_welder.cpp
index 7fdf9bd..482c09b 100644
--- a/PyArcWelder/py_arc_welder.cpp
+++ b/PyArcWelder/py_arc_welder.cpp
@@ -24,105 +24,420 @@
PyObject* py_arc_welder::build_py_progress(const arc_welder_progress& progress, std::string guid)
{
- std::string segment_statistics = progress.segment_statistics.str();
- PyObject* pyGuid = gcode_arc_converter::PyUnicode_SafeFromString(guid);
- if (pyGuid == NULL)
- return NULL;
- PyObject* pyMessage = gcode_arc_converter::PyUnicode_SafeFromString(segment_statistics);
- if (pyMessage == NULL)
- return NULL;
- double total_count_reduction_percent = progress.segment_statistics.get_total_count_reduction_percent();
- PyObject* py_progress = Py_BuildValue("{s:d,s:d,s:d,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:f,s:f,s:f,s:f,s:i,s:i,s:f}",
- "percent_complete",
- progress.percent_complete, //1
- "seconds_elapsed",
- progress.seconds_elapsed, //2
- "seconds_remaining",
- progress.seconds_remaining, //3
- "gcodes_processed",
- progress.gcodes_processed, //4
- "lines_processed",
- progress.lines_processed, //5
- "points_compressed",
- progress.points_compressed, //6
- "arcs_created",
- progress.arcs_created, //7
- "arcs_aborted_by_flowrate",
- progress.arcs_aborted_by_flow_rate, //8
- "num_firmware_compensations",
- progress.num_firmware_compensations, //9
- "source_file_position",
- progress.source_file_position, //10
- "source_file_size",
- progress.source_file_size, //11
- "target_file_size",
- progress.target_file_size, //12
- "compression_ratio",
- progress.compression_ratio, //13
- "compression_percent",
- progress.compression_percent, //14
- "source_file_total_length",
- progress.segment_statistics.total_length_source, //15
- "target_file_total_length",
- progress.segment_statistics.total_length_target, //16
- "source_file_total_count",
- progress.segment_statistics.total_count_source, //17
- "target_file_total_count",
- progress.segment_statistics.total_count_target, //18
- "total_count_reduction_percent",
- total_count_reduction_percent //19
-
- );
+ PyObject* pyGuid = gcode_arc_converter::PyUnicode_SafeFromString(guid);
+ if (pyGuid == NULL)
+ return NULL;
+ // Extrusion Statistics
+ std::string segment_statistics = progress.segment_statistics.str();
+ PyObject* pyMessage = gcode_arc_converter::PyUnicode_SafeFromString(segment_statistics);
+ if (pyMessage == NULL)
+ return NULL;
+ double total_count_reduction_percent = progress.segment_statistics.get_total_count_reduction_percent();
+ // Travel Statistics
+ std::string segment_travel_statistics = progress.travel_statistics.str();
+ PyObject* pyTravelMessage = gcode_arc_converter::PyUnicode_SafeFromString(segment_travel_statistics);
+ if (pyMessage == NULL)
+ return NULL;
+ double total_travel_count_reduction_percent = progress.travel_statistics.get_total_count_reduction_percent();
+ PyObject* py_progress = Py_BuildValue("{s:d,s:d,s:d,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:f,s:f,s:f,s:f,s:i,s:i,s:f,s:f,s:f,s:i,s:i,s:f}",
+ "percent_complete",
+ progress.percent_complete, //1
+ "seconds_elapsed",
+ progress.seconds_elapsed, //2
+ "seconds_remaining",
+ progress.seconds_remaining, //3
+ "gcodes_processed",
+ progress.gcodes_processed, //4
+ "lines_processed",
+ progress.lines_processed, //5
+ "points_compressed",
+ progress.points_compressed, //6
+ "arcs_created",
+ progress.arcs_created, //7
+ "arcs_aborted_by_flowrate",
+ progress.arcs_aborted_by_flow_rate, //8
+ "num_firmware_compensations",
+ progress.num_firmware_compensations, //9
+ "num_gcode_length_exceptions",
+ progress.num_gcode_length_exceptions, //10
+ "source_file_position",
+ progress.source_file_position, //11
+ "source_file_size",
+ progress.source_file_size, //12
+ "target_file_size",
+ progress.target_file_size, //13
+ "compression_ratio",
+ progress.compression_ratio, //14
+ "compression_percent",
+ progress.compression_percent, //15
+ "source_file_total_length",
+ progress.segment_statistics.total_length_source, //16
+ "target_file_total_length",
+ progress.segment_statistics.total_length_target, //17
+ "source_file_total_count",
+ progress.segment_statistics.total_count_source, //18
+ "target_file_total_count",
+ progress.segment_statistics.total_count_target, //19
+ "total_count_reduction_percent",
+ total_count_reduction_percent, //20
+ "source_file_total_travel_length",
+ progress.travel_statistics.total_length_source, //21
+ "target_file_total_travel_length",
+ progress.travel_statistics.total_length_target, //22
+ "source_file_total_travel_count",
+ progress.travel_statistics.total_count_source, //23
+ "target_file_total_travel_count",
+ progress.travel_statistics.total_count_target, //24
+ "total_travel_count_reduction_percent",
+ total_travel_count_reduction_percent //25
- if (py_progress == NULL)
- {
- return NULL;
- }
- // Due to a CRAZY issue, I have to add this item after building the py_progress object,
- // else it crashes in python 2.7. Looking forward to retiring this backwards
- // compatible code...
- PyDict_SetItemString(py_progress, "segment_statistics_text", pyMessage);
- PyDict_SetItemString(py_progress, "guid", pyGuid);
- return py_progress;
+ );
+
+ if (py_progress == NULL)
+ {
+ return NULL;
+ }
+ // Due to a CRAZY issue, I have to add this item after building the py_progress object,
+ // else it crashes in python 2.7. Looking forward to retiring this backwards
+ // compatible code...
+ PyDict_SetItemString(py_progress, "segment_statistics_text", pyMessage);
+ PyDict_SetItemString(py_progress, "segment_travel_statistics_text", pyTravelMessage);
+ PyDict_SetItemString(py_progress, "guid", pyGuid);
+ return py_progress;
}
bool py_arc_welder::on_progress_(const arc_welder_progress& progress)
{
- PyObject* py_dict = py_arc_welder::build_py_progress(progress, guid_);
- if (py_dict == NULL)
- {
- return false;
- }
- PyObject* func_args = Py_BuildValue("(O)", py_dict);
- if (func_args == NULL)
- {
- Py_DECREF(py_dict);
- return false; // This was returning true, I think it was a typo. Making a note just in case.
- }
-
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* pContinueProcessing = PyObject_CallObject(py_progress_callback_, func_args);
- PyGILState_Release(gstate);
- Py_DECREF(func_args);
- Py_DECREF(py_dict);
- bool continue_processing;
- if (pContinueProcessing == NULL)
- {
- // no return value was supply, assume true, but without decrefing pContinueProcessing
- continue_processing = true;
- }
- else
- {
- if (pContinueProcessing == Py_None)
- {
- continue_processing = true;
- }
- else
- {
- continue_processing = PyLong_AsLong(pContinueProcessing) > 0;
- }
- Py_DECREF(pContinueProcessing);
- }
-
- return continue_processing;
+ PyObject* py_dict = py_arc_welder::build_py_progress(progress, guid_);
+ if (py_dict == NULL)
+ {
+ return false;
+ }
+ PyObject* func_args = Py_BuildValue("(O)", py_dict);
+ if (func_args == NULL)
+ {
+ Py_DECREF(py_dict);
+ return false; // This was returning true, I think it was a typo. Making a note just in case.
+ }
+
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ PyObject* pContinueProcessing = PyObject_CallObject(py_progress_callback_, func_args);
+ PyGILState_Release(gstate);
+ Py_DECREF(func_args);
+ Py_DECREF(py_dict);
+ bool continue_processing;
+ if (pContinueProcessing == NULL)
+ {
+ // no return value was supply, assume true, but without decrefing pContinueProcessing
+ continue_processing = true;
+ }
+ else
+ {
+ if (pContinueProcessing == Py_None)
+ {
+ continue_processing = true;
+ }
+ else
+ {
+ continue_processing = PyLong_AsLong(pContinueProcessing) > 0;
+ }
+ Py_DECREF(pContinueProcessing);
+ }
+
+ return continue_processing;
}
+
+bool py_gcode_arc_args::parse_args(PyObject* py_args, py_logger* p_py_logger, py_gcode_arc_args& args, PyObject** py_progress_callback)
+{
+ p_py_logger->log(
+ GCODE_CONVERSION, INFO,
+ "Parsing GCode Conversion Args."
+ );
+
+#pragma region Required_Arguments
+#pragma region guid
+ // Extract the job guid
+ PyObject* py_guid = PyDict_GetItemString(py_args, "guid");
+ if (py_guid == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve required parameter 'guid' from the args.";
+ p_py_logger->log_exception(GCODE_CONVERSION, message);
+ return false;
+ }
+ args.guid = gcode_arc_converter::PyUnicode_SafeAsString(py_guid);
+#pragma endregion guid
+#pragma region source_path
+ // Extract the source file path
+ PyObject* py_source_path = PyDict_GetItemString(py_args, "source_path");
+ if (py_source_path == NULL)
+ {
+ std::string message = "ParseArgs -Unable to retrieve required parameter 'source_path' from the args.";
+ p_py_logger->log_exception(GCODE_CONVERSION, message);
+ return false;
+ }
+ args.source_path = gcode_arc_converter::PyUnicode_SafeAsString(py_source_path);
+#pragma endregion source_path
+#pragma region target_path
+ // Extract the target file path
+ PyObject* py_target_path = PyDict_GetItemString(py_args, "target_path");
+ if (py_target_path == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve required parameter 'target_path' from the args.";
+ p_py_logger->log_exception(GCODE_CONVERSION, message);
+ return false;
+ }
+ args.target_path = gcode_arc_converter::PyUnicode_SafeAsString(py_target_path);
+#pragma endregion target_path
+#pragma region on_progress_received
+ // on_progress_received
+ PyObject* py_on_progress_received = PyDict_GetItemString(py_args, "on_progress_received");
+ if (py_on_progress_received == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve required parameter 'on_progress_received' from the args.";
+ p_py_logger->log_exception(GCODE_CONVERSION, message);
+ return false;
+ }
+ // need to incref this so it doesn't vanish later (borrowed reference we are saving)
+ Py_XINCREF(py_on_progress_received);
+ *py_progress_callback = py_on_progress_received;
+#pragma endregion on_progress_received
+#pragma endregion Required_Arguments
+
+#pragma region Optional_Arguments
+#pragma region resolution_mm
+ // Extract the resolution in millimeters
+ PyObject* py_resolution_mm = PyDict_GetItemString(py_args, "resolution_mm");
+ if (py_resolution_mm == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'resolution_mm' parameter from the args.";
+ p_py_logger->log(GCODE_CONVERSION, WARNING, message);
+ }
+ else {
+ args.resolution_mm = gcode_arc_converter::PyFloatOrInt_AsDouble(py_resolution_mm);
+ if (args.resolution_mm <= 0)
+ {
+ args.resolution_mm = 0.05; // Set to the default if no resolution is provided, or if it is less than 0.
+ }
+ }
+#pragma endregion resolution_mm
+#pragma region allow_dynamic_precision
+ // extract allow_dynamic_precision
+ PyObject* py_allow_dynamic_precision = PyDict_GetItemString(py_args, "allow_dynamic_precision");
+ if (py_allow_dynamic_precision == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve 'allow_dynamic_precision' from the args.";
+ p_py_logger->log(GCODE_CONVERSION, WARNING, message);
+ }
+ else {
+ args.allow_dynamic_precision = PyLong_AsLong(py_allow_dynamic_precision) > 0;
+ }
+#pragma endregion allow_dynamic_precision
+#pragma region default_xyz_precision
+ // extract default_xyz_precision
+ PyObject* py_default_xyz_precision = PyDict_GetItemString(py_args, "default_xyz_precision");
+ if (py_default_xyz_precision == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'default_xyz_precision' parameter from the args.";
+ p_py_logger->log(GCODE_CONVERSION, WARNING, message);
+ }
+ else {
+ args.default_xyz_precision = gcode_arc_converter::PyFloatOrInt_AsDouble(py_default_xyz_precision);
+ if (args.default_xyz_precision < 3)
+ {
+ std::string message = "ParseArgs - The default XYZ precision received was less than 3, which could cause problems printing arcs. Setting to 3.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ args.default_xyz_precision = 3;
+ }
+ else if (args.default_xyz_precision > 6)
+ {
+ std::string message = "ParseArgs - The default XYZ precision received was greater than 6, which could can cause checksum errors depending on your firmware. Setting to 6.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ args.default_xyz_precision = 6;
+ }
+ }
+#pragma endregion default_xyz_precision
+#pragma region default_e_precision
+ // extract default_e_precision
+ PyObject* py_default_e_precision = PyDict_GetItemString(py_args, "default_e_precision");
+ if (py_default_e_precision == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'default_e_precision parameter' from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else {
+ args.default_e_precision = gcode_arc_converter::PyFloatOrInt_AsDouble(py_default_e_precision);
+ if (args.default_e_precision < 3)
+ {
+ std::string message = "ParseArgs - The default E precision received was less than 3, which could cause extrusion problems. Setting to 3.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ args.default_e_precision = 3;
+ }
+ else if (args.default_e_precision > 6)
+ {
+ std::string message = "ParseArgs - The default E precision received was greater than 6, which could can cause checksum errors depending on your firmware. Setting to 6.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ args.default_e_precision = 6;
+ }
+ }
+#pragma endregion default_e_precision
+#pragma region extrusion_rate_variance_percent
+ // Extract the extrusion_rate_variance
+ PyObject* py_extrusion_rate_variance_percent = PyDict_GetItemString(py_args, "extrusion_rate_variance_percent");
+ if (py_extrusion_rate_variance_percent == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'extrusion_rate_variance_percent' parameter from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.extrusion_rate_variance_percent = gcode_arc_converter::PyFloatOrInt_AsDouble(py_extrusion_rate_variance_percent);
+ if (args.extrusion_rate_variance_percent < 0)
+ {
+ args.extrusion_rate_variance_percent = DEFAULT_EXTRUSION_RATE_VARIANCE_PERCENT; // Set to the default if no resolution is provided, or if it is less than 0.
+ }
+ }
+#pragma endregion extrusion_rate_variance_percent
+#pragma region path_tolerance_percent
+ // Extract the path tolerance_percent
+ PyObject* py_path_tolerance_percent = PyDict_GetItemString(py_args, "path_tolerance_percent");
+ if (py_path_tolerance_percent == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'path_tolerance_percent' parameter from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.path_tolerance_percent = gcode_arc_converter::PyFloatOrInt_AsDouble(py_path_tolerance_percent);
+ if (args.path_tolerance_percent < 0)
+ {
+ args.path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT; // Set to the default if no resolution is provided, or if it is less than 0.
+ }
+ }
+#pragma endregion path_tolerance_percent
+#pragma region max_radius_mm
+ // Extract the max_radius in mm
+ PyObject* py_max_radius_mm = PyDict_GetItemString(py_args, "max_radius_mm");
+ if (py_max_radius_mm == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'max_radius_mm' parameter from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.max_radius_mm = gcode_arc_converter::PyFloatOrInt_AsDouble(py_max_radius_mm);
+ if (args.max_radius_mm > DEFAULT_MAX_RADIUS_MM)
+ {
+ args.max_radius_mm = DEFAULT_MAX_RADIUS_MM; // Set to the default if no resolution is provided, or if it is less than 0.
+ }
+ }
+#pragma endregion max_radius_mm
+#pragma region mm_per_arc_segment
+ // Extract the mm_per_arc_segment
+ PyObject* py_mm_per_arc_segment = PyDict_GetItemString(py_args, "mm_per_arc_segment");
+ if (py_mm_per_arc_segment == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'mm_per_arc_segment' parameter from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.mm_per_arc_segment = gcode_arc_converter::PyFloatOrInt_AsDouble(py_mm_per_arc_segment);
+ if (args.mm_per_arc_segment < 0)
+ {
+ args.mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT;
+ }
+ }
+#pragma endregion mm_per_arc_segment
+#pragma region min_arc_segments
+ // Extract min_arc_segments
+ PyObject* py_min_arc_segments = PyDict_GetItemString(py_args, "min_arc_segments");
+ if (py_min_arc_segments == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'min_arc_segments' parameter from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.min_arc_segments = (int)gcode_arc_converter::PyIntOrLong_AsLong(py_min_arc_segments);
+ if (args.min_arc_segments < 0)
+ {
+ args.min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS; // Set to the default if no resolution is provided, or if it is less than 0.
+ }
+ }
+#pragma endregion min_arc_segments
+#pragma region max_gcode_length
+ // Extract max_gcode_length
+ PyObject* py_max_gcode_length = PyDict_GetItemString(py_args, "max_gcode_length");
+ if (py_max_gcode_length == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the 'max_gcode_length' parameter from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.max_gcode_length = (int)gcode_arc_converter::PyIntOrLong_AsLong(py_max_gcode_length);
+ if (args.max_gcode_length < 0)
+ {
+ args.max_gcode_length = DEFAULT_MAX_GCODE_LENGTH;
+ }
+ }
+#pragma endregion max_gcode_length
+#pragma region allow_3d_arcs
+ // extract allow_3d_arcs
+ PyObject* py_allow_3d_arcs = PyDict_GetItemString(py_args, "allow_3d_arcs");
+ if (py_allow_3d_arcs == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve 'allow_3d_arcs' from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.allow_3d_arcs = PyLong_AsLong(py_allow_3d_arcs) > 0;
+ }
+#pragma endregion allow_3d_arcs
+#pragma region allow_travel_arcs
+ // extract allow_travel_arcs
+ PyObject* py_allow_travel_arcs = PyDict_GetItemString(py_args, "allow_travel_arcs");
+ if (py_allow_travel_arcs == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve 'allow_travel_arcs' from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.allow_travel_arcs = PyLong_AsLong(py_allow_travel_arcs) > 0;
+ }
+#pragma endregion allow_travel_arcs
+#pragma region g90_g91_influences_extruder
+ // Extract G90/G91 influences extruder
+ // g90_influences_extruder
+ PyObject* py_g90_g91_influences_extruder = PyDict_GetItemString(py_args, "g90_g91_influences_extruder");
+ if (py_g90_g91_influences_extruder == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve 'g90_g91_influences_extruder' from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ args.g90_g91_influences_extruder = PyLong_AsLong(py_g90_g91_influences_extruder) > 0;
+ }
+#pragma endregion g90_g91_influences_extruder
+#pragma region log_level
+ // Extract log_level
+ PyObject* py_log_level = PyDict_GetItemString(py_args, "log_level");
+ if (py_log_level == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve 'log_level' from the args.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ }
+ else
+ {
+ int log_level_value = static_cast<int>(PyLong_AsLong(py_log_level));
+ // determine the log level as an index rather than as a value
+ args.log_level = p_py_logger->get_log_level_for_value(log_level_value);
+ }
+#pragma endregion log_level
+#pragma endregion Optional_Arguments
+
+ return true;
+} \ No newline at end of file