Skip to content

Commit 9628cc3

Browse files
authored
Merge branch 'main' into blender-install-windows
2 parents 35655dd + 68558ee commit 9628cc3

File tree

10 files changed

+219
-137
lines changed

10 files changed

+219
-137
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
* Added optional `path` parameter to `compas.rpc.Proxy` to allow for non-package calls.
1616
* Added Grasshopper component to call RPC functions.
1717
* Added alternative installation procedure for Blender on Windows.
18+
* Added `Mesh.to_lines` method and tests.
1819

1920
### Changed
2021

2122
* Set `jinja >= 3.0` to dev dependencies to fix docs build error.
23+
* Fixed removing of collections for `compas_plotters`.
2224

2325
### Removed
2426

@@ -37,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3739

3840
### Changed
3941

42+
* Fixed bug in `normal_polygon` in `compas.geometry`.
4043
* Fixed bug in Blender mesh conversion.
4144
* Changed Rhino plugin installer to check for and install required plugin packages.
4245
* Refactor robot model artists to use the same `Mesh.to_vertices_and_faces` everywhere.

docs/tutorial/rpc.rst

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,11 @@
22
Remote Procedure Calls
33
********************************************************************************
44

5-
* :mod:`compas.rpc`
6-
75
Remote Procedure Calls (``RPC``) is a mechanism to transparently execute code in
86
a remote process or computer. This is especially useful in scenarios where COMPAS
97
runs inside an IronPython host (eg. Rhino) and needs to execute code that only
108
runs on CPython (eg. code that requires ``numpy``).
119

12-
COMPAS provides **two ways to achieve** this: ``rcp`` and ``XFunc``.
13-
14-
Through ``Xfunc``, COMPAS provides a mechanism for calling Python functions through
15-
a separately launched sub-process.
16-
17-
A drawback of the ``Xfunc`` mechanism is that every call launches a new Python
18-
(sub)process with all the overhead that that entails. For infrequent calls to
19-
long-running processes this is not an issue. However, for frequent calls to functions
20-
that are expected to run quickly, this is not ideal.
21-
22-
The second mechanism is the ``rpc`` module. The principle of RPC is to start a server
23-
that handles all requests. The advantage is that once the server is started,
24-
no additional processes have to be launched and the server can handle the requests
25-
without any overhead. Therefore, the response time is much faster than with ``XFunc``.
26-
2710

2811
Basic Usage
2912
===========
@@ -64,6 +47,70 @@ The use of :mod:`compas.rpc` is not restricted to COMPAS packages only. ::
6447
Note that Numpy arrays are automatically converted to lists.
6548

6649

50+
Configuration Options
51+
=====================
52+
53+
The :class:`compas.rpc.Proxy` object has several configuration options.
54+
We will discuss only a few of those here.
55+
For a complete overview, please refer to the API docs (:mod:`compas.rpc`).
56+
57+
``python``
58+
----------
59+
60+
The :class:`compas.rpc.Proxy` object will automatically try to reconnect to an
61+
active instance of the command server, or start a new one if no active server can be found.
62+
By default, a newly started server will run an instance of the default Python interpreter
63+
of the active environment, for example, when running RPC from the command line;
64+
or of the Python interpreter specified in `compas_bootstrapper`, for example, when running RPC from Rhino.
65+
66+
In some cases, this might not be what you want, or might not result in the expected behaviour,
67+
for example when `compas_bootstrapper` does not exist.
68+
69+
To use a specific Python iterpreter, you can specify the path to an executable through the ``python`` parameter.
70+
71+
.. code-block:: python
72+
73+
>>> from compas.rpc import Proxy
74+
>>> proxy = Proxy(python=r"C:\\Users\\<username>\\anaconda3\\envs\\research\\python.exe")
75+
76+
77+
``path``
78+
--------
79+
80+
Sometimes you will want the server to run custom functions that are not (yet) part of a specific package.
81+
To allow the server to find such functions, you can specify an additional search path.
82+
83+
For example, if you have a Python script on your desktop,
84+
defining a wrapper for the k-means clustering algorithm of ``scikit-learn``,
85+
you can tell the command server where to find it using the ``path`` parameter.
86+
87+
.. code-block:: python
88+
89+
# C:\Users\<username>\Desktop\clustering.py
90+
91+
from sklearn.cluster import KMeans
92+
from numpy import array
93+
94+
95+
def cluster(points, n_clusters):
96+
kmeans = KMeans(n_clusters=n_clusters, n_init=2000, max_iter=1000).fit(array(cloud, dtype=float))
97+
clusters = {}
98+
for label, point in zip(kmeans.labels_, cloud):
99+
if label not in clusters:
100+
clusters[label] = []
101+
clusters[label].append(point)
102+
return clusters
103+
104+
105+
.. code-block:: python
106+
107+
>>> from compas.geometry import Pointcloud
108+
>>> from compas.rpc import Proxy
109+
>>> cloud = Pointcloud.from_bounds(10, 5, 3, 100)
110+
>>> proxy = Proxy(package='clustering', path=r'C:\\Users\\<username>\\Desktop')
111+
>>> clusters = proxy.cluster(cloud, 10)
112+
113+
67114
Supported data types
68115
====================
69116

src/compas/artists/colordict.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import compas
22
from collections import defaultdict
3+
34
if compas.PY2:
45
from collections import Mapping
56
else:
@@ -12,7 +13,7 @@ class DescriptorProtocol(type):
1213

1314
def __init__(cls, name, bases, attrs):
1415
for k, v in iter(attrs.items()):
15-
if hasattr(v, '__set_name__'):
16+
if hasattr(v, "__set_name__"):
1617
v.__set_name__(cls, k)
1718

1819

@@ -58,8 +59,8 @@ def __set_name__(self, owner, name):
5859
5960
"""
6061
self.public_name = name
61-
self.private_name = '_' + name
62-
self.default_name = 'default_' + ''.join(name.split('_'))
62+
self.private_name = "_" + name
63+
self.default_name = "default_" + "".join(name.split("_"))
6364

6465
def __get__(self, obj, otype=None):
6566
"""Get the color dict stored in the private attribute corresponding to the public attribute name of the descriptor.

src/compas/datastructures/mesh/mesh.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,15 +377,15 @@ def from_lines(cls, lines, delete_boundary_face=False, precision=None):
377377
return mesh
378378

379379
def to_lines(self):
380-
"""Convert the mesh to a collection of lines.
380+
"""Return the lines of the mesh as pairs of start and end point coordinates.
381381
382382
Returns
383383
-------
384384
list[tuple[list[float], list[float]]]
385-
A list of lines each defined by a pair of points.
385+
A list of lines each defined by a pair of point coordinates.
386386
387387
"""
388-
raise NotImplementedError
388+
return [self.edge_coordinates(u, v) for u, v in self.edges()]
389389

390390
@classmethod
391391
def from_polylines(cls, boundary_polylines, other_polylines):

src/compas/datastructures/network/network.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ def from_pointcloud(cls, cloud, degree=3):
221221
Returns
222222
-------
223223
:class:`~compas.datastructures.Network`
224+
A network object.
224225
225226
"""
226227
network = cls()
@@ -256,6 +257,7 @@ def to_points(self):
256257
Returns
257258
-------
258259
list[list[float]]
260+
A list with the coordinates of the vertices of the network.
259261
260262
"""
261263
return [self.node_coordinates(key) for key in self.nodes()]
@@ -266,6 +268,7 @@ def to_lines(self):
266268
Returns
267269
-------
268270
list[tuple[list[float], list[float]]]
271+
A list of lines each defined by a pair of point coordinates.
269272
270273
"""
271274
return [self.edge_coordinates(u, v) for u, v in self.edges()]

src/compas/geometry/_core/normals.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ def normal_polygon(polygon, unitized=True):
6363
n = cross_vectors(oa, ob)
6464
oa = ob
6565

66-
nx += n[0]
67-
ny += n[1]
68-
nz += n[2]
66+
nx += n[0] * 0.5
67+
ny += n[1] * 0.5
68+
nz += n[2] * 0.5
6969

7070
if not unitized:
7171
return [nx, ny, nz]

0 commit comments

Comments
 (0)