Skip to content

Commit 7d3e626

Browse files
authored
Merge pull request #642 from compas-dev/compas-rhino-artists
Update compas_rhino artists
2 parents d8df626 + 8acaf2b commit 7d3e626

22 files changed

+779
-314
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
* Added `compas_rhino.artists.BoxArtist.draw_collection`.
13+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.CapsuleArtist.draw`.
14+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.ConeArtist.draw`.
15+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.CylinderArtist.draw`.
16+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.PolyhedronArtist.draw`.
17+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.SphereArtist.draw`.
18+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.TorusArtist.draw`.
19+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.PolygonArtist.draw`.
20+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.PolylineArtist.draw`.
21+
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.VectorArtist.draw`.
22+
1223
### Changed
1324

25+
* Changed implementation of `compas_rhino.artists.BoxArtist.draw`.
26+
* Fixed bug in `compas.geometry.Capsule`.
27+
* Fixed bug in `compas.geometry.Cone`.
28+
* Changed `compas_rhino.draw_mesh` to support Ngons if available.
29+
* Fixed bug in polyhedron data.
30+
1431
### Removed
1532

33+
* Removed `compas_rhino.artists.PointArtist.draw_collection`.
34+
* Removed `compas_rhino.artists.CircleArtist.draw_collection`.
35+
* Removed `compas_rhino.artists.LineArtist.draw_collection`.
1636

1737
## [0.16.9] 2020-10-21
1838

src/compas/geometry/__init__.py

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@
66
.. currentmodule:: compas.geometry
77
88
9+
Primitives
10+
==========
11+
912
Base Classes
10-
============
13+
------------
1114
1215
.. autosummary::
1316
:toctree: generated/
1417
:nosignatures:
1518
1619
Primitive
17-
Shape
1820
19-
20-
Primitives
21-
==========
21+
Classes
22+
-------
2223
2324
.. autosummary::
2425
:toctree: generated/
@@ -36,9 +37,59 @@
3637
Vector
3738
3839
40+
The following representations of primitives can be used
41+
interchangeably as input in methods and functions.
42+
The representations using native Python objects also correspond to the required input
43+
parameters of the default constructor functions of the corresponding COMPAS objects.
44+
45+
============ ============================== ============
46+
Object COMPAS Python
47+
------------ ------------------------------ ------------
48+
point Point(float, float, float) [float, float, float]
49+
vector Vector(float, float, float) [float, float, float]
50+
line Line(point, point) [[float, float, float], [float, float, float]]
51+
plane Plane(point, vector) [[float, float, float], [float, float, float]]
52+
circle Circle(plane, float) [[[float, float, float], [float, float, float]], float]
53+
polygon Polygon(points) [[float, float, float], ... [float, float, float]]
54+
polyline Polyline(points) [[float, float, float], ... [float, float, float]]
55+
ellipse Ellipse(plane, float, float) [[[float, float, float], [float, float, float]], float, float]
56+
frame Frame(point, vector, vector) [[float, float, float], [float, float, float], [float, float, float]]
57+
============ ============================== ============
58+
59+
COMPAS primitives also support indexing, assignment, and iteration according to the above
60+
equivalency.
61+
62+
::
63+
64+
>>> a = Point(0, 0, 0)
65+
>>> x, y, z = a
66+
>>> x = a[0]
67+
>>> a[0] = 0
68+
69+
::
70+
71+
>>> plane = Plane(Point(0, 0, 0), Vector(0, 0, 1))
72+
>>> a, n = plane
73+
>>> x, y, z = n
74+
>>> plane[0] = Point(1, 0, 0)
75+
76+
3977
Shapes
4078
======
4179
80+
Base Classes
81+
------------
82+
83+
.. autosummary::
84+
:toctree: generated/
85+
:nosignatures:
86+
87+
Shape
88+
89+
90+
Classes
91+
-------
92+
4293
.. autosummary::
4394
:toctree: generated/
4495
:nosignatures:
@@ -449,6 +500,17 @@
449500
450501
icp_numpy
451502
503+
504+
Base Classes
505+
============
506+
507+
.. autosummary::
508+
:toctree: generated/
509+
:nosignatures:
510+
511+
Primitive
512+
Shape
513+
452514
"""
453515
from __future__ import absolute_import
454516
from __future__ import division

src/compas/geometry/shapes/capsule.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def line(self):
8686

8787
@line.setter
8888
def line(self, line):
89-
self._line = line
89+
self._line = Line(*line)
9090

9191
@property
9292
def start(self):

src/compas/geometry/shapes/cone.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
from math import sin
88
from math import sqrt
99

10+
from compas.utilities import pairwise
11+
1012
from compas.geometry import matrix_from_frame
1113
from compas.geometry import transform_points
1214
from compas.geometry import Circle
1315
from compas.geometry import Frame
1416
from compas.geometry import Plane
1517

16-
from compas.geometry.shapes import Shape
18+
from ._shape import Shape
1719

1820

1921
__all__ = ['Cone']
@@ -96,7 +98,7 @@ def circle(self):
9698

9799
@circle.setter
98100
def circle(self, circle):
99-
self._circle = circle
101+
self._circle = Circle(circle[0], circle[1])
100102

101103
@property
102104
def radius(self):
@@ -228,25 +230,26 @@ def to_vertices_and_faces(self, u=10):
228230
if u < 3:
229231
raise ValueError('The value for u should be u > 3.')
230232

231-
vertices = []
233+
vertices = [[0, 0, 0]]
232234
a = 2 * pi / u
233235
for i in range(u):
234236
x = self.circle.radius * cos(i * a)
235237
y = self.circle.radius * sin(i * a)
236238
vertices.append([x, y, 0])
237239
vertices.append([0, 0, self.height])
238240

239-
# transform vertices to cylinder's plane
240241
frame = Frame.from_plane(self.circle.plane)
241242
M = matrix_from_frame(frame)
242243
vertices = transform_points(vertices, M)
243244

244245
faces = []
246+
first = 0
245247
last = len(vertices) - 1
246-
for i in range(u):
247-
faces.append([i, (i + 1) % u, last])
248-
faces.append([i for i in range(u)])
249-
faces[-1].reverse()
248+
for i, j in pairwise(range(1, last)):
249+
faces.append([i, j, last])
250+
faces.append([j, i, first])
251+
faces.append([last - 1, 1, last])
252+
faces.append([1, last - 1, first])
250253

251254
return vertices, faces
252255

src/compas/geometry/shapes/polyhedron.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,10 @@ def from_data(cls, data):
128128
Examples
129129
--------
130130
>>> from compas.geometry import Polyhedron
131-
>>> p = Polyhedron(4)
131+
>>> p = Polyhedron.from_platonicsolid(4)
132132
>>> q = Polyhedron.from_data(p.data)
133133
"""
134-
p = cls(len(data.get('faces')))
135-
p.data = data
136-
return p
134+
return cls(data['vertices'], data['faces'])
137135

138136
@classmethod
139137
def from_platonicsolid(cls, f):

src/compas_rhino/artists/_artist.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ def build(item, **kwargs):
5555
def draw(self):
5656
pass
5757

58-
@staticmethod
59-
def draw_collection(collection):
60-
raise NotImplementedError
61-
6258
def redraw(self):
6359
compas_rhino.rs.EnableRedraw(True)
6460

src/compas_rhino/artists/boxartist.py

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,66 @@ class BoxArtist(ShapeArtist):
1818
-----
1919
See :class:`compas_rhino.artists.ShapeArtist` for all other parameters.
2020
21+
Examples
22+
--------
23+
.. code-block:: python
24+
25+
import random
26+
from compas.geometry import Pointcloud
27+
from compas.geometry import Box
28+
from compas.utilities import i_to_rgb
29+
30+
import compas_rhino
31+
from compas_rhino.artists import BoxArtist
32+
33+
pcl = Pointcloud.from_bounds(10, 10, 10, 100)
34+
tpl = Box.from_width_height_depth(0.3, 0.3, 0.3)
35+
36+
compas_rhino.clear_layer("Test::BoxArtist")
37+
38+
for point in pcl.points:
39+
box = tpl.copy()
40+
box.frame.point = point
41+
artist = BoxArtist(box, color=i_to_rgb(random.random()), layer="Test::BoxArtist")
42+
artist.draw()
2143
"""
2244

23-
def draw(self):
45+
def draw(self, show_vertices=False, show_edges=False, show_faces=True, join_faces=True):
2446
"""Draw the box associated with the artist.
2547
48+
Parameters
49+
----------
50+
show_vertices : bool, optional
51+
Default is ``False``.
52+
show_edges : bool, optional
53+
Default is ``False``.
54+
show_faces : bool, optional
55+
Default is ``True``.
56+
join_faces : bool, optional
57+
Default is ``True``.
58+
2659
Returns
2760
-------
2861
list
2962
The GUIDs of the objects created in Rhino.
3063
"""
3164
vertices = [list(vertex) for vertex in self.shape.vertices]
32-
faces = self.shape.faces
33-
edges = self.shape.edges
34-
points = [{'pos': point, 'color': self.color} for point in vertices]
35-
lines = [{'start': vertices[i], 'end': vertices[j], 'color': self.color} for i, j in edges]
36-
polygons = [{'points': [vertices[index] for index in face], 'color': self.color} for face in faces]
37-
guids = compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
38-
guids += compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
39-
guids += compas_rhino.draw_faces(polygons, layer=self.layer, clear=False, redraw=False)
65+
guids = []
66+
if show_vertices:
67+
points = [{'pos': point, 'color': self.color, 'name': self.name} for point in vertices]
68+
guids += compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
69+
if show_edges:
70+
edges = self.shape.edges
71+
lines = [{'start': vertices[i], 'end': vertices[j], 'color': self.color, 'name': self.name} for i, j in edges]
72+
guids += compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
73+
if show_faces:
74+
faces = self.shape.faces
75+
if join_faces:
76+
guid = compas_rhino.draw_mesh(vertices, faces, layer=self.layer, name=self.name, color=self.color, disjoint=True)
77+
guids.append(guid)
78+
else:
79+
polygons = [{'points': [vertices[index] for index in face], 'color': self.color, 'name': self.name} for face in faces]
80+
guids += compas_rhino.draw_faces(polygons, layer=self.layer, clear=False, redraw=False)
4081
self._guids = guids
4182
return guids
4283

src/compas_rhino/artists/capsuleartist.py

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from __future__ import absolute_import
33
from __future__ import division
44

5+
from compas.utilities import pairwise
56
import compas_rhino
67
from ._shapeartist import ShapeArtist
78

@@ -18,9 +19,32 @@ class CapsuleArtist(ShapeArtist):
1819
-----
1920
See :class:`compas_rhino.artists.ShapeArtist` for all other parameters.
2021
22+
Examples
23+
--------
24+
.. code-block:: python
25+
26+
import random
27+
from compas.geometry import Pointcloud
28+
from compas.geometry import Capsule
29+
from compas.geometry import Translation
30+
from compas.utilities import i_to_rgb
31+
32+
import compas_rhino
33+
from compas_rhino.artists import CapsuleArtist
34+
35+
pcl = Pointcloud.from_bounds(10, 10, 10, 100)
36+
tpl = Capsule([[0, 0, 0], [0.8, 0, 0]], 0.15)
37+
38+
compas_rhino.clear_layer("Test::CapsuleArtist")
39+
40+
for point in pcl.points:
41+
capsule = tpl.transformed(Translation.from_vector(point))
42+
artist = CapsuleArtist(capsule, color=i_to_rgb(random.random()), layer="Test::CapsuleArtist")
43+
artist.draw()
44+
2145
"""
2246

23-
def draw(self, u=10, v=10):
47+
def draw(self, u=10, v=10, show_vertices=False, show_edges=False, show_faces=True, join_faces=True):
2448
"""Draw the capsule associated with the artist.
2549
2650
Parameters
@@ -31,6 +55,14 @@ def draw(self, u=10, v=10):
3155
v : int, optional
3256
Number of faces in the "v" direction.
3357
Default is ``10``.
58+
show_vertices : bool, optional
59+
Default is ``False``.
60+
show_edges : bool, optional
61+
Default is ``False``.
62+
show_faces : bool, optional
63+
Default is ``True``.
64+
join_faces : bool, optional
65+
Default is ``True``.
3466
3567
Returns
3668
-------
@@ -39,10 +71,27 @@ def draw(self, u=10, v=10):
3971
"""
4072
vertices, faces = self.shape.to_vertices_and_faces(u=u, v=v)
4173
vertices = [list(vertex) for vertex in vertices]
42-
points = [{'pos': point, 'color': self.color} for point in vertices]
43-
polygons = [{'points': [vertices[index] for index in face], 'color': self.color} for face in faces]
44-
guids = compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
45-
guids += compas_rhino.draw_faces(polygons, layer=self.layer, clear=False, redraw=False)
74+
guids = []
75+
if show_vertices:
76+
points = [{'pos': point, 'color': self.color} for point in vertices]
77+
guids += compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
78+
if show_edges:
79+
lines = []
80+
seen = set()
81+
for face in faces:
82+
for u, v in pairwise(face + face[:1]):
83+
if (u, v) not in seen:
84+
seen.add((u, v))
85+
seen.add((v, u))
86+
lines.append({'start': vertices[u], 'end': vertices[v], 'color': self.color})
87+
guids += compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
88+
if show_faces:
89+
if join_faces:
90+
guid = compas_rhino.draw_mesh(vertices, faces, layer=self.layer, name=self.name, color=self.color, disjoint=True)
91+
guids.append(guid)
92+
else:
93+
polygons = [{'points': [vertices[index] for index in face], 'color': self.color} for face in faces]
94+
guids += compas_rhino.draw_faces(polygons, layer=self.layer, clear=False, redraw=False)
4695
self._guids = guids
4796
return guids
4897

0 commit comments

Comments
 (0)