Skip to content

Commit da1bf92

Browse files
authored
Merge branch 'compas-dev:main' into main
2 parents 03aabb3 + 7ea3fbd commit da1bf92

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1267
-178
lines changed

AUTHORS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@
3939
- Katerina Toumpektsi <<[email protected]>> [@katarametin](https://github.com/katarametin)
4040
- Joelle Baehr-Bruyere <<[email protected]>> [@baehrjo](https://github.com/baehrjo)
4141
- Adam Anouar <<[email protected]>> [@AdamAnouar](https://github.com/AdamAnouar)
42-
- Joseph Kenny <<[email protected]>> [@jckenny59](https://github.com/jckenny59)
42+
- Joseph Kenny <<[email protected]>> [@jckenny59](https://github.com/jckenny59)
43+
- Panayiotis Papacharalambous <<[email protected]>> [@papachap](https://github.com/papachap)

CHANGELOG.md

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,114 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
### Changed
1313

14-
* Fixed `RuntimeError` when using `compas_rhino.unload_modules` in CPython`.
14+
### Removed
15+
16+
17+
## [2.8.1] 2025-01-15
18+
19+
### Added
20+
21+
### Changed
22+
23+
* Fixed `NotImplementedError` when calling `compas_rhino.conversions.surface_to_compas` on NURBS Surface.
24+
* Fixed `NotImplementedError` when calling `compas_rhino.conversions.surface_to_compas` on Surface.
25+
* Changed point comparison (`compas.geometry.Point.__eq__`) to use `TOL.is_allclose` instead of raw coordinate comparison.
26+
* Changed vector comparison (`compas.geometry.Vector.__eq__`) to use `TOL.is_allclose` instead of raw coordinate comparison.
27+
* Fixed bug in frame comparison (`compas.geometry.Frame.__eq__`).
28+
* Fixed bug in `compas.geometry.oriented_bounding_box_numpy`.
29+
* Fixed cannot copy `Line` using `deepcopy`.
30+
31+
### Removed
32+
33+
34+
## [2.8.0] 2024-12-13
35+
36+
### Added
37+
38+
* Added implementation of `RhinoBrep.fillet()` and `RhinoBrep.filleted()` to `compas_rhino`.
39+
* Added `Frame.invert` and `Frame.inverted`.
40+
* Added `Frame.flip` and `Frame.flipped` as alias for invert and inverted.
41+
* Added `Vector.flip` and `Vector.flipped` as alias for invert and inverted.
42+
43+
### Changed
44+
45+
* Fixed `native_edge` property of `RhinoBrepEdge`.
46+
* Expose the parameters `radius` and `nmax` from `compas.topology._face_adjacency` to `compas.topology.face_adjacency` and further propagate them to `unify_cycles` and `Mesh.unify_cycles`.
47+
* Modify `face_adjacency` to avoid using `compas.topology._face_adjacency` by default when there are more than 100 faces, unless one of the parameters `radius`, `nmax` is passed.
48+
* Changed `unify_cycles` to use the first face in the list as root if no root is provided.
49+
50+
### Removed
51+
52+
53+
## [2.7.0] 2024-11-28
54+
55+
### Added
56+
57+
* Added attribute `start_vertex` to `compas.geometry.BrepTrim`.
58+
* Added attribute `end_vertex` to `compas.geometry.BrepTrim`.
59+
* Added attribute `vertices` to `compas.geometry.BrepTrim`.
60+
* Added attribute `start_vertex` to `compas_rhino.geometry.RhinoBrepTrim`.
61+
* Added attribute `start_vertex` to `compas_rhino.geometry.RhinoBrepTrim`.
62+
* Added attribute `vertices` to `compas_rhino.geometry.RhinoBrepTrim`.
63+
64+
### Changed
65+
66+
* Fixed `PluginNotInstalledError` when using `Brep.from_boolean_*` in Rhino.
67+
* Added support for `Polyline` as input for `compas_rhino.Brep.from_extrusion`.
68+
69+
### Removed
70+
71+
72+
## [2.6.1] 2024-11-09
73+
74+
### Added
75+
76+
### Changed
77+
78+
* Fixed bug in `compas_rhino.scene.RhinoMeshObject.clear()`.
79+
80+
### Removed
81+
82+
83+
## [2.6.0] 2024-11-08
84+
85+
### Added
86+
87+
* Added key conversion map to `compas.colors.ColorDict` to avoid serialisation problems with tuple keys when used in combination with edges.
88+
* Added `Scene.find_all_by_itemtype`.
89+
90+
### Changed
91+
92+
* Fixed bug in `VolMesh.delete_cell`.
93+
* Fixed `NoneType` error when calling `compas.geometry.Sphere.edges`.
94+
* Fixed bug in `VolMesh.vertex_halffaces`.
95+
* Fixed bug in `VolMesh.vertex_cells`.
96+
* Fixed bug in `VolMesh.is_halfface_on_boundary`.
97+
98+
### Removed
99+
100+
* Removed `VolMesh.halfface_adjacent_halfface` because of general nonsensicalness, and because it is (and probably always has been) completely broken.
101+
102+
103+
## [2.5.0] 2024-10-25
104+
105+
### Added
106+
107+
* Added instructions for creating new data types to the dev guide.
108+
* Added `compact=False`, `minimal=False` to `compas.data.Data.to_json()` to `compas.data.Data.to_jsonstring()`.
109+
* Added `copy_guid=False` to `compas.data.Data.copy()`. If true, the copy has the same guid as the original.
110+
* Added implementation of `Brep.from_loft()` to `compas_rhino`.
111+
112+
### Changed
113+
114+
* Fixed `RuntimeError` when using `compas_rhino.unload_modules` in CPython`.
15115
* Fixed bug in `Box.scaled` causing a `TypeError` due to incorrect parameter forwarding.
16116
* Changed argument names of `Box.scale()` to `x`, `y`, `z`, instead of `factor` and made `y` and `z` optional to keep positional arguments backwards compatible.
17117
* Fixed import errors in `compas_rhino.conduits` for Rhino 8.
118+
* Fixed doctest failures.
119+
* Fixed bug in serialization when `compas.datastructures.attributes.AttributeView` is used.
120+
* Fixed bug in the serialisation of empty scenes.
121+
* Fixed bug in serialisation process due to `name` attribute appearing in json representation after copy even if not present before copy.
18122

19123
### Removed
20124

@@ -26,6 +130,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
26130
### Changed
27131

28132
* Fixed support for `compas_gpython` in Rhino 8 Grasshopper CPython components.
133+
* Changed installation instructions for Rhino 8 in the user guide.
29134
* Fixed `Graph.from_edges` always returning `None`.
30135

31136
### Removed

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def setup(app):
139139
"image_dark": "_static/compas_icon_white.png",
140140
"text": "COMPAS docs",
141141
},
142-
"announcement": "This is the documentation of the first stable release of COMPAS 2. If you have feedback, please give it here: <a href='https://compas.dev/compas/issues'>COMPAS issue tracker</a>.",
142+
"announcement": "This is the documentation of the first stable release of COMPAS 2. If you have feedback, please give it here: <a href='https://github.com/compas-dev/compas/issues'>COMPAS issue tracker</a>.",
143143
"navigation_depth": 2,
144144
}
145145

docs/devguide/dtypes.rst

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,184 @@
11
Implementing a New Data Type
22
============================
3+
4+
COMPAS data types are classes that are based on :class:`compas.data.Data`.
5+
6+
Data types can be serialized to JSON with
7+
8+
* :func:`compas.json_dump`
9+
* :func:`compas.json_dumps`
10+
* :func:`compas.json_dumpz`
11+
12+
and deserialized with the corresponding "load" functions
13+
14+
* :func:`compas.json_load`
15+
* :func:`compas.json_loads`
16+
* :func:`compas.json_loadz`
17+
18+
All geometry objects and data structures,
19+
and also, for example, the visualization scene,
20+
are serializable data types.
21+
22+
23+
Creating a new data type
24+
========================
25+
26+
In most cases, it is sufficient to implement the ``__data__`` property when creating your custom `Data` class.
27+
28+
.. code-block:: python
29+
30+
class SomeThing(Data):
31+
32+
def __init__(self, a, b)
33+
super().__init__()
34+
# note that if the code needs to be compatible with IronPython
35+
# you should write the following:
36+
# super(SomeThing, self).__init__()
37+
self.a = a
38+
self.b = b
39+
40+
@property
41+
def __data__(self):
42+
return {
43+
"a": self.a,
44+
"b": self.b,
45+
}
46+
47+
48+
>>> custom = SomeThing(a=1, b=2)
49+
>>> compas.json_dump(custom, "custom.json")
50+
>>> result = compas.json_load("custom.json")
51+
>>> isinstance(result, SomeThing)
52+
True
53+
>>> result.a
54+
1
55+
>>> result.b
56+
2
57+
58+
If the attributes stored in the data dictionary defined by the ``__data__`` property
59+
are different from the initialization parameters of the class,
60+
you must also customize the ``__from_data__`` class method to compensate for the difference.
61+
62+
.. code-block:: python
63+
64+
class SomeThing(Data):
65+
66+
def __init__(self)
67+
super().__init__()
68+
# note that if the code needs to be compatible with IronPython
69+
# you should write the following:
70+
# super(SomeThing, self).__init__()
71+
self.items = []
72+
73+
@property
74+
def __data__(self):
75+
return {
76+
"items": self.items,
77+
}
78+
79+
@classmethod
80+
def __from_data__(cls, data):
81+
custom = cls()
82+
for item in data['items']:
83+
custom.add(item)
84+
return custom
85+
86+
def add(self, item):
87+
self.items.append(item)
88+
89+
90+
>>> custom = SomeThing()
91+
>>> custom.add(1)
92+
>>> custom.add(2)
93+
>>> compas.json_dump(custom, "custom.json")
94+
>>> result = compas.json_load("custom.json")
95+
>>> isinstance(result, SomeThing)
96+
True
97+
>>> result.items
98+
[1, 2]
99+
100+
101+
Attribute types
102+
===============
103+
104+
Any attribute that is an instance of a Python base type or a serializable COMPAS data object
105+
can be included in the data dict created by the ``__data__`` property without further processing.
106+
The serialization process will recursively serialize all these attributes.
107+
108+
.. code-block:: python
109+
110+
class SomeThing(Data):
111+
112+
def __init__(self, point, frame, mesh):
113+
super().__init__()
114+
# note that if the code needs to be compatible with IronPython
115+
# you should write the following:
116+
# super(SomeThing, self).__init__()
117+
self.point = point
118+
self.frame = frame
119+
self.mesh = mesh
120+
121+
@property
122+
def __data__(self):
123+
return {
124+
"point": self.point,
125+
"frame": self.frame,
126+
"mesh": self.mesh,
127+
}
128+
129+
130+
>>> import compas
131+
>>> from compas.geometry import Point, Frame
132+
>>> from compas.datastructures import Mesh
133+
>>> point = Point(1, 2, 3)
134+
>>> frame = Frame()
135+
>>> mesh = Mesh.from_meshgrid(10, 10)
136+
>>> custom = SomeThing(point, frame, mesh)
137+
>>> compas.json_dump(custom, "custom.json")
138+
>>> result = compas.json_load("custom.json")
139+
>>> isinstance(result.point, Point)
140+
True
141+
>>> isinstance(result.frame, Frame)
142+
True
143+
>>> isinstance(result.mesh, Mesh)
144+
True
145+
>>> result.point == point
146+
True
147+
>>> result.point is point
148+
False
149+
150+
151+
Note that the the automatic serialization process will incur overhead information
152+
that increases the size of the resulting JSON file.
153+
The performance impact may be significant when many of these instances are serialized.
154+
155+
To avoid this, anticipated conversions can be included explicitly in `__data__` and `__from_data__`.
156+
157+
.. code-block:: python
158+
159+
class SomeThing(Data):
160+
161+
def __init__(self, point, frame, mesh):
162+
super().__init__()
163+
# note that if the code needs to be compatible with IronPython
164+
# you should write the following:
165+
# super(SomeThing, self).__init__()
166+
self.point = point
167+
self.frame = frame
168+
self.mesh = mesh
169+
170+
@property
171+
def __data__(self):
172+
return {
173+
"point": self.point.__data__,
174+
"frame": self.frame.__data__,
175+
"mesh": self.mesh.__data__,
176+
}
177+
178+
@classmethod
179+
def __from_data__(cls, data):
180+
return cls(
181+
Point.__from_data__(data['point']),
182+
Frame.__from_data__(data['frame']),
183+
Mesh.__from_data__(data['mesh']),
184+
)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ doctest_optionflags = [
8484
# ============================================================================
8585

8686
[tool.bumpversion]
87-
current_version = "2.4.3"
87+
current_version = "2.8.1"
8888
message = "Bump version to {new_version}"
8989
commit = true
9090
tag = true

src/compas/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
__copyright__ = "Copyright 2014-2022 - ETH Zurich, Copyright 2023 - COMPAS Association"
2121
__license__ = "MIT License"
2222
__email__ = "[email protected]"
23-
__version__ = "2.4.3"
23+
__version__ = "2.8.1"
2424

2525

2626
HERE = compas._os.realpath(os.path.dirname(__file__))

src/compas/colors/color.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class Color(Data):
9999
By default, this class will create a color with the RGB components in the range ``[0.0, 1.0]``.
100100
101101
>>> Color(1, 0, 0)
102-
Color(1, 0, 0, alpha=1.0)
102+
Color(red=1, green=0, blue=0, alpha=1.0)
103103
104104
Attempting to create a color with components outside of the range ``[0.0, 1.0]`` will raise a ``ValueError``.
105105
@@ -111,7 +111,7 @@ class Color(Data):
111111
To create a color with components in the range ``[0, 255]``, use the :meth:`from_rgb255` constructor.
112112
113113
>>> Color.from_rgb255(255, 0, 0)
114-
Color(1.0, 0.0, 0.0, alpha=1.0)
114+
Color(red=1.0, green=0.0, blue=0.0, alpha=1.0)
115115
116116
Similarly, other constructors are available to create colors from other color spaces.
117117
@@ -132,13 +132,13 @@ class Color(Data):
132132
133133
>>> color = Color.red()
134134
>>> color.desaturated(25)
135-
Color(0.875, 0.125, 0.125, alpha=1.0)
135+
Color(red=0.875, green=0.125, blue=0.125, alpha=1.0)
136136
>>> color.desaturated(50)
137-
Color(0.75, 0.25, 0.25, alpha=1.0)
137+
Color(red=0.75, green=0.25, blue=0.25, alpha=1.0)
138138
>>> color.desaturated(75)
139-
Color(0.625, 0.375, 0.375, alpha=1.0)
139+
Color(red=0.625, green=0.375, blue=0.375, alpha=1.0)
140140
>>> color.desaturated(100)
141-
Color(0.5, 0.5, 0.5, alpha=1.0)
141+
Color(red=0.5, green=0.5, blue=0.5, alpha=1.0)
142142
143143
See Also
144144
--------

0 commit comments

Comments
 (0)