Skip to content

Commit

Permalink
Added radius method to Mixin1D
Browse files Browse the repository at this point in the history
  • Loading branch information
marcus7070 committed Nov 18, 2020
1 parent 5eebcd5 commit 3136ede
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
20 changes: 20 additions & 0 deletions cadquery/occ_impl/shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@
GeomFill_CorrectedFrenet,
GeomFill_TrihedronLaw,
)

# for catching exceptions
from OCP.Standard import Standard_NoSuchObject

from math import pi, sqrt
import warnings

Expand Down Expand Up @@ -1053,6 +1057,22 @@ def Length(self: Mixin1DProtocol) -> float:

return GCPnts_AbscissaPoint.Length_s(self._geomAdaptor())

def radius(self: Mixin1DProtocol) -> float:
"""
Calculate the radius.
Note that when applied to a Wire, the radius is simply the radius of the first edge.
:return: radius
:raises ValueError: if kernel can not reduce the shape to a circular edge
"""
geom = self._geomAdaptor()
try:
circ = geom.Circle()
except Standard_NoSuchObject as e:
raise ValueError("Shape could not be reduced to a circle") from e
return circ.Radius()

def IsClosed(self: Mixin1DProtocol) -> bool:

return BRep_Tool.IsClosed_s(self.wrapped)
Expand Down
62 changes: 62 additions & 0 deletions tests/test_cad_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,68 @@ def testLocation(self):
== loc3.wrapped.Transformation().TranslationPart().Z()
)

def testEdgeWrapperRadius(self):

# get a radius from a simple circle
e0 = Edge.makeCircle(2.4)
self.assertAlmostEqual(e0.radius(), 2.4)

# radius of an arc
e1 = Edge.makeCircle(1.8, pnt=(5, 6, 7), dir=(1, 1, 1), angle1=20, angle2=30)
self.assertAlmostEqual(e1.radius(), 1.8)

# test value errors
e2 = Edge.makeEllipse(10, 20)
with self.assertRaises(ValueError):
e2.radius()

# radius from a wire
w0 = Wire.makeCircle(10, Vector(1, 2, 3), (-1, 0, 1))
self.assertAlmostEqual(w0.radius(), 10)

# radius from a wire with multiple edges
rad = 2.3
pnt = (7, 8, 9)
direction = (1, 0.5, 0.1)
w1 = Wire.assembleEdges(
[
Edge.makeCircle(rad, pnt, direction, 0, 10),
Edge.makeCircle(rad, pnt, direction, 10, 25),
Edge.makeCircle(rad, pnt, direction, 25, 230),
]
)
self.assertAlmostEqual(w1.radius(), rad)

# test value error from wire
w2 = Wire.makePolygon([Vector(-1, 0, 0), Vector(0, 1, 0), Vector(1, -1, 0),])
with self.assertRaises(ValueError):
w2.radius()

# (I think) the radius of a wire is the radius of it's first edge.
# Since this is stated in the docstring better make sure.
no_rad = Wire.assembleEdges(
[
Edge.makeLine(Vector(0, 0, 0), Vector(0, 1, 0)),
Edge.makeCircle(1.0, angle1=90, angle2=270),
]
)
with self.assertRaises(ValueError):
no_rad.radius()
yes_rad = Wire.assembleEdges(
[
Edge.makeCircle(1.0, angle1=90, angle2=270),
Edge.makeLine(Vector(0, -1, 0), Vector(0, 1, 0)),
]
)
self.assertAlmostEqual(yes_rad.radius(), 1.0)
many_rad = Wire.assembleEdges(
[
Edge.makeCircle(1.0, angle1=0, angle2=180),
Edge.makeCircle(3.0, pnt=Vector(2, 0, 0), angle1=180, angle2=359),
]
)
self.assertAlmostEqual(many_rad.radius(), 1.0)


if __name__ == "__main__":
unittest.main()

0 comments on commit 3136ede

Please sign in to comment.