mirror of
https://github.com/gumyr/build123d.git
synced 2026-01-27 23:10:59 -08:00
Merge pull request #1178 from slobberingant/dev
Some checks failed
benchmarks / benchmarks (macos-14, 3.12) (push) Has been cancelled
benchmarks / benchmarks (macos-15-intel, 3.12) (push) Has been cancelled
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Has been cancelled
benchmarks / benchmarks (windows-latest, 3.12) (push) Has been cancelled
Upload coverage reports to Codecov / run (push) Has been cancelled
pylint / lint (3.10) (push) Has been cancelled
Run type checker / typecheck (3.10) (push) Has been cancelled
Run type checker / typecheck (3.13) (push) Has been cancelled
Wheel building and publishing / Build wheel on ubuntu-latest (push) Has been cancelled
tests / tests (macos-14, 3.10) (push) Has been cancelled
tests / tests (macos-14, 3.13) (push) Has been cancelled
tests / tests (macos-15-intel, 3.10) (push) Has been cancelled
tests / tests (macos-15-intel, 3.13) (push) Has been cancelled
tests / tests (ubuntu-latest, 3.10) (push) Has been cancelled
tests / tests (ubuntu-latest, 3.13) (push) Has been cancelled
tests / tests (windows-latest, 3.10) (push) Has been cancelled
tests / tests (windows-latest, 3.13) (push) Has been cancelled
Wheel building and publishing / upload_pypi (push) Has been cancelled
Some checks failed
benchmarks / benchmarks (macos-14, 3.12) (push) Has been cancelled
benchmarks / benchmarks (macos-15-intel, 3.12) (push) Has been cancelled
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Has been cancelled
benchmarks / benchmarks (windows-latest, 3.12) (push) Has been cancelled
Upload coverage reports to Codecov / run (push) Has been cancelled
pylint / lint (3.10) (push) Has been cancelled
Run type checker / typecheck (3.10) (push) Has been cancelled
Run type checker / typecheck (3.13) (push) Has been cancelled
Wheel building and publishing / Build wheel on ubuntu-latest (push) Has been cancelled
tests / tests (macos-14, 3.10) (push) Has been cancelled
tests / tests (macos-14, 3.13) (push) Has been cancelled
tests / tests (macos-15-intel, 3.10) (push) Has been cancelled
tests / tests (macos-15-intel, 3.13) (push) Has been cancelled
tests / tests (ubuntu-latest, 3.10) (push) Has been cancelled
tests / tests (ubuntu-latest, 3.13) (push) Has been cancelled
tests / tests (windows-latest, 3.10) (push) Has been cancelled
tests / tests (windows-latest, 3.13) (push) Has been cancelled
Wheel building and publishing / upload_pypi (push) Has been cancelled
Added project_line feature to ExtensionLine.
This commit is contained in:
commit
4783f5e9df
4 changed files with 923 additions and 762 deletions
File diff suppressed because it is too large
Load diff
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 184 KiB |
|
|
@ -162,9 +162,13 @@ vis, _ = project_to_2d(
|
|||
)
|
||||
visible_lines.extend(vis)
|
||||
side_bbox = Curve(vis).bounding_box()
|
||||
perimeter = Pos(*side_bbox.center()) * Rectangle(side_bbox.size.X, side_bbox.size.Y)
|
||||
shaft_top_corner = vis.edges().sort_by(Axis.Y)[-1].vertices().sort_by(Axis.X)[-1]
|
||||
body_bottom_corner = (side_bbox.max.X, side_bbox.min.Y)
|
||||
d4 = ExtensionLine(
|
||||
border=perimeter.edges().sort_by(Axis.X)[-1], offset=1 * CM, draft=drafting_options
|
||||
border=(shaft_top_corner, body_bottom_corner),
|
||||
offset=-(side_bbox.max.X - shaft_top_corner.X) - 1 * CM, # offset to outside view.
|
||||
measurement_direction=(0, 1, 0),
|
||||
draft=drafting_options,
|
||||
)
|
||||
l3 = Text("Side Elevation", 6)
|
||||
l3.position = vis.group_by(Axis.Y)[0].sort_by(Edge.length)[-1].center() + (0, -5 * MM)
|
||||
|
|
|
|||
|
|
@ -504,7 +504,8 @@ class ExtensionLine(BaseSketchObject):
|
|||
label_angle (bool, optional): a flag indicating that instead of an extracted length
|
||||
value, the size of the circular arc extracted from the path should be displayed
|
||||
in degrees. Defaults to False.
|
||||
project_line (Vector, optional): Vector line which to project dimension against.
|
||||
measurement_direction (VectorLike, optional): Vector line which to project the dimension
|
||||
against. Offset start point is the position of the start of border.
|
||||
Defaults to None.
|
||||
mode (Mode, optional): combination mode. Defaults to Mode.ADD.
|
||||
|
||||
|
|
@ -520,7 +521,7 @@ class ExtensionLine(BaseSketchObject):
|
|||
arrows: tuple[bool, bool] = (True, True),
|
||||
tolerance: float | tuple[float, float] | None = None,
|
||||
label_angle: bool = False,
|
||||
project_line: VectorLike | None = None,
|
||||
measurement_direction: VectorLike | None = None,
|
||||
mode: Mode = Mode.ADD,
|
||||
):
|
||||
# pylint: disable=too-many-locals
|
||||
|
|
@ -528,24 +529,41 @@ class ExtensionLine(BaseSketchObject):
|
|||
context = BuildSketch._get_context(self)
|
||||
if sketch is None and not (context is None or context.sketch is None):
|
||||
sketch = context.sketch
|
||||
if project_line is not None:
|
||||
raise NotImplementedError("project_line is currently unsupported")
|
||||
if offset == 0:
|
||||
raise ValueError("A dimension line should be used if offset is 0")
|
||||
|
||||
# Create a wire modelling the path of the dimension lines from a variety of input types
|
||||
object_to_measure = Draft._process_path(border)
|
||||
if object_to_measure.position_at(0) == object_to_measure.position_at(1):
|
||||
raise ValueError("Start and end points of border must be different.")
|
||||
|
||||
if measurement_direction is not None:
|
||||
if isinstance(measurement_direction, Iterable):
|
||||
measurement_direction = Vector(measurement_direction)
|
||||
measure_object_span = object_to_measure.position_at(
|
||||
1
|
||||
) - object_to_measure.position_at(0)
|
||||
extent_along_wire = measure_object_span.project_to_line(
|
||||
measurement_direction
|
||||
)
|
||||
object_to_dimension = Edge.make_line(
|
||||
object_to_measure.position_at(0),
|
||||
object_to_measure.position_at(0) + extent_along_wire,
|
||||
)
|
||||
else:
|
||||
object_to_dimension = object_to_measure
|
||||
|
||||
side_lut = {1: Side.RIGHT, -1: Side.LEFT}
|
||||
|
||||
if offset == 0:
|
||||
raise ValueError("A dimension line should be used if offset is 0")
|
||||
dimension_path = object_to_measure.offset_2d(
|
||||
dimension_path = object_to_dimension.offset_2d(
|
||||
distance=offset, side=side_lut[int(copysign(1, offset))], closed=False
|
||||
)
|
||||
dimension_label_str = (
|
||||
label
|
||||
if label is not None
|
||||
else draft._label_to_str(label, object_to_measure, label_angle, tolerance)
|
||||
else draft._label_to_str(label, object_to_dimension, label_angle, tolerance)
|
||||
)
|
||||
|
||||
extension_lines = [
|
||||
Edge.make_line(
|
||||
object_to_measure.position_at(e), dimension_path.position_at(e)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ from build123d import (
|
|||
Axis,
|
||||
BuildLine,
|
||||
BuildSketch,
|
||||
CenterOf,
|
||||
Color,
|
||||
Compound,
|
||||
Edge,
|
||||
Face,
|
||||
FontStyle,
|
||||
|
|
@ -50,6 +52,7 @@ from build123d import (
|
|||
Rectangle,
|
||||
Sketch,
|
||||
Unit,
|
||||
Vector,
|
||||
add,
|
||||
make_face,
|
||||
offset,
|
||||
|
|
@ -292,14 +295,150 @@ class ExtensionLineTestCase(unittest.TestCase):
|
|||
self.assertAlmostEqual(bbox.size.X, 30 + metric.line_width, 5)
|
||||
self.assertAlmostEqual(bbox.size.Y, 10, 5)
|
||||
|
||||
def test_not_implemented(self):
|
||||
shape, outer, inner = create_test_sketch()
|
||||
with self.assertRaises(NotImplementedError):
|
||||
def test_vectorlike_in_extension_function(self):
|
||||
diagonal_line = Edge.make_line((100, 100), (200, 200))
|
||||
ext = ExtensionLine(
|
||||
border=diagonal_line,
|
||||
offset=-10,
|
||||
draft=metric,
|
||||
measurement_direction=(0, 1, 0),
|
||||
)
|
||||
self.assertIsNotNone(ext)
|
||||
|
||||
def test_vertical_projection_with_dim_outside_shape(self):
|
||||
diagonal_line = Edge.make_line((100, 100), (200, 200))
|
||||
ext = ExtensionLine(
|
||||
border=diagonal_line,
|
||||
offset=-10,
|
||||
draft=metric,
|
||||
measurement_direction=Vector(0, 1, 0),
|
||||
)
|
||||
self.assertIsNotNone(ext)
|
||||
self.assertGreater(
|
||||
Compound(children=[diagonal_line, ext]).bounding_box().size.X,
|
||||
diagonal_line.bounding_box().size.X,
|
||||
) # dimension should be outside shape.
|
||||
self.assertEqual(
|
||||
diagonal_line.bounding_box().size.Y + 0.25, # plus line_width
|
||||
ext.bounding_box().size.Y,
|
||||
)
|
||||
self.assertEqual(
|
||||
diagonal_line.center(CenterOf.BOUNDING_BOX).Y,
|
||||
ext.center(CenterOf.BOUNDING_BOX).Y,
|
||||
)
|
||||
self.assertEqual(ext.dimension, 100)
|
||||
|
||||
def test_vertical_projection_with_dim_inside_shape(self):
|
||||
diagonal_line = Edge.make_line((100, 100), (200, 200))
|
||||
ext = ExtensionLine(
|
||||
border=diagonal_line,
|
||||
offset=10,
|
||||
draft=metric,
|
||||
measurement_direction=Vector(0, 1, 0),
|
||||
)
|
||||
self.assertIsNotNone(ext)
|
||||
self.assertEqual(
|
||||
Compound(children=[diagonal_line, ext]).bounding_box().size.Y,
|
||||
diagonal_line.bounding_box().size.Y + 0.25,
|
||||
) # plus line_width
|
||||
self.assertEqual(
|
||||
diagonal_line.center(CenterOf.BOUNDING_BOX).Y,
|
||||
ext.center(CenterOf.BOUNDING_BOX).Y,
|
||||
)
|
||||
self.assertEqual(ext.dimension, 100)
|
||||
|
||||
def test_vertical_projection_with_dim_otherside(self):
|
||||
diagonal_line = Edge.make_line((100, 100), (200, 200))
|
||||
x_size = diagonal_line.bounding_box().size.X
|
||||
ext = ExtensionLine(
|
||||
border=diagonal_line,
|
||||
offset=x_size + 10,
|
||||
draft=metric,
|
||||
measurement_direction=Vector(0, 1, 0),
|
||||
)
|
||||
self.assertIsNotNone(ext)
|
||||
self.assertGreater(
|
||||
Compound(children=[diagonal_line, ext]).bounding_box().size.Y,
|
||||
diagonal_line.bounding_box().size.Y,
|
||||
) # plus line_width
|
||||
self.assertEqual(
|
||||
diagonal_line.center(CenterOf.BOUNDING_BOX).Y,
|
||||
ext.center(CenterOf.BOUNDING_BOX).Y,
|
||||
)
|
||||
self.assertEqual(ext.dimension, 100)
|
||||
|
||||
def test_vertical_projection_with_vertical_line(self):
|
||||
diagonal_line = Edge.make_line((100, 100), (100, 200))
|
||||
ext = ExtensionLine(
|
||||
border=diagonal_line,
|
||||
offset=10,
|
||||
draft=metric,
|
||||
measurement_direction=Vector(0, 1, 0),
|
||||
)
|
||||
self.assertIsNotNone(ext)
|
||||
self.assertEqual(
|
||||
diagonal_line.center(CenterOf.BOUNDING_BOX).Y,
|
||||
ext.center(CenterOf.BOUNDING_BOX).Y,
|
||||
)
|
||||
self.assertEqual(ext.dimension, 100)
|
||||
|
||||
def test_horizontal_projection_with_dim_outside_shape(self):
|
||||
diagonal_line = Edge.make_line((100, 100), (200, 200))
|
||||
ext = ExtensionLine(
|
||||
border=diagonal_line,
|
||||
offset=10,
|
||||
draft=metric,
|
||||
measurement_direction=Vector(1, 0, 0),
|
||||
)
|
||||
self.assertIsNotNone(ext)
|
||||
self.assertGreater(
|
||||
Compound(children=[diagonal_line, ext]).bounding_box().size.Y,
|
||||
diagonal_line.bounding_box().size.Y,
|
||||
) # dimension should be outside shape.
|
||||
self.assertEqual(
|
||||
diagonal_line.bounding_box().size.X + 0.25, # plus line_width
|
||||
ext.bounding_box().size.X,
|
||||
)
|
||||
self.assertEqual(
|
||||
diagonal_line.center(CenterOf.BOUNDING_BOX).X,
|
||||
ext.center(CenterOf.BOUNDING_BOX).X,
|
||||
)
|
||||
self.assertEqual(ext.dimension, 100)
|
||||
|
||||
def test_angled_projection(self):
|
||||
diagonal_line = Edge.make_line((100, 100), (200, 200))
|
||||
ext = ExtensionLine(
|
||||
border=diagonal_line,
|
||||
offset=10,
|
||||
draft=metric,
|
||||
measurement_direction=Vector(1, 1, 0),
|
||||
)
|
||||
self.assertIsNotNone(ext)
|
||||
self.assertAlmostEqual(ext.dimension, 141.421, places=2)
|
||||
|
||||
def test_half_circle(self):
|
||||
half_circle = Edge.make_circle(50, start_angle=0, end_angle=180)
|
||||
ext = ExtensionLine(
|
||||
border=half_circle,
|
||||
offset=-10,
|
||||
draft=metric,
|
||||
measurement_direction=Vector(1, 0, 0),
|
||||
)
|
||||
self.assertIsNotNone(ext)
|
||||
self.assertEqual(ext.dimension, 100)
|
||||
self.assertGreater(
|
||||
Compound(children=[half_circle, ext]).bounding_box().size.Y,
|
||||
half_circle.bounding_box().size.Y,
|
||||
) # dimension should be outside shape.
|
||||
|
||||
def test_full_circle(self):
|
||||
half_circle = Edge.make_circle(50)
|
||||
with pytest.raises(ValueError):
|
||||
ExtensionLine(
|
||||
outer.edges().sort_by(Axis.Y)[0],
|
||||
border=half_circle,
|
||||
offset=10,
|
||||
project_line=(1, 0, 0),
|
||||
draft=metric,
|
||||
measurement_direction=Vector(0, 1, 0),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue