Skip to content

Commit

Permalink
Merge branch 'main' into fix-transformations
Browse files Browse the repository at this point in the history
  • Loading branch information
tomvanmele authored Jun 22, 2024
2 parents cf4a609 + b7111f2 commit 4ba6b5e
Show file tree
Hide file tree
Showing 130 changed files with 3,770 additions and 3,551 deletions.
63 changes: 57 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

* Added `maxiter` parameter to `compas.geometry.icp_numpy`.

### Changed

* Added `resolution_u` and `resolution_v` to `compas.geometry.Shape` to control discretisation resolution.
* Added `vertices`, `edges`, `faces`, `triangles` to `compas.geometry.Shape`.
* Added `points`, `lines`, `polygons` to `compas.geometry.Shape`.
* Added abstract `compute_vertices`, `compute_edges`, `compute_faces`, `compute_triangles` to `compas.geometry.Shape`.
* Added implementation of `compute_vertices`, `compute_edges`, `compute_faces` to `compas.geometry.Box`.
* Added implementation of `compute_vertices`, `compute_edges`, `compute_faces` to `compas.geometry.Capsule`.
* Added implementation of `compute_vertices`, `compute_edges`, `compute_faces` to `compas.geometry.Cone`.
* Added implementation of `compute_vertices`, `compute_edges`, `compute_faces` to `compas.geometry.Cylinder`.
* Added implementation of `compute_vertices`, `compute_edges`, `compute_faces` to `compas.geometry.Sphere`.
* Added implementation of `compute_vertices`, `compute_edges`, `compute_faces` to `compas.geometry.Torus`.
* Added `compas_blender.scene.ShapeObject`.
* Added `compas.geometry.vector.__radd__`.
* Added `compas.geometry.vector.__rsub__`.
* Added `compas.geometry.vector.__rmul__`.
* Added `compas.geometry.vector.__rtruediv__`.
* Added `VolMesh.cell_lines`, `VolMesh.cell_polygons`.
* Added `VolMesh.vertex_edges`.
* Added `VolMesh.from_meshes`.
* Added `VolMesh.from_polyhedrons`.

### Changed

* Changed `compas_ghpython/utilities/drawing.py` to remove `System` dependency.
* Fixed bug in `compas.geometry.ic_numpy`, which was caused by returning only the last transformation of the iteration process.
* Changed `compas.geometry.Geometry.scaled` to use `compas.geometry.Geometry.scale` on a copy.
* Changed `compas.geometry.Geometry.translated` to use `compas.geometry.Geometry.translate` on a copy.
* Changed `compas.geometry.Geometry.rotated` to use `compas.geometry.Geometry.rotate` on a copy.

### Removed

* Changed `VolMesh._plane` back to point to a cell for every triplet of vertices.
* Fixed `VolMesh.add_halfface`, `VolMesh.add_cell`, `VolMesh.vertex_halffaces`, `VolMesh.vertex_cells`, `VolMesh.edge_halffaces`, `VolMesh.halfface_cell`, `VolMesh.halfface_opposite_cell`, `VolMesh.halfface_opposite_halfface`, `VolMesh.cell_neighbors`.
* Changed ordering of `Volmesh.edges()` to be deterministic.
* Changed ordering and direction of `Volmesh.vertex_edges()` to be deterministic.
* Changed check for empty vertices and faces to use `is None` to add support for `numpy` arrays.
* Changed order of `u` and `v` of `compas.geometry.SphericalSurface` to the match the excpected parametrisation.
* Changed `compas.geometry.Shape.to_vertices_and_faces` to use `Shape.vertices` and `Shape.faces` or `Shape.triangles`.
* Changed default of `compas.scene.descriptors.color.ColorAttribute` to `None` to support native coloring in CAD contexts.
* Changed `compas.colors.ColorDict.__data__` and `compas.colors.ColorDict.__from_data__` to properly support serialisation.
* Moved `compas_blender.utilities.drawing` to `compas_blender.drawing` with backward compatible imports and deprecation warning.
* Moved `compas_ghpython.utilities.drawing` to `compas_ghpython.drawing` with backward compatible imports and deprecation warning.
* Moved `compas_rhino.utilities.drawing` to `compas_rhino.drawing` with backward compatible imports and deprecation warning.
* Changed `draw_nodes` and `draw_edges` of `compas_blender.scene.GraphObject`, `compas_ghpython.scene.GraphObject`, and `compas_rhino.scene.GraphObject` to use only attributes instead of parameters.
* Changed `draw_vertices`, `draw_edges` and `draw_faces` of `compas_blender.scene.MeshObject`, `compas_ghpython.scene.MeshObject`, and `compas_rhino.scene.MeshObject` to use only attributes instead of parameters.
* Changed `draw_vertices`, `draw_edges` and `draw_faces` of `compas_blender.scene.VolMeshObject`, `compas_ghpython.scene.VolMeshObject`, and `compas_rhino.scene.VolMeshObject` to use only attributes instead of parameters.
* Changed registration of `Capsule`, `Cone`, `Cylinder`, `Sphere`, `Torus` to `ShapeObject` in `compas_blender.scene`.
* Updated `compas.geometry.vector.__mul__` to allow element-wise multiplication with another vector.
* Updated `compas.geometry.vector.__truediv__` to allow element-wise division with another vector.
* Fixed bug in registration `shapely` boolean plugins.
* Temporarily restrict `numpy` to versions lower than `2.x`.

### Removed

* Removed `System` dependency in `compas_ghpython/utilities/drawing.py`.
* Removed GH plugin for `compas.scene.clear` since it clashed with the Rhino version.

## [2.1.1] 2024-05-14

Expand All @@ -33,6 +75,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `compas.tolerance.Tolerance.angulardeflection`.
* Added `compas.tolerance.Tolerance.update_from_dict`.
* Added `compas.scene.SceneObject.scene` attribute.
* Added `compas.datastructures.CellNetwork.is_faces_closed`
* Added `compas.datastructures.CellNetwork.delete_edge`
* Added `compas.datastructures.CellNetwork.delete_cell`
* Added `compas.datastructures.CellNetwork.delete_face`
* Added `compas.datastructures.CellNetwork.cells_to_graph`
* Added `compas.datastructures.CellNetwork.face_plane`
* Added `compas.datastructures.CellNetwork.cell_volume`
* Added `compas.datastructures.CellNetwork.cell_neighbors`

### Changed

Expand All @@ -55,6 +105,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Changed `compas.tolerance.Tolerance` to a singleton, to ensure having only library-wide tolerance values.
* Updated `compas_rhino.conversions.point_to_compas` to allow for `Rhino.Geometry.Point` as input.
* Changed `compas.datastructures.Tree.print_hierarchy` to `compas.datastructures.Tree.__str__`.
* Changed `compas.scene.SceneObject.__init__` to accept `item` as kwarg.
* Fixed `compas.geometry.bbox_numpy.minimum_volume_box` to avoid `numpy.linalg.LinAlgError`.

### Removed
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions docs/api/compas.itertools.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
********************************************************************************
compas.itertools
********************************************************************************

.. currentmodule:: compas.itertools

.. rst-class:: lead

This package defines useful functions for working with iterable objects.


Functions
=========

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

normalize_values
remap_values
meshgrid
linspace
flatten
reshape
pairwise
window
iterable_like
2 changes: 2 additions & 0 deletions docs/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ and can be used independently of CAD systems in any environment that supports Py
compas.datastructures
compas.files
compas.geometry
compas.itertools
compas.plugins
compas.rpc
compas.scene
compas.tolerance


compas_blender
Expand Down
11 changes: 0 additions & 11 deletions docs/userguide/basics.datastructures.assemblies.rst

This file was deleted.

137 changes: 137 additions & 0 deletions docs/userguide/basics.datastructures.cellnetwork.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
********************************************************************************
Cell Networks
********************************************************************************

.. rst-class:: lead

A :class:`compas.datastructures.CellNetwork` uses a halfface data structure to represent a collection of mixed topologic entities (cells, faces, edges and vertices)
and to facilitate the application of topological and geometrical operations on it.
In addition, it provides a number of methods for storing arbitrary data on vertices, edges, faces, cells, and the overall cell network itself.

.. note::

Please refer to the API for a complete overview of all functionality:

* :class:`compas.datastructures.CellNetwork`
* :class:`compas.datastructures.HalfFace`


CellNetwork Construction
========================

CellNetworks can be constructed in a number of ways:

* from scratch, by adding vertices, faces and cells one by one,
* using a special constructor function, or
* from the data contained in a file.

From Scratch
------------

>>> from compas.datastructures import CellNetwork
>>> cell_network = CellNetwork()
>>> vertices = [(0, 0, 0), (0, 1, 0), (1, 1, 0), (1, 0, 0), (0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1)]
>>> faces = [[0, 1, 2, 3], [0, 3, 5, 4], [3, 2, 6, 5], [2, 1, 7, 6], [1, 0, 4, 7], [4, 5, 6, 7]]
>>> cells = [[0, 1, 2, 3, 4, 5]]
>>> vertices = [cell_network.add_vertex(x=x, y=y, z=z) for x, y, z in vertices]
>>> faces = [cell_network.add_face(fverts) for fverts in faces]
>>> cells = [cell_network.add_cell(fkeys) for fkeys in cells]
>>> print(cell_network)
<CellNetwork with 8 vertices, 6 faces, 1 cells, 12 edges>

Using Constructors
------------------

>>> from compas.datastructures import CellNetwork
>>> cell_network = CellNetwork.from_vertices_and_cells(...)


From Data in a File
-------------------

>>> from compas.datastructures import CellNetwork
>>> cell_network = CellNetwork.from_obj(...)
>>> cell_network = CellNetwork.from_json(...)


Visualisation
=============

Like all other COMPAS geometry objects and data structures, cell networks can be visualised by placing them in a scene.
For more information about visualisation with :class:`compas.scene.Scene`, see :doc:`/userguide/basics.visualisation`.

>>> import compas
>>> from compas.datastructures import CellNetwork
>>> from compas.scene import Scene
>>> cell_network = CellNetwork.from_json(compas.get('cellnetwork_example.json'))
>>> scene = Scene()
>>> scene.add(mesh)
>>> scene.show()

.. figure:: /_images/userguide/basics.datastructures.cellnetworks.example_grey.png


Vertices, Edges, Faces, Cells
=============================

The cell network contains mixed topologic entities such as cells, faces, edges and vertices.
* Vertices are identified by a positive integer that is unique among the vertices of the current mesh.
* Edges are identified by a pair (tuple) of two vertex identifiers.
* Faces are identified by a positive integer that is unique among the faces of the current mesh.
* Cells are identified by a positive integer that is unique among the cells of the current mesh.

>>> cell_network = CellNetwork.from_json(compas.get('cellnetwork_example.json'))
>>> cell_network.number_of_vertices()
44
>>> cell_network.number_of_edges()
91
>>> cell_network.number_of_faces()
43
>>> cell_network.number_of_cells()
6

An edge can be assigned to any number of faces, or to none. If an edge is assigned to more than 2 faces, it is non-manifold.

>>> cell_network.edge_faces((2, 6))
[2, 3, 39]
>>> cell_network.edge_faces((1, 10))
[8]
>>> cell_network.edge_faces((43, 34))
[]
>>> cell_network.edges_without_face()
[(43, 34)]
>>> nme = cell_network.nonmanifold_edges()

A face can be at maximum assigned to two cells, to one or None. A face is on the boundary if is is exactly assigned to one cell.

>>> cell_network.face_cells(7)
[12, 8]
>>> cell_network.face_cells(9)
[8]
>>> cell_network.faces_without_cell()
[34, 35, 36, 37, 38, 39]
>>> boundary = cell_network.faces_on_boundaries()
>>> boundary
[1, 2, 3, 5, 9, 10, 11, 13, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 30, 31, 32, 40, 41, 42, 43, 44, 49]

If all cells are connected, those faces form a closed cell as well:

>>> cell_network.is_faces_closed(boundary)
True

This shows only the faces on the boundary displayed.

.. figure:: /_images/userguide/basics.datastructures.cellnetworks.example_hull.png


If we want to add a cell, we need to provide a list of face keys that form a closed volume.
If they don't, the cell will not be added.

In the following image, the faces belonging to 2 cells are showin in yellow, the faces to one cell are shown in grey, and the faces belonging to no cell are shown in blue.
There is also one edge without face, shown with thicker linewidth.

.. figure:: /_images/userguide/basics.datastructures.cellnetworks.example_color.png




34 changes: 34 additions & 0 deletions docs/userguide/basics.datastructures.cellnetworks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import os

from compas_viewer import Viewer

import compas
from compas.colors import Color
from compas.datastructures import CellNetwork
from compas.geometry import Line
from compas.geometry import Polygon

cell_network: CellNetwork = CellNetwork.from_json(compas.get("cellnetwork_example.json")) # type: ignore

viewer = Viewer(show_grid=False)

no_cell = cell_network.faces_without_cell()

for face in cell_network.faces():
if cell_network.is_face_on_boundary(face) is True:
color, opacity = Color.silver(), 0.5
elif face in no_cell:
color, opacity = Color.azure(), 0.3
else:
color, opacity = Color.yellow(), 0.8

viewer.scene.add(Polygon(cell_network.face_coordinates(face)), facecolor=color, opacity=opacity)

for edge in cell_network.edges_without_face():
line = Line(*cell_network.edge_coordinates(edge))
viewer.scene.add(line, linewidth=3)

graph = cell_network.cells_to_graph()
viewer.scene.add(graph)

viewer.show()
2 changes: 1 addition & 1 deletion docs/userguide/basics.datastructures.meshes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ Halfedge Data Structure
The topology of a mesh is stored in a halfedge data structure.
In this data structure, vertices are connected to other vertices, and faces to other faces, via edges.
An edge has two connected vertices, and at most two connected faces.
Each each is split into two halfedges, one for each of the connected faces.
Each edge is split into two halfedges, one for each of the connected faces.
If an edge has only one connected face, the edge is on the boundary.

Note that in a mesh constructed using :meth:`compas.datastructures.Mesh.from_meshgrid`, the vertices are organised in a specific way.
Expand Down
2 changes: 1 addition & 1 deletion docs/userguide/basics.datastructures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Datastructures
basics.datastructures.graphs
basics.datastructures.meshes
basics.datastructures.cells
basics.datastructures.cellnetwork
basics.datastructures.trees
basics.datastructures.assemblies
Loading

0 comments on commit 4ba6b5e

Please sign in to comment.