diff --git a/CHANGELOG.md b/CHANGELOG.md index 09b229141b54..88a4ecdfeb29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +* Changed the `__str__` of `compas.geometry.Frame`, `compas.geometry.Plane`, `compas.geometry.Polygon`, `compas.geometry.Polyhedron`, `compas.geometry.Quaternion` to use a limited number of decimals (determined by `Tolerance.PRECISION`). Note: `__repr__` will instead maintain full precision. +* Changed the `__str__` of `compas.geometry.Pointcloud` to print total number of points instead of the long list of points. Note: `__repr__` will still print all the points with full precision. +* Fixed bug in `Pointcloud.from_box()`. + ### Removed diff --git a/src/compas/colors/color.py b/src/compas/colors/color.py index ab184f377776..7c90d3dd40d1 100644 --- a/src/compas/colors/color.py +++ b/src/compas/colors/color.py @@ -12,6 +12,7 @@ from compas.colors.html_colors import HTML_TO_RGB255 from compas.data import Data +from compas.tolerance import TOL BASE16 = "0123456789abcdef" @@ -172,7 +173,16 @@ def __init__(self, red, green, blue, alpha=1.0, name=None): self.a = alpha def __repr__(self): - return "{0}({1}, {2}, {3}, alpha={4})".format(type(self).__name__, self.r, self.g, self.b, self.a) + return "{0}(red={1}, green={2}, blue={3}, alpha={4})".format(type(self).__name__, self.r, self.g, self.b, self.a) + + def __str__(self): + return "{0}(red={1}, green={2}, blue={3}, alpha={4})".format( + type(self).__name__, + TOL.format_number(self.r), + TOL.format_number(self.g), + TOL.format_number(self.b), + TOL.format_number(self.a), + ) def __getitem__(self, key): if key == 0: diff --git a/src/compas/geometry/frame.py b/src/compas/geometry/frame.py index 50adc0e19f80..6f2d703990c0 100644 --- a/src/compas/geometry/frame.py +++ b/src/compas/geometry/frame.py @@ -108,6 +108,14 @@ def __repr__(self): self.yaxis, ) + def __str__(self): + return "{0}(point={1}, xaxis={2}, yaxis={3})".format( + type(self).__name__, + str(self.point), + str(self.xaxis), + str(self.yaxis), + ) + def __len__(self): return 3 diff --git a/src/compas/geometry/plane.py b/src/compas/geometry/plane.py index 3a05abc0f7f8..36dc74a7fae3 100644 --- a/src/compas/geometry/plane.py +++ b/src/compas/geometry/plane.py @@ -76,6 +76,13 @@ def __repr__(self): self.normal, ) + def __str__(self): + return "{0}(point={1}, normal={2})".format( + type(self).__name__, + str(self.point), + str(self.normal), + ) + def __len__(self): return 2 diff --git a/src/compas/geometry/pointcloud.py b/src/compas/geometry/pointcloud.py index ed1a25c2f556..db971cfaf5b7 100644 --- a/src/compas/geometry/pointcloud.py +++ b/src/compas/geometry/pointcloud.py @@ -56,6 +56,9 @@ def __init__(self, points, name=None): def __repr__(self): return "{0}(points={1!r})".format(type(self).__name__, self.points) + def __str__(self): + return "{0}(len(points)={1})".format(type(self).__name__, len(self.points)) + def __len__(self): return len(self.points) @@ -244,11 +247,9 @@ def from_box(cls, box, n): True """ - points = box.points - x, y, z = zip(*points) - xmin, xmax = min(x), max(x) - ymin, ymax = min(y), max(y) - zmin, zmax = min(z), max(z) + xmin, xmax = box.xmin, box.xmax + ymin, ymax = box.ymin, box.ymax + zmin, zmax = box.zmin, box.zmax x = [uniform(xmin, xmax) for i in range(n)] y = [uniform(ymin, ymax) for i in range(n)] z = [uniform(zmin, zmax) for i in range(n)] diff --git a/src/compas/geometry/polygon.py b/src/compas/geometry/polygon.py index e7cf8e245801..466abb67baea 100644 --- a/src/compas/geometry/polygon.py +++ b/src/compas/geometry/polygon.py @@ -104,6 +104,9 @@ def __init__(self, points, name=None): def __repr__(self): return "{0}(points={1!r})".format(type(self).__name__, self.points) + def __str__(self): + return "{0}(points=[{1}])".format(type(self).__name__, ", ".join([str(point) for point in self.points])) + def __len__(self): return len(self.points) diff --git a/src/compas/geometry/polyhedron.py b/src/compas/geometry/polyhedron.py index 62a14b0fe3b7..08dd7a21ec76 100644 --- a/src/compas/geometry/polyhedron.py +++ b/src/compas/geometry/polyhedron.py @@ -9,6 +9,7 @@ from compas.geometry import Polygon from compas.geometry import transform_points from compas.itertools import pairwise +from compas.tolerance import TOL from .geometry import Geometry @@ -216,6 +217,13 @@ def __repr__(self): self.faces, ) + def __str__(self): + return "{0}(vertices={1}, faces={2})".format( + type(self).__name__, + [[TOL.format_number(num) for num in vertice] for vertice in self.vertices], + self.faces, + ) + def __len__(self): return 2 diff --git a/src/compas/geometry/quaternion.py b/src/compas/geometry/quaternion.py index 18ed9b410f70..19d5d452003c 100644 --- a/src/compas/geometry/quaternion.py +++ b/src/compas/geometry/quaternion.py @@ -148,6 +148,15 @@ def __init__(self, w, x, y, z, name=None): def __repr__(self): return "{0}({1}, {2}, {3}, {4})".format(type(self).__name__, self.w, self.x, self.y, self.z) + def __str__(self): + return "{0}({1}, {2}, {3}, {4})".format( + type(self).__name__, + TOL.format_number(self.w), + TOL.format_number(self.x), + TOL.format_number(self.y), + TOL.format_number(self.z), + ) + def __eq__(self, other, tol=None): if not hasattr(other, "__iter__") or not hasattr(other, "__len__") or len(self) != len(other): return False diff --git a/tests/compas/geometry/test_pointcloud.py b/tests/compas/geometry/test_pointcloud.py index d77101aaecae..d0e2991f09fa 100644 --- a/tests/compas/geometry/test_pointcloud.py +++ b/tests/compas/geometry/test_pointcloud.py @@ -2,6 +2,7 @@ import json import compas from random import random, shuffle +from compas.geometry import Box from compas.geometry import Point # noqa: F401 from compas.geometry import Pointcloud @@ -54,3 +55,13 @@ def test_pointcloud__neq__(): assert a != b b = Pointcloud.from_bounds(10, 10, 10, 10) assert a != b + + +def test_pointcloud_from_box(): + x_size = 10.0 + y_size = 5.0 + z_size = 3.0 + box = Box.from_width_height_depth(x_size, z_size, y_size) + pointcloud = Pointcloud.from_box(box, 100) + assert len(pointcloud.points) == 100 + assert all((-x_size / 2 < x < x_size / 2) and (-y_size / 2 < y < y_size / 2) and (-z_size / 2 < z < z_size / 2) for x, y, z in pointcloud.points) diff --git a/tests/compas/geometry/test_polyhedron.py b/tests/compas/geometry/test_polyhedron.py new file mode 100644 index 000000000000..18d098b88f81 --- /dev/null +++ b/tests/compas/geometry/test_polyhedron.py @@ -0,0 +1,22 @@ +import pytest +import json +import compas +from random import random +from compas.geometry import Point +from compas.geometry import Polyhedron +from compas.itertools import pairwise + + +def test_polyhedron(): + vertices = [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]] + faces = [[0, 1, 2, 3]] + name = "Test Polyhedron" + polyhedron = Polyhedron(vertices, faces, name) + + assert polyhedron.vertices == vertices + assert polyhedron.faces == faces + assert polyhedron.name == name + assert polyhedron.points == vertices + assert polyhedron.lines == [(a, b) for a, b in pairwise(vertices + vertices[:1])] + assert polyhedron.points[0] == vertices[0] + assert polyhedron.points[-1] != polyhedron.points[0] diff --git a/tests/compas/geometry/test_quaternion.py b/tests/compas/geometry/test_quaternion.py index 8703e416e6a9..70ccbabc09e1 100644 --- a/tests/compas/geometry/test_quaternion.py +++ b/tests/compas/geometry/test_quaternion.py @@ -149,4 +149,5 @@ def test_quaternion_other_methods(): quaternion = Quaternion.from_frame(Frame.worldZX()) canonized = quaternion.canonized() - assert str(canonized) == str("Quaternion(0.5, -0.5, -0.5, -0.5)") + value = TOL.format_number(0.5) + assert str(canonized) == str("Quaternion(" + value + ", -" + value + ", -" + value + ", -" + value + ")")