feat: add CLI logging for debugging

- Add logging module with DEBUG level
- Log MainWindow initialization
- Log Viewer3DWidget initialization and mesh operations
- Log mouse events in Sketch2DWidget
- Log extrude operations with detailed steps
- Log component and sketch management
This commit is contained in:
bklronin
2026-03-14 09:01:20 +01:00
parent daed79dac6
commit d7ebbf45d5
+55 -1
View File
@@ -8,8 +8,12 @@ with a modern pygfx-based 3D renderer.
import sys
import math
import uuid
import logging
from typing import Optional, List, Dict, Any, Tuple
from dataclasses import dataclass, field
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
from PySide6.QtWidgets import (
QApplication,
QMainWindow,
@@ -325,6 +329,9 @@ class Sketch2DWidget(QWidget):
def mousePressEvent(self, event):
world_pos = self._screen_to_world(event.pos())
logger.debug(
f"Mouse press: button={event.button()}, mode={self._mode}, world_pos=({world_pos.x()}, {world_pos.y()})"
)
if event.button() == Qt.MiddleButton:
self._panning = True
@@ -333,6 +340,7 @@ class Sketch2DWidget(QWidget):
return
if event.button() == Qt.RightButton:
logger.debug("Right click - resetting mode")
self._mode = None
self._draw_buffer = []
self._dynamic_line_end = None
@@ -347,6 +355,7 @@ class Sketch2DWidget(QWidget):
world_snapped = (
self._screen_to_world(snapped_pos) if snapped_pos != event.pos() else world_pos
)
logger.debug(f"Left click - mode={self._mode}, snapped={snapped_pos != event.pos()}")
if self._mode == "line":
self._handle_line_click(world_snapped)
@@ -398,14 +407,17 @@ class Sketch2DWidget(QWidget):
self.update()
def _handle_line_click(self, pos: QPoint):
logger.debug(f"Line click at ({pos.x()}, {pos.y()})")
if not self._sketch:
self._sketch = OCCSketch()
logger.debug("Created new OCCSketch")
if not self._draw_buffer:
point = self._sketch.add_point(pos.x(), pos.y())
point.is_construction = self._is_construct
self._points.append(point)
self._draw_buffer.append(pos)
logger.debug(f"Added first point, buffer size={len(self._draw_buffer)}")
else:
point = self._sketch.add_point(pos.x(), pos.y())
point.is_construction = self._is_construct
@@ -414,6 +426,7 @@ class Sketch2DWidget(QWidget):
if len(self._points) >= 2:
line = self._sketch.add_line(self._points[-2], self._points[-1])
self._lines.append((self._points[-2], self._points[-1]))
logger.debug(f"Added line between points, total lines={len(self._lines)}")
self._draw_buffer = [pos]
@@ -653,9 +666,11 @@ class Viewer3DWidget(QWidget):
self._pending_meshes: List[Tuple] = []
def showEvent(self, event):
logger.info("Viewer3DWidget showEvent - initializing renderer")
if not self._initialized:
self._renderer.initialize(self)
self._initialized = True
logger.info(f"Renderer initialized, pending meshes: {len(self._pending_meshes)}")
for args in self._pending_meshes:
self.add_mesh(*args)
self._pending_meshes.clear()
@@ -663,6 +678,7 @@ class Viewer3DWidget(QWidget):
def _ensure_initialized(self):
if not self._initialized:
logger.debug("Ensuring renderer is initialized")
self._renderer.initialize(self)
self._initialized = True
@@ -670,14 +686,19 @@ class Viewer3DWidget(QWidget):
return self._renderer
def add_mesh(self, vertices, faces, color=None, name=None) -> str:
logger.debug(
f"add_mesh called: initialized={self._initialized}, vertices={len(vertices)}, faces={len(faces)}, name={name}"
)
if not self._initialized:
self._pending_meshes.append((vertices, faces, color, name))
logger.info(f"Queued pending mesh, total pending: {len(self._pending_meshes)}")
return f"pending_{len(self._pending_meshes)}"
self._ensure_initialized()
mesh_id = self._renderer.add_mesh(vertices, faces, color, name)
self._meshes[mesh_id] = {"vertices": vertices, "faces": faces, "name": name}
self._renderer.render()
logger.info(f"Added mesh: {mesh_id}, name={name}")
return mesh_id
def update_mesh(self, mesh_id: str, vertices, faces):
@@ -729,9 +750,11 @@ class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
logger.info("Initializing MainWindow")
self._project = Project()
self._kernel = OCGeometryKernel()
logger.info("Created Project and OCGeometryKernel")
self._current_component: Optional[Component] = None
self._current_sketch: Optional[Sketch] = None
@@ -743,6 +766,7 @@ class MainWindow(QMainWindow):
self._setup_ui()
self._setup_connections()
self._create_initial_component()
logger.info("MainWindow initialization complete")
def _setup_ui(self):
self.setWindowTitle("Fluency CAD 2.0")
@@ -1280,8 +1304,10 @@ class MainWindow(QMainWindow):
return 0
def _new_component(self):
logger.info("=== NEW COMPONENT ===")
comp = self._project.add_component()
self._current_component = comp
logger.info(f"Created component: {comp.name}")
btn = QPushButton(str(len(self._project.components)))
btn.setCheckable(True)
@@ -1365,19 +1391,27 @@ class MainWindow(QMainWindow):
self.statusBar().showMessage("Flip workplane (not implemented)")
def _add_sketch_to_component(self):
logger.info("=== ADD SKETCH TO COMPONENT ===")
if not self._current_component:
logger.info("No current component, creating new one")
self._current_component = self._project.add_component()
sketch = self._current_component.add_sketch()
sketch.occ_sketch = self._sketch_widget.get_sketch()
logger.debug(f"Created sketch: {sketch.name}")
sketch_widget_sketch = self._sketch_widget.get_sketch()
logger.debug(f"Sketch from widget: {sketch_widget_sketch}")
sketch.occ_sketch = sketch_widget_sketch
if not sketch.occ_sketch:
logger.info("Creating new sketch in widget")
sketch.occ_sketch = self._sketch_widget.create_sketch()
self._current_sketch = sketch
self._refresh_lists()
self._sketch_widget.set_mode(None)
self.statusBar().showMessage(f"Added sketch: {sketch.name}")
logger.info(f"=== SKETCH ADDED: {sketch.name} ===")
def _edit_sketch(self):
selected = self._sketch_list.currentItem()
@@ -1430,13 +1464,18 @@ class MainWindow(QMainWindow):
break
def _extrude_sketch(self):
logger.info("=== EXTRUDE SKETCH ===")
if not self._current_component:
logger.warning("No current component")
return
sketch = self._current_sketch
logger.debug(f"Current sketch: {sketch}")
if not sketch or not sketch.occ_sketch:
sketch_entity = self._sketch_widget.get_sketch()
logger.debug(f"Sketch from widget: {sketch_entity}")
if not sketch_entity:
logger.warning("No sketch entity found")
QMessageBox.warning(self, "No Sketch", "Please create a sketch first")
return
sketch.occ_sketch = sketch_entity
@@ -1444,16 +1483,23 @@ class MainWindow(QMainWindow):
dialog = ExtrudeDialog(self)
if dialog.exec():
length, symmetric, invert, cut, union, rounded = dialog.get_values()
logger.info(f"Extrude params: length={length}, symmetric={symmetric}, invert={invert}")
else:
logger.info("Extrude dialog cancelled")
return
try:
logger.debug("Getting geometry from sketch")
geometry = sketch.occ_sketch.get_geometry()
logger.debug(f"Geometry: {geometry}")
if not geometry:
logger.error("No geometry from sketch")
QMessageBox.warning(self, "No Geometry", "Sketch has no valid geometry")
return
logger.info("Calling kernel.extrude")
body_geometry = self._kernel.extrude(geometry, length, symmetric=symmetric)
logger.debug(f"Body geometry created: {body_geometry}")
body = self._current_component.add_body(
Body(
@@ -1463,15 +1509,23 @@ class MainWindow(QMainWindow):
source_operation="extrude",
)
)
logger.info(f"Created body: {body.name}")
logger.debug("Getting mesh for body")
vertices, faces = body.get_mesh(self._kernel)
logger.info(f"Mesh: {len(vertices)} vertices, {len(faces)} faces")
logger.debug("Adding mesh to viewer")
body.render_object = self._viewer_3d.add_mesh(vertices, faces, body.color, body.name)
logger.info(f"Render object: {body.render_object}")
self._refresh_lists()
self._viewer_3d.fit_camera()
self.statusBar().showMessage(f"Extruded: {body.name}")
logger.info("=== EXTRUDE COMPLETE ===")
except Exception as e:
logger.exception(f"Extrude failed: {e}")
QMessageBox.critical(self, "Error", f"Extrude failed: {e}")
def _revolve_sketch(self):