- added "measurement lines"

This commit is contained in:
bklronin
2026-07-26 21:39:47 +02:00
parent 9f1c29d319
commit 0daa6152ee
12 changed files with 3110 additions and 1675 deletions
+50 -38
View File
@@ -4,18 +4,13 @@ from __future__ import annotations
import logging
import math
from typing import Any, Dict, List, Optional, Tuple
from typing import Tuple
from PySide6.QtCore import Qt, QPoint, QPointF
from PySide6.QtGui import QColor, QFont, QKeySequence
from PySide6.QtWidgets import (
QButtonGroup,
QCheckBox,
QComboBox,
QDialog,
QDialogButtonBox,
QDoubleSpinBox,
QFormLayout,
QFrame,
QGridLayout,
QHBoxLayout,
@@ -24,11 +19,11 @@ from PySide6.QtWidgets import (
QPushButton,
QRadioButton,
QVBoxLayout,
QWidget,
)
logger = logging.getLogger(__name__)
class ExtrudeDialog(QDialog):
"""Dialog for extrude options.
@@ -76,6 +71,13 @@ class ExtrudeDialog(QDialog):
)
layout.addWidget(self.through_all_checkbox)
self.cut_all_bodies_checkbox = QCheckBox("Cut All Bodies")
self.cut_all_bodies_checkbox.setToolTip(
"Apply the boolean cut to every body in the current component, "
"not just the one the sketch was drawn on. Requires Perform Cut."
)
layout.addWidget(self.cut_all_bodies_checkbox)
self.rounded_checkbox = QCheckBox("Round Edges")
layout.addWidget(self.rounded_checkbox)
@@ -103,6 +105,7 @@ class ExtrudeDialog(QDialog):
self.cut_checkbox,
self.union_checkbox,
self.through_all_checkbox,
self.cut_all_bodies_checkbox,
self.rounded_checkbox,
):
# The spinbox has valueChanged; the checkboxes have stateChanged.
@@ -144,7 +147,7 @@ class ExtrudeDialog(QDialog):
pass
super().hideEvent(event)
def get_values(self) -> Tuple[float, bool, bool, bool, bool, bool, bool]:
def get_values(self) -> Tuple[float, bool, bool, bool, bool, bool, bool, bool]:
return (
self.length_input.value(),
self.symmetric_checkbox.isChecked(),
@@ -152,6 +155,7 @@ class ExtrudeDialog(QDialog):
self.cut_checkbox.isChecked(),
self.union_checkbox.isChecked(),
self.through_all_checkbox.isChecked(),
self.cut_all_bodies_checkbox.isChecked(),
self.rounded_checkbox.isChecked(),
)
@@ -295,12 +299,12 @@ class WorkplaneOrientationDialog(QDialog):
self._preset_group = QButtonGroup(self)
preset_layout = QGridLayout()
presets = [
("XY (Top)", (0, 0, 1), (1, 0, 0)),
("XZ (Front)", (0, 1, 0), (1, 0, 0)),
("YZ (Right)", (1, 0, 0), (0, 1, 0)),
("XY (Top)", (0, 0, 1), (1, 0, 0)),
("XZ (Front)", (0, 1, 0), (1, 0, 0)),
("YZ (Right)", (1, 0, 0), (0, 1, 0)),
("-XY (Bottom)", (0, 0, -1), (1, 0, 0)),
("-XZ (Back)", (0, -1, 0), (1, 0, 0)),
("-YZ (Left)", (-1, 0, 0), (0, 1, 0)),
("-XZ (Back)", (0, -1, 0), (1, 0, 0)),
("-YZ (Left)", (-1, 0, 0), (0, 1, 0)),
]
for idx, (label, normal, x_dir) in enumerate(presets):
btn = QRadioButton(label)
@@ -404,7 +408,6 @@ class WorkplaneOrientationDialog(QDialog):
def _on_ok(self):
"""Compute the final orientation and accept."""
import numpy as np
import math
if self._custom_radio.isChecked():
# Custom: start from XY normal and rotate by the two angles.
@@ -413,18 +416,22 @@ class WorkplaneOrientationDialog(QDialog):
# Start from +Z normal, rotate around X then Y
n = np.array([0.0, 0.0, 1.0])
# Rotate around X
rx = np.array([
[1, 0, 0],
[0, math.cos(ax), -math.sin(ax)],
[0, math.sin(ax), math.cos(ax)],
])
rx = np.array(
[
[1, 0, 0],
[0, math.cos(ax), -math.sin(ax)],
[0, math.sin(ax), math.cos(ax)],
]
)
n = rx @ n
# Rotate around Y
ry = np.array([
[math.cos(ay), 0, math.sin(ay)],
[0, 1, 0],
[-math.sin(ay), 0, math.cos(ay)],
])
ry = np.array(
[
[math.cos(ay), 0, math.sin(ay)],
[0, 1, 0],
[-math.sin(ay), 0, math.cos(ay)],
]
)
n = ry @ n
n = n / np.linalg.norm(n)
# x_dir: cross product of normal with world Y, or world Z if normal ~ Y
@@ -454,23 +461,26 @@ class WorkplaneOrientationDialog(QDialog):
whether called before or after ``_on_ok``.
"""
import numpy as np
import math
if self._custom_radio.isChecked():
ax = math.radians(self._angle_x.value())
ay = math.radians(self._angle_y.value())
n = np.array([0.0, 0.0, 1.0])
rx = np.array([
[1, 0, 0],
[0, math.cos(ax), -math.sin(ax)],
[0, math.sin(ax), math.cos(ax)],
])
rx = np.array(
[
[1, 0, 0],
[0, math.cos(ax), -math.sin(ax)],
[0, math.sin(ax), math.cos(ax)],
]
)
n = rx @ n
ry = np.array([
[math.cos(ay), 0, math.sin(ay)],
[0, 1, 0],
[-math.sin(ay), 0, math.cos(ay)],
])
ry = np.array(
[
[math.cos(ay), 0, math.sin(ay)],
[0, 1, 0],
[-math.sin(ay), 0, math.cos(ay)],
]
)
n = ry @ n
n = n / np.linalg.norm(n)
world_y = np.array([0.0, 1.0, 0.0])
@@ -492,6 +502,8 @@ class WorkplaneOrientationDialog(QDialog):
if btn is not None:
return (btn.normal, btn.x_dir, self._name_input.text().strip() or "Workplane")
# Fallback: XY default.
return ((0.0, 0.0, 1.0), (1.0, 0.0, 0.0), self._name_input.text().strip() or "Workplane")
return (
(0.0, 0.0, 1.0),
(1.0, 0.0, 0.0),
self._name_input.text().strip() or "Workplane",
)