Skip to content

Commit

Permalink
Merge pull request #488 from jdegenstein/volume_2Dzero
Browse files Browse the repository at this point in the history
Return 0.0 volume for 1D and 2D shapes
  • Loading branch information
jdegenstein authored Jan 31, 2024
2 parents 2376774 + 31aaeb7 commit 8cd3567
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 7 deletions.
42 changes: 36 additions & 6 deletions src/build123d/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,11 @@ def is_closed(self) -> bool:
"""Are the start and end points equal?"""
return BRep_Tool.IsClosed_s(self.wrapped)

@property
def volume(self) -> float:
"""volume - the volume of this Edge or Wire, which is always zero"""
return 0.0

def position_at(
self, distance: float, position_mode: PositionMode = PositionMode.LENGTH
) -> Vector:
Expand Down Expand Up @@ -2244,12 +2249,6 @@ def area(self) -> float:

return properties.Mass()

@property
def volume(self) -> float:
"""volume - the volume of this Shape"""
# when density == 1, mass == volume
return Shape.compute_mass(self)

def _apply_transform(self, transformation: gp_Trsf) -> Self:
"""Private Apply Transform
Expand Down Expand Up @@ -3805,6 +3804,12 @@ def __repr__(self):
result = f"{self.__class__.__name__} at {id(self):#x}"
return result

@property
def volume(self) -> float:
"""volume - the volume of this Compound"""
# when density == 1, mass == volume
return sum(i.volume for i in [*self.get_type(Solid), *self.get_type(Shell)])

def center(self, center_of: CenterOf = CenterOf.MASS) -> Vector:
"""Return center of object
Expand Down Expand Up @@ -5053,6 +5058,11 @@ def length(self) -> float:
result = face_vertices[-1].X - face_vertices[0].X
return result

@property
def volume(self) -> float:
"""volume - the volume of this Face, which is always zero"""
return 0.0

@property
def width(self) -> float:
"""width of planar face"""
Expand Down Expand Up @@ -5823,6 +5833,15 @@ class Shell(Shape):

_dim = 2

@property
def volume(self) -> float:
"""volume - the volume of this Shell if manifold, otherwise zero"""
# when density == 1, mass == volume
if self.is_manifold:
return Solid.make_solid(self).volume
else:
return 0.0

@classmethod
def make_shell(cls, faces: Iterable[Face]) -> Shell:
"""Create a Shell from provided faces"""
Expand All @@ -5848,6 +5867,12 @@ class Solid(Mixin3D, Shape):

_dim = 3

@property
def volume(self) -> float:
"""volume - the volume of this Solid"""
# when density == 1, mass == volume
return Shape.compute_mass(self)

@classmethod
def make_solid(cls, shell: Shell) -> Solid:
"""Create a Solid object from the surface shell"""
Expand Down Expand Up @@ -6590,6 +6615,11 @@ def __init__(self, *args, **kwargs):
super().__init__(ocp_vx)
self.X, self.Y, self.Z = self.to_tuple()

@property
def volume(self) -> float:
"""volume - the volume of this Vertex, which is always zero"""
return 0.0

def to_tuple(self) -> tuple[float, float, float]:
"""Return vertex as three tuple of floats"""
geom_point = BRep_Tool.Pnt_s(self.wrapped)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_build_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def test_add_to_part(self):
]
)
)
self.assertEqual(test.part.volume, 1125, 5)
self.assertAlmostEqual(test.part.volume, 1125, 5)
with BuildPart() as test:
add(Compound.make_compound([Edge.make_line((0, 0), (1, 1))]))
self.assertEqual(len(test.pending_edges), 1)
Expand Down
44 changes: 44 additions & 0 deletions tests/test_direct_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,23 @@ def test_triad(self):
self.assertLess(bbox.size.Z, 12.5)
self.assertEqual(triad.volume, 0)

def test_volume(self):
e = Edge.make_line((0, 0), (1, 1))
self.assertAlmostEqual(e.volume, 0, 5)

f = Face.make_rect(1, 1)
self.assertAlmostEqual(f.volume, 0, 5)

b = Solid.make_box(1, 1, 1)
self.assertAlmostEqual(b.volume, 1, 5)

bb = Box(1, 1, 1)
self.assertAlmostEqual(bb.volume, 1, 5)

c = Compound(children=[e, f, b, bb, b.translate((0, 5, 0))])
self.assertAlmostEqual(c.volume, 3, 5)
# N.B. b and bb overlap but still add to Compound volume


class TestEdge(DirectApiTestCase):
def test_close(self):
Expand Down Expand Up @@ -1024,6 +1041,10 @@ def test_center(self):
5,
)

def test_face_volume(self):
rect = Face.make_rect(1, 1)
self.assertAlmostEqual(rect.volume, 0, 5)

def test_chamfer_2d(self):
test_face = Face.make_rect(10, 10)
test_face = test_face.chamfer_2d(
Expand Down Expand Up @@ -1984,6 +2005,14 @@ def test_common_plane(self):
self.assertAlmostEqual(common.z_dir.Y, 0, 5)
self.assertAlmostEqual(common.z_dir.Z, 0, 5)

def test_edge_volume(self):
edge = Edge.make_line((0,0),(1,1))
self.assertAlmostEqual(edge.volume, 0, 5)

def test_wire_volume(self):
wire = Wire.make_rect(1,1)
self.assertAlmostEqual(wire.volume, 0, 5)


class TestMixin3D(DirectApiTestCase):
"""Test that 3D add ins"""
Expand Down Expand Up @@ -3040,6 +3069,17 @@ def test_center(self):
box_shell = Shell.make_shell(box_faces)
self.assertVectorAlmostEquals(box_shell.center(), (0.5, 0.5, 0.5), 5)

def test_manifold_shell_volume(self):
box_faces = Solid.make_box(1, 1, 1).faces()
box_shell = Shell.make_shell(box_faces)
self.assertAlmostEqual(box_shell.volume, 1, 5)

def test_nonmanifold_shell_volume(self):
box_faces = Solid.make_box(1, 1, 1).faces()
nm_shell = Shell.make_shell(box_faces)
nm_shell -= nm_shell.faces()[0]
self.assertAlmostEqual(nm_shell.volume, 0, 5)


class TestSolid(DirectApiTestCase):
def test_make_solid(self):
Expand Down Expand Up @@ -3412,6 +3452,10 @@ def test_basic_vertex(self):
self.assertVectorAlmostEquals(Vector(Vertex((7,))), (7, 0, 0), 7)
self.assertVectorAlmostEquals(Vector(Vertex((8, 9))), (8, 9, 0), 7)

def test_vertex_volume(self):
v = Vertex(1, 1, 1)
self.assertAlmostEqual(v.volume, 0, 5)

def test_vertex_add(self):
test_vertex = Vertex(0, 0, 0)
self.assertVectorAlmostEquals(
Expand Down

0 comments on commit 8cd3567

Please sign in to comment.