mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -08:00
Moved edge/point ordering to make_constrained_arcs
Some checks are pending
benchmarks / benchmarks (macos-13, 3.12) (push) Waiting to run
benchmarks / benchmarks (macos-14, 3.12) (push) Waiting to run
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Waiting to run
benchmarks / benchmarks (windows-latest, 3.12) (push) Waiting to run
Upload coverage reports to Codecov / run (push) Waiting to run
pylint / lint (3.10) (push) Waiting to run
Run type checker / typecheck (3.10) (push) Waiting to run
Run type checker / typecheck (3.13) (push) Waiting to run
Wheel building and publishing / Build wheel on ubuntu-latest (push) Waiting to run
Wheel building and publishing / upload_pypi (push) Blocked by required conditions
tests / tests (macos-13, 3.10) (push) Waiting to run
tests / tests (macos-13, 3.13) (push) Waiting to run
tests / tests (macos-14, 3.10) (push) Waiting to run
tests / tests (macos-14, 3.13) (push) Waiting to run
tests / tests (ubuntu-latest, 3.10) (push) Waiting to run
tests / tests (ubuntu-latest, 3.13) (push) Waiting to run
tests / tests (windows-latest, 3.10) (push) Waiting to run
tests / tests (windows-latest, 3.13) (push) Waiting to run
Some checks are pending
benchmarks / benchmarks (macos-13, 3.12) (push) Waiting to run
benchmarks / benchmarks (macos-14, 3.12) (push) Waiting to run
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Waiting to run
benchmarks / benchmarks (windows-latest, 3.12) (push) Waiting to run
Upload coverage reports to Codecov / run (push) Waiting to run
pylint / lint (3.10) (push) Waiting to run
Run type checker / typecheck (3.10) (push) Waiting to run
Run type checker / typecheck (3.13) (push) Waiting to run
Wheel building and publishing / Build wheel on ubuntu-latest (push) Waiting to run
Wheel building and publishing / upload_pypi (push) Blocked by required conditions
tests / tests (macos-13, 3.10) (push) Waiting to run
tests / tests (macos-13, 3.13) (push) Waiting to run
tests / tests (macos-14, 3.10) (push) Waiting to run
tests / tests (macos-14, 3.13) (push) Waiting to run
tests / tests (ubuntu-latest, 3.10) (push) Waiting to run
tests / tests (ubuntu-latest, 3.13) (push) Waiting to run
tests / tests (windows-latest, 3.10) (push) Waiting to run
tests / tests (windows-latest, 3.13) (push) Waiting to run
This commit is contained in:
parent
76ec798d21
commit
3b11f40d9d
2 changed files with 43 additions and 49 deletions
|
|
@ -264,11 +264,11 @@ def _make_2tan_rad_arcs(
|
|||
if isinstance(object_1, tuple):
|
||||
object_one, object_one_constraint = object_1
|
||||
else:
|
||||
object_one, object_one_constraint = object_1, None
|
||||
object_one, object_one_constraint = object_1, PositionConstraint.UNQUALIFIED
|
||||
if isinstance(object_2, tuple):
|
||||
object_two, object_two_constraint = object_2
|
||||
else:
|
||||
object_two, object_two_constraint = object_2, None
|
||||
object_two, object_two_constraint = object_2, PositionConstraint.UNQUALIFIED
|
||||
|
||||
# ---------------------------
|
||||
# Build inputs and GCC
|
||||
|
|
@ -280,10 +280,6 @@ def _make_2tan_rad_arcs(
|
|||
object_two, object_two_constraint
|
||||
)
|
||||
|
||||
# Put the Edge arg first when exactly one is an Edge (improves robustness)
|
||||
if is_edge1 ^ is_edge2:
|
||||
q_o1, q_o2 = (q_o1, q_o2) if is_edge1 else (q_o2, q_o1)
|
||||
|
||||
gcc = Geom2dGcc_Circ2d2TanRad(q_o1, q_o2, radius, TOLERANCE)
|
||||
if not gcc.IsDone() or gcc.NbSolutions() == 0:
|
||||
raise RuntimeError("Unable to find a tangent arc")
|
||||
|
|
@ -349,25 +345,18 @@ def _make_2tan_on_arcs(
|
|||
|
||||
Notes
|
||||
-----
|
||||
- `center_on` is treated as a **center locus** (not a tangency target). For a line
|
||||
locus this uses Geom2dGcc_Circ2d2TanOn; for other 2D curves it uses the *Geo variant*.
|
||||
- A point is NOT a valid center locus for the 2TanOn solver; use the TanCen variant
|
||||
(fixed center) for that case.
|
||||
- `center_on` is treated as a **center locus** (not a tangency target).
|
||||
"""
|
||||
|
||||
# Unpack optional qualifiers on the two tangency args
|
||||
object_one_constraint = PositionConstraint.UNQUALIFIED
|
||||
object_two_constraint = PositionConstraint.UNQUALIFIED
|
||||
|
||||
if isinstance(object_1, tuple):
|
||||
object_one, object_one_constraint = object_1
|
||||
else:
|
||||
object_one = object_1
|
||||
object_one, object_one_constraint = object_1, PositionConstraint.UNQUALIFIED
|
||||
|
||||
if isinstance(object_2, tuple):
|
||||
object_two, object_two_constraint = object_2
|
||||
else:
|
||||
object_two = object_2
|
||||
object_two, object_two_constraint = object_2, PositionConstraint.UNQUALIFIED
|
||||
|
||||
# ---------------------------
|
||||
# Build tangency inputs
|
||||
|
|
@ -379,17 +368,6 @@ def _make_2tan_on_arcs(
|
|||
object_two, object_two_constraint
|
||||
)
|
||||
|
||||
# Prefer "edge-first" ordering when exactly one arg is an Edge
|
||||
if is_edge1 ^ is_edge2:
|
||||
q_o1, q_o2 = (q_o1, q_o2) if is_edge1 else (q_o2, q_o1)
|
||||
h_e1, h_e2 = (h_e1, h_e2) if is_edge1 else (h_e2, h_e1)
|
||||
e1_first, e1_last, e2_first, e2_last = (
|
||||
(e1_first, e1_last, e2_first, e2_last)
|
||||
if is_edge1
|
||||
else (e2_first, e2_last, e1_first, e1_last)
|
||||
)
|
||||
is_edge1, is_edge2 = (True, False) if is_edge1 else (False, True)
|
||||
|
||||
# ---------------------------
|
||||
# Build center locus ("On") input
|
||||
# ---------------------------
|
||||
|
|
@ -404,7 +382,10 @@ def _make_2tan_on_arcs(
|
|||
guesses.append((e2_last - e2_first) / 2 + e2_first)
|
||||
guesses.append((on_last - on_first) / 2 + on_first)
|
||||
|
||||
if is_edge1 or is_edge2:
|
||||
gcc = Geom2dGcc_Circ2d2TanOn(q_o1, q_o2, adapt_on, TOLERANCE, *guesses)
|
||||
else:
|
||||
gcc = Geom2dGcc_Circ2d2TanOn(q_o1, q_o2, adapt_on, TOLERANCE)
|
||||
|
||||
if not gcc.IsDone() or gcc.NbSolutions() == 0:
|
||||
raise RuntimeError("Unable to find a tangent arc with center_on constraint")
|
||||
|
|
@ -510,10 +491,15 @@ def _make_3tan_arcs(
|
|||
q_o2, h_e2, e2_first, e2_last, is_edge2 = _as_gcc_arg(object_two, obj2_qual)
|
||||
q_o3, h_e3, e3_first, e3_last, is_edge3 = _as_gcc_arg(object_three, obj3_qual)
|
||||
|
||||
guesses = [
|
||||
(l - f) / 2 + f
|
||||
for f, l in [(e1_first, e1_last), (e2_first, e2_last), (e3_first, e3_last)]
|
||||
]
|
||||
# Provide initial guess parameters for all of the lines
|
||||
guesses = []
|
||||
if is_edge1:
|
||||
guesses.append((e1_last - e1_first) / 2 + e1_first)
|
||||
if is_edge2:
|
||||
guesses.append((e2_last - e2_first) / 2 + e2_first)
|
||||
if is_edge3:
|
||||
guesses.append((e3_last - e3_first) / 2 + e3_first)
|
||||
|
||||
# For 3Tan we keep the user-given order so the arc endpoints remain (arg1,arg2)
|
||||
gcc = Geom2dGcc_Circ2d3Tan(q_o1, q_o2, q_o3, TOLERANCE, *guesses)
|
||||
if not gcc.IsDone() or gcc.NbSolutions() == 0:
|
||||
|
|
|
|||
|
|
@ -1588,8 +1588,8 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
@classmethod
|
||||
def make_constrained_arcs(
|
||||
cls,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_two: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
tangency_two: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
*,
|
||||
radius: float,
|
||||
sagitta_constraint: LengthConstraint = LengthConstraint.SHORT,
|
||||
|
|
@ -1598,8 +1598,8 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
Create all planar circular arcs of a given radius that are tangent/contacting
|
||||
the two provided objects on the XY plane.
|
||||
Args:
|
||||
tangency_one (tuple[Edge, PositionConstraint] | Vertex | VectorLike):
|
||||
tangency_two (tuple[Edge, PositionConstraint] | Vertex | VectorLike):
|
||||
tangency_one (tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike):
|
||||
tangency_two (tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike):
|
||||
Geometric entities to be contacted/touched by the circle(s)
|
||||
radius (float): arc radius
|
||||
sagitta_constraint (LengthConstraint, optional): returned arc selector
|
||||
|
|
@ -1614,8 +1614,8 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
@classmethod
|
||||
def make_constrained_arcs(
|
||||
cls,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_two: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
tangency_two: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
*,
|
||||
center_on: Edge,
|
||||
sagitta_constraint: LengthConstraint = LengthConstraint.SHORT,
|
||||
|
|
@ -1625,8 +1625,8 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
CENTER lies on a given locus (line/circle/curve) on the XY plane.
|
||||
|
||||
Args:
|
||||
tangency_one (tuple[Edge, PositionConstraint] | Vertex | VectorLike):
|
||||
tangency_two (tuple[Edge, PositionConstraint] | Vertex | VectorLike):
|
||||
tangency_one (tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike):
|
||||
tangency_two (tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike):
|
||||
Geometric entities to be contacted/touched by the circle(s)
|
||||
center_on (Edge): center must lie on this edge
|
||||
sagitta_constraint (LengthConstraint, optional): returned arc selector
|
||||
|
|
@ -1641,9 +1641,9 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
@classmethod
|
||||
def make_constrained_arcs(
|
||||
cls,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_two: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_three: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
tangency_two: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
tangency_three: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
*,
|
||||
sagitta_constraint: LengthConstraint = LengthConstraint.SHORT,
|
||||
) -> ShapeList[Edge]:
|
||||
|
|
@ -1651,9 +1651,9 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
Create planar circular arc(s) on XY tangent to three provided objects.
|
||||
|
||||
Args:
|
||||
tangency_one (tuple[Edge, PositionConstraint] | Vertex | VectorLike):
|
||||
tangency_two (tuple[Edge, PositionConstraint] | Vertex | VectorLike):
|
||||
tangency_three (tuple[Edge, PositionConstraint] | Vertex | VectorLike):
|
||||
tangency_one (tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike):
|
||||
tangency_two (tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike):
|
||||
tangency_three (tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike):
|
||||
Geometric entities to be contacted/touched by the circle(s)
|
||||
sagitta_constraint (LengthConstraint, optional): returned arc selector
|
||||
(i.e. either the short, long or both arcs). Defaults to
|
||||
|
|
@ -1667,7 +1667,7 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
@classmethod
|
||||
def make_constrained_arcs(
|
||||
cls,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
*,
|
||||
center: VectorLike,
|
||||
) -> ShapeList[Edge]:
|
||||
|
|
@ -1677,7 +1677,7 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
a single object.
|
||||
|
||||
Args:
|
||||
tangency_one (tuple[Edge, PositionConstraint] | Vertex | VectorLike):
|
||||
tangency_one (tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike):
|
||||
Geometric entity to be contacted/touched by the circle(s)
|
||||
center (VectorLike): center position
|
||||
|
||||
|
|
@ -1689,7 +1689,7 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
@classmethod
|
||||
def make_constrained_arcs(
|
||||
cls,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Vertex | VectorLike,
|
||||
tangency_one: tuple[Edge, PositionConstraint] | Edge | Vertex | VectorLike,
|
||||
*,
|
||||
radius: float,
|
||||
center_on: Edge,
|
||||
|
|
@ -1742,6 +1742,14 @@ class Edge(Mixin1D, Shape[TopoDS_Edge]):
|
|||
tangencies = [
|
||||
t for t in (tangency_one, tangency_two, tangency_three) if t is not None
|
||||
]
|
||||
|
||||
# Sort the tangency inputs so points are always last
|
||||
tangent_tuples = [t if isinstance(t, tuple) else (t, None) for t in tangencies]
|
||||
tangent_tuples = sorted(
|
||||
tangent_tuples, key=lambda t: not issubclass(type(t[0]), Edge)
|
||||
)
|
||||
tangencies = [t[0] if t[1] is None else t for t in tangent_tuples]
|
||||
|
||||
tan_count = len(tangencies)
|
||||
if not (1 <= tan_count <= 3):
|
||||
raise TypeError("Provide 1 to 3 tangency targets.")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue