Skip to content

Commit fc4fd6d

Browse files
Improve STL workflows and toolpath rendering
1 parent 4d317b5 commit fc4fd6d

38 files changed

Lines changed: 10386 additions & 8469 deletions

‎CHANGELOG.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## 1.7.0 - 2026-09-29
4+
5+
- Corrected physical milling views for horizontal and vertical spindle profiles, including camera orientation and restoring the selected view after changing kinematics.
6+
- Fixed toolpath segments disappearing during middle-button orbit by refreshing orthographic camera clipping after rotation.
7+
- Show the active 3D/Top/Front/Left view as a checked, mutually exclusive toolbar action; add visible theme-aware hover and pressed states to the main toolbars.
8+
- Enable Save only when the editor has unsaved changes, and restore its disabled state after saving or opening a file.
9+
- Add action icons to STL Objects controls, hide the selected object's pivot marker with the panel, and log load, delete, transform, array and section timings.
10+
- Fixed STL section cap winding for all three axes, including Y-plane handedness; a cut coincident with an outer mesh face now retains that face instead of opening the shell.
11+
- Triangulate section caps with nested contours as polygons with holes, preserving hollow regions in tubes and enclosed cavities.
12+
- Replaced the section-cap Python ear-clipping and manual hole bridging with `mapbox-earcut`; preserve holes and disconnected contours, restore collinear boundary vertices for watertight caps, and keep cap normals aligned with the selected side. On `assets/stl/test4.stl` (14,522 triangles, midplane cuts), `clip_mesh` measured X 345 ms, Y 396 ms and Z 350 ms, down from 2,577/18,906/3,651 ms.
13+
- Keep the active section mesh in the plot after `loadPlot()`, and refresh both the visible cut and hidden source mesh when STL color or wireframe settings change.
14+
- Preserve STL undo history when importing after Clear STL or deleting the final object.
15+
- Reject cumulative STL scales that overflow float32 coordinates, collapse non-degenerate faces, or invalidate an originally closed mesh; report rejected GUI scaling in the status bar.
16+
- Added section-cap regression coverage for convex and concave contours, holes, disconnected outer contours, large polygon-with-hole earcut usage, X/Y/Z orientation, both kept sides and watertight results; retain coverage for face-coincident cuts, repeated scaling, plot reloads, appearance refresh and import/clear history.
17+
318
## 1.6.9 - 2026-09-29
419

520
- Switched the milling 3D camera to an orthographic CAD projection and kept it orthographic while orbiting from fixed views, so apparent feature size does not change with depth.

‎FAQ.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Easy G-Code Plot FAQ
22

3-
This document is the detailed user and developer reference for Easy G-Code Plot. It reflects the current 1.6.9 tree and explains the GUI, deterministic FANUC execution kernel, Macro B runtime, turning and milling cycles, indexed rotary behavior, diagnostics, CLI, batch analysis and export behavior.
3+
This document is the detailed user and developer reference for Easy G-Code Plot. It reflects the current 1.7.0 tree and explains the GUI, deterministic FANUC execution kernel, Macro B runtime, turning and milling cycles, indexed rotary behavior, diagnostics, CLI, batch analysis and export behavior.
44

55
The same FAQ can be packaged for offline use in **Help → FAQ**.
66

‎FAQ_RU.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Easy G-Code Plot: часто задаваемые вопросы
22

3-
Этот документ представляет собой подробное справочное руководство для пользователей и разработчиков Easy G-Code Plot. Он отражает текущую кодовую базу версии 1.6.9 и предназначен для объяснения графического интерфейса, детерминированного ядра выполнения FANUC, среды Macro B, циклов точения и фрезерования, диагностики, CLI, пакетного анализа и экспорта.
3+
Этот документ представляет собой подробное справочное руководство для пользователей и разработчиков Easy G-Code Plot. Он отражает текущую кодовую базу версии 1.7.0 и предназначен для объяснения графического интерфейса, детерминированного ядра выполнения FANUC, среды Macro B, циклов точения и фрезерования, диагностики, CLI, пакетного анализа и экспорта.
44

55
Тот же FAQ может быть упакован для автономного использования в **Справка → FAQ**.
66

‎app/main_window.py‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def __init__(self):
9494
self.ui.setupUi(self)
9595
self._configure_runtime_ui()
9696
self._configure_playback_speed_slider()
97-
self._plot_navigation = PlotNavigation(self.ui.graphicsView, self._update_adaptive_grid, self._pick_trace_at)
97+
self._plot_navigation = PlotNavigation(self.ui.graphicsView, self._plot_camera_changed, self._pick_trace_at)
9898
self.ui.graphicsView.installEventFilter(self._plot_navigation)
9999

100100
icon = QIcon()
@@ -180,12 +180,22 @@ def _select_rotary_kinematics(self, profile_id, *, force_refresh=False):
180180

181181
if not (changed or force_refresh):
182182
return
183-
if changed and not getattr(self, "latheMode", False) and getattr(self, "_view_mode", "3d") == "3d":
184-
self.view3d()
183+
view_mode = getattr(self, "_view_mode", "3d")
185184
self._deferred_execution_result = None
186185
self._deferred_execution_source = None
187186
if self.ui.editor.text():
188187
self.updateData()
188+
# Reapply after updateData: it redraws the scene and can restore a
189+
# previous camera state, including a quaternion left by table B.
190+
if not getattr(self, "latheMode", False):
191+
if view_mode == "top":
192+
self.viewTop()
193+
elif view_mode == "front":
194+
self.viewFront()
195+
elif view_mode == "left":
196+
self.viewLeft()
197+
else:
198+
self.view3d()
189199

190200
def _configure_runtime_ui(self):
191201
"""Attach runtime-only widgets and action groups to the generated Designer UI."""
@@ -198,6 +208,12 @@ def _configure_runtime_ui(self):
198208
self.ui.menuSettings.insertAction(self.ui.actionWCS, self.ui.actionStock)
199209
self.ui.menuCNC_Functions.addSeparator()
200210
self.ui.cncToolBar.addSeparator()
211+
self.viewActionGroup = QActionGroup(self)
212+
self.viewActionGroup.setExclusive(True)
213+
for action in (self.ui.action3D, self.ui.actionTop, self.ui.actionFront, self.ui.actionLeft):
214+
action.setCheckable(True)
215+
self.viewActionGroup.addAction(action)
216+
self.ui.action3D.setChecked(True)
201217
for name, text, icon_path in (
202218
(
203219
"actionHoleCalculator",
@@ -498,6 +514,7 @@ def connectActions(self):
498514
self.ui.actionStep_Forward.triggered.connect(self.forward)
499515

500516
self.ui.editor.modificationChanged.connect(self.documentWasModified)
517+
self.ui.actionSave.setEnabled(self.ui.editor.isModified())
501518
self.ui.editor.textChanged.connect(self.scheduleAutoUpdate)
502519
self.ui.editor.cursorPositionChanged.connect(self.updateStatusBar)
503520
self.ui.editor.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)

0 commit comments

Comments
 (0)