Added extensive test coverage for the TSP tunnel solver including linear
tunnels, pentagram diagonals, and complex wire geometries with various
constraint combinations. Introduced a Python wrapper function for
tunnel sorting that integrates with the C++ solver.
src/Mod/CAM/CAMTests/TestTSPSolver.py:
- Renumbered existing tests to run in sequential order
(test_01_simple_tsp, test_02_start_point, etc.)
- Added print_tunnels() helper function for displaying tunnel
information with original indices
- Added test_06_tunnels_tsp: Tests 7 linear tunnels with varying
lengths, connectivity, and flipping behavior
- Added test_07_pentagram_tunnels_tsp: Tests pentagram diagonal tunnels
with no constraints, start+end constraints, and start-only constraints
- Added test_08_open_wire_end_only: Tests end-only constraint on complex
wire with 8 tunnels including crossings and diagonals
src/Mod/CAM/PathScripts/PathUtils.py:
- Added sort_tunnels_tsp() wrapper function that interfaces with the C++
tsp_solver.solveTunnels()
- Supports allowFlipping, routeStartPoint, and routeEndPoint parameters
Introduce TSPTunnel struct and implement TSPSolver::solveTunnels
for optimizing tunnel order with support for flipping and start/end points.
Expose the new functionality to Python via pybind11, returning tunnel
dictionaries with flipped status.
src/Mod/CAM/App/tsp_solver.cpp:
- Add solveTunnels implementation for tunnel TSP with flipping and route endpoints
src/Mod/CAM/App/tsp_solver.h:
- Define TSPTunnel struct
- Declare solveTunnels static method in TSPSolver
src/Mod/CAM/App/tsp_solver_pybind.cpp:
- Add Python wrapper for solveTunnels
- Expose solveTunnels to Python with argument parsing and result conversion
- Completely re-implemented the TSP algorithm in C++ for better path quality
- Added detailed comments and documentation to clarify each step
- Improved nearest neighbor, 2-opt, and relocation logic
- Enhanced handling of start/end point constraints
- Updated PathUtils.py docstring to accurately describe start point behavior
- Enhanced the C++ TSP solver to accept optional start and end points, so the route can begin and/or end at the closest point to specified coordinates.
- Updated the Python pybind11 wrapper and PathUtils.sort_locations_tsp to support startPoint and endPoint as named parameters.
- Added a new Python test suite (TestTSPSolver.py) to verify correct handling of start/end points and integration with PathUtils.
- Registered the new test in TestCAMApp.py and CMakeLists.txt for automatic test discovery.
This update introduces a new C++ 2-Opt TSP solver with Python bindings.
src/Mod/CAM/App/CMakeLists.txt:
- Add build and install rules for the new pybind11-based tsp_solver Python module
src/Mod/CAM/App/tsp_solver.cpp:
- Add new C++ implementation of a 2-Opt TSP solver with nearest-neighbor initialization
src/Mod/CAM/App/tsp_solver.h:
- Add TSPPoint struct and TSPSolver class with 2-Opt solve method
src/Mod/CAM/App/tsp_solver_pybind.cpp:
- Add pybind11 wrapper exposing the TSP solver to Python as tsp_solver.solve
src/Mod/CAM/PathScripts/PathUtils.py:
- Add sort_locations_tsp Python wrapper for the C++ TSP solver
- Use tsp_solver.solve for TSP-based
Fixes#25924.
The `snapToIntersection` function has been changed to an if-elif structure, and in case of face-edge intersection snap, only two sublements are checked. This ensures a reasonable speed, even if objects have many edges and faces. The change does mean you have to move the mouse over the correct face for it to be processed. But since face-edge intersection snap is new anyway, this is acceptable I think.
Used TestMach3Mach4LegacyPost.py as the starting point with input from
other test scripts too.
The test demonstrate a fix for #25723, as the Fanuc post processor has not been not updated to the latest changes in
the Path module.
This is related to #24676, where thread tapping was added to LinuxCNC, but the equivalent code in the Fanuc
postprocessor were not adjusted to cope, and #25677 where it was observed that the Fanuc postprocessor was
broken in versions 0.20 and 1.0.
Added MockTool class to provide ShapeName to fanuc_post.py, used to
convert drill cycles to threading cycles if the tool has shapeid "tap".
Several methods introduced 2025-05-04 are preferred, but the methods
available in version 1.0 are used as fallback sources
for active status and coolent enabled.
The difference according to the documentation is that M30 will rewind
the paper tape while M2 will not. The effect on a CNC from 1994 is
that M30 turn on the indicator light marking that the program has
completed, while M2 do not, and the light is wanted to know when
the machine is done.
Fanuc only understand upper case letters, no point in providing the
file name in lower case letters. The provided file name is always "-",
so drop it completely. The first comment is presented in the Fanuc user
interface, it should get more relevant content.
Dropped useless semicolon.
Enabling tool height compensation will cause the axis to move up
the length of the tool, which will cause a Z overtravel error when
the tool change take place close to the top of the machine. To
counter this move, ask the machine to move its commanded position
down the length of the tool height, which in effect causes no upward
movement after the tool change. The #4120 variable contain the
current tool number, and #2000 - #20XX contain the tool heights.
The Fanuc post processor add a trailing space to all M6 lines.
This make it problematic to write test for the generated output,
when compiled with the automatic policy enforcer on github
removing trialing space from the expected output. Avoid the
problem by removing the trailing space from the generated
output.
The thread tapping implementation in the Fanuc post processor change
behaviour of M3, G81 and G82 when the tool ShapeID matches "tap".
but the code not not expect that the parse() method will be
called with two different classes as arguments.
Rewrite the M3 handling to handle ToolController arguments
instead of crashing with an AttributeError.
Issues:
Fixes#14016Fixes#25723
Some Fanuc machines do not understand the 'M6 T0' instructions in the
preamble. Move it out of the preamble and controlled by a new
command line argument --no-end-spindle-empty for the machines
where running to cause a "Tool Number Alarm" and the program to crash
as tool zero is not a valid tool.
Fixes: #25677
Reset line number when using --line-numbers. Restore all default values when a
command line argument is not used.
This helps the test scripts ensure that the arguments passed during one test is the only
one taking effect during this test.
This PR allows each Toolbit to have its own Units property (Metric/Imperial) for better unit management.
Short Summary:
- Adds a Units property (Metric/Imperial) to ToolBit objects for better unit management.
- Ensures ToolBit schema is set and restored properly in the editor and utilities.
- Updates formatting and property handling to respect the selected units.
- Improves the ToolBit editor widget to refresh and sync schema/UI when units change.
- Uses FreeCAD.Units.setSchema and getSchema to switch between unit schemas.
NOTE: Toolbit dimensions are read from JSON in their native units (as specified by the Units property),
converted to metric for all internal calculations, and displayed in the UI using the
toolbit's selected units. This ensures both accurate internal computation and user-friendly
display, while storing the correct units in the JSON. This can cause some rounding differences
when switching units. Example: 2 mm becomes 0.0787 inches. If you save that as imperial and then
switch back to metric, it will show 1.9999 mm
src/Mod/CAM/Path/Tool/toolbit/models/base.py:
- Add Units property to ToolBit and ensure it's set and synced with toolbit shape parameters.
- Update property creation and value formatting to use Units.
src/Mod/CAM/Path/Tool/toolbit/ui/editor.py:
- Use setToolBitSchema to set schema based on toolbit units.
- Add logic to refresh property editor widget when units change.
- Restore original schema on close.
- Improve docstrings and signal handling.
src/Mod/CAM/Path/Tool/toolbit/util.py:
- Add setToolBitSchema function for robust schema switching.
- Update format_value to use schema and units.
- Add docstrings and clarify formatting logic.
src/Mod/CAM/Path/Tool/library/ui/browser.py:
- Restore original schema after editing toolbit.
src/Mod/CAM/Path/Tool/library/ui/editor.py:
- Ensure correct schema is set for new toolbits.
* Part: TopoShape make getElementTypeAndIndex more robust
* Part: Add unit tests for new regex
---------
Co-authored-by: Chris Hennes <chennes@gmail.com>