Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

* Added `compas_rhino.artists.BoxArtist.draw_collection`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.CapsuleArtist.draw`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.ConeArtist.draw`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.CylinderArtist.draw`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.PolyhedronArtist.draw`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.SphereArtist.draw`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.TorusArtist.draw`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.PolygonArtist.draw`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.PolylineArtist.draw`.
* Added option to show/hide vertices, edges, and faces in `compas_rhino.artists.VectorArtist.draw`.

### Changed

* Changed implementation of `compas_rhino.artists.BoxArtist.draw`.
* Fixed bug in `compas.geometry.Capsule`.
* Fixed bug in `compas.geometry.Cone`.
* Changed `compas_rhino.draw_mesh` to support Ngons if available.
* Fixed bug in polyhedron data.

### Removed

* Removed `compas_rhino.artists.PointArtist.draw_collection`.
* Removed `compas_rhino.artists.CircleArtist.draw_collection`.
* Removed `compas_rhino.artists.LineArtist.draw_collection`.

## [0.16.9] 2020-10-21

Expand Down
72 changes: 67 additions & 5 deletions src/compas/geometry/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@
.. currentmodule:: compas.geometry


Primitives
==========

Base Classes
============
------------

.. autosummary::
:toctree: generated/
:nosignatures:

Primitive
Shape


Primitives
==========
Classes
-------

.. autosummary::
:toctree: generated/
Expand All @@ -36,9 +37,59 @@
Vector


The following representations of primitives can be used
interchangeably as input in methods and functions.
The representations using native Python objects also correspond to the required input
parameters of the default constructor functions of the corresponding COMPAS objects.

============ ============================== ============
Object COMPAS Python
------------ ------------------------------ ------------
point Point(float, float, float) [float, float, float]
vector Vector(float, float, float) [float, float, float]
line Line(point, point) [[float, float, float], [float, float, float]]
plane Plane(point, vector) [[float, float, float], [float, float, float]]
circle Circle(plane, float) [[[float, float, float], [float, float, float]], float]
polygon Polygon(points) [[float, float, float], ... [float, float, float]]
polyline Polyline(points) [[float, float, float], ... [float, float, float]]
ellipse Ellipse(plane, float, float) [[[float, float, float], [float, float, float]], float, float]
frame Frame(point, vector, vector) [[float, float, float], [float, float, float], [float, float, float]]
============ ============================== ============

COMPAS primitives also support indexing, assignment, and iteration according to the above
equivalency.

::

>>> a = Point(0, 0, 0)
>>> x, y, z = a
>>> x = a[0]
>>> a[0] = 0

::

>>> plane = Plane(Point(0, 0, 0), Vector(0, 0, 1))
>>> a, n = plane
>>> x, y, z = n
>>> plane[0] = Point(1, 0, 0)


Shapes
======

Base Classes
------------

.. autosummary::
:toctree: generated/
:nosignatures:

Shape


Classes
-------

.. autosummary::
:toctree: generated/
:nosignatures:
Expand Down Expand Up @@ -449,6 +500,17 @@

icp_numpy


Base Classes
============

.. autosummary::
:toctree: generated/
:nosignatures:

Primitive
Shape

"""
from __future__ import absolute_import
from __future__ import division
Expand Down
2 changes: 1 addition & 1 deletion src/compas/geometry/shapes/capsule.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def line(self):

@line.setter
def line(self, line):
self._line = line
self._line = Line(*line)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while fixing this, i noticed that the capsule has a very different logic than for example the box. it doesn't have a local frame and is defined directly through a line defined by two points. perhaps that should become an alternative constructor. the default, like with the box, should accept a frame and the parameters that define the capsule in that frame. ideally this is the default for all shapes: a frame and parameters. alternative constructors allow to use direct geometrical inputs, but would then have to compute a frame from those internally...

@gonzalocasas @beverlylytle @Licini

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the suggestion makes sense to me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will submit a proposal for this via a different PR


@property
def start(self):
Expand Down
19 changes: 11 additions & 8 deletions src/compas/geometry/shapes/cone.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
from math import sin
from math import sqrt

from compas.utilities import pairwise

from compas.geometry import matrix_from_frame
from compas.geometry import transform_points
from compas.geometry import Circle
from compas.geometry import Frame
from compas.geometry import Plane

from compas.geometry.shapes import Shape
from ._shape import Shape


__all__ = ['Cone']
Expand Down Expand Up @@ -96,7 +98,7 @@ def circle(self):

@circle.setter
def circle(self, circle):
self._circle = circle
self._circle = Circle(circle[0], circle[1])

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

vertices = []
vertices = [[0, 0, 0]]
a = 2 * pi / u
for i in range(u):
x = self.circle.radius * cos(i * a)
y = self.circle.radius * sin(i * a)
vertices.append([x, y, 0])
vertices.append([0, 0, self.height])

# transform vertices to cylinder's plane
frame = Frame.from_plane(self.circle.plane)
M = matrix_from_frame(frame)
vertices = transform_points(vertices, M)

faces = []
first = 0
last = len(vertices) - 1
for i in range(u):
faces.append([i, (i + 1) % u, last])
faces.append([i for i in range(u)])
faces[-1].reverse()
for i, j in pairwise(range(1, last)):
faces.append([i, j, last])
faces.append([j, i, first])
faces.append([last - 1, 1, last])
faces.append([1, last - 1, first])

return vertices, faces

Expand Down
6 changes: 2 additions & 4 deletions src/compas/geometry/shapes/polyhedron.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,10 @@ def from_data(cls, data):
Examples
--------
>>> from compas.geometry import Polyhedron
>>> p = Polyhedron(4)
>>> p = Polyhedron.from_platonicsolid(4)
>>> q = Polyhedron.from_data(p.data)
"""
p = cls(len(data.get('faces')))
p.data = data
return p
return cls(data['vertices'], data['faces'])

@classmethod
def from_platonicsolid(cls, f):
Expand Down
4 changes: 0 additions & 4 deletions src/compas_rhino/artists/_artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ def build(item, **kwargs):
def draw(self):
pass

@staticmethod
def draw_collection(collection):
raise NotImplementedError

def redraw(self):
compas_rhino.rs.EnableRedraw(True)

Expand Down
59 changes: 50 additions & 9 deletions src/compas_rhino/artists/boxartist.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,66 @@ class BoxArtist(ShapeArtist):
-----
See :class:`compas_rhino.artists.ShapeArtist` for all other parameters.

Examples
--------
.. code-block:: python

import random
from compas.geometry import Pointcloud
from compas.geometry import Box
from compas.utilities import i_to_rgb

import compas_rhino
from compas_rhino.artists import BoxArtist

pcl = Pointcloud.from_bounds(10, 10, 10, 100)
tpl = Box.from_width_height_depth(0.3, 0.3, 0.3)

compas_rhino.clear_layer("Test::BoxArtist")

for point in pcl.points:
box = tpl.copy()
box.frame.point = point
artist = BoxArtist(box, color=i_to_rgb(random.random()), layer="Test::BoxArtist")
artist.draw()
"""

def draw(self):
def draw(self, show_vertices=False, show_edges=False, show_faces=True, join_faces=True):
"""Draw the box associated with the artist.

Parameters
----------
show_vertices : bool, optional
Default is ``False``.
show_edges : bool, optional
Default is ``False``.
show_faces : bool, optional
Default is ``True``.
join_faces : bool, optional
Default is ``True``.

Returns
-------
list
The GUIDs of the objects created in Rhino.
"""
vertices = [list(vertex) for vertex in self.shape.vertices]
faces = self.shape.faces
edges = self.shape.edges
points = [{'pos': point, 'color': self.color} for point in vertices]
lines = [{'start': vertices[i], 'end': vertices[j], 'color': self.color} for i, j in edges]
polygons = [{'points': [vertices[index] for index in face], 'color': self.color} for face in faces]
guids = compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
guids += compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
guids += compas_rhino.draw_faces(polygons, layer=self.layer, clear=False, redraw=False)
guids = []
if show_vertices:
points = [{'pos': point, 'color': self.color, 'name': self.name} for point in vertices]
guids += compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
if show_edges:
edges = self.shape.edges
lines = [{'start': vertices[i], 'end': vertices[j], 'color': self.color, 'name': self.name} for i, j in edges]
guids += compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
if show_faces:
faces = self.shape.faces
if join_faces:
guid = compas_rhino.draw_mesh(vertices, faces, layer=self.layer, name=self.name, color=self.color, disjoint=True)
guids.append(guid)
else:
polygons = [{'points': [vertices[index] for index in face], 'color': self.color, 'name': self.name} for face in faces]
guids += compas_rhino.draw_faces(polygons, layer=self.layer, clear=False, redraw=False)
self._guids = guids
return guids

Expand Down
59 changes: 54 additions & 5 deletions src/compas_rhino/artists/capsuleartist.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import absolute_import
from __future__ import division

from compas.utilities import pairwise
import compas_rhino
from ._shapeartist import ShapeArtist

Expand All @@ -18,9 +19,32 @@ class CapsuleArtist(ShapeArtist):
-----
See :class:`compas_rhino.artists.ShapeArtist` for all other parameters.

Examples
--------
.. code-block:: python

import random
from compas.geometry import Pointcloud
from compas.geometry import Capsule
from compas.geometry import Translation
from compas.utilities import i_to_rgb

import compas_rhino
from compas_rhino.artists import CapsuleArtist

pcl = Pointcloud.from_bounds(10, 10, 10, 100)
tpl = Capsule([[0, 0, 0], [0.8, 0, 0]], 0.15)

compas_rhino.clear_layer("Test::CapsuleArtist")

for point in pcl.points:
capsule = tpl.transformed(Translation.from_vector(point))
artist = CapsuleArtist(capsule, color=i_to_rgb(random.random()), layer="Test::CapsuleArtist")
artist.draw()

"""

def draw(self, u=10, v=10):
def draw(self, u=10, v=10, show_vertices=False, show_edges=False, show_faces=True, join_faces=True):
"""Draw the capsule associated with the artist.

Parameters
Expand All @@ -31,6 +55,14 @@ def draw(self, u=10, v=10):
v : int, optional
Number of faces in the "v" direction.
Default is ``10``.
show_vertices : bool, optional
Default is ``False``.
show_edges : bool, optional
Default is ``False``.
show_faces : bool, optional
Default is ``True``.
join_faces : bool, optional
Default is ``True``.

Returns
-------
Expand All @@ -39,10 +71,27 @@ def draw(self, u=10, v=10):
"""
vertices, faces = self.shape.to_vertices_and_faces(u=u, v=v)
vertices = [list(vertex) for vertex in vertices]
points = [{'pos': point, 'color': self.color} for point in vertices]
polygons = [{'points': [vertices[index] for index in face], 'color': self.color} for face in faces]
guids = compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
guids += compas_rhino.draw_faces(polygons, layer=self.layer, clear=False, redraw=False)
guids = []
if show_vertices:
points = [{'pos': point, 'color': self.color} for point in vertices]
guids += compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
if show_edges:
lines = []
seen = set()
for face in faces:
for u, v in pairwise(face + face[:1]):
if (u, v) not in seen:
seen.add((u, v))
seen.add((v, u))
lines.append({'start': vertices[u], 'end': vertices[v], 'color': self.color})
guids += compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
if show_faces:
if join_faces:
guid = compas_rhino.draw_mesh(vertices, faces, layer=self.layer, name=self.name, color=self.color, disjoint=True)
guids.append(guid)
else:
polygons = [{'points': [vertices[index] for index in face], 'color': self.color} for face in faces]
guids += compas_rhino.draw_faces(polygons, layer=self.layer, clear=False, redraw=False)
self._guids = guids
return guids

Expand Down
Loading