- added "measurement lines"
This commit is contained in:
+50
-38
@@ -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",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user