diff --git a/.editorconfig b/.editorconfig index aed9aa0c366..4edb55d3deb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,13 +16,15 @@ end_of_line = crlf [*.md] trim_trailing_whitespace = false +[*.yml] +indent_size = 2 + +[*.rst] +indent_size = 4 + [Makefile] indent_style = tab indent_size = 4 -[*.yml] -indent_style = space -indent_size = 2 - [LICENSE] insert_final_newline = false diff --git a/.gitignore b/.gitignore index ea0011a574b..881ef29b8b6 100644 --- a/.gitignore +++ b/.gitignore @@ -144,4 +144,5 @@ dev NOTES -src/compas_blender/conversions/__temp/ \ No newline at end of file +src/compas_blender/conversions/__temp/ +docs/reference/__old/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 4913f2cf5fa..d2276103b80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added `compas.geometry.Torus.to_brep()`. * Added `compas.brep.Brep.from_iges()`. * Added `compas.brep.Brep.to_iges()`. +* Added `compas.scene.Scene`. ### Changed @@ -26,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Changed `compas.brep.Brep.from_step_file` to `from_step`. * Moved `compas.brep` to `compas.geometry.brep`. * Updated `compas-actions.docs` workflow to `v3`. +* `Artists` classes are renamed to `SceneObject` classes and now under `compas.scene`, `compas_rhino.scene`, `compas_ghpython.scene`, `compas_blender.scene`. ### Removed @@ -38,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added `Frame.axes` * Added `compas.datastructures.TreeNode` and `compas.datastructures.Tree` classes. * Added `EllipseArtist` to `compas_rhino` and `compas_ghpython`. +* Added `compas.scene.Scene`. ### Changed diff --git a/docs/_images/ghpython_custom.jpg b/docs/_images/ghpython_custom.jpg new file mode 100644 index 00000000000..4fc16847be6 Binary files /dev/null and b/docs/_images/ghpython_custom.jpg differ diff --git a/docs/_images/vscode_git.JPG b/docs/_images/vscode_git.JPG new file mode 100644 index 00000000000..04c76eaf9db Binary files /dev/null and b/docs/_images/vscode_git.JPG differ diff --git a/docs/_static/compas.css b/docs/_static/compas.css index bc31a2761d1..2e2ba3946c1 100644 --- a/docs/_static/compas.css +++ b/docs/_static/compas.css @@ -14,6 +14,21 @@ body { font-weight: 300; } +@media (min-width: 960px) { + .bd-page-width { + max-width: 106rem; + } + .bd-sidebar-primary { + width: 20%; + } + .bd-main { + flex-grow: 1; + } + .bd-main .bd-content .bd-article-container { + max-width: 66rem; + } +} + .bd-header { box-shadow: none; border-bottom: 1px solid var(--pst-color-shadow); @@ -25,48 +40,10 @@ body { display: none; } -/* .bd-sidebar-primary { - width: 20%; -} */ - -/* .bd-content { - flex-grow: 1; - max-width: 100%; -} - -.bd-page-width { - max-width: 100%; -} - -.bd-sidebar-primary { - padding-top: 1rem; -} */ - .bd-sidebar-primary .toctree-l3 { font-size: 0.8rem; } -@media (min-width: 960px) { - /* .bd-sidebar-primary { - max-width: 20%; - } */ - /* html[data-theme="light"] .bd-sidebar-primary { - background-color: var(--pst-color-surface); - } */ -} - -/* html[data-theme="light"] .bd-header { - background-color: var(--pst-color-primary); -} - -html[data-theme="light"] .bd-header .navbar-nav .nav-link { - color: rgba(255, 255, 255, 0.5); -} - -html[data-theme="light"] .bd-header .navbar-nav > .active > .nav-link { - color: rgba(255, 255, 255, 1); -} */ - .navbar-brand img { height: 32px; } @@ -82,15 +59,6 @@ dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(. margin-top: 1rem; } -/* .bd-header-announcement::after { - background-color: var(--pst-color-attention); -} */ - -.lead { - font-size: 1rem !important; - font-weight: unset; -} - .highlight pre { line-height: 150% !important; /* font-size: 0.75rem; */ @@ -99,7 +67,3 @@ dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(. .bd-footer-article { margin-top: 2rem; } - -/* .bd-breadcrumbs { - margin-top: 1rem; -} */ diff --git a/docs/conf.py b/docs/conf.py index 2ceb2490ee2..b2ddd4f1976 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -42,7 +42,7 @@ def get_latest_version(): ".md": "markdown", } templates_path = sphinx_compas_theme.get_autosummary_templates_path() + ["_templates"] -exclude_patterns = ["_build", "**.ipynb_checkpoints", "_notebooks", "**/__temp"] +exclude_patterns = ["_build", "**.ipynb_checkpoints", "_notebooks", "**/__temp", "**/__old"] # pygments_style = "sphinx" # pygments_dark_style = "monokai" @@ -59,11 +59,10 @@ def get_latest_version(): "sphinx.ext.doctest", "sphinx.ext.intersphinx", "sphinx.ext.mathjax", - # "sphinx.ext.linkcode", + "sphinx.ext.linkcode", "sphinx.ext.extlinks", "sphinx.ext.githubpages", "sphinx.ext.coverage", - # "sphinx.ext.inheritance_diagram", "sphinx.ext.graphviz", "matplotlib.sphinxext.plot_directive", "sphinx.ext.autodoc.typehints", @@ -72,8 +71,8 @@ def get_latest_version(): "sphinx_togglebutton", "sphinx_remove_toctrees", "sphinx_copybutton", - # "sphinxcontrib.bibtex", "numpydoc", + "sphinx.ext.viewcode", ] # remove_from_toctrees = ["api/generated/*"] @@ -285,29 +284,22 @@ def visit_reference(self, node): "navbar_center": ["navbar-nav"], "navbar_end": [ "version-switcher", - # "theme-switcher", + "theme-switcher", "navbar-icon-links", ], "navbar_persistent": ["search-button"], "navbar_align": "content", - "article_header_start": [ - # "breadcrumbs" - ], + "article_header_start": ["breadcrumbs"], "article_header_end": [], - "primary_sidebar_end": [ - # "sidebar-ethical-ads" - ], + "primary_sidebar_end": [], "secondary_sidebar_items": ["page-toc", "edit-this-page", "sourcelink"], "article_footer_items": ["prev-next.html"], "show_prev_next": True, - # "content_footer_items": [], "footer_start": ["copyright", "sphinx-version"], "footer_end": ["theme-version"], # navigation and links "external_links": [ - # {"name": "Changelog", "url": "https://github.com/compas-dev/compas/releases"}, {"name": "COMPAS Framework", "url": "https://compas.dev"}, - # {"name": "COMPAS Association", "url": "https://compas.dev/association"}, ], "header_links_before_dropdown": 5, "icon_links": [ @@ -362,7 +354,6 @@ def visit_reference(self, node): html_sidebars = { "**": [ "sidebar-nav-bs", - # "sidebar-ethical-ads", ], } diff --git a/docs/devguide/code.rst b/docs/devguide/code.rst index 38a53b0fbf7..ce72b9caadb 100644 --- a/docs/devguide/code.rst +++ b/docs/devguide/code.rst @@ -1,2 +1,181 @@ -Code Constributions +.. _code-contributions: + +Code Contributions =================== + +.. note:: + For the proper way of contributing code to COMPAS, please follow the :ref:`development-workflow`. + +To keep code clean, consistent and readable we try to follow the following guidelines when developing COMPAS. +Generally, we try to follow the `PEP8 `_ style guide for Python code. + +Naming conventions +------------------ + +.. note:: + + When naming **variables**, **functions**, **classes** and **modules** it is important to take the time and choose meaningful names. + Names should be short but descriptive and ideally unambiguous in the field they are intended to be used. + +**Classes** should be named using the ``CamelCase`` convention + +.. code-block:: python + + class MyClass(object): + ... + +**Functions**, **methods**, **arguments** and **local/member variables** should be named using the ``snake_case`` convention + +.. code-block:: python + + def my_function(): + ... + + def add(self, x, y): + result = x + y + return result + +**Functions**, **methods** and **member variables** which are intended for internal use only should be prefixed with an ``_`` (underscore) + +.. code-block:: python + + class Rectangle(object): + + def __init__(self, width, lentgh): + self._width = width + self._length = length + self._area = None + self._init_class() + + def _init_class(): + self._area = self._width * self._length + + @staticmethod + def _some_helper_function(): + ... + + +**Class attributes** should be named using all caps and underscores + +.. code-block:: python + + class MyClass(object): + MY_CONSTANT = 42 + + def __init__(self): + self.my_attribute = 0 + + def my_method(self): + return self.my_attribute + self.MY_CONSTANT + +Line length +----------- + +**COMPAS uses a line length of 120 characters**. While longer than the 80 characters recommended by ``PEP8``, it is in our opinion a more reasonable limit for modern displays. +This is enforced and can be automatically set using ``black -l 120``. + +**Indentations are 4 spaces**. Tab to spaces setting can be set in ``.editorconfig`` which is respected by most editors. For more information see `EditorConfig `_. + +Imports +------- + +Imports are grouped in the following order with a blank line between each group: + +1. Python standard library imports +2. Third party imports +3. Local application imports + +Single-item imports are preferred over multi-item imports + +.. code-block:: python + + # use: + from compas.geometry import Frame + from compas.geometry import Point + + # instead of: + from compas.geometry import Frame, Point + +Star (``*``) imports should be avoided. + +Second-level imports +-------------------- +To keep the API clean and consistent, any new public functions or classes should be importable from a second-level package. +This is achieved by importing the function or class in the ``__init__.py`` file of the package. + +For example: + +.. code-block:: bash + + compas + ├── __init__.py + └── my_package + ├── __init__.py + └── new_module.py + +.. code-block:: python + + # new_module.py + class NewClass(object): + ... + +.. code-block:: python + + # compas.my_package.__init__.py + from .new_module import NewClass + + __all__ = ['NewClass'] + +The result should be: + +.. code-block:: python + + >>> from compas.my_package import NewClass + +Comments +-------- + +The code should be self-explanatory and comments should be used sparingly. However, if a portion of the code is best understood in a certain context, a comment could be added. + +.. code-block:: python + + def my_function(): + # while seems unlikely, 42 is the answer to everything + return some_piece_of_code() + 42 + +Docstrings +---------- + +Docstings in the COMPAS ecosystem follow the `NumPy style docstrings `_. +These docstrings are later used by `Sphinx `_ to generate the API documentation. + +Therefore, it is important that functions and methods have at least the following docstrings: + +.. code-block:: python + + def my_function(point, line): + """This is a one-line description of the function. + + This is a longer description of the function. + It can span multiple lines. + + Parameters + ---------- + point : :class:`~compas.geometry.Point` + Point to check. + line : :class:`~compas.geometry.Line` + Line to analyze. + + Returns + ------- + :class:`~compas.geometry.Plane` + The resulting plane of the operation. + + """ + ... + +Python 2.7 compatibility +------------------------ + +**To keep COMPAS usable in Rhino, we make sure to maintain Python 2.7 compatibility** in parts of the package which are used in Rhino. +Packages that are not intended to be used in Rhino can utilise Python 3 features. diff --git a/docs/devguide/ghcomponent.rst b/docs/devguide/ghcomponent.rst index 447e33075b1..79ca83f0557 100644 --- a/docs/devguide/ghcomponent.rst +++ b/docs/devguide/ghcomponent.rst @@ -1,2 +1,181 @@ +.. _developing-components: + Developing a GH Component -========================= \ No newline at end of file +========================== + +The COMPAS ecosystem offers excellent integration with Grasshopper. Thanks to the `GHPython Componentizer `_ +it is possible to write Grasshopper components in Python, in a git friendly way, including the components' code in the same repository as the rest of your project. + +.. note:: + To develop GH components using the GHPython Componentizer, you would need a development setup of COMPAS. See :ref:`dev_setup` for more information. + +GHPython Componentizer +---------------------- + +To use the Componentizer, it is recommended that your project's repository be made from the `cookiecutter template for COMPAS packages `_. +This takes care of a lot of the boilerplate code, and makes compiling and installing the components so much easier. + +The ``ghuser`` section in the ``tasks.py`` file of your project tell the Componentizer where to find the source code of your components, and where to put the generated components. + +By default, the components' code is expected in ``src/{your_package_name}/components`` folder of your project. + +.. code-block:: python + + ns.configure( + { + "ghuser": { + "source_dir": "src/compas_bananas/components", + "target_dir": "src/compas_bananas/components/ghuser", + "prefix": "(COMPAS_BANANAS)", + }, + } +) + +Creating a component +-------------------- + +Inside the ``source_dir`` folder, each component shall have its own folder with the following three files: + +1. ``code.py`` - this is where our component's code goes +2. ``metadata.json`` - this is where we let the Componentizer know about different settings of our component +3. ``icon.png`` - this icon will appear in GH. It must be exactly 24x24 pixels. + +.. note:: + + By convension, we name the component folders with a two letter prefix, followed by an underscore, followed by the name of the component. For example, ``Cb_ExampleComponent``. + +.. code-block:: bash + + src/compas_bananas/components/Cb_ExampleComponent + ├── code.py + ├── icon.png + └── metadata.json + +Metadata +-------- + +A typical ``metadata.json`` file has the following structure: + +.. code-block:: json + + { + "name": "Example Component", + "nickname": "Example", + "category": "COMPAS Bananas", + "subcategory": "Example", + "description": "This is an example component.", + "exposure": 4, + "ghpython": { + "isAdvancedMode": true, + "iconDisplay": 0, + "inputParameters": [ + { + "name": "Arg1", + "description": "First example argument.", + "typeHintID": "none", + "scriptParamAccess": 1 + }, + { + "name": "Arg2", + "description": "Second example argument.", + "typeHintID": "bool", + "scriptParamAccess": 0 + } + ], + "outputParameters": [ + { + "name": "Output1", + "description": "First output." + }, + { + "name": "Output2", + "description": "Second output." + } + ] + } + } + +For more information about the required fields and their possible values please visit `GHPython Componentizer `_. + +Code +---- + +The GHPython Componentizer only supports GHPython components in advanced mode. +This means each component must inherit from the ``ghpythonlib.component`` class and implement the ``RunScript()`` method. + +A typical ``code`` file might look like this: + +.. code-block:: python + + from ghpythonlib.componentbase import executingcomponent as component + + class ExampleComponent(component): + + def RunScript(self, Input1, Input2): + # do the work here + Output1 = None + Output2 = None + return Output1, Output2 + +Please not that the inputs to the ``RunScript()`` method must match the ones defined in the ``metadata.json`` file by name and number. +The outputs must also match the ones defined in the ``metadata.json`` file by name and number. + +Icon +---- + +Finally, the component's folder must include an icon used to represent the component in GH. +The icon must be a 24x24 pixel PNG file named ``icon.png``. + +Compiling the components +------------------------ + +.. note:: + + IronPython 2.7 must be installed on your system in order to run the Componentizer. + You can download it from `here `_ + +In order to run the Componentizer make sure your dev virtual environment is activated and run + +.. code-block:: bash + + invoke build-ghuser-components + +If everything went well, you should see at least the following output: + +.. code-block:: bash + + Processing component bundles: + [x] Cb_ExampleComponent => C:\Users\path_to_repo\src\project_slug\ghpython\components\ghuser\Cb_ExampleComponent.ghuser + +If any error occurs, the Componentizer will let you know what went wrong. + +Installing the components to Rhino +---------------------------------- + +Once the components are compiled, and are in the ``target_dir`` folder, you can install them to Rhino by running + +.. code-block:: bash + + python -m compas_rhino.install -v 7.0 + +.. code-block:: bash + + You should then see + + Installing COMPAS packages to Rhino 7.0 scripts folder: + C:\Users\username\AppData\Roaming\McNeel\Rhinoceros\7.0\scripts + + compas OK + compas_ghpython OK + compas_rhino OK + compas_bananas OK + + Running post-installation steps... + + compas_bananas OK: Installed 1 GH User Objects + + +You component should now appear in Grasshopper + +.. image:: ../_images/ghpython_custom.jpg + :align: center diff --git a/docs/devguide/index.rst b/docs/devguide/index.rst index 1db0ec8eb1a..450097bc258 100644 --- a/docs/devguide/index.rst +++ b/docs/devguide/index.rst @@ -3,18 +3,15 @@ Developer Guide This guide is intended for developers who want to contribute to the code and/or documentation of COMPAS. -1. Setup (Development Environment) -2. Development Workflow -3. Code Contributions -4. Documentation Contributions -5. Developing an Extension -6. Developing a Plugin -7. Developing a GH Component -8. Implementing a New Data Type - - .. toctree:: - :maxdepth: 1 - :titlesonly: + :maxdepth: 1 + :titlesonly: - workflow \ No newline at end of file + setup + workflow + code + documentation + extensions + plugins + ghcomponent + dtypes diff --git a/docs/devguide/setup.rst b/docs/devguide/setup.rst index eca42adec8c..da13e2d9b8a 100644 --- a/docs/devguide/setup.rst +++ b/docs/devguide/setup.rst @@ -1,2 +1,48 @@ +.. _dev_setup: + Development Setup ================= + +.. note:: + This section is for you if you are intending to develop for COMPAS. If you + just want to use it, please check out the user :ref:`user_guide_install` guide. + +Tools +----- +To get started you would need to install the following tools: + +* Text/code editor +* Git +* Python (virtual environment) + +Text/code editor +---------------- +While any text editor can be used for developing COMPAS, we recommend using `Visual Studio Code `_. +It is free to use, open source and has a lot of useful features for developing python code. + +Git +--- +For version control we use `git `_. Our remote repository is hosted on `GitHub `_ + +While git offers an extensive command line interface, there are plentty of GUI based clients out there including: + +* `GitHub Desktop `_ +* `SourceTree `_ + +VS Code also has a built-in git client + +.. image:: ../_images/vscode_git.JPG + :align: center + +Python virtual environments +--------------------------- + +During development there might be a need to install different versions of different dependencies, some of them might conflict with ones used for other projects. +Moreover, using early development code can often lead to a corrupt python environment which can be hard to fix. For these reasons it is highly recommended to use virtual environments for development. + +For developing COMPAS we recommend using `conda `_. + +Installing COMPAS for development +--------------------------------- + +See the :ref:`development-workflow` for more details on how to install COMPAS for development and how to contribute to the project. diff --git a/docs/devguide/workflow.rst b/docs/devguide/workflow.rst index 2d41a809e51..f59b5a58b90 100644 --- a/docs/devguide/workflow.rst +++ b/docs/devguide/workflow.rst @@ -1,3 +1,5 @@ +.. _development-workflow: + Development Workflow ==================== @@ -46,7 +48,7 @@ Making changes 2. Making and pushing changes. Go ahead and make a few changes to the project using your favorite text editor. When you're ready to submit your changes, stage and commit your changes. Please use clear commit messages detailing the changes made. - + .. code-block:: bash git add . @@ -113,7 +115,7 @@ The procedure for submitting a PR is the following. * If your PR adds a new feature, add ``New feature`` to the description. * If your PR fixes a bug, add ``Bug fix`` to the description. * If your PR changes the API, add ``Breaking change`` to the description. - + 6. Wait for the tests to pass and for the code to be reviewed. We review pull requests as soon as we can, typically within a week. If you get no review comments within two weeks, feel free to ask for feedback by adding a comment on your PR (this will notify maintainers). Thank you! diff --git a/docs/index.rst b/docs/index.rst index 0edf9d9417a..96d508c6ca4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,6 +10,13 @@ This is the documentation of the core infratructure of COMPAS, an open source framework for computational research and collaboration in Architecture, Engineering, Fabrication, and Construction. +.. note:: + + This is the documentation of the core Python package of COMPAS. + If you are looking for the COMPAS Framework website, + please go to https://compas.dev. + + User Guide ========== @@ -17,31 +24,38 @@ If you want to use COMPAS for your research or in one of your projects, this is the place to start. .. toctree:: - :maxdepth: 2 - :titlesonly: + :maxdepth: 2 + :titlesonly: - userguide/index + userguide/index -Development -=========== +API Reference +============= -If you want to contribute to COMPAS, this is the place to start. +The reference documentation of the core package and the CAD packages. .. toctree:: - :maxdepth: 2 - :titlesonly: + :maxdepth: 2 - devguide/index + reference/index -API Reference -============= +Development +=========== -The reference documentation of the core package and the CAD packages. +If you want to contribute to COMPAS, this is the place to start. .. toctree:: - :maxdepth: 2 - :titlesonly: + :maxdepth: 2 + :titlesonly: + + devguide/index + + +Indices and tables +================== - reference/index +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/reference/compas.artists.rst b/docs/reference/compas.artists.rst deleted file mode 100644 index acbd32377d7..00000000000 --- a/docs/reference/compas.artists.rst +++ /dev/null @@ -1,37 +0,0 @@ -******************************************************************************** -compas.artists -******************************************************************************** - -.. currentmodule:: compas.artists - -.. rst-class:: lead - -For visualization of geometry objects and data structures, COMPAS provides "artists". -Every object type is paired with a corresponding artist type that is capable of visualizing the data of the object. -This package provides base artist classes with pluggable methods -that receive an implementation from plugins defined by various visualization contexts. - - -Classes -======= - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - Artist - GeometryArtist - MeshArtist - NetworkArtist - VolMeshArtist - - -Exceptions -========== - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - DataArtistNotRegistered - NoArtistContextError diff --git a/docs/reference/compas.colors.rst b/docs/reference/compas.colors.rst index c0267d6e744..01b61f2ddca 100644 --- a/docs/reference/compas.colors.rst +++ b/docs/reference/compas.colors.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.colors ******************************************************************************** @@ -6,8 +7,8 @@ compas.colors .. rst-class:: lead -This package provides a class for working with colors in different color spaces, -and color maps for various color palettes. +This package defines a color and color map class, +that can be used to work wihth colors in a consistent way across color spaces. Classes @@ -22,9 +23,4 @@ Classes ColorMap -HTML Colors -=========== -.. toctree:: - - compas.colors.html_colors diff --git a/docs/reference/compas.data.rst b/docs/reference/compas.data.rst index 90469593b35..e0b222e2393 100644 --- a/docs/reference/compas.data.rst +++ b/docs/reference/compas.data.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.data ******************************************************************************** @@ -6,8 +7,8 @@ compas.data .. rst-class:: lead -This package provides a base data class for all COMPAS data objects such as geometry objects, robots, and data structures, -and the infrastructure for data validation, conversion, coercion, and JSON serialisation. +This package defines the core infrastructure for data serialisation in the COMPAS framework. +It provides a base class for data objects, a JSON encoder and decoder, serialisers and deserialisers, and schema validation. Classes @@ -18,8 +19,9 @@ Classes :nosignatures: Data - DataEncoder DataDecoder + DataEncoder + DecoderError Functions @@ -29,18 +31,11 @@ Functions :toctree: generated/ :nosignatures: - json_load - json_loads + compas_dataclasses + dataclass_dataschema + dataclass_jsonschema + dataclass_typeschema json_dump json_dumps - - -Exceptions -========== - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - DecoderError - + json_load + json_loads diff --git a/docs/reference/compas.datastructures.rst b/docs/reference/compas.datastructures.rst index b4375033e25..f9a3955c1b8 100644 --- a/docs/reference/compas.datastructures.rst +++ b/docs/reference/compas.datastructures.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.datastructures ******************************************************************************** @@ -6,7 +7,9 @@ compas.datastructures .. rst-class:: lead -This package provides functionality for working with topologically structured data. +This package defines the core data structures of the COMPAS framework. +The data structures provide a structured way of storing and accessing data on individual components of both topological and geometrical objects. + Classes ======= @@ -15,83 +18,42 @@ Classes :toctree: generated/ :nosignatures: - Datastructure + Assembly + AssemblyError + BaseMesh + BaseNetwork + BaseVolMesh CellNetwork + Datastructure + Feature + FeatureError + GeometricFeature Graph HalfEdge HalfFace Mesh Network - VolMesh - Assembly - Part - Feature - GeometricFeature ParametricFeature - - -Exceptions -========== - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - AssemblyError - FeatureError + Part + Tree + TreeNode + VolMesh Functions ========= -Network -------- - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - network_adjacency_matrix - network_complement - network_connectivity_matrix - network_count_crossings - network_degree_matrix - network_disconnected_edges - network_disconnected_nodes - network_embed_in_plane_proxy - network_embed_in_plane - network_explode - network_find_crossings - network_find_cycles - network_is_connected - network_is_crossed - network_is_planar_embedding - network_is_planar - network_is_xy - network_join_edges - network_laplacian_matrix - network_polylines - network_shortest_path - network_smooth_centroid - network_split_edge - network_transform - network_transformed - -Mesh ----- - .. autosummary:: :toctree: generated/ :nosignatures: mesh_add_vertex_to_face_edge mesh_adjacency_matrix - mesh_bounding_box_xy mesh_bounding_box + mesh_bounding_box_xy mesh_collapse_edge mesh_connected_components mesh_connectivity_matrix - mesh_contours_numpy mesh_conway_ambo mesh_conway_bevel mesh_conway_dual @@ -115,15 +77,11 @@ Mesh mesh_face_matrix mesh_flatness mesh_flip_cycles - mesh_geodesic_distances_numpy mesh_insert_vertex_on_edge mesh_is_connected - mesh_isolines_numpy mesh_laplacian_matrix mesh_merge_faces mesh_offset - mesh_oriented_bounding_box_numpy - mesh_oriented_bounding_box_xy_numpy mesh_planarize_faces mesh_quads_to_triangles mesh_slice_plane @@ -133,63 +91,83 @@ Mesh mesh_split_edge mesh_split_face mesh_split_strip + mesh_subdivide mesh_subdivide_catmullclark mesh_subdivide_corner mesh_subdivide_doosabin mesh_subdivide_frames mesh_subdivide_quad mesh_subdivide_tri - mesh_subdivide mesh_substitute_vertex_in_faces mesh_thicken mesh_transform - mesh_transform_numpy mesh_transformed - mesh_transformed_numpy mesh_unify_cycles mesh_unweld_edges mesh_unweld_vertices mesh_weld - meshes_join_and_weld meshes_join + meshes_join_and_weld + network_adjacency_matrix + network_complement + network_connectivity_matrix + network_count_crossings + network_degree_matrix + network_disconnected_edges + network_disconnected_nodes + network_embed_in_plane + network_embed_in_plane_proxy + network_explode + network_find_crossings + network_find_cycles + network_is_connected + network_is_crossed + network_is_planar + network_is_planar_embedding + network_is_xy + network_join_edges + network_laplacian_matrix + network_polylines + network_shortest_path + network_smooth_centroid + network_split_edge + network_transform + network_transformed trimesh_collapse_edge trimesh_cotangent_laplacian_matrix trimesh_descent trimesh_face_circle trimesh_gaussian_curvature trimesh_mean_curvature - trimesh_pull_points_numpy trimesh_remesh - trimesh_samplepoints_numpy trimesh_smooth_laplacian_cotangent trimesh_split_edge trimesh_subdivide_loop trimesh_swap_edge trimesh_vertexarea_matrix - -VolMesh -------- - -.. autosummary:: - :toctree: generated/ - :nosignatures: - volmesh_bounding_box volmesh_transform volmesh_transformed -Assembly --------- +Functions using Numpy +===================== + +In environments where numpy is not available, these functions can still be accessed through RPC. .. autosummary:: :toctree: generated/ :nosignatures: + mesh_contours_numpy + mesh_geodesic_distances_numpy + mesh_isolines_numpy + mesh_oriented_bounding_box_numpy + mesh_oriented_bounding_box_xy_numpy + mesh_transform_numpy + mesh_transformed_numpy + trimesh_pull_points_numpy + trimesh_samplepoints_numpy + -CellNetwork -------- -.. autosummary:: - :toctree: generated/ - :nosignatures: \ No newline at end of file diff --git a/docs/reference/compas.files.rst b/docs/reference/compas.files.rst index 8862644fb98..fb7479afdf8 100644 --- a/docs/reference/compas.files.rst +++ b/docs/reference/compas.files.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.files ******************************************************************************** @@ -6,8 +7,7 @@ compas.files .. rst-class:: lead -This package provides classes for working with selected file formats that are capable -of storing information about 2D and 3D geometry, robots, pointclouds, ... +This package defines a number of file formats and provides functionality for reading and writing data in these formats. Classes @@ -26,32 +26,14 @@ Classes XML -Helper Classes -============== +Functions +========= .. autosummary:: :toctree: generated/ :nosignatures: - GLTFContent - GLTFExporter - GLTFMesh - GLTFParser - GLTFReader - OBJParser - OBJReader - OBJWriter - OFFReader - OFFWriter - PLYParser - PLYReader - PLYWriter - STLParser - STLReader - STLWriter - URDFElement - URDFGenericElement - URDFParser - XMLElement - XMLReader - XMLWriter + prettify_string + + + diff --git a/docs/reference/compas.geometry.rst b/docs/reference/compas.geometry.rst index 62d6593405a..a0c5b737155 100644 --- a/docs/reference/compas.geometry.rst +++ b/docs/reference/compas.geometry.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.geometry ******************************************************************************** @@ -6,22 +7,9 @@ compas.geometry .. rst-class:: lead -This package provides a wide range of geometry objects and geometric algorithms -independent from the geometry kernels of CAD software. - - -Base Classes -============ - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - Curve - Geometry - Shape - Surface - Transformation +This package defines all functionality for working with geometry in COMPAS. +It provides classes representing geometric primitives, transformations, (NURBS) curves and surfaces, +shapes, general polygons and polyhedrons, boundary representations (B-reps), and a number of geometry processing algorithms. Classes @@ -35,38 +23,53 @@ Classes Bezier Box Brep - BrepLoop BrepEdge - BrepVertex + BrepError BrepFace + BrepInvalidError + BrepLoop + BrepOrientation + BrepTrim + BrepTrimIsoStatus + BrepTrimmingError + BrepType + BrepVertex Capsule Circle Cone ConicalSurface + Curve Cylinder CylindricalSurface Ellipse Frame + Geometry Hyperbola KDTree Line NurbsCurve NurbsSurface - Plane + Parabola PlanarSurface + Plane Point Pointcloud + Polygon Polyhedron Polyline Projection + Quaternion Reflection Rotation Scale + Shape Shear Sphere SphericalSurface + Surface ToroidalSurface Torus + Transformation Translation Vector @@ -74,86 +77,6 @@ Classes Functions ========= -.. autosummary:: - :toctree: generated/ - :nosignatures: - - bestfit_circle_numpy - bestfit_frame_numpy - bestfit_line_numpy - bestfit_plane - bestfit_plane_numpy - bestfit_sphere_numpy - boolean_difference_mesh_mesh - boolean_difference_polygon_polygon - boolean_intersection_mesh_mesh - boolean_intersection_polygon_polygon - boolean_symmetric_difference_polygon_polygon - boolean_union_mesh_mesh - boolean_union_polygon_polygon - bounding_box - bounding_box_xy - conforming_delaunay_triangulation - constrained_delaunay_triangulation - convex_hull - convex_hull_numpy - convex_hull_xy - convex_hull_xy_numpy - delaunay_from_points - delaunay_from_points_numpy - delaunay_triangulation - discrete_coons_patch - earclip_polygon - icp_numpy - intersection_line_line - intersection_segment_segment - intersection_line_segment - intersection_line_plane - intersection_segment_plane - intersection_polyline_plane - intersection_line_triangle - intersection_plane_plane - intersection_plane_plane_plane - intersection_sphere_sphere - intersection_segment_polyline - intersection_sphere_line - intersection_plane_circle - intersection_line_line_xy - intersection_line_segment_xy - intersection_line_box_xy - intersection_polyline_box_xy - intersection_segment_segment_xy - intersection_circle_circle_xy - intersection_segment_polyline_xy - intersection_ellipse_line_xy - offset_line - offset_polygon - offset_polyline - oriented_bounding_box_numpy - oriented_bounding_box_xy_numpy - quadmesh_planarize - trimesh_descent_numpy - trimesh_gaussian_curvature - trimesh_geodistance - trimesh_gradient_numpy - trimesh_harmonic - trimesh_isolines - trimesh_lscm - trimesh_massmatrix - trimesh_mean_curvature - trimesh_principal_curvature - trimesh_remesh - trimesh_remesh_constrained - trimesh_remesh_along_isoline - trimesh_slice - tween_points - tween_points_distance - voronoi_from_points_numpy - - -Core Functions -============== - .. autosummary:: :toctree: generated/ :nosignatures: @@ -171,11 +94,24 @@ Core Functions angles_points_xy angles_vectors angles_vectors_xy + archimedean_spiral_evaluate + area_polygon + area_polygon_xy + area_triangle + area_triangle_xy argmax argmin + axis_and_angle_from_matrix + axis_angle_from_quaternion + axis_angle_vector_from_matrix + barycentric_coordinates + basis_vectors_from_matrix + bestfit_plane + bounding_box + bounding_box_xy centroid_points - centroid_points_xy centroid_points_weighted + centroid_points_xy centroid_polygon centroid_polygon_edges centroid_polygon_edges_xy @@ -183,7 +119,11 @@ Core Functions centroid_polygon_vertices_xy centroid_polygon_xy centroid_polyhedron + circle_evaluate + circle_from_points + circle_from_points_xy close + closest_line_to_point closest_point_in_cloud closest_point_in_cloud_xy closest_point_on_line @@ -194,12 +134,22 @@ Core Functions closest_point_on_polyline_xy closest_point_on_segment closest_point_on_segment_xy - closest_points_in_cloud_numpy compose_matrix + compute_basisfuncs + compute_basisfuncsderivs + conforming_delaunay_triangulation + constrained_delaunay_triangulation + construct_knotvector + convex_hull + convex_hull_xy cross_vectors cross_vectors_xy decompose_matrix dehomogenize_vectors + delaunay_from_points + delaunay_from_points + delaunay_triangulation + discrete_coons_patch distance_line_line distance_point_line distance_point_line_sqrd @@ -215,25 +165,45 @@ Core Functions divide_vectors_xy dot_vectors dot_vectors_xy + earclip_polygon + ellipse_evaluate + euler_angles_from_matrix + euler_angles_from_quaternion + find_span + helix_evaluate homogenize_vectors identity_matrix + intersection_circle_circle_xy + intersection_ellipse_line_xy + intersection_line_box_xy + intersection_line_line + intersection_line_line_xy + intersection_line_plane + intersection_line_segment + intersection_line_segment_xy + intersection_line_triangle + intersection_mesh_mesh + intersection_plane_circle + intersection_plane_plane + intersection_plane_plane_plane + intersection_polyline_box_xy + intersection_polyline_plane + intersection_ray_mesh + intersection_segment_plane + intersection_segment_polyline + intersection_segment_polyline_xy + intersection_segment_segment + intersection_segment_segment_xy + intersection_sphere_line + intersection_sphere_sphere is_ccw_xy is_colinear is_colinear_line_line is_colinear_xy is_coplanar - is_intersection_line_line - is_intersection_line_line_xy - is_intersection_line_plane - is_intersection_line_triangle - is_intersection_plane_plane - is_intersection_segment_plane - is_intersection_segment_segment - is_intersection_segment_segment_xy is_matrix_square is_parallel_line_line is_point_behind_plane - is_point_in_box is_point_in_circle is_point_in_circle_xy is_point_in_convex_polygon_xy @@ -252,34 +222,87 @@ Core Functions is_polygon_convex is_polygon_convex_xy is_polygon_in_polygon_xy + knots_and_mults_to_knotvector + knotvector_to_knots_and_mults length_vector length_vector_sqrd length_vector_sqrd_xy length_vector_xy + local_axes + local_to_world_coordinates + logarithmic_spiral_evaluate matrix_determinant + matrix_from_axis_and_angle + matrix_from_axis_angle_vector + matrix_from_basis_vectors matrix_from_change_of_basis matrix_from_euler_angles matrix_from_frame matrix_from_frame_to_frame + matrix_from_orthogonal_projection + matrix_from_parallel_projection + matrix_from_perspective_entries + matrix_from_perspective_projection + matrix_from_quaternion + matrix_from_scale_factors + matrix_from_shear + matrix_from_shear_entries + matrix_from_translation matrix_inverse matrix_minor midpoint_line midpoint_line_xy midpoint_point_point midpoint_point_point_xy + mirror_point_plane + mirror_points_line + mirror_points_line_xy + mirror_points_plane + mirror_points_point + mirror_points_point_xy + mirror_vector_vector multiply_matrices multiply_matrix_vector multiply_vectors multiply_vectors_xy norm_vector norm_vectors + normal_polygon + normal_triangle + normal_triangle_xy normalize_vector normalize_vector_xy normalize_vectors normalize_vectors_xy + offset_line + offset_polygon + offset_polyline + orient_points + orthonormalize_axes orthonormalize_vectors power_vector power_vectors + project_point_line + project_point_line_xy + project_point_plane + project_points_line + project_points_line_xy + project_points_plane + quaternion_canonize + quaternion_conjugate + quaternion_from_axis_angle + quaternion_from_euler_angles + quaternion_from_matrix + quaternion_is_unit + quaternion_multiply + quaternion_norm + quaternion_unitize + reflect_line_plane + reflect_line_triangle + rotate_points + rotate_points_xy + scale_points + scale_points_xy scale_vector scale_vector_xy scale_vectors @@ -291,9 +314,88 @@ Core Functions subtract_vectors subtract_vectors_xy sum_vectors + tangent_points_to_circle_xy + transform_frames + transform_points + transform_vectors + translate_points + translate_points_xy + translation_from_matrix transpose_matrix + trimesh_gaussian_curvature + trimesh_geodistance + trimesh_harmonic + trimesh_isolines + trimesh_lscm + trimesh_massmatrix + trimesh_mean_curvature + trimesh_principal_curvature + trimesh_remesh + trimesh_remesh_along_isoline + trimesh_remesh_constrained + trimesh_slice + tween_points + tween_points_distance vector_average vector_component vector_component_xy - vector_variance vector_standard_deviation + vector_variance + volume_polyhedron + world_to_local_coordinates + + +Functions using Numpy +===================== + +In environments where numpy is not available, these functions can still be accessed through RPC. + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + bestfit_circle_numpy + bestfit_frame_numpy + bestfit_line_numpy + bestfit_plane_numpy + bestfit_sphere_numpy + closest_points_in_cloud_numpy + convex_hull_numpy + convex_hull_xy_numpy + dehomogenize_and_unflatten_frames_numpy + dehomogenize_numpy + delaunay_from_points_numpy + homogenize_and_flatten_frames_numpy + homogenize_numpy + icp_numpy + local_to_world_coordinates_numpy + oriented_bounding_box_numpy + oriented_bounding_box_xy_numpy + transform_points_numpy + transform_vectors_numpy + trimesh_descent_numpy + trimesh_gradient_numpy + voronoi_from_points_numpy + world_to_local_coordinates_numpy + + +Pluggables +========== + +Pluggables are functions that don't have an actual implementation, but receive an implementation from a plugin. + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + boolean_difference_mesh_mesh + boolean_difference_polygon_polygon + boolean_intersection_mesh_mesh + boolean_intersection_polygon_polygon + boolean_symmetric_difference_polygon_polygon + boolean_union_mesh_mesh + boolean_union_polygon_polygon + quadmesh_planarize + + + diff --git a/docs/reference/compas.numerical.rst b/docs/reference/compas.numerical.rst index 3f765446855..2c3ffb8c13d 100644 --- a/docs/reference/compas.numerical.rst +++ b/docs/reference/compas.numerical.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.numerical ******************************************************************************** @@ -6,64 +7,53 @@ compas.numerical .. rst-class:: lead -This package provides some basic linear algabra functions, -and matrix-based implementations of various geometric and topological algorithms. - -Solvers -======= - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - pca_numpy - -Isolines -======== - -.. autosummary:: - :toctree: generated/ - :nosignatures: +This package defines a number of numerical utilities. +In future versions, this package will disappear, +and its functionality will be integrated into the geometry and datastructure packages directly. - scalarfield_contours_numpy +Functions using Numpy +===================== -Linalg -====== +In environments where numpy is not available, these functions can still be accessed through RPC. .. autosummary:: :toctree: generated/ :nosignatures: - nullspace - rank - dof - pivots - nonpivots - rref + adjacency_matrix chofactor + connectivity_matrix + degree_matrix + dof + equilibrium_matrix + face_matrix + laplacian_matrix lufactorized - uvw_lengths - normrow + mass_matrix + nonpivots normalizerow + normrow + nullspace + pca_numpy + pivots + rank rot90 + rref solve_with_known spsolve_with_known + stiffness_matrix + uvw_lengths + +Pluggables +========== -Matrices -======== +Pluggables are functions that don't have an actual implementation, but receive an implementation from a plugin. .. autosummary:: :toctree: generated/ :nosignatures: - adjacency_matrix - connectivity_matrix - degree_matrix - equilibrium_matrix - face_matrix - laplacian_matrix - mass_matrix - stiffness_matrix + scalarfield_contours diff --git a/docs/reference/compas.plugins.rst b/docs/reference/compas.plugins.rst index 1d2360ae900..686d8f0c2f3 100644 --- a/docs/reference/compas.plugins.rst +++ b/docs/reference/compas.plugins.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.plugins ******************************************************************************** @@ -9,17 +10,6 @@ compas.plugins COMPAS has an extensible architecture based on plugins that allows to customize and extend the functionality of the core framework. -Check out the developer guide to :ref:`plugins` for additional details. - -Decorators -========== - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - pluggable - plugin Classes ======= @@ -28,14 +18,18 @@ Classes :toctree: generated/ :nosignatures: + IncompletePluginImplError PluginManager + PluginNotInstalledError + PluginValidator + -Exceptions -========== +Functions +========= .. autosummary:: :toctree: generated/ :nosignatures: - IncompletePluginImplError - PluginNotInstalledError + pluggable + plugin diff --git a/docs/reference/compas.rpc.rst b/docs/reference/compas.rpc.rst index 048635479e2..7a6df694d7e 100644 --- a/docs/reference/compas.rpc.rst +++ b/docs/reference/compas.rpc.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.rpc ******************************************************************************** @@ -6,12 +7,14 @@ compas.rpc .. rst-class:: lead + COMPAS runs in many different environments, but in some environments the availablity of libraries is limited. For example, when running COMPAS in an IronPython-based environment like Rhino/Grasshopper, plenty of CPython libraries such as `numpy` and `scipy` are not available. -To workaround this limitation, COMPAS provides a mechanisms to access the -functionality of a CPython environment seemlessly from any other Python environment -through a "Remote Procedure Call" or RPC. +To workaround this limitation, COMPAS provides a mechanisms to access the functionality of a CPython environment seemlessly from any other Python environment through a "Remote Procedure Call" or RPC. +Through RPC, COMPAS can be used as a server for remote clients, and as a client for remote servers. +A typical use case is to run algorithms that require packages like ``numpy`` or ``scipy`` on a remote server, when working in Rhino. +Or to use COMPAS in a browser application. Classes @@ -23,16 +26,7 @@ Classes Dispatcher Proxy - Server - - -Exceptions -========== - -.. autosummary:: - :toctree: generated/ - :nosignatures: - RPCClientError RPCServerError - + Server + XFunc diff --git a/docs/reference/compas.rst b/docs/reference/compas.rst index dab91862796..f1f3e04812e 100644 --- a/docs/reference/compas.rst +++ b/docs/reference/compas.rst @@ -1,24 +1,16 @@ -******************************************************************************** compas -******************************************************************************** - -.. currentmodule:: compas - -.. rst-class:: lead +====== This package is the core package of the COMPAS framework. It defines all functionality for geometry processing, data structures, topology, numerical methods, robotics, the plugin mechanism, remote procedure calls ... and can be used independently of CAD systems in any environment that supports Python programming. -Modules -======= - .. toctree:: - :maxdepth: 1 + :maxdepth: 2 :titlesonly: + :caption: compas - compas.artists compas.colors compas.data compas.datastructures @@ -27,6 +19,5 @@ Modules compas.numerical compas.plugins compas.rpc + compas.scene compas.topology - - diff --git a/docs/reference/compas.scene.rst b/docs/reference/compas.scene.rst new file mode 100644 index 00000000000..56e69a48208 --- /dev/null +++ b/docs/reference/compas.scene.rst @@ -0,0 +1,46 @@ + +******************************************************************************** +compas.scene +******************************************************************************** + +.. currentmodule:: compas.scene + +.. rst-class:: lead + + +This package defines scene objects for visualising COMPAS objects. +Every object type is paired with a corresponding scene object type that is capable of visualizing the data of the object. +The scene objects are implemented as pluggables, and automatically switch between plugins depending on the contexct in which they are used. + + +Classes +======= + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + SceneObject + DataSceneObjectNotRegisteredError + GeometryObject + MeshObject + NetworkObject + NoSceneObjectContextError + VolMeshObject + + +Pluggables +========== + +Pluggables are functions that don't have an actual implementation, but receive an implementation from a plugin. + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + clear + redraw + register_scene_objects + + + diff --git a/docs/reference/compas.topology.rst b/docs/reference/compas.topology.rst index ebd109e1dbc..647c85176ba 100644 --- a/docs/reference/compas.topology.rst +++ b/docs/reference/compas.topology.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas.topology ******************************************************************************** @@ -8,6 +9,7 @@ compas.topology Package containing topological algorithms for traversal, connectivity, combinatorics, etc. + Functions ========= @@ -19,15 +21,29 @@ Functions astar_lightest_path astar_shortest_path breadth_first_ordering - breadth_first_traverse breadth_first_paths + breadth_first_traverse connected_components depth_first_ordering dijkstra_distances dijkstra_path face_adjacency - face_adjacency_numpy shortest_path unify_cycles - unify_cycles_numpy vertex_coloring + + +Functions using Numpy +===================== + +In environments where numpy is not available, these functions can still be accessed through RPC. + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + face_adjacency_numpy + unify_cycles_numpy + + + diff --git a/docs/reference/compas_blender.artists.rst b/docs/reference/compas_blender.artists.rst deleted file mode 100644 index 6f4f537baef..00000000000 --- a/docs/reference/compas_blender.artists.rst +++ /dev/null @@ -1,50 +0,0 @@ -******************************************************************************** -compas_blender.artists -******************************************************************************** - -.. currentmodule:: compas_blender.artists - -.. rst-class:: lead - -Artists for visualizing (painting) COMPAS geometry and data structures in Blender. -The artists in this package provide plugins for the pluggable methods of the base artists defined in :mod:`compas.artists`. -They can be used directly from here (:mod:`compas_blender.artists`), or through the base artist :class:`~compas.artists.Artist`. - - -Classes -======= - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - BoxArtist - CapsuleArtist - CircleArtist - ConeArtist - CurveArtist - CylinderArtist - FrameArtist - LineArtist - MeshArtist - NetworkArtist - PointArtist - PointcloudArtist - PolygonArtist - PolyhedronArtist - PolylineArtist - SphereArtist - SurfaceArtist - TorusArtist - VectorArtist - VolMeshArtist - - -Base Classes -============ - -.. autosummary:: - :toctree: generated/ - - BlenderArtist - diff --git a/docs/reference/compas_blender.conversions.rst b/docs/reference/compas_blender.conversions.rst index 199e09f1d43..2349a28b722 100644 --- a/docs/reference/compas_blender.conversions.rst +++ b/docs/reference/compas_blender.conversions.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas_blender.conversions ******************************************************************************** @@ -6,12 +7,15 @@ compas_blender.conversions .. rst-class:: lead -This package provides classes for converting between COMPAS geometry and Blender geometry. + +This package provides functions to convert between COMPAS data/objects and Blender data/objects. Functions ========= + + .. autosummary:: :toctree: generated/ :nosignatures: @@ -23,6 +27,7 @@ Functions line_to_blender_curve mesh_to_blender mesh_to_compas + meshobj_to_compas monkey_to_compas nurbscurve_to_blender_curve nurbssurface_to_blender_surface @@ -33,3 +38,6 @@ Functions transformation_to_blender transformation_to_compas vertices_and_faces_to_blender_mesh + + + diff --git a/docs/reference/compas_blender.geometry.rst b/docs/reference/compas_blender.geometry.rst index 581890b4cd7..092cb82bb45 100644 --- a/docs/reference/compas_blender.geometry.rst +++ b/docs/reference/compas_blender.geometry.rst @@ -1,5 +1,28 @@ + ******************************************************************************** compas_blender.geometry ******************************************************************************** .. currentmodule:: compas_blender.geometry + +.. rst-class:: lead + + +This package provides plugins for various geometry pluggables using Blender as the backend. + + +Plugins +======= + +Plugins provide implementations for pluggables. You can use the plugin directly, or through the pluggable. + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + boolean_difference_mesh_mesh + boolean_intersection_mesh_mesh + boolean_union_mesh_mesh + + + diff --git a/docs/reference/compas_blender.rst b/docs/reference/compas_blender.rst index e1ec0e76577..9d1fc39bca8 100644 --- a/docs/reference/compas_blender.rst +++ b/docs/reference/compas_blender.rst @@ -1,23 +1,15 @@ -******************************************************************************** compas_blender -******************************************************************************** - -.. currentmodule:: compas_blender - -.. rst-class:: lead +============== This package provides functionality for reading and writing Blender geometry, for visualising COMPAS geometry and data structures in Blender, and for basic user inter interaction. -Modules -======= - .. toctree:: - :maxdepth: 1 + :maxdepth: 2 :titlesonly: + :caption: compas_blender - compas_blender.artists compas_blender.conversions compas_blender.geometry - + compas_blender.scene diff --git a/docs/reference/compas_blender.scene.rst b/docs/reference/compas_blender.scene.rst new file mode 100644 index 00000000000..4c48c6efa5e --- /dev/null +++ b/docs/reference/compas_blender.scene.rst @@ -0,0 +1,47 @@ + +******************************************************************************** +compas_blender.scene +******************************************************************************** + +.. currentmodule:: compas_blender.scene + +.. rst-class:: lead + + +This package provides scene object plugins for visualising COMPAS objects in Blender. +When working in Blender, :class:`compas.scene.SceneObject` will automatically use the corresponding Blender scene object for each COMPAS object type. + + +Classes +======= +BoxObject + + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + BlenderSceneObject + BoxObject + CapsuleObject + CircleObject + ConeObject + CurveObject + CylinderObject + FrameObject + LineObject + MeshObject + NetworkObject + PointObject + PointcloudObject + PolygonObject + PolyhedronObject + PolylineObject + SphereObject + SurfaceObject + TorusObject + VectorObject + VolMeshObject + + + diff --git a/docs/reference/compas_ghpython.artists.rst b/docs/reference/compas_ghpython.artists.rst deleted file mode 100644 index b2a7ba4c345..00000000000 --- a/docs/reference/compas_ghpython.artists.rst +++ /dev/null @@ -1,51 +0,0 @@ -******************************************************************************** -compas_ghpython.artists -******************************************************************************** - -.. currentmodule:: compas_ghpython.artists - -.. rst-class:: lead - -Artists for visualizing (painting) COMPAS geometry and data structures in Grasshopper using the GH Python component. -The artists in this package provide plugins for the pluggable methods of the base artists in :mod:`compas.artists`. -Therefore, they can be used directly, from here, or through the base artists :class:`~compas.artists.Artist`. - - -Classes -======= - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - BoxArtist - BrepArtist - CapsuleArtist - CircleArtist - ConeArtist - CurveArtist - CylinderArtist - EllipseArtist - FrameArtist - LineArtist - MeshArtist - NetworkArtist - PointArtist - PolygonArtist - PolyhedronArtist - PolylineArtist - SphereArtist - SurfaceArtist - TorusArtist - VectorArtist - VolMeshArtist - - -Base Classes -============ - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - GHArtist diff --git a/docs/reference/compas_ghpython.components.rst b/docs/reference/compas_ghpython.components.rst new file mode 100644 index 00000000000..1508b4e75be --- /dev/null +++ b/docs/reference/compas_ghpython.components.rst @@ -0,0 +1,27 @@ + +******************************************************************************** +compas_ghpython.components +******************************************************************************** + +.. currentmodule:: compas_ghpython.components + +.. rst-class:: lead + + +This package provides a small set of functions to easily install and uninstall user-defined GH Components. + + +Functions +========= + + + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + install_userobjects + uninstall_userobjects + + + diff --git a/docs/reference/compas_ghpython.rst b/docs/reference/compas_ghpython.rst index 6d62a99ce49..8156b23c5ee 100644 --- a/docs/reference/compas_ghpython.rst +++ b/docs/reference/compas_ghpython.rst @@ -1,16 +1,14 @@ -******************************************************************************** compas_ghpython -******************************************************************************** - -.. currentmodule:: compas_ghpython - -.. rst-class:: lead +=============== This package provides functionality for reading and writing Rhino geometry, and for visualising COMPAS geometry and data structures in Rhino, through GHPython. .. toctree:: - :maxdepth: 1 + :maxdepth: 2 :titlesonly: + :caption: compas_ghpython + + compas_ghpython.components + compas_ghpython.scene - compas_ghpython.artists diff --git a/docs/reference/compas_ghpython.scene.rst b/docs/reference/compas_ghpython.scene.rst new file mode 100644 index 00000000000..9ef2c524832 --- /dev/null +++ b/docs/reference/compas_ghpython.scene.rst @@ -0,0 +1,47 @@ + +******************************************************************************** +compas_ghpython.scene +******************************************************************************** + +.. currentmodule:: compas_ghpython.scene + +.. rst-class:: lead + + +This package provides scene object plugins for visualising COMPAS objects in Grasshopper. +When working in GH Python components, :class:`compas.scene.SceneObject` will automatically use the corresponding GHPython scene object for each COMPAS object type. + + +Classes +======= + + + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + BoxObject + CapsuleObject + CircleObject + ConeObject + CurveObject + CylinderObject + EllipseObject + FrameObject + GHObject + LineObject + MeshObject + NetworkObject + PointObject + PolygonObject + PolyhedronObject + PolylineObject + SphereObject + SurfaceObject + TorusObject + VectorObject + VolMeshObject + + + diff --git a/docs/reference/compas_rhino.artists.rst b/docs/reference/compas_rhino.artists.rst deleted file mode 100644 index 72d447b997a..00000000000 --- a/docs/reference/compas_rhino.artists.rst +++ /dev/null @@ -1,46 +0,0 @@ -******************************************************************************** -compas_rhino.artists -******************************************************************************** - -.. currentmodule:: compas_rhino.artists - - -Classes -======= - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - BoxArtist - BrepArtist - CapsuleArtist - CircleArtist - ConeArtist - CurveArtist - CylinderArtist - EllipseArtist - FrameArtist - LineArtist - MeshArtist - NetworkArtist - PlaneArtist - PointArtist - PolygonArtist - PolyhedronArtist - PolylineArtist - SphereArtist - SurfaceArtist - TorusArtist - VectorArtist - VolMeshArtist - - -Base Classes -============ - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - RhinoArtist diff --git a/docs/reference/compas_rhino.conversions.rst b/docs/reference/compas_rhino.conversions.rst index d684b8e3198..96ab21b166d 100644 --- a/docs/reference/compas_rhino.conversions.rst +++ b/docs/reference/compas_rhino.conversions.rst @@ -1,3 +1,4 @@ + ******************************************************************************** compas_rhino.conversions ******************************************************************************** @@ -6,10 +7,14 @@ compas_rhino.conversions .. rst-class:: lead -Conversions between Rhino geometry objects (:mod:`Rhino.Geometry`) and COMPAS geometry objects (:mod:`compas.geometry`). -Exceptions -========== +This package provides functions to convert between COMPAS data/objects and Blender data/objects. + + +Classes +======= + + .. autosummary:: :toctree: generated/ @@ -21,6 +26,8 @@ Exceptions Functions ========= + + .. autosummary:: :toctree: generated/ :nosignatures: @@ -49,6 +56,7 @@ Functions cylinder_to_compas cylinder_to_rhino cylinder_to_rhino_brep + data_to_rhino_surface ellipse_to_compas ellipse_to_rhino ellipse_to_rhino_curve @@ -82,8 +90,11 @@ Functions surface_to_rhino torus_to_rhino torus_to_rhino_brep - transformation_to_rhino transformation_matrix_to_rhino + transformation_to_rhino vector_to_compas vector_to_rhino vertices_and_faces_to_rhino + + + diff --git a/docs/reference/compas_rhino.forms.rst b/docs/reference/compas_rhino.forms.rst index 34fef65c217..2d1ce455000 100644 --- a/docs/reference/compas_rhino.forms.rst +++ b/docs/reference/compas_rhino.forms.rst @@ -1,9 +1,12 @@ + ******************************************************************************** compas_rhino.forms ******************************************************************************** .. currentmodule:: compas_rhino.forms +.. rst-class:: lead + Classes ======= @@ -12,18 +15,11 @@ Classes :toctree: generated/ :nosignatures: + BaseForm BrowserForm ChartForm ImageForm + PropertyListForm + SettingsForm SliderForm TextForm - - -Base Classes -============ - -.. autosummary:: - :toctree: generated/ - :nosignatures: - - BaseForm diff --git a/docs/reference/compas_rhino.geometry.rst b/docs/reference/compas_rhino.geometry.rst index 99596728e32..5c354265955 100644 --- a/docs/reference/compas_rhino.geometry.rst +++ b/docs/reference/compas_rhino.geometry.rst @@ -1,12 +1,21 @@ + ******************************************************************************** compas_rhino.geometry ******************************************************************************** .. currentmodule:: compas_rhino.geometry +.. rst-class:: lead + + +This package provides plugins for various geometry pluggables using Rhino as the backend. + + Classes ======= + + .. autosummary:: :toctree: generated/ :nosignatures: @@ -24,20 +33,19 @@ Classes Plugins ======= +Plugins provide implementations for pluggables. You can use the plugin directly, or through the pluggable. + .. autosummary:: :toctree: generated/ :nosignatures: - booleans.boolean_difference_mesh_mesh - booleans.boolean_intersection_mesh_mesh - booleans.boolean_union_mesh_mesh - curves.new_curve - curves.new_nurbscurve - curves.new_nurbscurve_from_interpolation - curves.new_nurbscurve_from_parameters - curves.new_nurbscurve_from_points - curves.new_nurbscurve_from_step - trimesh.trimesh_gaussian_curvature - trimesh.trimesh_mean_curvature - trimesh.trimesh_principal_curvature - trimesh.trimesh_slice + boolean_difference_mesh_mesh + boolean_intersection_mesh_mesh + boolean_union_mesh_mesh + trimesh_gaussian_curvature + trimesh_mean_curvature + trimesh_principal_curvature + trimesh_slice + + + diff --git a/docs/reference/compas_rhino.rst b/docs/reference/compas_rhino.rst index 6d5f1cd43ac..27bd6a60edd 100644 --- a/docs/reference/compas_rhino.rst +++ b/docs/reference/compas_rhino.rst @@ -1,19 +1,16 @@ -******************************************************************************** compas_rhino -******************************************************************************** - -.. currentmodule:: compas_rhino - -.. rst-class:: lead +============ This package provides functionality for reading and writing Rhino geometry, for visualising COMPAS geometry and data structures in Rhino, and for basic user inter interaction. .. toctree:: - :maxdepth: 1 + :maxdepth: 2 :titlesonly: + :caption: compas_rhino - compas_rhino.artists compas_rhino.conversions compas_rhino.forms compas_rhino.geometry + compas_rhino.scene + diff --git a/docs/reference/compas_rhino.scene.rst b/docs/reference/compas_rhino.scene.rst new file mode 100644 index 00000000000..417fabd5589 --- /dev/null +++ b/docs/reference/compas_rhino.scene.rst @@ -0,0 +1,49 @@ + +******************************************************************************** +compas_rhino.scene +******************************************************************************** + +.. currentmodule:: compas_rhino.scene + +.. rst-class:: lead + + +This package provides scene object plugins for visualising COMPAS objects in Rhino. +When working in Rhino, :class:`compas.scene.SceneObject` will automatically use the corresponding Rhino scene object for each COMPAS object type. + + +Classes +======= + + + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + BoxObject + BrepObject + CapsuleObject + CircleObject + ConeObject + CurveObject + CylinderObject + EllipseObject + FrameObject + LineObject + MeshObject + NetworkObject + PlaneObject + PointObject + PolygonObject + PolyhedronObject + PolylineObject + RhinoObject + SphereObject + SurfaceObject + TorusObject + VectorObject + VolMeshObject + + + diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 44c7dafb4bf..836a10f211f 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -1,11 +1,75 @@ -Package Reference -================= +API Reference +============= + +compas +------ + +This package is the core package of the COMPAS framework. +It defines all functionality for geometry processing, +data structures, topology, numerical methods, robotics, the plugin mechanism, remote procedure calls ... +and can be used independently of CAD systems in any environment that supports Python programming. + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :caption: compas + + compas.scene + compas.colors + compas.data + compas.datastructures + compas.files + compas.geometry + compas.numerical + compas.plugins + compas.rpc + compas.topology + + +compas_blender +-------------- + +This package provides functionality for reading and writing Blender geometry, for visualising +COMPAS geometry and data structures in Blender, and for basic user inter interaction. + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :caption: compas_blender + + compas_blender.scene + compas_blender.conversions + compas_blender.geometry + + +compas_ghpython +--------------- + +This package provides functionality for reading and writing Rhino geometry, and for visualising +COMPAS geometry and data structures in Rhino, through GHPython. + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :caption: compas_ghpython + + compas_ghpython.scene + compas_ghpython.components + compas_ghpython.conversions + + +compas_rhino +------------ + +This package provides functionality for reading and writing Rhino geometry, for visualising +COMPAS geometry and data structures in Rhino, and for basic user inter interaction. .. toctree:: - :maxdepth: 2 - :titlesonly: + :maxdepth: 1 + :titlesonly: + :caption: compas_rhino - compas - compas_blender - compas_ghpython - compas_rhino + compas_rhino.scene + compas_rhino.conversions + compas_rhino.forms + compas_rhino.geometry diff --git a/docs/sort__all__.py b/docs/sort__all__.py new file mode 100644 index 00000000000..182eee9ae3d --- /dev/null +++ b/docs/sort__all__.py @@ -0,0 +1,40 @@ +import compas +from compas_blender import conversions as module + +functions = [] +classes = [] +errors = [] +numpy = [] + +__newall__ = { + "classes": [], + "errors": [], + "functions": [], + "numpy": [], + "pluggables": [], + "plugins": [], +} + +for name in module.__all__: + obj = getattr(module, name) + + if name.endswith("_numpy"): + numpy.append(name) + continue + + if isinstance(obj, type): + classes.append(name) + else: + functions.append(name) + +for name in sorted(classes): + __newall__["classes"].append(name) + +for name in sorted(functions): + __newall__["functions"].append(name) + +for name in sorted(numpy): + __newall__["numpy"].append(name) + + +compas.json_dump(__newall__, f"docs/{module.__name__}__all__.json", pretty=True) diff --git a/docs/userguide/configuration.rst b/docs/userguide/__old/configuration.rst similarity index 100% rename from docs/userguide/configuration.rst rename to docs/userguide/__old/configuration.rst diff --git a/docs/userguide/configuration/blender.rst b/docs/userguide/__old/configuration/blender.rst similarity index 100% rename from docs/userguide/configuration/blender.rst rename to docs/userguide/__old/configuration/blender.rst diff --git a/docs/userguide/configuration/freecad.rst b/docs/userguide/__old/configuration/freecad.rst similarity index 100% rename from docs/userguide/configuration/freecad.rst rename to docs/userguide/__old/configuration/freecad.rst diff --git a/docs/userguide/configuration/grasshopper.rst b/docs/userguide/__old/configuration/grasshopper.rst similarity index 91% rename from docs/userguide/configuration/grasshopper.rst rename to docs/userguide/__old/configuration/grasshopper.rst index be65939a5e7..141c64baed4 100644 --- a/docs/userguide/configuration/grasshopper.rst +++ b/docs/userguide/__old/configuration/grasshopper.rst @@ -20,11 +20,13 @@ component on your Grasshopper canvas, paste the following script and hit `OK`. import compas from compas.datastructures import Mesh - from compas_ghpython.artists import MeshArtist + from compas.scene import Scene mesh = Mesh.from_obj(compas.get('faces.obj')) - a = MeshArtist(mesh).draw() + scene = Scene() + scene.add(mesh) + a = scene.redraw() .. figure:: /_images/gh_verify.jpg @@ -64,6 +66,6 @@ recognizes the changes. To avoid restarting Rhino, you can use the function Prefer using `unload_modules` as early as possible in your grasshopper workflow. Re-loading modules later might result, for example, - in COMPAS not being able to find an `Artist` as well as other issues + in COMPAS not being able to find an `SceneObject` as well as other issues related to a mid-workflow re-definition of Python types. diff --git a/docs/userguide/configuration/rhino.rst b/docs/userguide/__old/configuration/rhino.rst similarity index 100% rename from docs/userguide/configuration/rhino.rst rename to docs/userguide/__old/configuration/rhino.rst diff --git a/docs/userguide/configuration/rhino5.rst b/docs/userguide/__old/configuration/rhino5.rst similarity index 100% rename from docs/userguide/configuration/rhino5.rst rename to docs/userguide/__old/configuration/rhino5.rst diff --git a/docs/userguide/configuration/vscode.rst b/docs/userguide/__old/configuration/vscode.rst similarity index 100% rename from docs/userguide/configuration/vscode.rst rename to docs/userguide/__old/configuration/vscode.rst diff --git a/docs/userguide/__old/firststeps.rst b/docs/userguide/__old/firststeps.rst new file mode 100644 index 00000000000..29a03935c34 --- /dev/null +++ b/docs/userguide/__old/firststeps.rst @@ -0,0 +1,60 @@ +*********** +First Steps +*********** + +Once COMPAS is installed, you can start using it in your Python scripts. +Here are some some super simple examples to get you started. + +The visualisations shown on this page are generated with the COMPAS Viewer in VS Code. +See the :doc:`basics.visualisation` for more information on how to set it up and use it. +Alternatively, you can run the examples in Rhino or Blender. +See the :doc:`cad.rhino` and :doc:`cad.blender` for more information on how to get started with that. + + +Random Geometry +--------------- + + +Containment and Membership +-------------------------- + + +Oriented Bounding Box +--------------------- + +.. code-block:: python + + import math + + from compas.geometry import Pointcloud, Box, Rotation + from compas.geometry import oriented_bounding_box_numpy + + Rz = Rotation.from_axis_and_angle([0.0, 0.0, 1.0], math.radians(60)) + Ry = Rotation.from_axis_and_angle([0.0, 1.0, 0.0], math.radians(20)) + Rx = Rotation.from_axis_and_angle([1.0, 0.0, 0.0], math.radians(10)) + + points = Pointcloud.from_bounds(x=10, y=5, z=3, n=100) + + points.transform(Rz * Ry * Rx) + + obb = oriented_bounding_box_numpy(points) + box = Box.from_bounding_box(obb) + + +Shortest Path +------------- + + +Loops and Strips +---------------- + + +Mesh Subdivision +---------------- + + +Conway Operators +---------------- + + + diff --git a/docs/userguide/tutorials/__old/plotters.rst b/docs/userguide/__old/tutorials/__old/plotters.rst similarity index 100% rename from docs/userguide/tutorials/__old/plotters.rst rename to docs/userguide/__old/tutorials/__old/plotters.rst diff --git a/docs/userguide/tutorials/__old/plotters_dynamic.py b/docs/userguide/__old/tutorials/__old/plotters_dynamic.py similarity index 100% rename from docs/userguide/tutorials/__old/plotters_dynamic.py rename to docs/userguide/__old/tutorials/__old/plotters_dynamic.py diff --git a/docs/userguide/tutorials/__old/plotters_line-options.py b/docs/userguide/__old/tutorials/__old/plotters_line-options.py similarity index 100% rename from docs/userguide/tutorials/__old/plotters_line-options.py rename to docs/userguide/__old/tutorials/__old/plotters_line-options.py diff --git a/docs/userguide/tutorials/__old/plotters_point-options.py b/docs/userguide/__old/tutorials/__old/plotters_point-options.py similarity index 100% rename from docs/userguide/tutorials/__old/plotters_point-options.py rename to docs/userguide/__old/tutorials/__old/plotters_point-options.py diff --git a/docs/userguide/tutorials/__old/plotters_polygon-options.py b/docs/userguide/__old/tutorials/__old/plotters_polygon-options.py similarity index 100% rename from docs/userguide/tutorials/__old/plotters_polygon-options.py rename to docs/userguide/__old/tutorials/__old/plotters_polygon-options.py diff --git a/docs/userguide/tutorials/__old/plotters_vector-options.py b/docs/userguide/__old/tutorials/__old/plotters_vector-options.py similarity index 100% rename from docs/userguide/tutorials/__old/plotters_vector-options.py rename to docs/userguide/__old/tutorials/__old/plotters_vector-options.py diff --git a/docs/userguide/tutorials/colors.rst b/docs/userguide/__old/tutorials/colors.rst similarity index 100% rename from docs/userguide/tutorials/colors.rst rename to docs/userguide/__old/tutorials/colors.rst diff --git a/docs/userguide/tutorials/data.rst b/docs/userguide/__old/tutorials/data.rst similarity index 100% rename from docs/userguide/tutorials/data.rst rename to docs/userguide/__old/tutorials/data.rst diff --git a/docs/userguide/tutorials/datastructures/assemblies.rst b/docs/userguide/__old/tutorials/datastructures/assemblies.rst similarity index 100% rename from docs/userguide/tutorials/datastructures/assemblies.rst rename to docs/userguide/__old/tutorials/datastructures/assemblies.rst diff --git a/docs/userguide/tutorials/datastructures/assembly_blocks.py b/docs/userguide/__old/tutorials/datastructures/assembly_blocks.py similarity index 100% rename from docs/userguide/tutorials/datastructures/assembly_blocks.py rename to docs/userguide/__old/tutorials/datastructures/assembly_blocks.py diff --git a/docs/userguide/tutorials/datastructures/assembly_robot.py b/docs/userguide/__old/tutorials/datastructures/assembly_robot.py similarity index 100% rename from docs/userguide/tutorials/datastructures/assembly_robot.py rename to docs/userguide/__old/tutorials/datastructures/assembly_robot.py diff --git a/docs/userguide/tutorials/datastructures/assembly_splines.py b/docs/userguide/__old/tutorials/datastructures/assembly_splines.py similarity index 100% rename from docs/userguide/tutorials/datastructures/assembly_splines.py rename to docs/userguide/__old/tutorials/datastructures/assembly_splines.py diff --git a/docs/userguide/tutorials/datastructures/index.rst b/docs/userguide/__old/tutorials/datastructures/index.rst similarity index 100% rename from docs/userguide/tutorials/datastructures/index.rst rename to docs/userguide/__old/tutorials/datastructures/index.rst diff --git a/docs/userguide/tutorials/datastructures/intro.rst b/docs/userguide/__old/tutorials/datastructures/intro.rst similarity index 100% rename from docs/userguide/tutorials/datastructures/intro.rst rename to docs/userguide/__old/tutorials/datastructures/intro.rst diff --git a/docs/userguide/tutorials/datastructures/meshes.rst b/docs/userguide/__old/tutorials/datastructures/meshes.rst similarity index 100% rename from docs/userguide/tutorials/datastructures/meshes.rst rename to docs/userguide/__old/tutorials/datastructures/meshes.rst diff --git a/docs/userguide/tutorials/datastructures/networks.rst b/docs/userguide/__old/tutorials/datastructures/networks.rst similarity index 100% rename from docs/userguide/tutorials/datastructures/networks.rst rename to docs/userguide/__old/tutorials/datastructures/networks.rst diff --git a/docs/userguide/tutorials/datastructures/volmeshes.rst b/docs/userguide/__old/tutorials/datastructures/volmeshes.rst similarity index 100% rename from docs/userguide/tutorials/datastructures/volmeshes.rst rename to docs/userguide/__old/tutorials/datastructures/volmeshes.rst diff --git a/docs/userguide/tutorials/files/3_way_split.PNG b/docs/userguide/__old/tutorials/files/3_way_split.PNG similarity index 100% rename from docs/userguide/tutorials/files/3_way_split.PNG rename to docs/userguide/__old/tutorials/files/3_way_split.PNG diff --git a/docs/userguide/tutorials/files/box_w_plane.png b/docs/userguide/__old/tutorials/files/box_w_plane.png similarity index 100% rename from docs/userguide/tutorials/files/box_w_plane.png rename to docs/userguide/__old/tutorials/files/box_w_plane.png diff --git a/docs/userguide/tutorials/files/boxy_1.png b/docs/userguide/__old/tutorials/files/boxy_1.png similarity index 100% rename from docs/userguide/tutorials/files/boxy_1.png rename to docs/userguide/__old/tutorials/files/boxy_1.png diff --git a/docs/userguide/tutorials/files/boxy_2.png b/docs/userguide/__old/tutorials/files/boxy_2.png similarity index 100% rename from docs/userguide/tutorials/files/boxy_2.png rename to docs/userguide/__old/tutorials/files/boxy_2.png diff --git a/docs/userguide/tutorials/files/boxy_3.png b/docs/userguide/__old/tutorials/files/boxy_3.png similarity index 100% rename from docs/userguide/tutorials/files/boxy_3.png rename to docs/userguide/__old/tutorials/files/boxy_3.png diff --git a/docs/userguide/tutorials/files/coordinate_frames.jpg b/docs/userguide/__old/tutorials/files/coordinate_frames.jpg similarity index 100% rename from docs/userguide/tutorials/files/coordinate_frames.jpg rename to docs/userguide/__old/tutorials/files/coordinate_frames.jpg diff --git a/docs/userguide/tutorials/files/drinking_bird.png b/docs/userguide/__old/tutorials/files/drinking_bird.png similarity index 100% rename from docs/userguide/tutorials/files/drinking_bird.png rename to docs/userguide/__old/tutorials/files/drinking_bird.png diff --git a/docs/userguide/tutorials/files/drinking_bird.py b/docs/userguide/__old/tutorials/files/drinking_bird.py similarity index 93% rename from docs/userguide/tutorials/files/drinking_bird.py rename to docs/userguide/__old/tutorials/files/drinking_bird.py index 1e839b3324b..615b4c4a48e 100644 --- a/docs/userguide/tutorials/files/drinking_bird.py +++ b/docs/userguide/__old/tutorials/files/drinking_bird.py @@ -1,4 +1,4 @@ -from compas.artists import Artist +from compas.scene import Scene from compas.robots import Joint from compas.robots import RobotModel from compas.geometry import Box @@ -49,6 +49,6 @@ hat_joint_origin = Frame([0, 0, 1 - 0.3 + 1.5 / 2], [1, 0, 0], [0, 1, 0]) model.add_joint("hat_joint", Joint.FIXED, head_link, hat_link, origin=hat_joint_origin) -artist = Artist(model, layer="COMPAS::Example Robot") -artist.clear_layer() -artist.draw_visual() +scene = Scene() +scene.add(model, layer="COMPAS::Example Robot") +scene.redraw() \ No newline at end of file diff --git a/docs/userguide/tutorials/files/jointy.png b/docs/userguide/__old/tutorials/files/jointy.png similarity index 100% rename from docs/userguide/tutorials/files/jointy.png rename to docs/userguide/__old/tutorials/files/jointy.png diff --git a/docs/userguide/tutorials/files/trimmed_box.png b/docs/userguide/__old/tutorials/files/trimmed_box.png similarity index 100% rename from docs/userguide/tutorials/files/trimmed_box.png rename to docs/userguide/__old/tutorials/files/trimmed_box.png diff --git a/docs/userguide/tutorials/geometry/breps.rst b/docs/userguide/__old/tutorials/geometry/breps.rst similarity index 100% rename from docs/userguide/tutorials/geometry/breps.rst rename to docs/userguide/__old/tutorials/geometry/breps.rst diff --git a/docs/userguide/tutorials/geometry/curves-and-surfs.rst b/docs/userguide/__old/tutorials/geometry/curves-and-surfs.rst similarity index 100% rename from docs/userguide/tutorials/geometry/curves-and-surfs.rst rename to docs/userguide/__old/tutorials/geometry/curves-and-surfs.rst diff --git a/docs/userguide/tutorials/geometry/curves.py b/docs/userguide/__old/tutorials/geometry/curves.py similarity index 100% rename from docs/userguide/tutorials/geometry/curves.py rename to docs/userguide/__old/tutorials/geometry/curves.py diff --git a/docs/userguide/tutorials/geometry/curves.rst b/docs/userguide/__old/tutorials/geometry/curves.rst similarity index 100% rename from docs/userguide/tutorials/geometry/curves.rst rename to docs/userguide/__old/tutorials/geometry/curves.rst diff --git a/docs/userguide/tutorials/geometry/frames_and_transformations.rst b/docs/userguide/__old/tutorials/geometry/frames_and_transformations.rst similarity index 100% rename from docs/userguide/tutorials/geometry/frames_and_transformations.rst rename to docs/userguide/__old/tutorials/geometry/frames_and_transformations.rst diff --git a/docs/userguide/tutorials/geometry/geomaps.rst b/docs/userguide/__old/tutorials/geometry/geomaps.rst similarity index 100% rename from docs/userguide/tutorials/geometry/geomaps.rst rename to docs/userguide/__old/tutorials/geometry/geomaps.rst diff --git a/docs/userguide/tutorials/geometry/index.rst b/docs/userguide/__old/tutorials/geometry/index.rst similarity index 100% rename from docs/userguide/tutorials/geometry/index.rst rename to docs/userguide/__old/tutorials/geometry/index.rst diff --git a/docs/userguide/tutorials/geometry/intro.rst b/docs/userguide/__old/tutorials/geometry/intro.rst similarity index 100% rename from docs/userguide/tutorials/geometry/intro.rst rename to docs/userguide/__old/tutorials/geometry/intro.rst diff --git a/docs/userguide/tutorials/geometry/surfaces.rst b/docs/userguide/__old/tutorials/geometry/surfaces.rst similarity index 100% rename from docs/userguide/tutorials/geometry/surfaces.rst rename to docs/userguide/__old/tutorials/geometry/surfaces.rst diff --git a/docs/userguide/tutorials/numericaldata.rst b/docs/userguide/__old/tutorials/numericaldata.rst similarity index 100% rename from docs/userguide/tutorials/numericaldata.rst rename to docs/userguide/__old/tutorials/numericaldata.rst diff --git a/docs/userguide/tutorials/rpc.rst b/docs/userguide/__old/tutorials/rpc.rst similarity index 100% rename from docs/userguide/tutorials/rpc.rst rename to docs/userguide/__old/tutorials/rpc.rst diff --git a/docs/userguide/advanced.pluggables.rst b/docs/userguide/advanced.pluggables.rst new file mode 100644 index 00000000000..7e0fac1a90e --- /dev/null +++ b/docs/userguide/advanced.pluggables.rst @@ -0,0 +1,4 @@ +********************** +Pluggables and Plugins +********************** + diff --git a/docs/userguide/advanced.rpc.rst b/docs/userguide/advanced.rpc.rst new file mode 100644 index 00000000000..1a15cfd8390 --- /dev/null +++ b/docs/userguide/advanced.rpc.rst @@ -0,0 +1,3 @@ +**************************** +Remote Procedure Calls (RPC) +**************************** diff --git a/docs/userguide/advanced.serialisation.rst b/docs/userguide/advanced.serialisation.rst new file mode 100644 index 00000000000..e1834177993 --- /dev/null +++ b/docs/userguide/advanced.serialisation.rst @@ -0,0 +1,4 @@ +**************** +Serialising Data +**************** + diff --git a/docs/userguide/tutorials/artists/index.rst b/docs/userguide/advanced.tolerance.rst similarity index 50% rename from docs/userguide/tutorials/artists/index.rst rename to docs/userguide/advanced.tolerance.rst index bb252a59273..5ea4d562afc 100644 --- a/docs/userguide/tutorials/artists/index.rst +++ b/docs/userguide/advanced.tolerance.rst @@ -1,5 +1,4 @@ *********************** -Introduction to Artists +Dealing with Tolerances *********************** -More info coming soon... diff --git a/docs/userguide/basics.colors.rst b/docs/userguide/basics.colors.rst new file mode 100644 index 00000000000..7b8311695f6 --- /dev/null +++ b/docs/userguide/basics.colors.rst @@ -0,0 +1,3 @@ +********************* +Colors and Color Maps +********************* diff --git a/docs/userguide/basics.datastructures.assemblies.rst b/docs/userguide/basics.datastructures.assemblies.rst new file mode 100644 index 00000000000..0518646e6bd --- /dev/null +++ b/docs/userguide/basics.datastructures.assemblies.rst @@ -0,0 +1,3 @@ +********** +Assemblies +********** diff --git a/docs/userguide/basics.datastructures.cells.rst b/docs/userguide/basics.datastructures.cells.rst new file mode 100644 index 00000000000..e4a4ae21732 --- /dev/null +++ b/docs/userguide/basics.datastructures.cells.rst @@ -0,0 +1,3 @@ +*************** +Cellular Meshes +*************** diff --git a/docs/userguide/basics.datastructures.meshes.rst b/docs/userguide/basics.datastructures.meshes.rst new file mode 100644 index 00000000000..94dab389d51 --- /dev/null +++ b/docs/userguide/basics.datastructures.meshes.rst @@ -0,0 +1,3 @@ +****** +Meshes +****** diff --git a/docs/userguide/basics.datastructures.networks.rst b/docs/userguide/basics.datastructures.networks.rst new file mode 100644 index 00000000000..82a93f7f998 --- /dev/null +++ b/docs/userguide/basics.datastructures.networks.rst @@ -0,0 +1,3 @@ +******** +Networks +******** diff --git a/docs/userguide/basics.datastructures.rst b/docs/userguide/basics.datastructures.rst new file mode 100644 index 00000000000..c2f884af8b2 --- /dev/null +++ b/docs/userguide/basics.datastructures.rst @@ -0,0 +1,13 @@ +Datastructures +============== + +.. toctree:: + :maxdepth: 2 + :titlesonly: + :caption: Data Structures + + basics.datastructures.networks + basics.datastructures.meshes + basics.datastructures.cells + basics.datastructures.trees + basics.datastructures.assemblies diff --git a/docs/userguide/basics.datastructures.trees.rst b/docs/userguide/basics.datastructures.trees.rst new file mode 100644 index 00000000000..865aed996b6 --- /dev/null +++ b/docs/userguide/basics.datastructures.trees.rst @@ -0,0 +1,3 @@ +***** +Trees +***** diff --git a/docs/userguide/basics.geometry.breps.rst b/docs/userguide/basics.geometry.breps.rst new file mode 100644 index 00000000000..89601f141df --- /dev/null +++ b/docs/userguide/basics.geometry.breps.rst @@ -0,0 +1,3 @@ +************************ +Boundary Representations +************************ diff --git a/docs/userguide/basics.geometry.curves_and_surfaces.rst b/docs/userguide/basics.geometry.curves_and_surfaces.rst new file mode 100644 index 00000000000..25e9a5982eb --- /dev/null +++ b/docs/userguide/basics.geometry.curves_and_surfaces.rst @@ -0,0 +1,3 @@ +******************* +Curves and Surfaces +******************* diff --git a/docs/userguide/basics.geometry.intersections.rst b/docs/userguide/basics.geometry.intersections.rst new file mode 100644 index 00000000000..c1511e1d794 --- /dev/null +++ b/docs/userguide/basics.geometry.intersections.rst @@ -0,0 +1,3 @@ +************* +Intersections +************* diff --git a/docs/userguide/basics.geometry.polygons_and_polyhedrons.rst b/docs/userguide/basics.geometry.polygons_and_polyhedrons.rst new file mode 100644 index 00000000000..43633c3243e --- /dev/null +++ b/docs/userguide/basics.geometry.polygons_and_polyhedrons.rst @@ -0,0 +1,3 @@ +************************ +Polygons and Polyhedrons +************************ diff --git a/docs/userguide/basics.geometry.primitives.rst b/docs/userguide/basics.geometry.primitives.rst new file mode 100644 index 00000000000..a48fa10cdce --- /dev/null +++ b/docs/userguide/basics.geometry.primitives.rst @@ -0,0 +1,158 @@ +******************** +Geometric Primitives +******************** + +Points and Vectors +================== + +A :class:`compas.geometry.Point` object represents a location in 3D space. + +>>> from compas.geometry import Point +>>> a = Point(1, 2, 3) +>>> a +Point(1.0, 2.0, z=3.0) + +The coordinates of a point can be accessed by their names, or by their index. + +>>> a.x +1.0 +>>> a.y +2.0 +>>> a.z +3.0 + +>>> a[0] +1.0 +>>> a[1] +2.0 +>>> a[2] +3.0 + +When construction a point, the Z coordinate is optional and defaults to zero. + +>>> b = Point(1, 2) +>>> b +Point(1.0, 2.0, z=0.0) +>>> b.z +0.0 + +A :class:`compas.geometry.Vector` object represents a direction and magnitude in 3D spaces. + +>>> from compas.geometry import Vector +>>> u = Vector(1, 2, 3) +>>> u +Vector(1.0, 2.0, z=3.0) + +As with points, the components of a vector can be accessed by their names, or by their index. + +>>> u.x +1.0 +>>> u.y +2.0 +>>> u.z +3.0 + +>>> u[0] +1.0 +>>> u[1] +2.0 +>>> u[2] +3.0 + +Also here, the Z component is optional and defaults to zero. + +>>> v = Vector(1, 2) +>>> v +Vector(1.0, 2.0, z=0.0) +>>> v.z +0.0 + + +Operators +--------- + +Points and vectors can be added, subtracted, and multiplied with or divided by a scalar. + +>>> a = Point(1, 0, 0) +>>> b = Point(0, 1, 0) +>>> a + b +Point(1.0, 1.0, z=0.0) +>>> a - b +Vector(1.0, -1.0, z=0.0) +>>> a * 2 +Point(2.0, 0.0, z=0.0) +>>> a / 2 +Point(0.5, 0.0, z=0.0) + +>>> u = Vector(1, 0, 0) +>>> v = Vector(0, 1, 0) +>>> u + v +Vector(1.0, 1.0, z=0.0) +>>> u - v +Vector(1.0, -1.0, z=0.0) +>>> u * 2 +Vector(2.0, 0.0, z=0.0) +>>> u / 2 +Vector(0.5, 0.0, z=0.0) + +Note that the second operand of addition and subtraction can also be a Python list or tuple. + +>>> a + [0, 1, 0] +Point(1.0, 1.0, z=0.0) +>>> u + [0, 1, 0] +Vector(1.0, 1.0, z=0.0) + +Also the in-place variants of the operators are supported. + +>>> a += b +>>> a +Point(1.0, 1.0, z=0.0) + +>>> u += v +>>> u +Vector(1.0, 1.0, z=0.0) + + +Comparison +---------- + +Points and vectors can be compared. + +>>> a == b +False +>>> a != b +True + +>>> u == v +False +>>> u != v +True + +The comparison is based on the coordinates and components of the points and vectors. +The tolerance for the comparison defaults to the global COMPAS tolerance. + +>>> a = Point(1.0, 0, 0) +>>> b = Point(1.0 + 1e-3, 0, 0) +>>> a == b +False + +>>> a = Point(1.0, 0, 0) +>>> b = Point(1.0 + 1e-9, 0, 0) +>>> a == b +True + +To use a different tolerance for a specific comparison, you have to use the corresponding comparison method instead, and provide the tolerance as an argument. + +>>> a = Point(1.0, 0, 0) +>>> b = Point(1.0 + 1e-3, 0, 0) +>>> a.is_equal(b, tol=1e-3) +True + +For more information about working with tolerances in COMPAS, see :doc:`advanced.tolerance`. + + +Planes +====== + +Frames +====== diff --git a/docs/userguide/basics.geometry.rst b/docs/userguide/basics.geometry.rst new file mode 100644 index 00000000000..2fbcc8df1d6 --- /dev/null +++ b/docs/userguide/basics.geometry.rst @@ -0,0 +1,15 @@ +Geometry +======== + +.. toctree:: + :maxdepth: 2 + :titlesonly: + :caption: Geometry + + basics.geometry.primitives + basics.geometry.polygons_and_polyhedrons + basics.geometry.curves_and_surfaces + basics.geometry.solids + basics.geometry.breps + basics.geometry.intersections + basics.geometry.transformations diff --git a/docs/userguide/basics.geometry.solids.rst b/docs/userguide/basics.geometry.solids.rst new file mode 100644 index 00000000000..786bef18afa --- /dev/null +++ b/docs/userguide/basics.geometry.solids.rst @@ -0,0 +1,3 @@ +***************** +Shapes and Solids +***************** diff --git a/docs/userguide/basics.geometry.transformations.rst b/docs/userguide/basics.geometry.transformations.rst new file mode 100644 index 00000000000..e1dce14155e --- /dev/null +++ b/docs/userguide/basics.geometry.transformations.rst @@ -0,0 +1,3 @@ +*************** +Transformations +*************** diff --git a/docs/userguide/basics.visualisation.rst b/docs/userguide/basics.visualisation.rst new file mode 100644 index 00000000000..5cef0baa1a3 --- /dev/null +++ b/docs/userguide/basics.visualisation.rst @@ -0,0 +1,116 @@ +************* +Visualisation +************* + +COMPAS (data) objects can be visualised by placing them into a "scene". + +>>> from compas.scene import Scene +>>> from compas.geometry import Box +>>> box = Box(1) +>>> scene = Scene() +>>> scene.add(box) +>>> scene.redraw() + +.. When a COMPAS object is added, the scene automatically creates a corresponding scene object for the current/active visualisation context. +.. Currently, four visualisation contexts are supported: COMPAS Viewer (default), Rhino, Grasshopper, and Blender. + +Scene Objects +============= + +When a COMPAS object is added to a scene, a scene object is created automatically, corresponding to the type of COMPAS object. + +>>> sceneobj = scene.add(box) +>>> sceneobj +BoxObject + +The scene object holds a reference to the COMPAS data object, and stores its visualisation settings and transformation matrix. +Multiple scene objects can be created for the same COMPAS data object, each with different visualisation settings and transformations. + +>>> sceneobj1 = scene.add(box) +>>> sceneobj2 = scene.add(box) +>>> sceneobj1 is sceneobj2 +False +>>> sceneobj1.data is sceneobj2.data +True + +Visualiation Settings +===================== + +Scene objects have visualisation settings that can be changed by setting the corresponding attributes. +All scene objects have a color attribute. + +>>> sceneobj = scene.add(box) +>>> sceneobj.color +Color(0.0, 0.0, 0.0, alpha=1.0) + +Color attributes can be set using a COMPAS Color object, or a tuple of RGB values, with the color components specified as floats in the range 0.0-1.0 or as integers in the range 0-255. + +.. note:: + + For more information about working with colors in COMPAS, see :doc:`basics.colors`. + +>>> sceneobj.color = (255, 0, 0) +>>> sceneobj.color +Color(1.0, 0.0, 0.0, alpha=1.0) + +Visualisation settings can be changed by modifying the corresponding attributes of the scene object, or by providing values or the attributes to the :meth:`Scene.add` method. + +>>> sceneobj = scene.add(box, color=(0, 255, 0)) +>>> sceneobj.color +Color(0.0, 1.0, 0.0, alpha=1.0) + +Some objects have additional color attributes, for more precise control over the visualisation. +For example, meshes can have different colors for the vertices, the edges, and the faces. +And the colors of vertices, edges, and faces can be specified individually, per element. +See the section about mesh visualisation for more information. + +Object Transformation +===================== + +All scene objects have a transformation matrix that can be used to transform the object in the visualisation, +independently of the geometry of the underlying data object. +The default transformation matrix is the identity matrix, which means that the visualised geometry is the same as the geometry represented by the data. + +>>> sceneobj = scene.add(box) +>>> sceneobj.transformation +Transformation([[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]]) + +The transformation matrix can be set using a COMPAS Transformation object, or a 4x4 nested list of floats. + +>>> from compas.geometry import Translation +>>> sceneobj.transformation = Translation.from_vector([1.0, 2.0, 3.0]) +>>> sceneobj.transformation +Transformation([[1.0, 0.0, 0.0, 1.0], [0.0, 1.0, 0.0, 2.0], [0.0, 0.0, 1.0, 3.0], [0.0, 0.0, 0.0, 1.0]]) + +.. note:: + + For more information about working with transformations in COMPAS, see :doc:`basics.geometry.transformations`. + +Scene Hierarchy +=============== + +Scene objects are organised in a hierarchy, with the scene as the root node. +The hierarchy is represented by a COMPAS Tree data structure. +All scene objects are nodes in the tree. +The scene tree has an implicit root node, which is the scene itself. + +>>> scene = Scene() +>>> scene.root +SceneObject + +By default, every scene object is added as a direct child of the scene. + +>>> sceneobj = scene.add(box) +>>> sceneobj.parent +SceneObject +>>> scene.children() +[BoxObject] + +To use a different scene object as the parent, the parent attribute of the scene object can be set to the desired parent. + +>>> from compas.geometry import Point +>>> point = Point(1, 2, 3) +>>> pointobj = scene.add(point) +>>> boxobj = scene.add(box, parent=pointobj) +>>> boxobj.parent +PointObject diff --git a/docs/userguide/cad.blender.rst b/docs/userguide/cad.blender.rst new file mode 100644 index 00000000000..c1d31bec6a3 --- /dev/null +++ b/docs/userguide/cad.blender.rst @@ -0,0 +1,3 @@ +****************** +Working in Blender +****************** diff --git a/docs/userguide/cad.grasshopper.rst b/docs/userguide/cad.grasshopper.rst new file mode 100644 index 00000000000..eaf1abd6113 --- /dev/null +++ b/docs/userguide/cad.grasshopper.rst @@ -0,0 +1,3 @@ +********************** +Working in Grasshopper +********************** diff --git a/docs/userguide/cad.other.rst b/docs/userguide/cad.other.rst new file mode 100644 index 00000000000..7dbd5ff2ff2 --- /dev/null +++ b/docs/userguide/cad.other.rst @@ -0,0 +1,4 @@ +***************************** +Working in Other CAD Software +***************************** + diff --git a/docs/userguide/cad.rhino.rst b/docs/userguide/cad.rhino.rst new file mode 100644 index 00000000000..396c841cb21 --- /dev/null +++ b/docs/userguide/cad.rhino.rst @@ -0,0 +1,4 @@ +**************** +Working in Rhino +**************** + diff --git a/docs/userguide/firststeps.rst b/docs/userguide/firststeps.rst new file mode 100644 index 00000000000..7a3ae1dacaf --- /dev/null +++ b/docs/userguide/firststeps.rst @@ -0,0 +1,19 @@ +*********** +First Steps +*********** + +Once COMPAS is installed, you can start using it in your Python scripts. +Here are some some super simple examples to get you started. + +The visualisations shown on this page are generated with the COMPAS Viewer in VS Code. +See the :doc:`basics.visualisation` for more information on how to set it up and use it. +Alternatively, you can run the examples in Rhino or Blender. +See the :doc:`cad.rhino` and :doc:`cad.blender` for more information on how to get started with that. + + +Naive Collision Detection +------------------------- + + +Various Mesh Operations +----------------------- diff --git a/docs/userguide/index.rst b/docs/userguide/index.rst index baa5dedb282..46a5f948de2 100644 --- a/docs/userguide/index.rst +++ b/docs/userguide/index.rst @@ -2,12 +2,53 @@ User Guide ========== .. toctree:: - :maxdepth: 2 - :titlesonly: - - installation - configuration - tutorials - releases - citing - license + :maxdepth: 2 + :titlesonly: + :caption: Getting Started + + introduction + installation + firststeps + whatsnext + + +.. toctree:: + :maxdepth: 2 + :titlesonly: + :caption: Tutorial: Basics + + basics.geometry + basics.datastructures + basics.visualisation + + +.. toctree:: + :maxdepth: 2 + :titlesonly: + :caption: Tutorial: Advanced + + advanced.tolerance + advanced.serialisation + advanced.rpc + advanced.pluggables + + +.. toctree:: + :maxdepth: 2 + :titlesonly: + :caption: Tutorial: Working in CAD + + cad.rhino + cad.grasshopper + cad.blender + cad.other + + +.. toctree:: + :maxdepth: 2 + :titlesonly: + :caption: Miscellaneous Info + + releases + citing + license diff --git a/docs/userguide/installation.rst b/docs/userguide/installation.rst index e70bea16d00..f7d1a0185dd 100644 --- a/docs/userguide/installation.rst +++ b/docs/userguide/installation.rst @@ -1,3 +1,5 @@ +.. _user_guide_install: + ************ Installation ************ @@ -7,11 +9,6 @@ Installation COMPAS can be easily installed on multiple platforms, using popular package managers such as conda or pip. -.. figure:: /_images/installation.gif - :figclass: figure - :class: figure-img img-fluid mx-auto - - Install with conda (recommended) ================================ @@ -45,7 +42,7 @@ Install COMPAS in an environment with a specific version of Python. .. code-block:: bash - conda create -n research python=3.8 compas + conda create -n research python=3.9 compas Install COMPAS in an existing environment. @@ -84,7 +81,7 @@ Install a specific version. .. code-block:: bash - conda install compas=1.13.3 + conda install compas=1.17.9 Update with pip @@ -100,29 +97,4 @@ Install a specific version. .. code-block:: bash - pip install compas==1.13.3 - - -Known Issues -============ - -If you encounter a problem that is not described here, -please file an issue using the `Issue Tracker `_. - - -Microsoft Visual C++ Build Tools --------------------------------- - -The installation with ``pip`` can fail because "Microsoft Visual C++ Build Tools are missing". -To install the Microsoft Visual C++ Build Tools choose one of the options provided -here: https://www.scivision.dev/python-windows-visual-c-14-required/ -and just follow the instructions. -Then run the ``pip`` installation commands again. - - -RuntimeError: The current Numpy installation (...) fails to pass a sanity check -------------------------------------------------------------------------------- - -If you see this error, it means latest Numpy 1.19.4 could not init due to a bug from windows. -To avoid it, simply downgrade Numpy by ``pip install numpy==1.19.3`` -See the detail of the bug here: https://github.com/numpy/numpy/issues/17726 + pip install compas==1.17.9 diff --git a/docs/userguide/introduction.rst b/docs/userguide/introduction.rst new file mode 100644 index 00000000000..ad6540ea09b --- /dev/null +++ b/docs/userguide/introduction.rst @@ -0,0 +1,3 @@ +************ +Introduction +************ diff --git a/docs/userguide/scene.py b/docs/userguide/scene.py new file mode 100644 index 00000000000..cd2522ff4c0 --- /dev/null +++ b/docs/userguide/scene.py @@ -0,0 +1,86 @@ +from compas.scene import Scene +from compas.geometry import Box +from compas.geometry import Capsule +from compas.geometry import Circle +from compas.geometry import Cone +from compas.geometry import Cylinder +from compas.geometry import Ellipse +from compas.geometry import Frame +from compas.geometry import Line +from compas.geometry import Point +from compas.geometry import Polygon +from compas.geometry import Polyhedron +from compas.geometry import Polyline +from compas.geometry import Sphere +from compas.geometry import Torus +from compas.geometry import Vector +# from compas.geometry import Plane + +from compas.datastructures import Mesh +from compas.datastructures import Network +from compas.datastructures import VolMesh + +from compas.geometry import Translation + + +box = Box.from_width_height_depth(1, 1, 1) +capsule = Capsule(0.5, 1, Frame.worldXY()) +circle = Circle(1, Frame.worldXY()) +cone = Cone(1, 1, Frame.worldXY()) +cylinder = Cylinder(1, 1, Frame.worldXY()) +line = Line(Point(0, 0, 0), Point(1, 1, 1)) +point = Point(0, 0, 0) +polygon = Polygon.from_sides_and_radius_xy(5, 1) +polyhedron = Polyhedron.from_platonicsolid(4) +polyline = Polyline([[0, 0, 0], [1, 0, 0], [1, 0, 1]]) +sphere = Sphere(1) +torus = Torus(1, 0.3, Frame.worldXY()) +vector = Vector(0, 0, 1) + +# TODO: Make these work everywhere +# ellipse = Ellipse(1, 0.5, Frame.worldXY()) +# frame = Frame.worldXY() +# plane = Plane(Point(0, 0, 0), Vector(0, 0, 1)) + + +mesh = Mesh.from_polyhedron(8) +network = Network.from_nodes_and_edges([(0, 0, 0), (0, -1.5, 0), (-1, 1, 0), (1, 1, 0)], [(0, 1), (0, 2), (0, 3)]) +volmesh = VolMesh.from_meshgrid(1, 1, 1, 2, 2, 2) + + +scene = Scene() +scene.add(box) +scene.add(capsule) +scene.add(circle) +scene.add(cone) +scene.add(cylinder) +scene.add(line) +scene.add(point) +scene.add(polygon) +scene.add(polyhedron) +scene.add(polyline) +scene.add(sphere) +scene.add(torus) +scene.add(vector) + +# scene.add(ellipse) +# scene.add(frame) +# scene.add(plane) + +scene.add(mesh) +scene.add(network) +scene.add(volmesh) + + +x = 0 +y = 0 +for obj in scene.sceneobjects: + obj.transformation = Translation.from_vector([x, y, 0]) + x += 5 + if x > 20: + x = 0 + y += 5 + + +scene.print_hierarchy() +scene.redraw() diff --git a/docs/userguide/tutorials.rst b/docs/userguide/tutorials.rst deleted file mode 100644 index d80ae99c14f..00000000000 --- a/docs/userguide/tutorials.rst +++ /dev/null @@ -1,13 +0,0 @@ -Tutorials -********* - -.. toctree:: - :maxdepth: 1 - :titlesonly: - - tutorials/data - tutorials/geometry/index - tutorials/datastructures/index - tutorials/rpc - tutorials/colors - turorials/artists/index diff --git a/docs/userguide/tutorials/artists/boxartist.py b/docs/userguide/tutorials/artists/boxartist.py deleted file mode 100644 index 915214f9008..00000000000 --- a/docs/userguide/tutorials/artists/boxartist.py +++ /dev/null @@ -1,11 +0,0 @@ -from compas.geometry import Box -from compas.artists import Artist - -Artist.clear() - -box = Box.from_corner_corner_height([0, 0, 0], [1, 1, 0], 3) - -artist = Artist(box, layer='Test::Child') -artist.draw(color=(0.0, 1.0, 0.0)) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/capsuleartist.py b/docs/userguide/tutorials/artists/capsuleartist.py deleted file mode 100644 index da3b1933f98..00000000000 --- a/docs/userguide/tutorials/artists/capsuleartist.py +++ /dev/null @@ -1,11 +0,0 @@ -from compas.geometry import Capsule -from compas.artists import Artist - -Artist.clear() - -capsule = Capsule(radius=1.0, height=7.0) - -artist = Artist(capsule) -artist.draw(color=(1.0, 0.0, 0.0)) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/circleartist.py b/docs/userguide/tutorials/artists/circleartist.py deleted file mode 100644 index 66c33f8ee6d..00000000000 --- a/docs/userguide/tutorials/artists/circleartist.py +++ /dev/null @@ -1,11 +0,0 @@ -from compas.geometry import Circle -from compas.artists import Artist - -Artist.clear() - -circle = Circle(radius=3.0) - -artist = Artist(circle) -artist.draw(color=(0.0, 0.0, 1.0), show_point=True, show_normal=True) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/coneartist.py b/docs/userguide/tutorials/artists/coneartist.py deleted file mode 100644 index 12113ec9d91..00000000000 --- a/docs/userguide/tutorials/artists/coneartist.py +++ /dev/null @@ -1,11 +0,0 @@ -from compas.geometry import Cone -from compas.artists import Artist - -Artist.clear() - -cone = Cone(radius=1.0, height=7.0) - -artist = Artist(cone) -artist.draw(color=(1.0, 0.0, 0.0)) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/curveartist.py b/docs/userguide/tutorials/artists/curveartist.py deleted file mode 100644 index 0ce569c4e5a..00000000000 --- a/docs/userguide/tutorials/artists/curveartist.py +++ /dev/null @@ -1,12 +0,0 @@ -from compas.geometry import NurbsCurve -from compas.artists import Artist - -Artist.clear() - -curve = NurbsCurve.from_points([[0, 0, 0], [3, 3, 6], [6, -3, -3], [9, 0, 0]]) - -artist = Artist(curve) -artist.color = (0.0, 1.0, 0.0) -artist.draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/cylinderartist.py b/docs/userguide/tutorials/artists/cylinderartist.py deleted file mode 100644 index 9628b035a34..00000000000 --- a/docs/userguide/tutorials/artists/cylinderartist.py +++ /dev/null @@ -1,11 +0,0 @@ -from compas.geometry import Cylinder -from compas.artists import Artist - -Artist.clear() - -cylinder = Cylinder(radius=1.0, height=7.0) - -artist = Artist(cylinder) -artist.draw(color=(1.0, 0.0, 0.0)) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/frameartist.py b/docs/userguide/tutorials/artists/frameartist.py deleted file mode 100644 index 7a2d41582f2..00000000000 --- a/docs/userguide/tutorials/artists/frameartist.py +++ /dev/null @@ -1,10 +0,0 @@ -from compas.geometry import Frame -from compas.artists import Artist - -Artist.clear() - -frame = Frame.worldXY() -artist = Artist(frame) -artist.draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/lineartist.py b/docs/userguide/tutorials/artists/lineartist.py deleted file mode 100644 index 47dc60be132..00000000000 --- a/docs/userguide/tutorials/artists/lineartist.py +++ /dev/null @@ -1,20 +0,0 @@ -from math import pi -from compas.geometry import Rotation, Scale -from compas.geometry import Line -from compas.artists import Artist -from compas.colors import Color - -Artist.clear() - -line = Line([0, 0, 0], [3, 0, 0]) -artist = Artist(line) -# artist.color = (1.0, 0.0, 0.0) - -step = pi / 10.0 -rotation = Rotation.from_axis_and_angle([0, 0, 1], angle=step) - -for i in range(11): - artist.draw(color=Color.from_i(i / 10)) - line.transform(rotation) - -Artist.redraw() \ No newline at end of file diff --git a/docs/userguide/tutorials/artists/meshartist.py b/docs/userguide/tutorials/artists/meshartist.py deleted file mode 100644 index 83a3fc8508e..00000000000 --- a/docs/userguide/tutorials/artists/meshartist.py +++ /dev/null @@ -1,16 +0,0 @@ -from compas.datastructures import Mesh -from compas.artists import Artist -from compas.colors import Color - -mesh = Mesh.from_meshgrid(10, 10) - -Artist.clear() - -artist = Artist(mesh) -artist.draw_vertices() -artist.draw_edges() -artist.draw_faces(color={face: Color.pink() for face in mesh.face_sample(size=17)}) -#artist.draw_vertexnormals() -artist.draw_facenormals() - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/networkartist.py b/docs/userguide/tutorials/artists/networkartist.py deleted file mode 100644 index a53e3429e47..00000000000 --- a/docs/userguide/tutorials/artists/networkartist.py +++ /dev/null @@ -1,21 +0,0 @@ -from compas.geometry import Pointcloud -from compas.datastructures import Network -from compas.artists import Artist -from compas.colors import Color - -network = Network.from_pointcloud(Pointcloud.from_bounds(8, 5, 3, 53)) - -node = network.node_sample(size=1)[0] -nbrs = network.neighbors(node) -edges = network.connected_edges(node) - -Artist.clear() - -artist = Artist(network) -artist.draw( - nodecolor={n: Color.pink() for n in [node] + nbrs}, - edgecolor={e: Color.pink() for e in edges}, - nodetext='index' -) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/pointartist.py b/docs/userguide/tutorials/artists/pointartist.py deleted file mode 100644 index 28be7d90886..00000000000 --- a/docs/userguide/tutorials/artists/pointartist.py +++ /dev/null @@ -1,17 +0,0 @@ -import compas_rhino - -from compas.geometry import Point -from compas.artists import Artist -from compas.colors import Color - -compas_rhino.clear() - -point = Point(0, 0, 0) -artist = Artist(point) -# artist.color = (0.0, 1.0, 0.0) - -for i in range(11): - point.x = i - artist.draw(color=Color.from_i(i / 10)) - -compas_rhino.redraw() diff --git a/docs/userguide/tutorials/artists/polygonartist.py b/docs/userguide/tutorials/artists/polygonartist.py deleted file mode 100644 index 81960502493..00000000000 --- a/docs/userguide/tutorials/artists/polygonartist.py +++ /dev/null @@ -1,13 +0,0 @@ -from compas.geometry import Polygon -from compas.artists import Artist - -Artist.clear() - -polygon = Polygon.from_sides_and_radius_xy(8, 7.0) - -artist = Artist(polygon) -artist.color = (0.0, 1.0, 0.0) - -artist.draw(show_points=True, show_edges=True) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/polyhedronartist.py b/docs/userguide/tutorials/artists/polyhedronartist.py deleted file mode 100644 index 00fab26f62e..00000000000 --- a/docs/userguide/tutorials/artists/polyhedronartist.py +++ /dev/null @@ -1,10 +0,0 @@ -from compas.geometry import Polyhedron -from compas.artists import Artist - -Artist.clear() - -polyhedron = Polyhedron.from_platonicsolid(f=8) -artist = Artist(polyhedron) -artist.draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/polylineartist.py b/docs/userguide/tutorials/artists/polylineartist.py deleted file mode 100644 index 37584c501bf..00000000000 --- a/docs/userguide/tutorials/artists/polylineartist.py +++ /dev/null @@ -1,20 +0,0 @@ -from random import randrange -from compas.geometry import Polyline -from compas.artists import Artist -from compas.colors import Color - -Artist.clear() - -polyline = Polyline([[0, 0, 0]]) - -for i, r in enumerate([randrange(1, 20) for _ in range(10)]): - if i % 2 == 0: - polyline.append([r, polyline.points[-1].y, 0]) - else: - polyline.append([polyline.points[-1].x, r, 0]) - -artist = Artist(polyline) -artist.color = (0.0, 0.0, 1.0) -artist.draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/sphereartist.py b/docs/userguide/tutorials/artists/sphereartist.py deleted file mode 100644 index 551f12051f9..00000000000 --- a/docs/userguide/tutorials/artists/sphereartist.py +++ /dev/null @@ -1,11 +0,0 @@ -from compas.geometry import Sphere -from compas.artists import Artist - -Artist.clear() - -sphere = Sphere(radius=1.0) - -artist = Artist(sphere) -artist.draw(color=(1.0, 0.0, 0.0)) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/torusartist.py b/docs/userguide/tutorials/artists/torusartist.py deleted file mode 100644 index 2e64114b432..00000000000 --- a/docs/userguide/tutorials/artists/torusartist.py +++ /dev/null @@ -1,11 +0,0 @@ -from compas.geometry import Torus -from compas.artists import Artist - -Artist.clear() - -torus = Torus(radius_axis=7.0, radius_pipe=2.0) - -artist = Artist(torus) -artist.draw(color=(1.0, 0.0, 0.0)) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/try_artists_mesh.py b/docs/userguide/tutorials/artists/try_artists_mesh.py deleted file mode 100644 index 45808d6ad22..00000000000 --- a/docs/userguide/tutorials/artists/try_artists_mesh.py +++ /dev/null @@ -1,12 +0,0 @@ -from compas.datastructures import Mesh -from compas.artists import Artist -from compas.colors import Color - -mesh = Mesh.from_meshgrid(10, 10) - -Artist.clear() - -artist = Artist(mesh) -artist.draw_faces(color={face: Color.pink() for face in mesh.face_sample(size=17)}) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/try_artists_network.py b/docs/userguide/tutorials/artists/try_artists_network.py deleted file mode 100644 index 38e2f2bde74..00000000000 --- a/docs/userguide/tutorials/artists/try_artists_network.py +++ /dev/null @@ -1,20 +0,0 @@ -from compas.geometry import Pointcloud -from compas.datastructures import Network -from compas.artists import Artist -from compas.colors import Color - -network = Network.from_pointcloud(Pointcloud.from_bounds(8, 5, 3, 53)) - -node = network.node_sample(size=1)[0] -nbrs = network.neighbors(node) -edges = network.connected_edges(node) - -Artist.clear() - -artist = Artist(network) -artist.draw( - nodecolor={n: Color.pink() for n in [node] + nbrs}, - edgecolor={e: Color.pink() for e in edges}, -) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/try_artists_shapes.py b/docs/userguide/tutorials/artists/try_artists_shapes.py deleted file mode 100644 index 803304606c1..00000000000 --- a/docs/userguide/tutorials/artists/try_artists_shapes.py +++ /dev/null @@ -1,27 +0,0 @@ -import random -from compas.geometry import Box, Sphere, Cylinder, Cone, Capsule, Torus, Polyhedron -from compas.geometry import Plane, Circle, Pointcloud -from compas.geometry import Translation -from compas.artists import Artist -from compas.colors import Color - -shapes = [ - Box.from_width_height_depth(1, 1, 1), - Sphere([0, 0, 0], 0.3), - Cylinder(Circle(Plane([0, 0, 0], [0, 0, 1]), 0.3), 1.0), - Cone(Circle(Plane([0, 0, 0], [0, 0, 1]), 0.3), 1.0), - Capsule([[0, 0, 0], [1, 0, 0]], 0.2), - Torus(Plane([0, 0, 0], [0, 0, 1]), 1.0, 0.3), - Polyhedron.from_platonicsolid(12), -] - -cloud = Pointcloud.from_bounds(8, 5, 3, len(shapes)) - -Artist.clear() - -for point, shape in zip(cloud, shapes): - shape.transform(Translation.from_vector(point)) - artist = Artist(shape) - artist.draw(color=Color.from_i(random.random())) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/try_artists_volmesh.py b/docs/userguide/tutorials/artists/try_artists_volmesh.py deleted file mode 100644 index ed42ab05053..00000000000 --- a/docs/userguide/tutorials/artists/try_artists_volmesh.py +++ /dev/null @@ -1,12 +0,0 @@ -from compas.datastructures import VolMesh -from compas.artists import Artist -from compas.colors import Color - -mesh = VolMesh.from_meshgrid(dx=10, nx=10) - -Artist.clear() - -artist = Artist(mesh) -artist.draw_cells(color={cell: Color.pink() for cell in mesh.cell_sample(size=83)}) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/vectorartist.py b/docs/userguide/tutorials/artists/vectorartist.py deleted file mode 100644 index f1f86d78d2f..00000000000 --- a/docs/userguide/tutorials/artists/vectorartist.py +++ /dev/null @@ -1,28 +0,0 @@ -from math import pi -from compas.geometry import Vector -from compas.geometry import Rotation -from compas.artists import Artist -from compas.colors import Color - -Artist.clear() - -vector = Vector(1, 0, 0) -artist = Artist(vector) -# artist.color = (0.0, 1.0, 0.0) - -# for i in range(11): -# artist.draw( -# color=Color.from_i(i / 10), -# point=[i, 0, 0], -# show_point=True -# ) - -step = pi / 10.0 - -for i in range(11): - artist.draw(color=Color.from_i(i / 10)) - - rotation = Rotation.from_axis_and_angle([0, 0, 1], angle=step) - vector.transform(rotation) - -Artist.redraw() diff --git a/docs/userguide/tutorials/artists/volmeshartist.py b/docs/userguide/tutorials/artists/volmeshartist.py deleted file mode 100644 index ed42ab05053..00000000000 --- a/docs/userguide/tutorials/artists/volmeshartist.py +++ /dev/null @@ -1,12 +0,0 @@ -from compas.datastructures import VolMesh -from compas.artists import Artist -from compas.colors import Color - -mesh = VolMesh.from_meshgrid(dx=10, nx=10) - -Artist.clear() - -artist = Artist(mesh) -artist.draw_cells(color={cell: Color.pink() for cell in mesh.cell_sample(size=83)}) - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_closest_point.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_closest_point.py deleted file mode 100644 index 893c8cb1c8b..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_closest_point.py +++ /dev/null @@ -1,27 +0,0 @@ -from compas.geometry import Point -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -points = [Point(0, 0, 0), Point(3, 0, 2), Point(6, 0, -3), Point(8, 0, 0)] -curve = NurbsCurve.from_interpolation(points) - -projection_point = Point(2, -1, 0) - -closest_point, t = curve.closest_point(projection_point, return_parameter=True) - -print(curve.point_at(t) == closest_point) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(curve, color=Color.from_hex("#0092D2")).draw() - -Artist(projection_point).draw() -Artist(closest_point).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_comparison1.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_comparison1.py deleted file mode 100644 index 3607a9c1f26..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_comparison1.py +++ /dev/null @@ -1,52 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline, Bezier -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -points = [Point(0, 0, 0), Point(1, 3, 0), Point(2, 0, 0)] -bezier = Bezier(points) - -points = [Point(3, 0, 0), Point(4, 3, 0), Point(5, 0, 0)] - -curve1 = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 1.0, 1.0], - knots=[0.0, 1.0], - multiplicities=[3, 3], - degree=2, -) - -curve2 = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 2.0, 1.0], - knots=[0.0, 1.0], - multiplicities=[3, 3], - degree=2, -) - -curve3 = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 1.0, 1.0], - knots=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0], - multiplicities=[1, 1, 1, 1, 1, 1], - degree=2, -) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(Polyline(bezier.points)).draw() -Artist(Polyline(bezier.locus())).draw(show_points=True) - -Artist(Polyline(curve1.points)).draw(show_points=True) - -Artist(curve1).draw(color=Color.black()) -Artist(curve2).draw(color=Color.pink()) -Artist(curve3).draw(color=Color.azure()) - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_comparison2.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_comparison2.py deleted file mode 100644 index 0d2b532c751..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_comparison2.py +++ /dev/null @@ -1,81 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline, Bezier -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -points = [Point(0, 0, 0), Point(1, 2, 0), Point(2, -2, 0), Point(3, 0, 0)] -bezier = Bezier(points) - -points = [Point(4, 0, 0), Point(5, 2, 0), Point(6, -2, 0), Point(7, 0, 0)] - -curve1 = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 1.0, 1.0, 1.0], - knots=[0.0, 1.0], - multiplicities=[4, 4], - degree=3, -) - -curve2 = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 2.0, 2.0, 1.0], - knots=[0.0, 1.0], - multiplicities=[4, 4], - degree=3, -) - -curve3 = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 1.0, 1.0, 1.0], - knots=[0.0, 1 / 3, 2 / 3, 1.0], - multiplicities=[3, 1, 1, 3], - degree=3, -) - -curve4 = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 1.0, 1.0, 1.0], - knots=[0.0, 1 / 5, 2 / 5, 3 / 5, 4 / 5, 1.0], - multiplicities=[2, 1, 1, 1, 1, 2], - degree=3, -) - -curve5 = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 1.0, 1.0, 1.0], - knots=[0.0, 1 / 7, 2 / 7, 3 / 7, 4 / 7, 5 / 7, 6 / 7, 1.0], - multiplicities=[1, 1, 1, 1, 1, 1, 1, 1], - degree=3, -) - -# curve6 = NurbsCurve.from_parameters( -# points=points, -# weights=[1.0, 1.0, 1.0, 1.0], -# knots=[0.0, 0.5, 1.0], -# multiplicities=[3, 1, 3], -# degree=2 -# ) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(Polyline(bezier.points)).draw() -Artist(Polyline(bezier.locus())).draw() - -Artist(Polyline(curve1.points)).draw(show_points=True) - -color = Color.red() - -Artist(curve1).draw(color=color) -Artist(curve2).draw(color=color.lightened(factor=20)) -Artist(curve3).draw(color=color.lightened(factor=40)) -Artist(curve4).draw(color=color.lightened(factor=60)) -Artist(curve5).draw(color=color.lightened(factor=80)) -# Artist(curve6).draw(color=color.lightened(factor=50)) - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_circle.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_circle.py deleted file mode 100644 index 8ecff71057d..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_circle.py +++ /dev/null @@ -1,21 +0,0 @@ -from compas.geometry import Vector, Point, Plane -from compas.geometry import Polyline -from compas.geometry import Circle -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -circle = Circle(Plane(Point(0, 0, 0), Vector(0, 0, 1)), 1.0) -curve = NurbsCurve.from_circle(circle) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(curve).draw(color=Color.green()) -Artist(Polyline(curve.points)).draw(show_points=True) - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_ellipse.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_ellipse.py deleted file mode 100644 index 0ee6da9a32c..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_ellipse.py +++ /dev/null @@ -1,21 +0,0 @@ -from compas.geometry import Vector, Point, Plane -from compas.geometry import Polyline -from compas.geometry import Ellipse -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -ellipse = Ellipse(Plane(Point(0, 0, 0), Vector(0, 0, 1)), 2.0, 1.0) -curve = NurbsCurve.from_ellipse(ellipse) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(curve).draw(color=Color.green()) -Artist(Polyline(curve.points)).draw(show_points=True) - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_interpolation.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_interpolation.py deleted file mode 100644 index c449ffea17e..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_interpolation.py +++ /dev/null @@ -1,26 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline, Bezier -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -points = [Point(0, 0, 0), Point(3, 6, 0), Point(6, -3, 3), Point(10, 0, 0)] -bezier = Bezier(points) -points = bezier.locus(10) - -curve = NurbsCurve.from_interpolation(points) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(curve).draw(color=Color.green()) -Artist(Polyline(curve.points)).draw(show_points=True) - -for point in points: - Artist(point).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_line.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_line.py deleted file mode 100644 index 60eb4c2205f..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_line.py +++ /dev/null @@ -1,22 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Line -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -line = Line(Point(0, 0, 0), Point(3, 3, 0)) -curve = NurbsCurve.from_line(line) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(curve).draw(color=Color.green()) - -for point in curve.points: - Artist(point).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_parameters.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_parameters.py deleted file mode 100644 index 1362bd83833..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_parameters.py +++ /dev/null @@ -1,27 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -points = [Point(0, 0, 0), Point(3, 6, 0), Point(6, -3, 3), Point(10, 0, 0)] - -curve = NurbsCurve.from_parameters( - points=points, - weights=[1.0, 1.0, 1.0, 1.0], - knots=[0.0, 1.0], - multiplicities=[4, 4], - degree=3, -) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(curve).draw(color=Color.green()) -Artist(Polyline(curve.points)).draw(show_points=True) - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_points.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_points.py deleted file mode 100644 index 59dad83714e..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/curve_from_points.py +++ /dev/null @@ -1,21 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline -from compas.geometry import NurbsCurve -from compas.artists import Artist -from compas.colors import Color - - -points = [Point(0, 0, 0), Point(3, 6, 0), Point(6, -3, 3), Point(10, 0, 0)] - -curve = NurbsCurve.from_points(points) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(curve).draw(color=Color.green()) -Artist(Polyline(curve.points)).draw(show_points=True) - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_aabb.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_aabb.py deleted file mode 100644 index 4821d031adb..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_aabb.py +++ /dev/null @@ -1,43 +0,0 @@ -from math import radians -from compas.geometry import Point, Translation, Rotation -from compas.geometry import Polyline -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -points = [ - [Point(0, 0, 0), Point(1, 0, 0), Point(2, 0, 0), Point(3, 0, 0), Point(4, 0, 0)], - [Point(0, 1, 0), Point(1, 1, 2), Point(2, 1, 2), Point(3, 1, 0), Point(4, 1, 0)], - [Point(0, 2, 0), Point(1, 2, 2), Point(2, 2, 2), Point(3, 2, 0), Point(4, 2, 0)], - [Point(0, 3, 0), Point(1, 3, 0), Point(2, 3, 0), Point(3, 3, 0), Point(4, 3, 0)], -] - -surface = NurbsSurface.from_points(points=points) - -T = Translation.from_vector([0, -1.5, 0]) -R = Rotation.from_axis_and_angle([0, 0, 1], radians(45)) - -surface.transform(R * T) - -# ============================================================================== -# AABB -# ============================================================================== - -box = surface.aabb(optimal=True) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -for row in surface.points: - Artist(Polyline(row)).draw() - -for col in zip(*list(surface.points)): - Artist(Polyline(col)).draw() - -Artist(surface).draw() -Artist(box).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_frames.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_frames.py deleted file mode 100644 index 804c02af11c..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_frames.py +++ /dev/null @@ -1,34 +0,0 @@ -from compas.geometry import Point -from compas.utilities import meshgrid, flatten -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -points = [ - [Point(0, 0, 0), Point(1, 0, 0), Point(2, 0, 0), Point(3, 0, 0)], - [Point(0, 1, 0), Point(1, 1, 2), Point(2, 1, 2), Point(3, 1, 0)], - [Point(0, 2, 0), Point(1, 2, 2), Point(2, 2, 2), Point(3, 2, 0)], - [Point(0, 3, 0), Point(1, 3, 0), Point(2, 3, 0), Point(3, 3, 0)], -] - -surface = NurbsSurface.from_points(points=points) - -# ============================================================================== -# Frames -# ============================================================================== - -U, V = meshgrid(surface.u_space(), surface.v_space(), "ij") -frames = [surface.frame_at(u, v) for u, v in zip(flatten(U), flatten(V))] - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -Artist(surface).draw() - -for frame in frames: - Artist(frame).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_meshgrid.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_meshgrid.py deleted file mode 100644 index 267b293c934..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_meshgrid.py +++ /dev/null @@ -1,44 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline -from compas.utilities import meshgrid, linspace -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -UU, VV = meshgrid(linspace(0, 8, 9), linspace(0, 5, 6)) - -Z = 0.5 - -points = [] -for i, (U, V) in enumerate(zip(UU, VV)): - row = [] - for j, (u, v) in enumerate(zip(U, V)): - if i == 0 or i == 5 or j == 0 or j == 8: - z = 0.0 - elif i < 2 or i > 3: - z = -1.0 - else: - if j < 2 or j > 6: - z = -1.0 - else: - z = Z - row.append(Point(u, v, z)) - points.append(row) - -surface = NurbsSurface.from_points(points=points) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -for row in surface.points: - Artist(Polyline(row)).draw() - -for col in zip(*list(surface.points)): - Artist(Polyline(col)).draw() - -Artist(surface).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_parameters.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_parameters.py deleted file mode 100644 index d73814b3128..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_parameters.py +++ /dev/null @@ -1,103 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -points = [ - [ - Point(0, 0, 0), - Point(1, 0, +0), - Point(2, 0, +0), - Point(3, 0, +0), - Point(4, 0, +0), - Point(5, 0, 0), - ], - [ - Point(0, 1, 0), - Point(1, 1, -1), - Point(2, 1, -1), - Point(3, 1, -1), - Point(4, 1, -1), - Point(5, 1, 0), - ], - [ - Point(0, 2, 0), - Point(1, 2, -1), - Point(2, 2, +2), - Point(3, 2, +2), - Point(4, 2, -1), - Point(5, 2, 0), - ], - [ - Point(0, 3, 0), - Point(1, 3, -1), - Point(2, 3, +2), - Point(3, 3, +2), - Point(4, 3, -1), - Point(5, 3, 0), - ], - [ - Point(0, 4, 0), - Point(1, 4, -1), - Point(2, 4, -1), - Point(3, 4, -1), - Point(4, 4, -1), - Point(5, 4, 0), - ], - [ - Point(0, 5, 0), - Point(1, 5, +0), - Point(2, 5, +0), - Point(3, 5, +0), - Point(4, 5, +0), - Point(5, 5, 0), - ], -] - -weights = [ - [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], - [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], - [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], - [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], - [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], - [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], -] - -surface = NurbsSurface.from_parameters( - points=points, - weights=weights, - u_knots=[ - 1.0, - 1 + 1 / 9, - 1 + 2 / 9, - 1 + 3 / 9, - 1 + 4 / 9, - 1 + 5 / 9, - 1 + 6 / 9, - 1 + 7 / 9, - 1 + 8 / 9, - 2.0, - ], - v_knots=[0.0, 1 / 9, 2 / 9, 3 / 9, 4 / 9, 5 / 9, 6 / 9, 7 / 9, 8 / 9, 1.0], - u_mults=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - v_mults=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - u_degree=3, - v_degree=3, -) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -for row in surface.points: - Artist(Polyline(row)).draw() - -for col in zip(*list(surface.points)): - Artist(Polyline(col)).draw() - -Artist(surface).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_points.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_points.py deleted file mode 100644 index b1086dbb1f7..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_from_points.py +++ /dev/null @@ -1,30 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -points = [ - [Point(0, 0, 0), Point(1, 0, 0), Point(2, 0, 0), Point(3, 0, 0)], - [Point(0, 1, 0), Point(1, 1, 2), Point(2, 1, 2), Point(3, 1, 0)], - [Point(0, 2, 0), Point(1, 2, 2), Point(2, 2, 2), Point(3, 2, 0)], - [Point(0, 3, 0), Point(1, 3, 0), Point(2, 3, 0), Point(3, 3, 0)], -] - -surface = NurbsSurface.from_points(points=points) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -for row in surface.points: - Artist(Polyline(row)).draw() - -for col in zip(*list(surface.points)): - Artist(Polyline(col)).draw() - -Artist(surface).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_isocurves.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_isocurves.py deleted file mode 100644 index d32c44836fb..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_isocurves.py +++ /dev/null @@ -1,40 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -points = [ - [Point(0, 0, 0), Point(1, 0, 0), Point(2, 0, 0), Point(3, 0, 0), Point(4, 0, 0)], - [Point(0, 1, 0), Point(1, 1, 2), Point(2, 1, 2), Point(3, 1, 0), Point(4, 1, 0)], - [Point(0, 2, 0), Point(1, 2, 2), Point(2, 2, 2), Point(3, 2, 0), Point(4, 2, 0)], - [Point(0, 3, 0), Point(1, 3, 0), Point(2, 3, 0), Point(3, 3, 0), Point(4, 3, 0)], -] - -surface = NurbsSurface.from_points(points=points) - -# ============================================================================== -# Isocurves -# ============================================================================== - -u_curves = [] -for u in surface.u_space(): - u_curves.append(surface.u_isocurve(u)) - -v_curves = [] -for v in surface.v_space(): - v_curves.append(surface.v_isocurve(v)) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -for curve in u_curves: - Artist(Polyline(curve.locus())).draw() - -for curve in v_curves: - Artist(Polyline(curve.locus())).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_jsondata.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_jsondata.py deleted file mode 100644 index fbb53bff069..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_jsondata.py +++ /dev/null @@ -1,45 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -points = [ - [Point(0, 0, 0), Point(1, 0, 0), Point(2, 0, 0), Point(3, 0, 0)], - [Point(0, 1, 0), Point(1, 1, 2), Point(2, 1, 2), Point(3, 1, 0)], - [Point(0, 2, 0), Point(1, 2, 2), Point(2, 2, 2), Point(3, 2, 0)], - [Point(0, 3, 0), Point(1, 3, 0), Point(2, 3, 0), Point(3, 3, 0)], -] - -surface = NurbsSurface.from_points(points=points) - -# ============================================================================== -# JSON Data -# ============================================================================== - -string = surface.to_jsonstring(pretty=True) - -print(string) - -other = NurbsSurface.from_jsonstring(string) - -# print(surface == other) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -u = surface.u_isocurve(0.5 * sum(surface.u_domain)) -v = surface.v_isocurve(0.5 * sum(surface.v_domain)) - -Artist(Polyline(u.locus())).draw() -Artist(Polyline(v.locus())).draw() - -# for curve in surface.boundary(): -# Artist(Polyline(curve.locus())).draw() - -Artist(other).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_random.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_random.py deleted file mode 100644 index b044928815a..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_random.py +++ /dev/null @@ -1,36 +0,0 @@ -import random -from compas.geometry import Polyline -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -U = 10 -V = 20 - -surface = NurbsSurface.from_meshgrid(nu=U, nv=V) - -# ============================================================================== -# Update -# ============================================================================== - -for u in range(1, U): - for v in range(1, V): - point = surface.points[u, v] - point.z = random.choice([+1, -1]) * random.random() - surface.points[u, v] = point - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -for row in surface.points: - Artist(Polyline(row)).draw() - -for col in zip(*list(surface.points)): - Artist(Polyline(col)).draw() - -Artist(surface).draw() - -Artist.redraw() diff --git a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_spacepoints.py b/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_spacepoints.py deleted file mode 100644 index a6ba872bce7..00000000000 --- a/docs/userguide/tutorials/geometry/curves_and_surfaces/surface_spacepoints.py +++ /dev/null @@ -1,39 +0,0 @@ -from compas.geometry import Point -from compas.geometry import Polyline -from compas.geometry import NurbsSurface -from compas.artists import Artist - - -points = [ - [Point(0, 0, 0), Point(1, 0, 0), Point(2, 0, 0), Point(3, 0, 0), Point(4, 0, 0)], - [Point(0, 1, 0), Point(1, 1, 2), Point(2, 1, 2), Point(3, 1, 0), Point(4, 1, 0)], - [Point(0, 2, 0), Point(1, 2, 2), Point(2, 2, 2), Point(3, 2, 0), Point(4, 2, 0)], - [Point(0, 3, 0), Point(1, 3, 0), Point(2, 3, 0), Point(3, 3, 0), Point(4, 3, 0)], -] - -surface = NurbsSurface.from_points(points=points) - -# ============================================================================== -# Points over UV space -# ============================================================================== - -spacepoints = surface.xyz(nu=50, nv=10) - -# ============================================================================== -# Visualisation -# ============================================================================== - -Artist.clear() - -for row in surface.points: - Artist(Polyline(row)).draw() - -for col in zip(*list(surface.points)): - Artist(Polyline(col)).draw() - -Artist(surface).draw() - -for point in spacepoints: - Artist(point).draw() - -Artist.redraw() diff --git a/docs/userguide/whatsnext.rst b/docs/userguide/whatsnext.rst new file mode 100644 index 00000000000..71b9c60c14a --- /dev/null +++ b/docs/userguide/whatsnext.rst @@ -0,0 +1,3 @@ +*********** +What's Next +*********** \ No newline at end of file diff --git a/docs/write_rst.py b/docs/write_rst.py new file mode 100644 index 00000000000..55978280048 --- /dev/null +++ b/docs/write_rst.py @@ -0,0 +1,152 @@ +# from pathlib import Path +from compas_rhino import geometry as module + +TPL = """ +******************************************************************************** +{currentmodule} +******************************************************************************** + +.. currentmodule:: {currentmodule} + +.. rst-class:: lead + +{lead} +{sections} + +""" + +SECTION = """ +{title} +{line} + +{summary} + +.. autosummary:: + :toctree: generated/ + :nosignatures: + +{items} +""" + +__newall__ = { + "functions": [], + "classes": [], + "errors": [], + "numpy": [], + "pluggables": [], + "plugins": [], +} + +for name in module.__all__: + obj = getattr(module, name) + + if name.endswith("_numpy"): + __newall__["numpy"].append(name) + continue + + if issubclass(type(obj), Exception): + __newall__["errors"].append(name) + continue + + if hasattr(obj, "__pluggable__"): + __newall__["pluggables"].append(name) + continue + + if hasattr(obj, "__plugin__"): + __newall__["plugins"].append(name) + continue + + if isinstance(obj, type): + __newall__["classes"].append(name) + else: + __newall__["functions"].append(name) + + +currentmodule = module.__name__ + +lead = module.__doc__ + +classes = "" +for name in sorted(__newall__["classes"]): + classes += " {name}\n".format(name=name) + +if classes: + classes = SECTION.format( + title="Classes", + line="=" * len("Classes"), + summary="", + items=classes, + ) + +errors = "" +for name in sorted(__newall__["errors"]): + errors += " {name}\n".format(name=name) + +if errors: + errors = SECTION.format( + title="Exceptions", + line="=" * len("Exceptions"), + summary="", + items=errors, + ) + +functions = "" +for name in sorted(__newall__["functions"]): + functions += " {name}\n".format(name=name) + +if functions: + functions = SECTION.format( + title="Functions", + line="=" * len("Functions"), + summary="", + items=functions, + ) + +numpy = "" +for name in sorted(__newall__["numpy"]): + numpy += " {name}\n".format(name=name) + +if numpy: + numpy = SECTION.format( + title="Functions using Numpy", + line="=" * len("Functions using Numpy"), + summary="In environments where numpy is not available, these functions can still be accessed through RPC.", + items=numpy, + ) + +pluggables = "" +for name in sorted(__newall__["pluggables"]): + pluggables += " {name}\n".format(name=name) + +if pluggables: + pluggables = SECTION.format( + title="Pluggables", + line="=" * len("Pluggables"), + summary="Pluggables are functions that don't have an actual implementation, but receive an implementation from a plugin.", + items=pluggables, + ) + +plugins = "" +for name in sorted(__newall__["plugins"]): + plugins += " {name}\n".format(name=name) + +if plugins: + plugins = SECTION.format( + title="Plugins", + line="=" * len("Plugins"), + summary="Plugins provide implementations for pluggables. You can use the plugin directly, or through the pluggable.", + items=plugins, + ) + +sections = "".join([classes, errors, functions, numpy, pluggables, plugins]) + +# docs = Path(__file__).parent + +with open("/Users/vanmelet/Code/compas/docs/reference/{name}.rst".format(name=module.__name__), "w") as f: + f.write( + TPL.format( + currentmodule=currentmodule, + lead=lead, + sections=sections, + ) + ) diff --git a/src/compas/artists/__init__.py b/src/compas/artists/__init__.py deleted file mode 100644 index 85cd6a8141b..00000000000 --- a/src/compas/artists/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -from __future__ import print_function -from __future__ import absolute_import -from __future__ import division - -from .exceptions import DataArtistNotRegistered -from .exceptions import NoArtistContextError -from .artist import Artist -from .meshartist import MeshArtist -from .networkartist import NetworkArtist -from .geometryartist import GeometryArtist -from .volmeshartist import VolMeshArtist - -from .artist import clear # noqa: F401 -from .artist import redraw # noqa: F401 -from .artist import register_artists # noqa: F401 - - -__all__ = [ - "DataArtistNotRegistered", - "NoArtistContextError", - "Artist", - "MeshArtist", - "NetworkArtist", - "GeometryArtist", - "VolMeshArtist", -] diff --git a/src/compas/colors/__init__.py b/src/compas/colors/__init__.py index 97e56cfd40d..b9b5b290c1a 100644 --- a/src/compas/colors/__init__.py +++ b/src/compas/colors/__init__.py @@ -1,3 +1,8 @@ +""" +This package defines a color and color map class, +that can be used to work wihth colors in a consistent way across color spaces. +""" + from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/src/compas/colors/color.py b/src/compas/colors/color.py index 8e09cb900a3..06e016b655c 100644 --- a/src/compas/colors/color.py +++ b/src/compas/colors/color.py @@ -357,7 +357,7 @@ def from_rgb255(cls, r, g, b): # type: (int, int, int) -> Color Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(r / 255, g / 255, b / 255) @@ -377,7 +377,7 @@ def from_hls(cls, hue, luminance, saturation): # type: (float, float, float) -> Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` References ---------- @@ -402,7 +402,7 @@ def from_hsv(cls, h, s, v): # type: (float, float, float) -> Color Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` References ---------- @@ -427,7 +427,7 @@ def from_yiq(cls, y, i, q): # type: (float, float, float) -> Color Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` References ---------- @@ -452,7 +452,7 @@ def from_yuv(cls, y, u, v): # type: (float, float, float) -> Color Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` References ---------- @@ -475,7 +475,7 @@ def from_i(cls, i): # type: (float) -> Color Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ if i == 0.0: @@ -511,7 +511,7 @@ def from_hex(cls, value): # type: (str) -> Color Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ value = value.lstrip("#").lower() @@ -531,7 +531,7 @@ def from_name(cls, name): # type: (str) -> Color Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` References ---------- @@ -553,7 +553,7 @@ def white(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(1.0, 1.0, 1.0) @@ -564,7 +564,7 @@ def black(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.0, 0.0, 0.0) @@ -575,7 +575,7 @@ def grey(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.5, 0.5, 0.5) @@ -586,7 +586,7 @@ def red(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(1.0, 0.0, 0.0) @@ -597,7 +597,7 @@ def orange(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(1.0, 0.5, 0.0) @@ -608,7 +608,7 @@ def yellow(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(1.0, 1.0, 0.0) @@ -619,7 +619,7 @@ def lime(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.5, 1.0, 0.0) @@ -630,7 +630,7 @@ def green(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.0, 1.0, 0.0) @@ -641,7 +641,7 @@ def mint(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.0, 1.0, 0.5) @@ -652,7 +652,7 @@ def cyan(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.0, 1.0, 1.0) @@ -663,7 +663,7 @@ def azure(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.0, 0.5, 1.0) @@ -674,7 +674,7 @@ def blue(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.0, 0.0, 1.0) @@ -685,7 +685,7 @@ def violet(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.5, 0.0, 1.0) @@ -696,7 +696,7 @@ def magenta(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(1.0, 0.0, 1.0) @@ -707,7 +707,7 @@ def pink(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(1.0, 0.0, 0.5) @@ -721,7 +721,7 @@ def maroon(cls): """Construct the color maroon. Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.5, 0.0, 0.0) @@ -732,7 +732,7 @@ def brown(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.5, 0.25, 0.0) @@ -743,7 +743,7 @@ def olive(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.5, 0.5, 0.0) @@ -754,7 +754,7 @@ def teal(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.0, 0.5, 0.5) @@ -765,7 +765,7 @@ def navy(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.0, 0.0, 0.5) @@ -776,7 +776,7 @@ def purple(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.5, 0.0, 0.5) @@ -787,7 +787,7 @@ def silver(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ return cls(0.75, 0.75, 0.75) @@ -810,12 +810,12 @@ def coerce(color): Parameters ---------- - color : str | tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color` + color : str | tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color` The color input. Returns ------- - :class:`~compas.colors.Color` | None + :class:`compas.colors.Color` | None Raises ------ @@ -909,7 +909,7 @@ def lightened(self, factor=10): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` Raises ------ @@ -960,7 +960,7 @@ def darkened(self, factor=10): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` Raises ------ @@ -989,7 +989,7 @@ def inverted(self): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ color = self.copy() @@ -1035,7 +1035,7 @@ def saturated(self, factor=10): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` Raises ------ @@ -1086,7 +1086,7 @@ def desaturated(self, factor=10): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` Raises ------ diff --git a/src/compas/colors/colordict.py b/src/compas/colors/colordict.py index 2915b1083fd..5e8d6462476 100644 --- a/src/compas/colors/colordict.py +++ b/src/compas/colors/colordict.py @@ -11,7 +11,7 @@ class ColorDict(Data): Attributes ---------- - default : :class:`~compas.colors.Color` + default : :class:`compas.colors.Color` The default color to use if the requested key is not in the dictionary. """ @@ -83,7 +83,7 @@ def update(self, other): Parameters ---------- - other : dict or :class:`~compas.artists.ColorDict` + other : dict or :class:`compas.scene.ColorDict` The other dictionary. Returns diff --git a/src/compas/colors/colormap.py b/src/compas/colors/colormap.py index d891bfd4673..0692d81beb5 100644 --- a/src/compas/colors/colormap.py +++ b/src/compas/colors/colormap.py @@ -31,7 +31,7 @@ class ColorMap(object): Attributes ---------- - colors : list[:class:`~compas.colors.Color`] + colors : list[:class:`compas.colors.Color`] The colors of the map. Raises @@ -95,7 +95,7 @@ def __call__(self, value, minval=0.0, maxval=1.0): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` Raises ------ @@ -124,7 +124,7 @@ def from_palette(cls, name): Returns ------- - :class:`~compas.colors.ColorMap` + :class:`compas.colors.ColorMap` A color map with 256 colors. Raises @@ -165,7 +165,7 @@ def from_mpl(cls, name): Returns ------- - :class:`~compas.colors.ColorMap` + :class:`compas.colors.ColorMap` A color map with 256 colors. Raises @@ -189,7 +189,7 @@ def from_color(cls, color, rangetype="full"): Parameters ---------- - color : :class:`~compas.colors.Color` + color : :class:`compas.colors.Color` The base color. rangetype : Literal['full', 'light', 'dark'], optional If ``'full'``, use the full luminance range (0.0 - 1.0). @@ -198,7 +198,7 @@ def from_color(cls, color, rangetype="full"): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` A color map with 256 colors. """ @@ -228,16 +228,16 @@ def from_two_colors(cls, c1, c2, diverging=False): Parameters ---------- - c1 : :class:`~compas.colors.Color` + c1 : :class:`compas.colors.Color` The first color. - c2 : :class:`~compas.colors.Color` + c2 : :class:`compas.colors.Color` The second color. diverging : bool, optional If True, use white as transition color in the middle. Returns ------- - :class:`~compas.colors.ColorMap` + :class:`compas.colors.ColorMap` A color map with 256 colors. """ @@ -267,16 +267,16 @@ def from_three_colors(cls, c1, c2, c3): Parameters ---------- - c1 : :class:`~compas.colors.Color` + c1 : :class:`compas.colors.Color` The first color. - c2 : :class:`~compas.colors.Color` + c2 : :class:`compas.colors.Color` The second color. - c3 : :class:`~compas.colors.Color` + c3 : :class:`compas.colors.Color` The third color. Returns ------- - :class:`~compas.colors.ColorMap` + :class:`compas.colors.ColorMap` A color map with 256 colors. """ @@ -299,7 +299,7 @@ def from_rgb(cls): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` """ colors = [] diff --git a/src/compas/data/__init__.py b/src/compas/data/__init__.py index a3a884ac2c6..8912e07f696 100644 --- a/src/compas/data/__init__.py +++ b/src/compas/data/__init__.py @@ -1,13 +1,11 @@ +""" +This package defines the core infrastructure for data serialisation in the COMPAS framework. +It provides a base class for data objects, a JSON encoder and decoder, serialisers and deserialisers, and schema validation. +""" + from __future__ import absolute_import from .exceptions import DecoderError -from .validators import is_sequence_of_int -from .validators import is_sequence_of_uint -from .validators import is_sequence_of_float -from .validators import is_int3 -from .validators import is_float3 -from .validators import is_float4x4 -from .validators import is_item_iterable from .encoders import DataEncoder from .encoders import DataDecoder from .data import Data @@ -20,13 +18,6 @@ "DataEncoder", "DataDecoder", "DecoderError", - "is_sequence_of_int", - "is_sequence_of_uint", - "is_sequence_of_float", - "is_int3", - "is_float3", - "is_float4x4", - "is_item_iterable", "json_load", "json_loads", "json_dump", diff --git a/src/compas/data/data.py b/src/compas/data/data.py index 1d85ed78fc4..8c6a6eaa1c5 100644 --- a/src/compas/data/data.py +++ b/src/compas/data/data.py @@ -180,7 +180,7 @@ def from_data(cls, data): # type: (dict) -> Data Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` An instance of this object type if the data contained in the dict has the correct schema. """ @@ -208,7 +208,7 @@ def from_json(cls, filepath): # type: (...) -> Data Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` An instance of this object type if the data contained in the file has the correct schema. """ @@ -233,13 +233,13 @@ def copy(self, cls=None): # type: (...) -> D Parameters ---------- - cls : Type[:class:`~compas.data.Data`], optional + cls : Type[:class:`compas.data.Data`], optional The type of data object to return. Defaults to the type of the current data object. Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` An independent copy of this object. """ diff --git a/src/compas/data/encoders.py b/src/compas/data/encoders.py index 41cb597de5d..d31f489e7cf 100644 --- a/src/compas/data/encoders.py +++ b/src/compas/data/encoders.py @@ -46,7 +46,7 @@ def cls_from_dtype(dtype): # type: (...) -> Type[Data] Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` Raises ------ @@ -70,7 +70,7 @@ class DataEncoder(json.JSONEncoder): * Numpy objects to their Python equivalents; * iterables to lists; and - * :class:`~compas.data.Data` objects, + * :class:`compas.data.Data` objects, such as geometric primitives and shapes, data structures, robots, ..., to a dict with the following structure: ``{'dtype': o.dtype, 'value': o.data}`` @@ -161,7 +161,7 @@ class DataDecoder(json.JSONDecoder): """Data decoder for custom JSON serialization with support for COMPAS data structures and geometric primitives. The decoder hooks into the JSON deserialisation process - to reconstruct :class:`~compas.data.Data` objects, + to reconstruct :class:`compas.data.Data` objects, such as geometric primitives and shapes, data structures, robots, ..., from the serialized data when possible. diff --git a/src/compas/data/json.py b/src/compas/data/json.py index a08f0eda83a..abeb59113c5 100644 --- a/src/compas/data/json.py +++ b/src/compas/data/json.py @@ -106,7 +106,7 @@ def json_dumps(data, pretty=False, compact=False, minimal=False): # type: (...) return json.dumps(data, cls=DataEncoder, **kwargs) -def json_load(fp): # type: (...) -> Data +def json_load(fp): # type: (...) -> dict """Read COMPAS object data from a JSON file. Parameters @@ -140,7 +140,7 @@ def json_load(fp): # type: (...) -> Data return json.load(f, cls=DataDecoder) -def json_loads(s): # type: (...) -> Data +def json_loads(s): # type: (...) -> dict """Read COMPAS object data from a JSON string. Parameters diff --git a/src/compas/data/schema.py b/src/compas/data/schema.py index 6ca1ffdae5e..a7a05965d87 100644 --- a/src/compas/data/schema.py +++ b/src/compas/data/schema.py @@ -11,7 +11,7 @@ def dataclass_dataschema(cls): # type: (...) -> dict Parameters ---------- - cls : :class:`~compas.data.Data` + cls : :class:`compas.data.Data` The COMPAS object class. Returns @@ -28,7 +28,7 @@ def dataclass_typeschema(cls): # type: (...) -> dict Parameters ---------- - cls : :class:`~compas.data.Data` + cls : :class:`compas.data.Data` The COMPAS object class. Returns @@ -48,7 +48,7 @@ def dataclass_jsonschema(cls, filepath=None, draft=None): # type: (...) -> dict Parameters ---------- - cls : :class:`~compas.data.Data` + cls : :class:`compas.data.Data` The COMPAS object class. filepath : str, optional The path to the file where the schema should be saved. diff --git a/src/compas/datastructures/__init__.py b/src/compas/datastructures/__init__.py index cd761fe275a..0e076ef46b9 100644 --- a/src/compas/datastructures/__init__.py +++ b/src/compas/datastructures/__init__.py @@ -1,3 +1,8 @@ +""" +This package defines the core data structures of the COMPAS framework. +The data structures provide a structured way of storing and accessing data on individual components of both topological and geometrical objects. +""" + from __future__ import absolute_import import compas diff --git a/src/compas/datastructures/assembly/assembly.py b/src/compas/datastructures/assembly/assembly.py index 4a042a1f63a..95f2f3bed96 100644 --- a/src/compas/datastructures/assembly/assembly.py +++ b/src/compas/datastructures/assembly/assembly.py @@ -19,7 +19,7 @@ class Assembly(Datastructure): ---------- attributes : dict[str, Any] General attributes of the data structure that will be included in the data dict and serialization. - graph : :class:`~compas.datastructures.Graph` + graph : :class:`compas.datastructures.Graph` The graph that is used under the hood to store the parts and their connections. See Also @@ -94,7 +94,7 @@ def add_part(self, part, key=None, **kwargs): Parameters ---------- - part : :class:`~compas.datastructures.Part` + part : :class:`compas.datastructures.Part` The part to add. key : int | str, optional The identifier of the part in the assembly. @@ -122,9 +122,9 @@ def add_connection(self, a, b, **kwargs): Parameters ---------- - a : :class:`~compas.datastructures.Part` + a : :class:`compas.datastructures.Part` The "from" part. - b : :class:`~compas.datastructures.Part` + b : :class:`compas.datastructures.Part` The "to" part. **kwargs : dict[str, Any], optional Attribute dict compiled from named arguments. @@ -152,7 +152,7 @@ def parts(self): Yields ------ - :class:`~compas.datastructures.Part` + :class:`compas.datastructures.Part` The individual parts of the assembly. """ @@ -187,7 +187,7 @@ def find(self, guid): Returns ------- - :class:`~compas.datastructures.Part` | None + :class:`compas.datastructures.Part` | None The identified part, or None if the part can't be found. @@ -209,7 +209,7 @@ def find_by_key(self, key): Returns ------- - :class:`~compas.datastructures.Part` | None + :class:`compas.datastructures.Part` | None The identified part, or None if the part can't be found. diff --git a/src/compas/datastructures/assembly/part.py b/src/compas/datastructures/assembly/part.py index cd629a95e7c..9524e528d2b 100644 --- a/src/compas/datastructures/assembly/part.py +++ b/src/compas/datastructures/assembly/part.py @@ -10,14 +10,14 @@ class Feature(Data): - """Base class for a feature which may be applied to a :class:`~compas.datastructures.Part`.""" + """Base class for a feature which may be applied to a :class:`compas.datastructures.Part`.""" def apply(self, part): """Apply this Feature to the given part. Parameters ---------- - part : :class:`~compas.datastructures.Part` + part : :class:`compas.datastructures.Part` The part onto which this feature should be applied. """ @@ -25,7 +25,7 @@ def apply(self, part): class GeometricFeature(Feature): - """Base class for geometric feature which may be applied to a :class:`~compas.datastructures.Part`. + """Base class for geometric feature which may be applied to a :class:`compas.datastructures.Part`. Applies a binary operation on Part's current geometry and the feature's. @@ -76,7 +76,7 @@ def from_data(cls, data): class ParametricFeature(Feature): - """Base class for Features that may be applied to the parametric definition of a :class:`~compas.datastructures.Part`. + """Base class for Features that may be applied to the parametric definition of a :class:`compas.datastructures.Part`. Examples -------- @@ -104,7 +104,7 @@ def restore(self, part): Parameters ---------- - part : :class:`~compas.datastructures.Part` + part : :class:`compas.datastructures.Part` The part onto which this feature has been previously applied and should now be reverted. """ @@ -117,12 +117,12 @@ def accumulate(self, feature): Parameters ---------- - feature : :class:`~compas.datastructures.ParametricFeature` + feature : :class:`compas.datastructures.ParametricFeature` Another compatible ParametricFeature whose effect should be accumulated with this one's. Returns ------- - :class:`~compas.datastructures.ParametricFeatures` + :class:`compas.datastructures.ParametricFeatures` """ raise NotImplementedError @@ -136,7 +136,7 @@ class Part(Datastructure): name : str, optional The name of the part. The name will be stored in :attr:`Part.attributes`. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system of the part. Attributes @@ -145,9 +145,9 @@ class Part(Datastructure): General data structure attributes that will be included in the data dict and serialization. key : int or str The identifier of the part in the connectivity graph of the parent assembly. - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` The local coordinate system of the part. - features : list(:class:`~compas.datastructures.Feature`) + features : list(:class:`compas.datastructures.Feature`) The features added to the base shape of the part's geometry. """ @@ -193,7 +193,7 @@ def get_geometry(self, with_features=False): """ Returns a transformed copy of the part's geometry. - The returned type can be drawn with an Artist. + The returned type can be drawn with a scene object. Parameters ---------- @@ -202,7 +202,7 @@ def get_geometry(self, with_features=False): Returns ------- - :class:`~compas.geometry.Geometry` + :class:`compas.geometry.Geometry` """ raise NotImplementedError @@ -215,7 +215,7 @@ def add_feature(self, feature, apply=False): Parameters ---------- - feature : :class:`~compas.assembly.Feature` + feature : :class:`compas.assembly.Feature` The feature to add apply : :bool: If True, feature is also applied. Otherwise, feature is only added and user must call `apply_features`. diff --git a/src/compas/datastructures/cell_network/cell_network.py b/src/compas/datastructures/cell_network/cell_network.py index 51c050ad302..ba8f9636ade 100644 --- a/src/compas/datastructures/cell_network/cell_network.py +++ b/src/compas/datastructures/cell_network/cell_network.py @@ -203,11 +203,20 @@ def add_edge(self, u, v, attr_dict=None, **kwattr): tuple[hashable, hashable] The identifier of the edge. + Raises + ------ + ValueError + If either of the nodes of the edge does not exist. + """ + if u not in self._vertex: + raise ValueError("Cannot add edge {}, {} has no vertex {}".format((u, v), self.name, u)) + if v not in self._vertex: + raise ValueError("Cannot add edge {}, {} has no vertex {}".format((u, v), self.name, u)) + attr = attr_dict or {} attr.update(kwattr) - assert u in self._vertex, "Cannot add edge {}, {} has no vertex {}".format((u, v), self.name, u) - assert v in self._vertex, "Cannot add edge {}, {} has no vertex {}".format((u, v), self.name, u) + data = self._edge[u].get(v, {}) data.update(attr) self._edge[u][v] = data @@ -302,6 +311,36 @@ def edge_coordinates(self, edge, axes="xyz"): u, v = edge return self.vertex_coordinates(u, axes=axes), self.vertex_coordinates(v, axes=axes) + def edge_start(self, edge): + """Return the start point of an edge. + + Parameters + ---------- + edge : tuple[int, int] + The edge identifier. + + Returns + ------- + :class:`compas.geometry.Point` + The start point. + """ + return self.vertex_point(edge[0]) + + def edge_end(self, edge): + """Return the end point of an edge. + + Parameters + ---------- + edge : tuple[int, int] + The edge identifier. + + Returns + ------- + :class:`compas.geometry.Point` + The end point. + """ + return self.vertex_point(edge[1]) + def edge_vector(self, edge): """Return the vector of an edge. @@ -346,7 +385,7 @@ def edge_line(self, edge): :class:`compas.geometry.Line` The line. """ - return Line(self.edge_start(edge), self.edge_end(edge)) + return Line(*self.edge_coordinates(edge)) def edge_length(self, edge): """Return the length of an edge. @@ -714,6 +753,7 @@ def face_neighbors(self, fkey): ------- list[int] The identifiers of the neighboring faces. + """ nbrs = set() for edge in self.face_edges(fkey): @@ -732,6 +772,7 @@ def edge_face_adjacency(self, faces=None): ------- dict A dictionary dict[edge] = face key + """ faces = faces or self.faces() adjacency = {} @@ -756,7 +797,9 @@ def face_adjacency(self, faces=None): ------- dict A face adjacency dictionary. + """ + faces = faces or self.faces() faces_vertices = [self.face_vertices(face) for face in faces] vertices = list({v: None for face in faces_vertices for v in face}.keys()) # unique, but keep order return face_adjacency(vertices, faces) @@ -773,6 +816,7 @@ def face_cells(self, fkey): ------- list[int] The identifiers of the cells connected to the face. + """ cells = {cell for cell in [self.halfface_cell(fkey), self.halfface_opposite_cell(fkey)] if cell is not None} return list(cells) @@ -802,6 +846,7 @@ def is_halfface_on_boundary(self, halfface): bool True if the face is on the boundary. False otherwise. + """ u, v = self._halfface[halfface][:2] cu = 0 if self._plane[v][u][halfface] is None else 1 @@ -819,7 +864,8 @@ def face_cell_adjacency(self, faces=None): Parameters ---------- faces : list of int, optional - The faces for which to compute the adjacency, defaults to all faces in the datastructure + The faces for which to compute the adjacency, defaults to all faces in the datastructure. + """ faces = faces or self.faces() adjacency = {} @@ -1055,7 +1101,7 @@ def cell_to_mesh(self, cell): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. See Also diff --git a/src/compas/datastructures/graph/graph.py b/src/compas/datastructures/graph/graph.py index a9e0d908500..100c24cd54b 100644 --- a/src/compas/datastructures/graph/graph.py +++ b/src/compas/datastructures/graph/graph.py @@ -154,7 +154,7 @@ def from_edges(cls, edges): Returns ------- - :class:`~compas.datastructures.Graph` + :class:`compas.datastructures.Graph` See Also -------- @@ -180,7 +180,7 @@ def from_networkx(cls, graph): Returns ------- - :class:`~compas.datastructures.Graph` + :class:`compas.datastructures.Graph` See Also -------- diff --git a/src/compas/datastructures/mesh/bbox.py b/src/compas/datastructures/mesh/bbox.py index 93b8a158292..1a9e51c17b6 100644 --- a/src/compas/datastructures/mesh/bbox.py +++ b/src/compas/datastructures/mesh/bbox.py @@ -11,7 +11,7 @@ def mesh_bounding_box(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh data structure. Returns @@ -42,7 +42,7 @@ def mesh_bounding_box_xy(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh data structure. Returns diff --git a/src/compas/datastructures/mesh/bbox_numpy.py b/src/compas/datastructures/mesh/bbox_numpy.py index 6d592bc2870..31dea4c6fa6 100644 --- a/src/compas/datastructures/mesh/bbox_numpy.py +++ b/src/compas/datastructures/mesh/bbox_numpy.py @@ -11,7 +11,7 @@ def mesh_oriented_bounding_box_numpy(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh data structure. Returns @@ -37,7 +37,7 @@ def mesh_oriented_bounding_box_xy_numpy(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh data structure. Returns diff --git a/src/compas/datastructures/mesh/clean.py b/src/compas/datastructures/mesh/clean.py index f09c43322e7..928daef33d3 100644 --- a/src/compas/datastructures/mesh/clean.py +++ b/src/compas/datastructures/mesh/clean.py @@ -10,7 +10,7 @@ def mesh_delete_duplicate_vertices(mesh, precision=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. precision : str, optional Precision for point comparison in the form of a string formatting specifier. diff --git a/src/compas/datastructures/mesh/combinatorics.py b/src/compas/datastructures/mesh/combinatorics.py index 92833a6e701..0e160a475f8 100644 --- a/src/compas/datastructures/mesh/combinatorics.py +++ b/src/compas/datastructures/mesh/combinatorics.py @@ -11,7 +11,7 @@ def mesh_is_connected(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh data structure. Returns @@ -51,7 +51,7 @@ def mesh_connected_components(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh data structure. Returns diff --git a/src/compas/datastructures/mesh/contours_numpy.py b/src/compas/datastructures/mesh/contours_numpy.py index 4b8648d1e9f..0464fb89f94 100644 --- a/src/compas/datastructures/mesh/contours_numpy.py +++ b/src/compas/datastructures/mesh/contours_numpy.py @@ -12,7 +12,7 @@ import matplotlib.pyplot as plt -from compas.numerical import scalarfield_contours_numpy +from compas.numerical import scalarfield_contours def mesh_isolines_numpy(mesh, attr_name, N=50): @@ -20,7 +20,7 @@ def mesh_isolines_numpy(mesh, attr_name, N=50): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. attr_name : str The name of the vertex attribute. @@ -39,7 +39,7 @@ def mesh_isolines_numpy(mesh, attr_name, N=50): """ xy = [mesh.vertex_coordinates(key, "xy") for key in mesh.vertices()] s = [mesh.vertex[key][attr_name] for key in mesh.vertices()] - return scalarfield_contours_numpy(xy, s, N) + return scalarfield_contours(xy, s, N) def mesh_contours_numpy(mesh, levels=50, density=100): @@ -47,7 +47,7 @@ def mesh_contours_numpy(mesh, levels=50, density=100): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh object. levels : int, optional The number of contours. diff --git a/src/compas/datastructures/mesh/conway.py b/src/compas/datastructures/mesh/conway.py index 8b7f5b58ccf..8b87ddaaad6 100644 --- a/src/compas/datastructures/mesh/conway.py +++ b/src/compas/datastructures/mesh/conway.py @@ -8,12 +8,12 @@ def mesh_conway_dual(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The dual mesh. References @@ -54,12 +54,12 @@ def mesh_conway_join(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The join mesh. References @@ -111,12 +111,12 @@ def mesh_conway_ambo(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The ambo mesh. References @@ -149,12 +149,12 @@ def mesh_conway_kis(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The kis mesh. References @@ -198,12 +198,12 @@ def mesh_conway_needle(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The needle mesh. References @@ -236,12 +236,12 @@ def mesh_conway_zip(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The zip mesh. References @@ -274,12 +274,12 @@ def mesh_conway_truncate(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The truncate mesh. References @@ -313,12 +313,12 @@ def mesh_conway_ortho(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The ortho mesh. References @@ -351,12 +351,12 @@ def mesh_conway_expand(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The expand mesh. References @@ -389,12 +389,12 @@ def mesh_conway_gyro(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The gyro mesh. References @@ -450,12 +450,12 @@ def mesh_conway_snub(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The gyro mesh. References @@ -488,12 +488,12 @@ def mesh_conway_meta(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The meta mesh. References @@ -526,12 +526,12 @@ def mesh_conway_bevel(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A seed mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The bevel mesh. References diff --git a/src/compas/datastructures/mesh/curvature.py b/src/compas/datastructures/mesh/curvature.py index 20c3160f11b..a475995e3d1 100644 --- a/src/compas/datastructures/mesh/curvature.py +++ b/src/compas/datastructures/mesh/curvature.py @@ -16,7 +16,7 @@ def trimesh_gaussian_curvature(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The triangle mesh data structure. Returns diff --git a/src/compas/datastructures/mesh/descent_numpy.py b/src/compas/datastructures/mesh/descent_numpy.py index 837ebb1dd59..058d6529b31 100644 --- a/src/compas/datastructures/mesh/descent_numpy.py +++ b/src/compas/datastructures/mesh/descent_numpy.py @@ -11,7 +11,7 @@ def trimesh_descent(trimesh): Parameters ---------- - trimesh : :class:`~compas.datastructures.Mesh` + trimesh : :class:`compas.datastructures.Mesh` The triangle mesh. Returns diff --git a/src/compas/datastructures/mesh/duality.py b/src/compas/datastructures/mesh/duality.py index f64565d309a..c06bd172095 100644 --- a/src/compas/datastructures/mesh/duality.py +++ b/src/compas/datastructures/mesh/duality.py @@ -14,9 +14,9 @@ def mesh_dual(mesh, cls=None, include_boundary=False): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. - cls : Type[:class:`~compas.datastructures.Mesh`], optional + cls : Type[:class:`compas.datastructures.Mesh`], optional The type of the dual mesh. Defaults to the type of the provided mesh object. include_boundary: bool, optional @@ -25,7 +25,7 @@ def mesh_dual(mesh, cls=None, include_boundary=False): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The dual mesh object. Examples diff --git a/src/compas/datastructures/mesh/explode.py b/src/compas/datastructures/mesh/explode.py index 3a17d0ea90c..78107778cf2 100644 --- a/src/compas/datastructures/mesh/explode.py +++ b/src/compas/datastructures/mesh/explode.py @@ -10,7 +10,7 @@ def mesh_disconnected_vertices(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh. Returns @@ -27,7 +27,7 @@ def mesh_disconnected_faces(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh. Returns @@ -45,14 +45,14 @@ def mesh_explode(mesh, cls=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh. - cls : Type[:class:`~compas.datastructures.Mesh`], optional + cls : Type[:class:`compas.datastructures.Mesh`], optional The type of the return mesh. Returns ------- - list[:class:`~compas.datastructures.Mesh`] + list[:class:`compas.datastructures.Mesh`] The list of the meshes from the exploded mesh parts. """ diff --git a/src/compas/datastructures/mesh/geodesics_numpy.py b/src/compas/datastructures/mesh/geodesics_numpy.py index eccafb1d85a..1345a2a7d71 100644 --- a/src/compas/datastructures/mesh/geodesics_numpy.py +++ b/src/compas/datastructures/mesh/geodesics_numpy.py @@ -25,7 +25,7 @@ def mesh_geodesic_distances_numpy(mesh, sources, m=1.0): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh instance. sources : list[int] A list of vertex identifiers from which the distances should be calculated. diff --git a/src/compas/datastructures/mesh/join.py b/src/compas/datastructures/mesh/join.py index b79369467b6..40a45c4ce7c 100644 --- a/src/compas/datastructures/mesh/join.py +++ b/src/compas/datastructures/mesh/join.py @@ -11,17 +11,17 @@ def mesh_weld(mesh, precision=None, cls=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh. precision: str, optional Tolerance distance for welding. - cls : Type[:class:`~compas.datastructures.Mesh`], optional + cls : Type[:class:`compas.datastructures.Mesh`], optional Type of the welded mesh. This defaults to the type of the first mesh in the list. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The welded mesh. """ @@ -49,15 +49,15 @@ def meshes_join(meshes, cls=None): Parameters ---------- - meshes : list[:class:`~compas.datastructures.Mesh`] + meshes : list[:class:`compas.datastructures.Mesh`] A list of meshes. - cls : Type[:class:`~compas.datastructures.Mesh`], optional + cls : Type[:class:`compas.datastructures.Mesh`], optional The type of the joined mesh. This defaults to the type of the first mesh in the list. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The joined mesh. Examples @@ -96,18 +96,18 @@ def meshes_join_and_weld(meshes, precision=None, cls=None): Parameters ---------- - meshes : list[:class:`~compas.datastructures.Mesh`] + meshes : list[:class:`compas.datastructures.Mesh`] A list of meshes. precision: str, optional Precision for point comparison in the form of a string formatting specifier. For example, floating point precision (``'3f'``), or decimal integer (``'d'``). Default is :attr:`compas.PRECISION`. - cls : Type[:class:`~compas.datastructures.Mesh`], optional + cls : Type[:class:`compas.datastructures.Mesh`], optional The type of return mesh. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The joined and welded mesh. """ diff --git a/src/compas/datastructures/mesh/matrices.py b/src/compas/datastructures/mesh/matrices.py index db78b10cc9a..6fa0a7004f3 100644 --- a/src/compas/datastructures/mesh/matrices.py +++ b/src/compas/datastructures/mesh/matrices.py @@ -26,7 +26,7 @@ def mesh_adjacency_matrix(mesh, rtype="array"): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. rtype : Literal['array', 'csc', 'csr', 'coo', 'list'], optional Format of the result. @@ -57,7 +57,7 @@ def mesh_connectivity_matrix(mesh, rtype="array"): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. rtype : Literal['array', 'csc', 'csr', 'coo', 'list'], optional Format of the result. @@ -92,7 +92,7 @@ def mesh_degree_matrix(mesh, rtype="array"): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. rtype : Literal['array', 'csc', 'csr', 'coo', 'list'], optional Format of the result. @@ -127,7 +127,7 @@ def mesh_face_matrix(mesh, rtype="array"): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. rtype : Literal['array', 'csc', 'csr', 'coo', 'list'], optional Format of the result. @@ -184,7 +184,7 @@ def mesh_laplacian_matrix(mesh, rtype="csr"): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. rtype : Literal['array', 'csc', 'csr', 'coo', 'list'], optional Format of the result. @@ -269,7 +269,7 @@ def trimesh_edge_cotangent(mesh, edge): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. edge : tuple[int, int] The identifier of the halfedge. @@ -298,7 +298,7 @@ def trimesh_edge_cotangents(mesh, edge): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. edge : tuple[int, int] The identifier of the edge. @@ -320,7 +320,7 @@ def trimesh_cotangent_laplacian_matrix(mesh, rtype="csr"): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. Returns @@ -409,7 +409,7 @@ def trimesh_vertexarea_matrix(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The triangle mesh data structure. Returns diff --git a/src/compas/datastructures/mesh/mesh.py b/src/compas/datastructures/mesh/mesh.py index 3a17bbe1595..02502af91c5 100644 --- a/src/compas/datastructures/mesh/mesh.py +++ b/src/compas/datastructures/mesh/mesh.py @@ -181,7 +181,7 @@ def from_obj(cls, filepath, precision=None): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. Notes @@ -247,7 +247,7 @@ def from_ply(cls, filepath, precision=None): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -286,7 +286,7 @@ def from_stl(cls, filepath, precision=None): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -335,7 +335,7 @@ def from_off(cls, filepath): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -379,7 +379,7 @@ def from_lines(cls, lines, delete_boundary_face=False, precision=None): # type: Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -426,7 +426,7 @@ def from_polylines(cls, boundary_polylines, other_polylines): # type: (...) -> Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -489,7 +489,7 @@ def from_vertices_and_faces(cls, vertices, faces): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -567,7 +567,7 @@ def from_polyhedron(cls, f): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -580,14 +580,14 @@ def from_shape(cls, shape, **kwargs): # type: (...) -> Mesh Parameters ---------- - shape : :class:`~compas.geometry.Shape` + shape : :class:`compas.geometry.Shape` The input shape to generate a mesh from. **kwargs : dict[str, Any], optional Optional keyword arguments to be passed on to :meth:`compas.geometry.Shape.to_vertices_and_faces`. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -608,7 +608,7 @@ def from_points(cls, points, boundary=None, holes=None): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -643,7 +643,7 @@ def from_polygons(cls, polygons, precision=None): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -691,7 +691,7 @@ def from_meshgrid(cls, dx, nx, dy=None, ny=None): # type: (...) -> Mesh Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. """ @@ -805,7 +805,7 @@ def join(self, other): Parameters ---------- - other : :class:`~compas.datastructures.Mesh` + other : :class:`compas.datastructures.Mesh` The other mesh. Returns diff --git a/src/compas/datastructures/mesh/offset.py b/src/compas/datastructures/mesh/offset.py index e06f5979efa..45d6bf22183 100644 --- a/src/compas/datastructures/mesh/offset.py +++ b/src/compas/datastructures/mesh/offset.py @@ -14,14 +14,14 @@ def mesh_offset(mesh, distance=1.0): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A Mesh to offset. distance : float, optional The offset distance. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The offset mesh. Notes @@ -57,7 +57,7 @@ def mesh_thicken(mesh, thickness=1.0, both=True): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh to thicken. thickness : float, optional The mesh thickness. @@ -68,7 +68,7 @@ def mesh_thicken(mesh, thickness=1.0, both=True): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The thickened mesh. Raises diff --git a/src/compas/datastructures/mesh/operations/collapse.py b/src/compas/datastructures/mesh/operations/collapse.py index 3202f4117ae..d80a19f0913 100644 --- a/src/compas/datastructures/mesh/operations/collapse.py +++ b/src/compas/datastructures/mesh/operations/collapse.py @@ -8,7 +8,7 @@ def is_collapse_legal(mesh, edge, allow_boundary=False): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. edge : tuple[int, int] The identifier of the edge. @@ -76,7 +76,7 @@ def mesh_collapse_edge(mesh, edge, t=0.5, allow_boundary=False, fixed=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of a mesh. edge : tuple[int, int] The identifier of the edge. @@ -222,7 +222,7 @@ def trimesh_collapse_edge(mesh, edge, t=0.5, allow_boundary=False, fixed=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of a mesh. edge : tuple[int, int] The identifier of the edge. diff --git a/src/compas/datastructures/mesh/operations/insert.py b/src/compas/datastructures/mesh/operations/insert.py index 5faa6586b8a..f1a49ca00a2 100644 --- a/src/compas/datastructures/mesh/operations/insert.py +++ b/src/compas/datastructures/mesh/operations/insert.py @@ -8,7 +8,7 @@ def mesh_add_vertex_to_face_edge(mesh, key, fkey, v): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh data structure. key : int The identifier of the vertex. diff --git a/src/compas/datastructures/mesh/operations/merge.py b/src/compas/datastructures/mesh/operations/merge.py index 67dcc549704..9d8dbd636a4 100644 --- a/src/compas/datastructures/mesh/operations/merge.py +++ b/src/compas/datastructures/mesh/operations/merge.py @@ -8,7 +8,7 @@ def mesh_merge_faces(mesh, faces): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh data structure. faces : list[int] Face identifiers. diff --git a/src/compas/datastructures/mesh/operations/split.py b/src/compas/datastructures/mesh/operations/split.py index 58ed640c1fc..2a7f0cb840d 100644 --- a/src/compas/datastructures/mesh/operations/split.py +++ b/src/compas/datastructures/mesh/operations/split.py @@ -10,7 +10,7 @@ def mesh_split_edge(mesh, edge, t=0.5, allow_boundary=False): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of a mesh. edge : tuple[int, int] The identifier of the edge to split. @@ -86,7 +86,7 @@ def trimesh_split_edge(mesh, edge, t=0.5, allow_boundary=False): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of a mesh. edge : tuple[int, int] The identifier of the edge to split. @@ -163,7 +163,7 @@ def mesh_split_face(mesh, fkey, u, v): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of a mesh fkey : int The face key. @@ -231,7 +231,7 @@ def mesh_split_strip(mesh, edge): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The input mesh. edge : tuple[int, int] The edge identifying the strip. diff --git a/src/compas/datastructures/mesh/operations/swap.py b/src/compas/datastructures/mesh/operations/swap.py index 52c9fd74e75..adeac70e505 100644 --- a/src/compas/datastructures/mesh/operations/swap.py +++ b/src/compas/datastructures/mesh/operations/swap.py @@ -9,7 +9,7 @@ def trimesh_swap_edge(mesh, edge, allow_boundary=True): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Instance of mesh. edge : tuple[int, int] The identifier of the edge to swap. diff --git a/src/compas/datastructures/mesh/operations/weld.py b/src/compas/datastructures/mesh/operations/weld.py index 02aff67eb46..90132c0ccdd 100644 --- a/src/compas/datastructures/mesh/operations/weld.py +++ b/src/compas/datastructures/mesh/operations/weld.py @@ -15,7 +15,7 @@ def mesh_unweld_vertices(mesh, fkey, where=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. fkey : int The identifier of a face. @@ -53,7 +53,7 @@ def mesh_unweld_edges(mesh, edges): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh. edges: list[tuple[int, int]] List of edges as tuples of vertex keys. diff --git a/src/compas/datastructures/mesh/orientation.py b/src/compas/datastructures/mesh/orientation.py index 802a717f671..1fba0ee2154 100644 --- a/src/compas/datastructures/mesh/orientation.py +++ b/src/compas/datastructures/mesh/orientation.py @@ -16,36 +16,37 @@ def _mesh_face_adjacency(mesh, nmax=10, radius=10.0): from scipy.spatial import cKDTree tree = cKDTree(points) - _, closest = tree.query(points, k=k, n_jobs=-1) + _, closest = tree.query(points, k=k, workers=-1) except Exception: - # try: - # from Rhino.Geometry import RTree - # from Rhino.Geometry import Sphere - # from Rhino.Geometry import Point3d - - # except Exception: - from compas.geometry import KDTree - - tree = KDTree(points) - closest = [tree.nearest_neighbors(point, k) for point in points] - closest = [[index for xyz, index, d in nnbrs] for nnbrs in closest] - - # else: - # tree = RTree() - # for i, point in enumerate(points): - # tree.Insert(Point3d(* point), i) - - # def callback(sender, e): - # data = e.Tag - # data.append(e.Id) - - # closest = [] - # for i, point in enumerate(points): - # sphere = Sphere(Point3d(* point), radius) - # data = [] - # tree.Search(sphere, callback, data) - # closest.append(data) + try: + from Rhino.Geometry import RTree # type: ignore + from Rhino.Geometry import Sphere # type: ignore + from Rhino.Geometry import Point3d # type: ignore + + except Exception: + from compas.geometry import KDTree + + tree = KDTree(points) + closest = [tree.nearest_neighbors(point, k) for point in points] + closest = [[index for xyz, index, d in nnbrs] for nnbrs in closest] + + else: + tree = RTree() + + for i, point in enumerate(points): + tree.Insert(Point3d(*point), i) + + def callback(sender, e): + data = e.Tag + data.append(e.Id) + + closest = [] + for i, point in enumerate(points): + sphere = Sphere(Point3d(*point), radius) + data = [] + tree.Search(sphere, callback, data) + closest.append(data) adjacency = {} @@ -87,7 +88,7 @@ def mesh_face_adjacency(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. Returns @@ -112,13 +113,6 @@ def mesh_face_adjacency(mesh): faces = list(mesh.faces()) for fkey in mesh.faces(): - # faces = [] - # for key in mesh.face_vertices(fkey): - # for nbr in mesh.halfedge[key]: - # fnbr = mesh.halfedge[key][nbr] - # if fnbr is not None: - # faces.append(fnbr) - nbrs = [] found = set() @@ -154,7 +148,7 @@ def mesh_unify_cycles(mesh, root=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. root : str, optional The key of the root face. @@ -166,7 +160,7 @@ def mesh_unify_cycles(mesh, root=None): Raises ------ - AssertionError + Exception If no all faces are included in the unnification process. """ @@ -192,7 +186,8 @@ def unify(node, nbr): visited = breadth_first_traverse(adj, root, unify) - assert len(list(visited)) == mesh.number_of_faces(), "Not all faces were visited" + if len(list(visited)) != mesh.number_of_faces(): + raise Exception("Not all faces were visited.") mesh.halfedge = {key: {} for key in mesh.vertices()} for fkey in mesh.faces(): @@ -207,7 +202,7 @@ def mesh_flip_cycles(mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. Returns diff --git a/src/compas/datastructures/mesh/planarisation.py b/src/compas/datastructures/mesh/planarisation.py index 9cda441f14e..18aa2872b50 100644 --- a/src/compas/datastructures/mesh/planarisation.py +++ b/src/compas/datastructures/mesh/planarisation.py @@ -18,7 +18,7 @@ def mesh_flatness(mesh, maxdev=1.0): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. maxdev : float, optional A maximum value for the allowed deviation from flatness. @@ -62,7 +62,7 @@ def mesh_planarize_faces(mesh, fixed=None, kmax=100, callback=None, callback_arg Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. fixed : list[int], optional A list of fixed vertices. @@ -88,7 +88,6 @@ def mesh_planarize_faces(mesh, fixed=None, kmax=100, callback=None, callback_arg fixed = set(fixed) for k in range(kmax): - positions = {key: [] for key in mesh.vertices()} for fkey in mesh.faces(): diff --git a/src/compas/datastructures/mesh/pull_numpy.py b/src/compas/datastructures/mesh/pull_numpy.py index fb0ccb07baf..b1bcecaf92b 100644 --- a/src/compas/datastructures/mesh/pull_numpy.py +++ b/src/compas/datastructures/mesh/pull_numpy.py @@ -23,9 +23,9 @@ def trimesh_pull_points_numpy(mesh, points): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh data structure. - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] The input points. Returns diff --git a/src/compas/datastructures/mesh/remesh.py b/src/compas/datastructures/mesh/remesh.py index 9141a338326..c3992978b70 100644 --- a/src/compas/datastructures/mesh/remesh.py +++ b/src/compas/datastructures/mesh/remesh.py @@ -27,7 +27,7 @@ def trimesh_remesh( Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A triangle mesh. target : float The target length for the mesh edges. diff --git a/src/compas/datastructures/mesh/slice.py b/src/compas/datastructures/mesh/slice.py index 25b3f0f2a45..0a98705d584 100644 --- a/src/compas/datastructures/mesh/slice.py +++ b/src/compas/datastructures/mesh/slice.py @@ -9,14 +9,14 @@ def mesh_slice_plane(mesh, plane): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The original mesh. - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` The cutting plane. Returns ------- - tuple[:class:`~compas.datastructures.Mesh`, :class:`~compas.datastructures.Mesh`] | None + tuple[:class:`compas.datastructures.Mesh`, :class:`compas.datastructures.Mesh`] | None The "positive" and "negative" submeshes. If the mesh and plane do not intersect, or if the intersection is degenerate (point or line), diff --git a/src/compas/datastructures/mesh/smoothing.py b/src/compas/datastructures/mesh/smoothing.py index c8098937cd6..9e66281e4d5 100644 --- a/src/compas/datastructures/mesh/smoothing.py +++ b/src/compas/datastructures/mesh/smoothing.py @@ -11,7 +11,7 @@ def mesh_smooth_centroid(mesh, fixed=None, kmax=100, damping=0.5, callback=None, Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. fixed : list[int], optional The fixed vertices of the mesh. @@ -65,7 +65,7 @@ def mesh_smooth_centerofmass(mesh, fixed=None, kmax=100, damping=0.5, callback=N Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. fixed : list[int], optional The fixed vertices of the mesh. @@ -119,7 +119,7 @@ def mesh_smooth_area(mesh, fixed=None, kmax=100, damping=0.5, callback=None, cal Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. fixed : list[int], optional The fixed vertices of the mesh. diff --git a/src/compas/datastructures/mesh/smoothing_numpy.py b/src/compas/datastructures/mesh/smoothing_numpy.py index d03d2512e47..0e9682404cb 100644 --- a/src/compas/datastructures/mesh/smoothing_numpy.py +++ b/src/compas/datastructures/mesh/smoothing_numpy.py @@ -8,7 +8,7 @@ def trimesh_smooth_laplacian_cotangent(trimesh, fixed, kmax=10): Parameters ---------- - trimesh : :class:`~compas.datastructures.Mesh` + trimesh : :class:`compas.datastructures.Mesh` A triangle mesh. fixed : list[int] A list of fixed vertices. diff --git a/src/compas/datastructures/mesh/subdivision.py b/src/compas/datastructures/mesh/subdivision.py index 0db8bc76aaa..31f1f70e0fb 100644 --- a/src/compas/datastructures/mesh/subdivision.py +++ b/src/compas/datastructures/mesh/subdivision.py @@ -77,7 +77,7 @@ def mesh_subdivide(mesh, scheme="catmullclark", **options): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh object. scheme : Literal['tri', 'quad', 'corner', 'catmullclark', 'doosabin', 'frames', 'loop'], optional The scheme according to which the mesh should be subdivided. @@ -86,7 +86,7 @@ def mesh_subdivide(mesh, scheme="catmullclark", **options): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The subdivided mesh. Raises @@ -118,14 +118,14 @@ def mesh_subdivide_tri(mesh, k=1): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh object that will be subdivided. k : int, optional The number of levels of subdivision. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A new subdivided mesh. Examples @@ -158,14 +158,14 @@ def mesh_subdivide_quad(mesh, k=1): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh object that will be subdivided. k : int, optional The number of levels of subdivision. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A new subdivided mesh. Examples @@ -214,14 +214,14 @@ def mesh_subdivide_corner(mesh, k=1): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh object that will be subdivided. k : int, optional The number of levels of subdivision. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A new subdivided mesh. Notes @@ -257,7 +257,7 @@ def mesh_subdivide_catmullclark(mesh, k=1, fixed=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh object that will be subdivided. k : int, optional The number of levels of subdivision. @@ -266,7 +266,7 @@ def mesh_subdivide_catmullclark(mesh, k=1, fixed=None): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A new subdivided mesh. Notes @@ -441,7 +441,7 @@ def mesh_subdivide_doosabin(mesh, k=1, fixed=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh object that will be subdivided. k : int, optional The number of levels of subdivision. @@ -450,7 +450,7 @@ def mesh_subdivide_doosabin(mesh, k=1, fixed=None): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A new subdivided mesh. Examples @@ -556,7 +556,7 @@ def mesh_subdivide_frames(mesh, offset, add_windows=False): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh object to be subdivided. offset : float | dict[int, float] The offset distance to create the frames. @@ -567,7 +567,7 @@ def mesh_subdivide_frames(mesh, offset, add_windows=False): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A new subdivided mesh. """ @@ -623,7 +623,7 @@ def trimesh_subdivide_loop(mesh, k=1, fixed=None): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh object that will be subdivided. k : int, optional The number of levels of subdivision. @@ -632,7 +632,7 @@ def trimesh_subdivide_loop(mesh, k=1, fixed=None): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A new subdivided mesh. Examples diff --git a/src/compas/datastructures/mesh/transformations.py b/src/compas/datastructures/mesh/transformations.py index 232663a8c98..ba11bf8a568 100644 --- a/src/compas/datastructures/mesh/transformations.py +++ b/src/compas/datastructures/mesh/transformations.py @@ -10,9 +10,9 @@ def mesh_transform(mesh, transformation): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation. Returns @@ -42,14 +42,14 @@ def mesh_transformed(mesh, transformation): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A transformed independent copy of `mesh`. Examples diff --git a/src/compas/datastructures/mesh/transformations_numpy.py b/src/compas/datastructures/mesh/transformations_numpy.py index 6b2cf9bf9fd..7808345b540 100644 --- a/src/compas/datastructures/mesh/transformations_numpy.py +++ b/src/compas/datastructures/mesh/transformations_numpy.py @@ -10,9 +10,9 @@ def mesh_transform_numpy(mesh, transformation): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation. Returns @@ -42,14 +42,14 @@ def mesh_transformed_numpy(mesh, transformation): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation. Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A transformed independent copy of `mesh`. Examples diff --git a/src/compas/datastructures/mesh/triangulation.py b/src/compas/datastructures/mesh/triangulation.py index 19298855060..a2f978fe63e 100644 --- a/src/compas/datastructures/mesh/triangulation.py +++ b/src/compas/datastructures/mesh/triangulation.py @@ -11,7 +11,7 @@ def mesh_quads_to_triangles(mesh, check_angles=False): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A mesh data structure. check_angles : bool, optional Flag indicating that the angles of the quads should be checked to choose the best diagonal. diff --git a/src/compas/datastructures/mesh/trimesh_samplepoints_numpy.py b/src/compas/datastructures/mesh/trimesh_samplepoints_numpy.py index ab0c60511fb..2c9f31c2ce5 100644 --- a/src/compas/datastructures/mesh/trimesh_samplepoints_numpy.py +++ b/src/compas/datastructures/mesh/trimesh_samplepoints_numpy.py @@ -14,7 +14,7 @@ def trimesh_samplepoints_numpy(mesh, num_points=1000, return_normals=False): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A triangle mesh data structure. num_points : int, optional The number of sample points. diff --git a/src/compas/datastructures/network/combinatorics.py b/src/compas/datastructures/network/combinatorics.py index ee796af7daf..f9f22fe6f82 100644 --- a/src/compas/datastructures/network/combinatorics.py +++ b/src/compas/datastructures/network/combinatorics.py @@ -10,7 +10,7 @@ def network_is_connected(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network data structure. Returns diff --git a/src/compas/datastructures/network/complementarity.py b/src/compas/datastructures/network/complementarity.py index eb2a201258f..7d5c3de8fd1 100644 --- a/src/compas/datastructures/network/complementarity.py +++ b/src/compas/datastructures/network/complementarity.py @@ -13,12 +13,12 @@ def network_complement(network, cls=None): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network. Returns ------- - :class:`~compas.datastructures.Network` + :class:`compas.datastructures.Network` The complement network. References diff --git a/src/compas/datastructures/network/duality.py b/src/compas/datastructures/network/duality.py index cb0b1e2a03c..994254694b7 100644 --- a/src/compas/datastructures/network/duality.py +++ b/src/compas/datastructures/network/duality.py @@ -17,7 +17,7 @@ def network_find_cycles(network, breakpoints=None): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` The network object. breakpoints : list, optional The vertices at which to break the found faces. diff --git a/src/compas/datastructures/network/explode.py b/src/compas/datastructures/network/explode.py index 1750a479168..97bdd7bff93 100644 --- a/src/compas/datastructures/network/explode.py +++ b/src/compas/datastructures/network/explode.py @@ -10,7 +10,7 @@ def network_disconnected_nodes(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network. Returns @@ -27,7 +27,7 @@ def network_disconnected_edges(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network. Returns @@ -45,12 +45,12 @@ def network_explode(network, cls=None): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network. Returns ------- - list[:class:`~compas.datastructures.Network`] + list[:class:`compas.datastructures.Network`] The list of exploded network parts. """ diff --git a/src/compas/datastructures/network/matrices.py b/src/compas/datastructures/network/matrices.py index 814ae32564e..791c1ed277e 100644 --- a/src/compas/datastructures/network/matrices.py +++ b/src/compas/datastructures/network/matrices.py @@ -69,7 +69,7 @@ def network_connectivity_matrix(network, rtype="array"): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` Network data structure. rtype : Literal['array', 'csc', 'csr', 'coo', 'list'], optional Format of the result. @@ -90,7 +90,7 @@ def network_laplacian_matrix(network, normalize=False, rtype="array"): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` Network data structure. normalize : bool, optional If True, normalize the entries such that the value on the diagonal is 1. diff --git a/src/compas/datastructures/network/network.py b/src/compas/datastructures/network/network.py index b3dfaf8adf7..0e8edb75b1d 100644 --- a/src/compas/datastructures/network/network.py +++ b/src/compas/datastructures/network/network.py @@ -129,7 +129,7 @@ def from_obj(cls, filepath, precision=None): Returns ------- - :class:`~compas.datastructures.Network` + :class:`compas.datastructures.Network` A network object. See Also @@ -163,7 +163,7 @@ def from_lines(cls, lines, precision=None): Returns ------- - :class:`~compas.datastructures.Network` + :class:`compas.datastructures.Network` A network object. See Also @@ -205,7 +205,7 @@ def from_nodes_and_edges(cls, nodes, edges): Returns ------- - :class:`~compas.datastructures.Network` + :class:`compas.datastructures.Network` A network object. See Also @@ -234,14 +234,14 @@ def from_pointcloud(cls, cloud, degree=3): Parameters ---------- - cloud : :class:`~compas.geometry.Pointcloud` + cloud : :class:`compas.geometry.Pointcloud` A pointcloud object. degree : int, optional The number of connections per node. Returns ------- - :class:`~compas.datastructures.Network` + :class:`compas.datastructures.Network` A network object. See Also diff --git a/src/compas/datastructures/network/operations/join.py b/src/compas/datastructures/network/operations/join.py index 7777b15367e..63146c7a262 100644 --- a/src/compas/datastructures/network/operations/join.py +++ b/src/compas/datastructures/network/operations/join.py @@ -11,7 +11,7 @@ def network_join_edges(network, key): Parameters ---------- - network : :class:`~compas.geometry.Network` + network : :class:`compas.geometry.Network` A network data structure. key : hashable The node identifier. @@ -61,7 +61,7 @@ def network_polylines(network, splits=None): ---------- network : Network A network. - splits : sequence[[float, float, float] | :class:`~compas.geometry.Point`], optional + splits : sequence[[float, float, float] | :class:`compas.geometry.Point`], optional List of point coordinates for polyline splits. Returns diff --git a/src/compas/datastructures/network/planarity.py b/src/compas/datastructures/network/planarity.py index c743e041f50..6f86c882316 100644 --- a/src/compas/datastructures/network/planarity.py +++ b/src/compas/datastructures/network/planarity.py @@ -9,10 +9,11 @@ from itertools import product from compas.geometry import angle_vectors_xy -from compas.geometry import is_intersection_segment_segment_xy from compas.geometry import is_ccw_xy from compas.geometry import subtract_vectors_xy +from compas.geometry._core.predicates_2 import is_intersection_segment_segment_xy + def network_embed_in_plane_proxy(data, fixed=None, straightline=True): from compas.datastructures import Network @@ -27,7 +28,7 @@ def network_is_crossed(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network object. Returns @@ -71,7 +72,7 @@ def network_count_crossings(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network object. Returns @@ -92,7 +93,7 @@ def network_find_crossings(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network object. Returns @@ -127,7 +128,7 @@ def network_is_xy(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network object. Returns @@ -152,7 +153,7 @@ def network_is_planar(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network object. Returns @@ -189,7 +190,7 @@ def network_is_planar_embedding(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network object. Returns @@ -207,7 +208,7 @@ def network_embed_in_plane(network, fixed=None, straightline=True): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network object. fixed : [hashable, hashable], optional Two fixed points. diff --git a/src/compas/datastructures/network/transformations.py b/src/compas/datastructures/network/transformations.py index 8dd228a0256..b22dcf7014f 100644 --- a/src/compas/datastructures/network/transformations.py +++ b/src/compas/datastructures/network/transformations.py @@ -11,9 +11,9 @@ def network_transform(network, transformation): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` The network. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation. Returns @@ -38,14 +38,14 @@ def network_transformed(network, transformation): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` The network. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation. Returns ------- - :class:`~compas.datastructures.Network` + :class:`compas.datastructures.Network` A transformed independent copy of `network`. Notes diff --git a/src/compas/datastructures/network/traversal.py b/src/compas/datastructures/network/traversal.py index eeba6b1565b..9dd5dff8c93 100644 --- a/src/compas/datastructures/network/traversal.py +++ b/src/compas/datastructures/network/traversal.py @@ -10,7 +10,7 @@ def network_shortest_path(network, start, end): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A network data structure. start : hashable The identifier of the start node. diff --git a/src/compas/datastructures/tree/tree.py b/src/compas/datastructures/tree/tree.py index 7d55c7fcb94..63a36b84926 100644 --- a/src/compas/datastructures/tree/tree.py +++ b/src/compas/datastructures/tree/tree.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from __future__ import print_function from __future__ import absolute_import from __future__ import division @@ -22,11 +24,11 @@ class TreeNode(Data): The name of the datastructure. attributes : dict[str, Any] User-defined attributes of the datastructure. - parent : :class:`~compas.datastructures.TreeNode` + parent : :class:`compas.datastructures.TreeNode` The parent node of the tree node. - children : list[:class:`~compas.datastructures.TreeNode`] + children : list[:class:`compas.datastructures.TreeNode`] The children of the tree node. - tree : :class:`~compas.datastructures.Tree` + tree : :class:`compas.datastructures.Tree` The tree to which the node belongs. is_root : bool True if the node is the root node of the tree. @@ -34,9 +36,9 @@ class TreeNode(Data): True if the node is a leaf node of the tree. is_branch : bool True if the node is a branch node of the tree. - acestors : generator[:class:`~compas.datastructures.TreeNode`] + acestors : generator[:class:`compas.datastructures.TreeNode`] A generator of the acestors of the tree node. - descendants : generator[:class:`~compas.datastructures.TreeNode`] + descendants : generator[:class:`compas.datastructures.TreeNode`] A generator of the descendants of the tree node, using a depth-first preorder traversal. """ @@ -110,7 +112,7 @@ def add(self, node): Parameters ---------- - node : :class:`~compas.datastructures.TreeNode` + node : :class:`compas.datastructures.TreeNode` The node to add. Returns @@ -120,7 +122,7 @@ def add(self, node): Raises ------ TypeError - If the node is not a :class:`~compas.datastructures.TreeNode` object. + If the node is not a :class:`compas.datastructures.TreeNode` object. """ if not isinstance(node, TreeNode): @@ -135,7 +137,7 @@ def remove(self, node): Parameters ---------- - node : :class:`~compas.datastructures.TreeNode` + node : :class:`compas.datastructures.TreeNode` The node to remove. Returns @@ -173,7 +175,7 @@ def traverse(self, strategy="depthfirst", order="preorder"): Yields ------ - :class:`~compas.datastructures.TreeNode` + :class:`compas.datastructures.TreeNode` The next node in the traversal. Raises @@ -222,11 +224,11 @@ class Tree(Datastructure): The name of the datastructure. attributes : dict[str, Any] User-defined attributes of the datastructure. - root : :class:`~compas.datastructures.TreeNode` + root : :class:`compas.datastructures.TreeNode` The root node of the tree. - nodes : generator[:class:`~compas.datastructures.TreeNode`] + nodes : generator[:class:`compas.datastructures.TreeNode`] The nodes of the tree. - leaves : generator[:class:`~compas.datastructures.TreeNode`] + leaves : generator[:class:`compas.datastructures.TreeNode`] A generator of the leaves of the tree. Examples @@ -291,9 +293,9 @@ def add(self, node, parent=None): Parameters ---------- - node : :class:`~compas.datastructures.TreeNode` + node : :class:`compas.datastructures.TreeNode` The node to add. - parent : :class:`~compas.datastructures.TreeNode`, optional + parent : :class:`compas.datastructures.TreeNode`, optional The parent node of the node to add. Default is ``None``, in which case the node is added as a root node. @@ -304,8 +306,8 @@ def add(self, node, parent=None): Raises ------ TypeError - If the node is not a :class:`~compas.datastructures.TreeNode` object. - If the supplied parent node is not a :class:`~compas.datastructures.TreeNode` object. + If the node is not a :class:`compas.datastructures.TreeNode` object. + If the supplied parent node is not a :class:`compas.datastructures.TreeNode` object. ValueError If the node is already part of another tree. If the supplied parent node is not part of this tree. @@ -348,7 +350,7 @@ def remove(self, node): Parameters ---------- - node : :class:`~compas.datastructures.TreeNode` + node : :class:`compas.datastructures.TreeNode` The node to remove. Returns @@ -381,7 +383,7 @@ def traverse(self, strategy="depthfirst", order="preorder"): Yields ------ - :class:`~compas.datastructures.TreeNode` + :class:`compas.datastructures.TreeNode` The next node in the traversal. Raises @@ -406,7 +408,7 @@ def get_node_by_name(self, name): Returns ------- - :class:`~compas.datastructures.TreeNode` + :class:`compas.datastructures.TreeNode` The node. """ @@ -425,7 +427,7 @@ def get_nodes_by_name(self, name): Returns ------- - list[:class:`~compas.datastructures.TreeNode`] + list[:class:`compas.datastructures.TreeNode`] The nodes. """ @@ -438,12 +440,14 @@ def get_nodes_by_name(self, name): def __repr__(self): return "".format(len(list(self.nodes))) - def print(self): + def print_hierarchy(self): """Print the spatial hierarchy of the tree.""" - def _print(node, depth=0): - print(" " * depth + str(node)) - for child in node.children: - _print(child, depth + 1) + def _print(node, prefix="", last=True): + connector = "└── " if last else "├── " + print("{}{}{}".format(prefix, connector, node)) + prefix += " " if last else "│ " + for i, child in enumerate(node.children): + _print(child, prefix, i == len(node.children) - 1) _print(self.root) diff --git a/src/compas/datastructures/volmesh/bbox.py b/src/compas/datastructures/volmesh/bbox.py index 10d2a7eb212..e6bc5e6341b 100644 --- a/src/compas/datastructures/volmesh/bbox.py +++ b/src/compas/datastructures/volmesh/bbox.py @@ -16,7 +16,7 @@ def volmesh_bounding_box(volmesh): Parameters ---------- - volmesh : :class:`~compas.datastructures.VolMesh` + volmesh : :class:`compas.datastructures.VolMesh` The volmesh data structure. Returns diff --git a/src/compas/datastructures/volmesh/transformations.py b/src/compas/datastructures/volmesh/transformations.py index 001cfa967cf..aeea068b321 100644 --- a/src/compas/datastructures/volmesh/transformations.py +++ b/src/compas/datastructures/volmesh/transformations.py @@ -16,9 +16,9 @@ def volmesh_transform(volmesh, transformation): Parameters ---------- - volmesh : :class:`~compas.datastructures.VolMesh` + volmesh : :class:`compas.datastructures.VolMesh` The volmesh. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation. Returns @@ -50,14 +50,14 @@ def volmesh_transformed(volmesh, transformation): Parameters ---------- - volmesh : :class:`~compas.datastructures.VolMesh` + volmesh : :class:`compas.datastructures.VolMesh` The volmesh. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation. Returns ------- - :class:`~compas.datastructures.VolMesh` + :class:`compas.datastructures.VolMesh` A transformed independent copy of `volmesh`. Notes diff --git a/src/compas/datastructures/volmesh/volmesh.py b/src/compas/datastructures/volmesh/volmesh.py index 172170d0335..62e3fa13e0d 100644 --- a/src/compas/datastructures/volmesh/volmesh.py +++ b/src/compas/datastructures/volmesh/volmesh.py @@ -131,7 +131,7 @@ def from_meshgrid(cls, dx=10, dy=None, dz=None, nx=10, ny=None, nz=None): Returns ------- - :class:`~compas.datastructures.VolMesh` + :class:`compas.datastructures.VolMesh` See Also -------- @@ -184,7 +184,7 @@ def from_obj(cls, filepath, precision=None): Returns ------- - :class:`~compas.datastructures.VolMesh` + :class:`compas.datastructures.VolMesh` A volmesh object. See Also @@ -254,7 +254,7 @@ def from_vertices_and_cells(cls, vertices, cells): Returns ------- - :class:`~compas.datastructures.VolMesh` + :class:`compas.datastructures.VolMesh` A volmesh object. See Also @@ -305,7 +305,7 @@ def cell_to_mesh(self, cell): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` A mesh object. See Also diff --git a/src/compas/files/__init__.py b/src/compas/files/__init__.py index 6a64e60e6d3..a2dd5eca748 100644 --- a/src/compas/files/__init__.py +++ b/src/compas/files/__init__.py @@ -1,47 +1,29 @@ +""" +This package defines a number of file formats and provides functionality for reading and writing data in these formats. +""" + from __future__ import absolute_import from .gltf.gltf import GLTF -from .gltf.gltf_content import GLTFContent -from .gltf.gltf_exporter import GLTFExporter -from .gltf.gltf_mesh import GLTFMesh -from .gltf.gltf_parser import GLTFParser -from .gltf.gltf_reader import GLTFReader -from .obj import OBJ, OBJParser, OBJReader, OBJWriter -from .off import OFF, OFFReader, OFFWriter -from .ply import PLY, PLYParser, PLYReader, PLYWriter -from .stl import STL, STLParser, STLReader, STLWriter -from .urdf import URDF, URDFElement, URDFGenericElement, URDFParser -from .xml import XML, XMLElement, XMLReader, XMLWriter, prettify_string +from .gltf.gltf_content import GLTFContent # noqa: F401 +from .gltf.gltf_exporter import GLTFExporter # noqa: F401 +from .gltf.gltf_mesh import GLTFMesh # noqa: F401 +from .gltf.gltf_parser import GLTFParser # noqa: F401 +from .gltf.gltf_reader import GLTFReader # noqa: F401 +from .obj import OBJ, OBJParser, OBJReader, OBJWriter # noqa: F401 +from .off import OFF, OFFReader, OFFWriter # noqa: F401 +from .ply import PLY, PLYParser, PLYReader, PLYWriter # noqa: F401 +from .stl import STL, STLParser, STLReader, STLWriter # noqa: F401 +from .urdf import URDF, URDFElement, URDFGenericElement, URDFParser # noqa: F401 +from .xml import XML, XMLElement, XMLReader, XMLWriter, prettify_string # noqa: F401 __all__ = [ "GLTF", - "GLTFContent", - "GLTFMesh", - "GLTFReader", - "GLTFParser", - "GLTFExporter", "OBJ", - "OBJParser", - "OBJReader", - "OBJWriter", "OFF", - "OFFReader", - "OFFWriter", "PLY", - "PLYParser", - "PLYReader", - "PLYWriter", "STL", - "STLParser", - "STLReader", - "STLWriter", "URDF", - "URDFElement", - "URDFGenericElement", - "URDFParser", "XML", - "XMLElement", - "XMLReader", - "XMLWriter", "prettify_string", ] diff --git a/src/compas/files/gltf/gltf.py b/src/compas/files/gltf/gltf.py index 0557817c257..4caec55fbec 100644 --- a/src/compas/files/gltf/gltf.py +++ b/src/compas/files/gltf/gltf.py @@ -17,10 +17,10 @@ class GLTF(object): ---------- filepath : str Path to the location of the glTF file. - content : :class:`~compas.files.GLTFContent` - reader : :class:`~compas.files.GLTFReader` - parser : :class:`~compas.files.GLTFParser` - exporter : :class:`~compas.files.GLTFExporter` + content : :class:`compas.files.GLTFContent` + reader : :class:`compas.files.GLTFReader` + parser : :class:`compas.files.GLTFParser` + exporter : :class:`compas.files.GLTFExporter` References ---------- @@ -75,7 +75,7 @@ def exporter(self): return self._exporter def export(self, embed_data=False): - """Export the content of this :class:`~compas.files.GLTF` to the location + """Export the content of this :class:`compas.files.GLTF` to the location :attr:`compas.files.GLTF.filepath`, with file format determined by the given extension. Parameters diff --git a/src/compas/files/gltf/gltf_content.py b/src/compas/files/gltf/gltf_content.py index dafde42716d..5da98eeab19 100644 --- a/src/compas/files/gltf/gltf_content.py +++ b/src/compas/files/gltf/gltf_content.py @@ -18,27 +18,27 @@ class GLTFContent(object): Attributes ---------- scenes : dict - Dictionary containing (int, :class:`~compas.files.GLTFScene`) pairs. + Dictionary containing (int, :class:`compas.files.GLTFScene`) pairs. default_scene_key : int or None Key of the scene to be displayed on loading the glTF. nodes : dict - Dictionary containing (int, :class:`~compas.files.GLTFNode`) pairs. + Dictionary containing (int, :class:`compas.files.GLTFNode`) pairs. meshes : dict - Dictionary containing (int, :class:`~compas.files.GLTFMesh`) pairs. + Dictionary containing (int, :class:`compas.files.GLTFMesh`) pairs. cameras : dict - Dictionary containing (int, :class:`~compas.files.data_classes.CameraData`) pairs. + Dictionary containing (int, :class:`compas.files.data_classes.CameraData`) pairs. animations : dict - Dictionary containing (int, :class:`~compas.files.data_classes.AnimationData`) pairs. + Dictionary containing (int, :class:`compas.files.data_classes.AnimationData`) pairs. skins : dict - Dictionary containing (int, :class:`~compas.files.data_classes.SkinData`) pairs. + Dictionary containing (int, :class:`compas.files.data_classes.SkinData`) pairs. materials : dict - Dictionary containing (int, :class:`~compas.files.data_classes.MaterialData`) pairs. + Dictionary containing (int, :class:`compas.files.data_classes.MaterialData`) pairs. textures : dict - Dictionary containing (int, :class:`~compas.files.data_classes.TextureData`) pairs. + Dictionary containing (int, :class:`compas.files.data_classes.TextureData`) pairs. samplers : dict - Dictionary containing (int, :class:`~compas.files.data_classes.SamplerData`) pairs. + Dictionary containing (int, :class:`compas.files.data_classes.SamplerData`) pairs. images : dict - Dictionary containing (int, :class:`~compas.files.data_classes.ImageData`) pairs. + Dictionary containing (int, :class:`compas.files.data_classes.ImageData`) pairs. extras : object extensions : object @@ -213,7 +213,7 @@ def update_scene_transforms_and_positions(self, scene): Parameters ---------- - scene : :class:`~compas.files.GLTFScene` + scene : :class:`compas.files.GLTFScene` Returns ------- @@ -239,7 +239,7 @@ def get_node_faces(self, node): Parameters ---------- - node : :class:`~compas.files.GLTFNode` + node : :class:`compas.files.GLTFNode` Returns ------- @@ -255,7 +255,7 @@ def get_node_vertices(self, node): Parameters ---------- - node : :class:`~compas.files.GLTFNode` + node : :class:`compas.files.GLTFNode` Returns ------- @@ -367,22 +367,22 @@ def add_scene(self, name=None, extras=None): Returns ------- - :class:`~compas.files.GLTFScene` + :class:`compas.files.GLTFScene` """ return GLTFScene(self, name=name, extras=extras) def add_node_to_scene(self, scene, node_name=None, node_extras=None): - """Creates a :class:`~compas.files.GLTFNode` and adds this node to the children of ``scene``. + """Creates a :class:`compas.files.GLTFNode` and adds this node to the children of ``scene``. Parameters ---------- - scene : :class:`~compas.files.GLTFScene` + scene : :class:`compas.files.GLTFScene` node_name : str node_extras : object Returns ------- - :class:`~compas.files.GLTFNode` + :class:`compas.files.GLTFNode` """ if scene not in self.scenes.values(): raise Exception("Cannot find scene.") @@ -391,33 +391,33 @@ def add_node_to_scene(self, scene, node_name=None, node_extras=None): return node def add_child_to_node(self, parent_node, child_name=None, child_extras=None): - """Creates a :class:`~compas.files.GLTFNode` and adds this node to the children of ``parent_node``. + """Creates a :class:`compas.files.GLTFNode` and adds this node to the children of ``parent_node``. Parameters ---------- - parent_node : :class:`~compas.files.GLTFNode` + parent_node : :class:`compas.files.GLTFNode` child_name : str child_extras : object Returns ------- - :class:`~compas.files.GLTFNode` + :class:`compas.files.GLTFNode` """ child_node = GLTFNode(self, child_name, child_extras) parent_node.children.append(child_node.key) return child_node def add_mesh(self, mesh): - """Creates a :class:`~compas.files.GLTFMesh` object from a compas mesh, and adds this + """Creates a :class:`compas.files.GLTFMesh` object from a compas mesh, and adds this to the content. Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Returns ------- - :class:`~compas.files.GLTFMesh` + :class:`compas.files.GLTFMesh` """ return GLTFMesh.from_mesh(self, mesh) @@ -427,12 +427,12 @@ def add_mesh_to_node(self, node, mesh): Parameters ---------- - node : :class:`~compas.files.GLTFNode` - mesh : Union[:class:`~compas.datastructures.Mesh`, int] + node : :class:`compas.files.GLTFNode` + mesh : Union[:class:`compas.datastructures.Mesh`, int] Returns ------- - :class:`~compas.files.GLTFMesh` + :class:`compas.files.GLTFMesh` """ if isinstance(mesh, int): mesh_data = self.meshes[mesh] @@ -446,7 +446,7 @@ def get_nodes_from_scene(self, scene): Parameters ---------- - scene : :class:`~compas.files.GLTFScene` + scene : :class:`compas.files.GLTFScene` Returns ------- @@ -469,7 +469,7 @@ def get_scene_positions_and_edges(self, scene): Parameters ---------- - scene : :class:`~compas.files.GLTFScene` + scene : :class:`compas.files.GLTFScene` Returns ------- @@ -494,7 +494,6 @@ def visit(node, key): # ============================================================================== if __name__ == "__main__": - import os import urllib diff --git a/src/compas/files/gltf/gltf_exporter.py b/src/compas/files/gltf/gltf_exporter.py index 7a27a53aebb..24b847f4256 100644 --- a/src/compas/files/gltf/gltf_exporter.py +++ b/src/compas/files/gltf/gltf_exporter.py @@ -40,7 +40,7 @@ class GLTFExporter(object): Location where the glTF or glb is to be written. The extension of the filepath determines which format will be used. If there will be an accompanying binary file, it will be written in the same directory. - content : :class:`~compas.files.GLTFContent` + content : :class:`compas.files.GLTFContent` embed_data : bool When ``True``, all mesh and other data will be embedded as data uri's in the glTF json, with the exception of external image data. diff --git a/src/compas/files/gltf/gltf_mesh.py b/src/compas/files/gltf/gltf_mesh.py index 4736da08357..1ec4619b0f2 100644 --- a/src/compas/files/gltf/gltf_mesh.py +++ b/src/compas/files/gltf/gltf_mesh.py @@ -160,14 +160,14 @@ def validate_vertices(cls, vertices): @classmethod def from_vertices_and_faces(cls, context, vertices, faces, mesh_name=None, extras=None): - """Construct a :class:`~compas.files.GLTFMesh` object from lists of vertices and faces. + """Construct a :class:`compas.files.GLTFMesh` object from lists of vertices and faces. Vertices can be given as either a list of xyz-tuples or -lists, in which case the faces reference vertices by index, or vertices can be given as a dictionary of key-value pairs where the values are xyz-tuples or -lists and the faces reference the keys. Parameters ---------- - context : :class:`~compas.files.GLTFContent` + context : :class:`compas.files.GLTFContent` vertices : Union[list, dict] faces : list mesh_name : str @@ -175,7 +175,7 @@ def from_vertices_and_faces(cls, context, vertices, faces, mesh_name=None, extra Returns ------- - :class:`~compas.files.GLTFMesh` + :class:`compas.files.GLTFMesh` """ cls.validate_faces(faces) @@ -198,16 +198,16 @@ def from_vertices_and_faces(cls, context, vertices, faces, mesh_name=None, extra @classmethod def from_mesh(cls, context, mesh): - """Construct a :class:`~compas.files.GLTFMesh` object from a compas mesh. + """Construct a :class:`compas.files.GLTFMesh` object from a compas mesh. Parameters ---------- - context : :class:`~compas.files.GLTFContent` - mesh : :class:`~compas.datastructures.Mesh` + context : :class:`compas.files.GLTFContent` + mesh : :class:`compas.datastructures.Mesh` Returns ------- - :class:`~compas.files.GLTFMesh` + :class:`compas.files.GLTFMesh` """ vertices, faces = mesh.to_vertices_and_faces() texture_coordinates = mesh.vertices_attribute("texture_coordinate") @@ -248,18 +248,18 @@ def to_data(self, primitives): @classmethod def from_data(cls, mesh, context, primitive_data_list): - """Creates a :class:`~compas.files.GLTFMesh` from a glTF node dictionary + """Creates a :class:`compas.files.GLTFMesh` from a glTF node dictionary and inserts it in the provided context. Parameters ---------- mesh : dict - context : :class:`~compas.files.GLTFContent` + context : :class:`compas.files.GLTFContent` primitive_data_list : list Returns ------- - :class:`~compas.files.GLTFMesh` + :class:`compas.files.GLTFMesh` """ if mesh is None: return None diff --git a/src/compas/files/gltf/gltf_node.py b/src/compas/files/gltf/gltf_node.py index 44650a8e455..13698f63990 100644 --- a/src/compas/files/gltf/gltf_node.py +++ b/src/compas/files/gltf/gltf_node.py @@ -241,7 +241,7 @@ def get_matrix_from_trs(self): return matrix def add_child(self, child_name=None, child_extras=None): - """Creates a :class:`~compas.files.GLTFNode` with name `child_name` (default `None`) and extras `child_extras` + """Creates a :class:`compas.files.GLTFNode` with name `child_name` (default `None`) and extras `child_extras` (default `None`), and adds this node to the children of this node. Parameters @@ -251,7 +251,7 @@ def add_child(self, child_name=None, child_extras=None): Returns ------- - :class:`~compas.files.GLTFNode` + :class:`compas.files.GLTFNode` """ return self.context.add_child_to_node(self, child_name, child_extras) @@ -317,17 +317,17 @@ def to_data( @classmethod def from_data(cls, node, context): - """Creates a :class:`~compas.files.GLTFNode` from a glTF node dictionary + """Creates a :class:`compas.files.GLTFNode` from a glTF node dictionary and inserts it in the provided context. Parameters ---------- node : dict - context : :class:`~compas.files.GLTFContent` + context : :class:`compas.files.GLTFContent` Returns ------- - :class:`~compas.files.GLTFNode` + :class:`compas.files.GLTFNode` """ if node is None: return None diff --git a/src/compas/files/gltf/gltf_parser.py b/src/compas/files/gltf/gltf_parser.py index 98c82b95658..e1b7fcde995 100644 --- a/src/compas/files/gltf/gltf_parser.py +++ b/src/compas/files/gltf/gltf_parser.py @@ -22,12 +22,12 @@ class GLTFParser(object): Parameters ---------- - reader : :class:`~compas.files.GLTFReader` + reader : :class:`compas.files.GLTFReader` Attributes ---------- - reader : :class:`~compas.files.GLTFReader` - content : :class:`~compas.files.GLTFContent` + reader : :class:`compas.files.GLTFReader` + content : :class:`compas.files.GLTFContent` """ def __init__(self, reader): diff --git a/src/compas/files/gltf/gltf_scene.py b/src/compas/files/gltf/gltf_scene.py index 87cece4c486..215baed5476 100644 --- a/src/compas/files/gltf/gltf_scene.py +++ b/src/compas/files/gltf/gltf_scene.py @@ -65,7 +65,7 @@ def positions_and_edges(self): return self.context.get_scene_positions_and_edges(self) def add_child(self, node_name=None, node_extras=None): - """Creates a :class:`~compas.files.GLTFNode` and adds this node to the children of `scene`. + """Creates a :class:`compas.files.GLTFNode` and adds this node to the children of `scene`. Parameters ---------- @@ -74,7 +74,7 @@ def add_child(self, node_name=None, node_extras=None): Returns ------- - :class:`~compas.fikes.GLTFNode` + :class:`compas.fikes.GLTFNode` """ return self.context.add_node_to_scene(self, node_name, node_extras) @@ -102,17 +102,17 @@ def to_data(self, node_index_by_key): @classmethod def from_data(cls, scene, context): - """Creates a :class:`~compas.files.GLTFScene` from a glTF scene dictionary + """Creates a :class:`compas.files.GLTFScene` from a glTF scene dictionary and inserts it in the provided context. Parameters ---------- scene : dict - context : :class:`~compas.files.GLTFContent` + context : :class:`compas.files.GLTFContent` Returns ------- - :class:`~compas.files.GLTFScene` + :class:`compas.files.GLTFScene` """ if scene is None: return None diff --git a/src/compas/files/obj.py b/src/compas/files/obj.py index 37c3c93796f..c9dd273a1a1 100644 --- a/src/compas/files/obj.py +++ b/src/compas/files/obj.py @@ -120,7 +120,7 @@ def write(self, mesh, unweld=False, **kwargs): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. unweld : bool, optional Flag indicating that the vertices of the faces should be unwelded. @@ -556,7 +556,7 @@ class OBJWriter(object): ---------- filepath : path string | file-like object | URL string A path, a file-like object or a URL pointing to a file. - meshes : list[:class:`~compas.datastructures.Mesh`] + meshes : list[:class:`compas.datastructures.Mesh`] list of meshes to write to the file. precision : str, optional COMPAS precision specification for parsing geometric data. diff --git a/src/compas/files/off.py b/src/compas/files/off.py index b885a137d74..65a7e279010 100644 --- a/src/compas/files/off.py +++ b/src/compas/files/off.py @@ -59,7 +59,7 @@ def write(self, mesh, **kwargs): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. author : str, optional The author name to include in the header. @@ -234,7 +234,7 @@ class OFFWriter(object): ---------- filepath : path string | file-like object | URL string A path, a file-like object or a URL pointing to a file. - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Mesh to write to the file. author : str, optional The author name to include in the header. diff --git a/src/compas/files/ply.py b/src/compas/files/ply.py index e8b14ecefc1..cc6a155eaf2 100644 --- a/src/compas/files/ply.py +++ b/src/compas/files/ply.py @@ -72,7 +72,7 @@ def write(self, mesh, **kwargs): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. author : str, optional The author name to include in the header. @@ -628,7 +628,7 @@ class PLYWriter(object): ---------- filepath : path string | file-like object | URL string A path, a file-like object or a URL pointing to a file. - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Mesh to write to the file. author : str, optional The author name to include in the header. diff --git a/src/compas/files/stl.py b/src/compas/files/stl.py index f7f455cd56b..d9f3db52cf0 100644 --- a/src/compas/files/stl.py +++ b/src/compas/files/stl.py @@ -66,7 +66,7 @@ def write(self, mesh, **kwargs): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. binary : bool, optional Flag indicating that the file should be written in binary format. @@ -332,7 +332,7 @@ class STLWriter(object): ---------- filepath : path string | file-like object | URL string A path, a file-like object or a URL pointing to a file. - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh. binary : bool, optional Flag indicating that the file should be written in binary format. diff --git a/src/compas/files/urdf.py b/src/compas/files/urdf.py index ba7c87ace32..068bdd7546a 100644 --- a/src/compas/files/urdf.py +++ b/src/compas/files/urdf.py @@ -82,11 +82,11 @@ def from_robot(cls, robot): Parameters ---------- - robot : :class:`~compas.robots.RobotModel` + robot : :class:`compas.robots.RobotModel` Returns ------- - :class:`~compas.files.URDF` + :class:`compas.files.URDF` """ urdf = cls() @@ -104,7 +104,7 @@ def from_file(cls, source): Returns ------- - :class:`~compas.files.URDF` + :class:`compas.files.URDF` Examples -------- @@ -126,7 +126,7 @@ def from_string(cls, text): Returns ------- - :class:`~compas.files.URDF` + :class:`compas.files.URDF` Examples -------- @@ -242,7 +242,7 @@ def parse_element(cls, element, path="", element_default_namespace=None): Parameters ---------- - element : :class:`~compas.files.XMLElement` + element : :class:`compas.files.XMLElement` XML Element node. path : str, optional Full path to the element. diff --git a/src/compas/files/xml.py b/src/compas/files/xml.py index 30f6dae9cf1..aa8fc472be3 100644 --- a/src/compas/files/xml.py +++ b/src/compas/files/xml.py @@ -26,7 +26,7 @@ class XML(object): Attributes ---------- - reader : :class:`~compas.files.XMLReader`, read-only + reader : :class:`compas.files.XMLReader`, read-only Reader used to process the XML file or string. writer : :class:`XMLWriter`, read-only Writer used to process the XML object to a file or string. @@ -129,7 +129,7 @@ def from_file(cls, source): Returns ------- - :class:`~compas.files.XML` + :class:`compas.files.XML` """ xml = cls(source) @@ -147,7 +147,7 @@ def from_string(cls, text): Returns ------- - :class:`~compas.files.XML` + :class:`compas.files.XML` """ xml = cls() @@ -200,7 +200,7 @@ def from_file(cls, source, tree_parser=None): Returns ------- - :class:`~compas.files.XMLReader` + :class:`compas.files.XMLReader` """ return cls(xml_impl.xml_from_file(source, tree_parser)) @@ -218,7 +218,7 @@ def from_string(cls, text, tree_parser=None): Returns ------- - :class:`~compas.files.XMLReader` + :class:`compas.files.XMLReader` """ return cls(xml_impl.xml_from_string(text, tree_parser)) @@ -229,7 +229,7 @@ class XMLWriter(object): Parameters ---------- - xml : :class:`~compas.files.XML` + xml : :class:`compas.files.XML` The XML tree to write. """ @@ -284,7 +284,7 @@ class XMLElement(object): The type of XML tag. attributes : dict[str, Any], optional The attributes of the tag as name-value pairs. - elements : list[:class:`~compas.files.XMLElement`], optional + elements : list[:class:`compas.files.XMLElement`], optional A list of elements contained by the current element. text : str, optional The text contained by the element. diff --git a/src/compas/geometry/__init__.py b/src/compas/geometry/__init__.py index 383afdeec3d..bc984412eb5 100644 --- a/src/compas/geometry/__init__.py +++ b/src/compas/geometry/__init__.py @@ -1,3 +1,9 @@ +""" +This package defines all functionality for working with geometry in COMPAS. +It provides classes representing geometric primitives, transformations, (NURBS) curves and surfaces, +shapes, general polygons and polyhedrons, boundary representations (B-reps), and a number of geometry processing algorithms. +""" + from __future__ import absolute_import import compas @@ -5,23 +11,38 @@ # Core # ============================================================================= -from ._core._algebra import add_vectors, add_vectors_xy, allclose, argmax, argmin -from ._core._algebra import close, cross_vectors, cross_vectors_xy -from ._core._algebra import dehomogenize_vectors, divide_vectors, divide_vectors_xy, dot_vectors, dot_vectors_xy -from ._core._algebra import homogenize_vectors -from ._core._algebra import length_vector, length_vector_sqrd, length_vector_sqrd_xy, length_vector_xy -from ._core._algebra import multiply_matrices, multiply_matrix_vector, multiply_vectors, multiply_vectors_xy from ._core._algebra import ( + add_vectors, + add_vectors_xy, + allclose, + argmax, + argmin, + close, + cross_vectors, + cross_vectors_xy, + dehomogenize_vectors, + divide_vectors, + divide_vectors_xy, + dot_vectors, + dot_vectors_xy, + homogenize_vectors, + length_vector, + length_vector_sqrd, + length_vector_sqrd_xy, + length_vector_xy, + multiply_matrices, + multiply_matrix_vector, + multiply_vectors, + multiply_vectors_xy, norm_vector, norm_vectors, normalize_vector, normalize_vector_xy, normalize_vectors, normalize_vectors_xy, -) -from ._core._algebra import orthonormalize_vectors -from ._core._algebra import power_vector, power_vectors -from ._core._algebra import ( + orthonormalize_vectors, + power_vector, + power_vectors, scale_vector, scale_vector_xy, scale_vectors, @@ -31,9 +52,7 @@ subtract_vectors, subtract_vectors_xy, sum_vectors, -) -from ._core._algebra import transpose_matrix -from ._core._algebra import ( + transpose_matrix, vector_average, vector_component, vector_component_xy, @@ -104,7 +123,11 @@ sort_points, sort_points_xy, ) -from ._core.normals import normal_polygon, normal_triangle, normal_triangle_xy +from ._core.normals import ( + normal_polygon, + normal_triangle, + normal_triangle_xy, +) from ._core.quaternions import ( quaternion_canonize, quaternion_conjugate, @@ -113,11 +136,14 @@ quaternion_norm, quaternion_unitize, ) -from ._core.size import area_polygon, area_polygon_xy, area_triangle, area_triangle_xy, volume_polyhedron +from ._core.size import ( + area_polygon, + area_polygon_xy, + area_triangle, + area_triangle_xy, + volume_polyhedron, +) from ._core.tangent import tangent_points_to_circle_xy - -from ._core.kdtree import KDTree - from ._core.matrices import ( axis_and_angle_from_matrix, axis_angle_from_quaternion, @@ -153,51 +179,49 @@ quaternion_from_matrix, translation_from_matrix, ) - -from ._core.transformations import local_axes, local_to_world_coordinates from ._core.transformations import ( - # mirror_point_line, - # mirror_point_line_xy, + local_axes, + local_to_world_coordinates, mirror_point_plane, - # mirror_point_point, - # mirror_point_point_xy, mirror_points_line, mirror_points_line_xy, mirror_points_point, mirror_points_plane, mirror_points_point_xy, mirror_vector_vector, -) -from ._core.transformations import orient_points, orthonormalize_axes -from ._core.transformations import ( + orient_points, + orthonormalize_axes, project_point_line, project_point_line_xy, project_point_plane, project_points_line, project_points_line_xy, project_points_plane, -) -from ._core.transformations import reflect_line_plane, reflect_line_triangle, rotate_points, rotate_points_xy -from ._core.transformations import scale_points, scale_points_xy -from ._core.transformations import ( + reflect_line_plane, + reflect_line_triangle, + rotate_points, + rotate_points_xy, + scale_points, + scale_points_xy, transform_frames, transform_points, transform_vectors, translate_points_xy, translate_points, + world_to_local_coordinates, ) -from ._core.transformations import world_to_local_coordinates if not compas.IPY: - from ._core.transformations_numpy import dehomogenize_and_unflatten_frames_numpy, dehomogenize_numpy - from ._core.transformations_numpy import homogenize_and_flatten_frames_numpy, homogenize_numpy - from ._core.transformations_numpy import local_to_world_coordinates_numpy from ._core.transformations_numpy import ( - # transform_frames_numpy, + dehomogenize_and_unflatten_frames_numpy, + dehomogenize_numpy, + homogenize_and_flatten_frames_numpy, + homogenize_numpy, + local_to_world_coordinates_numpy, transform_points_numpy, transform_vectors_numpy, + world_to_local_coordinates_numpy, ) - from ._core.transformations_numpy import world_to_local_coordinates_numpy from ._core.predicates_2 import ( is_ccw_xy, @@ -211,8 +235,6 @@ is_point_in_convex_polygon_xy, is_point_in_circle_xy, is_polygon_in_polygon_xy, - is_intersection_line_line_xy, - is_intersection_segment_segment_xy, ) from ._core.predicates_3 import ( is_colinear, @@ -220,23 +242,15 @@ is_coplanar, is_parallel_line_line, is_polygon_convex, - is_point_in_box, is_point_on_plane, is_point_infront_plane, is_point_behind_plane, - is_point_in_halfspace, is_point_on_line, is_point_on_segment, is_point_on_polyline, is_point_in_triangle, is_point_in_circle, is_point_in_polyhedron, - is_intersection_line_line, - is_intersection_segment_segment, - is_intersection_line_triangle, - is_intersection_line_plane, - is_intersection_segment_plane, - is_intersection_plane_plane, ) from ._core.nurbs import ( @@ -252,8 +266,8 @@ # Algorithms # ============================================================================= -from .bbox.bbox import bounding_box, bounding_box_xy -from .bestfit.bestfit import bestfit_plane +from .bbox import bounding_box, bounding_box_xy +from .bestfit import bestfit_plane from .booleans import ( boolean_union_mesh_mesh, boolean_difference_mesh_mesh, @@ -263,12 +277,12 @@ boolean_symmetric_difference_polygon_polygon, boolean_intersection_polygon_polygon, ) -from .hull.hull import convex_hull, convex_hull_xy -from .interpolation.barycentric import barycentric_coordinates -from .interpolation.coons import discrete_coons_patch -from .interpolation.tweening import tween_points, tween_points_distance -from .intersections import intersection_mesh_mesh, intersection_ray_mesh -from .intersections.intersections import ( +from .hull import convex_hull, convex_hull_xy +from .interpolation_barycentric import barycentric_coordinates # move this to core +from .interpolation_coons import discrete_coons_patch +from .interpolation_tweening import tween_points, tween_points_distance +from .intersections import intersection_mesh_mesh, intersection_ray_mesh # move this into intersections.intersections +from .intersections.intersections import ( # move this to intersections.py intersection_circle_circle_xy, intersection_ellipse_line_xy, intersection_line_box_xy, @@ -291,36 +305,56 @@ intersection_sphere_line, intersection_sphere_sphere, ) -from .offset.offset import offset_line, offset_polyline, offset_polygon -from .quadmesh.planarization import quadmesh_planarize -from .triangulation import conforming_delaunay_triangulation, constrained_delaunay_triangulation, delaunay_triangulation -from .triangulation.delaunay import delaunay_from_points -from .triangulation.earclip import earclip_polygon -from .trimesh.curvature import trimesh_mean_curvature, trimesh_gaussian_curvature, trimesh_principal_curvature -from .trimesh.geodistance import trimesh_geodistance -from .trimesh.isolines import trimesh_isolines -from .trimesh.matrices import trimesh_massmatrix -from .trimesh.parametrisation import trimesh_harmonic, trimesh_lscm -from .trimesh.remesh import trimesh_remesh, trimesh_remesh_along_isoline, trimesh_remesh_constrained -from .trimesh.slicing import trimesh_slice +from .kdtree import KDTree +from .offset import ( + offset_line, + offset_polyline, + offset_polygon, +) +from .quadmesh_planarize import quadmesh_planarize +from .triangulation_delaunay import ( + conforming_delaunay_triangulation, + constrained_delaunay_triangulation, + delaunay_triangulation, +) +from .triangulation_delaunay_none import delaunay_from_points +from .triangulation_earclip import earclip_polygon +from .trimesh_curvature import ( + trimesh_mean_curvature, + trimesh_gaussian_curvature, + trimesh_principal_curvature, +) +from .trimesh_geodistance import trimesh_geodistance +from .trimesh_isolines import trimesh_isolines +from .trimesh_matrices import trimesh_massmatrix +from .trimesh_parametrisation import ( + trimesh_harmonic, + trimesh_lscm, +) +from .trimesh_remeshing import ( + trimesh_remesh, + trimesh_remesh_along_isoline, + trimesh_remesh_constrained, +) +from .trimesh_slicing import trimesh_slice if not compas.IPY: - from .bbox.bbox_numpy import ( + from .bbox_numpy import ( oriented_bounding_box_numpy, oriented_bounding_box_xy_numpy, ) - from .bestfit.bestfit_numpy import ( + from .bestfit_numpy import ( bestfit_line_numpy, bestfit_plane_numpy, bestfit_frame_numpy, bestfit_circle_numpy, bestfit_sphere_numpy, ) - from .hull.hull_numpy import convex_hull_numpy, convex_hull_xy_numpy - from .icp.icp_numpy import icp_numpy - from .triangulation.delaunay_numpy import delaunay_from_points_numpy, voronoi_from_points_numpy - from .trimesh.gradient_numpy import trimesh_gradient_numpy - from .trimesh.descent_numpy import trimesh_descent_numpy + from .hull_numpy import convex_hull_numpy, convex_hull_xy_numpy + from .icp_numpy import icp_numpy + from .triangulation_delaunay_numpy import delaunay_from_points_numpy, voronoi_from_points_numpy + from .trimesh_gradient_numpy import trimesh_gradient_numpy + from .trimesh_descent_numpy import trimesh_descent_numpy # ============================================================================= # Class APIs @@ -381,378 +415,367 @@ BrepTrimmingError, ) -from .brep.brep import Brep -from .brep.brep import BrepOrientation -from .brep.brep import BrepType +from .brep.brep import ( + Brep, + BrepOrientation, + BrepType, +) from .brep.edge import BrepEdge from .brep.loop import BrepLoop from .brep.face import BrepFace from .brep.vertex import BrepVertex -from .brep.trim import BrepTrim -from .brep.trim import BrepTrimIsoStatus +from .brep.trim import BrepTrim, BrepTrimIsoStatus __all__ = [ - "close", - "allclose", - "argmin", - "argmax", + "Arc", + "Bezier", + "Box", + "Brep", + "BrepEdge", + "BrepError", + "BrepFace", + "BrepInvalidError", + "BrepLoop", + "BrepOrientation", + "BrepTrim", + "BrepTrimIsoStatus", + "BrepTrimmingError", + "BrepType", + "BrepVertex", + "Capsule", + "Circle", + "Cone", + "ConicalSurface", + "Curve", + "Cylinder", + "CylindricalSurface", + "Ellipse", + "Frame", + "Geometry", + "Hyperbola", + "KDTree", + "Line", + "NurbsCurve", + "NurbsSurface", + "Parabola", + "PlanarSurface", + "Plane", + "Point", + "Pointcloud", + "Polygon", + "Polyhedron", + "Polyline", + "Projection", + "Quaternion", + "Reflection", + "Rotation", + "Scale", + "Shape", + "Shear", + "Sphere", + "SphericalSurface", + "Surface", + "ToroidalSurface", + "Torus", + "Transformation", + "Translation", + "Vector", "add_vectors", "add_vectors_xy", - "sum_vectors", - "cross_vectors", - "cross_vectors_xy", - "divide_vectors", - "divide_vectors_xy", - "dot_vectors", - "dot_vectors_xy", - "length_vector", - "length_vector_xy", - "length_vector_sqrd", - "length_vector_sqrd_xy", - "multiply_matrices", - "multiply_matrix_vector", - "multiply_vectors", - "multiply_vectors_xy", - "norm_vector", - "norm_vectors", - "normalize_vector", - "normalize_vector_xy", - "normalize_vectors", - "normalize_vectors_xy", - "homogenize_vectors", - "dehomogenize_vectors", - "orthonormalize_vectors", - "power_vector", - "power_vectors", - "scale_vector", - "scale_vector_xy", - "scale_vectors", - "scale_vectors_xy", - "square_vector", - "square_vectors", - "subtract_vectors", - "subtract_vectors_xy", - "transpose_matrix", - "vector_component", - "vector_component_xy", - "vector_average", - "vector_variance", - "vector_standard_deviation", - "circle_evaluate", - "ellipse_evaluate", - "archimedean_spiral_evaluate", - "logarithmic_spiral_evaluate", - "helix_evaluate", - "angles_vectors", - "angles_vectors_xy", - "angles_vectors", - "angles_vectors_xy", - "angles_points", - "angles_points_xy", + "allclose", + "angle_planes", + "angle_points", + "angle_points_xy", "angle_vectors", "angle_vectors_signed", "angle_vectors_xy", - "angle_points", - "angle_points_xy", - "angle_planes", - "midpoint_point_point", - "midpoint_point_point_xy", - "midpoint_line", - "midpoint_line_xy", + "angles_points", + "angles_points_xy", + "angles_vectors", + "angles_vectors_xy", + "archimedean_spiral_evaluate", + "area_polygon", + "area_polygon_xy", + "area_triangle", + "area_triangle_xy", + "argmax", + "argmin", + "axis_and_angle_from_matrix", + "axis_angle_from_quaternion", + "axis_angle_vector_from_matrix", + "barycentric_coordinates", + "basis_vectors_from_matrix", + "bestfit_plane", + "boolean_difference_mesh_mesh", + "boolean_difference_polygon_polygon", + "boolean_intersection_mesh_mesh", + "boolean_intersection_polygon_polygon", + "boolean_symmetric_difference_polygon_polygon", + "boolean_union_mesh_mesh", + "boolean_union_polygon_polygon", + "bounding_box", + "bounding_box_xy", "centroid_points", "centroid_points_weighted", "centroid_points_xy", "centroid_polygon", - "centroid_polygon_xy", - "centroid_polygon_vertices", - "centroid_polygon_vertices_xy", "centroid_polygon_edges", "centroid_polygon_edges_xy", + "centroid_polygon_vertices", + "centroid_polygon_vertices_xy", + "centroid_polygon_xy", "centroid_polyhedron", + "circle_evaluate", "circle_from_points", "circle_from_points_xy", - "distance_point_point", - "distance_point_point_xy", - "distance_point_point_sqrd", - "distance_point_point_sqrd_xy", - "distance_point_line", - "distance_point_line_xy", - "distance_point_line_sqrd", - "distance_point_line_sqrd_xy", - "distance_point_plane", - "distance_point_plane_signed", - "distance_line_line", + "close", + "closest_line_to_point", "closest_point_in_cloud", "closest_point_in_cloud_xy", "closest_point_on_line", "closest_point_on_line_xy", - "closest_point_on_segment", - "closest_point_on_segment_xy", - "closest_point_on_polyline", + "closest_point_on_plane", "closest_point_on_polygon_xy", + "closest_point_on_polyline", "closest_point_on_polyline_xy", - "closest_point_on_plane", - "closest_points_in_cloud_numpy", - "closest_line_to_point", - "sort_points", - "sort_points_xy", - "normal_polygon", - "normal_triangle", - "normal_triangle_xy", - "quaternion_norm", - "quaternion_unitize", - "quaternion_is_unit", - "quaternion_multiply", - "quaternion_canonize", - "quaternion_conjugate", - "area_polygon", - "area_polygon_xy", - "area_triangle", - "area_triangle_xy", - "volume_polyhedron", - "tangent_points_to_circle_xy", - "bounding_box", - "bounding_box_xy", - "bestfit_plane", - "boolean_union_mesh_mesh", - "boolean_difference_mesh_mesh", - "boolean_intersection_mesh_mesh", - "boolean_union_polygon_polygon", - "boolean_difference_polygon_polygon", - "boolean_symmetric_difference_polygon_polygon", - "boolean_intersection_polygon_polygon", + "closest_point_on_segment", + "closest_point_on_segment_xy", + "compose_matrix", + "compute_basisfuncs", + "compute_basisfuncsderivs", + "conforming_delaunay_triangulation", + "constrained_delaunay_triangulation", + "construct_knotvector", "convex_hull", "convex_hull_xy", - "barycentric_coordinates", + "cross_vectors", + "cross_vectors_xy", + "decompose_matrix", + "dehomogenize_vectors", + "delaunay_from_points", + "delaunay_from_points", + "delaunay_triangulation", "discrete_coons_patch", - "tween_points", - "tween_points_distance", - "intersection_circle_circle_xy", - "intersection_ellipse_line_xy", - "intersection_line_box_xy", - "intersection_line_line_xy", - "intersection_line_line", - "intersection_line_plane", - "intersection_line_segment_xy", - "intersection_line_segment", - "intersection_line_triangle", - "intersection_mesh_mesh", - "intersection_plane_circle", - "intersection_plane_plane_plane", - "intersection_plane_plane", - "intersection_polyline_box_xy", - "intersection_polyline_plane", - "intersection_ray_mesh", - "intersection_segment_plane", - "intersection_segment_polyline_xy", - "intersection_segment_polyline", - "intersection_segment_segment_xy", + "distance_line_line", + "distance_point_line", + "distance_point_line_sqrd", + "distance_point_line_sqrd_xy", + "distance_point_line_xy", + "distance_point_plane", + "distance_point_plane_signed", + "distance_point_point", + "distance_point_point_sqrd", + "distance_point_point_sqrd_xy", + "distance_point_point_xy", + "divide_vectors", + "divide_vectors_xy", + "dot_vectors", + "dot_vectors_xy", + "earclip_polygon", + "ellipse_evaluate", + "euler_angles_from_matrix", + "euler_angles_from_quaternion", + "find_span", + "helix_evaluate", + "homogenize_vectors", + "identity_matrix", + "intersection_circle_circle_xy", + "intersection_ellipse_line_xy", + "intersection_line_box_xy", + "intersection_line_line", + "intersection_line_line_xy", + "intersection_line_plane", + "intersection_line_segment", + "intersection_line_segment_xy", + "intersection_line_triangle", + "intersection_mesh_mesh", + "intersection_plane_circle", + "intersection_plane_plane", + "intersection_plane_plane_plane", + "intersection_polyline_box_xy", + "intersection_polyline_plane", + "intersection_ray_mesh", + "intersection_segment_plane", + "intersection_segment_polyline", + "intersection_segment_polyline_xy", "intersection_segment_segment", + "intersection_segment_segment_xy", "intersection_sphere_line", "intersection_sphere_sphere", - "offset_line", - "offset_polyline", - "offset_polygon", "is_ccw_xy", - "is_colinear_xy", - "is_polygon_convex_xy", - "is_point_on_line_xy", - "is_point_on_segment_xy", - "is_point_on_polyline_xy", - "is_point_in_triangle_xy", - "is_point_in_polygon_xy", - "is_point_in_convex_polygon_xy", - "is_point_in_circle_xy", - "is_polygon_in_polygon_xy", - "is_intersection_line_line_xy", - "is_intersection_segment_segment_xy", "is_colinear", "is_colinear_line_line", + "is_colinear_xy", "is_coplanar", + "is_matrix_square", "is_parallel_line_line", - "is_polygon_convex", - "is_point_on_plane", - "is_point_in_box", - "is_point_infront_plane", "is_point_behind_plane", - "is_point_in_halfspace", - "is_point_on_line", - "is_point_on_segment", - "is_point_on_polyline", - "is_point_in_triangle", "is_point_in_circle", + "is_point_in_circle_xy", + "is_point_in_convex_polygon_xy", + "is_point_in_polygon_xy", "is_point_in_polyhedron", - "is_intersection_line_line", - "is_intersection_segment_segment", - "is_intersection_line_triangle", - "is_intersection_line_plane", - "is_intersection_segment_plane", - "is_intersection_plane_plane", - "construct_knotvector", - "find_span", - "compute_basisfuncs", - "compute_basisfuncsderivs", + "is_point_in_triangle", + "is_point_in_triangle_xy", + "is_point_infront_plane", + "is_point_on_line", + "is_point_on_line_xy", + "is_point_on_plane", + "is_point_on_polyline", + "is_point_on_polyline_xy", + "is_point_on_segment", + "is_point_on_segment_xy", + "is_polygon_convex", + "is_polygon_convex_xy", + "is_polygon_in_polygon_xy", "knots_and_mults_to_knotvector", "knotvector_to_knots_and_mults", - "quadmesh_planarize", - "is_matrix_square", + "length_vector", + "length_vector_sqrd", + "length_vector_sqrd_xy", + "length_vector_xy", + "local_axes", + "local_to_world_coordinates", + "logarithmic_spiral_evaluate", "matrix_determinant", - "matrix_inverse", - "decompose_matrix", - "compose_matrix", - "identity_matrix", - "matrix_from_frame", - "matrix_from_frame_to_frame", - "matrix_from_change_of_basis", - "matrix_from_euler_angles", "matrix_from_axis_and_angle", "matrix_from_axis_angle_vector", "matrix_from_basis_vectors", - "matrix_from_translation", + "matrix_from_change_of_basis", + "matrix_from_euler_angles", + "matrix_from_frame", + "matrix_from_frame_to_frame", "matrix_from_orthogonal_projection", "matrix_from_parallel_projection", - "matrix_from_perspective_projection", "matrix_from_perspective_entries", - "matrix_from_shear_entries", - "matrix_from_shear", - "matrix_from_scale_factors", + "matrix_from_perspective_projection", "matrix_from_quaternion", + "matrix_from_scale_factors", + "matrix_from_shear", + "matrix_from_shear_entries", + "matrix_from_translation", + "matrix_inverse", "matrix_minor", - "euler_angles_from_matrix", - "euler_angles_from_quaternion", - "axis_and_angle_from_matrix", - "axis_angle_vector_from_matrix", - "axis_angle_from_quaternion", - "quaternion_from_matrix", - "quaternion_from_euler_angles", - "quaternion_from_axis_angle", - "basis_vectors_from_matrix", - "translation_from_matrix", - "local_axes", - "orthonormalize_axes", - "transform_points", - "transform_vectors", - "transform_frames", - "local_to_world_coordinates", - "world_to_local_coordinates", - "translate_points", - "translate_points_xy", - "scale_points", - "scale_points_xy", - "rotate_points", - "rotate_points_xy", - "mirror_vector_vector", - "mirror_points_point", - "mirror_points_point_xy", + "midpoint_line", + "midpoint_line_xy", + "midpoint_point_point", + "midpoint_point_point_xy", + "mirror_point_plane", "mirror_points_line", "mirror_points_line_xy", - "mirror_point_plane", "mirror_points_plane", - "project_point_plane", - "project_points_plane", + "mirror_points_point", + "mirror_points_point_xy", + "mirror_vector_vector", + "multiply_matrices", + "multiply_matrix_vector", + "multiply_vectors", + "multiply_vectors_xy", + "norm_vector", + "norm_vectors", + "normal_polygon", + "normal_triangle", + "normal_triangle_xy", + "normalize_vector", + "normalize_vector_xy", + "normalize_vectors", + "normalize_vectors_xy", + "offset_line", + "offset_polygon", + "offset_polyline", + "orient_points", + "orthonormalize_axes", + "orthonormalize_vectors", + "power_vector", + "power_vectors", "project_point_line", "project_point_line_xy", + "project_point_plane", "project_points_line", "project_points_line_xy", + "project_points_plane", + "quadmesh_planarize", + "quaternion_canonize", + "quaternion_conjugate", + "quaternion_from_axis_angle", + "quaternion_from_euler_angles", + "quaternion_from_matrix", + "quaternion_is_unit", + "quaternion_multiply", + "quaternion_norm", + "quaternion_unitize", "reflect_line_plane", "reflect_line_triangle", - "orient_points", - "conforming_delaunay_triangulation", - "constrained_delaunay_triangulation", - "delaunay_from_points", - "delaunay_from_points", - "delaunay_triangulation", - "earclip_polygon", + "rotate_points", + "rotate_points_xy", + "scale_points", + "scale_points_xy", + "scale_vector", + "scale_vector_xy", + "scale_vectors", + "scale_vectors_xy", + "sort_points", + "sort_points_xy", + "square_vector", + "square_vectors", + "subtract_vectors", + "subtract_vectors_xy", + "sum_vectors", + "tangent_points_to_circle_xy", + "transform_frames", + "transform_points", + "transform_vectors", + "translate_points", + "translate_points_xy", + "translation_from_matrix", + "transpose_matrix", "trimesh_gaussian_curvature", - "trimesh_mean_curvature", - "trimesh_principal_curvature", "trimesh_geodistance", - "trimesh_isolines", - "trimesh_massmatrix", "trimesh_harmonic", + "trimesh_isolines", "trimesh_lscm", + "trimesh_massmatrix", + "trimesh_mean_curvature", + "trimesh_principal_curvature", "trimesh_remesh", - "trimesh_remesh_constrained", "trimesh_remesh_along_isoline", + "trimesh_remesh_constrained", "trimesh_slice", - "Geometry", - "Bezier", - "Arc", - "Circle", - "Ellipse", - "Hyperbola", - "Parabola", - "Frame", - "Line", - "Plane", - "Point", - "Polygon", - "Polyline", - "Quaternion", - "Vector", - "Shape", - "Box", - "Capsule", - "Cone", - "Cylinder", - "Polyhedron", - "Sphere", - "Torus", - "Pointcloud", - "KDTree", - "Projection", - "Reflection", - "Rotation", - "Scale", - "Shear", - "Transformation", - "Translation", - "Curve", - "NurbsCurve", - "Surface", - "SphericalSurface", - "CylindricalSurface", - "ToroidalSurface", - "ConicalSurface", - "PlanarSurface", - "NurbsSurface", - "Brep", - "BrepLoop", - "BrepEdge", - "BrepVertex", - "BrepFace", - "BrepTrim", - "BrepTrimIsoStatus", - "BrepType", - "BrepOrientation", - "BrepError", - "BrepInvalidError", - "BrepTrimmingError", + "tween_points", + "tween_points_distance", + "vector_average", + "vector_component", + "vector_component_xy", + "vector_standard_deviation", + "vector_variance", + "volume_polyhedron", + "world_to_local_coordinates", ] if not compas.IPY: __all__ += [ - "oriented_bounding_box_numpy", - "oriented_bounding_box_xy_numpy", + "bestfit_circle_numpy", + "bestfit_frame_numpy", "bestfit_line_numpy", "bestfit_plane_numpy", - "bestfit_frame_numpy", - "bestfit_circle_numpy", "bestfit_sphere_numpy", + "closest_points_in_cloud_numpy", "convex_hull_numpy", "convex_hull_xy_numpy", - "icp_numpy", - "transform_points_numpy", - "transform_vectors_numpy", - "homogenize_numpy", + "dehomogenize_and_unflatten_frames_numpy", "dehomogenize_numpy", + "delaunay_from_points_numpy", "homogenize_and_flatten_frames_numpy", - "dehomogenize_and_unflatten_frames_numpy", - "world_to_local_coordinates_numpy", + "homogenize_numpy", + "icp_numpy", "local_to_world_coordinates_numpy", - "delaunay_from_points_numpy", - "voronoi_from_points_numpy", + "oriented_bounding_box_numpy", + "oriented_bounding_box_xy_numpy", + "transform_points_numpy", + "transform_vectors_numpy", "trimesh_descent_numpy", "trimesh_gradient_numpy", + "voronoi_from_points_numpy", + "world_to_local_coordinates_numpy", ] diff --git a/src/compas/geometry/_core/_algebra.py b/src/compas/geometry/_core/_algebra.py index 5e90e4548b4..4518aa6813b 100644 --- a/src/compas/geometry/_core/_algebra.py +++ b/src/compas/geometry/_core/_algebra.py @@ -11,7 +11,7 @@ def vector_average(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` List of values. Returns @@ -27,7 +27,7 @@ def vector_variance(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` List of values. Returns @@ -44,7 +44,7 @@ def vector_standard_deviation(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` List of values. Returns @@ -193,7 +193,7 @@ def sum_vectors(vectors, axis=0): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. axis : int, optional If ``axis == 0``, the sum is taken per column. @@ -224,7 +224,7 @@ def norm_vector(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. Returns @@ -250,7 +250,7 @@ def norm_vectors(vectors): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors Returns @@ -272,7 +272,7 @@ def length_vector(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. Returns @@ -297,7 +297,7 @@ def length_vector_xy(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` XY(Z) components of the vector. Returns @@ -325,7 +325,7 @@ def length_vector_sqrd(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. Returns @@ -347,7 +347,7 @@ def length_vector_sqrd_xy(vector): Parameters ---------- - vector : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) components of the vector. Returns @@ -383,7 +383,7 @@ def scale_vector(vector, factor): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. factor : float The scaling factor. @@ -411,7 +411,7 @@ def scale_vector_xy(vector, factor): Parameters ---------- - vector : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) components of the vector. scale : float Scale factor. @@ -435,7 +435,7 @@ def scale_vectors(vectors, factor): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. factor : float The scaling factor. @@ -458,7 +458,7 @@ def scale_vectors_xy(vectors, factor): Parameters ---------- - vectors : sequence[[float, float] or [float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. factor : float The scaling factor. @@ -481,7 +481,7 @@ def normalize_vector(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. Returns @@ -505,7 +505,7 @@ def normalize_vector_xy(vector): Parameters ---------- - vector : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) components of the vector. Returns @@ -529,7 +529,7 @@ def normalize_vectors(vectors): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns @@ -550,7 +550,7 @@ def normalize_vectors_xy(vectors): Parameters ---------- - vectors : sequence[[float, float] or [float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns @@ -571,7 +571,7 @@ def power_vector(vector, power): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. power : int, float The power to which to raise the vector. @@ -594,7 +594,7 @@ def power_vectors(vectors, power): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. power : int, float The power to which to raise the vectors. @@ -617,7 +617,7 @@ def square_vector(vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. Returns @@ -638,7 +638,7 @@ def square_vectors(vectors): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns @@ -666,9 +666,9 @@ def add_vectors(u, v): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the second vector. Returns @@ -685,9 +685,9 @@ def add_vectors_xy(u, v): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) components of the first vector. - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) components of the second vector. Returns @@ -708,9 +708,9 @@ def subtract_vectors(u, v): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the second vector. Returns @@ -731,9 +731,9 @@ def subtract_vectors_xy(u, v): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` The XY(Z) components of the first vector. - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` The XY(Z) components of the second vector. Returns @@ -754,9 +754,9 @@ def multiply_vectors(u, v): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` The XYZ components of the first vector. - v : l[float, float, float] | :class:`~compas.geometry.Vector` + v : l[float, float, float] | :class:`compas.geometry.Vector` The XYZ components of the second vector. Returns @@ -777,9 +777,9 @@ def multiply_vectors_xy(u, v): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` The XY(Z) components of the first vector. - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` The XY(Z) components of the second vector. Returns @@ -800,9 +800,9 @@ def divide_vectors(u, v): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` The XYZ components of the first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` The XYZ components of the second vector. Returns @@ -823,9 +823,9 @@ def divide_vectors_xy(u, v): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` The XY(Z) components of the first vector. - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` The XY(Z) components of the second vector. Returns @@ -851,9 +851,9 @@ def cross_vectors(u, v): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the second vector. Returns @@ -908,9 +908,9 @@ def cross_vectors_xy(u, v): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) coordinates of the first vector. - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) coordinates of the second vector. Returns @@ -939,9 +939,9 @@ def dot_vectors(u, v): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the second vector. Returns @@ -963,9 +963,9 @@ def dot_vectors_xy(u, v): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) coordinates of the first vector. - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) coordinates of the second vector. Returns @@ -993,9 +993,9 @@ def vector_component(u, v): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the direction. Returns @@ -1032,9 +1032,9 @@ def vector_component_xy(u, v): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the vector. - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the direction. Returns @@ -1077,7 +1077,7 @@ def transpose_matrix(M): Parameters ---------- - M : list[list[float]] | :class:`~compas.geometry.Transformation` + M : list[list[float]] | :class:`compas.geometry.Transformation` The matrix to be transposed. Returns @@ -1094,9 +1094,9 @@ def multiply_matrices(A, B): Parameters ---------- - A : list[list[float]] | :class:`~compas.geometry.Transformation` + A : list[list[float]] | :class:`compas.geometry.Transformation` The first matrix. - B : list[list[float]] | :class:`~compas.geometry.Transformation` + B : list[list[float]] | :class:`compas.geometry.Transformation` The second matrix. Returns @@ -1145,9 +1145,9 @@ def multiply_matrix_vector(A, b): Parameters ---------- - A : list[list[float]] | :class:`~compas.geometry.Transformation` + A : list[list[float]] | :class:`compas.geometry.Transformation` The matrix. - b : [float, float, float] | :class:`~compas.geometry.Vector` + b : [float, float, float] | :class:`compas.geometry.Vector` The vector. Returns @@ -1195,7 +1195,7 @@ def homogenize_vectors(vectors, w=1.0): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. w : float, optional Homogenisation parameter. @@ -1226,7 +1226,7 @@ def dehomogenize_vectors(vectors): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns @@ -1247,7 +1247,7 @@ def orthonormalize_vectors(vectors): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] The set of vectors to othonormalize. Returns diff --git a/src/compas/geometry/_core/angles.py b/src/compas/geometry/_core/angles.py index 1ecfb85c278..55704a95576 100644 --- a/src/compas/geometry/_core/angles.py +++ b/src/compas/geometry/_core/angles.py @@ -5,7 +5,6 @@ from math import pi from math import degrees from math import acos - from ._algebra import subtract_vectors from ._algebra import subtract_vectors_xy from ._algebra import dot_vectors @@ -20,9 +19,9 @@ def angle_vectors(u, v, deg=False, tol=0.0): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the second vector. deg : bool, optional If True, returns the angle in degrees. @@ -46,10 +45,30 @@ def angle_vectors(u, v, deg=False, tol=0.0): return 0 a = dot_vectors(u, v) / L a = max(min(a, 1), -1) + angle = acos(a) + + # a = length_vector(u) + # b = length_vector(v) + # if a < tol or b < tol: + # return 0 + # c = length_vector(subtract_vectors(u, v)) + # if c < tol: + # return 0 + # if b >= c and c >= 0: + # mu = c - (a - b) + # elif c > b and b >= 0: + # mu = b - (a - c) + # else: + # raise Exception("Invalid input vectors.") + # angle = 2 * atan(sqrt(((a - b) + c) * mu / ((a + (b + c)) * ((a - c) + b)))) + + # a = normalize_vector(u) + # b = normalize_vector(v) + # angle = 2 * atan2(length_vector(subtract_vectors(a, b)), length_vector(add_vectors(a, b))) if deg: - return degrees(acos(a)) - return acos(a) + return degrees(angle) + return angle def angle_vectors_signed(u, v, normal, deg=False, threshold=1e-3): @@ -60,11 +79,11 @@ def angle_vectors_signed(u, v, normal, deg=False, threshold=1e-3): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the second vector. - normal : [float, float, float] | :class:`~compas.geometry.Vector` + normal : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the plane's normal spanned by u and v. deg : bool, optional If True, returns the angle in degrees. @@ -102,9 +121,9 @@ def angle_vectors_xy(u, v, deg=False, tol=1e-4): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` The first 2D or 3D vector (Z will be ignored). - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` The second 2D or 3D vector (Z will be ignored). deg : bool, optional If True, returns the angle in degrees. @@ -137,11 +156,11 @@ def angle_points(a, b, c, deg=False): Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. - c : [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. deg : bool, optional If True, returns the angle in degrees. @@ -174,11 +193,11 @@ def angle_points_xy(a, b, c, deg=False): Parameters ---------- - a : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). - b : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). - c : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). deg : bool, optional If True, returns the angle in degrees. @@ -211,9 +230,9 @@ def angles_vectors(u, v, deg=False): Parameters ---------- - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` XYZ components of the second vector. deg : bool, optional If True, returns the angle in degrees. @@ -242,9 +261,9 @@ def angles_vectors_xy(u, v, deg=False): Parameters ---------- - u : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) coordinates of the first vector. - v : [float, float] or [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector` XY(Z) coordinates of the second vector. deg : bool, optional If True, returns the angle in degrees. @@ -277,11 +296,11 @@ def angles_points(a, b, c, deg=False): Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. - c : [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. deg : bool, optional If True, returns the angle in degrees. @@ -317,11 +336,11 @@ def angles_points_xy(a, b, c, deg=False): Parameters ---------- - a : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates. - b : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates. - c : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates. deg : bool, optional If True, returns the angle in degrees. @@ -359,9 +378,9 @@ def angle_planes(a, b, deg=False): Parameters ---------- - a : [point, vector] | :class:`~compas.geometry.Plane` + a : [point, vector] | :class:`compas.geometry.Plane` The first plane. - b : [point, vector] | :class:`~compas.geometry.Plane` + b : [point, vector] | :class:`compas.geometry.Plane` The second plane. deg : bool, optional If True, returns the angle in degrees. diff --git a/src/compas/geometry/_core/centroids.py b/src/compas/geometry/_core/centroids.py index 63777dc524f..842f627ba09 100644 --- a/src/compas/geometry/_core/centroids.py +++ b/src/compas/geometry/_core/centroids.py @@ -23,9 +23,9 @@ def midpoint_point_point(a, b): Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the first point. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the second point. Returns @@ -42,9 +42,9 @@ def midpoint_point_point_xy(a, b): Parameters ---------- - a : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the first 2D or 3D point (Z will be ignored). - b : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the second 2D or 3D point (Z will be ignored). Returns @@ -60,7 +60,7 @@ def midpoint_line(line): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` XYZ coordinates of the first point, and XYZ coordinates of the second point. Returns @@ -81,7 +81,7 @@ def midpoint_line_xy(line): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` XYZ coordinates of the first point, and XYZ coordinates of the second point. Returns @@ -102,7 +102,7 @@ def centroid_points(points): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A sequence of XYZ coordinates. Returns @@ -131,7 +131,7 @@ def centroid_points_weighted(points, weights): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of point coordinates. weights : sequence[float] A list of weight floats. @@ -151,7 +151,7 @@ def centroid_points_xy(points): Parameters ---------- - points : sequence[[float, float] or [float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Point`] A sequence of points represented by their XY(Z) coordinates. Returns @@ -180,7 +180,7 @@ def centroid_polygon(polygon): Parameters ---------- - polygon : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + polygon : sequence[[float, float, float] | :class:`compas.geometry.Point`] A sequence of polygon point coordinates. Returns @@ -188,6 +188,21 @@ def centroid_polygon(polygon): [float, float, float] The XYZ coordinates of the centroid. + Raises + ------ + ValueError + If the polygon has less than three points. + + Warnings + -------- + The polygon need not be convex. + + The polygon need not be flat. However, it is unclear what the meaning of the + centroid is in that case. + + The polygon may be self-intersecting. However, it is unclear what the meaning + of the centroid is in that case. + Notes ----- The centroid is the centre of gravity of the polygon surface if mass would be @@ -204,25 +219,17 @@ def centroid_polygon(polygon): c_y = \frac{1}{A} \sum_{i=1}^{N} A_i \cdot c_{y,i} c_z = \frac{1}{A} \sum_{i=1}^{N} A_i \cdot c_{z,i} - Warnings - -------- - The polygon need not be convex. - - The polygon need not be flat. However, it is unclear what the meaning of the - centroid is in that case. - - The polygon may be self-intersecting. However, it is unclear what the meaning - of the centroid is in that case. - Examples -------- >>> polygon = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]] >>> centroid_polygon(polygon) [0.5, 0.5, 0.0] + """ p = len(polygon) - assert p > 2, "At least three points required" + if p < 3: + raise ValueError("At least three points required.") if p == 3: return centroid_points(polygon) @@ -273,7 +280,7 @@ def centroid_polygon_xy(polygon): Parameters ---------- - polygon : sequence[[float, float] or [float, float, float] | :class:`~compas.geometry.Point`] + polygon : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Point`] A sequence of polygon point XY(Z) coordinates. The Z coordinates are ignored. @@ -282,6 +289,18 @@ def centroid_polygon_xy(polygon): [float, float, 0.0] The XYZ coordinates of the centroid in the XY plane. + Raises + ------ + ValueError + If the polygon has less than three points. + + Warnings + -------- + The polygon need not be convex. + + The polygon may be self-intersecting. However, it is unclear what the meaning + of the centroid is in that case. + Notes ----- The centroid is the centre of gravity of the polygon surface if mass would be @@ -298,22 +317,17 @@ def centroid_polygon_xy(polygon): c_y = \frac{1}{A} \sum_{i=1}^{N} A_i \cdot c_{y,i} c_z = 0 - Warnings - -------- - The polygon need not be convex. - - The polygon may be self-intersecting. However, it is unclear what the meaning - of the centroid is in that case. - Examples -------- >>> polygon = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]] >>> centroid_polygon_xy(polygon) [0.5, 0.5, 0.0] + """ p = len(polygon) - assert p > 2, "At least three points required" + if p < 3: + raise ValueError("At least three points required") if p == 3: return centroid_points_xy(polygon) @@ -359,13 +373,14 @@ def centroid_polygon_vertices(polygon): Parameters ---------- - polygon : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + polygon : sequence[[float, float, float] | :class:`compas.geometry.Point`] A sequence of polygon point coordinates. Returns ------- [float, float, float] The XYZ coordinates of the centroid. + """ return centroid_points(polygon) @@ -375,7 +390,7 @@ def centroid_polygon_vertices_xy(polygon): Parameters ---------- - polygon : sequence[[float, float] or [float, float, float] | :class:`~compas.geometry.Point`] + polygon : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Point`] A sequence of polygon point coordinates. The Z coordinates will be ignored. @@ -393,7 +408,7 @@ def centroid_polygon_edges(polygon): Parameters ---------- - polygon : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + polygon : sequence[[float, float, float] | :class:`compas.geometry.Point`] A sequence of polygon point coordinates. Returns @@ -428,7 +443,7 @@ def centroid_polygon_edges_xy(polygon): Parameters ---------- - polygon : sequence[[float, float] or [float, float, float] | :class:`~compas.geometry.Point`] + polygon : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Point`] A sequence of polygon point coordinates. The Z coordinates will be ignored. @@ -462,7 +477,7 @@ def centroid_polyhedron(polyhedron): Parameters ---------- - polyhedron : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[sequence[int]]] + polyhedron : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[sequence[int]]] The coordinates of the vertices, and the indices of the vertices forming the faces. diff --git a/src/compas/geometry/_core/constructors.py b/src/compas/geometry/_core/constructors.py index 5a31dadb826..419ee869d15 100644 --- a/src/compas/geometry/_core/constructors.py +++ b/src/compas/geometry/_core/constructors.py @@ -19,11 +19,11 @@ def circle_from_points(a, b, c): Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. - c : [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. Returns @@ -69,11 +69,11 @@ def circle_from_points_xy(a, b, c): Parameters ---------- - a : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). - b : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). - c : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). Returns diff --git a/src/compas/geometry/_core/distance.py b/src/compas/geometry/_core/distance.py index decbbe7636e..b9b8a732903 100644 --- a/src/compas/geometry/_core/distance.py +++ b/src/compas/geometry/_core/distance.py @@ -29,9 +29,9 @@ def distance_point_point(a, b): Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of point a. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of point b. Returns @@ -58,9 +58,9 @@ def distance_point_point_xy(a, b): Parameters ---------- - a : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). - b : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). Returns @@ -89,9 +89,9 @@ def distance_point_point_sqrd(a, b): Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of point a. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of point b. Returns @@ -118,9 +118,9 @@ def distance_point_point_sqrd_xy(a, b): Parameters ---------- - a : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the first point. - b : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the second point. Returns @@ -149,9 +149,9 @@ def distance_point_line(point, line): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` Point location. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Line defined by two points. Returns @@ -189,9 +189,9 @@ def distance_point_line_xy(point, line): Parameters ---------- - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the point. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Line defined by two points. Returns @@ -225,9 +225,9 @@ def distance_point_line_sqrd(point, line): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the point. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Line defined by two points. Returns @@ -259,9 +259,9 @@ def distance_point_line_sqrd_xy(point, line): Parameters ---------- - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Line defined by two points. Returns @@ -295,9 +295,9 @@ def distance_point_plane(point, plane): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` Point coordinates. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` A point and a vector defining a plane. Returns @@ -350,9 +350,9 @@ def distance_point_plane_signed(point, plane): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` Point coordinates. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` A point and a vector defining a plane. Returns @@ -407,9 +407,9 @@ def distance_line_line(l1, l2, tol=0.0): Parameters ---------- - l1 : [point, point] | :class:`~compas.geometry.Line` + l1 : [point, point] | :class:`compas.geometry.Line` Two points defining a line. - l2 : [point, point] | :class:`~compas.geometry.Line` + l2 : [point, point] | :class:`compas.geometry.Line` Two points defining a line. Returns @@ -461,9 +461,9 @@ def sort_points(point, cloud): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The XYZ coordinates of the base point. - cloud : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + cloud : sequence[[float, float, float] | :class:`compas.geometry.Point`] A sequence locations in three-dimensional space. Returns @@ -492,9 +492,9 @@ def sort_points_xy(point, cloud): Parameters ---------- - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point. - cloud : sequence[[float, float] or [float, float, float] | :class:`~compas.geometry.Point`] + cloud : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Point`] A list of points represented by their XY(Z) coordinates. Returns @@ -522,9 +522,9 @@ def closest_point_in_cloud(point, cloud): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the base point. - cloud : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + cloud : sequence[[float, float, float] | :class:`compas.geometry.Point`] A sequence locations in three-dimensional space. Returns @@ -610,9 +610,9 @@ def closest_point_in_cloud_xy(point, cloud): Parameters ---------- - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a the base point. - cloud : sequence[[float, float] or [float, float, float] | :class:`~compas.geometry.Point`] + cloud : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Point`] A list of points forming the cloud, with each point represented by its XY(Z) coordinates. Returns @@ -639,9 +639,9 @@ def closest_point_on_line(point, line): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the line. Returns @@ -670,9 +670,9 @@ def closest_point_on_line_xy(point, line): Parameters ---------- - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two XY(Z) points defining a line. Returns @@ -693,9 +693,9 @@ def closest_point_on_segment(point, segment): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates. - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` Two points defining the segment. Returns @@ -725,9 +725,9 @@ def closest_point_on_segment_xy(point, segment): Parameters ---------- - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point. - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` Two 2D or 3D points defining the line segment (Z components will be ignored). Returns @@ -753,9 +753,9 @@ def closest_point_on_polyline(point, polyline): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of a 2D or 3D point (Z will be ignored). - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` A sequence of XYZ coordinates representing the locations of the corners of a polyline. The vertices are assumed to be in order. @@ -779,9 +779,9 @@ def closest_point_on_polyline_xy(point, polyline): Parameters ---------- - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` A sequence of XY(Z) coordinates of 2D or 3D points (Z will be ignored) representing the locations of the corners of a polyline. The vertices are assumed to be in order. @@ -805,9 +805,9 @@ def closest_point_on_polygon_xy(point, polygon): Parameters ---------- - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a 2D or 3D point (Z will be ignored). - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` A sequence of XY(Z) coordinates of 2D or 3D points (Z will be ignored) representing the locations of the corners of a polygon. The vertices are assumed to be in order. The polygon is assumed to be closed: @@ -832,9 +832,9 @@ def closest_point_on_plane(point, plane): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of point. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` The base point and normal defining the plane. Returns @@ -873,9 +873,9 @@ def closest_line_to_point(point, lines): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of point. - lines : sequence[[point, point] | :class:`~compas.geometry.Line`]. + lines : sequence[[point, point] | :class:`compas.geometry.Line`]. The lines to be checked for distance. Returns diff --git a/src/compas/geometry/_core/matrices.py b/src/compas/geometry/_core/matrices.py index 6f23a3228ae..0a9a27921fb 100644 --- a/src/compas/geometry/_core/matrices.py +++ b/src/compas/geometry/_core/matrices.py @@ -67,6 +67,10 @@ def is_matrix_square(M): True if the length of every row is equal to the number of rows. False otherwise. + See Also + -------- + is_matrix_symmetric + Examples -------- >>> M = identity_matrix(4) @@ -98,6 +102,11 @@ def matrix_minor(M, i, j): list[list[float]] The minor. + See Also + -------- + matrix_determinant + matrix_inverse + """ return [row[:j] + row[j + 1 :] for row in (M[:i] + M[i + 1 :])] @@ -122,6 +131,11 @@ def matrix_determinant(M, check=True): float The determinant. + See Also + -------- + matrix_minor + matrix_inverse + Examples -------- >>> M = identity_matrix(4) @@ -166,6 +180,11 @@ def matrix_inverse(M): ValueError If the matrix is not invertible. + See Also + -------- + matrix_minor + matrix_determinant + Examples -------- >>> from compas.geometry import Frame @@ -234,6 +253,10 @@ def decompose_matrix(M): perspective : [float, float, float, float] The 4 perspective entries of the matrix. + See Also + -------- + compose_matrix + Examples -------- >>> trans1 = [1, 2, 3] @@ -381,6 +404,10 @@ def compose_matrix(scale=None, shear=None, angles=None, translation=None, perspe list[list[float]] The 4x4 matrix that combines the provided transformation components. + See Also + -------- + decompose_matrix + Examples -------- >>> trans1 = [1, 2, 3] @@ -433,6 +460,18 @@ def identity_matrix(dim): The items on the "diagonal" are one. All other items are zero. + See Also + -------- + matrix_from_frame + matrix_from_frame_to_frame + matrix_from_euler_angles + matrix_from_axis_and_angle + matrix_from_basis_vectors + matrix_from_translation + matrix_from_scale_factors + matrix_from_shear_entries + matrix_from_perspective_entries + Examples -------- >>> identity_matrix(4) @@ -447,7 +486,7 @@ def matrix_from_frame(frame): Parameters ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` A frame describing the targeted Cartesian coordinate system Returns @@ -480,9 +519,9 @@ def matrix_from_frame_to_frame(frame_from, frame_to): Parameters ---------- - frame_from : :class:`~compas.geometry.Frame` + frame_from : :class:`compas.geometry.Frame` A frame defining the original Cartesian coordinate system - frame_to : :class:`~compas.geometry.Frame` + frame_to : :class:`compas.geometry.Frame` A frame defining the targeted Cartesian coordinate system Returns @@ -511,9 +550,9 @@ def matrix_from_change_of_basis(frame_from, frame_to): Parameters ---------- - frame_from : :class:`~compas.geometry.Frame` + frame_from : :class:`compas.geometry.Frame` A frame defining the original Cartesian coordinate system - frame_to : :class:`~compas.geometry.Frame` + frame_to : :class:`compas.geometry.Frame` A frame defining the targeted Cartesian coordinate system Returns @@ -703,7 +742,7 @@ def matrix_from_axis_and_angle(axis, angle, point=None): Three numbers that represent the axis of rotation. angle : float The rotation angle in radians. - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional A point to perform a rotation around an origin other than [0, 0, 0]. Returns @@ -770,7 +809,7 @@ def matrix_from_axis_angle_vector(axis_angle_vector, point=[0, 0, 0]): axis_angle_vector : [float, float, float] Three numbers that represent the axis of rotation and angle of rotation through the vector's magnitude. - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional A point to perform a rotation around an origin other than [0, 0, 0]. Returns @@ -999,9 +1038,9 @@ def matrix_from_basis_vectors(xaxis, yaxis): Parameters ---------- - xaxis : [float, float, float] | :class:`~compas.geometry.Vector` + xaxis : [float, float, float] | :class:`compas.geometry.Vector` The x-axis of the frame. - yaxis : [float, float, float] | :class:`~compas.geometry.Vector` + yaxis : [float, float, float] | :class:`compas.geometry.Vector` The y-axis of the frame. Returns @@ -1132,7 +1171,7 @@ def matrix_from_orthogonal_projection(plane): Parameters ---------- - plane : [point, normal] | :class:`~compas.geometry.Plane` + plane : [point, normal] | :class:`compas.geometry.Plane` The plane to project onto. Returns @@ -1165,9 +1204,9 @@ def matrix_from_parallel_projection(plane, direction): Parameters ---------- - plane : [point, normal] | :class:`~compas.geometry.Plane` + plane : [point, normal] | :class:`compas.geometry.Plane` The plane to project onto. - direction : [float, float, float] | :class:`~compas.geometry.Vector` + direction : [float, float, float] | :class:`compas.geometry.Vector` Direction of the projection. Returns @@ -1202,9 +1241,9 @@ def matrix_from_perspective_projection(plane, center_of_projection): Parameters ---------- - plane : [point, normal] | :class:`~compas.geometry.Plane` + plane : [point, normal] | :class:`compas.geometry.Plane` The plane to project onto. - center_of_projection : [float, float, float] | :class:`~compas.geometry.Point` + center_of_projection : [float, float, float] | :class:`compas.geometry.Point` The camera view point. Returns @@ -1314,12 +1353,12 @@ def matrix_from_shear(angle, direction, point, normal): ---------- angle : float The angle in radians. - direction : [float, float, float] | :class:`~compas.geometry.Vector` + direction : [float, float, float] | :class:`compas.geometry.Vector` The direction vector as list of 3 numbers. It must be orthogonal to the normal vector. - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point of the shear plane as list of 3 numbers. - normal : [float, float, float] | :class:`~compas.geometry.Vector` + normal : [float, float, float] | :class:`compas.geometry.Vector` The normal of the shear plane as list of 3 numbers. Returns @@ -1456,7 +1495,7 @@ def quaternion_from_axis_angle(axis, angle): Parameters ---------- - axis : [float, float, float] | :class:`~compas.geometry.Vector` + axis : [float, float, float] | :class:`compas.geometry.Vector` XYZ coordinates of the rotation axis vector. angle : float Angle of rotation in radians. diff --git a/src/compas/geometry/_core/normals.py b/src/compas/geometry/_core/normals.py index c7f9d066716..961c0190b30 100644 --- a/src/compas/geometry/_core/normals.py +++ b/src/compas/geometry/_core/normals.py @@ -17,7 +17,7 @@ def normal_polygon(polygon, unitized=True): Parameters ---------- - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` A list of polygon point coordinates. unitized : bool, optional If True, unitize the normal vector. @@ -29,9 +29,14 @@ def normal_polygon(polygon, unitized=True): Raises ------ - AssertionError + ValueError If less than three points are provided. + See Also + -------- + normal_triangle + normal_triangle_xy + Notes ----- The points in the list should be unique. For example, the first and last @@ -40,7 +45,8 @@ def normal_polygon(polygon, unitized=True): """ p = len(polygon) - assert p > 2, "At least three points required" + if p < 3: + raise ValueError("At least three points required.") nx = 0 ny = 0 @@ -71,7 +77,7 @@ def normal_triangle(triangle, unitized=True): Parameters ---------- - triangle : [point, point, point] | :class:`~compas.geometry.Polygon` + triangle : [point, point, point] | :class:`compas.geometry.Polygon` A list of triangle point coordinates. unitized : bool, optional If True, unitize the normal vector. @@ -83,11 +89,18 @@ def normal_triangle(triangle, unitized=True): Raises ------ - AssertionError + ValueError If the triangle does not have three vertices. + See Also + -------- + normal_polygon + normal_triangle_xy + """ - assert len(triangle) == 3, "Three points are required." + if len(triangle) != 3: + raise ValueError("Three points are required.") + a, b, c = triangle ab = subtract_vectors(b, a) ac = subtract_vectors(c, a) @@ -103,7 +116,7 @@ def normal_triangle_xy(triangle, unitized=True): Parameters ---------- - triangle : [point, point, point] | :class:`~compas.geometry.Polygon` + triangle : [point, point, point] | :class:`compas.geometry.Polygon` A list of triangle point coordinates. Z-coordinates are ignored. unitized : bool, optional @@ -116,10 +129,18 @@ def normal_triangle_xy(triangle, unitized=True): Raises ------ - AssertionError + ValueError If the triangle does not have three vertices. + See Also + -------- + normal_polygon + normal_triangle + """ + if len(triangle) != 3: + raise ValueError("Three points are required.") + a, b, c = triangle ab = subtract_vectors_xy(b, a) ac = subtract_vectors_xy(c, a) diff --git a/src/compas/geometry/_core/nurbs.py b/src/compas/geometry/_core/nurbs.py index 923f2996307..7f850eb513a 100644 --- a/src/compas/geometry/_core/nurbs.py +++ b/src/compas/geometry/_core/nurbs.py @@ -27,6 +27,14 @@ def construct_knotvector(degree, pointcount): ValueError If the number of control points is less than degree + 1. + See Also + -------- + knotvector_to_knots_and_mults + knots_and_mults_to_knotvector + find_span + compute_basisfuncs + compute_basisfuncsderivs + References ---------- The NURBS Book. Chapter 2. Page 66. @@ -54,6 +62,14 @@ def knotvector_to_knots_and_mults(knotvector): tuple[list[int | float], list[int]] Knots and multiplicities. + See Also + -------- + construct_knotvector + knots_and_mults_to_knotvector + find_span + compute_basisfuncs + compute_basisfuncsderivs + Notes ----- The "standard" representation of a knot vector is a list of the form @@ -88,6 +104,14 @@ def knots_and_mults_to_knotvector(knots, mults): list[int | float] Knot vector. + See Also + -------- + construct_knotvector + knotvector_to_knots_and_mults + find_span + compute_basisfuncs + compute_basisfuncsderivs + Notes ----- The "standard" representation of a knot vector is a list of the form @@ -129,6 +153,14 @@ def find_span(n, degree, knotvector, u): ValueError If the parameter value is greater than the maximum knot or less than the minimum knot. + See Also + -------- + construct_knotvector + knotvector_to_knots_and_mults + knots_and_mults_to_knotvector + compute_basisfuncs + compute_basisfuncsderivs + References ---------- The NURBS Book. Chapter 2. Page 68. Algorithm A2.1. @@ -176,6 +208,14 @@ def compute_basisfuncs(degree, knotvector, i, u): list[float] Basis functions. + See Also + -------- + construct_knotvector + knotvector_to_knots_and_mults + knots_and_mults_to_knotvector + find_span + compute_basisfuncsderivs + Notes ----- In any given knot span, :math:`\\[u_{j}, u_{j+1}\\)` at most degree + 1 of the :math:`N_{i,degree}` basis functions are nonzero, @@ -230,6 +270,14 @@ def compute_basisfuncsderivs(degree, knotvector, i, u, n): list[float] Derivatives of the basis functions. + See Also + -------- + construct_knotvector + knotvector_to_knots_and_mults + knots_and_mults_to_knotvector + find_span + compute_basisfuncs + References ---------- The NURBS Book. Chapter 2. Page 72. Algorithm A2.3. diff --git a/src/compas/geometry/_core/predicates_2.py b/src/compas/geometry/_core/predicates_2.py index c46ae9c71aa..c5e37d0d1c1 100644 --- a/src/compas/geometry/_core/predicates_2.py +++ b/src/compas/geometry/_core/predicates_2.py @@ -7,17 +7,34 @@ from compas.geometry import closest_point_on_segment_xy +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Fundamental +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + def is_ccw_xy(a, b, c, colinear=False): """Determine if c is on the left of ab when looking from a to b, and assuming that all points lie in the XY plane. Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` Base point defined by XY(Z) coordinates. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` First end point defined by XY(Z) coordinates. - c : [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float, float] | :class:`compas.geometry.Point` Second end point defined by XY(Z) coordinates. colinear : bool, optional If True, colinear points will return a positive result. @@ -28,6 +45,10 @@ def is_ccw_xy(a, b, c, colinear=False): True if ccw. False otherwise. + See Also + -------- + is_colinear_xy + References ---------- For more info, see [1]_. @@ -64,11 +85,11 @@ def is_colinear_xy(a, b, c): Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` Point 1 defined by XY(Z) coordinates. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` Point 2 defined by XY(Z) coordinates. - c : [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float, float] | :class:`compas.geometry.Point` Point 3 defined by XY(Z) coordinates. Returns @@ -77,6 +98,10 @@ def is_colinear_xy(a, b, c): True if the points are colinear. False otherwise. + See Also + -------- + is_ccw_xy + """ ab_x = b[0] - a[0] ab_y = b[1] - a[1] @@ -85,12 +110,46 @@ def is_colinear_xy(a, b, c): return ab_x * ac_y == ab_y * ac_x +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Parallel, Perpendicular +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Convexity +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + def is_polygon_convex_xy(polygon, colinear=False): """Determine if the polygon is convex on the XY-plane. Parameters ---------- - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` The XY(Z) coordinates of the corners of a polygon. The vertices are assumed to be in order. The polygon is assumed to be closed: the first and last vertex in the sequence should not be the same. @@ -117,14 +176,31 @@ def is_polygon_convex_xy(polygon, colinear=False): return True +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Containment (Curves) +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + def is_point_on_line_xy(point, line, tol=1e-6): """Determine if a point lies on a line on the XY-plane. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` XY(Z) coordinates of two points defining a line. tol : float, optional A tolerance for membership verification. @@ -135,6 +211,11 @@ def is_point_on_line_xy(point, line, tol=1e-6): True if the point is in on the line. False otherwise. + See Also + -------- + is_point_on_segment_xy + is_point_on_polyline_xy + """ return distance_point_line_xy(point, line) <= tol @@ -144,9 +225,9 @@ def is_point_on_segment_xy(point, segment, tol=1e-6): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point. - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` XY(Z) coordinates of two points defining a segment. tol : float, optional A tolerance for membership verification. @@ -157,6 +238,11 @@ def is_point_on_segment_xy(point, segment, tol=1e-6): True if the point is on the line segment. False otherwise. + See Also + -------- + is_point_on_line_xy + is_point_on_polyline_xy + """ a, b = segment @@ -182,9 +268,9 @@ def is_point_on_polyline_xy(point, polyline, tol=1e-6): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates. - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` XY(Z) coordinates of the points of the polyline. tol : float, optional The tolerance for membership verification. @@ -195,6 +281,11 @@ def is_point_on_polyline_xy(point, polyline, tol=1e-6): True if the point is on the polyline. False otherwise. + See Also + -------- + is_point_on_line_xy + is_point_on_segment_xy + """ for i in range(len(polyline) - 1): a = polyline[i] @@ -207,12 +298,29 @@ def is_point_on_polyline_xy(point, polyline, tol=1e-6): return False +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Containment (Shapes) +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + def is_point_in_triangle_xy(point, triangle, colinear=False): """Determine if a point is in the interior of a triangle lying on the XY-plane. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point. triangle : [point, point, point] XY(Z) coordinates of the corners of the triangle. @@ -225,6 +333,12 @@ def is_point_in_triangle_xy(point, triangle, colinear=False): True if the point is in the convex polygon. False otherwise. + See Also + -------- + is_point_in_convex_polygon_xy + is_point_in_polygon_xy + is_point_in_circle_xy + """ a, b, c = triangle ccw = is_ccw_xy(c, a, point, colinear) @@ -243,9 +357,9 @@ def is_point_in_convex_polygon_xy(point, polygon): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point (Z will be ignored). - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` A sequence of XY(Z) coordinates of points representing the locations of the corners of a polygon (Z will be ignored). The vertices are assumed to be in order. The polygon is assumed to be closed: the first and last vertex in the sequence should not be the same. @@ -260,6 +374,12 @@ def is_point_in_convex_polygon_xy(point, polygon): -------- Does not work for concave polygons. + See Also + -------- + is_point_in_triangle_xy + is_point_in_polygon_xy + is_point_in_circle_xy + """ ccw = None for i in range(-1, len(polygon) - 1): @@ -278,9 +398,9 @@ def is_point_in_polygon_xy(point, polygon): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point (Z will be ignored). - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` A sequence of XY(Z) coordinates of points representing the locations of the corners of a polygon (Z will be ignored). The vertices are assumed to be in order. The polygon is assumed to be closed. @@ -296,6 +416,12 @@ def is_point_in_polygon_xy(point, polygon): -------- A boundary check is not yet implemented. This should include a tolerance value. + See Also + -------- + is_point_in_triangle_xy + is_point_in_convex_polygon_xy + is_point_in_circle_xy + """ x, y = point[0], point[1] polygon = [(p[0], p[1]) for p in polygon] # make 2D @@ -320,9 +446,9 @@ def is_point_in_circle_xy(point, circle): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point (Z will be ignored). - circle : [[point, vector], float] | :class:`~compas.geometry.Circle` + circle : [[point, vector], float] | :class:`compas.geometry.Circle` Center and radius of the circle on the XY plane. Returns @@ -331,6 +457,12 @@ def is_point_in_circle_xy(point, circle): True if the point lies in the circle. False otherwise. + See Also + -------- + is_point_in_triangle_xy + is_point_in_convex_polygon_xy + is_point_in_polygon_xy + """ dis = distance_point_point_xy(point, circle[0][0]) if dis <= circle[1]: @@ -343,11 +475,11 @@ def is_polygon_in_polygon_xy(polygon1, polygon2): Parameters ---------- - polygon1 : sequence[point] | :class:`~compas.geometry.Polygon` + polygon1 : sequence[point] | :class:`compas.geometry.Polygon` List of XY(Z) coordinates of points representing the locations of the corners of the exterior polygon (Z will be ignored). The vertices are assumed to be in order. The polygon is assumed to be closed: the first and last vertex in the sequence should not be the same. - polygon2 : sequence[point] | :class:`~compas.geometry.Polygon` + polygon2 : sequence[point] | :class:`compas.geometry.Polygon` List of XY(Z) coordinates of points representing the locations of the corners of the interior polygon (Z will be ignored). The vertices are assumed to be in order. The polygon is assumed to be closed: the first and last vertex in the sequence should not be the same. @@ -377,14 +509,31 @@ def is_polygon_in_polygon_xy(polygon1, polygon2): return False +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Deprecated +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + def is_intersection_line_line_xy(l1, l2, tol=1e-6): """Verifies if two lines intersect on the XY-plane. Parameters ---------- - l1 : [point, point] | :class:`~compas.geometry.Line` + l1 : [point, point] | :class:`compas.geometry.Line` XY(Z) coordinates of two points defining a line. - l2 : [point, point] | :class:`~compas.geometry.Line` + l2 : [point, point] | :class:`compas.geometry.Line` XY(Z) coordinates of two points defining a line. tol : float, optional A tolerance for intersection verification. @@ -404,10 +553,10 @@ def is_intersection_segment_segment_xy(ab, cd): Parameters ---------- - ab : [point, point] | :class:`~compas.geometry.Line` + ab : [point, point] | :class:`compas.geometry.Line` Two points representing the start and end points of a segment. Z coordinates will be ignored. - cd : [point, point] | :class:`~compas.geometry.Line` + cd : [point, point] | :class:`compas.geometry.Line` Two points representing the start and end points of a segment. Z coordinates will be ignored. diff --git a/src/compas/geometry/_core/predicates_3.py b/src/compas/geometry/_core/predicates_3.py index 55560cdf7a9..f7bc234aa3c 100644 --- a/src/compas/geometry/_core/predicates_3.py +++ b/src/compas/geometry/_core/predicates_3.py @@ -2,14 +2,11 @@ from __future__ import absolute_import from __future__ import division -from math import fabs - from compas.utilities import window from compas.geometry import subtract_vectors from compas.geometry import cross_vectors from compas.geometry import dot_vectors -from compas.geometry import normalize_vector from compas.geometry import centroid_points from compas.geometry import normal_polygon from compas.geometry import length_vector_sqrd @@ -19,7 +16,22 @@ from compas.geometry import distance_point_line from compas.geometry import closest_point_on_segment -from compas.geometry import area_triangle + +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Colinear, Coplanar +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= def is_colinear(a, b, c, tol=1e-6): @@ -27,14 +39,14 @@ def is_colinear(a, b, c, tol=1e-6): Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` Point 1. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` Point 2. - c : [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float, float] | :class:`compas.geometry.Point` Point 3. tol : float, optional - A tolerance for membership verification. + Tolerance for comparing the area of the triangle defined by the three points with zero. Returns ------- @@ -42,8 +54,13 @@ def is_colinear(a, b, c, tol=1e-6): True if the points are colinear. False otherwise. + See Also + -------- + is_colinear_line_line + is_coplanar + """ - return area_triangle([a, b, c]) < tol + return 0.5 * length_vector_sqrd(cross_vectors(subtract_vectors(b, a), subtract_vectors(c, a))) < tol**2 def is_colinear_line_line(line1, line2, tol=1e-6): @@ -51,9 +68,9 @@ def is_colinear_line_line(line1, line2, tol=1e-6): Parameters ---------- - line1 : [point, point] | :class:`~compas.geometry.Line` + line1 : [point, point] | :class:`compas.geometry.Line` Line 1. - line2 : [point, point] | :class:`~compas.geometry.Line` + line2 : [point, point] | :class:`compas.geometry.Line` Line 2. tol : float, optional A tolerance for colinearity verification. @@ -64,23 +81,132 @@ def is_colinear_line_line(line1, line2, tol=1e-6): True if the lines are colinear. False otherwise. + See Also + -------- + is_colinear + is_coplanar + """ a, b = line1 c, d = line2 return is_colinear(a, b, c, tol) and is_colinear(a, b, d, tol) +def is_coplanar(points, tol=1e-6): + """Determine if the points are coplanar. + + Parameters + ---------- + points : sequence[point] + A sequence of point locations. + tol : float, optional + A tolerance for planarity validation. + + Returns + ------- + bool + True if the points are coplanar. + False otherwise. + + See Also + -------- + is_colinear + is_colinear_line_line + + Notes + ----- + Compute the normal vector (cross product) of the vectors formed by the first three points. + Taking the first point as base point, include one more vector at a time and check if that vector is perpendicular to the normal vector. + If all vectors are perpendicular, the points are coplanar. + + """ + if len(points) < 4: + return True + + tol2 = tol**2 + temp = points[:] + + while True: + a = temp.pop(0) + b = temp.pop(0) + c = temp.pop(0) + n = cross_vectors(subtract_vectors(b, a), subtract_vectors(c, a)) + if not (0.5 * length_vector_sqrd(n) < tol2): + # perhaps we should use a different tolerance here? + # or rather check if the squared length is large enough? + break + if not temp: + return True + + return all(is_perpendicular_vector_vector(n, subtract_vectors(d, a), tol) for d in temp) + + +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Parallel, Perpendicular +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + +def is_parallel_vector_vector(u, v, tol=1e-6): + """Determine if two vectors are parallel. + + Parameters + ---------- + u : [float, float, float] | :class:`compas.geometry.Vector` + Vector 1. + v : [float, float, float] | :class:`compas.geometry.Vector` + Vector 2. + tol : float, optional + A tolerance for comparing the length of the cross product to zero. + + Returns + ------- + bool + True if the vectors are parallel. + False otherwise. + + See Also + -------- + is_parallel_line_line + is_parallel_plane_plane + is_perpendicular_vector_vector + + Notes + ----- + This function does not distinguish between parallel and antiparallel vectors. + + """ + # uv = dot_vectors(u, v) + # uu = dot_vectors(u, u) + # vv = dot_vectors(v, v) + # return abs(uv * uv - uu * vv) < tol + u_v = cross_vectors(u, v) + return dot_vectors(u_v, u_v) < tol**2 + # return abs(dot_vectors(normalize_vector(u), normalize_vector(v)) - 1.0) < tol + + def is_parallel_line_line(line1, line2, tol=1e-6): """Determine if two lines are parallel. Parameters ---------- - line1 : [point, point] | :class:`~compas.geometry.Line` + line1 : [point, point] | :class:`compas.geometry.Line` Line 1. - line2 : [point, point] | :class:`~compas.geometry.Line` + line2 : [point, point] | :class:`compas.geometry.Line` Line 2. tol : float, optional - A tolerance for colinearity verification. + A tolerance for verifying parallelity of the line direction vectors. Returns ------- @@ -88,64 +214,152 @@ def is_parallel_line_line(line1, line2, tol=1e-6): True if the lines are colinear. False otherwise. + See Also + -------- + is_parallel_vector_vector + is_parallel_plane_plane + is_perpendicular_line_line + """ a, b = line1 c, d = line2 - e1 = normalize_vector(subtract_vectors(b, a)) - e2 = normalize_vector(subtract_vectors(d, c)) - return abs(dot_vectors(e1, e2)) > 1.0 - tol + # e1 = normalize_vector(subtract_vectors(b, a)) + # e2 = normalize_vector(subtract_vectors(d, c)) + # return abs(dot_vectors(e1, e2)) > 1.0 - tol + return is_parallel_vector_vector(subtract_vectors(b, a), subtract_vectors(d, c), tol) -def is_coplanar(points, tol=0.01): - """Determine if the points are coplanar. +def is_parallel_plane_plane(plane1, plane2, tol=1e-6): + """Determine if two planes are parallel. Parameters ---------- - points : sequence[point] - A sequence of point locations. + plane1 : [point, vector] | :class:`compas.geometry.Plane` + Plane 1. + plane2 : [point, vector] | :class:`compas.geometry.Plane` + Plane 2. tol : float, optional - A tolerance for planarity validation. + A tolerance for verifying parallelity of the plane normals. Returns ------- bool - True if the points are coplanar. + True if the planes are parallel. False otherwise. - Notes - ----- - Compute the normal vector (cross product) of the vectors formed by the first - three points. Include one more vector at a time to compute a new normal and - compare with the original normal. If their cross product is not zero, they - are not parallel, which means the point are not in the same plane. + See Also + -------- + is_parallel_vector_vector + is_parallel_line_line + is_perpendicular_plane_plane + + """ + return is_parallel_vector_vector(plane1[1], plane2[1], tol) + + +def is_perpendicular_vector_vector(u, v, tol=1e-6): + """Determine if two vectors are perpendicular. - Four points are coplanar if the volume of the tetrahedron defined by them is - 0. Coplanarity is equivalent to the statement that the pair of lines - determined by the four points are not skew, and can be equivalently stated - in vector form as (x2 - x0).[(x1 - x0) x (x3 - x2)] = 0. + Parameters + ---------- + u : [float, float, float] | :class:`compas.geometry.Vector` + Vector 1. + v : [float, float, float] | :class:`compas.geometry.Vector` + Vector 2. + tol : float, optional + A tolerance for comparing the dot product of the two vectors to zero. + + Returns + ------- + bool + True if the vectors are perpendicular. + False otherwise. + + See Also + -------- + is_perpendicular_line_line + is_perpendicular_plane_plane + is_parallel_vector_vector """ - if len(points) < 4: - return True + return abs(dot_vectors(u, v)) < tol - tol2 = tol**2 - if len(points) == 4: - v01 = subtract_vectors(points[1], points[0]) - v02 = subtract_vectors(points[2], points[0]) - v23 = subtract_vectors(points[3], points[2]) - res = dot_vectors(v02, cross_vectors(v01, v23)) - return res**2 < tol2 - - a, b, c = points[:3] - ab = subtract_vectors(b, a) - n0 = cross_vectors(ab, subtract_vectors(c, a)) - points = points[3:] - for c in points: - n1 = cross_vectors(ab, subtract_vectors(c, a)) - if length_vector_sqrd(cross_vectors(n0, n1)) > tol: - return False - return True +def is_perpendicular_line_line(line1, line2, tol=1e-6): + """Determine if two lines are perpendicular. + + Parameters + ---------- + line1 : [point, point] | :class:`compas.geometry.Line` + Line 1. + line2 : [point, point] | :class:`compas.geometry.Line` + Line 2. + tol : float, optional + A tolerance for verifying perpendicularity of the line direction vectors. + + Returns + ------- + bool + True if the lines are perpendicular. + False otherwise. + + See Also + -------- + is_perpendicular_vector_vector + is_perpendicular_plane_plane + is_parallel_line_line + + """ + return is_perpendicular_vector_vector( + subtract_vectors(line1[1], line1[0]), + subtract_vectors(line2[1], line2[0]), + tol, + ) + + +def is_perpendicular_plane_plane(plane1, plane2, tol=1e-6): + """Determine if two planes are perpendicular. + + Parameters + ---------- + plane1 : [point, vector] | :class:`compas.geometry.Plane` + Plane 1. + plane2 : [point, vector] | :class:`compas.geometry.Plane` + Plane 2. + tol : float, optional + A tolerance for verifying perpendicularity of the plane normals. + + Returns + ------- + bool + True if the planes are perpendicular. + False otherwise. + + See Also + -------- + is_perpendicular_vector_vector + is_perpendicular_line_line + is_parallel_plane_plane + + """ + return is_perpendicular_vector_vector(plane1[1], plane2[1], tol) + + +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Convexity +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= def is_polygon_convex(polygon): @@ -153,7 +367,7 @@ def is_polygon_convex(polygon): Parameters ---------- - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` A polygon. Returns @@ -162,6 +376,10 @@ def is_polygon_convex(polygon): True if the polygon is convex. False otherwise. + See Also + -------- + is_polyhedron_convex + Notes ----- Use this function for *spatial* polygons. @@ -191,61 +409,67 @@ def is_polygon_convex(polygon): return True -def is_point_on_plane(point, plane, tol=1e-6): - """Determine if a point lies on a plane. +def is_polyhedron_convex(polyhedron): + """Determine if a polyhedron is convex. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` - A point. - plane : [point, vector] | :class:`~compas.geometry.Plane` - A plane. - tol : float, optional - A tolerance for membership verification. + polyhedron : [sequence[point], sequence[sequence[int]]] | :class:`compas.geometry.Polyhedron` + A polyhedron defined by a sequence of points + and a sequence of faces, with each face defined as a sequence of indices into the sequence of points. Returns ------- bool - True if the point is in on the plane. + True if the polyhedron is convex. False otherwise. - """ - return distance_point_plane(point, plane) <= tol - - -def is_point_infront_plane(point, plane, tol=1e-6): - """Determine if a point lies in front of a plane. - - Parameters - ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` - A point. - plane : [point, vector] | :class:`~compas.geometry.Plane` - A plane. - tol : float, optional - A tolerance for membership verification. - - Returns - ------- - bool - True if the point is in front of the plane. - False otherwise. + See Also + -------- + is_polygon_convex """ - return dot_vectors(subtract_vectors(point, plane[0]), plane[1]) > tol + vertices, faces = polyhedron + for face in faces: + base = vertices[face[0]] + normal = normal_polygon([vertices[index] for index in face]) + direction = None + for i in range(len(vertices)): + if i not in face: + point = vertices[i] + if direction is None: + direction = dot_vectors(subtract_vectors(point, base), normal) >= 0 + else: + if dot_vectors(subtract_vectors(point, base), normal) >= 0 != direction: + return False + return True -is_point_in_halfspace = is_point_infront_plane +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Containment (Plane) +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= -def is_point_behind_plane(point, plane, tol=1e-6): - """Determine if a point lies behind a plane. +def is_point_on_plane(point, plane, tol=1e-6): + """Determine if a point lies on a plane. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` A point. - plane : [point, normal] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` A plane. tol : float, optional A tolerance for membership verification. @@ -253,11 +477,28 @@ def is_point_behind_plane(point, plane, tol=1e-6): Returns ------- bool - True if the point is in front of the plane. + True if the point is in on the plane. False otherwise. """ - return dot_vectors(subtract_vectors(point, plane[0]), plane[1]) < -tol + return distance_point_plane(point, plane) <= tol + + +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Containment (Curves) +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= def is_point_on_line(point, line, tol=1e-6): @@ -265,9 +506,9 @@ def is_point_on_line(point, line, tol=1e-6): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` A point. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` A line. tol : float, optional A tolerance for membership verification. @@ -287,9 +528,9 @@ def is_point_on_segment(point, segment, tol=1e-6): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` A point. - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` A line segment. tol : float, optional A tolerance for membership verification. @@ -323,9 +564,9 @@ def is_point_on_polyline(point, polyline, tol=1e-6): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` A point. - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` A polyline. tol : float, optional The tolerance for membership verification. @@ -348,57 +589,73 @@ def is_point_on_polyline(point, polyline, tol=1e-6): return False -def is_point_in_triangle(point, triangle): - """Determine if a point is in the interior of a triangle. +def is_point_on_circle(point, circle, tol=1e-6): + """Determine if a point lies on a circle. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` A point. - triangle : [point, point, point] - A triangle. + circle : [plane, float] + A circle. + tol : float, optional + A tolerance for membership verification. Returns ------- bool - True if the point is in inside the triangle. + True if the point lies on the circle. False otherwise. - See Also - -------- - compas.geometry.is_point_in_triangle_xy - - Notes - ----- - Should the point be on the same plane as the triangle? - """ - - def is_on_same_side(p1, p2, segment): - a, b = segment - v = subtract_vectors(b, a) - c1 = cross_vectors(v, subtract_vectors(p1, a)) - c2 = cross_vectors(v, subtract_vectors(p2, a)) - if dot_vectors(c1, c2) >= 0: - return True - return False - - a, b, c = triangle - - if is_on_same_side(point, a, (b, c)) and is_on_same_side(point, b, (a, c)) and is_on_same_side(point, c, (a, b)): - return True - + plane, radius = circle + if is_point_on_plane(point, plane): + return abs(distance_point_point(point, plane[0]) - radius) <= tol return False -def is_point_in_circle(point, circle): +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Containment (Surfaces) +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Containment (Shapes) +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + +def is_point_in_circle(point, circle, tol=1e-6): """Determine if a point lies in a circle. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` A point. - circle : [plane, float] | :class:`~compas.geometry.Circle` + circle : [plane, float] A circle. Returns @@ -409,272 +666,435 @@ def is_point_in_circle(point, circle): """ plane, radius = circle - if is_point_on_plane(point, plane): + if is_point_on_plane(point, plane, tol=tol): return distance_point_point(point, plane[0]) <= radius return False -def is_intersection_line_line(l1, l2, tol=1e-6): - """Verifies if two lines intersect. +def is_point_in_triangle(point, triangle, tol=1e-6): + """Determine if a point is in the interior of a triangle. Parameters ---------- - l1 : [point, point] | :class:`~compas.geometry.Line` - A line. - l2 : [point, point] | :class:`~compas.geometry.Line` - A line. - tol : float, optional - A tolerance for intersection verification. + point : [float, float, float] | :class:`compas.geometry.Point` + A point. + triangle : [point, point, point] + A triangle. Returns ------- bool - True if the lines intersect in one point. - False if the lines are skew, parallel or lie on top of each other. + True if the point is in inside the triangle. + False otherwise. - """ - a, b = l1 - c, d = l2 + See Also + -------- + compas.geometry.is_point_in_triangle_xy - e1 = normalize_vector(subtract_vectors(b, a)) - e2 = normalize_vector(subtract_vectors(d, c)) + """ - # check for parallel lines - if abs(dot_vectors(e1, e2)) > 1.0 - tol: + def is_on_same_side(p1, p2, segment): + a, b = segment + v = subtract_vectors(b, a) + c1 = cross_vectors(v, subtract_vectors(p1, a)) + c2 = cross_vectors(v, subtract_vectors(p2, a)) + if dot_vectors(c1, c2) >= 0: + return True return False - # check for intersection - if abs(dot_vectors(cross_vectors(e1, e2), subtract_vectors(c, a))) < tol: - return True + a, b, c = triangle + + if is_point_on_plane(point, (a, normal_polygon(triangle)), tol=tol): + if ( + is_on_same_side(point, a, (b, c)) + and is_on_same_side(point, b, (a, c)) + and is_on_same_side(point, c, (a, b)) + ): + return True + return False -def is_intersection_segment_segment(s1, s2, tol=1e-6): - """Verifies if two segments intersect. +def is_point_in_polygon(point, polygon, tol=1e-6): + """Determine if a point is in the interior of a polygon. Parameters ---------- - s1 : [point, point] | :class:`~compas.geometry.Line` - A line segment. - s2 : [point, point] | :class:`~compas.geometry.Line` - A line segment. - tol : float, optional - A tolerance for intersection verification. + point : [float, float, float] | :class:`compas.geometry.Point` + A point. + polygon : sequence[point] | :class:`compas.geometry.Polygon` + A polygon. Returns ------- bool - True if the segments intersect in one point. - False if the segments are skew, parallel or lie on top of each other. + True if the point is in inside the polygon. + False otherwise. """ raise NotImplementedError -def is_intersection_line_triangle(line, triangle, tol=1e-6): - """Verifies if a line (ray) intersects with a triangle. +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Containment (Solids) +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + +def is_point_in_sphere(point, sphere, tol=1e-6): + """Determine if a point lies in a sphere. Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` - A line. - triangle : [point, point, point] - A triangle. - tol : float, optional - A tolerance for intersection verification. + point : [float, float, float] | :class:`compas.geometry.Point` + A point. + sphere : [point, float] + A sphere. Returns ------- bool - True if the line (ray) intersects with the triangle. + True if the point lies in the sphere. False otherwise. - Notes - ----- - Based on the Moeller Trumbore intersection algorithm. - The line is treated as continues, directed ray and not as line segment with a start and end point - - Examples - -------- - >>> - """ - a, b, c = triangle - # direction vector and base point of line - v1 = subtract_vectors(line[1], line[0]) - p1 = line[0] - # Find vectors for two edges sharing triangle vertex 1 - e1 = subtract_vectors(b, a) - e2 = subtract_vectors(c, a) - # Begin calculating determinant - also used to calculate u parameter - p = cross_vectors(v1, e2) - # if determinant is near zero, ray lies in plane of triangle - det = dot_vectors(e1, p) - - # NOT CULLING - if det > -tol and det < tol: - return False - - inv_det = 1.0 / det - # calculate distance from V1 to ray origin - t = subtract_vectors(p1, a) - # Calculate u parameter and make_blocks bound - u = dot_vectors(t, p) * inv_det + center, radius = sphere + return distance_point_point(point, center) <= radius + tol - # The intersection lies outside of the triangle - if u < 0.0 or u > 1.0: - return False - # Prepare to make_blocks v parameter - q = cross_vectors(t, e1) - # Calculate V parameter and make_blocks bound - v = dot_vectors(v1, q) * inv_det - - # The intersection lies outside of the triangle - if v < 0.0 or u + v > 1.0: - return False - - t = dot_vectors(e2, q) * inv_det - - if t > tol: - return True - # No hit - return False - - -def is_intersection_line_plane(line, plane, tol=1e-6): - """Determine if a line (ray) intersects with a plane. +def is_point_in_aab(point, box, tol=1e-6): + """Determine if a point lies in an axis-aligned box. Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` - A line. - plane : [point, vector] | :class:`~compas.geometry.Plane` - A plane. - tol : float, optional - A tolerance for intersection verification. + point : [float, float, float] | :class:`compas.geometry.Point` + A point. + box : [[float, float, float], [float, float, float]] | [:class:`compas.geometry.Point`, :class:`compas.geometry.Point``] + An axis-aligned box defined by the min/max corners. Returns ------- bool - True if the line intersects with the plane. + True if the point lies in the box. False otherwise. """ - pt1 = line[0] - pt2 = line[1] - p_norm = plane[1] - - v1 = subtract_vectors(pt2, pt1) - dot = dot_vectors(p_norm, v1) + a, b = box + return all(a[i] - tol <= point[i] <= b[i] + tol for i in range(3)) - if fabs(dot) > tol: - return True - return False - -def is_intersection_segment_plane(segment, plane, tol=1e-6): - """Determine if a line segment intersects with a plane. +def is_point_in_polyhedron(point, polyhedron): + """Determine if the point lies inside the given polyhedron. Parameters ---------- - segment : [point, point] | :class:`~compas.geometry.Line` - A line segment. - plane : [point, vector] | :class:`~compas.geometry.Plane` - A plane. - tol : float, optional - A tolerance for intersection verification. + point : [float, float, float] | :class:`compas.geometry.Point` + The test point. + polyhedron : [sequence[point], sequence[sequence[int]]] | :class:`compas.geometry.Polyhedron`. + The polyhedron defined by a sequence of points + and a sequence of faces, with each face defined as a sequence of indices into the sequence of points. Returns ------- bool - True if the segment intersects with the plane. - False otherwise. + True, if the point lies in the polyhedron. + False, otherwise. """ - pt1 = segment[0] - pt2 = segment[1] - p_cent = plane[0] - p_norm = plane[1] - - v1 = subtract_vectors(pt2, pt1) - dot = dot_vectors(p_norm, v1) - - if fabs(dot) > tol: - v2 = subtract_vectors(pt1, p_cent) - fac = -dot_vectors(p_norm, v2) / dot - if fac > 0.0 and fac < 1.0: - return True - return False - else: - return False + vertices, faces = polyhedron + polygons = [[vertices[index] for index in face] for face in faces] + planes = [[centroid_points(polygon), normal_polygon(polygon)] for polygon in polygons] + return all(is_point_behind_plane(point, plane) for plane in planes) -def is_intersection_plane_plane(plane1, plane2, tol=1e-6): - """Verifies if two planes intersect. +def is_point_infront_plane(point, plane, tol=1e-6): + """Determine if a point lies in front of a plane. Parameters ---------- - plane1 : [point, vector] | :class:`~compas.geometry.Plane` - A plane. - plane2 : [point, vector] | :class:`~compas.geometry.Plane` + point : [float, float, float] | :class:`compas.geometry.Point` + A point. + plane : [point, vector] | :class:`compas.geometry.Plane` A plane. tol : float, optional - A tolerance for intersection verification. + A tolerance for membership verification. Returns ------- bool - True if plane1 intersects with plane2. + True if the point is in front of the plane. False otherwise. """ - # check for parallelity of planes - if abs(dot_vectors(plane1[1], plane2[1])) > 1 - tol: - return False - return True + return dot_vectors(subtract_vectors(point, plane[0]), plane[1]) > tol -def is_point_in_box(point, box): - """Determine if the point lies inside the given box. +def is_point_behind_plane(point, plane, tol=1e-6): + """Determine if a point lies behind a plane. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` - The test point. - box : sequence[point] | :class:`~compas.geometry.Box`. - The box defined by 8 points with the first 4 points defining the bottom face, - and the last 4 points defining the top face. + point : [float, float, float] | :class:`compas.geometry.Point` + A point. + plane : [point, normal] | :class:`compas.geometry.Plane` + A plane. + tol : float, optional + A tolerance for membership verification. Returns ------- bool - True, if the point lies inside the box. - False, otherwise. + True if the point is in front of the plane. + False otherwise. """ - raise NotImplementedError - - -def is_point_in_polyhedron(point, polyhedron): - """Determine if the point lies inside the given polyhedron. - - Parameters - ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` - The test point. - polyhedron : [sequence[point], sequence[sequence[int]]] | :class:`~compas.geometry.Polyhedron`. - The polyhedron defined by a sequence of points - and a sequence of faces, with each face defined as a sequence of indices into the sequence of points. + return dot_vectors(subtract_vectors(point, plane[0]), plane[1]) < -tol - Returns - ------- - bool - True, if the point lies in the polyhedron. - False, otherwise. - """ - vertices, faces = polyhedron - polygons = [[vertices[index] for index in face] for face in faces] - planes = [[centroid_points(polygon), normal_polygon(polygon)] for polygon in polygons] - return all(is_point_behind_plane(point, plane) for plane in planes) +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# Deprecated +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= +# ============================================================================= + + +# def is_intersection_line_line(l1, l2, tol=1e-6): +# """Verifies if two lines intersect. + +# Parameters +# ---------- +# l1 : [point, point] | :class:`compas.geometry.Line` +# A line. +# l2 : [point, point] | :class:`compas.geometry.Line` +# A line. +# tol : float, optional +# A tolerance for intersection verification. + +# Returns +# ------- +# bool +# True if the lines intersect in one point. +# False if the lines are skew, parallel or lie on top of each other. + +# """ +# a, b = l1 +# c, d = l2 + +# e1 = normalize_vector(subtract_vectors(b, a)) +# e2 = normalize_vector(subtract_vectors(d, c)) + +# # check for parallel lines +# if abs(dot_vectors(e1, e2)) > 1.0 - tol: +# return False + +# # check for intersection +# if abs(dot_vectors(cross_vectors(e1, e2), subtract_vectors(c, a))) < tol: +# return True +# return False + + +# def is_intersection_segment_segment(s1, s2, tol=1e-6): +# """Verifies if two segments intersect. + +# Parameters +# ---------- +# s1 : [point, point] | :class:`compas.geometry.Line` +# A line segment. +# s2 : [point, point] | :class:`compas.geometry.Line` +# A line segment. +# tol : float, optional +# A tolerance for intersection verification. + +# Returns +# ------- +# bool +# True if the segments intersect in one point. +# False if the segments are skew, parallel or lie on top of each other. + +# """ +# raise NotImplementedError + + +# def is_intersection_line_triangle(line, triangle, tol=1e-6): +# """Verifies if a line (ray) intersects with a triangle. + +# Parameters +# ---------- +# line : [point, point] | :class:`compas.geometry.Line` +# A line. +# triangle : [point, point, point] +# A triangle. +# tol : float, optional +# A tolerance for intersection verification. + +# Returns +# ------- +# bool +# True if the line (ray) intersects with the triangle. +# False otherwise. + +# Notes +# ----- +# Based on the Moeller Trumbore intersection algorithm. +# The line is treated as continues, directed ray and not as line segment with a start and end point + +# Examples +# -------- +# >>> + +# """ +# a, b, c = triangle +# # direction vector and base point of line +# v1 = subtract_vectors(line[1], line[0]) +# p1 = line[0] +# # Find vectors for two edges sharing triangle vertex 1 +# e1 = subtract_vectors(b, a) +# e2 = subtract_vectors(c, a) +# # Begin calculating determinant - also used to calculate u parameter +# p = cross_vectors(v1, e2) +# # if determinant is near zero, ray lies in plane of triangle +# det = dot_vectors(e1, p) + +# # NOT CULLING +# if det > -tol and det < tol: +# return False + +# inv_det = 1.0 / det +# # calculate distance from V1 to ray origin +# t = subtract_vectors(p1, a) +# # Calculate u parameter and make_blocks bound +# u = dot_vectors(t, p) * inv_det + +# # The intersection lies outside of the triangle +# if u < 0.0 or u > 1.0: +# return False + +# # Prepare to make_blocks v parameter +# q = cross_vectors(t, e1) +# # Calculate V parameter and make_blocks bound +# v = dot_vectors(v1, q) * inv_det + +# # The intersection lies outside of the triangle +# if v < 0.0 or u + v > 1.0: +# return False + +# t = dot_vectors(e2, q) * inv_det + +# if t > tol: +# return True +# # No hit +# return False + + +# def is_intersection_line_plane(line, plane, tol=1e-6): +# """Determine if a line (ray) intersects with a plane. + +# Parameters +# ---------- +# line : [point, point] | :class:`compas.geometry.Line` +# A line. +# plane : [point, vector] | :class:`compas.geometry.Plane` +# A plane. +# tol : float, optional +# A tolerance for intersection verification. + +# Returns +# ------- +# bool +# True if the line intersects with the plane. +# False otherwise. + +# """ +# pt1 = line[0] +# pt2 = line[1] +# p_norm = plane[1] + +# v1 = subtract_vectors(pt2, pt1) +# dot = dot_vectors(p_norm, v1) + +# if fabs(dot) > tol: +# return True +# return False + + +# def is_intersection_segment_plane(segment, plane, tol=1e-6): +# """Determine if a line segment intersects with a plane. + +# Parameters +# ---------- +# segment : [point, point] | :class:`compas.geometry.Line` +# A line segment. +# plane : [point, vector] | :class:`compas.geometry.Plane` +# A plane. +# tol : float, optional +# A tolerance for intersection verification. + +# Returns +# ------- +# bool +# True if the segment intersects with the plane. +# False otherwise. + +# """ +# pt1 = segment[0] +# pt2 = segment[1] +# p_cent = plane[0] +# p_norm = plane[1] + +# v1 = subtract_vectors(pt2, pt1) +# dot = dot_vectors(p_norm, v1) + +# if fabs(dot) > tol: +# v2 = subtract_vectors(pt1, p_cent) +# fac = -dot_vectors(p_norm, v2) / dot +# if fac > 0.0 and fac < 1.0: +# return True +# return False +# else: +# return False + + +# def is_intersection_plane_plane(plane1, plane2, tol=1e-6): +# """Verifies if two planes intersect. + +# Parameters +# ---------- +# plane1 : [point, vector] | :class:`compas.geometry.Plane` +# A plane. +# plane2 : [point, vector] | :class:`compas.geometry.Plane` +# A plane. +# tol : float, optional +# A tolerance for intersection verification. + +# Returns +# ------- +# bool +# True if plane1 intersects with plane2. +# False otherwise. + +# """ +# # check for parallelity of planes +# if abs(dot_vectors(plane1[1], plane2[1])) > 1 - tol: +# return False +# return True diff --git a/src/compas/geometry/_core/quaternions.py b/src/compas/geometry/_core/quaternions.py index 7cfb6b5bcca..9a60e261019 100644 --- a/src/compas/geometry/_core/quaternions.py +++ b/src/compas/geometry/_core/quaternions.py @@ -1,52 +1,3 @@ -""" -This module contains functions that operate on and/or return quaternions. - -Notes ------ -The default convention to represent a quaternion :math:`q` in this module is by four real values **w**, **x**, **y**, **z**. -The first value **w** is the scalar (real) part, and **x**, **y**, **z** form the vector (complex, imaginary) part [1]_, so that: - -:math:`q = w + xi + yj + zk` - -where :math:`i, j, k` are basis components with following multiplication rules [2]_: - -:math:`ii = jj = kk = ijk = -1` - -:math:`ij = k,\\qquad ji = -k` - -:math:`jk = i,\\qquad kj = -i` - -:math:`ki = j,\\qquad ik = -j` - -Quaternions are associative but not commutative. - -**Quaternion as rotation.** -A rotation through an angle :math:`\\theta` around an axis defined by a euclidean unit vector :math:`u = u_{x}i + u_{y}j + u_{z}k` -can be represented as a quaternion: - -:math:`q = cos(\\frac{\\theta}{2}) + sin(\\frac{\\theta}{2}) [u_{x}i + u_{y}j + u_{z}k]` - -i.e.: - -:math:`w = cos(\\frac{\\theta}{2})` - -:math:`x = sin(\\frac{\\theta}{2}) u_{x}` - -:math:`y = sin(\\frac{\\theta}{2}) u_{y}` - -:math:`z = sin(\\frac{\\theta}{2}) u_{z}` - -For a quaternion to represent a rotation or orientation, it must be unit-length. -A quaternion representing a rotation :math:`p` resulting from applying a rotation :math:`r` to a rotation :math:`q`, i.e.: -:math:`p = rq`, -is also unit-length. - -References ----------- -.. [1] http://mathworld.wolfram.com/Quaternion.html -.. [2] http://mathworld.wolfram.com/HamiltonsRules.html -.. [3] https://github.com/matthew-brett/transforms3d/blob/master/transforms3d/quaternions.py -""" import math from ._algebra import allclose @@ -60,7 +11,7 @@ def quaternion_norm(q): Parameters ---------- - q : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + q : [float, float, float, float] | :class:`compas.geometry.Quaternion` Quaternion or sequence of four floats ``[w, x, y, z]``. Returns @@ -68,6 +19,14 @@ def quaternion_norm(q): float The length (euclidean norm) of a quaternion. + See Also + -------- + quaternion_is_unit + quaternion_unitize + quaternion_multiply + quaternion_canonize + quaternion_conjugate + References ---------- * Quaternion Norm: http://mathworld.wolfram.com/QuaternionNorm.html @@ -81,13 +40,22 @@ def quaternion_unitize(q): Parameters ---------- - q : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + q : [float, float, float, float] | :class:`compas.geometry.Quaternion` Quaternion or sequence of four floats ``[w, x, y, z]``. Returns ------- [float, float, float, float] Quaternion of length 1 as a list of four real values ``[nw, nx, ny, nz]``. + + See Also + -------- + quaternion_is_unit + quaternion_norm + quaternion_multiply + quaternion_canonize + quaternion_conjugate + """ n = quaternion_norm(q) if allclose([n], [0.0], ATOL): @@ -101,7 +69,7 @@ def quaternion_is_unit(q, tol=ATOL): Parameters ---------- - q : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + q : [float, float, float, float] | :class:`compas.geometry.Quaternion` Quaternion or sequence of four floats ``[w, x, y, z]``. tol : float, optional Requested decimal precision. @@ -111,6 +79,15 @@ def quaternion_is_unit(q, tol=ATOL): bool True if the quaternion is unit-length, and False if otherwise. + + See Also + -------- + quaternion_unitize + quaternion_norm + quaternion_multiply + quaternion_canonize + quaternion_conjugate + """ n = quaternion_norm(q) return allclose([n], [1.0], tol) @@ -121,9 +98,9 @@ def quaternion_multiply(r, q): Parameters ---------- - r : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + r : [float, float, float, float] | :class:`compas.geometry.Quaternion` Quaternion or sequence of four floats ``[w, x, y, z]``. - q : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + q : [float, float, float, float] | :class:`compas.geometry.Quaternion` Quaternion or sequence of four floats ``[w, x, y, z]``. Returns @@ -131,6 +108,14 @@ def quaternion_multiply(r, q): [float, float, float, float] Quaternion :math:`p = rq` as a list of four real values ``[pw, px, py, pz]``. + See Also + -------- + quaternion_is_unit + quaternion_norm + quaternion_unitize + quaternion_canonize + quaternion_conjugate + Notes ----- Multiplication of two quaternions :math:`p = rq` can be interpreted as applying rotation :math:`r` to an orientation :math:`q`, @@ -157,7 +142,7 @@ def quaternion_canonize(q): Parameters ---------- - q : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + q : [float, float, float, float] | :class:`compas.geometry.Quaternion` Quaternion or sequence of four floats ``[w, x, y, z]``. Returns @@ -165,6 +150,14 @@ def quaternion_canonize(q): [float, float, float, float] Quaternion in a canonic form as a list of four real values ``[cw, cx, cy, cz]``. + See Also + -------- + quaternion_is_unit + quaternion_norm + quaternion_unitize + quaternion_multiply + quaternion_conjugate + Notes ----- Canonic form means the scalar component is a non-negative number. @@ -180,7 +173,7 @@ def quaternion_conjugate(q): Parameters ---------- - q : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + q : [float, float, float, float] | :class:`compas.geometry.Quaternion` Quaternion or sequence of four floats ``[w, x, y, z]``. Returns @@ -188,6 +181,14 @@ def quaternion_conjugate(q): [float, float, float, float] Conjugate quaternion as a list of four real values ``[cw, cx, cy, cz]``. + See Also + -------- + quaternion_is_unit + quaternion_norm + quaternion_unitize + quaternion_multiply + quaternion_canonize + References ---------- * Quaternion Conjugate: http://mathworld.wolfram.com/QuaternionConjugate.html diff --git a/src/compas/geometry/_core/size.py b/src/compas/geometry/_core/size.py index 7536a8e985c..ba6e3a461f4 100644 --- a/src/compas/geometry/_core/size.py +++ b/src/compas/geometry/_core/size.py @@ -20,12 +20,58 @@ from .normals import normal_triangle_xy +def area_triangle(triangle): + """Compute the area of a triangle defined by three points. + + Parameters + ---------- + triangle : [point, point, point] | :class:`compas.geometry.Polygon` + XYZ coordinates of the corners of the triangle. + + Returns + ------- + float + The area of the triangle. + + See Also + -------- + area_triangle_xy + area_polygon + area_polygon_xy + + """ + return 0.5 * length_vector(normal_triangle(triangle, False)) + + +def area_triangle_xy(triangle): + """Compute the area of a triangle defined by three points lying in the XY-plane. + + Parameters + ---------- + triangle : [point, point, point] | :class:`compas.geometry.Polygon` + XY(Z) coordinates of the corners of the triangle. + + Returns + ------- + float + The area of the triangle. + + See Also + -------- + area_triangle + area_polygon + area_polygon_xy + + """ + return 0.5 * length_vector(normal_triangle_xy(triangle, False)) + + def area_polygon(polygon): """Compute the area of a polygon. Parameters ---------- - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` The XYZ coordinates of the vertices/corners of the polygon. The vertices are assumed to be in order. The polygon is assumed to be closed: @@ -36,9 +82,11 @@ def area_polygon(polygon): float The area of the polygon. - Examples + See Also -------- - >>> + area_polygon_xy + area_triangle + """ o = centroid_points(polygon) a = polygon[-1] @@ -64,7 +112,7 @@ def area_polygon_xy(polygon): Parameters ---------- - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` A sequence of XY(Z) coordinates of 2D or 3D points representing the locations of the corners of a polygon. The vertices are assumed to be in order. The polygon is assumed to be closed: @@ -75,6 +123,11 @@ def area_polygon_xy(polygon): float The area of the polygon. + See Also + -------- + area_polygon + area_triangle_xy + """ o = centroid_points_xy(polygon) u = subtract_vectors_xy(polygon[-1], o) @@ -87,46 +140,12 @@ def area_polygon_xy(polygon): return fabs(a) -def area_triangle(triangle): - """Compute the area of a triangle defined by three points. - - Parameters - ---------- - triangle : [point, point, point] | :class:`~compas.geometry.Polygon` - XYZ coordinates of the corners of the triangle. - - Returns - ------- - float - The area of the triangle. - - """ - return 0.5 * length_vector(normal_triangle(triangle, False)) - - -def area_triangle_xy(triangle): - """Compute the area of a triangle defined by three points lying in the XY-plane. - - Parameters - ---------- - triangle : [point, point, point] | :class:`~compas.geometry.Polygon` - XY(Z) coordinates of the corners of the triangle. - - Returns - ------- - float - The area of the triangle. - - """ - return 0.5 * length_vector(normal_triangle_xy(triangle, False)) - - def volume_polyhedron(polyhedron): r"""Compute the volume of a polyhedron represented by a closed mesh. Parameters ---------- - polyhedron : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[sequence[int]]] + polyhedron : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[sequence[int]]] The vertices and faces of the polyhedron. Returns @@ -134,6 +153,11 @@ def volume_polyhedron(polyhedron): float The volume of the polyhedron. + Warnings + -------- + The volume computed by this funtion is only correct if the polyhedron is convex, + has planar faces, and is positively oriented (all face normals point outwards). + Notes ----- This implementation is based on the divergence theorem, the fact that the @@ -151,11 +175,6 @@ def volume_polyhedron(polyhedron): &= \frac{1}{6} \sum_{i=0}^{N-1} a_{i} \cdot \hat n_{i} \end{align} - Warnings - -------- - The volume computed by this funtion is only correct if the polyhedron is convex, - has planar faces, and is positively oriented (all face normals point outwards). - References ---------- .. [1] Nurnberg, R. *Calculating the area and centroid of a polygon in 2d*. diff --git a/src/compas/geometry/_core/tangent.py b/src/compas/geometry/_core/tangent.py index 32da71412a5..6db30a2cd3c 100644 --- a/src/compas/geometry/_core/tangent.py +++ b/src/compas/geometry/_core/tangent.py @@ -10,9 +10,9 @@ def tangent_points_to_circle_xy(circle, point): Parameters ---------- - circle : [plane, float] | :class:`~compas.geometry.Circle` + circle : [plane, float] | :class:`compas.geometry.Circle` Plane and radius of the circle. - point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float] or [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of a point in the xy plane. Returns @@ -30,6 +30,7 @@ def tangent_points_to_circle_xy(circle, point): True >>> allclose(t2, [0.972, -0.236, 0.000], 1e-3) True + """ plane, R = circle center, _ = plane diff --git a/src/compas/geometry/_core/transformations.py b/src/compas/geometry/_core/transformations.py index dd185d80d42..f4bd054f4b8 100644 --- a/src/compas/geometry/_core/transformations.py +++ b/src/compas/geometry/_core/transformations.py @@ -43,9 +43,9 @@ def orthonormalize_axes(xaxis, yaxis): Parameters ---------- - xaxis: [float, float, float] | :class:`~compas.geometry.Vector` + xaxis: [float, float, float] | :class:`compas.geometry.Vector` The first axis. - yaxis: [float, float, float] | :class:`~compas.geometry.Vector` + yaxis: [float, float, float] | :class:`compas.geometry.Vector` The second axis. Returns @@ -86,7 +86,7 @@ def homogenize(xyz, w=1.0): Parameters ---------- - xyz : sequence[[float, float, float] | :class:`~compas.geometry.Point`] | sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + xyz : sequence[[float, float, float] | :class:`compas.geometry.Point`] | sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of points or vectors. w : float, optional Homogenisation parameter. @@ -139,7 +139,7 @@ def homogenize_and_flatten_frames(frames): Parameters ---------- - frames : sequence[[point, vector, vector] | :class:`~compas.geometry.Frame`] + frames : sequence[[point, vector, vector] | :class:`compas.geometry.Frame`] Returns ------- @@ -195,9 +195,9 @@ def transform_points(points, T): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points to be transformed. - T : list[list[float]] | :class:`~compas.geometry.Transformation` + T : list[list[float]] | :class:`compas.geometry.Transformation` The transformation to apply. Returns @@ -220,9 +220,9 @@ def transform_vectors(vectors, T): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors to be transformed. - T : list[list[float]] | :class:`~compas.geometry.Transformation` + T : list[list[float]] | :class:`compas.geometry.Transformation` The transformation to apply. Returns @@ -245,9 +245,9 @@ def transform_frames(frames, T): Parameters ---------- - frames : sequence[[point, vector, vector] | :class:`~compas.geometry.Frame`] + frames : sequence[[point, vector, vector] | :class:`compas.geometry.Frame`] A list of frames to be transformed. - T : list[list[float]] | :class:`~compas.geometry.Transformation` + T : list[list[float]] | :class:`compas.geometry.Transformation` The transformation to apply on the frames. Returns @@ -272,9 +272,9 @@ def world_to_local_coordinates(frame, xyz): Parameters ---------- - frame : [point, vector, vector] | :class:`~compas.geometry.Frame` + frame : [point, vector, vector] | :class:`compas.geometry.Frame` The local coordinate system. - xyz : array-like[[float, float, float] | :class:`~compas.geometry.Point`] + xyz : array-like[[float, float, float] | :class:`compas.geometry.Point`] The global coordinates of the points to convert. Returns @@ -302,9 +302,9 @@ def local_to_world_coordinates(frame, xyz): Parameters ---------- - frame : [point, vector, vector] | :class:`~compas.geometry.Frame` + frame : [point, vector, vector] | :class:`compas.geometry.Frame` The local coordinate system. - xyz : array-like[[float, float, float] | :class:`~compas.geometry.Point`] + xyz : array-like[[float, float, float] | :class:`compas.geometry.Point`] The global coordinates of the points to convert. Returns @@ -337,9 +337,9 @@ def translate_points(points, vector): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points. - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` A translation vector. Returns @@ -360,9 +360,9 @@ def translate_points_xy(points, vector): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points. - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` A translation vector. Returns @@ -388,7 +388,7 @@ def scale_points(points, scale): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points. scale : float A scaling factor. @@ -412,7 +412,7 @@ def scale_points_xy(points, scale): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points. scale : float A scaling factor. @@ -441,14 +441,14 @@ def rotate_points(points, angle, axis=None, origin=None): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points. angle : float The angle of rotation in radians. - axis : [float, float, float] | :class:`~compas.geometry.Vector`, optional + axis : [float, float, float] | :class:`compas.geometry.Vector`, optional The rotation axis. Default is ``[0.0, 0.0, 1.0]`` - origin : [float, float, float] | :class:`~compas.geometry.Point`, optional + origin : [float, float, float] | :class:`compas.geometry.Point`, optional The origin of the rotation axis. Default is ``[0.0, 0.0, 0.0]``. @@ -486,11 +486,11 @@ def rotate_points_xy(points, angle, origin=None): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points. angle : float The angle of rotation in radians. - origin : [float, float, float] | :class:`~compas.geometry.Point`, optional + origin : [float, float, float] | :class:`compas.geometry.Point`, optional The origin of the rotation axis. Default is ``[0.0, 0.0, 0.0]``. @@ -529,9 +529,9 @@ def mirror_vector_vector(v1, v2): Parameters ---------- - v1 : [float, float, float] | :class:`~compas.geometry.Vector` + v1 : [float, float, float] | :class:`compas.geometry.Vector` The vector. - v2 : [float, float, float] | :class:`~compas.geometry.Vector` + v2 : [float, float, float] | :class:`compas.geometry.Vector` The normalized vector as mirror axis Returns @@ -557,9 +557,9 @@ def mirror_point_point(point, mirror): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the point to mirror. - mirror : [float, float, float] | :class:`~compas.geometry.Point` + mirror : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the mirror point. Returns @@ -576,9 +576,9 @@ def mirror_point_point_xy(point, mirror): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the point to mirror. - mirror : [float, float, float] | :class:`~compas.geometry.Point` + mirror : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the mirror point. Returns @@ -595,9 +595,9 @@ def mirror_points_point(points, mirror): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] List of points. - mirror : [float, float, float] | :class:`~compas.geometry.Point` + mirror : [float, float, float] | :class:`compas.geometry.Point` The mirror point. Returns @@ -614,9 +614,9 @@ def mirror_points_point_xy(points, mirror): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] List of points with XY(Z) coordinates. - mirror : [float, float, float] | :class:`~compas.geometry.Point` + mirror : [float, float, float] | :class:`compas.geometry.Point` The XY(Z) coordinates of the mirror point. Returns @@ -633,9 +633,9 @@ def mirror_point_line(point, line): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the point to mirror. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the mirror line. Returns @@ -653,9 +653,9 @@ def mirror_point_line_xy(point, line): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the point to mirror. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the line. XY(Z) coordinates of the two points defining the mirror line. @@ -674,9 +674,9 @@ def mirror_points_line(points, line): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] List of points to mirror. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the mirror line. Returns @@ -693,9 +693,9 @@ def mirror_points_line_xy(points, line): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] List of points to mirror. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the mirror line. Returns @@ -714,7 +714,7 @@ def mirror_point_plane(point, plane): ---------- point : list[float] XYZ coordinates of mirror point. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` Base point and normal defining the mirror plane. Returns @@ -732,9 +732,9 @@ def mirror_points_plane(points, plane): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] List of points to mirror. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` Base point and normal defining the mirror plane. Returns @@ -758,9 +758,9 @@ def project_point_plane(point, plane): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the point. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` Base point and normal vector defining the projection plane. Returns @@ -800,9 +800,9 @@ def project_points_plane(points, plane): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] List of points. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` Base point and normal vector defining the projection plane. Returns @@ -823,9 +823,9 @@ def project_point_line(point, line): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the point. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the projection line. Returns @@ -856,9 +856,9 @@ def project_point_line_xy(point, line): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the point. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the projection line. Returns @@ -888,9 +888,9 @@ def project_points_line(points, line): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] XYZ coordinates of the points. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the projection line. Returns @@ -916,9 +916,9 @@ def project_points_line_xy(points, line): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the point. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the projection line. Returns @@ -949,9 +949,9 @@ def reflect_line_plane(line, plane, tol=1e-6): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the line. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` Base point and normal vector of the plane. tol : float, optional A tolerance for membership verification. @@ -1001,7 +1001,7 @@ def reflect_line_triangle(line, triangle, tol=1e-6): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the line. triangle : [point, point, point] The triangle vertices. @@ -1064,11 +1064,11 @@ def orient_points(points, reference_plane, target_plane): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`]s + points : sequence[[float, float, float] | :class:`compas.geometry.Point`]s XYZ coordinates of the points. - reference_plane : [point, vector] | :class:`~compas.geometry.Plane` + reference_plane : [point, vector] | :class:`compas.geometry.Plane` Base point and normal defining a reference plane. - target_plane : [point, vector] | :class:`~compas.geometry.Plane` + target_plane : [point, vector] | :class:`compas.geometry.Plane` Base point and normal defining a target plane. Returns diff --git a/src/compas/geometry/_core/transformations_numpy.py b/src/compas/geometry/_core/transformations_numpy.py index d0d6b5ad554..972fd892d41 100644 --- a/src/compas/geometry/_core/transformations_numpy.py +++ b/src/compas/geometry/_core/transformations_numpy.py @@ -14,9 +14,9 @@ def transform_points_numpy(points, T): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points to be transformed. - T : :class:`~compas.geometry.Transformation` | list[list[float]] + T : :class:`compas.geometry.Transformation` | list[list[float]] The transformation to apply. Returns @@ -42,9 +42,9 @@ def transform_vectors_numpy(vectors, T): Parameters ---------- - vectors : sequence[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : sequence[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors to be transformed. - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` The transformation to apply. Returns @@ -70,9 +70,9 @@ def transform_frames_numpy(frames, T): Parameters ---------- - frames : sequence[[point, vector, vector] | :class:`~compas.geometry.Frame`] + frames : sequence[[point, vector, vector] | :class:`compas.geometry.Frame`] A list of frames to be transformed. - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` The transformation to apply on the frames. Returns @@ -98,9 +98,9 @@ def world_to_local_coordinates_numpy(frame, xyz): Parameters ---------- - frame : [point, vector, vector] | :class:`~compas.geometry.Frame` + frame : [point, vector, vector] | :class:`compas.geometry.Frame` The local coordinate system. - xyz : array-like[[float, float, float] | :class:`~compas.geometry.Point`] + xyz : array-like[[float, float, float] | :class:`compas.geometry.Point`] The global coordinates of the points to convert. Returns @@ -131,9 +131,9 @@ def local_to_world_coordinates_numpy(frame, rst): Parameters ---------- - frame : [point, vector, vector] | :class:`~compas.geometry.Frame` + frame : [point, vector, vector] | :class:`compas.geometry.Frame` The local coordinate system. - rst : array-like[[float, float, float] | :class:`~compas.geometry.Point`] + rst : array-like[[float, float, float] | :class:`compas.geometry.Point`] The coordinates of the points wrt the local coordinate system. Returns @@ -174,7 +174,7 @@ def homogenize_numpy(data, w=1.0): Parameters ---------- - data : array_like[[float, float, float] | :class:`~compas.geometry.Point`] | array_like[[float, float, float] | :class:`~compas.geometry.Vector`] + data : array_like[[float, float, float] | :class:`compas.geometry.Point`] | array_like[[float, float, float] | :class:`compas.geometry.Vector`] The input data. w : float, optional The homogenization factor. @@ -232,7 +232,7 @@ def homogenize_and_flatten_frames_numpy(frames): Parameters ---------- - frames : array_like[[point, vector, vector] | :class:`~compas.geometry.Frame`] + frames : array_like[[point, vector, vector] | :class:`compas.geometry.Frame`] The input frames. Returns diff --git a/src/compas/geometry/bbox/bbox.py b/src/compas/geometry/bbox.py similarity index 100% rename from src/compas/geometry/bbox/bbox.py rename to src/compas/geometry/bbox.py diff --git a/src/compas/geometry/bbox/__init__.py b/src/compas/geometry/bbox/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/geometry/bbox/bbox_numpy.py b/src/compas/geometry/bbox_numpy.py similarity index 97% rename from src/compas/geometry/bbox/bbox_numpy.py rename to src/compas/geometry/bbox_numpy.py index 0732979442e..d67bbacdd5b 100644 --- a/src/compas/geometry/bbox/bbox_numpy.py +++ b/src/compas/geometry/bbox_numpy.py @@ -34,7 +34,7 @@ def oriented_bounding_box_numpy(points, tol=1e-12): Raises ------ - AssertionError + ValueError If the input data is not 3D. See Also @@ -76,7 +76,8 @@ def oriented_bounding_box_numpy(points, tol=1e-12): points = asarray(points) n, dim = points.shape - assert dim == 3, "The point coordinates should be 3D: %i" % dim + if dim != 3: + raise ValueError("The point coordinates should be 3D: %i" % dim) points = points[:, :3] @@ -141,7 +142,7 @@ def oriented_bounding_box_xy_numpy(points): Raises ------ - AssertionError + ValueError If the input data is not at least 2D. See Also @@ -153,7 +154,8 @@ def oriented_bounding_box_xy_numpy(points): points = asarray(points) n, dim = points.shape - assert dim >= 2, "The point coordinates should be at least 2D: %i" % dim + if dim < 2: + raise ValueError("The point coordinates should be at least 2D: %i" % dim) if dim == 2: temp = zeros((n, 3)) diff --git a/src/compas/geometry/bestfit/bestfit.py b/src/compas/geometry/bestfit.py similarity index 98% rename from src/compas/geometry/bestfit/bestfit.py rename to src/compas/geometry/bestfit.py index 53ecce07a79..84e92a7e0a9 100644 --- a/src/compas/geometry/bestfit/bestfit.py +++ b/src/compas/geometry/bestfit.py @@ -40,10 +40,6 @@ def bestfit_plane(points): .. [ernerfeldt2015] Ernerfeldt, E. *Fitting a plane to many points in 3D*. Available at: http://www.ilikebigbits.com/blog/2015/3/2/plane-from-points - Examples - -------- - >>> - """ centroid = centroid_points(points) diff --git a/src/compas/geometry/bestfit/__init__.py b/src/compas/geometry/bestfit/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/geometry/bestfit/bestfit_numpy.py b/src/compas/geometry/bestfit_numpy.py similarity index 98% rename from src/compas/geometry/bestfit/bestfit_numpy.py rename to src/compas/geometry/bestfit_numpy.py index 08ad03964d2..a513014df47 100644 --- a/src/compas/geometry/bestfit/bestfit_numpy.py +++ b/src/compas/geometry/bestfit_numpy.py @@ -36,10 +36,6 @@ def bestfit_line_numpy(points): :func:`compas.geometry.bestfit_plane_numpy`, :func:`compas.geometry.bestfit_frame_numpy` :func:`compas.geometry.bestfit_circle_numpy`, :func:`compas.geometry.bestfit_sphere_numpy` - Examples - -------- - >>> - """ o, uvw, _ = pca_numpy(points) return o, uvw[0] @@ -73,10 +69,6 @@ def bestfit_plane_numpy(points): :func:`compas.geometry.bestfit_circle_numpy`, :func:`compas.geometry.bestfit_sphere_numpy` :func:`compas.geometry.bestfit_plane` - Examples - -------- - >>> - """ o, uvw, _ = pca_numpy(points) return o, uvw[2] @@ -111,10 +103,6 @@ def bestfit_frame_numpy(points): :func:`compas.geometry.bestfit_line_numpy`, :func:`compas.geometry.bestfit_plane_numpy` :func:`compas.geometry.bestfit_circle_numpy`, :func:`compas.geometry.bestfit_sphere_numpy` - Examples - -------- - >>> - """ o, uvw, _ = pca_numpy(points) return o, uvw[0], uvw[1] @@ -166,10 +154,6 @@ def bestfit_circle_numpy(points): .. [1] Scipy. *Least squares circle*. Available at: http://scipy-cookbook.readthedocs.io/items/Least_Squares_Circle.html. - Examples - -------- - >>> - """ o, uvw, _ = pca_numpy(points) frame = [o, uvw[0], uvw[1]] diff --git a/src/compas/geometry/booleans/__init__.py b/src/compas/geometry/booleans.py similarity index 89% rename from src/compas/geometry/booleans/__init__.py rename to src/compas/geometry/booleans.py index e7fe55a862f..518a012d50d 100644 --- a/src/compas/geometry/booleans/__init__.py +++ b/src/compas/geometry/booleans.py @@ -24,8 +24,8 @@ def boolean_union_mesh_mesh(A, B): See Also -------- - :func:`compas.geometry.boolean_difference_mesh_mesh` - :func:`compas.geometry.boolean_intersection_mesh_mesh` + boolean_difference_mesh_mesh + boolean_intersection_mesh_mesh Notes ----- @@ -62,6 +62,9 @@ def boolean_union_mesh_mesh(A, B): ) +boolean_union_mesh_mesh.__pluggable__ = True + + @pluggable(category="booleans") def boolean_difference_mesh_mesh(A, B): """Compute the boolean difference of two triangle meshes. @@ -80,8 +83,8 @@ def boolean_difference_mesh_mesh(A, B): See Also -------- - :func:`compas.geometry.boolean_union_mesh_mesh` - :func:`compas.geometry.boolean_intersection_mesh_mesh` + boolean_union_mesh_mesh + boolean_intersection_mesh_mesh Notes ----- @@ -96,6 +99,9 @@ def boolean_difference_mesh_mesh(A, B): ) +boolean_difference_mesh_mesh.__pluggable__ = True + + @pluggable(category="booleans") def boolean_intersection_mesh_mesh(A, B): """Compute the boolean intersection of two triangle meshes. @@ -114,8 +120,8 @@ def boolean_intersection_mesh_mesh(A, B): See Also -------- - :func:`compas.geometry.boolean_union_mesh_mesh` - :func:`compas.geometry.boolean_difference_mesh_mesh` + boolean_union_mesh_mesh + boolean_difference_mesh_mesh Notes ----- @@ -130,6 +136,9 @@ def boolean_intersection_mesh_mesh(A, B): ) +boolean_intersection_mesh_mesh.__pluggable__ = True + + @pluggable(category="booleans") def boolean_union_polygon_polygon(A, B): """Compute the boolean union of two polygons. @@ -153,9 +162,9 @@ def boolean_union_polygon_polygon(A, B): See Also -------- - :func:`compas.geometry.boolean_difference_polygon_polygon` - :func:`compas.geometry.boolean_intersection_polygon_polygon` - :func:`compas.geometry.boolean_symmetric_difference_polygon_polygon` + boolean_difference_polygon_polygon + boolean_intersection_polygon_polygon + boolean_symmetric_difference_polygon_polygon Notes ----- @@ -170,6 +179,9 @@ def boolean_union_polygon_polygon(A, B): ) +boolean_union_polygon_polygon.__pluggable__ = True + + @pluggable(category="booleans") def boolean_difference_polygon_polygon(A, B): """Compute the boolean difference of two polygons. @@ -193,9 +205,9 @@ def boolean_difference_polygon_polygon(A, B): See Also -------- - :func:`compas.geometry.boolean_union_polygon_polygon` - :func:`compas.geometry.boolean_intersection_polygon_polygon` - :func:`compas.geometry.boolean_symmetric_difference_polygon_polygon` + boolean_union_polygon_polygon + boolean_intersection_polygon_polygon + boolean_symmetric_difference_polygon_polygon Notes ----- @@ -210,6 +222,9 @@ def boolean_difference_polygon_polygon(A, B): ) +boolean_difference_polygon_polygon.__pluggable__ = True + + @pluggable(category="booleans") def boolean_symmetric_difference_polygon_polygon(A, B): """Compute the boolean symmetric difference of two polygons. @@ -233,9 +248,9 @@ def boolean_symmetric_difference_polygon_polygon(A, B): See Also -------- - :func:`compas.geometry.boolean_union_polygon_polygon` - :func:`compas.geometry.boolean_intersection_polygon_polygon` - :func:`compas.geometry.boolean_difference_polygon_polygon` + boolean_union_polygon_polygon + boolean_intersection_polygon_polygon + boolean_difference_polygon_polygon Notes ----- @@ -250,6 +265,9 @@ def boolean_symmetric_difference_polygon_polygon(A, B): ) +boolean_symmetric_difference_polygon_polygon.__pluggable__ = True + + @pluggable(category="booleans") def boolean_intersection_polygon_polygon(A, B): """Compute the boolean intersection of two polygons. @@ -273,9 +291,9 @@ def boolean_intersection_polygon_polygon(A, B): See Also -------- - :func:`compas.geometry.boolean_union_polygon_polygon` - :func:`compas.geometry.boolean_difference_polygon_polygon` - :func:`compas.geometry.boolean_symmetric_difference_polygon_polygon` + boolean_union_polygon_polygon + boolean_difference_polygon_polygon + boolean_symmetric_difference_polygon_polygon Notes ----- @@ -288,3 +306,6 @@ def boolean_intersection_polygon_polygon(A, B): raise PluginNotInstalledError( "No plugin was found for the boolean_intersection_polygon_polygon pluggable. Installing Shapely should solve the problem." ) + + +boolean_intersection_polygon_polygon.__pluggable__ = True diff --git a/src/compas/geometry/booleans/booleans_shapely.py b/src/compas/geometry/booleans_shapely.py similarity index 86% rename from src/compas/geometry/booleans/booleans_shapely.py rename to src/compas/geometry/booleans_shapely.py index 068826a3167..dbcd130a086 100644 --- a/src/compas/geometry/booleans/booleans_shapely.py +++ b/src/compas/geometry/booleans_shapely.py @@ -23,6 +23,12 @@ def boolean_union_polygon_polygon(A, B): list[point] The vertices of the boolean union. + See Also + -------- + boolean_difference_polygon_polygon + boolean_symmetric_difference_polygon_polygon + boolean_intersection_polygon_polygon + """ a = Polygon([point[:2] for point in A.points]) b = Polygon([point[:2] for point in B.points]) @@ -53,6 +59,12 @@ def boolean_difference_polygon_polygon(A, B): list[point] The vertices of the boolean difference. + See Also + -------- + boolean_union_polygon_polygon + boolean_symmetric_difference_polygon_polygon + boolean_intersection_polygon_polygon + """ a = Polygon([point[:2] for point in A.points]) b = Polygon([point[:2] for point in B.points]) @@ -83,6 +95,12 @@ def boolean_symmetric_difference_polygon_polygon(A, B): list[list[point]] The lists of vertices of the boolean symmetric difference. + See Also + -------- + boolean_union_polygon_polygon + boolean_difference_polygon_polygon + boolean_intersection_polygon_polygon + """ a = Polygon([point[:2] for point in A.points]) b = Polygon([point[:2] for point in B.points]) @@ -113,6 +131,12 @@ def boolean_intersection_polygon_polygon(A, B): list[point] The vertices of the boolean difference. + See Also + -------- + boolean_union_polygon_polygon + boolean_difference_polygon_polygon + boolean_symmetric_difference_polygon_polygon + """ a = Polygon([point[:2] for point in A.points]) b = Polygon([point[:2] for point in B.points]) diff --git a/src/compas/geometry/brep/brep.py b/src/compas/geometry/brep/brep.py index 3f78e895e58..de1ddf753a8 100644 --- a/src/compas/geometry/brep/brep.py +++ b/src/compas/geometry/brep/brep.py @@ -163,29 +163,29 @@ class Brep(Geometry): Attributes ---------- - vertices : list[:class:`~compas.geometry.BrepVertex`], read-only + vertices : list[:class:`compas.geometry.BrepVertex`], read-only The vertices of the Brep. - edges : list[:class:`~compas.geometry.BrepEdge`], read-only + edges : list[:class:`compas.geometry.BrepEdge`], read-only The edges of the Brep. - trims : list[:class:`~compas.geometry.BrepTrim`], read-only + trims : list[:class:`compas.geometry.BrepTrim`], read-only The trims of the Brep. - loops : list[:class:`~compas.geometry.BrepLoop`], read-only + loops : list[:class:`compas.geometry.BrepLoop`], read-only The loops of the Brep. - faces : list[:class:`~compas.geometry.BrepFace`], read-only + faces : list[:class:`compas.geometry.BrepFace`], read-only The faces of the Brep. - frame : :class:`~compas.geometry.Frame`, read-only + frame : :class:`compas.geometry.Frame`, read-only The local coordinate system of the Brep. area : float, read-only The surface area of the Brep. volume : float, read-only The volume of the regions contained by the Brep. - solids : list[:class:`~compas.geometry.Brep`], read-only + solids : list[:class:`compas.geometry.Brep`], read-only The solids of this brep. - shells : list[:class:`~compas.geometry.Brep`], read-only + shells : list[:class:`compas.geometry.Brep`], read-only The shells of this brep. - points : list[:class:`~compas.geometry.Point`], read-only + points : list[:class:`compas.geometry.Point`], read-only The points of this brep. - centroid : :class:`~compas.geometry.Point`, read-only + centroid : :class:`compas.geometry.Point`, read-only The centroid of this brep. is_valid : bool, read-only True if this brep is valid, False otherwise @@ -387,11 +387,11 @@ def from_box(cls, box): Parameters ---------- - box : :class:`~compas.geometry.Box` + box : :class:`compas.geometry.Box` Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_box(box) @@ -402,11 +402,11 @@ def from_brepfaces(cls, faces): Parameters ---------- - faces : list[:class:`~compas.geometry.BrepFace`] + faces : list[:class:`compas.geometry.BrepFace`] Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_brepfaces(faces) @@ -417,11 +417,11 @@ def from_cone(cls, cone): Parameters ---------- - cone : :class:`~compas.geometry.Cone` + cone : :class:`compas.geometry.Cone` Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_cone(cone) @@ -432,11 +432,11 @@ def from_curves(cls, curves): Parameters ---------- - curves : list[:class:`~compas.geometry.NurbsCurve`] + curves : list[:class:`compas.geometry.NurbsCurve`] Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_curves(curves) @@ -447,11 +447,11 @@ def from_cylinder(cls, cylinder): Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + cylinder : :class:`compas.geometry.Cylinder` Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_cylinder(cylinder) @@ -462,14 +462,14 @@ def from_extrusion(cls, curve, vector): Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` The curve to extrude - vector : :class:`~compas.geometry.Vector` + vector : :class:`compas.geometry.Vector` The vector to extrude the curve by Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_extrusion(curve, vector) @@ -484,7 +484,7 @@ def from_iges(cls, filename): Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_iges(filename) @@ -495,11 +495,11 @@ def from_loft(cls, curves): Parameters ---------- - curves : list[:class:`~compas.geometry.Curve`] + curves : list[:class:`compas.geometry.Curve`] Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_loft(curves) @@ -510,11 +510,11 @@ def from_mesh(cls, mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_mesh(mesh) @@ -530,7 +530,7 @@ def from_native(cls, native_brep): Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_native(native_brep) @@ -540,7 +540,7 @@ def from_pipe(cls, curve, radius, thickness=None): Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` The curve to extrude radius : float The radius of the pipe. @@ -550,7 +550,7 @@ def from_pipe(cls, curve, radius, thickness=None): Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_pipe(curve, radius, thickness=thickness) @@ -561,11 +561,11 @@ def from_polygons(cls, polygons): Parameters ---------- - polygons : list[:class:`~compas.geometry.Polygon`] + polygons : list[:class:`compas.geometry.Polygon`] Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_polygons(polygons) @@ -576,11 +576,11 @@ def from_sphere(cls, sphere): Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + sphere : :class:`compas.geometry.Sphere` Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_sphere(sphere) @@ -595,7 +595,7 @@ def from_step(cls, filename): Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_step(filename) @@ -606,14 +606,14 @@ def from_sweep(cls, profile, path): Parameters ---------- - profile : :class:`~compas.geometry.BrepEdge` or :class:`~compas.geometry.BrepFace` + profile : :class:`compas.geometry.BrepEdge` or :class:`compas.geometry.BrepFace` the profile to sweep. Either an edge or a face. - path : :class:`~compas.geometry.BrepLoop` + path : :class:`compas.geometry.BrepLoop` the path to sweep along Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_sweep(profile, path) @@ -624,11 +624,11 @@ def from_torus(cls, torus): Parameters ---------- - torus : :class:`~compas.geometry.Torus` + torus : :class:`compas.geometry.Torus` Returns ------- - :class:`~compas.geometry.BRep` + :class:`compas.geometry.BRep` """ return from_torus(torus) @@ -643,12 +643,12 @@ def from_boolean_difference(cls, brep_a, brep_b): Parameters ---------- - brep_a : :class:`~compas.geometry.Brep` - brep_b : :class:`~compas.geometry.Brep` + brep_a : :class:`compas.geometry.Brep` + brep_b : :class:`compas.geometry.Brep` Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_boolean_difference(brep_a, brep_b) @@ -659,12 +659,12 @@ def from_boolean_intersection(cls, brep_a, brep_b): Parameters ---------- - brep_a : :class:`~compas.geometry.Brep` - brep_b : :class:`~compas.geometry.Brep` + brep_a : :class:`compas.geometry.Brep` + brep_b : :class:`compas.geometry.Brep` Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_boolean_intersection(brep_a, brep_b) @@ -675,12 +675,12 @@ def from_boolean_union(cls, brep_a, brep_b): Parameters ---------- - brep_a : :class:`~compas.geometry.Brep` - brep_b : :class:`~compas.geometry.Brep` + brep_a : :class:`compas.geometry.Brep` + brep_b : :class:`compas.geometry.Brep` Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` """ return from_boolean_union(brep_a, brep_b) @@ -690,12 +690,12 @@ def __sub__(self, other): Parameters ---------- - other : :class:`~compas.geometry.Brep` + other : :class:`compas.geometry.Brep` The other Brep to create a union with. Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` The Brep resulting from the difference operation. """ @@ -709,12 +709,12 @@ def __and__(self, other): Parameters ---------- - other : :class:`~compas.geometry.Brep` + other : :class:`compas.geometry.Brep` The other Brep to create a union with. Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` The Brep resulting from the intersection operation. """ @@ -728,12 +728,12 @@ def __add__(self, other): Parameters ---------- - other : :class:`~compas.geometry.Brep` + other : :class:`compas.geometry.Brep` The other Brep to create a union with. Returns ------- - :class:`~compas.geometry.Brep` + :class:`compas.geometry.Brep` The Brep resulting from the union operation. """ @@ -786,7 +786,7 @@ def to_tesselation(self, linear_deflection=LINEAR_DEFLECTION): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` """ raise NotImplementedError @@ -803,7 +803,7 @@ def to_meshes(self, u=16, v=16): Returns ------- - list[:class:`~compas.datastructures.Mesh`] + list[:class:`compas.datastructures.Mesh`] """ raise NotImplementedError @@ -818,7 +818,7 @@ def to_viewmesh(self, precision): Returns ------- - :class:`~compas.datastructure.Mesh` + :class:`compas.datastructure.Mesh` """ raise NotImplementedError @@ -832,11 +832,11 @@ def vertex_neighbors(self, vertex): Parameters ---------- - vertex : :class:`~compas.geometry.BrepVertex` + vertex : :class:`compas.geometry.BrepVertex` Returns ------- - list[:class:`~compas.geometry.BrepVertex`] + list[:class:`compas.geometry.BrepVertex`] """ raise NotImplementedError @@ -846,11 +846,11 @@ def vertex_edges(self, vertex): Parameters ---------- - vertex : :class:`~compas.geometry.BrepVertex` + vertex : :class:`compas.geometry.BrepVertex` Returns ------- - list[:class:`~compas.geometry.BrepEdge`] + list[:class:`compas.geometry.BrepEdge`] """ raise NotImplementedError @@ -860,11 +860,11 @@ def vertex_faces(self, vertex): Parameters ---------- - vertex : :class:`~compas.geometry.BrepVertex` + vertex : :class:`compas.geometry.BrepVertex` Returns ------- - list[:class:`~compas.geometry.BrepFace`] + list[:class:`compas.geometry.BrepFace`] """ raise NotImplementedError @@ -878,7 +878,7 @@ def trim(self, trimming_plane, tolerance): Parameters ---------- - trimming_plane : :class:`~compas.geometry.Frame` + trimming_plane : :class:`compas.geometry.Frame` defines the trimming plane tolerance: float the tolerance to use when trimming @@ -965,12 +965,12 @@ def contours(self, planes): Parameters ---------- - planes : list[:class:`~compas.geometry.Plane`] + planes : list[:class:`compas.geometry.Plane`] The slicing planes. Returns ------- - list[list[:class:`~compas.geometry.Polyline`]] + list[list[:class:`compas.geometry.Polyline`]] A list of polylines per plane. """ @@ -985,7 +985,7 @@ def slice(self, plane): Returns ------- - :class:`~compas.geometry.BrepFace` + :class:`compas.geometry.BrepFace` """ @@ -994,12 +994,12 @@ def split(self, cutter): Parameters ---------- - cutter : :class:`~compas.geomtery.Brep` + cutter : :class:`compas.geomtery.Brep` Another Brep to use as a cutter. Returns ------- - list[:class:`~compas.geometry.Brep`] + list[:class:`compas.geometry.Brep`] """ raise NotImplementedError @@ -1009,7 +1009,7 @@ def overlap(self, other, deflection=LINEAR_DEFLECTION, tolerance=0.0): Parameters ---------- - other : :class:`~compas.geometry.Brep` + other : :class:`compas.geometry.Brep` The other Brep. deflection : float, optional Allowable deflection for mesh generation used for proximity detection. @@ -1018,7 +1018,7 @@ def overlap(self, other, deflection=LINEAR_DEFLECTION, tolerance=0.0): Returns ------- - tuple[list[:class:`~compas.geometry.BrepFace`]] + tuple[list[:class:`compas.geometry.BrepFace`]] """ raise NotImplementedError diff --git a/src/compas/geometry/brep/edge.py b/src/compas/geometry/brep/edge.py index 8fe64bdeb52..628e71c6552 100644 --- a/src/compas/geometry/brep/edge.py +++ b/src/compas/geometry/brep/edge.py @@ -24,13 +24,13 @@ class BrepEdge(Data): Returns True if this edge is of another shape, False otherwise. is_valid : bool, read-only Returns True if this edge is valid, False otherwise. - vertices : list[:class:`~compas.geometry.BrepVertex`], read-only + vertices : list[:class:`compas.geometry.BrepVertex`], read-only Gets the list of vertices which compound this edge. - first_vertex : :class:`~compas.geometry.BrepVertex` + first_vertex : :class:`compas.geometry.BrepVertex` Returns the first vertex of this edge. - last_vertex : :class:`~compas.geometry.BrepVertex` + last_vertex : :class:`compas.geometry.BrepVertex` Returns the last vertex of this edge. - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` Returns the curve geometry of this edge. """ @@ -101,11 +101,11 @@ def from_vertices(cls, vertices): Parameters ---------- - vertices : list[:class:`~compas.geometry.BrepVertex`] + vertices : list[:class:`compas.geometry.BrepVertex`] Returns ------- - :class:`~compas.geometry.BrepVertex` + :class:`compas.geometry.BrepVertex` """ raise NotImplementedError @@ -116,11 +116,11 @@ def from_points(cls, points): Parameters ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] Returns ------- - :class:`~compas.geometry.BrepVertex` + :class:`compas.geometry.BrepVertex` """ raise NotImplementedError @@ -131,11 +131,11 @@ def from_line(cls, line): Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` Returns ------- - :class:`~compas.geometry.BrepEdge` + :class:`compas.geometry.BrepEdge` """ raise NotImplementedError @@ -146,11 +146,11 @@ def from_circle(cls, circle): Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` Returns ------- - :class:`~compas.geometry.BrepEdge` + :class:`compas.geometry.BrepEdge` """ raise NotImplementedError @@ -161,11 +161,11 @@ def from_ellipse(cls, ellipse): Parameters ---------- - ellipse : :class:`~compas.geometry.Ellipse` + ellipse : :class:`compas.geometry.Ellipse` Returns ------- - :class:`~compas.geometry.BrepEdge` + :class:`compas.geometry.BrepEdge` """ raise NotImplementedError @@ -176,11 +176,11 @@ def from_curve(cls, curve): Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` Returns ------- - :class:`~compas.geometry.BrepEdge` + :class:`compas.geometry.BrepEdge` """ raise NotImplementedError @@ -194,7 +194,7 @@ def to_line(self): Returns ------- - :class:`~compas.geometry.Line` + :class:`compas.geometry.Line` """ raise NotImplementedError @@ -204,7 +204,7 @@ def to_circle(self): Returns ------- - :class:`~compas.geometry.Circle` + :class:`compas.geometry.Circle` """ raise NotImplementedError @@ -214,7 +214,7 @@ def to_ellipse(self): Returns ------- - :class:`~compas.geometry.Ellipse` + :class:`compas.geometry.Ellipse` """ raise NotImplementedError @@ -244,7 +244,7 @@ def to_bezier(self): Returns ------- - :class:`~compas.geometry.Bezier` + :class:`compas.geometry.Bezier` """ raise NotImplementedError @@ -264,7 +264,7 @@ def to_curve(self): Returns ------- - :class:`~compas.geometry.Curve` + :class:`compas.geometry.Curve` """ raise NotImplementedError diff --git a/src/compas/geometry/brep/face.py b/src/compas/geometry/brep/face.py index 5cd2551f998..1a6f6c2d2ca 100644 --- a/src/compas/geometry/brep/face.py +++ b/src/compas/geometry/brep/face.py @@ -18,19 +18,19 @@ class BrepFace(Data): Returns True if this face is a cone, False otherwise. is_bspline : bool, read-only Returns True if this face is a bspline, False otherwise. - vertices : list[:class:`~compas.geometry.BrepVertex`], read-only + vertices : list[:class:`compas.geometry.BrepVertex`], read-only Returns a list of the vertices comprising this face. - edges : list[:class:`~compas.geometry.BrepEdge`], read-only + edges : list[:class:`compas.geometry.BrepEdge`], read-only Returns a list of the edges comprising this face. - loops : list[:class:`~compas.geometry.BrepLoop`], read-only + loops : list[:class:`compas.geometry.BrepLoop`], read-only Returns a list of the loops comprising this face. - surface : :class:`~compas.geometry.Surface`, read-only + surface : :class:`compas.geometry.Surface`, read-only Returns the geometry of this face as a surface. - nurbssurface : :class:`~compas.geometry.NurbsSurface`, read-only + nurbssurface : :class:`compas.geometry.NurbsSurface`, read-only Returns the geometry of this face as a NURBS surface. area : float, read-only Returns the area of this face's geometry. - centroid : :class:`~compas.geometry.Point`, read-only + centroid : :class:`compas.geometry.Point`, read-only Returns the centroid of this face's geometry. is_valid : bool, read-only Return True if this face is valid, False otherwise. @@ -51,7 +51,6 @@ def is_cylinder(self): @property def is_sphere(self): - raise NotImplementedError @property @@ -108,11 +107,11 @@ def from_plane(cls, plane): Parameters ---------- - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` Returns ------- - :class:`~compas.geometry.BrepFace` + :class:`compas.geometry.BrepFace` """ raise NotImplementedError @@ -123,11 +122,11 @@ def from_cylinder(cls): Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + cylinder : :class:`compas.geometry.Cylinder` Returns ------- - :class:`~compas.geometry.BrepFace` + :class:`compas.geometry.BrepFace` """ raise NotImplementedError @@ -138,11 +137,11 @@ def from_cone(cls, cone): Parameters ---------- - cone : :class:`~compas.geometry.Cone` + cone : :class:`compas.geometry.Cone` Returns ------- - :class:`~compas.geometry.BrepFace` + :class:`compas.geometry.BrepFace` """ raise NotImplementedError @@ -153,11 +152,11 @@ def from_sphere(cls, sphere): Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + sphere : :class:`compas.geometry.Sphere` Returns ------- - :class:`~compas.geometry.BrepFace` + :class:`compas.geometry.BrepFace` """ raise NotImplementedError @@ -168,11 +167,11 @@ def from_torus(cls, torus): Parameters ---------- - torus : :class:`~compas.geometry.Torus` + torus : :class:`compas.geometry.Torus` Returns ------- - :class:`~compas.geometry.BrepFace` + :class:`compas.geometry.BrepFace` """ raise NotImplementedError @@ -183,11 +182,11 @@ def from_surface(cls, surface): Parameters ---------- - surface : :class:`~compas.geometry.Surface` + surface : :class:`compas.geometry.Surface` Returns ------- - :class:`~compas.geometry.BrepFace` + :class:`compas.geometry.BrepFace` """ raise NotImplementedError diff --git a/src/compas/geometry/brep/loop.py b/src/compas/geometry/brep/loop.py index 60f0fa6a0f2..1aa7405abf4 100644 --- a/src/compas/geometry/brep/loop.py +++ b/src/compas/geometry/brep/loop.py @@ -8,9 +8,9 @@ class BrepLoop(Data): ---------- is_valid : bool, read-only Returns True if this loop is valid, False otherwise. - vertices : list[:class:`~compas.geometry.BrepVertex`], read-only + vertices : list[:class:`compas.geometry.BrepVertex`], read-only Returns the list of vertices associated with this loop. - edges : list[:class:`~compas.geometry.BrepEdge`], read-only + edges : list[:class:`compas.geometry.BrepEdge`], read-only Returns the list of deges associated with this loop. """ @@ -41,11 +41,11 @@ def from_edges(cls, edges): Parameters ---------- - edges : list[:class:`~compas.geometry.BrepEdge`] + edges : list[:class:`compas.geometry.BrepEdge`] Returns ------- - :class:`~compas.geometry.BrepLoop` + :class:`compas.geometry.BrepLoop` """ raise NotImplementedError @@ -56,11 +56,11 @@ def from_polyline(cls, polyline): Parameters ---------- - polyline : :class:`~compas.geometry.Polyline` + polyline : :class:`compas.geometry.Polyline` Returns ------- - :class:`~compas.geometry.BrepLoop` + :class:`compas.geometry.BrepLoop` """ raise NotImplementedError @@ -71,11 +71,11 @@ def from_polygon(cls, polygon): Parameters ---------- - polygon : :class:`~compas.geometry.Polygon` + polygon : :class:`compas.geometry.Polygon` Returns ------- - :class:`~compas.geometry.BrepLoop` + :class:`compas.geometry.BrepLoop` """ raise NotImplementedError diff --git a/src/compas/geometry/brep/trim.py b/src/compas/geometry/brep/trim.py index d2ef2de5dde..3bc50667eb3 100644 --- a/src/compas/geometry/brep/trim.py +++ b/src/compas/geometry/brep/trim.py @@ -18,7 +18,7 @@ class BrepTrim(Data): Attributes ---------- - curve : :class:`~compas.geometry.NurbsCurve`, read_only + curve : :class:`compas.geometry.NurbsCurve`, read_only Returns the geometry for this trim as a 2d curve. iso_status : literal(NONE|X|Y|WEST|SOUTH|EAST|NORTH) The isoparametric curve direction on the surface. diff --git a/src/compas/geometry/brep/vertex.py b/src/compas/geometry/brep/vertex.py index 67c63b0225d..186713aec53 100644 --- a/src/compas/geometry/brep/vertex.py +++ b/src/compas/geometry/brep/vertex.py @@ -6,7 +6,7 @@ class BrepVertex(Data): Attributes ---------- - point : :class:`~compas.geometry.Point`, read_only + point : :class:`compas.geometry.Point`, read_only Returns the geometry of this vertex as a 3D point """ @@ -29,12 +29,12 @@ def from_point(cls, point): Parameters ---------- - point: :class:`~compas.geometry.Point` + point: :class:`compas.geometry.Point` The point to create a vertex from Returns ------- - :class:`~compas.geometry.BrepVertex` + :class:`compas.geometry.BrepVertex` The created vertex """ raise NotImplementedError diff --git a/src/compas/geometry/curves/arc.py b/src/compas/geometry/curves/arc.py index 83ecdc678f6..9ae50c5bb2c 100644 --- a/src/compas/geometry/curves/arc.py +++ b/src/compas/geometry/curves/arc.py @@ -35,13 +35,13 @@ class Arc(Curve): The angle in radians of the start of this Arc. end_angle : float The angle in radians of the end of this Arc. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional Local coordinate system of the arc. Defaults to the world XY plane. Attributes ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` The coordinate frame of the arc. transformation : :class:`Transformation`, read-only The transformation from the local coordinate system of the arc (:attr:`frame`) to the world coordinate system. @@ -51,9 +51,9 @@ class Arc(Curve): The start angle of the arc. end_angle : float The end angle of the arc. - circle : :class:`~compas.geometry.Circle`, read-only + circle : :class:`compas.geometry.Circle`, read-only The underlying circle. - plane : :class:`~compas.geometry.Plane`, read-only + plane : :class:`compas.geometry.Plane`, read-only The plane of the arc. diameter : float, read-only The diameter of the underlying circle. @@ -272,7 +272,7 @@ def from_circle(cls, circle, start_angle, end_angle): Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` The frame and radius of this circle will be used to create an Arc. start_angle : float The start angle in radians. @@ -281,7 +281,7 @@ def from_circle(cls, circle, start_angle, end_angle): Returns ------- - :class:`~compas.geometry.Arc` + :class:`compas.geometry.Arc` """ return cls( @@ -358,7 +358,7 @@ def normal_at(self, t, world=True): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` Raises ------ @@ -399,7 +399,7 @@ def tangent_at(self, t, world=True): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The tangent on the circle at the specified parameter. Raises diff --git a/src/compas/geometry/curves/bezier.py b/src/compas/geometry/curves/bezier.py index a2a4bd6a610..7896e227c64 100644 --- a/src/compas/geometry/curves/bezier.py +++ b/src/compas/geometry/curves/bezier.py @@ -129,11 +129,11 @@ class Bezier(Curve): Attributes ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The control points. degree : int, read-only The degree of the curve. - frame : :class:`~compas.geometry.Frame`, read-only + frame : :class:`compas.geometry.Frame`, read-only The frame of the curve. This is always the world coordinate system. @@ -231,7 +231,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` The transformation. Returns @@ -257,7 +257,7 @@ def point_at(self, t): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` the corresponding point on the curve. See Also @@ -290,7 +290,7 @@ def tangent_at(self, t): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The corresponding tangent vector. See Also @@ -321,7 +321,7 @@ def normal_at(self, t): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The corresponding normal vector. See Also diff --git a/src/compas/geometry/curves/circle.py b/src/compas/geometry/curves/circle.py index 04109bb5410..2bb1d015c95 100644 --- a/src/compas/geometry/curves/circle.py +++ b/src/compas/geometry/curves/circle.py @@ -27,17 +27,17 @@ class Circle(Conic): ---------- radius : float The radius of the circle. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The coordinate frame of the circle. The default value is ``None``, in which case the world coordinate system is used. Attributes ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` The coordinate frame of the circle. transformation : :class:`Transformation`, read-only The transformation from the local coordinate system of the circle (:attr:`frame`) to the world coordinate system. - center : :class:`~compas.geometry.Point` + center : :class:`compas.geometry.Point` The center of the circle. radius : float The radius of the circle. @@ -184,14 +184,14 @@ def from_point_and_radius(cls, point, radius): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The center of the circle. radius : float The radius of the circle. Returns ------- - :class:`~compas.geometry.Circle` + :class:`compas.geometry.Circle` The constructed circle. See Also @@ -208,14 +208,14 @@ def from_plane_and_radius(cls, plane, radius): Parameters ---------- - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` The plane of the circle. radius : float The radius of the circle. Returns ------- - :class:`~compas.geometry.Circle` + :class:`compas.geometry.Circle` The constructed circle. See Also @@ -239,16 +239,16 @@ def from_three_points(cls, a, b, c): Parameters ---------- - a : :class:`~compas.geometry.Point` + a : :class:`compas.geometry.Point` The first point. - b : :class:`~compas.geometry.Point` + b : :class:`compas.geometry.Point` The second point. - c : :class:`~compas.geometry.Point` + c : :class:`compas.geometry.Point` The third point. Returns ------- - :class:`~compas.geometry.Circle` + :class:`compas.geometry.Circle` The constructed circle. See Also @@ -269,12 +269,12 @@ def from_points(cls, points): Parameters ---------- - points : list of :class:`~compas.geometry.Point` + points : list of :class:`compas.geometry.Point` A list of three points defining the circle. Returns ------- - :class:`~compas.geometry.Circle` + :class:`compas.geometry.Circle` The constructed circle. Raises @@ -324,7 +324,7 @@ def point_at(self, t, world=True): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` The point on the circle at the specified parameter. See Also @@ -358,7 +358,7 @@ def normal_at(self, t, world=True): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The normal on the circle at the specified parameter. See Also @@ -391,7 +391,7 @@ def tangent_at(self, t, world=True): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The tangent on the circle at the specified parameter. See Also @@ -417,14 +417,14 @@ def closest_point(self, point, return_parameter=False): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` A point. return_parameter : bool, optional Return the parameter of the closest point as well. Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` The closest point on the circle. Notes @@ -449,7 +449,7 @@ def contains_point(self, point, tol=1e-6, dmax=1e-6): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The point. tol : float, optional The tolerance for the verification. diff --git a/src/compas/geometry/curves/curve.py b/src/compas/geometry/curves/curve.py index 8b769ba1427..ea70e8f18b3 100644 --- a/src/compas/geometry/curves/curve.py +++ b/src/compas/geometry/curves/curve.py @@ -22,7 +22,7 @@ class Curve(Geometry): Parameters ---------- - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system of the curve. Default is the world coordinate system. name : str, optional @@ -30,11 +30,11 @@ class Curve(Geometry): Attributes ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` The frame of the curve. - transformation : :class:`~compas.geometry.Transformation`, read-only + transformation : :class:`compas.geometry.Transformation`, read-only The transformation from the local coordinate system of the curve (:attr:`frame`) to the world coordinate system. - plane : :class:`~compas.geometry.Plane`, read-only + plane : :class:`compas.geometry.Plane`, read-only The plane of the curve. dimension : int, read-only The spatial dimension of the curve. @@ -142,7 +142,7 @@ def from_step(cls, filepath): Returns ------- - :class:`~compas.geometry.Curve` + :class:`compas.geometry.Curve` """ raise NotImplementedError @@ -158,7 +158,7 @@ def from_obj(cls, filepath): Returns ------- - :class:`~compas.geometry.Curve` + :class:`compas.geometry.Curve` """ raise NotImplementedError @@ -213,7 +213,7 @@ def to_points(self, n=10, domain=None): Returns ------- - list[:class:`~compas.geometry.Point`] + list[:class:`compas.geometry.Point`] """ domain = domain or self.domain @@ -235,7 +235,7 @@ def to_polyline(self, n=16, domain=None): Returns ------- - :class:`~compas.geometry.Polyline` + :class:`compas.geometry.Polyline` """ from compas.geometry import Polyline @@ -254,7 +254,7 @@ def to_polygon(self, n=16): Returns ------- - :class:`~compas.geometry.Polygon` + :class:`compas.geometry.Polygon` Raises ------ @@ -279,7 +279,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` | list[list[float]] + T : :class:`compas.geometry.Transformation` | list[list[float]] The transformation. Returns @@ -311,7 +311,7 @@ def point_at(self, t): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` the corresponding point on the curve. Raises @@ -336,7 +336,7 @@ def normal_at(self, t): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The corresponding normal vector. Raises @@ -361,7 +361,7 @@ def tangent_at(self, t): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The corresponding tangent vector. Raises @@ -386,7 +386,7 @@ def frame_at(self, t): Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The corresponding local frame. Raises @@ -416,7 +416,7 @@ def curvature_at(self, t): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The corresponding curvature vector. Raises @@ -454,7 +454,7 @@ def reversed(self): Returns ------- - :class:`~compas.geometry.Curve` + :class:`compas.geometry.Curve` See Also -------- @@ -496,7 +496,7 @@ def reversed(self): # Returns # ------- - # list[:class:`~compas.geometry.Point`] + # list[:class:`compas.geometry.Point`] # Points along the curve. # See Also @@ -511,14 +511,14 @@ def closest_point(self, point, return_parameter=False): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The test point. return_parameter : bool, optional If True, the parameter corresponding to the closest point should be returned in addition to the point. Returns ------- - :class:`~compas.geometry.Point` | tuple[:class:`~compas.geometry.Point`, float] + :class:`compas.geometry.Point` | tuple[:class:`compas.geometry.Point`, float] If `return_parameter` is False (default), only the closest point is returned. If `return_parameter` is True, the closest point and the corresponding parameter are returned. @@ -539,7 +539,7 @@ def divide_by_count(self, count, return_points=False): Returns ------- - list[float] | tuple[list[float], list[:class:`~compas.geometry.Point`]] + list[float] | tuple[list[float], list[:class:`compas.geometry.Point`]] If `return_points` is False, the parameters of the discretisation. If `return_points` is True, a list of points in addition to the parameters of the discretisation. @@ -565,7 +565,7 @@ def divide_by_length(self, length, return_points=False): Returns ------- - list[float] | tuple[list[float], list[:class:`~compas.geometry.Point`]] + list[float] | tuple[list[float], list[:class:`compas.geometry.Point`]] If `return_points` is False, the parameters of the discretisation. If `return_points` is True, a list of points in addition to the parameters of the discretisation. @@ -582,7 +582,7 @@ def aabb(self): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` """ raise NotImplementedError diff --git a/src/compas/geometry/curves/ellipse.py b/src/compas/geometry/curves/ellipse.py index 3131fbc4f9e..9336064eeb6 100644 --- a/src/compas/geometry/curves/ellipse.py +++ b/src/compas/geometry/curves/ellipse.py @@ -28,13 +28,13 @@ class Ellipse(Conic): The major of the ellipse. minor : float The minor of the ellipse. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system of the ellipse. The default value is ``None``, in which case the ellipse is constructed in the XY plane of the world coordinate system. Attributes ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` The coordinate frame of the ellipse. transformation : :class:`Transformation`, read-only The transformation from the local coordinate system of the ellipse (:attr:`frame`) to the world coordinate system. @@ -42,7 +42,7 @@ class Ellipse(Conic): The major of the ellipse. minor : float The minor of the ellipse. - plane : :class:`~compas.geometry.Plane`, read-only + plane : :class:`compas.geometry.Plane`, read-only The plane of the ellipse. area : float, read-only The area of the ellipse. @@ -56,15 +56,15 @@ class Ellipse(Conic): eccentricity : float, read-only The eccentricity of the ellipse. This is the ratio between the semifocal length to the length of the semi-major axis. - focus1 : :class:`~compas.geometry.Point`, read-only + focus1 : :class:`compas.geometry.Point`, read-only The first focus point of the ellipse. - focus2 : :class:`~compas.geometry.Point`, read-only + focus2 : :class:`compas.geometry.Point`, read-only The second focus point of the ellipse. - directix1 : :class:`~compas.geometry.Line`, read-only + directix1 : :class:`compas.geometry.Line`, read-only The first directix of the ellipse. The directix is perpendicular to the major axis and passes through a point at a distance ``major **2 / semifocal`` along the positive xaxis from the center of the ellipse. - directix2 : :class:`~compas.geometry.Line`, read-only + directix2 : :class:`compas.geometry.Line`, read-only The second directix of the ellipse. The directix is perpendicular to the major axis and passes through a point at a distance ``major **2 / semifocal`` along the negative xaxis from the center of the ellipse. diff --git a/src/compas/geometry/curves/hyperbola.py b/src/compas/geometry/curves/hyperbola.py index 929afa6ca3b..cd5dc829565 100644 --- a/src/compas/geometry/curves/hyperbola.py +++ b/src/compas/geometry/curves/hyperbola.py @@ -40,7 +40,7 @@ class Hyperbola(Conic): The major of the hyperbola. minor : float The minor of the hyperbola. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system of the hyperbola. The default value is ``None``, in which case the hyperbola is constructed in the XY plane of the world coordinate system. diff --git a/src/compas/geometry/curves/line.py b/src/compas/geometry/curves/line.py index 062911fb56c..197ec10672a 100644 --- a/src/compas/geometry/curves/line.py +++ b/src/compas/geometry/curves/line.py @@ -24,29 +24,29 @@ class Line(Curve): Parameters ---------- - start : [float, float, float] | :class:`~compas.geometry.Point` + start : [float, float, float] | :class:`compas.geometry.Point` The first point. - end : [float, float, float] | :class:`~compas.geometry.Point` + end : [float, float, float] | :class:`compas.geometry.Point` The second point. Attributes ---------- - start : :class:`~compas.geometry.Point` + start : :class:`compas.geometry.Point` The start point of the line. - end : :class:`~compas.geometry.Point` + end : :class:`compas.geometry.Point` The end point of the line. - vector : :class:`~compas.geometry.Vector`, read-only + vector : :class:`compas.geometry.Vector`, read-only A vector pointing from start to end. length : float, read-only The length of the vector from start to end. - direction : :class:`~compas.geometry.Vector`, read-only + direction : :class:`compas.geometry.Vector`, read-only A unit vector parallel to the line vector. - midpoint : :class:`~compas.geometry.Point`, read-only + midpoint : :class:`compas.geometry.Point`, read-only The midpoint between start and end. - frame : :class:`~compas.geometry.Frame`, read-only + frame : :class:`compas.geometry.Frame`, read-only The frame of the line. This is alsways the world XY frame. - transformation : :class:`~compas.geometry.Transformation`, read-only + transformation : :class:`compas.geometry.Transformation`, read-only This is always the identity transformation. Examples @@ -205,9 +205,9 @@ def from_point_and_vector(cls, point, vector): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The start point of the line. - vector : :class:`~compas.geometry.Vector` + vector : :class:`compas.geometry.Vector` The vector of the line. Returns @@ -235,9 +235,9 @@ def from_point_direction_length(cls, point, direction, length): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The start point of the line. - direction : :class:`~compas.geometry.Vector` + direction : :class:`compas.geometry.Vector` The direction of the line. length : float The length of the line. @@ -272,7 +272,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` The transformation. Returns @@ -307,7 +307,7 @@ def point_at(self, t): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` The point at the specified location. See Also @@ -329,7 +329,7 @@ def closest_point(self, point, return_parameter=False): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The point. return_parameter : bool, optional Return the parameter of the closest point on the line. @@ -337,7 +337,7 @@ def closest_point(self, point, return_parameter=False): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` The closest point on the line. float The parameter of the closest point on the line. diff --git a/src/compas/geometry/curves/nurbs.py b/src/compas/geometry/curves/nurbs.py index 65bd25c6d05..4be1eba7b3d 100644 --- a/src/compas/geometry/curves/nurbs.py +++ b/src/compas/geometry/curves/nurbs.py @@ -49,7 +49,7 @@ class NurbsCurve(Curve): Attributes ---------- - points : list[:class:`~compas.geometry.Point`], read-only + points : list[:class:`compas.geometry.Point`], read-only The control points. weights : list[float], read-only The weights of the control points. @@ -129,7 +129,7 @@ def from_data(cls, data): Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` The constructed curve. """ @@ -197,7 +197,7 @@ def from_step(cls, filepath): Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ return new_nurbscurve_from_step(cls, filepath) @@ -207,7 +207,7 @@ def from_parameters(cls, points, weights, knots, multiplicities, degree, is_peri Parameters ---------- - points : list[[float, float, float] | :class:`~compas.geometry.Point`] + points : list[[float, float, float] | :class:`compas.geometry.Point`] The control points. weights : list[float] The weights of the control points. @@ -222,7 +222,7 @@ def from_parameters(cls, points, weights, knots, multiplicities, degree, is_peri Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ return new_nurbscurve_from_parameters(cls, points, weights, knots, multiplicities, degree, is_periodic=False) @@ -233,14 +233,14 @@ def from_points(cls, points, degree=3): Parameters ---------- - points : list[[float, float, float] | :class:`~compas.geometry.Point`] + points : list[[float, float, float] | :class:`compas.geometry.Point`] The control points. degree : int, optional The degree of the curve. Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ return new_nurbscurve_from_points(cls, points, degree=degree) @@ -251,14 +251,14 @@ def from_interpolation(cls, points, precision=1e-3): Parameters ---------- - points : list[[float, float, float] | :class:`~compas.geometry.Point`] + points : list[[float, float, float] | :class:`compas.geometry.Point`] A list of interpolation points. precision : int, optional The desired precision of the interpolation. Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ return new_nurbscurve_from_interpolation(cls, points, precision=1e-3) @@ -269,11 +269,11 @@ def from_arc(cls, arc): Parameters ---------- - arc : :class:`~compas.geometry.Arc` + arc : :class:`compas.geometry.Arc` Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ raise NotImplementedError @@ -284,11 +284,11 @@ def from_circle(cls, circle): Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ frame = Frame.from_plane(circle.plane) @@ -317,11 +317,11 @@ def from_ellipse(cls, ellipse): Parameters ---------- - ellipse : :class:`~compas.geometry.Ellipse` + ellipse : :class:`compas.geometry.Ellipse` Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ frame = Frame.from_plane(ellipse.plane) @@ -351,11 +351,11 @@ def from_line(cls, line): Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ return cls.from_parameters( @@ -379,7 +379,7 @@ def copy(self): Returns ------- - :class:`~compas.geometry.NurbsCurve` + :class:`compas.geometry.NurbsCurve` """ return NurbsCurve.from_parameters( diff --git a/src/compas/geometry/curves/polyline.py b/src/compas/geometry/curves/polyline.py index 3dcf40c3918..cd8ecec68b9 100644 --- a/src/compas/geometry/curves/polyline.py +++ b/src/compas/geometry/curves/polyline.py @@ -26,24 +26,24 @@ class Polyline(Curve): Parameters ---------- - points : list[[float, float, float] | :class:`~compas.geometry.Point`] + points : list[[float, float, float] | :class:`compas.geometry.Point`] An ordered list of points. Each consecutive pair of points forms a segment of the polyline. Attributes ---------- - frame : :class:`~compas.geometry.Frame`, read-only + frame : :class:`compas.geometry.Frame`, read-only The frame of the spatial coordinates of the polyline. This is always the world XY frame. - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The points of the polyline. - lines : list[:class:`~compas.geometry.Line`], read-only + lines : list[:class:`compas.geometry.Line`], read-only The lines of the polyline. length : float, read-only The length of the polyline. - start : :class:`~compas.geometry.Point`, read-only + start : :class:`compas.geometry.Point`, read-only The start point of the polyline. - end : :class:`~compas.geometry.Point`, read-only + end : :class:`compas.geometry.Point`, read-only The end point of the polyline. is_selfintersecting : bool, read-only True if the polyline is self-intersecting. @@ -181,7 +181,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` | list[list[float]] + T : :class:`compas.geometry.Transformation` | list[list[float]] The transformation. Examples @@ -207,7 +207,7 @@ def append(self, point): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point to append. """ @@ -221,7 +221,7 @@ def insert(self, i, point): ---------- i : int The index of the insertion point. - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point to insert. """ @@ -240,7 +240,7 @@ def point_at(self, t, snap=False): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` The point on the polyline. Examples @@ -282,7 +282,7 @@ def parameter_at(self, point, tol=1e-6): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point on the polyline. tol : float, optional A tolerance for membership verification. @@ -321,7 +321,7 @@ def tangent_at(self, t): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The tangent vector at the specified parameter. Examples @@ -358,11 +358,11 @@ def tangent_at_point(self, point): Parameters ---------- - point: [float, float, float] | :class:`~compas.geometry.Point` + point: [float, float, float] | :class:`compas.geometry.Point` Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` """ for line in self.lines: @@ -380,7 +380,7 @@ def split_at_corners(self, angle_threshold): Returns ------- - list[:class:`~compas.geometry.Polyline`] + list[:class:`compas.geometry.Polyline`] """ corner_ids = [] @@ -424,7 +424,7 @@ def divide_at_corners(self, angle_threshold): Returns ------- - list[:class:`~compas.geometry.Point`] + list[:class:`compas.geometry.Point`] """ corner_ids = [] @@ -448,7 +448,7 @@ def divide(self, num_segments): Returns ------- list - list[:class:`~compas.geometry.Point`] + list[:class:`compas.geometry.Point`] Examples -------- @@ -475,7 +475,7 @@ def divide_by_length(self, length, strict=True, tol=1e-06): Returns ------- - list[:class:`~compas.geometry.Point`] + list[:class:`compas.geometry.Point`] Notes ----- @@ -539,7 +539,7 @@ def split_by_length(self, length, strict=True): Returns ------- - list[:class:`~compas.geometry.Polyline`] + list[:class:`compas.geometry.Polyline`] Examples -------- @@ -600,7 +600,7 @@ def split(self, num_segments): Returns ------- list - list[:class:`~compas.geometry.Polyline`] + list[:class:`compas.geometry.Polyline`] Examples -------- @@ -654,7 +654,7 @@ def extended(self, length): Returns ------- - :class:`~compas.geometry.Polyline` + :class:`compas.geometry.Polyline` """ crv = self.copy() @@ -716,7 +716,7 @@ def shortened(self, length): Returns ------- - :class:`~compas.geometry.Polyline` + :class:`compas.geometry.Polyline` """ crv = self.copy() diff --git a/src/compas/geometry/frame.py b/src/compas/geometry/frame.py index f83031859cf..66931a37616 100644 --- a/src/compas/geometry/frame.py +++ b/src/compas/geometry/frame.py @@ -29,30 +29,30 @@ class Frame(Geometry): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The origin of the frame. - xaxis : [float, float, float] | :class:`~compas.geometry.Vector`, optional + xaxis : [float, float, float] | :class:`compas.geometry.Vector`, optional The x-axis of the frame. Defaults to the unit X vector. - yaxis : [float, float, float] | :class:`~compas.geometry.Vector`, optional + yaxis : [float, float, float] | :class:`compas.geometry.Vector`, optional The y-axis of the frame. Defaults to the unit Y vector. Attributes ---------- - axes : list of :class:`~compas.geometry.Vector`, read-only + axes : list of :class:`compas.geometry.Vector`, read-only The XYZ axes of the frame. - axis_angle_vector : :class:`~compas.geometry.Vector`, read-only + axis_angle_vector : :class:`compas.geometry.Vector`, read-only The axis-angle vector representing the rotation of the frame. - normal : :class:`~compas.geometry.Vector`, read-only + normal : :class:`compas.geometry.Vector`, read-only The normal of the base plane of the frame. - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The base point of the frame. - quaternion : :class:`~compas.geometry.Quaternion`, read-only + quaternion : :class:`compas.geometry.Quaternion`, read-only The quaternion from the rotation given by the frame. - xaxis : :class:`~compas.geometry.Vector` + xaxis : :class:`compas.geometry.Vector` The local X axis of the frame. - yaxis : :class:`~compas.geometry.Vector` + yaxis : :class:`compas.geometry.Vector` The local Y axis of the frame. - zaxis : :class:`~compas.geometry.Vector`, read-only + zaxis : :class:`compas.geometry.Vector`, read-only The Z axis of the frame. Notes @@ -216,7 +216,7 @@ def worldXY(cls): # type: () -> Frame Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The world XY frame. Examples @@ -238,7 +238,7 @@ def worldZX(cls): # type: () -> Frame Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The world ZX frame. Examples @@ -260,7 +260,7 @@ def worldYZ(cls): # type: () -> Frame Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The world YZ frame. Examples @@ -282,16 +282,16 @@ def from_points(cls, point, point_xaxis, point_xyplane): # type: (...) -> Frame Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The origin of the frame. - point_xaxis : [float, float, float] | :class:`~compas.geometry.Point` + point_xaxis : [float, float, float] | :class:`compas.geometry.Point` A point on the x-axis of the frame. - point_xyplane : [float, float, float] | :class:`~compas.geometry.Point` + point_xyplane : [float, float, float] | :class:`compas.geometry.Point` A point within the xy-plane of the frame. Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Examples @@ -316,14 +316,14 @@ def from_rotation(cls, rotation, point=[0, 0, 0]): # type: (...) -> Frame Parameters ---------- - rotation : :class:`~compas.geometry.Rotation` + rotation : :class:`compas.geometry.Rotation` The rotation defines the orientation of the frame. - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional The origin of the frame. Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Examples @@ -345,13 +345,13 @@ def from_transformation(cls, transformation): # type: (...) -> Frame Parameters ---------- - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation defines the orientation of the frame through the rotation and the origin through the translation. Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Examples @@ -379,7 +379,7 @@ def from_matrix(cls, matrix): # type: (...) -> Frame Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Examples @@ -409,7 +409,7 @@ def from_list(cls, values): # type: (...) -> Frame Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Raises @@ -446,14 +446,14 @@ def from_quaternion(cls, quaternion, point=[0, 0, 0]): # type: (...) -> Frame Parameters ---------- - quaternion : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + quaternion : [float, float, float, float] | :class:`compas.geometry.Quaternion` Four numbers that represent the four coefficient values of a quaternion. - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional The point of the frame. Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Examples @@ -478,12 +478,12 @@ def from_axis_angle_vector(cls, axis_angle_vector, point=[0, 0, 0]): # type: (. axis_angle_vector : [float, float, float] Three numbers that represent the axis of rotation and angle of rotation by its magnitude. - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional The point of the frame. Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Examples @@ -512,12 +512,12 @@ def from_euler_angles(cls, euler_angles, static=True, axes="xyz", point=[0, 0, 0 If False, to a rotational. axes : str, optional A 3 character string specifying the order of the axes. - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional The point of the frame. Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Examples @@ -541,12 +541,12 @@ def from_plane(cls, plane): # type: (...) -> Frame Parameters ---------- - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` A plane. Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The constructed frame. Examples @@ -626,12 +626,12 @@ def to_local_coordinates(self, obj_in_wcf): Parameters ---------- - obj_in_wcf : [float, float, float] | :class:`~compas.geometry.Geometry` + obj_in_wcf : [float, float, float] | :class:`compas.geometry.Geometry` An object in the world coordinate frame. Returns ------- - :class:`~compas.geometry.Geometry` + :class:`compas.geometry.Geometry` The object in the local coordinate system of the frame. Notes @@ -658,12 +658,12 @@ def to_world_coordinates(self, obj_in_lcf): Parameters ---------- - obj_in_lcf : [float, float, float] | :class:`~compas.geometry.Geometry` + obj_in_lcf : [float, float, float] | :class:`compas.geometry.Geometry` An object in local coordinate system of the frame. Returns ------- - :class:`~compas.geometry.Geometry` + :class:`compas.geometry.Geometry` The object in the world coordinate frame. Notes @@ -690,7 +690,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` The transformation. Examples diff --git a/src/compas/geometry/geometry.py b/src/compas/geometry/geometry.py index f02da2b44c9..82612533f24 100644 --- a/src/compas/geometry/geometry.py +++ b/src/compas/geometry/geometry.py @@ -30,13 +30,20 @@ def transform(self, transformation): Parameters ---------- - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation used to transform the geometry. Returns ------- None + See Also + -------- + transformed + translate + rotate + scale + """ raise NotImplementedError @@ -45,7 +52,7 @@ def transformed(self, transformation): # type: (...) -> G Parameters ---------- - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation used to transform the geometry. Returns @@ -53,6 +60,13 @@ def transformed(self, transformation): # type: (...) -> G :class:`Geometry` The transformed geometry. + See Also + -------- + transform + translated + rotated + scaled + """ geometry = self.copy() # type: Geometry geometry.transform(transformation) @@ -76,6 +90,13 @@ def scale(self, x, y=None, z=None): ------- None + See Also + -------- + scaled + translate + rotate + transform + """ from compas.geometry import Scale @@ -106,6 +127,13 @@ def scaled(self, x, y=None, z=None): # type: (...) -> G :class:`Geometry` The scaled geometry. + See Also + -------- + scale + translated + rotated + transformed + """ from compas.geometry import Scale @@ -129,6 +157,13 @@ def translate(self, vector): ------- None + See Also + -------- + translated + rotate + scale + transform + """ from compas.geometry import Translation @@ -147,6 +182,13 @@ def translated(self, vector): # type: (...) -> G :class:`Geometry` The translated geometry. + See Also + -------- + translate + rotated + scaled + transformed + """ from compas.geometry import Translation @@ -170,6 +212,13 @@ def rotate(self, angle, axis=None, point=None): ------- None + See Also + -------- + rotated + translate + scale + transform + """ from compas.geometry import Rotation @@ -197,6 +246,13 @@ def rotated(self, angle, axis=None, point=None): # type: (...) -> G :class:`Geometry` The rotated geometry. + See Also + -------- + rotate + translated + scaled + transformed + """ from compas.geometry import Rotation diff --git a/src/compas/geometry/hull/hull.py b/src/compas/geometry/hull.py similarity index 98% rename from src/compas/geometry/hull/hull.py rename to src/compas/geometry/hull.py index 547019b8a73..28b22384431 100644 --- a/src/compas/geometry/hull/hull.py +++ b/src/compas/geometry/hull.py @@ -22,6 +22,10 @@ def convex_hull(points): The triangular faces of the convex hull as lists of vertex indices referring to the original point coordinates. + See Also + -------- + convex_hull_xy + Notes ----- This algorithm is based on [1]_. Note that is not optimized and relatively @@ -35,10 +39,6 @@ def convex_hull(points): .. [2] Thomas Diewald. *Convex Hull 3D - Quickhull Algorithm*. Available at: https://web.archive.org/web/20180106161310/http://thomasdiewald.com/blog/?p=1888 - Examples - -------- - >>> - """ def _normal_face(face): @@ -90,6 +90,10 @@ def convex_hull_xy(points, strict=False): XY(Z) coordinates of vertices of the convex hull in counter-clockwise order, starting from the vertex with the lexicographically smallest coordinates. + See Also + -------- + convex_hull + Notes ----- Implements Andrew's monotone chain algorithm [1]_. @@ -100,10 +104,6 @@ def convex_hull_xy(points, strict=False): .. [1] Wiki Books. *Algorithm Implementation/Geometry/Convex hull/Monotone chain*. Available at: https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain. - Examples - -------- - >>> - """ def cross(o, a, b): diff --git a/src/compas/geometry/hull/__init__.py b/src/compas/geometry/hull/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/geometry/hull/hull_numpy.py b/src/compas/geometry/hull_numpy.py similarity index 84% rename from src/compas/geometry/hull/hull_numpy.py rename to src/compas/geometry/hull_numpy.py index d1119502db8..277387e2f25 100644 --- a/src/compas/geometry/hull/hull_numpy.py +++ b/src/compas/geometry/hull_numpy.py @@ -23,9 +23,13 @@ def convex_hull_numpy(points): Raises ------ - AssertionError + ValueError If the input data is not 3D. + See Also + -------- + convex_hull_xy_numpy + Notes ----- The faces of the hull returned by this function do not necessarily have consistent @@ -33,15 +37,12 @@ def convex_hull_numpy(points): a mesh from the returned vertices, this function should be used in combination with :func:`compas.topology.unify_cycles`. - Examples - -------- - >>> - """ points = asarray(points) n, dim = points.shape - assert 2 < dim, "The point coordinates should be at least 3D: %i" % dim + if dim < 3: + raise ValueError("The point coordinates should be at least 3D: %i" % dim) points = points[:, :3] hull = ConvexHull(points) @@ -66,18 +67,19 @@ def convex_hull_xy_numpy(points): Raises ------ - AssertionError + ValueError If the input data is not at least 2D. - Examples + See Also -------- - >>> + convex_hull_numpy """ points = asarray(points) n, dim = points.shape - assert 1 < dim, "The point coordinates should be at least 2D: %i" % dim + if dim < 2: + raise ValueError("The point coordinates should be at least 2D: %i" % dim) points = points[:, :2] hull = ConvexHull(points) diff --git a/src/compas/geometry/icp/__init__.py b/src/compas/geometry/icp/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/geometry/icp/icp_numpy.py b/src/compas/geometry/icp_numpy.py similarity index 98% rename from src/compas/geometry/icp/icp_numpy.py rename to src/compas/geometry/icp_numpy.py index cd7534912b8..1a3ae2bc26d 100644 --- a/src/compas/geometry/icp/icp_numpy.py +++ b/src/compas/geometry/icp_numpy.py @@ -74,10 +74,6 @@ def icp_numpy(source, target, tol=1e-3): The algorithm terminates when the alignment error is below a specified tolerance. - Examples - -------- - >>> - """ from compas.geometry import Transformation from compas.geometry import Frame diff --git a/src/compas/geometry/interpolation/__init__.py b/src/compas/geometry/interpolation/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/geometry/interpolation/barycentric.py b/src/compas/geometry/interpolation_barycentric.py similarity index 93% rename from src/compas/geometry/interpolation/barycentric.py rename to src/compas/geometry/interpolation_barycentric.py index 7a5663b0439..229fa1afb6a 100644 --- a/src/compas/geometry/interpolation/barycentric.py +++ b/src/compas/geometry/interpolation_barycentric.py @@ -11,7 +11,7 @@ def barycentric_coordinates(point, triangle): Parameters ---------- - point: [float, float, float] | :class:`~compas.geometry.Point` + point: [float, float, float] | :class:`compas.geometry.Point` Point location. triangle: [point, point, point] A triangle defined by 3 points. diff --git a/src/compas/geometry/interpolation/coons.py b/src/compas/geometry/interpolation_coons.py similarity index 90% rename from src/compas/geometry/interpolation/coons.py rename to src/compas/geometry/interpolation_coons.py index 868ba0cef40..6147781fc7a 100644 --- a/src/compas/geometry/interpolation/coons.py +++ b/src/compas/geometry/interpolation_coons.py @@ -16,13 +16,13 @@ def discrete_coons_patch(ab, bc, dc, ad): Parameters ---------- - ab : list[[float, float, float] | :class:`~compas.geometry.Point`] + ab : list[[float, float, float] | :class:`compas.geometry.Point`] The XYZ coordinates of the vertices of the first polyline. - bc : list[[float, float, float] | :class:`~compas.geometry.Point`] + bc : list[[float, float, float] | :class:`compas.geometry.Point`] The XYZ coordinates of the vertices of the second polyline. - dc : list[[float, float, float] | :class:`~compas.geometry.Point`] + dc : list[[float, float, float] | :class:`compas.geometry.Point`] The XYZ coordinates of the vertices of the third polyline. - ad : list[[float, float, float] | :class:`~compas.geometry.Point`] + ad : list[[float, float, float] | :class:`compas.geometry.Point`] The XYZ coordinates of the vertices of the fourth polyline. Returns @@ -88,7 +88,7 @@ def discrete_coons_patch(ab, bc, dc, ad): d = scale_vector(ad[-1], (1 - ki) * kj) lin_interp_a_b_c_d = sum_vectors([a, b, c, d]) # coons patch = first + second - third functions - array[i][j] = subtract_vectors(add_vectors(lin_interp_ab_dc, lin_interp_bc_ad), lin_interp_a_b_c_d) + array[i][j] = subtract_vectors(add_vectors(lin_interp_ab_dc, lin_interp_bc_ad), lin_interp_a_b_c_d) # type: ignore # create vertex list vertices = [] diff --git a/src/compas/geometry/interpolation/tweening.py b/src/compas/geometry/interpolation_tweening.py similarity index 88% rename from src/compas/geometry/interpolation/tweening.py rename to src/compas/geometry/interpolation_tweening.py index 8b8862d9914..0b05de764c6 100644 --- a/src/compas/geometry/interpolation/tweening.py +++ b/src/compas/geometry/interpolation_tweening.py @@ -13,9 +13,9 @@ def tween_points(points1, points2, num): Parameters ---------- - points1 : list[[float, float, float] | :class:`~compas.geometry.Point`] + points1 : list[[float, float, float] | :class:`compas.geometry.Point`] The first set of points. - points2 : list[[float, float, float] | :class:`~compas.geometry.Point`] + points2 : list[[float, float, float] | :class:`compas.geometry.Point`] The second set of points. num : int The number of interpolated sets to return. @@ -56,9 +56,9 @@ def tween_points_distance(points1, points2, dist, index=None): Parameters ---------- - points1 : list[[float, float, float] | :class:`~compas.geometry.Point`] + points1 : list[[float, float, float] | :class:`compas.geometry.Point`] The first set of points. - points2 : list[[float, float, float] | :class:`~compas.geometry.Point`] + points2 : list[[float, float, float] | :class:`compas.geometry.Point`] The second set of points. dist : float The distance from the first set to the second at which to compute the interpolated set. diff --git a/src/compas/geometry/intersection.py b/src/compas/geometry/intersection.py new file mode 100644 index 00000000000..3c54c5d618a --- /dev/null +++ b/src/compas/geometry/intersection.py @@ -0,0 +1,121 @@ +from __future__ import print_function +from __future__ import absolute_import +from __future__ import division + +# from compas.precision import Precision +from compas.geometry import distance_point_point + + +class Intersection(object): + """A class for computing intersections between geometric objects. + + Attributes + ---------- + number_of_intersections : int + The number of intersections. + points : list[:class:`compas.geometry.Point`] + The intersection points. + + Examples + -------- + >>> from compas.geometry import Line + >>> from compas.geometry import Intersection + >>> a = Line([0, 0, 0], [2, 0, 0]) + >>> b = Line([1, 0, 0], [1, 1, 0]) + >>> intersection = Intersection() + >>> intersection.line_line(a, b) + >>> intersection.number_of_intersections + 1 + >>> intersection.points[0] + Point(1.0, 0.0, z=0.0) + + """ + + def __init__(self): + self.number_of_intersections = 0 + self.points = [] + + def __len__(self): + return self.number_of_intersections + + def __iter__(self): + return iter(self.points) + + def __getitem__(self, key): + return self.points[key] + + def line_line(self, a, b, tol=1e-6): + """Compute the intersection of two lines. + + Parameters + ---------- + a : :class:`compas.geometry.Line` + A line. + b : :class:`compas.geometry.Line` + A line. + tol : float, optional + The tolerance for numerical fuzz. + + Returns + ------- + None + + """ + from compas.geometry import intersection_line_line + + x1, x2 = intersection_line_line(a, b) + + if x1 is None or x2 is None: + self.number_of_intersections = 0 + self.points = [] + return + + if distance_point_point(x1, x2) < tol: + self.number_of_intersections = 1 + self.points = [x1] + return + + self.number_of_intersections = 2 + self.points = [x1, x2] + + def line_segment(self, a, b): + pass + + def line_polyline(self, a, b): + pass + + def line_plane(self, a, b): + pass + + def line_circle(self, a, b): + pass + + def line_ellipse(self, a, b): + pass + + def line_curve(self, a, b): + pass + + def line_surface(self, a, b): + pass + + def line_box(self, a, b): + pass + + def line_sphere(self, a, b): + pass + + def line_cylinder(self, a, b): + pass + + def line_cone(self, a, b): + pass + + def line_torus(self, a, b): + pass + + def line_triangle(self, a, b): + pass + + def line_mesh(self, a, b): + pass diff --git a/src/compas/geometry/intersections/intersections.py b/src/compas/geometry/intersections/intersections.py index 0da81dd9480..2c6c4cd2c95 100644 --- a/src/compas/geometry/intersections/intersections.py +++ b/src/compas/geometry/intersections/intersections.py @@ -30,9 +30,9 @@ def intersection_line_line(l1, l2, tol=1e-6): Parameters ---------- - l1 : [point, point] | :class:`~compas.geometry.Line` + l1 : [point, point] | :class:`compas.geometry.Line` XYZ coordinates of two points defining the first line. - l2 : [point, point] | :class:`~compas.geometry.Line` + l2 : [point, point] | :class:`compas.geometry.Line` XYZ coordinates of two points defining the second line. tol : float, optional A tolerance for membership verification. @@ -103,9 +103,9 @@ def intersection_segment_segment(ab, cd, tol=1e-6): Parameters ---------- - ab : [point, point] | :class:`~compas.geometry.Line` + ab : [point, point] | :class:`compas.geometry.Line` XYZ coordinates of two points defining a line segment. - cd : [point, point] | :class:`~compas.geometry.Line` + cd : [point, point] | :class:`compas.geometry.Line` XYZ coordinates of two points defining another line segment. tol : float, optional A tolerance for membership verification. @@ -168,9 +168,9 @@ def intersection_line_segment(line, segment, tol=1e-6): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining a line. - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` Two points defining a line segment. tol : float, optional A tolerance for membership verification. @@ -200,9 +200,9 @@ def intersection_line_plane(line, plane, tol=1e-6): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the line. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` The base point and normal defining the plane. tol : float, optional A tolerance for membership verification. @@ -242,9 +242,9 @@ def intersection_segment_plane(segment, plane, tol=1e-6): Parameters ---------- - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` Two points defining the line segment. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` The base point and normal defining the plane. tol : float, optional A tolerance for membership verification. @@ -288,9 +288,9 @@ def intersection_polyline_plane(polyline, plane, expected_number_of_intersection Parameters ---------- - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` Polyline to test intersection. - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` Plane to compute intersection. expected_number_of_intersections : int, optional Number of useful or expected intersections. @@ -322,7 +322,7 @@ def intersection_line_triangle(line, triangle, tol=1e-6): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` Two points defining the line. triangle : [point, point, point] XYZ coordinates of the triangle corners. @@ -354,9 +354,9 @@ def intersection_plane_plane(plane1, plane2, tol=1e-6): Parameters ---------- - plane1 : [point, vector] | :class:`~compas.geometry.Plane` + plane1 : [point, vector] | :class:`compas.geometry.Plane` The base point and normal (normalized) defining the 1st plane. - plane2 : [point, vector] | :class:`~compas.geometry.Plane` + plane2 : [point, vector] | :class:`compas.geometry.Plane` The base point and normal (normalized) defining the 2nd plane. tol : float, optional A tolerance for membership verification. @@ -391,11 +391,11 @@ def intersection_plane_plane_plane(plane1, plane2, plane3, tol=1e-6): Parameters ---------- - plane1 : [point, vector] | :class:`~compas.geometry.Plane` + plane1 : [point, vector] | :class:`compas.geometry.Plane` The base point and normal (normalized) defining the 1st plane. - plane2 : [point, vector] | :class:`~compas.geometry.Plane` + plane2 : [point, vector] | :class:`compas.geometry.Plane` The base point and normal (normalized) defining the 2nd plane. - plane3 : [point, vector] | :class:`~compas.geometry.Plane` + plane3 : [point, vector] | :class:`compas.geometry.Plane` The base point and normal (normalized) defining the 3rd plane. tol : float, optional A tolerance for membership verification. @@ -426,9 +426,9 @@ def intersection_sphere_sphere(sphere1, sphere2): Parameters ---------- - sphere1 : [point, float] | :class:`~compas.geometry.Sphere` + sphere1 : [point, float] | :class:`compas.geometry.Sphere` A sphere defined by a point and radius. - sphere2 : [point, float] | :class:`~compas.geometry.Sphere` + sphere2 : [point, float] | :class:`compas.geometry.Sphere` A sphere defined by a point and radius. Returns @@ -520,9 +520,9 @@ def intersection_segment_polyline(segment, polyline, tol=1e-6): Parameters ---------- - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` XYZ coordinates of two points defining a line segment. - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` XYZ coordinates of the points of the polyline. tol : float, optional The tolerance for intersection verification. @@ -564,9 +564,9 @@ def intersection_sphere_line(sphere, line): Parameters ---------- - sphere : [point, radius] | :class:`~compas.geometry.Sphere` + sphere : [point, radius] | :class:`compas.geometry.Sphere` A sphere defined by a point and a radius. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` A line defined by two points. Returns @@ -650,9 +650,9 @@ def intersection_plane_circle(plane, circle): Parameters ---------- - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` A plane defined by a point and normal vector. - circle : [plane, float] | :class:`~compas.geometry.Circle` + circle : [plane, float] | :class:`compas.geometry.Circle` A circle defined by a plane and radius. Returns @@ -699,9 +699,9 @@ def intersection_line_line_xy(l1, l2, tol=1e-6): Parameters ---------- - l1 : [point, point] | :class:`~compas.geometry.Line` + l1 : [point, point] | :class:`compas.geometry.Line` A line defined by two points, with at least XY coordinates. - l2 : [point, point] | :class:`~compas.geometry.Line` + l2 : [point, point] | :class:`compas.geometry.Line` A line defined by two points, with at least XY coordinates. tol : float, optional A tolerance for membership verification. @@ -739,9 +739,9 @@ def intersection_line_segment_xy(line, segment, tol=1e-6): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` A line defined by two points, with at least XY coordinates. - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` A segment defined by two points, with at least XY coordinates. tol : float, optional A tolerance for membership verification. @@ -764,7 +764,7 @@ def intersection_line_box_xy(line, box, tol=1e-6): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` A line defined by two points, with at least XY coordinates. box : [point, point, point, point] A box defined by 4 points, with at least XY coordinates. @@ -800,7 +800,7 @@ def intersection_polyline_box_xy(polyline, box, tol=1e-6): Parameters ---------- - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` A polyline defined by a sequence of points, with at least XY coordinates. box : [point, point, point, point] A box defined by a sequence of 4 points, with at least XY coordinates. @@ -831,9 +831,9 @@ def intersection_segment_segment_xy(ab, cd, tol=1e-6): Parameters ---------- - ab : [point, point] | :class:`~compas.geometry.Line` + ab : [point, point] | :class:`compas.geometry.Line` A segment defined by two points, with at least XY coordinates. - cd : [point, point] | :class:`~compas.geometry.Line` + cd : [point, point] | :class:`compas.geometry.Line` A segment defined by two points, with at least XY coordinates. tol : float, optional A tolerance for membership verification. @@ -864,9 +864,9 @@ def intersection_circle_circle_xy(circle1, circle2): Parameters ---------- - circle1 : [plane, float] | :class:`~compas.geometry.Circle` + circle1 : [plane, float] | :class:`compas.geometry.Circle` Circle defined by a plane, with at least XY coordinates, and a radius. - circle2 : [plane, float] | :class:`~compas.geometry.Circle` + circle2 : [plane, float] | :class:`compas.geometry.Circle` Circle defined by a plane, with at least XY coordinates, and a radius. Returns @@ -916,9 +916,9 @@ def intersection_segment_polyline_xy(segment, polyline, tol=1e-6): Parameters ---------- - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` A line segment defined by two points, with at least XY coordinates. - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` A polyline defined by a sequence of points, with at least XY coordinates. tol : float, optional The tolerance for intersection verification. @@ -958,7 +958,7 @@ def intersection_ellipse_line_xy(ellipse, line): ---------- ellipse : tuple[float, float] The major and minor of the ellipse. - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` A line defined by two points, with at least XY coordinates. Returns diff --git a/src/compas/geometry/_core/kdtree.py b/src/compas/geometry/kdtree.py similarity index 93% rename from src/compas/geometry/_core/kdtree.py rename to src/compas/geometry/kdtree.py index bd9587f2ea4..e73761358a4 100644 --- a/src/compas/geometry/_core/kdtree.py +++ b/src/compas/geometry/kdtree.py @@ -4,7 +4,7 @@ import collections -from .distance import distance_point_point_sqrd +from ._core.distance import distance_point_point_sqrd Node = collections.namedtuple("Node", "point axis label left right") @@ -15,7 +15,7 @@ class KDTree(object): Parameters ---------- - objects : sequence[[float, float, float] | :class:`~compas.geometry.Point`], optional + objects : sequence[[float, float, float] | :class:`compas.geometry.Point`], optional A list of objects to populate the tree with. If objects are provided, the tree is built automatically. Otherwise, use :meth:`build`. @@ -53,7 +53,7 @@ def build(self, objects, axis=0): Parameters ---------- - objects : sequence[tuple[[float, float, float] | :class:`~compas.geometry.Point`, int or str]] + objects : sequence[tuple[[float, float, float] | :class:`compas.geometry.Point`, int or str]] The tree objects as a sequence of point-label tuples. axis : int, optional The axis along which to build. @@ -86,7 +86,7 @@ def nearest_neighbor(self, point, exclude=None): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the base point. exclude : sequence[int or str], optional A sequence of point identified by their label to exclude from the search. @@ -130,7 +130,7 @@ def nearest_neighbors(self, point, number, distance_sort=False): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` XYZ coordinates of the base point. number : int The number of nearest neighbors. diff --git a/src/compas/geometry/offset/offset.py b/src/compas/geometry/offset.py similarity index 91% rename from src/compas/geometry/offset/offset.py rename to src/compas/geometry/offset.py index 44f20a9b9d6..28c8b98c774 100644 --- a/src/compas/geometry/offset/offset.py +++ b/src/compas/geometry/offset.py @@ -12,7 +12,7 @@ from compas.geometry import normal_polygon from compas.geometry import is_colinear -from compas.data import is_item_iterable +from compas.data.validators import is_item_iterable from compas.utilities import iterable_like from compas.utilities import pairwise @@ -56,13 +56,13 @@ def offset_line(line, distance, normal=[0.0, 0.0, 1.0]): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` A line defined by two points. distances : float or list[float] The offset distance as float. A single value determines a constant offset. A list of two offset values can be used to a create variable offset at the start and end. - normal : [float, float, float] | :class:`~compas.geometry.Vector`, optional + normal : [float, float, float] | :class:`compas.geometry.Vector`, optional The normal of the offset plane. Returns @@ -70,16 +70,17 @@ def offset_line(line, distance, normal=[0.0, 0.0, 1.0]): tuple[[float, float, float], [float, float, float]] Two points defining the offset line. + See Also + -------- + offset_polyline + offset_polygon + Notes ----- The offset direction is chosen such that if the line were along the positve X axis and the normal of the offset plane is along the positive Z axis, the offset line is in the direction of the postive Y axis. - Examples - -------- - >>> - """ a, b = line @@ -102,7 +103,7 @@ def offset_polygon(polygon, distance, tol=1e-6): Parameters ---------- - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` The XYZ coordinates of the corners of the polygon. The first and last coordinates must not be identical. distance : float | list[tuple[float, float]] @@ -118,6 +119,11 @@ def offset_polygon(polygon, distance, tol=1e-6): The XYZ coordinates of the corners of the offset polygon. The first and last coordinates are identical. + See Also + -------- + offset_polyline + offset_line + Notes ----- The offset direction is determined by the normal of the polygon. @@ -158,13 +164,13 @@ def offset_polyline(polyline, distance, normal=[0.0, 0.0, 1.0], tol=1e-6): Parameters ---------- - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` The XYZ coordinates of the vertices of a polyline. distance : float | list[tuple[float, float]] The offset distance as float. A single value determines a constant offset globally. Alternatively, pairs of local offset values per line segment can be used to create variable offsets. - normal : [float, float, float] | :class:`~compas.geometry.Vector`, optional + normal : [float, float, float] | :class:`compas.geometry.Vector`, optional The normal of the offset plane. tol : float, optional A tolerance value for intersection calculations. @@ -174,6 +180,11 @@ def offset_polyline(polyline, distance, normal=[0.0, 0.0, 1.0], tol=1e-6): list[[float, float, float]] The XYZ coordinates of the resulting polyline. + See Also + -------- + offset_polygon + offset_line + Notes ----- The offset direction is determined by the provided normal vector. @@ -181,10 +192,6 @@ def offset_polyline(polyline, distance, normal=[0.0, 0.0, 1.0], tol=1e-6): positive offset distances will result in counterclockwise offsets, and negative values in clockwise direction. - Examples - -------- - >>> - """ if not is_item_iterable(distance): diff --git a/src/compas/geometry/offset/__init__.py b/src/compas/geometry/offset/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/geometry/plane.py b/src/compas/geometry/plane.py index 97977a14488..4044d38cebc 100644 --- a/src/compas/geometry/plane.py +++ b/src/compas/geometry/plane.py @@ -16,9 +16,9 @@ class Plane(Geometry): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The base point of the plane. - normal : [float, float, float] | :class:`~compas.geometry.Vector` + normal : [float, float, float] | :class:`compas.geometry.Vector` The normal vector of the plane. Attributes @@ -27,9 +27,9 @@ class Plane(Geometry): The coefficients of the plane equation. d : float, read-only The *d* parameter of the linear equation describing the plane. - normal : :class:`~compas.geometry.Vector` + normal : :class:`compas.geometry.Vector` The normal vector of the plane. - point : :class:`~compas.geometry.Plane` + point : :class:`compas.geometry.Plane` The base point of the plane. Examples @@ -148,16 +148,16 @@ def from_three_points(cls, a, b, c): # type: (...) -> Plane Parameters ---------- - a : [float, float, float] | :class:`~compas.geometry.Point` + a : [float, float, float] | :class:`compas.geometry.Point` The first point. - b : [float, float, float] | :class:`~compas.geometry.Point` + b : [float, float, float] | :class:`compas.geometry.Point` The second point. - c : [float, float, float] | :class:`~compas.geometry.Point` + c : [float, float, float] | :class:`compas.geometry.Point` The second point. Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` A plane with base point `a` and normal vector defined as the unitized cross product of the vectors `ab` and `ac`. @@ -182,16 +182,16 @@ def from_point_and_two_vectors(cls, point, u, v): # type: (...) -> Plane Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The base point. - u : [float, float, float] | :class:`~compas.geometry.Vector` + u : [float, float, float] | :class:`compas.geometry.Vector` The first vector. - v : [float, float, float] | :class:`~compas.geometry.Vector` + v : [float, float, float] | :class:`compas.geometry.Vector` The second vector. Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` A plane with base point `point` and normal vector defined as the unitized cross product of vectors `u` and `v`. @@ -218,7 +218,7 @@ def from_abcd(cls, abcd): # type: (...) -> Plane Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` """ a, b, c, d = abcd @@ -233,7 +233,7 @@ def worldXY(cls): # type: (...) -> Plane Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` The world XY plane. """ @@ -245,7 +245,7 @@ def worldYZ(cls): # type: (...) -> Plane Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` The world YZ plane. """ @@ -257,7 +257,7 @@ def worldZX(cls): # type: (...) -> Plane Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` The world ZX plane. """ @@ -269,7 +269,7 @@ def from_frame(cls, frame): # type: (...) -> Plane Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` A plane with the frame's `point` and the frame's `normal`. Examples @@ -290,12 +290,12 @@ def from_points(cls, points): # type: (...) -> Plane Parameters ---------- - points : list of [float, float, float] | :class:`~compas.geometry.Point` + points : list of [float, float, float] | :class:`compas.geometry.Point` The points. Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` The plane defined by the points. See Also @@ -326,7 +326,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` | list[list[float]] + T : :class:`compas.geometry.Transformation` | list[list[float]] The transformation. Returns @@ -356,7 +356,7 @@ def is_parallel(self, other, tol=1e-06): Parameters ---------- - other : :class:`~compas.geometry.Plane` + other : :class:`compas.geometry.Plane` The other plane. tol : float, optional Tolerance for the dot product of the normals. @@ -382,7 +382,7 @@ def is_perpendicular(self, other, tol=1e-06): Parameters ---------- - other : :class:`~compas.geometry.Plane` + other : :class:`compas.geometry.Plane` The other plane. tol : float, optional Tolerance for the dot product of the normals. @@ -410,7 +410,7 @@ def contains_point(self, point, tol=1e-06): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point. tol : float, optional Tolerance for the distance from the point to the plane. @@ -438,7 +438,7 @@ def distance_to_point(self, point): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point. Returns @@ -464,12 +464,12 @@ def closest_point(self, point): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point. Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` The closest point on the plane. Examples @@ -491,12 +491,12 @@ def projected_point(self, point, direction=None): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point. Returns ------- - :class:`~compas.geometry.Point` | None + :class:`compas.geometry.Point` | None The projected point, or None if a direction is given and it is parallel to the plane. Examples @@ -523,12 +523,12 @@ def mirrored_point(self, point): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point. Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` The mirrored point. Examples @@ -547,14 +547,14 @@ def intersection_with_line(self, line, tol=1e-06): Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` The line. tol : float, optional Tolerance for the dot product of the line vector and the plane normal. Returns ------- - :class:`~compas.geometry.Point` | None + :class:`compas.geometry.Point` | None The intersection point, or ``None`` if the line is parallel to the plane. Examples @@ -577,12 +577,12 @@ def intersection_with_plane(self, plane): Parameters ---------- - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` The other plane. Returns ------- - :class:`~compas.geometry.Line` | None + :class:`compas.geometry.Line` | None The intersection line, or None if the planes are parallel or coincident. Examples @@ -612,14 +612,14 @@ def intersections_with_curve(self, curve, tol=1e-06): Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` The curve. tol : float, optional Tolerance for the dot product of the line vector and the plane normal. Returns ------- - list of :class:`~compas.geometry.Point` + list of :class:`compas.geometry.Point` The intersection points. Examples @@ -647,7 +647,7 @@ def offset(self, distance): Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` The offset plane. """ diff --git a/src/compas/geometry/point.py b/src/compas/geometry/point.py index 324c18d0afc..910731b1551 100644 --- a/src/compas/geometry/point.py +++ b/src/compas/geometry/point.py @@ -254,7 +254,7 @@ def distance_to_point(self, point): Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The other point. Returns @@ -277,7 +277,7 @@ def distance_to_line(self, line): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` The line. Returns @@ -301,7 +301,7 @@ def distance_to_plane(self, plane): Parameters ---------- - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` The plane. Returns @@ -337,7 +337,7 @@ def in_polygon(self, polygon): Parameters ---------- - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` The polygon. Returns @@ -374,7 +374,7 @@ def in_convex_polygon(self, polygon): Parameters ---------- - polygon : sequence[point] | :class:`~compas.geometry.Polygon` + polygon : sequence[point] | :class:`compas.geometry.Polygon` The polygon. Returns @@ -407,7 +407,7 @@ def on_line(self, line, tol=1e-6): Parameters ---------- - line : [point, point] | :class:`~compas.geometry.Line` + line : [point, point] | :class:`compas.geometry.Line` The line. tol : float, optional A tolerance value for the distance between the point and the line. @@ -434,7 +434,7 @@ def on_segment(self, segment, tol=1e-6): Parameters ---------- - segment : [point, point] | :class:`~compas.geometry.Line` + segment : [point, point] | :class:`compas.geometry.Line` The segment. tol : float, optional A tolerance value for the distance between the point and the segment. @@ -461,7 +461,7 @@ def on_polyline(self, polyline): Parameters ---------- - polyline : sequence[point] | :class:`~compas.geometry.Polyline` + polyline : sequence[point] | :class:`compas.geometry.Polyline` The polyline. Returns @@ -486,7 +486,7 @@ def on_plane(self, plane, tol=1e-6): Parameters ---------- - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` The plane. tol : float, optional A tolerance value for the distance between the point and the plane. @@ -514,7 +514,7 @@ def on_circle(self, circle, tol=1e-6): Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` The circle. tol : float, optional A tolerance value for the distance between the point and the circle. @@ -535,7 +535,7 @@ def on_curve(self, curve, tol=1e-6): Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` The curve. tol : float, optional A tolerance value for the distance between the point and the curve. @@ -554,7 +554,7 @@ def in_triangle(self, triangle): Parameters ---------- - triangle : [point, point, point] | :class:`~compas.geometry.Polygon` + triangle : [point, point, point] | :class:`compas.geometry.Polygon` The triangle. Returns @@ -579,7 +579,7 @@ def in_circle(self, circle): Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` The circle. Returns @@ -610,7 +610,7 @@ def in_polyhedron(self, polyhedron): Parameters ---------- - polyhedron : [vertices, faces] | :class:`~compas.geometry.Polyhedron` + polyhedron : [vertices, faces] | :class:`compas.geometry.Polyhedron` The polyhedron. Returns @@ -634,7 +634,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` | list[list[float]] + T : :class:`compas.geometry.Transformation` | list[list[float]] The transformation matrix. Examples diff --git a/src/compas/geometry/pointcloud.py b/src/compas/geometry/pointcloud.py index 2b7ab46744b..4b069d98fd3 100644 --- a/src/compas/geometry/pointcloud.py +++ b/src/compas/geometry/pointcloud.py @@ -24,7 +24,7 @@ class Pointcloud(Geometry): Attributes ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The points of the cloud. Examples @@ -126,7 +126,7 @@ def from_ply(cls, filepath): Returns ------- - :class:`~compas.geometry.Pointcloud` + :class:`compas.geometry.Pointcloud` """ from compas.files import PLY @@ -149,7 +149,7 @@ def from_pcd(cls, filepath): Returns ------- - :class:`~compas.geometry.Pointcloud` + :class:`compas.geometry.Pointcloud` """ pass @@ -177,7 +177,7 @@ def from_bounds(cls, x, y, z, n): Returns ------- - :class:`~compas.geometry.Pointcloud` + :class:`compas.geometry.Pointcloud` Notes ----- @@ -221,14 +221,14 @@ def from_box(cls, box, n): Parameters ---------- - box: :class:`~compas.geometry.Box` + box: :class:`compas.geometry.Box` The axis aligned bounding box of the cloud. n: int The number of points in the cloud. Returns ------- - :class:`~compas.geometry.Pointcloud` + :class:`compas.geometry.Pointcloud` Examples -------- @@ -257,7 +257,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` The transformation. Returns @@ -279,12 +279,12 @@ def closest_point(self, point): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The point. Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` The closest point on the pointcloud. """ diff --git a/src/compas/geometry/polygon.py b/src/compas/geometry/polygon.py index 25232088398..d787d17c347 100644 --- a/src/compas/geometry/polygon.py +++ b/src/compas/geometry/polygon.py @@ -41,20 +41,20 @@ class Polygon(Geometry): Parameters ---------- - points : list[[float, float, float] | :class:`~compas.geometry.Point`] + points : list[[float, float, float] | :class:`compas.geometry.Point`] An ordered list of points. Attributes ---------- - points : list of :class:`~compas.geometry.Point` + points : list of :class:`compas.geometry.Point` The points of the polygon. - lines : list of :class:`~compas.geometry.Line`, read-only + lines : list of :class:`compas.geometry.Line`, read-only The lines of the polygon. length : float, read-only The length of the boundary. - centroid : :class:`~compas.geometry.Point`, read-only + centroid : :class:`compas.geometry.Point`, read-only The centroid of the polygon. - normal : :class:`~compas.geometry.Vector`, read-only + normal : :class:`compas.geometry.Vector`, read-only The (average) normal of the polygon. area : float, read-only The area of the polygon. @@ -241,9 +241,14 @@ def from_sides_and_radius_xy(cls, n, radius): Returns ------- - :class:`~compas.geometry.Polygon` + :class:`compas.geometry.Polygon` The constructed polygon. + Raises + ------ + ValueError + If the number of sides is smaller than 3. + Notes ----- The first point of the polygon aligns with the Y-axis. @@ -265,7 +270,9 @@ def from_sides_and_radius_xy(cls, n, radius): True """ - assert n >= 3, "Supplied number of sides must be at least 3!" + if n < 3: + raise ValueError("Supplied number of sides must be at least 3!") + points = [] side = math.pi * 2 / n for i in range(n): @@ -343,7 +350,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` | list[list[float]] + T : :class:`compas.geometry.Transformation` | list[list[float]] The transformation. Returns diff --git a/src/compas/geometry/polyhedron.py b/src/compas/geometry/polyhedron.py index adbb72c7e33..351eab4326d 100644 --- a/src/compas/geometry/polyhedron.py +++ b/src/compas/geometry/polyhedron.py @@ -153,7 +153,7 @@ class Polyhedron(Geometry): Parameters ---------- - vertices : list[[float, float, float] | :class:`~compas.geometry.Point`] + vertices : list[[float, float, float] | :class:`compas.geometry.Point`] The point locations of the vertices of the polyhedron. faces : list[list[int]] The faces as a list of index lists. @@ -359,7 +359,7 @@ def from_platonicsolid(cls, f): Returns ------- - :class:`~compas.geometry.Polyhedron` + :class:`compas.geometry.Polyhedron` The constructed polyhedron. References @@ -396,7 +396,7 @@ def from_halfspaces(cls, halfspaces, interior_point): Returns ------- - :class:`~compas.geometry.Polyhedron` + :class:`compas.geometry.Polyhedron` Examples -------- @@ -445,11 +445,11 @@ def from_planes(cls, planes): Parameters ---------- - planes : list[[point, normal] | :class:`~compas.geometry.Plane`] + planes : list[[point, normal] | :class:`compas.geometry.Plane`] Returns ------- - :class:`~compas.geometry.Polyhedron` + :class:`compas.geometry.Polyhedron` Examples -------- @@ -481,7 +481,7 @@ def from_convex_hull(cls, points): Returns ------- - :class:`~compas.geometry.Polyhedron` + :class:`compas.geometry.Polyhedron` Examples -------- @@ -532,7 +532,7 @@ def transform(self, transformation): Parameters ---------- - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` Returns ------- @@ -563,12 +563,12 @@ def boolean_union(self, other): Parameters ---------- - other : :class:`~compas.geometry.Polyhedron` + other : :class:`compas.geometry.Polyhedron` The polyhedron to add. Returns ------- - :class:`~compas.geometry.Polyhedron` + :class:`compas.geometry.Polyhedron` The resulting polyhedron. Examples @@ -592,12 +592,12 @@ def boolean_difference(self, other): Parameters ---------- - other : :class:`~compas.geometry.Polyhedron` + other : :class:`compas.geometry.Polyhedron` The polyhedron to subtract. Returns ------- - :class:`~compas.geometry.Polyhedron` + :class:`compas.geometry.Polyhedron` The resulting polyhedron. Examples @@ -621,12 +621,12 @@ def boolean_intersection(self, other): Parameters ---------- - other : :class:`~compas.geometry.Polyhedron` + other : :class:`compas.geometry.Polyhedron` The polyhedron to intersect with. Returns ------- - :class:`~compas.geometry.Polyhedron` + :class:`compas.geometry.Polyhedron` The resulting polyhedron. Examples diff --git a/src/compas/geometry/projection.py b/src/compas/geometry/projection.py index 7a0aef1823f..568bc4ad6c0 100644 --- a/src/compas/geometry/projection.py +++ b/src/compas/geometry/projection.py @@ -54,12 +54,12 @@ def from_plane(cls, plane): Parameters ---------- - plane : [point, normal] | :class:`~compas.geometry.Plane` + plane : [point, normal] | :class:`compas.geometry.Plane` The plane to project onto. Returns ------- - :class:`~compas.geometry.Projection` + :class:`compas.geometry.Projection` An orthogonal projection transformation. Examples @@ -80,14 +80,14 @@ def from_plane_and_direction(cls, plane, direction): Parameters ---------- - plane : [point, normal] | :class:`~compas.geometry.Plane` + plane : [point, normal] | :class:`compas.geometry.Plane` The plane to project onto. - direction : [float, float, float] | :class:`~compas.geometry.Vector` + direction : [float, float, float] | :class:`compas.geometry.Vector` The direction of projection direction. Returns ------- - :class:`~compas.geometry.Projection` + :class:`compas.geometry.Projection` A parallel projection transformation. Examples @@ -109,14 +109,14 @@ def from_plane_and_point(cls, plane, center_of_projection): Parameters ---------- - plane : [point, normal] | :class:`~compas.geometry.Plane` + plane : [point, normal] | :class:`compas.geometry.Plane` The plane to project onto. - center_of_projection : [float, float, float] | :class:`~compas.geometry.Point` + center_of_projection : [float, float, float] | :class:`compas.geometry.Point` The camera view point. Returns ------- - :class:`~compas.geometry.Projection` + :class:`compas.geometry.Projection` A perspective projection transformation. Examples @@ -144,7 +144,7 @@ def from_entries(cls, perspective_entries): Returns ------- - :class:`~compas.geometry.Projection` + :class:`compas.geometry.Projection` A projection transformation. """ diff --git a/src/compas/geometry/quadmesh/__init__.py b/src/compas/geometry/quadmesh/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/geometry/quadmesh/planarization.py b/src/compas/geometry/quadmesh_planarize.py similarity index 83% rename from src/compas/geometry/quadmesh/planarization.py rename to src/compas/geometry/quadmesh_planarize.py index 85d904db9a8..f2761e6a26d 100644 --- a/src/compas/geometry/quadmesh/planarization.py +++ b/src/compas/geometry/quadmesh_planarize.py @@ -23,9 +23,11 @@ def quadmesh_planarize(M, kmax=500, maxdev=0.005): list The coordinates of the new vertices. - Examples - -------- - >>> - """ raise NotImplementedError + + +quadmesh_planarize.__pluggable__ = True +quadmesh_planarize.__plugins__ = { + "libigl": "compas_libigl.planarize.quadmesh_planarize", +} diff --git a/src/compas/geometry/quaternion.py b/src/compas/geometry/quaternion.py index 8c5f4927cb6..265a9fb961c 100644 --- a/src/compas/geometry/quaternion.py +++ b/src/compas/geometry/quaternion.py @@ -242,12 +242,12 @@ def __mul__(self, other): Parameters ---------- - other : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + other : [float, float, float, float] | :class:`compas.geometry.Quaternion` A Quaternion. Returns ------- - :class:`~compas.geometry.Quaternion` + :class:`compas.geometry.Quaternion` The product :math:`P = R * Q` of this quaternion (R) multiplied by other quaternion (Q). Notes @@ -279,11 +279,11 @@ def from_frame(cls, frame): Parameters ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` Returns ------- - :class:`~compas.geometry.Quaternion` + :class:`compas.geometry.Quaternion` The new quaternion. Examples @@ -310,7 +310,7 @@ def from_matrix(cls, M): Returns ------- - :class:`~compas.geometry.Quaternion` + :class:`compas.geometry.Quaternion` The new quaternion. Examples @@ -330,11 +330,11 @@ def from_rotation(cls, R): Parameters ---------- - R : :class:`~compas.geometry.Rotation` + R : :class:`compas.geometry.Rotation` Returns ------- - :class:`~compas.geometry.Quaternion` + :class:`compas.geometry.Quaternion` The new quaternion. Examples @@ -376,7 +376,7 @@ def unitized(self): Returns ------- - :class:`~compas.geometry.Quaternion` + :class:`compas.geometry.Quaternion` Examples -------- @@ -417,7 +417,7 @@ def canonized(self): Returns ------- - :class:`~compas.geometry.Quaternion` + :class:`compas.geometry.Quaternion` A quaternion in canonic form. Examples @@ -457,7 +457,7 @@ def conjugated(self): Returns ------- - :class:`~compas.geometry.Quaternion` + :class:`compas.geometry.Quaternion` The conjugated quaternion. Examples diff --git a/src/compas/geometry/reflection.py b/src/compas/geometry/reflection.py index 7b32a1cf818..50699202d34 100644 --- a/src/compas/geometry/reflection.py +++ b/src/compas/geometry/reflection.py @@ -56,12 +56,12 @@ def from_plane(cls, plane): Parameters ---------- - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` The reflection plane. Returns ------- - :class:`~compas.geometry.Reflection` + :class:`compas.geometry.Reflection` The reflection transformation. """ @@ -81,11 +81,11 @@ def from_frame(cls, frame): Parameters ---------- - frame : [point, vector, vector] | :class:`~compas.geometry.Frame` + frame : [point, vector, vector] | :class:`compas.geometry.Frame` Returns ------- - :class:`~compas.geometry.Reflection` + :class:`compas.geometry.Reflection` The reflection transformation. """ diff --git a/src/compas/geometry/rotation.py b/src/compas/geometry/rotation.py index 41925c1baf8..34da1360261 100644 --- a/src/compas/geometry/rotation.py +++ b/src/compas/geometry/rotation.py @@ -41,13 +41,13 @@ class Rotation(Transformation): Attributes ---------- - quaternion : :class:`~compas.geometry.Quaternion`, read-only + quaternion : :class:`compas.geometry.Quaternion`, read-only The quaternion from the rotation. - axis_and_angle : tuple[:class:`~compas.geometry.Vector`, float], read-only + axis_and_angle : tuple[:class:`compas.geometry.Vector`, float], read-only The axis and the angle of the rotation. - axis_angle_vector : :class:`~compas.geometry.Vector`, read-only + axis_angle_vector : :class:`compas.geometry.Vector`, read-only The axis-angle vector of the rotation. - basis_vectors : tuple[:class:`~compas.geometry.Vector`, :class:`~compas.geometry.Vector`], read-only + basis_vectors : tuple[:class:`compas.geometry.Vector`, :class:`compas.geometry.Vector`], read-only The basis vectors of the rotation. Raises @@ -113,16 +113,16 @@ def from_axis_and_angle(cls, axis, angle, point=[0, 0, 0]): Parameters ---------- - axis : [float, float, float] | :class:`~compas.geometry.Vector` + axis : [float, float, float] | :class:`compas.geometry.Vector` Three numbers that represent the axis of rotation. angle : float The rotation angle in radians. - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` A point to perform a rotation around an origin other than [0, 0, 0]. Returns ------- - :class:`~compas.geometry.Rotation` + :class:`compas.geometry.Rotation` Notes ----- @@ -150,14 +150,14 @@ def from_basis_vectors(cls, xaxis, yaxis): Parameters ---------- - xaxis : [float, float, float] | :class:`~compas.geometry.Vector` + xaxis : [float, float, float] | :class:`compas.geometry.Vector` The x-axis of the frame. - yaxis : [float, float, float] | :class:`~compas.geometry.Vector` + yaxis : [float, float, float] | :class:`compas.geometry.Vector` The y-axis of the frame. Returns ------- - :class:`~compas.geometry.Rotation` + :class:`compas.geometry.Rotation` Examples -------- @@ -184,12 +184,12 @@ def from_frame(cls, frame): Parameters ---------- - frame : [point, vector, vector] | :class:`~compas.geometry.Frame` + frame : [point, vector, vector] | :class:`compas.geometry.Frame` A frame describing the targeted Cartesian coordinate system. Returns ------- - :class:`~compas.geometry.Rotation` + :class:`compas.geometry.Rotation` Notes ----- @@ -218,12 +218,12 @@ def from_quaternion(cls, quaternion): Parameters ---------- - quaternion : [float, float, float, float] | :class:`~compas.geometry.Quaternion` + quaternion : [float, float, float, float] | :class:`compas.geometry.Quaternion` Four numbers that represents the four coefficient values of a quaternion. Returns ------- - :class:`~compas.geometry.Rotation` + :class:`compas.geometry.Rotation` Examples -------- @@ -244,14 +244,14 @@ def from_axis_angle_vector(cls, axis_angle_vector, point=[0, 0, 0]): Parameters ---------- - axis_angle_vector : [float, float, float] | :class:`~compas.geometry.Vector` + axis_angle_vector : [float, float, float] | :class:`compas.geometry.Vector` Three numbers that represent the axis of rotation and angle of rotation through the vector's magnitude. - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional A point to perform a rotation around an origin other than [0, 0, 0]. Returns ------- - :class:`~compas.geometry.Rotation` + :class:`compas.geometry.Rotation` Examples -------- @@ -290,7 +290,7 @@ def from_euler_angles(cls, euler_angles, static=True, axes="xyz", **kwargs): Returns ------- - :class:`~compas.geometry.Rotation` + :class:`compas.geometry.Rotation` Examples -------- diff --git a/src/compas/geometry/scale.py b/src/compas/geometry/scale.py index 4cac8e7af13..3ec41ea15ba 100644 --- a/src/compas/geometry/scale.py +++ b/src/compas/geometry/scale.py @@ -70,12 +70,12 @@ def from_factors(cls, factors, frame=None): ---------- factors : [float, float, float] The scale factors along X, Y, Z. - frame : [point, vector, vector] | :class:`~compas.geometry.Frame`, optional + frame : [point, vector, vector] | :class:`compas.geometry.Frame`, optional The anchor frame for the scaling transformation. Returns ------- - :class:`~compas.geometry.Scale` + :class:`compas.geometry.Scale` A scale transformation. Examples diff --git a/src/compas/geometry/shapes/box.py b/src/compas/geometry/shapes/box.py index c9534366d46..0741c69d313 100644 --- a/src/compas/geometry/shapes/box.py +++ b/src/compas/geometry/shapes/box.py @@ -32,70 +32,72 @@ class Box(Shape): zsize : float, optional The size of the box in the box frame's z direction. Defaults to the value of ``xsize``. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The frame of the box. Defaults to ``Frame.worldXY()``. Attributes ---------- - xsize : float - The size of the box in the box frame's x direction. - ysize : float - The size of the box in the box frame's y direction. - zsize : float - The size of the box in the box frame's z direction. - frame : :class:`~compas.geometry.Frame` + area : float, read-only + The surface area of the box. + depth : float, read-only + The depth of the box in Y direction. + diagonal : :class:`compas.geometry.Line`, read-only + Diagonal of the box. + dimensions : list[float], read-only + The dimensions of the box in the local frame. + frame : :class:`compas.geometry.Frame` The box's frame. + height : float, read-only + The height of the box in Z direction. + volume : float, read-only + The volume of the box. + width : float, read-only + The width of the box in X direction. xmin : float, read-only Minimum value along local X axis. xmax : float, read-only Maximum value along local X axis. + xsize : float + The size of the box in the box frame's x direction. ymin : float, read-only Minimum value along local Y axis. ymax : float, read-only Maximum value along local Y axis. + ysize : float + The size of the box in the box frame's y direction. zmin : float, read-only Minimum value along local Z axis. zmax : float, read-only Maximum value along local Z axis. - width : float, read-only - The width of the box in X direction. - depth : float, read-only - The depth of the box in Y direction. - height : float, read-only - The height of the box in Z direction. - diagonal : :class:`~compas.geometry.Line`, read-only - Diagonal of the box. - dimensions : list[float], read-only - The dimensions of the box in the local frame. - area : float, read-only - The surface area of the box. - volume : float, read-only - The volume of the box. - points : list[:class:`~compas.geometry.Point`], read-only - The XYZ coordinates of the corners of the box. - vertices : list[:class:`~compas.geometry.Point`], read-only - The XYZ coordinates of the vertices of the box. - faces : list[list[int]], read-only - The faces of the box defined as lists of vertex indices. - bottom : list[int], read-only - The vertex indices of the bottom face. - front : list[int], read-only - The vertex indices of the front face. - right : list[int], read-only - The vertex indices of the right face. - back : list[int], read-only - The vertex indices of the back face. - left : list[int], read-only - The vertex indices of the left face. - top : list[int], read-only - The vertex indices of the top face. - edges : list[tuple[int, int]], read-only - The edges of the box as vertex index pairs. + zsize : float + The size of the box in the box frame's z direction. Examples -------- - >>> box = Box(Frame.worldXY(), 1.0, 2.0, 3.0) + >>> box = Box(1) + >>> box.xsize + 1.0 + >>> box.ysize + 1.0 + >>> box.zsize + 1.0 + >>> box.volume + 1.0 + >>> box.area + 6.0 + + >>> box = Box(1, 2, 3) + >>> box.xsize + 1.0 + >>> box.ysize + 2.0 + >>> box.zsize + 3.0 + >>> box.volume + 6.0 + >>> box.area + 22.0 """ @@ -259,8 +261,19 @@ def height(self): @property def diagonal(self): - vertices = self.vertices - return Line(vertices[0], vertices[-2]) + a = ( + self.frame.point + + self.frame.xaxis * -0.5 * self.xsize + + self.frame.yaxis * -0.5 * self.ysize + + self.frame.zaxis * -0.5 * self.zsize + ) + b = ( + self.frame.point + + self.frame.xaxis * 0.5 * self.xsize + + self.frame.yaxis * 0.5 * self.ysize + + self.frame.zaxis * 0.5 * self.zsize + ) + return Line(a, b) @property def dimensions(self): @@ -274,36 +287,6 @@ def area(self): def volume(self): return self.xsize * self.ysize * self.zsize - @property - def points(self): - return self.vertices - - @property - def vertices(self): - point = self.frame.point - xaxis = self.frame.xaxis - yaxis = self.frame.yaxis - zaxis = self.frame.zaxis - - dx = 0.5 * self.xsize - dy = 0.5 * self.ysize - dz = 0.5 * self.zsize - - a = point + xaxis * -dx + yaxis * -dy + zaxis * -dz - b = point + xaxis * -dx + yaxis * +dy + zaxis * -dz - c = point + xaxis * +dx + yaxis * +dy + zaxis * -dz - d = point + xaxis * +dx + yaxis * -dy + zaxis * -dz - e = a + zaxis * self.zsize - f = d + zaxis * self.zsize - g = c + zaxis * self.zsize - h = b + zaxis * self.zsize - - return [a, b, c, d, e, f, g, h] - - @property - def faces(self): - return [self.bottom, self.front, self.right, self.back, self.left, self.top] - @property def bottom(self): return [0, 1, 2, 3] @@ -328,19 +311,12 @@ def left(self): def top(self): return [4, 5, 6, 7] - @property - def edges(self): - edges = [(0, 1), (1, 2), (2, 3), (3, 0)] - edges += [(4, 5), (5, 6), (6, 7), (7, 4)] - edges += [(0, 4), (1, 7), (2, 6), (3, 5)] - return edges - # ========================================================================== # Constructors # ========================================================================== @classmethod - def from_width_height_depth(cls, width, height, depth): + def from_width_height_depth(cls, width, height, depth): # type: (...) -> Box """Construct a box from its width, height and depth. Note that width is along the X-axis, height along Z-axis, and depth along the Y-axis. @@ -356,7 +332,7 @@ def from_width_height_depth(cls, width, height, depth): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` The resulting box. Notes @@ -375,12 +351,12 @@ def from_width_height_depth(cls, width, height, depth): return cls(width, depth, height) @classmethod - def from_bounding_box(cls, bbox): + def from_bounding_box(cls, bbox): # type: (...) -> Box """Construct a box from the result of a bounding box calculation. Parameters ---------- - bbox : list[[float, float, float] | :class:`~compas.geometry.Point`] + bbox : list[[float, float, float] | :class:`compas.geometry.Point`] A list of 8 point locations, representing the corners of the bounding box. Positions 0, 1, 2, 3 are the bottom corners. Positions 4, 5, 6, 7 are the top corners. @@ -388,7 +364,7 @@ def from_bounding_box(cls, bbox): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` The box shape. Examples @@ -418,21 +394,21 @@ def from_bounding_box(cls, bbox): return cls(xsize=xsize, ysize=ysize, zsize=zsize, frame=frame) @classmethod - def from_corner_corner_height(cls, corner1, corner2, height): + def from_corner_corner_height(cls, corner1, corner2, height): # type: (...) -> Box """Construct a box from the opposite corners of its base and its height. Parameters ---------- - corner1 : [float, float, float] | :class:`~compas.geometry.Point` + corner1 : [float, float, float] | :class:`compas.geometry.Point` The XYZ coordinates of the bottom left corner of the base of the box. - corner2 : [float, float, float] | :class:`~compas.geometry.Point` + corner2 : [float, float, float] | :class:`compas.geometry.Point` The XYZ coordinates of the top right corner of the base of the box. height : float The height of the box. Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` The resulting box. Examples @@ -459,17 +435,17 @@ def from_corner_corner_height(cls, corner1, corner2, height): return cls(xsize=width, ysize=depth, zsize=height, frame=frame) @classmethod - def from_diagonal(cls, diagonal): + def from_diagonal(cls, diagonal): # type: (...) -> Box """Construct a box from its main diagonal. Parameters ---------- - diagonal : [point, point] | :class:`~compas.geometry.Line` + diagonal : [point, point] | :class:`compas.geometry.Line` The diagonal of the box, represented by a pair of points in space. Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` The resulting box. Examples @@ -497,21 +473,25 @@ def from_diagonal(cls, diagonal): return cls(width, depth, height, frame) - # @classmethod - # def from_points(cls, points): - # """Construct a box from a set of points. + @classmethod + def from_points(cls, points): # type: (...) -> Box + """Construct a box from a set of points. - # Parameters - # ---------- - # points : list[:class:`~compas.geometry.Point`] - # A list of points. + Parameters + ---------- + points : list[:class:`compas.geometry.Point`] + A list of points. - # Returns - # ------- - # :class:`~compas.geometry.Box` - # The resulting box. + Returns + ------- + :class:`compas.geometry.Box` + The resulting box. - # """ + """ + from compas.geometry import bounding_box + + bbox = bounding_box(points) + return cls.from_bounding_box(bbox) # ========================================================================== # Conversions @@ -532,14 +512,36 @@ def to_vertices_and_faces(self, triangulated=False): with each face defined as a list of indices into the list of vertices. """ + point = self.frame.point + xaxis = self.frame.xaxis + yaxis = self.frame.yaxis + zaxis = self.frame.zaxis + + dx = 0.5 * self.xsize + dy = 0.5 * self.ysize + dz = 0.5 * self.zsize + + a = point + xaxis * -dx + yaxis * -dy + zaxis * -dz + b = point + xaxis * -dx + yaxis * +dy + zaxis * -dz + c = point + xaxis * +dx + yaxis * +dy + zaxis * -dz + d = point + xaxis * +dx + yaxis * -dy + zaxis * -dz + e = a + zaxis * self.zsize + f = d + zaxis * self.zsize + g = c + zaxis * self.zsize + h = b + zaxis * self.zsize + + vertices = [a, b, c, d, e, f, g, h] + _faces = [self.bottom, self.front, self.right, self.back, self.left, self.top] + if triangulated: faces = [] - for a, b, c, d in self.faces: + for a, b, c, d in _faces: faces.append([a, b, c]) faces.append([a, c, d]) else: - faces = self.faces - return self.vertices, faces + faces = _faces + + return vertices, faces def to_brep(self): """Returns a BREP representation of the box. @@ -608,12 +610,58 @@ def scale(self, factor): # Methods # ========================================================================== + def corner(self, index): + """Return one of the eight corners of the box. + + Parameters + ---------- + index : int + The index of the corner. + + Returns + ------- + :class:`compas.geometry.Point` + The corner point. + + Raises + ------ + ValueError + If the index is not between 0 and 7. + + """ + if index < 0 or index > 7: + raise ValueError("Index should be between 0 and 7.") + + point = self.frame.point + xaxis = self.frame.xaxis + yaxis = self.frame.yaxis + zaxis = self.frame.zaxis + dx = 0.5 * self.xsize + dy = 0.5 * self.ysize + dz = 0.5 * self.zsize + if index == 0: + return point + xaxis * -dx + yaxis * -dy + zaxis * -dz + if index == 1: + return point + xaxis * -dx + yaxis * +dy + zaxis * -dz + if index == 2: + return point + xaxis * +dx + yaxis * +dy + zaxis * -dz + if index == 3: + return point + xaxis * +dx + yaxis * -dy + zaxis * -dz + if index == 4: + return point + xaxis * -dx + yaxis * -dy + zaxis * +dz + if index == 5: + return point + xaxis * -dx + yaxis * +dy + zaxis * +dz + if index == 6: + return point + xaxis * +dx + yaxis * +dy + zaxis * +dz + if index == 7: + return point + xaxis * +dx + yaxis * -dy + zaxis * +dz + def contains_point(self, point, tol=1e-6): """Verify if the box contains a given point. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point` + point : [float, float, float] | :class:`compas.geometry.Point` The point to test. tol : float, optional The tolerance for the point containment check. @@ -622,6 +670,10 @@ def contains_point(self, point, tol=1e-6): ------- bool + See Also + -------- + contains_points + """ T = Transformation.from_change_of_basis(Frame.worldXY(), self.frame) x, y, z = transform_points([point], T)[0] @@ -648,7 +700,7 @@ def contains_points(self, points, tol=1e-6): Parameters ---------- - points : list[[float, float, float]] | list[:class:`~compas.geometry.Point`] + points : list[[float, float, float]] | list[:class:`compas.geometry.Point`] A list of points. tol : float, optional The tolerance for the point containment check. @@ -657,6 +709,10 @@ def contains_points(self, points, tol=1e-6): ------- list[bool] + See Also + -------- + contains_point + Examples -------- >>> from compas.geometry import Point, Box diff --git a/src/compas/geometry/shapes/capsule.py b/src/compas/geometry/shapes/capsule.py index 1012f8162c4..f3afe31f650 100644 --- a/src/compas/geometry/shapes/capsule.py +++ b/src/compas/geometry/shapes/capsule.py @@ -30,37 +30,37 @@ class Capsule(Shape): height : float The height of the capsule along the z-axis of the frame. Half of the capsule is above the XY plane of the frame, the other half below. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system, or "frame", of the capsule. Default is ``None``, in which case the world coordinate system is used. Attributes ---------- - frame : :class:`~compas.geometry.Frame` - The local coordinate system of the capsule. - The capsule is oriented along the local z-axis. - transformation : :class:`~compas.geometry.Transformation` - The transformation of the capsule to global coordinates. - radius : float - The radius of the base circle of the capsule. - height : float - The height of the capsule. - axis : :class:`~compas.geometry.Line`, read-only + area : float, read-only + The surface area of the capsule. + axis : :class:`compas.geometry.Line`, read-only The central axis of the capsule. - base : :class:`~compas.geometry.Point`, read-only + base : :class:`compas.geometry.Point`, read-only The base point of the capsule. The base point is at the origin of the local coordinate system. - plane : :class:`~compas.geometry.Plane`, read-only - The plane of the capsule. - The base point of the plane is at the origin of the local coordinate system. - The normal of the plane is in the direction of the z-axis of the local coordinate system. - circle : :class:`~compas.geometry.Circle`, read-only + circle : :class:`compas.geometry.Circle`, read-only The base circle of the capsule. The center of the circle is at the origin of the local coordinate system. diameter : float, read-only The diameter of the base circle of the capsule. - area : float, read-only - The surface area of the capsule. + frame : :class:`compas.geometry.Frame` + The local coordinate system of the capsule. + The capsule is oriented along the local z-axis. + height : float + The height of the capsule. + plane : :class:`compas.geometry.Plane`, read-only + The plane of the capsule. + The base point of the plane is at the origin of the local coordinate system. + The normal of the plane is in the direction of the z-axis of the local coordinate system. + radius : float + The radius of the base circle of the capsule. + transformation : :class:`compas.geometry.Transformation` + The transformation of the capsule to global coordinates. volume : float, read-only The volume of the capsule. @@ -185,19 +185,19 @@ def area(self): # ========================================================================== @classmethod - def from_line_and_radius(cls, line, radius): + def from_line_and_radius(cls, line, radius): # type: (...) -> Capsule """Construct a capsule from a line and a radius. Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` The line. radius : float The radius. Returns ------- - :class:`~compas.geometry.Capsule` + :class:`compas.geometry.Capsule` The constructed capsule. See Also @@ -214,19 +214,19 @@ def from_line_and_radius(cls, line, radius): return cls(frame=frame, radius=radius, height=line.length) @classmethod - def from_circle_and_height(cls, circle, height): + def from_circle_and_height(cls, circle, height): # type: (...) -> Capsule """Construct a capsule from a circle and a height. Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` The circle. height : float The height. Returns ------- - :class:`~compas.geometry.Capsule` + :class:`compas.geometry.Capsule` The constructed capsule. See Also @@ -266,6 +266,11 @@ def to_vertices_and_faces(self, u=16, v=16, triangulated=False): A list of vertex locations, and a list of faces, with each face defined as a list of indices into the list of vertices. + Raises + ------ + ValueError + If the value for ``u`` or ``v`` is smaller than 3. + """ if u < 3: raise ValueError("The value for u should be u > 3.") @@ -342,9 +347,7 @@ def to_brep(self): :class:`compas.brep.Brep` """ - from compas.geometry import Brep - - return Brep.from_capsule(self) + raise NotImplementedError # ============================================================================= # Transformations @@ -375,7 +378,7 @@ def contains_point(self, point, tol=1e-6): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The point. tol : float, optional The tolerance for the test. @@ -386,6 +389,10 @@ def contains_point(self, point, tol=1e-6): True if the point is inside the capsule. False otherwise. + See Also + -------- + contains_points + """ T = Transformation.from_change_of_basis(Frame.worldXY(), self.frame) x, y, z = transform_points([point], T)[0] @@ -418,7 +425,7 @@ def contains_points(self, points, tol=1e-6): Parameters ---------- - points : list of :class:`~compas.geometry.Point` + points : list of :class:`compas.geometry.Point` The points. tol : float, optional The tolerance for the test. @@ -429,6 +436,10 @@ def contains_points(self, points, tol=1e-6): For each point, True if the point is inside the capsule. False otherwise. + See Also + -------- + contains_point + """ T = Transformation.from_change_of_basis(Frame.worldXY(), self.frame) points = transform_points(points, T) diff --git a/src/compas/geometry/shapes/cone.py b/src/compas/geometry/shapes/cone.py index d174ff3e40f..b35fda605d9 100644 --- a/src/compas/geometry/shapes/cone.py +++ b/src/compas/geometry/shapes/cone.py @@ -26,7 +26,7 @@ class Cone(Shape): Parameters ---------- - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system of the cone. Default is ``None``, in which case the world coordinate system is used. radius : float, optional @@ -38,31 +38,31 @@ class Cone(Shape): Attributes ---------- - frame : :class:`~compas.geometry.Frame` - The local coordinate system of the cone. - The cone is oriented along the local z-axis. - transformation : :class:`~compas.geometry.Transformation` - The transformation of the cone to global coordinates. - radius : float - The radius of the base circle of the cone. - height : float - The height of the cone. - axis : :class:`~compas.geometry.Line`, read-only + area : float, read-only + The surface area of the cone. + axis : :class:`compas.geometry.Line`, read-only The central axis of the cone. - base : :class:`~compas.geometry.Point`, read-only + base : :class:`compas.geometry.Point`, read-only The base point of the cone. The base point is at the origin of the local coordinate system. - plane : :class:`~compas.geometry.Plane`, read-only - The plane of the cone. - The base point of the plane is at the origin of the local coordinate system. - The normal of the plane is in the direction of the z-axis of the local coordinate system. - circle : :class:`~compas.geometry.Circle`, read-only + circle : :class:`compas.geometry.Circle`, read-only The base circle of the cone. The center of the circle is at the origin of the local coordinate system. diameter : float, read-only The diameter of the base circle of the cone. - area : float, read-only - The surface area of the cone. + frame : :class:`compas.geometry.Frame` + The local coordinate system of the cone. + The cone is oriented along the local z-axis. + height : float + The height of the cone. + plane : :class:`compas.geometry.Plane`, read-only + The plane of the cone. + The base point of the plane is at the origin of the local coordinate system. + The normal of the plane is in the direction of the z-axis of the local coordinate system. + radius : float + The radius of the base circle of the cone. + transformation : :class:`compas.geometry.Transformation` + The transformation of the cone to global coordinates. volume : float, read-only The volume of the cone. @@ -177,19 +177,19 @@ def volume(self): # ========================================================================== @classmethod - def from_line_and_radius(cls, line, radius): + def from_line_and_radius(cls, line, radius): # type: (...) -> Cone """Construct a cone from a line and a radius. Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` The axis of the cone. radius : float The radius of the base circle of the cone. Returns ------- - :class:`~compas.geometry.Cone` + :class:`compas.geometry.Cone` The cone. See Also @@ -206,19 +206,19 @@ def from_line_and_radius(cls, line, radius): return cls(frame=frame, radius=radius, height=line.length) @classmethod - def from_circle_and_height(cls, circle, height): + def from_circle_and_height(cls, circle, height): # type: (...) -> Cone """Construct a cone from a circle and a height. Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` The base circle of the cone. height : float The height of the cone. Returns ------- - :class:`~compas.geometry.Cone` + :class:`compas.geometry.Cone` The cone. See Also diff --git a/src/compas/geometry/shapes/cylinder.py b/src/compas/geometry/shapes/cylinder.py index 66caa7c9eab..8a9b4ff1865 100644 --- a/src/compas/geometry/shapes/cylinder.py +++ b/src/compas/geometry/shapes/cylinder.py @@ -29,37 +29,37 @@ class Cylinder(Shape): height : float The height of the cylinder along the z-axis of the frame. Half of the cylinder is above the XY plane of the frame, the other half below. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system, or "frame", of the cylinder. Default is ``None``, in which case the world coordinate system is used. Attributes ---------- - frame : :class:`~compas.geometry.Frame` - The local coordinate system of the cylinder. - The cylinder is oriented along the local z-axis. - transformation : :class:`~compas.geometry.Transformation` - The transformation of the cylinder to global coordinates. - radius : float - The radius of the base circle of the cylinder. - height : float - The height of the cylinder. - axis : :class:`~compas.geometry.Line`, read-only + area : float, read-only + The surface area of the cylinder. + axis : :class:`compas.geometry.Line`, read-only The central axis of the cylinder. - base : :class:`~compas.geometry.Point`, read-only + base : :class:`compas.geometry.Point`, read-only The base point of the cylinder. The base point is at the origin of the local coordinate system. - plane : :class:`~compas.geometry.Plane`, read-only - The plane of the cylinder. - The base point of the plane is at the origin of the local coordinate system. - The normal of the plane is in the direction of the z-axis of the local coordinate system. - circle : :class:`~compas.geometry.Circle`, read-only + circle : :class:`compas.geometry.Circle`, read-only The base circle of the cylinder. The center of the circle is at the origin of the local coordinate system. diameter : float, read-only The diameter of the base circle of the cylinder. - area : float, read-only - The surface area of the cylinder. + frame : :class:`compas.geometry.Frame` + The local coordinate system of the cylinder. + The cylinder is oriented along the local z-axis. + height : float + The height of the cylinder. + plane : :class:`compas.geometry.Plane`, read-only + The plane of the cylinder. + The base point of the plane is at the origin of the local coordinate system. + The normal of the plane is in the direction of the z-axis of the local coordinate system. + radius : float + The radius of the base circle of the cylinder. + transformation : :class:`compas.geometry.Transformation` + The transformation of the cylinder to global coordinates. volume : float, read-only The volume of the cylinder. @@ -178,19 +178,19 @@ def volume(self): # ========================================================================== @classmethod - def from_line_and_radius(cls, line, radius): + def from_line_and_radius(cls, line, radius): # type: (...) -> Cylinder """Construct a cylinder from a line and a radius. Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` The line. radius : float The radius. Returns ------- - :class:`~compas.geometry.Cylinder` + :class:`compas.geometry.Cylinder` The cylinder. Examples @@ -205,19 +205,19 @@ def from_line_and_radius(cls, line, radius): return cls(frame=frame, height=line.length, radius=radius) @classmethod - def from_circle_and_height(cls, circle, height): + def from_circle_and_height(cls, circle, height): # type: (...) -> Cylinder """Construct a cylinder from a circle and a height. Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` The circle. height : float The height. Returns ------- - :class:`~compas.geometry.Cylinder` + :class:`compas.geometry.Cylinder` The cylinder. Examples diff --git a/src/compas/geometry/shapes/shape.py b/src/compas/geometry/shapes/shape.py index c07760f25e4..47b01036b10 100644 --- a/src/compas/geometry/shapes/shape.py +++ b/src/compas/geometry/shapes/shape.py @@ -6,7 +6,6 @@ from compas.geometry import Frame from compas.geometry import Transformation from compas.geometry import Rotation -from compas.geometry import Plane class Shape(Geometry): @@ -33,16 +32,12 @@ class Shape(Geometry): Attributes ---------- + area : float, read-only + The surface area of the shape. frame : :class:`compas.geometry.Frame` The local coordinate system of the shape. transformation : :class:`compas.geometry.Transformation`, read-only The transformation of the shape to global coordinates. - normal : :class:`compas.geometry.Vector`, read-only - The normal of the shape. - plane : :class:`compas.geometry.Plane`, read-only - The plane of the shape. - area : float, read-only - The surface area of the shape. volume : float, read-only The volume of the shape. @@ -82,18 +77,6 @@ def transformation(self): self._transformation = Transformation.from_frame_to_frame(Frame.worldXY(), self.frame) return self._transformation - @property - def point(self): - return self.frame.point - - @point.setter - def point(self, point): - self.frame.point = point - - @property - def plane(self): - return Plane(self.frame.point, self.frame.zaxis) - @property def area(self): raise NotImplementedError @@ -200,6 +183,12 @@ def transform(self, transformation): ------- None + See Also + -------- + translate + rotate + scale + """ self.frame.transform(transformation) @@ -215,6 +204,12 @@ def translate(self, vector): ------- None + See Also + -------- + rotate + scale + transform + """ self.frame.point += vector @@ -230,6 +225,12 @@ def rotate(self, angle, axis=None, point=None): ------- None + See Also + -------- + translate + scale + transform + """ point = point or [0, 0, 0] matrix = Rotation.from_axis_and_angle(axis=axis, angle=angle, point=point) @@ -250,6 +251,12 @@ def scale(self, scale): ------- None + See Also + -------- + translate + rotate + transform + """ raise NotImplementedError @@ -262,7 +269,7 @@ def contains_point(self, point): Parameters ---------- - point : :class:`Point` + point : :class:`compas.geometry.Point` The point to test. Returns @@ -279,7 +286,7 @@ def contains_points(self, points): Parameters ---------- - points : list of :class:`Point` + points : list of :class:`compas.geometry.Point` The points to test. Returns diff --git a/src/compas/geometry/shapes/sphere.py b/src/compas/geometry/shapes/sphere.py index 34e975c1e5f..f51410824e8 100644 --- a/src/compas/geometry/shapes/sphere.py +++ b/src/compas/geometry/shapes/sphere.py @@ -20,37 +20,37 @@ class Sphere(Shape): ---------- radius: float The radius of the sphere. - frame: :class:`~compas.geometry.Frame`, optional + frame: :class:`compas.geometry.Frame`, optional The local coordinates system, or "frame", of the sphere. Default is ``None``, in which case the sphere is constructed in world coordinates. - point: :class:`~compas.geometry.Point`, optional + point: :class:`compas.geometry.Point`, optional The center of the sphere. When provided, this point overwrites the location of the origin of the local coordinate system. Attributes ---------- - frame : :class:`~compas.geometry.Frame` - The coordinate system of the sphere. - transformation : :class:`~compas.geometry.Transformation` - The transformation of the sphere to global coordinates. - radius : float - The radius of the sphere. - axis : :class:`~compas.geometry.Line`, read-only + area : float, read-only + The surface area of the sphere. + axis : :class:`compas.geometry.Line`, read-only The central axis of the sphere. - base : :class:`~compas.geometry.Point`, read-only + base : :class:`compas.geometry.Point`, read-only The base point of the sphere. The base point is at the origin of the local coordinate system. - plane : :class:`~compas.geometry.Plane`, read-only - The plane of the sphere. - The base point of the plane is at the origin of the local coordinate system. - The normal of the plane is in the direction of the z-axis of the local coordinate system. - circle : :class:`~compas.geometry.Circle`, read-only + circle : :class:`compas.geometry.Circle`, read-only The base circle of the sphere. The center of the circle is at the origin of the local coordinate system. diameter : float, read-only The diameter of the sphere. - area : float, read-only - The surface area of the sphere. + frame : :class:`compas.geometry.Frame` + The coordinate system of the sphere. + plane : :class:`compas.geometry.Plane`, read-only + The plane of the sphere. + The base point of the plane is at the origin of the local coordinate system. + The normal of the plane is in the direction of the z-axis of the local coordinate system. + radius : float + The radius of the sphere. + transformation : :class:`compas.geometry.Transformation` + The transformation of the sphere to global coordinates. volume : float, read-only The volume of the sphere. @@ -149,19 +149,19 @@ def volume(self): # ========================================================================== @classmethod - def from_point_and_radius(cls, point, radius): + def from_point_and_radius(cls, point, radius): # type: (...) -> Sphere """Construct a sphere from a point and a radius. Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The center of the sphere. radius : float The radius of the sphere. Returns ------- - :class:`~compas.geometry.Sphere` + :class:`compas.geometry.Sphere` The constructed sphere. """ @@ -277,7 +277,7 @@ def to_brep(self): # Parameters # ---------- - # transformation : :class:`~compas.geometry.Transformation` + # transformation : :class:`compas.geometry.Transformation` # The transformation used to transform the Sphere. # Note that non-similarity preserving transformations will not change # the sphere into an ellipsoid. In such case, the radius of the sphere @@ -326,7 +326,7 @@ def contains_point(self, point, tol=1e-6): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The point to test. tol : float, optional The tolerance for the test. @@ -345,7 +345,7 @@ def contains_points(self, points, tol=1e-6): Parameters ---------- - points : list of :class:`~compas.geometry.Point` + points : list of :class:`compas.geometry.Point` The points to test. tol : float, optional The tolerance for the test. diff --git a/src/compas/geometry/shapes/torus.py b/src/compas/geometry/shapes/torus.py index 7265bbe2a7c..832593c8ef1 100644 --- a/src/compas/geometry/shapes/torus.py +++ b/src/compas/geometry/shapes/torus.py @@ -23,30 +23,30 @@ class Torus(Shape): The radius of the axis. radius_pipe: float, optional The radius of the pipe. - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system of the torus. Default is ``None``, in which case the torus is constructed in the world XY plane. Attributes ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` The coordinate system of the torus. - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation of the sphere to global coordinates. radius_axis : float The radius of the axis. radius_pipe : float The radius of the pipe. - axis : :class:`~compas.geometry.Line`, read-only + axis : :class:`compas.geometry.Line`, read-only The central axis of the torus. - base : :class:`~compas.geometry.Point`, read-only + base : :class:`compas.geometry.Point`, read-only The base point of the torus. The base point is at the origin of the local coordinate system. - plane : :class:`~compas.geometry.Plane`, read-only + plane : :class:`compas.geometry.Plane`, read-only The plane of the torus. The base point of the plane is at the origin of the local coordinate system. The normal of the plane is in the direction of the z-axis of the local coordinate system. - circle : :class:`~compas.geometry.Circle`, read-only + circle : :class:`compas.geometry.Circle`, read-only The base circle of the torus. The center of the circle is at the origin of the local coordinate system. area : float, read-only @@ -189,7 +189,7 @@ def from_plane_and_radii(cls, plane, radius_axis, radius_pipe): Parameters ---------- - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` The plane of the torus. radius_axis: float The radius of the axis. @@ -198,7 +198,7 @@ def from_plane_and_radii(cls, plane, radius_axis, radius_pipe): Returns ------- - :class:`~compas.geometry.Torus` + :class:`compas.geometry.Torus` The constructed torus. Examples @@ -302,7 +302,7 @@ def transform(self, transformation): Parameters ---------- - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` The transformation used to transform the Torus. Returns diff --git a/src/compas/geometry/shear.py b/src/compas/geometry/shear.py index 63c2e6d25fa..eac095bb22f 100644 --- a/src/compas/geometry/shear.py +++ b/src/compas/geometry/shear.py @@ -59,15 +59,15 @@ def from_angle_direction_plane(cls, angle, direction, plane): ---------- angle : float The angle in radians. - direction : [float, float, float] | :class:`~compas.geometry.Vector` + direction : [float, float, float] | :class:`compas.geometry.Vector` The direction vector as list of 3 numbers. It must be orthogonal to the normal vector (i.e. it must lie in the shear plane). - plane : [point, vector] | :class:`~compas.geometry.Plane` + plane : [point, vector] | :class:`compas.geometry.Plane` The shear plane defined by a point and normal. Returns ------- - :class:`~compas.geometry.Shear` + :class:`compas.geometry.Shear` The shear transformation object. Raises @@ -100,7 +100,7 @@ def from_entries(cls, shear_entries): Returns ------- - :class:`~compas.geometry.Shear` + :class:`compas.geometry.Shear` The shear transformation object. Examples diff --git a/src/compas/geometry/surfaces/nurbs.py b/src/compas/geometry/surfaces/nurbs.py index 59a972689fe..baf343b4f73 100644 --- a/src/compas/geometry/surfaces/nurbs.py +++ b/src/compas/geometry/surfaces/nurbs.py @@ -46,7 +46,7 @@ class NurbsSurface(Surface): Attributes ---------- - points : list[list[:class:`~compas.geometry.Point`]], read-only + points : list[list[:class:`compas.geometry.Point`]], read-only The control points as rows along the U direction. weights : list[list[float]], read-only The weights of the control points. @@ -138,7 +138,7 @@ def from_data(cls, data): Returns ------- - :class:`~compas.geometry.NurbsSurface` + :class:`compas.geometry.NurbsSurface` The constructed surface. """ @@ -221,7 +221,7 @@ def from_parameters( Parameters ---------- - points : list[list[[float, float, float] | :class:`~compas.geometry.Point`]] + points : list[list[[float, float, float] | :class:`compas.geometry.Point`]] The control points. weights : list[list[float]] The weights of the control points. @@ -240,7 +240,7 @@ def from_parameters( Returns ------- - :class:`~compas.geometry.NurbsSurface` + :class:`compas.geometry.NurbsSurface` """ return new_nurbssurface_from_parameters( @@ -263,7 +263,7 @@ def from_points(cls, points, degree_u=3, degree_v=3): Parameters ---------- - points : list[list[[float, float, float] | :class:`~compas.geometry.Point`]] + points : list[list[[float, float, float] | :class:`compas.geometry.Point`]] The control points. degree_u : int Degree in the U direction. @@ -272,7 +272,7 @@ def from_points(cls, points, degree_u=3, degree_v=3): Returns ------- - :class:`~compas.geometry.NurbsSurface` + :class:`compas.geometry.NurbsSurface` """ return new_nurbssurface_from_points(cls, points, degree_u=degree_u, degree_v=degree_v) @@ -290,7 +290,7 @@ def from_meshgrid(cls, nu=10, nv=10): Returns ------- - :class:`~compas.geometry.NurbsSurface` + :class:`compas.geometry.NurbsSurface` """ UU, VV = meshgrid(linspace(0, nu, nu + 1), linspace(0, nv, nv + 1)) @@ -312,7 +312,7 @@ def from_step(cls, filepath): Returns ------- - :class:`~compas.geometry.NurbsSurface` + :class:`compas.geometry.NurbsSurface` """ return new_nurbssurface_from_step(cls, filepath) @@ -340,7 +340,7 @@ def from_fill(cls, curve1, curve2, curve3=None, curve4=None, style="stretch"): Returns ------- - :class:`~compas.geometry.NurbsSurface` + :class:`compas.geometry.NurbsSurface` """ return new_nurbssurface_from_fill(cls, curve1, curve2, curve3, curve4, style) @@ -358,7 +358,7 @@ def copy(self): Returns ------- - :class:`~compas.geometry.NurbsSurface` + :class:`compas.geometry.NurbsSurface` """ return NurbsSurface.from_parameters( diff --git a/src/compas/geometry/surfaces/planar.py b/src/compas/geometry/surfaces/planar.py index e8cae9b2870..3162ec6b11e 100644 --- a/src/compas/geometry/surfaces/planar.py +++ b/src/compas/geometry/surfaces/planar.py @@ -14,7 +14,7 @@ class PlanarSurface(Surface): Parameters ---------- - frame : :class:`~compas.geometry.Frame`, optional + frame : :class:`compas.geometry.Frame`, optional The local coordinate system of the surface. Default is ``None``, in which case the world coordinate system is used. xsize : float, optional diff --git a/src/compas/geometry/surfaces/surface.py b/src/compas/geometry/surfaces/surface.py index dad1e20c3bd..8fcd52c5a9e 100644 --- a/src/compas/geometry/surfaces/surface.py +++ b/src/compas/geometry/surfaces/surface.py @@ -34,10 +34,10 @@ class Surface(Geometry): Attributes ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` The local coordinate system of the surface. Default is the world coordinate system. - transformation : :class:`~compas.geometry.Transformation`, read-only + transformation : :class:`compas.geometry.Transformation`, read-only The transformation from the surface's local coordinate system to the world coordinate system. domain_u : tuple[float, float], read-only The parameter domain of the surface in the U direction. @@ -160,7 +160,7 @@ def from_step(cls, filepath): Returns ------- - :class:`~compas.geometry.Surface` + :class:`compas.geometry.Surface` """ raise NotImplementedError @@ -176,7 +176,7 @@ def from_obj(cls, filepath): Returns ------- - :class:`~compas.geometry.Surface` + :class:`compas.geometry.Surface` """ raise NotImplementedError @@ -192,7 +192,7 @@ def from_plane(cls, plane, *args, **kwargs): Returns ------- - :class:`~compas.geometry.Surface` + :class:`compas.geometry.Surface` """ return new_surface_from_plane(cls, plane, *args, **kwargs) @@ -285,7 +285,7 @@ def to_triangles(self, nu=16, nv=16, du=None, dv=None): Returns ------- - list[list[:class:`~compas.geometry.Point`]] + list[list[:class:`compas.geometry.Point`]] """ vertices, faces = self.to_vertices_and_faces(nu=nu, nv=nv, du=du, dv=dv) @@ -316,7 +316,7 @@ def to_quads(self, nu=16, nv=16, du=None, dv=None): Returns ------- - list[list[:class:`~compas.geometry.Point`]] + list[list[:class:`compas.geometry.Point`]] """ vertices, faces = self.to_vertices_and_faces(nu=nu, nv=nv, du=du, dv=dv) @@ -388,7 +388,7 @@ def to_tesselation(self): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` """ raise NotImplementedError @@ -413,7 +413,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` The transformation. Returns @@ -475,7 +475,7 @@ def isocurve_u(self, u): Returns ------- - :class:`~compas.geometry.Curve` + :class:`compas.geometry.Curve` """ raise NotImplementedError @@ -489,7 +489,7 @@ def isocurve_v(self, v): Returns ------- - :class:`~compas_occ.geometry.Curve` + :class:`compas_occ.geometry.Curve` """ raise NotImplementedError @@ -499,7 +499,7 @@ def boundary(self): Returns ------- - list[:class:`~compas.geometry.Curve`] + list[:class:`compas.geometry.Curve`] """ raise NotImplementedError @@ -527,7 +527,7 @@ def point_at(self, u, v): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` """ raise NotImplementedError @@ -542,7 +542,7 @@ def normal_at(self, u, v): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` """ raise NotImplementedError @@ -557,7 +557,7 @@ def curvature_at(self, u, v): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` """ raise NotImplementedError @@ -572,7 +572,7 @@ def frame_at(self, u, v): Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` """ raise NotImplementedError @@ -593,7 +593,7 @@ def closest_point(self, point, return_parameters=False): Returns ------- - :class:`~compas.geometry.Point` | tuple[:class:`~compas.geometry.Point`, tuple[float, float]] + :class:`compas.geometry.Point` | tuple[:class:`compas.geometry.Point`, tuple[float, float]] If `return_parameters` is False, the nearest point on the surface. If `return_parameters` is True, the UV parameters in addition to the nearest point on the surface. @@ -610,7 +610,7 @@ def aabb(self, precision=0.0, optimal=False): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` """ raise NotImplementedError @@ -624,7 +624,7 @@ def obb(self, precision=0.0): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` """ raise NotImplementedError @@ -634,11 +634,11 @@ def intersections_with_line(self, line): Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` Returns ------- - list[:class:`~compas.geometry.Point`] + list[:class:`compas.geometry.Point`] """ raise NotImplementedError @@ -648,11 +648,11 @@ def intersections_with_curve(self, curve): Parameters ---------- - line : :class:`~compas.geometry.Curve` + line : :class:`compas.geometry.Curve` Returns ------- - list[:class:`~compas.geometry.Point`] + list[:class:`compas.geometry.Point`] """ raise NotImplementedError @@ -662,11 +662,11 @@ def intersections_with_plane(self, plane): Parameters ---------- - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` Returns ------- - list[:class:`~compas.geometry.Curve`] + list[:class:`compas.geometry.Curve`] """ raise NotImplementedError @@ -683,7 +683,7 @@ def intersections_with_plane(self, plane): # Returns # ------- - # :class:`~compas.geometry.NurbsSurface` + # :class:`compas.geometry.NurbsSurface` # """ # raise NotImplementedError diff --git a/src/compas/geometry/transformation.py b/src/compas/geometry/transformation.py index ad8b5924efb..31df673db2c 100644 --- a/src/compas/geometry/transformation.py +++ b/src/compas/geometry/transformation.py @@ -48,19 +48,19 @@ class Transformation(Data): Attributes ---------- - scale : :class:`~compas.geometry.Scale`, read-only + scale : :class:`compas.geometry.Scale`, read-only The scale component of the transformation matrix. - shear : :class:`~compas.geometry.Shear`, read-only + shear : :class:`compas.geometry.Shear`, read-only The shear component of the transformation matrix. - rotation : :class:`~compas.geometry.Rotation`, read-only + rotation : :class:`compas.geometry.Rotation`, read-only The rotation component of the transformation matrix. - translation : :class:`~compas.geometry.Translation`, read-only + translation : :class:`compas.geometry.Translation`, read-only The translation component of the transformation matrix. - projection : :class:`~compas.geometry.Projection`, read-only + projection : :class:`compas.geometry.Projection`, read-only The projection component of the transformation matrix. - translation_vector : :class:`~compas.geometry.Vector`, read-only + translation_vector : :class:`compas.geometry.Vector`, read-only The translation component of the transformation matrix as a translation vector. - basis_vectors : tuple[:class:`~compas.geometry.Vector`, :class:`~compas.geometry.Vector`], read-only + basis_vectors : tuple[:class:`compas.geometry.Vector`, :class:`compas.geometry.Vector`], read-only The basis vectors from the rotation component of the transformation matrix. list : list[float], read-only Flattens the 4x4 transformation matrix into a list of 16 numbers. @@ -221,7 +221,7 @@ def from_matrix(cls, matrix): Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The transformation. """ @@ -238,7 +238,7 @@ def from_list(cls, numbers): Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The transformation. Notes @@ -276,7 +276,7 @@ def from_euler_angles(cls, euler_angles, static=True, axes="xyz", point=[0, 0, 0 Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The transformation. """ @@ -292,12 +292,12 @@ def from_frame(cls, frame): Parameters ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` A frame describing the targeted Cartesian coordinate system. Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The transformation. Notes @@ -326,14 +326,14 @@ def from_frame_to_frame(cls, frame_from, frame_to): Parameters ---------- - frame_from : :class:`~compas.geometry.Frame` + frame_from : :class:`compas.geometry.Frame` A frame defining the original Cartesian coordinate system. - frame_to : :class:`~compas.geometry.Frame` + frame_to : :class:`compas.geometry.Frame` A frame defining the targeted Cartesian coordinate system. Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The transformation. Examples @@ -360,14 +360,14 @@ def from_change_of_basis(cls, frame_from, frame_to): Parameters ---------- - frame_from : :class:`~compas.geometry.Frame` + frame_from : :class:`compas.geometry.Frame` A frame defining the original Cartesian coordinate system. - frame_to : :class:`~compas.geometry.Frame` + frame_to : :class:`compas.geometry.Frame` A frame defining the targeted Cartesian coordinate system. Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The transformation representing a change of basis. Examples @@ -396,7 +396,7 @@ def copy(self): Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` An independent copy of the transformation. """ @@ -425,7 +425,7 @@ def transposed(self): Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The transposed transformation object. """ @@ -449,7 +449,7 @@ def inverse(self): Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The inverse transformation. Examples @@ -473,15 +473,15 @@ def decomposed(self): Returns ------- - :class:`~compas.geometry.Scale` + :class:`compas.geometry.Scale` The scale component of the current transformation. - :class:`~compas.geometry.Shear` + :class:`compas.geometry.Shear` The shear component of the current transformation. - :class:`~compas.geometry.Rotation` + :class:`compas.geometry.Rotation` The rotation component of the current transformation. - :class:`~compas.geometry.Translation` + :class:`compas.geometry.Translation` The translation component of the current transformation. - :class:`~compas.geometry.Projection` + :class:`compas.geometry.Projection` The projection component of the current transformation. Examples @@ -522,7 +522,7 @@ def concatenate(self, other): Parameters ---------- - other: :class:`~compas.geometry.Transformation` + other: :class:`compas.geometry.Transformation` The transformation object to concatenate. Returns @@ -542,12 +542,12 @@ def concatenated(self, other): Parameters ---------- - other : :class:`~compas.geometry.Transformation` + other : :class:`compas.geometry.Transformation` The transformation object to concatenate. Returns ------- - :class:`~compas.geometry.Transformation` + :class:`compas.geometry.Transformation` The new transformation that is the concatenation of this one and the other. Notes diff --git a/src/compas/geometry/translation.py b/src/compas/geometry/translation.py index cb52359950a..59fafb2eaba 100644 --- a/src/compas/geometry/translation.py +++ b/src/compas/geometry/translation.py @@ -29,7 +29,7 @@ class Translation(Transformation): Attributes ---------- - translation_vector : :class:`~compas.geometry.Vector` + translation_vector : :class:`compas.geometry.Vector` The translation vector. Raises @@ -88,12 +88,12 @@ def from_vector(cls, vector): Parameters ---------- - vector : [float, float, float] | :class:`~compas.geometry.Vector` + vector : [float, float, float] | :class:`compas.geometry.Vector` The translation vector. Returns ------- - :class:`~compas.geometry.Translation` + :class:`compas.geometry.Translation` The translation transformation. """ diff --git a/src/compas/geometry/triangulation/__init__.py b/src/compas/geometry/triangulation_delaunay.py similarity index 100% rename from src/compas/geometry/triangulation/__init__.py rename to src/compas/geometry/triangulation_delaunay.py diff --git a/src/compas/geometry/triangulation/delaunay.py b/src/compas/geometry/triangulation_delaunay_none.py similarity index 95% rename from src/compas/geometry/triangulation/delaunay.py rename to src/compas/geometry/triangulation_delaunay_none.py index 9a679ad1408..c4c27214841 100644 --- a/src/compas/geometry/triangulation/delaunay.py +++ b/src/compas/geometry/triangulation_delaunay_none.py @@ -21,11 +21,11 @@ def delaunay_from_points(points, boundary=None, holes=None, tiny=1e-12): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] XYZ coordinates of the original points. - boundary : sequence[[float, float, float] | :class:`~compas.geometry.Point`] | :class:`~compas.geometry.Polygon`, optional + boundary : sequence[[float, float, float] | :class:`compas.geometry.Point`] | :class:`compas.geometry.Polygon`, optional List of ordered points describing the outer boundary. - holes : sequence[sequence[[float, float, float] | :class:`~compas.geometry.Point`] | :class:`~compas.geometry.Polygon`], optional + holes : sequence[sequence[[float, float, float] | :class:`compas.geometry.Point`] | :class:`compas.geometry.Polygon`], optional List of polygons (ordered points describing internal holes. Returns diff --git a/src/compas/geometry/triangulation/delaunay_numpy.py b/src/compas/geometry/triangulation_delaunay_numpy.py similarity index 86% rename from src/compas/geometry/triangulation/delaunay_numpy.py rename to src/compas/geometry/triangulation_delaunay_numpy.py index d9eef25ccad..c3f4975e844 100644 --- a/src/compas/geometry/triangulation/delaunay_numpy.py +++ b/src/compas/geometry/triangulation_delaunay_numpy.py @@ -12,7 +12,7 @@ def delaunay_from_points_numpy(points): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] XYZ coordinates of the original points. Returns @@ -36,7 +36,7 @@ def voronoi_from_points_numpy(points): Parameters ---------- - points : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + points : sequence[[float, float, float] | :class:`compas.geometry.Point`] XYZ coordinates of the voronoi sites. Returns diff --git a/src/compas/geometry/triangulation/earclip.py b/src/compas/geometry/triangulation_earclip.py similarity index 100% rename from src/compas/geometry/triangulation/earclip.py rename to src/compas/geometry/triangulation_earclip.py diff --git a/src/compas/geometry/trimesh/__init__.py b/src/compas/geometry/trimesh/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/geometry/trimesh/curvature.py b/src/compas/geometry/trimesh_curvature.py similarity index 80% rename from src/compas/geometry/trimesh/curvature.py rename to src/compas/geometry/trimesh_curvature.py index 1e0f688a055..7e314491bf9 100644 --- a/src/compas/geometry/trimesh/curvature.py +++ b/src/compas/geometry/trimesh_curvature.py @@ -11,7 +11,7 @@ def trimesh_gaussian_curvature(M): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns @@ -33,7 +33,7 @@ def trimesh_principal_curvature(M): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns @@ -55,7 +55,7 @@ def trimesh_mean_curvature(M): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns diff --git a/src/compas/geometry/trimesh/descent_numpy.py b/src/compas/geometry/trimesh_descent_numpy.py similarity index 90% rename from src/compas/geometry/trimesh/descent_numpy.py rename to src/compas/geometry/trimesh_descent_numpy.py index 821209440e4..16a1bf9e35f 100644 --- a/src/compas/geometry/trimesh/descent_numpy.py +++ b/src/compas/geometry/trimesh_descent_numpy.py @@ -1,5 +1,5 @@ from numpy import asarray -from .gradient_numpy import trimesh_gradient_numpy +from .trimesh_gradient_numpy import trimesh_gradient_numpy def trimesh_descent_numpy(M): diff --git a/src/compas/geometry/trimesh/geodistance.py b/src/compas/geometry/trimesh_geodistance.py similarity index 89% rename from src/compas/geometry/trimesh/geodistance.py rename to src/compas/geometry/trimesh_geodistance.py index 513aab0c516..258c53a02c2 100644 --- a/src/compas/geometry/trimesh/geodistance.py +++ b/src/compas/geometry/trimesh_geodistance.py @@ -11,7 +11,7 @@ def trimesh_geodistance(M, source, method="exact"): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. source : int The index of the vertex from where the geodesic distances should be calculated. diff --git a/src/compas/geometry/trimesh/gradient_numpy.py b/src/compas/geometry/trimesh_gradient_numpy.py similarity index 100% rename from src/compas/geometry/trimesh/gradient_numpy.py rename to src/compas/geometry/trimesh_gradient_numpy.py diff --git a/src/compas/geometry/trimesh/isolines.py b/src/compas/geometry/trimesh_isolines.py similarity index 89% rename from src/compas/geometry/trimesh/isolines.py rename to src/compas/geometry/trimesh_isolines.py index 4b0ecb0a3c4..f312694a5a9 100644 --- a/src/compas/geometry/trimesh/isolines.py +++ b/src/compas/geometry/trimesh_isolines.py @@ -12,7 +12,7 @@ def trimesh_isolines(M, S, N=50): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. S : list[float] A list of scalars. diff --git a/src/compas/geometry/trimesh/matrices.py b/src/compas/geometry/trimesh_matrices.py similarity index 83% rename from src/compas/geometry/trimesh/matrices.py rename to src/compas/geometry/trimesh_matrices.py index d1aa7cc1501..9a4643bccab 100644 --- a/src/compas/geometry/trimesh/matrices.py +++ b/src/compas/geometry/trimesh_matrices.py @@ -12,7 +12,7 @@ def trimesh_massmatrix(M): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns diff --git a/src/compas/geometry/trimesh/parametrisation.py b/src/compas/geometry/trimesh_parametrisation.py similarity index 81% rename from src/compas/geometry/trimesh/parametrisation.py rename to src/compas/geometry/trimesh_parametrisation.py index fd62c4c0c56..60e38e6150f 100644 --- a/src/compas/geometry/trimesh/parametrisation.py +++ b/src/compas/geometry/trimesh_parametrisation.py @@ -11,7 +11,7 @@ def trimesh_harmonic(M): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns @@ -33,7 +33,7 @@ def trimesh_lscm(M): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns diff --git a/src/compas/geometry/trimesh/remesh.py b/src/compas/geometry/trimesh_remeshing.py similarity index 88% rename from src/compas/geometry/trimesh/remesh.py rename to src/compas/geometry/trimesh_remeshing.py index 1879adf518c..cbc180f7e0b 100644 --- a/src/compas/geometry/trimesh/remesh.py +++ b/src/compas/geometry/trimesh_remeshing.py @@ -11,7 +11,7 @@ def trimesh_remesh(mesh, target_edge_length, number_of_iterations=10, do_project Parameters ---------- - mesh : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + mesh : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. target_edge_length : float The target edge length. @@ -42,7 +42,7 @@ def trimesh_remesh_constrained(mesh, target_edge_length, protected_edges, number Parameters ---------- - mesh : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + mesh : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. target_edge_length : float The target edge length. @@ -70,7 +70,7 @@ def trimesh_remesh_along_isoline(mesh, scalarfield, scalar): Parameters ---------- - mesh : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + mesh : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. scalarfield : sequence[float] A scalar value per vertex of the mesh. diff --git a/src/compas/geometry/trimesh/slicing.py b/src/compas/geometry/trimesh_slicing.py similarity index 74% rename from src/compas/geometry/trimesh/slicing.py rename to src/compas/geometry/trimesh_slicing.py index 635f430a000..2b46cd2ce55 100644 --- a/src/compas/geometry/trimesh/slicing.py +++ b/src/compas/geometry/trimesh_slicing.py @@ -11,9 +11,9 @@ def trimesh_slice(mesh, planes): Parameters ---------- - mesh : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + mesh : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. - planes : sequence[[point, vector] | :class:`~compas.geometry.Plane`] + planes : sequence[[point, vector] | :class:`compas.geometry.Plane`] The slicing planes. Returns diff --git a/src/compas/geometry/vector.py b/src/compas/geometry/vector.py index 0e43d8beb79..61ec4c7a0ea 100644 --- a/src/compas/geometry/vector.py +++ b/src/compas/geometry/vector.py @@ -223,7 +223,7 @@ def Xaxis(cls): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` A vector with components ``x = 1.0, y = 0.0, z = 0.0``. Examples @@ -240,7 +240,7 @@ def Yaxis(cls): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` A vector with components ``x = 0.0, y = 1.0, z = 0.0``. Examples @@ -257,7 +257,7 @@ def Zaxis(cls): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` A vector with components ``x = 0.0, y = 0.0, z = 1.0``. Examples @@ -274,14 +274,14 @@ def from_start_end(cls, start, end): Parameters ---------- - start : [float, float, float] | :class:`~compas.geometry.Point` + start : [float, float, float] | :class:`compas.geometry.Point` The start point. - end : [float, float, float] | :class:`~compas.geometry.Point` + end : [float, float, float] | :class:`compas.geometry.Point` The end point. Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The vector from start to end. Examples @@ -303,7 +303,7 @@ def transform_collection(collection, X): Parameters ---------- - collection : list[[float, float, float] | :class:`~compas.geometry.Vector`] + collection : list[[float, float, float] | :class:`compas.geometry.Vector`] The collection of vectors. Returns @@ -336,12 +336,12 @@ def transformed_collection(collection, X): Parameters ---------- - collection : list[[float, float, float] | :class:`~compas.geometry.Vector`] + collection : list[[float, float, float] | :class:`compas.geometry.Vector`] The collection of vectors. Returns ------- - list[:class:`~compas.geometry.Vector`] + list[:class:`compas.geometry.Vector`] The transformed vectors. Examples @@ -368,7 +368,7 @@ def length_vectors(vectors): Parameters ---------- - vectors : list[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns @@ -390,12 +390,12 @@ def sum_vectors(vectors): Parameters ---------- - vectors : list[[float, float, float] | :class:`~compas.geometry.Vector`] + vectors : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` A vector that is the sum of the vectors. Examples @@ -412,9 +412,9 @@ def dot_vectors(left, right): Parameters ---------- - left : list[[float, float, float] | :class:`~compas.geometry.Vector`] + left : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. - right : list[[float, float, float] | :class:`~compas.geometry.Vector`] + right : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns @@ -436,14 +436,14 @@ def cross_vectors(left, right): Parameters ---------- - left : list[[float, float, float] | :class:`~compas.geometry.Vector`] + left : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. - right : list[[float, float, float] | :class:`~compas.geometry.Vector`] + right : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns ------- - list[:class:`~compas.geometry.Vector`] + list[:class:`compas.geometry.Vector`] A list of cross products. Examples @@ -461,9 +461,9 @@ def angles_vectors(left, right): Parameters ---------- - left : list[[float, float, float] | :class:`~compas.geometry.Vector`] + left : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. - right : list[[float, float, float] | :class:`~compas.geometry.Vector`] + right : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns @@ -485,9 +485,9 @@ def angle_vectors(left, right): Parameters ---------- - left : list[[float, float, float] | :class:`~compas.geometry.Vector`] + left : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. - right : list[[float, float, float] | :class:`~compas.geometry.Vector`] + right : list[[float, float, float] | :class:`compas.geometry.Vector`] A list of vectors. Returns @@ -512,7 +512,7 @@ def copy(self): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The copy. Examples @@ -557,7 +557,7 @@ def unitized(self): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` A unitized copy of the vector. Examples @@ -606,7 +606,7 @@ def inverted(self): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` Examples -------- @@ -653,7 +653,7 @@ def scaled(self, n): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` A scaled copy of the vector. Examples @@ -675,7 +675,7 @@ def dot(self, other): Parameters ---------- - other : [float, float, float] | :class:`~compas.geometry.Vector` + other : [float, float, float] | :class:`compas.geometry.Vector` The other vector. Returns @@ -698,12 +698,12 @@ def cross(self, other): Parameters ---------- - other : [float, float, float] | :class:`~compas.geometry.Vector` + other : [float, float, float] | :class:`compas.geometry.Vector` The other vector. Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The cross product. Examples @@ -721,7 +721,7 @@ def angle(self, other): Parameters ---------- - other : [float, float, float] | :class:`~compas.geometry.Vector` + other : [float, float, float] | :class:`compas.geometry.Vector` The other vector. Returns @@ -744,9 +744,9 @@ def angle_signed(self, other, normal): Parameters ---------- - other : [float, float, float] | :class:`~compas.geometry.Vector` + other : [float, float, float] | :class:`compas.geometry.Vector` The other vector. - normal : [float, float, float] | :class:`~compas.geometry.Vector` + normal : [float, float, float] | :class:`compas.geometry.Vector` The plane's normal spanned by this and the other vector. Returns @@ -771,7 +771,7 @@ def angles(self, other): Parameters ---------- - other : [float, float, float] | :class:`~compas.geometry.Vector` + other : [float, float, float] | :class:`compas.geometry.Vector` The other vector. Returns @@ -794,7 +794,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` | list[list[float]] + T : :class:`compas.geometry.Transformation` | list[list[float]] The transformation. Returns @@ -821,12 +821,12 @@ def transformed(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` | list[list[float]] + T : :class:`compas.geometry.Transformation` | list[list[float]] The transformation. Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The transformed copy. Examples diff --git a/src/compas/numerical/__init__.py b/src/compas/numerical/__init__.py index 5ccc927b415..e6f6d10a56b 100644 --- a/src/compas/numerical/__init__.py +++ b/src/compas/numerical/__init__.py @@ -1,3 +1,8 @@ +""" +This package defines a number of numerical utilities. +In future versions, this package will disappear, +and its functionality will be integrated into the geometry and datastructure packages directly. +""" from __future__ import absolute_import import compas @@ -30,8 +35,8 @@ equilibrium_matrix, ) - from .pca.pca_numpy import pca_numpy - from .isolines.isolines_numpy import scalarfield_contours_numpy + from .pca_numpy import pca_numpy + from .contours import scalarfield_contours __all__ = [] @@ -61,5 +66,5 @@ "stiffness_matrix", "equilibrium_matrix", "pca_numpy", - "scalarfield_contours_numpy", + "scalarfield_contours", ] diff --git a/src/compas/numerical/contours.py b/src/compas/numerical/contours.py new file mode 100644 index 00000000000..9ed3b1a8cec --- /dev/null +++ b/src/compas/numerical/contours.py @@ -0,0 +1,32 @@ +from compas.plugins import pluggable +from compas.plugins import PluginNotInstalledError + + +@pluggable(category="contours") +def scalarfield_contours(xy, s, levels=50, density=100): + r"""Compute the contour lines of a scalarfield. + + Parameters + ---------- + xy : array-like + The xy-coordinates at which the scalar field is defined. + s : array-like + The values of the scalar field. + levels : int, optional + The number of contour lines to compute. + Default is ``50``. + + Returns + ------- + tuple + A tuple of a list of levels and a list of contour geometry. + + The list of levels contains the values of the scalarfield at each of + the contours. The second item in the tuple is a list of contour lines. + Each contour line is a list of paths, and each path is a list polygons. + + """ + raise PluginNotInstalledError() + + +scalarfield_contours.__pluggable__ = True diff --git a/src/compas/numerical/isolines/__init__.py b/src/compas/numerical/isolines/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/numerical/isolines/isolines_numpy.py b/src/compas/numerical/isolines/isolines_numpy.py deleted file mode 100644 index d83070efccf..00000000000 --- a/src/compas/numerical/isolines/isolines_numpy.py +++ /dev/null @@ -1,94 +0,0 @@ -from numpy import asarray -from numpy import meshgrid -from numpy import linspace -from numpy import amax -from numpy import amin -from scipy.interpolate import griddata # type: ignore -import matplotlib.pyplot as plt - - -def scalarfield_contours_numpy(xy, s, levels=50, density=100): - r"""Compute the contour lines of a scalarfield. - - Parameters - ---------- - xy : array-like - The xy-coordinates at which the scalar field is defined. - s : array-like - The values of the scalar field. - levels : int, optional - The number of contour lines to compute. - Default is ``50``. - - Returns - ------- - tuple - A tuple of a list of levels and a list of contour geometry. - - The list of levels contains the values of the scalarfield at each of - the contours. The second item in the tuple is a list of contour lines. - Each contour line is a list of paths, and each path is a list polygons. - - Notes - ----- - The computation of the contour lines is based on the `contours function`_ - available through matplotlib. - - Examples - -------- - .. code-block:: python - - import compas - from compas.datastructures import Mesh - from compas.geometry import centroid_points - from compas.geometry import distance_point_point - from compas.geometry import scalarfield_contours_numpy - - mesh = Mesh.from_obj(compas.get('faces.obj')) - - points = [mesh.vertex_coordinates(key) for key in mesh.vertices()] - centroid = centroid_points(points) - distances = [distance_point_point(point, centroid) for point in points] - - xy = [point[0:2] for point in points] - - levels, contours = scalarfield_contours_numpy(xy, distances) - - for i in range(len(contours)): - level = levels[i] - contour = contours[i] - print(level) - for path in contour: - for polygon in path: - print(polygon) - - .. _contours function: http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.contour.html#matplotlib.axes.Axes.contour - - """ - xy = asarray(xy) - s = asarray(s) - x = xy[:, 0] - y = xy[:, 1] - X, Y = meshgrid(linspace(amin(x), amax(x), 2 * density), linspace(amin(y), amax(y), 2 * density)) - S = griddata((x, y), s, (X, Y), method="cubic") - - fig = plt.figure() - ax = fig.add_subplot(111, aspect="equal") - - c = ax.contour(X, Y, S, levels) - - contours = [0] * len(c.collections) # type: ignore - levels = c.levels # type: ignore - - for i, coll in enumerate(iter(c.collections)): # type: ignore - paths = coll.get_paths() - contours[i] = [0] * len(paths) # type: ignore - for j, path in enumerate(iter(paths)): - polygons = path.to_polygons() - contours[i][j] = [0] * len(polygons) # type: ignore - for k, polygon in enumerate(iter(polygons)): - contours[i][j][k] = polygon # type: ignore - - plt.close(fig) - - return levels, contours diff --git a/src/compas/numerical/pca/__init__.py b/src/compas/numerical/pca/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/compas/numerical/pca/pca_numpy.py b/src/compas/numerical/pca_numpy.py similarity index 100% rename from src/compas/numerical/pca/pca_numpy.py rename to src/compas/numerical/pca_numpy.py diff --git a/src/compas/plugins.py b/src/compas/plugins.py index 4babcb6ebc2..756a57da75b 100644 --- a/src/compas/plugins.py +++ b/src/compas/plugins.py @@ -1,3 +1,7 @@ +""" +COMPAS has an extensible architecture based on plugins that allows to +customize and extend the functionality of the core framework. +""" # The COMPAS plugin system owes a lot to pluggy, the pytest plugin framework # There are portions of code loosely based on pluggy's # and while it is not strictly derivative work, we include diff --git a/src/compas/rpc/__init__.py b/src/compas/rpc/__init__.py index 89c69c2c645..4516b55c427 100644 --- a/src/compas/rpc/__init__.py +++ b/src/compas/rpc/__init__.py @@ -1,3 +1,12 @@ +""" +COMPAS runs in many different environments, but in some environments the availablity of libraries is limited. +For example, when running COMPAS in an IronPython-based environment like Rhino/Grasshopper, +plenty of CPython libraries such as `numpy` and `scipy` are not available. +To workaround this limitation, COMPAS provides a mechanisms to access the functionality of a CPython environment seemlessly from any other Python environment through a "Remote Procedure Call" or RPC. +Through RPC, COMPAS can be used as a server for remote clients, and as a client for remote servers. +A typical use case is to run algorithms that require packages like ``numpy`` or ``scipy`` on a remote server, when working in Rhino. +Or to use COMPAS in a browser application. +""" from __future__ import absolute_import from .errors import RPCClientError, RPCServerError diff --git a/src/compas/rpc/xfunc.py b/src/compas/rpc/xfunc.py index 1b1da319f79..4db80d60169 100644 --- a/src/compas/rpc/xfunc.py +++ b/src/compas/rpc/xfunc.py @@ -176,15 +176,14 @@ class XFunc(object): is based on Numpy and Scipy. This implementation is not directly available in Rhino because Numpy and Scipy are not available for IronPython. - With :class:`~compas.utilities.XFunc`, :func:`compas.numerical.fd_numpy` can be easily + With :class:`compas.utilities.XFunc`, :func:`compas.numerical.fd_numpy` can be easily wrapped in an external process and called as if it would be directly available. .. code-block:: python import compas - import compas_rhino - from compas_rhino.artists import MeshArtist + from compas.scene import Scene from compas.datastructures import Mesh from compas.utilities import XFunc @@ -213,9 +212,9 @@ class XFunc(object): attr['y'] = xyz[vertex][1] attr['z'] = xyz[vertex][2] - artist = MeshArtist(mesh) - artist.draw_vertices() - artist.draw_edges() + scene = Scene() + scene.add(mesh) + scene.redraw() """ diff --git a/src/compas/scene/__init__.py b/src/compas/scene/__init__.py new file mode 100644 index 00000000000..d19d7d63eae --- /dev/null +++ b/src/compas/scene/__init__.py @@ -0,0 +1,37 @@ +""" +This package defines sceneobjects for visualising COMPAS items (geometry & datastructures). +Every item type is paired with a corresponding scene object type that is capable of visualizing the data of the object. +The scene objects are implemented as pluggables, and automatically switch between plugins depending on the contexct in which they are used. +""" + +from __future__ import print_function +from __future__ import absolute_import +from __future__ import division + +from .exceptions import SceneObjectNotRegisteredError +from .exceptions import NoSceneObjectContextError +from .sceneobject import SceneObject +from .meshobject import MeshObject +from .networkobject import NetworkObject +from .geometryobject import GeometryObject +from .volmeshobject import VolMeshObject + +from .sceneobject import clear +from .sceneobject import redraw +from .sceneobject import register_scene_objects + +from .scene import Scene + +__all__ = [ + "SceneObjectNotRegisteredError", + "NoSceneObjectContextError", + "SceneObject", + "MeshObject", + "NetworkObject", + "GeometryObject", + "VolMeshObject", + "Scene", + "clear", + "redraw", + "register_scene_objects", +] diff --git a/src/compas/artists/assemblyartist.py b/src/compas/scene/assemblyobject.py similarity index 100% rename from src/compas/artists/assemblyartist.py rename to src/compas/scene/assemblyobject.py diff --git a/src/compas/artists/descriptors/__init__.py b/src/compas/scene/descriptors/__init__.py similarity index 100% rename from src/compas/artists/descriptors/__init__.py rename to src/compas/scene/descriptors/__init__.py diff --git a/src/compas/artists/descriptors/attribute.py b/src/compas/scene/descriptors/attribute.py similarity index 100% rename from src/compas/artists/descriptors/attribute.py rename to src/compas/scene/descriptors/attribute.py diff --git a/src/compas/artists/descriptors/color.py b/src/compas/scene/descriptors/color.py similarity index 94% rename from src/compas/artists/descriptors/color.py rename to src/compas/scene/descriptors/color.py index 0ca8eefbbaf..7a764c4bbff 100644 --- a/src/compas/artists/descriptors/color.py +++ b/src/compas/scene/descriptors/color.py @@ -6,7 +6,7 @@ class ColorAttribute(object): Parameters ---------- - default : :class:`~compas.colors.Color`, optional + default : :class:`compas.colors.Color`, optional The default value of the attribute. Default is ``None``. @@ -52,7 +52,7 @@ def __get__(self, obj, otype=None): Returns ------- - :class:`~compas.colors.Color` + :class:`compas.colors.Color` The color stored in the private attribute corresponding to the public attribute name of the descriptor. If the private attribute does not exist, the default value of the descriptor is returned. @@ -75,7 +75,7 @@ def __set__(self, obj, value): ---------- obj : object The owner of the descriptor. - value : :class:`~compas.colors.Color` + value : :class:`compas.colors.Color` The new value for the descriptor. This value is stored in the corresponding private attribute. diff --git a/src/compas/artists/descriptors/colordict.py b/src/compas/scene/descriptors/colordict.py similarity index 96% rename from src/compas/artists/descriptors/colordict.py rename to src/compas/scene/descriptors/colordict.py index d338449fd6c..fa100993e12 100644 --- a/src/compas/artists/descriptors/colordict.py +++ b/src/compas/scene/descriptors/colordict.py @@ -72,7 +72,7 @@ def __set__(self, obj, value): ---------- obj : object The owner of the descriptor. - value : dict[Any, :class:`~compas.colors.Color`] | :class:`~compas.colors.Color` + value : dict[Any, :class:`compas.colors.Color`] | :class:`compas.colors.Color` The new value for the descriptor. This value is stored in the corresponding private attribute in the form of a defaultdict. diff --git a/src/compas/artists/descriptors/protocol.py b/src/compas/scene/descriptors/protocol.py similarity index 100% rename from src/compas/artists/descriptors/protocol.py rename to src/compas/scene/descriptors/protocol.py diff --git a/src/compas/artists/exceptions.py b/src/compas/scene/exceptions.py similarity index 54% rename from src/compas/artists/exceptions.py rename to src/compas/scene/exceptions.py index 8b21c798c02..c628888c210 100644 --- a/src/compas/artists/exceptions.py +++ b/src/compas/scene/exceptions.py @@ -3,16 +3,16 @@ from __future__ import division -class DataArtistNotRegistered(Exception): - """Exception that is raised when no artist is registered for a given data type.""" +class SceneObjectNotRegisteredError(Exception): + """Exception that is raised when no scene object is registered for a given data type.""" -class NoArtistContextError(Exception): - """Exception that is raised when no artist context is assigned is registered for a given data type.""" +class NoSceneObjectContextError(Exception): + """Exception that is raised when no scene object context is assigned is registered for a given data type.""" def __init__(self): error_message = "No context defined." error_message += "\n\nThis usually means that the script that you are running requires" error_message += "\na CAD environment but it is being ran as a standalone script" error_message += "\n(ie. from the command line or code editor)." - super(NoArtistContextError, self).__init__(error_message) + super(NoSceneObjectContextError, self).__init__(error_message) diff --git a/src/compas/artists/geometryartist.py b/src/compas/scene/geometryobject.py similarity index 51% rename from src/compas/artists/geometryartist.py rename to src/compas/scene/geometryobject.py index b3c41ce0b8e..7fe3a57fa73 100644 --- a/src/compas/artists/geometryartist.py +++ b/src/compas/scene/geometryobject.py @@ -2,23 +2,23 @@ from __future__ import absolute_import from __future__ import division -from .artist import Artist +from .sceneobject import SceneObject from .descriptors.color import ColorAttribute -class GeometryArtist(Artist): - """Base class for artists for geometry objects. +class GeometryObject(SceneObject): + """Base class for scene objects for geometry objects. Parameters ---------- - geometry : :class:`~compas.geometry.Geometry` + geometry : :class:`compas.geometry.Geometry` The geometry of the geometry. Attributes ---------- - geometry : :class:`~compas.geometry.Geometry` - The geometry object associated with the artist. - color : :class:`~compas.colors.Color` + geometry : :class:`compas.geometry.Geometry` + The geometry object associated with the scene object. + color : :class:`compas.colors.Color` The color of the object. """ @@ -26,5 +26,5 @@ class GeometryArtist(Artist): color = ColorAttribute(default=None) def __init__(self, geometry, **kwargs): - super(GeometryArtist, self).__init__(item=geometry, **kwargs) + super(GeometryObject, self).__init__(item=geometry, **kwargs) self.geometry = geometry diff --git a/src/compas/artists/meshartist.py b/src/compas/scene/meshobject.py similarity index 83% rename from src/compas/artists/meshartist.py rename to src/compas/scene/meshobject.py index da429f08f5c..bd13561d6b8 100644 --- a/src/compas/artists/meshartist.py +++ b/src/compas/scene/meshobject.py @@ -5,39 +5,39 @@ from abc import abstractmethod from compas.geometry import transform_points -from .artist import Artist +from .sceneobject import SceneObject from .descriptors.color import ColorAttribute from .descriptors.colordict import ColorDictAttribute -class MeshArtist(Artist): - """Base class for all mesh artists. +class MeshObject(SceneObject): + """Base class for all mesh scene objects. Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A COMPAS mesh. Attributes ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The mesh data structure. vertex_xyz : dict[int, list[float]] View coordinates of the vertices. Defaults to the real coordinates. - color : :class:`~compas.colors.Color` + color : :class:`compas.colors.Color` The base RGB color of the mesh. - vertex_color : :class:`~compas.colors.ColorDict`] + vertex_color : :class:`compas.colors.ColorDict`] Vertex colors. - edge_color : :class:`~compas.colors.ColorDict` + edge_color : :class:`compas.colors.ColorDict` Edge colors. - face_color : :class:`~compas.colors.ColorDict` + face_color : :class:`compas.colors.ColorDict` Face colors. See Also -------- - :class:`compas.artists.NetworkArtist` - :class:`compas.artists.VolMeshArtist` + :class:`compas.scene.NetworkObject` + :class:`compas.scene.VolMeshObject` """ @@ -48,7 +48,7 @@ class MeshArtist(Artist): face_color = ColorDictAttribute(default=None) def __init__(self, mesh, **kwargs): - super(MeshArtist, self).__init__(item=mesh, **kwargs) + super(MeshObject, self).__init__(item=mesh, **kwargs) self._mesh = None self._vertex_xyz = None self.mesh = mesh @@ -94,7 +94,7 @@ def draw_vertices(self, vertices=None, color=None, text=None): vertices : list[int], optional The vertices to include in the drawing. Default is all vertices. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the vertices, as either a single color to be applied to all vertices, or a color dict, mapping specific vertices to specific colors. @@ -119,7 +119,7 @@ def draw_edges(self, edges=None, color=None, text=None): edges : list[tuple[int, int]], optional The edges to include in the drawing. Default is all edges. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[tuple[int, int], tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[tuple[int, int], tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the edges, as either a single color to be applied to all edges, or a color dict, mapping specific edges to specific colors. @@ -144,7 +144,7 @@ def draw_faces(self, faces=None, color=None, text=None): faces : list[int], optional The faces to include in the drawing. Default is all faces. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the faces, as either a single color to be applied to all faces, or a color dict, mapping specific faces to specific colors. @@ -164,7 +164,7 @@ def draw_mesh(self, *args, **kwargs): """Draw the mesh of the mesh. .. deprecated:: 1.14.1 - Use :meth:`~MeshArtist.draw` instead. + Use :meth:`~MeshObject.draw` instead. Returns ------- diff --git a/src/compas/artists/networkartist.py b/src/compas/scene/networkobject.py similarity index 82% rename from src/compas/artists/networkartist.py rename to src/compas/scene/networkobject.py index b417e1cd4db..a41797e070d 100644 --- a/src/compas/artists/networkartist.py +++ b/src/compas/scene/networkobject.py @@ -6,34 +6,34 @@ from compas.colors import Color from compas.geometry import transform_points -from .artist import Artist +from .sceneobject import SceneObject from .descriptors.colordict import ColorDictAttribute -class NetworkArtist(Artist): - """Artist for drawing network data structures. +class NetworkObject(SceneObject): + """Scene object for drawing network data structures. Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A COMPAS network. Attributes ---------- - network : :class:`~compas.datastructures.Network` - The COMPAS network associated with the artist. + network : :class:`compas.datastructures.Network` + The COMPAS network associated with the scene object. node_xyz : dict[hashable, list[float]] Mapping between nodes and their view coordinates. The default view coordinates are the actual coordinates of the nodes of the network. - node_color : :class:`~compas.colors.ColorDict` + node_color : :class:`compas.colors.ColorDict` Mapping between nodes and RGB color values. - edge_color : :class:`~compas.colors.ColorDict` + edge_color : :class:`compas.colors.ColorDict` Mapping between edges and colors. See Also -------- - :class:`compas.artists.MeshArtist` - :class:`compas.artists.VolMeshArtist` + :class:`compas.scene.MeshObject` + :class:`compas.scene.VolMeshObject` """ @@ -41,7 +41,7 @@ class NetworkArtist(Artist): edge_color = ColorDictAttribute(default=Color.black()) def __init__(self, network, **kwargs): - super(NetworkArtist, self).__init__(**kwargs) + super(NetworkObject, self).__init__(item=network, **kwargs) self._network = None self._node_xyz = None self.network = network @@ -87,7 +87,7 @@ def draw_nodes(self, nodes=None, color=None, text=None): nodes : list[int], optional The nodes to include in the drawing. Default is all nodes. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the nodes, as either a single color to be applied to all nodes, or a color dict, mapping specific nodes to specific colors. @@ -112,7 +112,7 @@ def draw_edges(self, edges=None, color=None, text=None): edges : list[tuple[int, int]], optional The edges to include in the drawing. Default is all edges. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[tuple[int, int], tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[tuple[int, int], tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the edges, as either a single color to be applied to all edges, or a color dict, mapping specific edges to specific colors. diff --git a/src/compas/scene/scene.py b/src/compas/scene/scene.py new file mode 100644 index 00000000000..49605177208 --- /dev/null +++ b/src/compas/scene/scene.py @@ -0,0 +1,69 @@ +from compas.data import Data +from compas.datastructures import Tree +from compas.datastructures import TreeNode +from compas.scene import SceneObject + + +class Scene(Data): + def __init__(self, name=None): + super(Scene, self).__init__(name) + self._tree = Tree("Scene") + root = TreeNode(name="root") + self.tree.add(root) + + @property + def tree(self): + return self._tree + + @property + def sceneobjects(self): + return [node.attributes["sceneobject"] for node in self.tree.nodes if "sceneobject" in node.attributes] + + def add(self, item, parent=None, **kwargs): + sceneobject = SceneObject(item, **kwargs) + name = item.name or item.__class__.__name__ + node = TreeNode(name, attributes={"sceneobject": sceneobject}) + + if parent is None: + self.tree.add(node, parent=self.tree.root) + else: + parent_node = self._get_node(parent) + self.tree.add(node, parent=parent_node) + + return sceneobject + + def remove(self, sceneobject): + node = self._get_node(sceneobject) + self.tree.remove_node(node) + + def _get_node(self, sceneobject): + for node in self.tree.nodes: + if "sceneobject" in node.attributes: + if node.attributes["sceneobject"] == sceneobject: + return node + raise Exception("Scene object not in scene") + + def redraw(self): + sceneobject = None + + drawn_objects = [] + for sceneobject in self.sceneobjects: + drawn_object = sceneobject.draw() + + # TODO: unify output of draw(), so we don't have to do this + if isinstance(drawn_object, (list, tuple)): + for item in drawn_object: + if isinstance(item, (list, tuple)): + drawn_objects.extend(item) + else: + drawn_objects.append(item) + else: + drawn_objects.append(drawn_object) + + if drawn_objects: + sceneobject.redraw() + + return drawn_objects + + def print_hierarchy(self): + self.tree.print_hierarchy() diff --git a/src/compas/artists/artist.py b/src/compas/scene/sceneobject.py similarity index 57% rename from src/compas/artists/artist.py rename to src/compas/scene/sceneobject.py index cdcbcfe8c44..c35dea7b1ee 100644 --- a/src/compas/artists/artist.py +++ b/src/compas/scene/sceneobject.py @@ -7,8 +7,8 @@ from collections import defaultdict import compas -from compas.artists.exceptions import DataArtistNotRegistered -from compas.artists.exceptions import NoArtistContextError +from compas.scene.exceptions import SceneObjectNotRegisteredError +from compas.scene.exceptions import NoSceneObjectContextError from compas.plugins import PluginValidator from compas.plugins import pluggable @@ -20,17 +20,26 @@ def clear(): raise NotImplementedError +clear.__pluggable__ = True + + @pluggable(category="drawing-utils") def redraw(): raise NotImplementedError +redraw.__pluggable__ = True + + @pluggable(category="factories", selector="collect_all") -def register_artists(): - """Registers artists available in the current context.""" +def register_scene_objects(): + """Registers scene objects available in the current context.""" raise NotImplementedError +register_scene_objects.__pluggable__ = True + + def is_viewer_open(): """Returns True if an instance of the compas_view2 App is available. @@ -45,7 +54,7 @@ def is_viewer_open(): # if the instance exists, return True # in this case, the viewer is the current context # to do this without introducing compas_view2 as a dependency, - # creating the singleton instance should modify a class attribute of the Artist + # creating the singleton instance should modify a class attribute of the SceneObject # (or potentially a module level attribute of compas itself) return False @@ -54,13 +63,13 @@ def _detect_current_context(): """Chooses an appropriate context depending on available contexts and open instances. with the following priority: 1. Viewer 2. Plotter - 3. Rhino / GH - checked explicitly since Artists for both get registered when code is run from either. + 3. Rhino / GH - checked explicitly since SceneObjects for both get registered when code is run from either. 4. Other Returns ------- str - Name of an available context, used as key in :attr:`Artist.ITEM_ARTIST` + Name of an available context, used as key in :attr:`SceneObject.ITEM_SCENEOBJECT` """ if is_viewer_open(): @@ -71,23 +80,23 @@ def _detect_current_context(): return "Rhino" if compas.is_blender(): return "Blender" - other_contexts = [v for v in Artist.ITEM_ARTIST.keys()] + other_contexts = [v for v in SceneObject.ITEM_SCENEOBJECT.keys()] if other_contexts: return other_contexts[0] - raise NoArtistContextError() + raise NoSceneObjectContextError() -def _get_artist_cls(data, **kwargs): +def _get_sceneobject_cls(data, **kwargs): # in any case user gets to override the choice context_name = kwargs.get("context") or _detect_current_context() dtype = type(data) cls = None - if "artist_type" in kwargs: - cls = kwargs["artist_type"] + if "sceneobject_type" in kwargs: + cls = kwargs["sceneobject_type"] else: - context = Artist.ITEM_ARTIST[context_name] + context = SceneObject.ITEM_SCENEOBJECT[context_name] for type_ in inspect.getmro(dtype): cls = context.get(type_, None) @@ -95,51 +104,51 @@ def _get_artist_cls(data, **kwargs): break if cls is None: - raise DataArtistNotRegistered( - "No artist is registered for this data type: {} in this context: {}".format(dtype, context_name) + raise SceneObjectNotRegisteredError( + "No scene object is registered for this data type: {} in this context: {}".format(dtype, context_name) ) return cls -class Artist(object): - """Base class for all artists. +class SceneObject(object): + """Base class for all scene objects. Parameters ---------- item : Any - The item which should be visualized using the created Artist. + The item which should be visualized using the created SceneObject. context : str, optional - Explicit context to pick the Artist from. + Explicit context to pick the SceneObject from. If not specified, an attempt will be made to automatically detect the appropriate context. Attributes ---------- - ITEM_ARTIST : dict[str, dict[Type[:class:`~compas.data.Data`], Type[:class:`~compas.artists.Artist`]]] - Dictionary mapping data types to the corresponding artists types per visualization context. + ITEM_SCENEOBJECT : dict[str, dict[Type[:class:`~compas.data.Data`], Type[:class:`~compas.scene.SceneObject`]]] + Dictionary mapping data types to the corresponding scene objects types per visualization context. """ # add this to support the descriptor protocol vor Python versions below 3.6 __metaclass__ = DescriptorProtocol - __ARTISTS_REGISTERED = False + __SCENEOBJECTS_REGISTERED = False - ITEM_ARTIST = defaultdict(dict) + ITEM_SCENEOBJECT = defaultdict(dict) def __new__(cls, item, **kwargs): - if not Artist.__ARTISTS_REGISTERED: - cls.register_artists() - Artist.__ARTISTS_REGISTERED = True + if not SceneObject.__SCENEOBJECTS_REGISTERED: + cls.register_scene_objects() + SceneObject.__SCENEOBJECTS_REGISTERED = True if item is None: raise ValueError( - "Cannot create an artist for None. Please ensure you pass a instance of a supported class." + "Cannot create a scene object for None. Please ensure you pass a instance of a supported class." ) - cls = _get_artist_cls(item, **kwargs) + cls = _get_sceneobject_cls(item, **kwargs) PluginValidator.ensure_implementations(cls) - return super(Artist, cls).__new__(cls) + return super(SceneObject, cls).__new__(cls) def __init__(self, item, **kwargs): self._item = item @@ -147,7 +156,7 @@ def __init__(self, item, **kwargs): @property def transformation(self): - """The transformation matrix of the artist. + """The transformation matrix of the scene object. Returns ------- @@ -163,44 +172,44 @@ def transformation(self, transformation): @staticmethod def build(item, **kwargs): - """Build an artist corresponding to the item type. + """Build a scene object corresponding to the item type. Parameters ---------- **kwargs : dict[str, Any], optional The keyword arguments (kwargs) collected in a dict. - For relevant options, see the parameter lists of the matching artist type. + For relevant options, see the parameter lists of the matching scene object type. Returns ------- - :class:`~compas.artists.Artist` - An artist of the type matching the provided item according to the item-artist map :attr:`~Artist.ITEM_ARTIST`. - The map is created by registering item-artist type pairs using :meth:`~Artist.register`. + :class:`~compas.scene.SceneObject` + A scene object of the type matching the provided item according to the item-sceneobject map :attr:`~SceneObject.ITEM_SCENEOBJECT`. + The map is created by registering item-sceneobject type pairs using :meth:`~SceneObject.register`. """ - artist_type = _get_artist_cls(item, **kwargs) - artist = artist_type(item, **kwargs) - return artist + sceneobject_type = _get_sceneobject_cls(item, **kwargs) + sceneobject = sceneobject_type(item, **kwargs) + return sceneobject @staticmethod - def build_as(item, artist_type, **kwargs): - """Build an artist with the given type. + def build_as(item, sceneobject_type, **kwargs): + """Build a scene object with the given type. Parameters ---------- - artist_type : :class:`~compas.artists.Artist` + sceneobject_type : :class:`~compas.scene.SceneObject` **kwargs : dict[str, Any], optional The keyword arguments (kwargs) collected in a dict. - For relevant options, see the parameter lists of the matching artist type. + For relevant options, see the parameter lists of the matching sceneobject type. Returns ------- - :class:`~compas.artists.Artist` - An artist of the given type. + :class:`~compas.scene.SceneObject` + A scene object of the given type. """ - artist = artist_type(item, **kwargs) - return artist + sceneobject = sceneobject_type(item, **kwargs) + return sceneobject @staticmethod def clear(): @@ -225,27 +234,27 @@ def redraw(): return redraw() @staticmethod - def register_artists(): - """Register Artists using available plugins. + def register_scene_objects(): + """Register SceneObjects using available plugins. Returns ------- List[str] - List containing names of discovered Artist plugins. + List containing names of discovered SceneObject plugins. """ - return register_artists() + return register_scene_objects() @staticmethod - def register(item_type, artist_type, context=None): - """Register an artist type to a data type. + def register(item_type, sceneobject_type, context=None): + """Register a scene object type to a data type. Parameters ---------- item_type : :class:`~compas.data.Data` The type of data item. - artist_type : :class:`~compas.artists.Artist` - The type of the corresponding/compatible artist. + sceneobject_type : :class:`~compas.scene.SceneObject` + The type of the corresponding/compatible scene object. context : Literal['Viewer', 'Rhino', 'Grasshopper', 'Blender'], optional The visualization context in which the pair should be registered. @@ -254,7 +263,7 @@ def register(item_type, artist_type, context=None): None """ - Artist.ITEM_ARTIST[context][item_type] = artist_type + SceneObject.ITEM_SCENEOBJECT[context][item_type] = sceneobject_type @abstractmethod def draw(self): diff --git a/src/compas/artists/volmeshartist.py b/src/compas/scene/volmeshobject.py similarity index 82% rename from src/compas/artists/volmeshartist.py rename to src/compas/scene/volmeshobject.py index 9739aaa6df9..82f4114c866 100644 --- a/src/compas/artists/volmeshartist.py +++ b/src/compas/scene/volmeshobject.py @@ -6,43 +6,43 @@ from compas.colors import Color from compas.geometry import transform_points -from .artist import Artist +from .sceneobject import SceneObject from .descriptors.color import ColorAttribute from .descriptors.colordict import ColorDictAttribute -class VolMeshArtist(Artist): - """Artist for drawing volmesh data structures. +class VolMeshObject(SceneObject): + """Scene object for drawing volmesh data structures. Parameters ---------- - volmesh : :class:`~compas.datastructures.VolMesh` + volmesh : :class:`compas.datastructures.VolMesh` A COMPAS volmesh. Attributes ---------- - volmesh : :class:`~compas.datastructures.VolMesh` - The COMPAS volmesh associated with the artist. + volmesh : :class:`compas.datastructures.VolMesh` + The COMPAS volmesh associated with the scene object. vertex_xyz : dict[int, list[float]] The view coordinates of the vertices. By default, the actual vertex coordinates are used. - vertex_color : dict[int, :class:`~compas.colors.Color`] + vertex_color : dict[int, :class:`compas.colors.Color`] Mapping between vertices and colors. Missing vertices get the default vertex color: :attr:`default_vertexcolor`. - edge_color : dict[tuple[int, int], :class:`~compas.colors.Color`] + edge_color : dict[tuple[int, int], :class:`compas.colors.Color`] Mapping between edges and colors. Missing edges get the default edge color: :attr:`default_edgecolor`. - face_color : dict[int, :class:`~compas.colors.Color`] + face_color : dict[int, :class:`compas.colors.Color`] Mapping between faces and colors. Missing faces get the default face color: :attr:`default_facecolor`. - cell_color : dict[int, :class:`~compas.colors.Color`] + cell_color : dict[int, :class:`compas.colors.Color`] Mapping between cells and colors. Missing cells get the default cell color: :attr:`default_facecolor`. See Also -------- - :class:`compas.artists.NetworkArtist` - :class:`compas.artists.MeshArtist` + :class:`compas.scene.NetworkObject` + :class:`compas.scene.MeshObject` """ @@ -54,7 +54,7 @@ class VolMeshArtist(Artist): cell_color = ColorDictAttribute(default=Color.grey()) def __init__(self, volmesh, **kwargs): - super(VolMeshArtist, self).__init__(item=volmesh, **kwargs) + super(VolMeshObject, self).__init__(item=volmesh, **kwargs) self._volmesh = None self._vertex_xyz = None self.volmesh = volmesh @@ -100,7 +100,7 @@ def draw_vertices(self, vertices=None, color=None, text=None): vertices : list[int], optional The vertices to include in the drawing. Default is all vertices. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the vertices, as either a single color to be applied to all vertices, or a color dict, mapping specific vertices to specific colors. @@ -125,7 +125,7 @@ def draw_edges(self, edges=None, color=None, text=None): edges : list[tuple[int, int]], optional The edges to include in the drawing. Default is all edges. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[tuple[int, int], tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[tuple[int, int], tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the edges, as either a single color to be applied to all edges, or a color dict, mapping specific edges to specific colors. @@ -150,7 +150,7 @@ def draw_faces(self, faces=None, color=None, text=None): faces : list[int], optional The faces to include in the drawing. Default is all faces. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the faces, as either a single color to be applied to all faces, or a color dict, mapping specific faces to specific colors. @@ -175,7 +175,7 @@ def draw_cells(self, cells=None, color=None, text=None): cells : list[int], optional The cells to include in the drawing. Default is all cells. - color : tuple[float, float, float] | :class:`~compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`~compas.colors.Color`], optional + color : tuple[float, float, float] | :class:`compas.colors.Color` | dict[int, tuple[float, float, float] | :class:`compas.colors.Color`], optional The color of the cells, as either a single color to be applied to all cells, or a color dict, mapping specific cells to specific colors. diff --git a/src/compas/topology/__init__.py b/src/compas/topology/__init__.py index e4b887e9c45..fb1ccf082f9 100644 --- a/src/compas/topology/__init__.py +++ b/src/compas/topology/__init__.py @@ -1,3 +1,7 @@ +""" +Package containing topological algorithms for traversal, connectivity, combinatorics, etc. +""" + from __future__ import absolute_import import compas diff --git a/src/compas/topology/orientation.py b/src/compas/topology/orientation.py index 4e46d4cb62f..0de04cd27a8 100644 --- a/src/compas/topology/orientation.py +++ b/src/compas/topology/orientation.py @@ -14,7 +14,7 @@ def unify_cycles(vertices, faces, root=0): Parameters ---------- - vertices : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + vertices : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of vertex coordinates. faces : sequence[sequence[int]] A list of faces with each face defined by a list of indices into the list of vertices. @@ -28,7 +28,7 @@ def unify_cycles(vertices, faces, root=0): Raises ------ - AssertionError + Exception If not all faces were visited. Notes @@ -62,7 +62,10 @@ def unify(node, nbr): adj = face_adjacency(vertices, faces) visited = breadth_first_traverse(adj, root, unify) - assert len(list(visited)) == len(faces), "Not all faces were visited" + + if len(list(visited)) != len(faces): + raise Exception("Not all faces were visited") + return faces @@ -71,7 +74,7 @@ def face_adjacency(xyz, faces): Parameters ---------- - xyz : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + xyz : sequence[[float, float, float] | :class:`compas.geometry.Point`] The coordinates of the face vertices. faces : sequence[sequence[int]] A list of faces with each face defined by a list of indices into the list of xyz coordinates. diff --git a/src/compas/topology/orientation_numpy.py b/src/compas/topology/orientation_numpy.py index 13655f1c5b6..9057cd1eaa1 100644 --- a/src/compas/topology/orientation_numpy.py +++ b/src/compas/topology/orientation_numpy.py @@ -14,7 +14,7 @@ def unify_cycles_numpy(vertices, faces, root=0): Parameters ---------- - vertices : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + vertices : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of vertex coordinates. faces : sequence[sequence[int]] A list of faces with each face defined by a list of indices into the list of vertices. @@ -28,7 +28,7 @@ def unify_cycles_numpy(vertices, faces, root=0): Raises ------ - AssertionError + Exception If not all faces were visited. Notes @@ -62,7 +62,10 @@ def unify(node, nbr): adj = face_adjacency_numpy(vertices, faces) visited = breadth_first_traverse(adj, root, unify) - assert len(list(visited)) == len(faces), "Not all faces were visited" + + if len(list(visited)) != len(faces): + raise Exception("Not all faces were visited.") + return faces @@ -71,7 +74,7 @@ def face_adjacency_numpy(xyz, faces): Parameters ---------- - xyz : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + xyz : sequence[[float, float, float] | :class:`compas.geometry.Point`] The coordinates of the face vertices. faces : sequence[sequence[int]] A list of faces with each face defined by a list of indices into the list of xyz coordinates. @@ -126,7 +129,7 @@ def _face_adjacency(xyz, faces, nmax=10, radius=2.0): points = [centroid_points([xyz[index] for index in face]) for face in faces] k = min(len(faces), nmax) tree = cKDTree(points) - _, closest = tree.query(points, k=k, n_jobs=-1) + _, closest = tree.query(points, k=k, workers=-1) adjacency = {} for face, vertices in enumerate(faces): nbrs = [] diff --git a/src/compas/topology/orientation_rhino.py b/src/compas/topology/orientation_rhino.py index a6755875258..c05aba7bd78 100644 --- a/src/compas/topology/orientation_rhino.py +++ b/src/compas/topology/orientation_rhino.py @@ -2,9 +2,9 @@ from __future__ import absolute_import from __future__ import division -from Rhino.Geometry import RTree -from Rhino.Geometry import Sphere -from Rhino.Geometry import Point3d +from Rhino.Geometry import RTree # type: ignore +from Rhino.Geometry import Sphere # type: ignore +from Rhino.Geometry import Point3d # type: ignore from compas.utilities import pairwise from compas.geometry import centroid_points @@ -16,7 +16,7 @@ def unify_cycles_rhino(vertices, faces, root=0): Parameters ---------- - vertices : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + vertices : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of vertex coordinates. faces : sequence[sequence[int]] A list of faces with each face defined by a list of indices into the list of vertices. @@ -30,7 +30,7 @@ def unify_cycles_rhino(vertices, faces, root=0): Raises ------ - AssertionError + Exception If not all faces were visited. Notes @@ -64,7 +64,10 @@ def unify(node, nbr): adj = face_adjacency_rhino(vertices, faces) visited = breadth_first_traverse(adj, root, unify) - assert len(list(visited)) == len(faces), "Not all faces were visited" + + if len(list(visited)) != len(faces): + raise Exception("Not all faces were visited") + return faces @@ -73,7 +76,7 @@ def face_adjacency_rhino(xyz, faces): Parameters ---------- - xyz : sequence[[float, float, float] | :class:`~compas.geometry.Point`] + xyz : sequence[[float, float, float] | :class:`compas.geometry.Point`] The coordinates of the face vertices. faces : sequence[sequence[int]] A list of faces with each face defined by a list of indices into the list of xyz coordinates. diff --git a/src/compas/topology/traversal.py b/src/compas/topology/traversal.py index ec405c2e85a..040ca61dcc5 100644 --- a/src/compas/topology/traversal.py +++ b/src/compas/topology/traversal.py @@ -448,7 +448,7 @@ def astar_shortest_path(graph, root, goal): Parameters ---------- - graph : :class:`~compas.datastructures.Network` | :class:`~compas.datastructures.Mesh` + graph : :class:`compas.datastructures.Network` | :class:`compas.datastructures.Mesh` A network or mesh data structure. root : hashable The identifier of the starting node. diff --git a/src/compas/utilities/colors.py b/src/compas/utilities/colors.py index 54362355edf..ef6ba7105e1 100644 --- a/src/compas/utilities/colors.py +++ b/src/compas/utilities/colors.py @@ -43,7 +43,7 @@ def i_to_rgb(i, normalize=False): """Convert a number between 0.0 and 1.0 to an equivalent RGB tuple. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -102,7 +102,7 @@ def i_to_rgb(i, normalize=False): elif i == 0.75: r, g, b = 255, 255, 0 elif 0.75 < i < 1.0: - r, g, b, = ( + (r, g, b,) = ( 255, int(255 - 255 * 4 * (i - 0.75)), 0, @@ -120,7 +120,7 @@ def i_to_red(i, normalize=False): """Convert a number between 0.0 and 1.0 to a shade of red. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -157,7 +157,7 @@ def i_to_green(i, normalize=False): """Convert a number between 0.0 and 1.0 to a shade of green. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -194,7 +194,7 @@ def i_to_blue(i, normalize=False): """Convert a number between 0.0 and 1.0 to a shade of blue. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -231,7 +231,7 @@ def i_to_white(i, normalize=False): """Convert a number between 0.0 and 1.0 to a shade of white. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -269,7 +269,7 @@ def i_to_black(i, normalize=False): """Convert a number between 0.0 and 1.0 to a shade of black. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -307,7 +307,7 @@ class Colormap(object): """Convenience class for converting a data range into a corresponding RGB color range. .. deprecated:: 1.14 - Use :class:`~compas.colors.ColorMap` instead. + Use :class:`compas.colors.ColorMap` instead. Parameters ---------- @@ -366,7 +366,7 @@ def is_color_rgb(color): """Is a color in a valid RGB format. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -413,7 +413,7 @@ def is_color_hex(color): """Is a color in a valid HEX format. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -450,7 +450,7 @@ def rgb_to_rgb(rgb, g=None, b=None): """Convert an RGB color specification to an integer-based RGB color specification. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -502,7 +502,7 @@ def rgb_to_hex(rgb, g=None, b=None): """Convert an RGB color specification to HEX. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -540,7 +540,7 @@ def hex_to_rgb(value, normalize=False): """Convert a HEX color to the corresponding RGB format. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -576,7 +576,7 @@ def color_to_rgb(color, normalize=False): """Convert a HEX or RGB color to RGB. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -624,7 +624,7 @@ def color_to_colordict(color, keys, default=None, colorformat="rgb", normalize=F """Convert a color specification to a dict of colors. .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- @@ -701,7 +701,7 @@ def is_color_light(color): r"""Is a color "light". .. deprecated:: 1.14 - Use :class:`~compas.colors.Color` instead. + Use :class:`compas.colors.Color` instead. Parameters ---------- diff --git a/src/compas_blender/__init__.py b/src/compas_blender/__init__.py index 755646a27b8..6a6e8dd71ea 100644 --- a/src/compas_blender/__init__.py +++ b/src/compas_blender/__init__.py @@ -78,6 +78,5 @@ def _get_default_blender_installation_path_windows(version): __all_plugins__ = [ "compas_blender.geometry.booleans", - "compas_blender.artists", - # "compas_blender.geometry.curves", + "compas_blender.scene", ] diff --git a/src/compas_blender/artists/__init__.py b/src/compas_blender/artists/__init__.py deleted file mode 100644 index 0b96344672d..00000000000 --- a/src/compas_blender/artists/__init__.py +++ /dev/null @@ -1,107 +0,0 @@ -import compas_blender - -from compas.plugins import plugin -from compas.artists import Artist - -from compas.geometry import Box -from compas.geometry import Capsule -from compas.geometry import Circle -from compas.geometry import Cone -from compas.geometry import Curve -from compas.geometry import Cylinder -from compas.geometry import Frame -from compas.geometry import Line -from compas.geometry import Point -from compas.geometry import Pointcloud -from compas.geometry import Polygon -from compas.geometry import Polyhedron -from compas.geometry import Polyline -from compas.geometry import Sphere -from compas.geometry import Surface -from compas.geometry import Torus -from compas.geometry import Vector -from compas.datastructures import Mesh -from compas.datastructures import Network -from compas.datastructures import VolMesh - -from .artist import BlenderArtist -from .boxartist import BoxArtist -from .capsuleartist import CapsuleArtist -from .circleartist import CircleArtist -from .coneartist import ConeArtist -from .curveartist import CurveArtist -from .cylinderartist import CylinderArtist -from .frameartist import FrameArtist -from .lineartist import LineArtist -from .meshartist import MeshArtist -from .networkartist import NetworkArtist -from .pointartist import PointArtist -from .pointcloudartist import PointcloudArtist -from .polygonartist import PolygonArtist -from .polyhedronartist import PolyhedronArtist -from .polylineartist import PolylineArtist -from .sphereartist import SphereArtist -from .surfaceartist import SurfaceArtist -from .torusartist import TorusArtist -from .vectorartist import VectorArtist -from .volmeshartist import VolMeshArtist - - -@plugin(category="drawing-utils", pluggable_name="clear", requires=["bpy"]) -def clear_blender(): - compas_blender.clear() - - -@plugin(category="drawing-utils", pluggable_name="redraw", requires=["bpy"]) -def redraw_blender(): - compas_blender.redraw() - - -@plugin(category="factories", requires=["bpy"]) -def register_artists(): - Artist.register(Box, BoxArtist, context="Blender") - Artist.register(Capsule, CapsuleArtist, context="Blender") - Artist.register(Circle, CircleArtist, context="Blender") - Artist.register(Cone, ConeArtist, context="Blender") - Artist.register(Curve, CurveArtist, context="Blender") - Artist.register(Cylinder, CylinderArtist, context="Blender") - Artist.register(Frame, FrameArtist, context="Blender") - Artist.register(Line, LineArtist, context="Blender") - Artist.register(Mesh, MeshArtist, context="Blender") - Artist.register(Network, NetworkArtist, context="Blender") - Artist.register(Point, PointArtist, context="Blender") - Artist.register(Pointcloud, PointcloudArtist, context="Blender") - Artist.register(Polygon, PolygonArtist, context="Blender") - Artist.register(Polyhedron, PolyhedronArtist, context="Blender") - Artist.register(Polyline, PolylineArtist, context="Blender") - Artist.register(Sphere, SphereArtist, context="Blender") - Artist.register(Surface, SurfaceArtist, context="Blender") - Artist.register(Torus, TorusArtist, context="Blender") - Artist.register(Vector, VectorArtist, context="Blender") - Artist.register(VolMesh, VolMeshArtist, context="Blender") - print("Blender Artists registered.") - - -__all__ = [ - "BlenderArtist", - "BoxArtist", - "CapsuleArtist", - "CircleArtist", - "ConeArtist", - "CurveArtist", - "CylinderArtist", - "FrameArtist", - "LineArtist", - "MeshArtist", - "NetworkArtist", - "PointArtist", - "PointcloudArtist", - "PolygonArtist", - "PolyhedronArtist", - "PolylineArtist", - "SphereArtist", - "SurfaceArtist", - "TorusArtist", - "VectorArtist", - "VolMeshArtist", -] diff --git a/src/compas_blender/conversions/__init__.py b/src/compas_blender/conversions/__init__.py index c7460d02ee5..5cb3488246b 100644 --- a/src/compas_blender/conversions/__init__.py +++ b/src/compas_blender/conversions/__init__.py @@ -1,3 +1,6 @@ +""" +This package provides functions to convert between COMPAS data/objects and Blender data/objects. +""" from .colors import color_to_blender_material from .geometry import pointcloud_to_blender diff --git a/src/compas_blender/conversions/meshes.py b/src/compas_blender/conversions/meshes.py index 47eba65b562..a92483cb162 100644 --- a/src/compas_blender/conversions/meshes.py +++ b/src/compas_blender/conversions/meshes.py @@ -1,4 +1,5 @@ from typing import Optional + import bpy # type: ignore import bmesh # type: ignore diff --git a/src/compas_blender/geometry/__init__.py b/src/compas_blender/geometry/__init__.py index b60d21f5c3e..574c3a9ed55 100644 --- a/src/compas_blender/geometry/__init__.py +++ b/src/compas_blender/geometry/__init__.py @@ -1,27 +1,17 @@ """ -******************************************************************************** -geometry -******************************************************************************** - -.. currentmodule:: compas_blender.geometry - -Classes -======= - -.. autosummary:: - :toctree: generated/ - :nosignatures: - +This package provides plugins for various geometry pluggables using Blender as the backend. +""" -Plugins -======= +from .curves.curve import BlenderCurve # noqa: F401 +from .curves.nurbs import BlenderNurbsCurve # noqa: F401 -.. autosummary:: - :toctree: generated/ - :nosignatures: +from .booleans import boolean_difference_mesh_mesh +from .booleans import boolean_intersection_mesh_mesh +from .booleans import boolean_union_mesh_mesh - booleans.boolean_difference_mesh_mesh - booleans.boolean_intersection_mesh_mesh - booleans.boolean_union_mesh_mesh -""" +__all__ = [ + "boolean_difference_mesh_mesh", + "boolean_intersection_mesh_mesh", + "boolean_union_mesh_mesh", +] diff --git a/src/compas_blender/geometry/booleans/__init__.py b/src/compas_blender/geometry/booleans.py similarity index 75% rename from src/compas_blender/geometry/booleans/__init__.py rename to src/compas_blender/geometry/booleans.py index e136030c8ea..b60c0f5b543 100644 --- a/src/compas_blender/geometry/booleans/__init__.py +++ b/src/compas_blender/geometry/booleans.py @@ -1,4 +1,4 @@ -import bpy +import bpy # type: ignore from compas.plugins import plugin @@ -8,9 +8,9 @@ def boolean_union_mesh_mesh(A, B, remesh=False): Parameters ---------- - A : tuple[sequence[[float, float, foat], :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + A : tuple[sequence[[float, float, foat], :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh A. - B : tuple[sequence[[float, float, foat], :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + B : tuple[sequence[[float, float, foat], :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh B. remesh : bool, optional If True, remesh the result. @@ -24,15 +24,18 @@ def boolean_union_mesh_mesh(A, B, remesh=False): return _boolean_operation(A, B, "UNION") +boolean_union_mesh_mesh.__plugin__ = True + + @plugin(category="booleans", requires=["bpy"]) def boolean_difference_mesh_mesh(A, B, remesh=False): """Compute the boolean difference of two triangle meshes. Parameters ---------- - A : tuple[sequence[[float, float, foat], :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + A : tuple[sequence[[float, float, foat], :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh A. - B : tuple[sequence[[float, float, foat], :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + B : tuple[sequence[[float, float, foat], :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh B. remesh : bool, optional If True, remesh the result. @@ -46,15 +49,18 @@ def boolean_difference_mesh_mesh(A, B, remesh=False): return _boolean_operation(A, B, "DIFFERENCE") +boolean_difference_mesh_mesh.__plugin__ = True + + @plugin(category="booleans", requires=["bpy"]) def boolean_intersection_mesh_mesh(A, B, remesh=False): """Compute the boolean intersection of two triangle meshes. Parameters ---------- - A : tuple[sequence[[float, float, foat], :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + A : tuple[sequence[[float, float, foat], :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh A. - B : tuple[sequence[[float, float, foat], :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + B : tuple[sequence[[float, float, foat], :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh B. remesh : bool, optional If True, remesh the result. @@ -68,6 +74,9 @@ def boolean_intersection_mesh_mesh(A, B, remesh=False): return _boolean_operation(A, B, "INTERSECT") +boolean_intersection_mesh_mesh.__plugin__ = True + + def _boolean_operation(A, B, method): from compas_blender.utilities import draw_mesh from compas_blender.utilities import delete_object diff --git a/src/compas_blender/geometry/curves/curve.py b/src/compas_blender/geometry/curves/curve.py index 31464e61386..3fd66bb59f0 100644 --- a/src/compas_blender/geometry/curves/curve.py +++ b/src/compas_blender/geometry/curves/curve.py @@ -29,9 +29,9 @@ class BlenderCurve(Curve): The spatial dimension of the curve. domain : tuple[float, float], read-only The parameter domain. - start : :class:`~compas.geometry.Point`, read-only + start : :class:`compas.geometry.Point`, read-only The point corresponding to the start of the parameter domain. - end : :class:`~compas.geometry.Point`, read-only + end : :class:`compas.geometry.Point`, read-only The point corresponding to the end of the parameter domain. is_closed : bool, read-only True if the curve is closed. @@ -117,7 +117,7 @@ def from_native(cls, native_curve): Returns ------- - :class:`~compas_rhino.geometry.BlenderCurve` + :class:`compas_rhino.geometry.BlenderCurve` """ curve = cls() @@ -137,7 +137,7 @@ def from_native(cls, native_curve): # Returns # ------- - # :class:`~compas_rhino.geometry.RhinoCurve` + # :class:`compas_rhino.geometry.RhinoCurve` # """ # cls = type(self) @@ -150,7 +150,7 @@ def from_native(cls, native_curve): # Parameters # ---------- - # T : :class:`~compas.geometry.Transformation` + # T : :class:`compas.geometry.Transformation` # A COMPAS transformation. # Returns @@ -180,7 +180,7 @@ def from_native(cls, native_curve): # Returns # ------- - # :class:`~compas.geometry.Point` + # :class:`compas.geometry.Point` # the corresponding point on the curve. # """ @@ -197,7 +197,7 @@ def from_native(cls, native_curve): # Returns # ------- - # :class:`~compas.geometry.Vector` + # :class:`compas.geometry.Vector` # The corresponding tangent vector. # """ @@ -214,7 +214,7 @@ def from_native(cls, native_curve): # Returns # ------- - # :class:`~compas.geometry.Vector` + # :class:`compas.geometry.Vector` # The corresponding curvature vector. # """ @@ -231,7 +231,7 @@ def from_native(cls, native_curve): # Returns # ------- - # :class:`~compas.geometry.Frame` + # :class:`compas.geometry.Frame` # The corresponding local frame. # """ diff --git a/src/compas_blender/geometry/curves/nurbs.py b/src/compas_blender/geometry/curves/nurbs.py index 78bc4bf6d15..4125efb8a87 100644 --- a/src/compas_blender/geometry/curves/nurbs.py +++ b/src/compas_blender/geometry/curves/nurbs.py @@ -18,7 +18,7 @@ def native_curve_from_parameters(points, weights, knots, multiplicities, degree, Parameters ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The control points. weights : list[float] The control point weights. @@ -71,7 +71,7 @@ class BlenderNurbsCurve(NurbsCurve, BlenderCurve): Attributes ---------- - points : list[:class:`~compas.geometry.Point`], read-only + points : list[:class:`compas.geometry.Point`], read-only The control points of the curve. weights : list[float], read-only The weights of the control points. @@ -183,7 +183,7 @@ def from_parameters(cls, points, weights, knots, multiplicities, degree, is_peri Parameters ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The control points. weights : list[float] The control point weights. @@ -199,7 +199,7 @@ def from_parameters(cls, points, weights, knots, multiplicities, degree, is_peri Returns ------- - :class:`~compas_blender.geometry.BlenderNurbsCurve` + :class:`compas_blender.geometry.BlenderNurbsCurve` """ curve = cls() @@ -212,7 +212,7 @@ def from_points(cls, points, degree=3, is_periodic=False): Parameters ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The control points. degree : int, optional The degree of the curve. @@ -221,7 +221,7 @@ def from_points(cls, points, degree=3, is_periodic=False): Returns ------- - :class:`~compas_blender.geometry.BlenderNurbsCurve` + :class:`compas_blender.geometry.BlenderNurbsCurve` """ weights = [1.0 for point in points] diff --git a/src/compas_blender/install.py b/src/compas_blender/install.py index ee5855aabed..8c597764472 100644 --- a/src/compas_blender/install.py +++ b/src/compas_blender/install.py @@ -155,7 +155,6 @@ def install(blender_path, version=None): # ============================================================================== if __name__ == "__main__": - import argparse parser = argparse.ArgumentParser() diff --git a/src/compas_blender/install_windows.py b/src/compas_blender/install_windows.py index 5ca64f34f74..4948780abd9 100644 --- a/src/compas_blender/install_windows.py +++ b/src/compas_blender/install_windows.py @@ -166,7 +166,6 @@ def install_windows(blender_path, version=None, packages=None, force_reinstall=F # ============================================================================== if __name__ == "__main__": - import argparse parser = argparse.ArgumentParser() diff --git a/src/compas_blender/scene/__init__.py b/src/compas_blender/scene/__init__.py new file mode 100644 index 00000000000..9e59b81cedf --- /dev/null +++ b/src/compas_blender/scene/__init__.py @@ -0,0 +1,112 @@ +""" +This package provides scene object plugins for visualising COMPAS objects in Blender. +When working in Blender, :class:`compas.scene.SceneObject` will automatically use the corresponding Blender object for each COMPAS object type. +""" + +import compas_blender + +from compas.plugins import plugin +from compas.scene import SceneObject + +from compas.geometry import Box +from compas.geometry import Capsule +from compas.geometry import Circle +from compas.geometry import Cone +from compas.geometry import Curve +from compas.geometry import Cylinder +from compas.geometry import Frame +from compas.geometry import Line +from compas.geometry import Point +from compas.geometry import Pointcloud +from compas.geometry import Polygon +from compas.geometry import Polyhedron +from compas.geometry import Polyline +from compas.geometry import Sphere +from compas.geometry import Surface +from compas.geometry import Torus +from compas.geometry import Vector +from compas.datastructures import Mesh +from compas.datastructures import Network +from compas.datastructures import VolMesh + +from .sceneobject import BlenderSceneObject +from .boxobject import BoxObject +from .capsuleobject import CapsuleObject +from .circleobject import CircleObject +from .coneobject import ConeObject +from .curveobject import CurveObject +from .cylinderobject import CylinderObject +from .frameobject import FrameObject +from .lineobject import LineObject +from .meshobject import MeshObject +from .networkobject import NetworkObject +from .pointobject import PointObject +from .pointcloudobject import PointcloudObject +from .polygonobject import PolygonObject +from .polyhedronobject import PolyhedronObject +from .polylineobject import PolylineObject +from .sphereobject import SphereObject +from .surfaceobject import SurfaceObject +from .torusobject import TorusObject +from .vectorobject import VectorObject +from .volmeshobject import VolMeshObject + + +@plugin(category="drawing-utils", pluggable_name="clear", requires=["bpy"]) +def clear_blender(): + compas_blender.clear() + + +@plugin(category="drawing-utils", pluggable_name="redraw", requires=["bpy"]) +def redraw_blender(): + compas_blender.redraw() + + +@plugin(category="factories", requires=["bpy"]) +def register_scene_objects(): + SceneObject.register(Box, BoxObject, context="Blender") + SceneObject.register(Capsule, CapsuleObject, context="Blender") + SceneObject.register(Circle, CircleObject, context="Blender") + SceneObject.register(Cone, ConeObject, context="Blender") + SceneObject.register(Curve, CurveObject, context="Blender") + SceneObject.register(Cylinder, CylinderObject, context="Blender") + SceneObject.register(Frame, FrameObject, context="Blender") + SceneObject.register(Line, LineObject, context="Blender") + SceneObject.register(Mesh, MeshObject, context="Blender") + SceneObject.register(Network, NetworkObject, context="Blender") + SceneObject.register(Point, PointObject, context="Blender") + SceneObject.register(Pointcloud, PointcloudObject, context="Blender") + SceneObject.register(Polygon, PolygonObject, context="Blender") + SceneObject.register(Polyhedron, PolyhedronObject, context="Blender") + SceneObject.register(Polyline, PolylineObject, context="Blender") + SceneObject.register(Sphere, SphereObject, context="Blender") + SceneObject.register(Surface, SurfaceObject, context="Blender") + SceneObject.register(Torus, TorusObject, context="Blender") + SceneObject.register(Vector, VectorObject, context="Blender") + SceneObject.register(VolMesh, VolMeshObject, context="Blender") + print("Blender Objects registered.") + + +__all__ = [ + "BlenderSceneObject", + "BoxObject", + "CapsuleObject", + "CircleObject", + "ConeObject", + "CurveObject", + "CylinderObject", + "FrameObject", + "LineObject", + "MeshObject", + "NetworkObject", + "PointObject", + "PointcloudObject", + "PolygonObject", + "PolyhedronObject", + "PolylineObject", + "SphereObject", + "SurfaceObject", + "TorusObject", + "VectorObject", + "VolMeshObject", +] diff --git a/src/compas_blender/artists/boxartist.py b/src/compas_blender/scene/boxobject.py similarity index 83% rename from src/compas_blender/artists/boxartist.py rename to src/compas_blender/scene/boxobject.py index 4d04840f50c..1ca0fe23897 100644 --- a/src/compas_blender/artists/boxartist.py +++ b/src/compas_blender/scene/boxobject.py @@ -9,16 +9,16 @@ from compas_blender import conversions -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class BoxArtist(BlenderArtist, GeometryArtist): - """Artist for drawing box shapes in Blender. +class BoxObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing box shapes in Blender. Parameters ---------- - box : :class:`~compas.geometry.Box` + box : :class:`compas.geometry.Box` A COMPAS box. **kwargs : dict, optional Additional keyword arguments. @@ -34,11 +34,11 @@ def draw( collection: Optional[Union[str, bpy.types.Collection]] = None, show_wire: bool = True, ) -> bpy.types.Object: - """Draw the box associated with the artist. + """Draw the box associated with the scene object. Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the box. collection : str | :blender:`bpy.types.Collection`, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/capsuleartist.py b/src/compas_blender/scene/capsuleobject.py similarity index 83% rename from src/compas_blender/artists/capsuleartist.py rename to src/compas_blender/scene/capsuleobject.py index aa30eb23af4..48bfc5f0425 100644 --- a/src/compas_blender/artists/capsuleartist.py +++ b/src/compas_blender/scene/capsuleobject.py @@ -8,16 +8,16 @@ from compas_blender import conversions -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class CapsuleArtist(BlenderArtist, GeometryArtist): - """Artist for drawing capsule shapes in Blender. +class CapsuleObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing capsule shapes in Blender. Parameters ---------- - capsule : :class:`~compas.geometry.Capsule` + capsule : :class:`compas.geometry.Capsule` A COMPAS capsule. **kwargs : dict, optional Additional keyword arguments. @@ -36,11 +36,11 @@ def draw( show_wire: bool = False, shade_smooth: bool = True, ) -> bpy.types.Object: - """Draw the capsule associated with the artist. + """Draw the capsule associated with the scene object. Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the capsule. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -65,6 +65,7 @@ def draw( vertices, faces = self.geometry.to_vertices_and_faces(u=u, v=v) mesh = conversions.vertices_and_faces_to_blender_mesh(vertices, faces, name=self.geometry.name) if shade_smooth: + print(dir(mesh)) mesh.shade_smooth() obj = self.create_object(mesh, name=name) diff --git a/src/compas_blender/artists/circleartist.py b/src/compas_blender/scene/circleobject.py similarity index 81% rename from src/compas_blender/artists/circleartist.py rename to src/compas_blender/scene/circleobject.py index ba5234f2c05..e363876a141 100644 --- a/src/compas_blender/artists/circleartist.py +++ b/src/compas_blender/scene/circleobject.py @@ -6,16 +6,16 @@ from compas.geometry import Circle from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class CircleArtist(BlenderArtist, GeometryArtist): - """Artist for drawing circles in Blender. +class CircleObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing circles in Blender. Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` A COMPAS circle. **kwargs : dict, optional Additional keyword arguments. @@ -30,7 +30,7 @@ def draw(self, color: Optional[Color] = None, collection: Optional[str] = None) Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the capsule. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/coneartist.py b/src/compas_blender/scene/coneobject.py similarity index 83% rename from src/compas_blender/artists/coneartist.py rename to src/compas_blender/scene/coneobject.py index 24d637ef323..ef290df7b76 100644 --- a/src/compas_blender/artists/coneartist.py +++ b/src/compas_blender/scene/coneobject.py @@ -8,16 +8,16 @@ from compas_blender import conversions -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class ConeArtist(BlenderArtist, GeometryArtist): - """Artist for drawing cone shapes in Blender. +class ConeObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing cone shapes in Blender. Parameters ---------- - cone : :class:`~compas.geometry.Cone` + cone : :class:`compas.geometry.Cone` A COMPAS cone. **kwargs : dict, optional Additional keyword arguments. @@ -35,11 +35,11 @@ def draw( show_wire: bool = False, shade_smooth: bool = True, ) -> bpy.types.Object: - """Draw the cone associated with the artist. + """Draw the cone associated with the scene object. Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the cone. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/curveartist.py b/src/compas_blender/scene/curveobject.py similarity index 81% rename from src/compas_blender/artists/curveartist.py rename to src/compas_blender/scene/curveobject.py index 17c446c9bda..5af65965546 100644 --- a/src/compas_blender/artists/curveartist.py +++ b/src/compas_blender/scene/curveobject.py @@ -7,16 +7,16 @@ from compas.colors import Color from compas_blender import conversions -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class CurveArtist(BlenderArtist, GeometryArtist): - """Artist for drawing curves in Blender. +class CurveObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing curves in Blender. Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` A COMPAS curve. **kwargs : dict, optional Additional keyword arguments. @@ -35,7 +35,7 @@ def draw( Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the curve. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/cylinderartist.py b/src/compas_blender/scene/cylinderobject.py similarity index 83% rename from src/compas_blender/artists/cylinderartist.py rename to src/compas_blender/scene/cylinderobject.py index b50eb72cdc4..2ebe33bf1df 100644 --- a/src/compas_blender/artists/cylinderartist.py +++ b/src/compas_blender/scene/cylinderobject.py @@ -8,16 +8,16 @@ from compas_blender import conversions -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class CylinderArtist(BlenderArtist, GeometryArtist): - """Artist for drawing cylinder shapes in Blender. +class CylinderObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing cylinder shapes in Blender. Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + cylinder : :class:`compas.geometry.Cylinder` A COMPAS cylinder. **kwargs : dict, optional Additional keyword arguments. @@ -35,11 +35,11 @@ def draw( show_wire: bool = False, shade_smooth: bool = True, ) -> bpy.types.Object: - """Draw the cylinder associated with the artist. + """Draw the cylinder associated with the scene object. Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the cylinder. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/frameartist.py b/src/compas_blender/scene/frameobject.py similarity index 83% rename from src/compas_blender/artists/frameartist.py rename to src/compas_blender/scene/frameobject.py index 5db898c2e0c..3cc4d802848 100644 --- a/src/compas_blender/artists/frameartist.py +++ b/src/compas_blender/scene/frameobject.py @@ -7,32 +7,32 @@ from compas.geometry import Frame from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class FrameArtist(BlenderArtist, GeometryArtist): - """Artist for drawing frames in Blender. +class FrameObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing frames in Blender. Parameters ---------- - frame: :class:`~compas.geometry.Frame` + frame: :class:`compas.geometry.Frame` A COMPAS frame. **kwargs : dict, optional Additional keyword arguments. For more info, - see :class:`~compas_blender.artists.BlenderArtist` and :class:`~compas.artists.GeometryArtist`. + see :class:`compas_blender.scene.BlenderSceneObject` and :class:`compas.scene.GeometryObject`. Attributes ---------- - color_origin : :class:`~compas.colors.Color` + color_origin : :class:`compas.colors.Color` Color for the point at the frame origin. Default is ``Color.black()``. - color_xaxis : :class:`~compas.colors.Color` + color_xaxis : :class:`compas.colors.Color` Default is ``Color.red()``. - color_yaxis : :class:`~compas.colors.Color` + color_yaxis : :class:`compas.colors.Color` Default is ``Color.green()``. - color_zaxis : :class:`~compas.colors.Color` + color_zaxis : :class:`compas.colors.Color` Default is ``Color.blue()``. """ diff --git a/src/compas_blender/artists/lineartist.py b/src/compas_blender/scene/lineobject.py similarity index 77% rename from src/compas_blender/artists/lineartist.py rename to src/compas_blender/scene/lineobject.py index e2b0556d57f..c2428dea93f 100644 --- a/src/compas_blender/artists/lineartist.py +++ b/src/compas_blender/scene/lineobject.py @@ -9,21 +9,21 @@ from compas_blender import conversions -from compas.artists import GeometryArtist -from compas_blender.artists import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class LineArtist(BlenderArtist, GeometryArtist): - """Artist for drawing lines in Blender. +class LineObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing lines in Blender. Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` A COMPAS line. **kwargs : dict, optional Additional keyword arguments. For more info, - see :class:`~compas_blender.artists.BlenderArtist` and :class:`~compas.artists.GeometryArtist`. + see :class:`compas_blender.scene.BlenderSceneObject` and :class:`compas.scene.GeometryObject`. """ @@ -39,7 +39,7 @@ def draw( Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the box. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/meshartist.py b/src/compas_blender/scene/meshobject.py similarity index 94% rename from src/compas_blender/artists/meshartist.py rename to src/compas_blender/scene/meshobject.py index c2b65acd99a..84e5b8c93f0 100644 --- a/src/compas_blender/artists/meshartist.py +++ b/src/compas_blender/scene/meshobject.py @@ -17,18 +17,18 @@ from compas.geometry import scale_vector from compas.colors import Color -from compas.artists import MeshArtist as BaseArtist -from .artist import BlenderArtist +from compas.scene import MeshObject as BaseMeshObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class MeshArtist(BlenderArtist, BaseArtist): - """Artist for drawing mesh data structures in Blender. +class MeshObject(BlenderSceneObject, BaseMeshObject): + """Scene object for drawing mesh data structures in Blender. Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A COMPAS mesh. """ @@ -87,7 +87,7 @@ def draw( Parameters ---------- - color : :class:`~compas.colors.Color`, optional + color : :class:`compas.colors.Color`, optional The color of the mesh. collection : str, optional The name of the collection that should contain the mesh. @@ -124,7 +124,7 @@ def draw_vertices( vertices : list[int], optional A list of vertex keys identifying which vertices to draw. Default is None, in which case all vertices are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color specification for the vertices. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -174,7 +174,7 @@ def draw_edges( edges : list[tuple[int, int]], optional A list of edge keys (as uv pairs) identifying which edges to draw. The default is None, in which case all edges are drawn. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color specification for the edges. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -213,7 +213,7 @@ def draw_faces( faces : list[int], optional A list of face keys identifying which faces to draw. The default is None, in which case all faces are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color specification for the faces. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -259,7 +259,7 @@ def draw_vertexnormals( vertices : list[int], optional A selection of vertex normals to draw. Default is to draw all vertex normals. - color : :class:`~compas.colors.Color`, optional + color : :class:`compas.colors.Color`, optional The color specification of the normal vectors. scale : float, optional Scale factor for the vertex normals. @@ -305,7 +305,7 @@ def draw_facenormals( faces : list[int], optional A selection of face normals to draw. Default is to draw all face normals. - color : :class:`~compas.colors.Color`, optional + color : :class:`compas.colors.Color`, optional The color specification of the normal vectors. scale : float, optional Scale factor for the face normals. @@ -439,7 +439,7 @@ def draw_spheres( ---------- radius : dict[int, float], optional The radius of the spheres. - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the spheres. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -479,7 +479,7 @@ def draw_pipes( ---------- radius : dict[tuple[int, int], float] The radius per edge. - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color of the pipes. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/networkartist.py b/src/compas_blender/scene/networkobject.py similarity index 86% rename from src/compas_blender/artists/networkartist.py rename to src/compas_blender/scene/networkobject.py index 24268ea5868..47d705a10f2 100644 --- a/src/compas_blender/artists/networkartist.py +++ b/src/compas_blender/scene/networkobject.py @@ -12,18 +12,18 @@ from compas.colors import Color from compas.geometry import Line -from compas.artists import NetworkArtist as BaseArtist -from .artist import BlenderArtist +from compas.scene import NetworkObject as BaseSceneObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class NetworkArtist(BlenderArtist, BaseArtist): - """Artist for drawing network data structures in Blender. +class NetworkObject(BlenderSceneObject, BaseSceneObject): + """Scene object for drawing network data structures in Blender. Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A COMPAS network. """ @@ -98,9 +98,9 @@ def draw( edges : list[tuple[hashable, hashable]], optional A list of edge keys (as uv pairs) identifying which edges to draw. The default is None, in which case all edges are drawn. - nodecolor : :class:`~compas.colors.Color` | dict[hashable, :class:`~compas.colors.Color`], optional + nodecolor : :class:`compas.colors.Color` | dict[hashable, :class:`compas.colors.Color`], optional The color specification for the nodes. - edgecolor : :class:`~compas.colors.Color` | dict[tuple[hashable, hashable], :class:`~compas.colors.Color`], optional + edgecolor : :class:`compas.colors.Color` | dict[tuple[hashable, hashable], :class:`compas.colors.Color`], optional The color specification for the edges. Returns @@ -128,7 +128,7 @@ def draw_nodes( nodes : list[hashable], optional A list of node identifiers. Default is None, in which case all nodes are drawn. - color : :class:`~compas.colors.Color` | dict[hashable, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[hashable, :class:`compas.colors.Color`], optional The color specification for the nodes. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -145,7 +145,7 @@ def draw_nodes( for node in nodes or self.network.nodes(): # type: ignore name = f"{self.network.name}.node.{node}" # type: ignore color = self.node_color[node] # type: ignore - point = self.node_xyz[node] # type: ignore + point = self.network.nodes_attributes("xyz")[node] # type: ignore # there is no such thing as a sphere data block bpy.ops.mesh.primitive_uv_sphere_add(location=point, radius=radius, segments=u, ring_count=v) @@ -169,7 +169,7 @@ def draw_edges( edges : list[tuple[hashable, hashable]], optional A list of edge keys (as uv pairs) identifying which edges to draw. The default is None, in which case all edges are drawn. - color : :class:`~compas.colors.Color` | dict[tuple[hashable, hashable], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[hashable, hashable], :class:`compas.colors.Color`], optional The color specification for the edges. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -186,7 +186,9 @@ def draw_edges( for u, v in edges or self.network.edges(): # type: ignore name = f"{self.network.name}.edge.{u}-{v}" # type: ignore color = self.edge_color[u, v] # type: ignore - curve = conversions.line_to_blender_curve(Line(self.node_xyz[u], self.node_xyz[v])) + curve = conversions.line_to_blender_curve( + Line(self.network.nodes_attributes("xyz")[u], self.network.nodes_attributes("xyz")[v]) + ) obj = self.create_object(curve, name=name) self.update_object(obj, color=color, collection=collection) @@ -217,7 +219,7 @@ def draw_edges( # for node in self.node_text: # labels.append( # { - # "pos": self.node_xyz[node], + # "pos": self.network.nodes_attributes("xyz")[node], # "name": f"{self.network.name}.nodelabel.{node}", # "text": self.node_text[node], # "color": self.node_color[node], @@ -245,7 +247,7 @@ def draw_edges( # u, v = edge # labels.append( # { - # "pos": centroid_points([self.node_xyz[u], self.node_xyz[v]]), + # "pos": centroid_points([self.network.nodes_attributes("xyz")[u], self.network.nodes_attributes("xyz")[v]]), # "name": f"{self.network.name}.edgelabel.{u}-{v}", # "text": self.edge_text[edge], # "color": self.edge_color[edge], diff --git a/src/compas_blender/artists/pointcloudartist.py b/src/compas_blender/scene/pointcloudobject.py similarity index 84% rename from src/compas_blender/artists/pointcloudartist.py rename to src/compas_blender/scene/pointcloudobject.py index 4c28ecc437f..f5d98daa31a 100644 --- a/src/compas_blender/artists/pointcloudartist.py +++ b/src/compas_blender/scene/pointcloudobject.py @@ -6,18 +6,18 @@ from compas.geometry import Point from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class PointcloudArtist(BlenderArtist, GeometryArtist): - """Artist for drawing pointclouds in Blender. +class PointcloudObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing pointclouds in Blender. Parameters ---------- - pointcloud : :class:`~compas.geometry.Pointcloud` + pointcloud : :class:`compas.geometry.Pointcloud` A COMPAS point. **kwargs : dict, optional Additional keyword arguments. @@ -39,7 +39,7 @@ def draw( Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional Color of the point object. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/pointartist.py b/src/compas_blender/scene/pointobject.py similarity index 85% rename from src/compas_blender/artists/pointartist.py rename to src/compas_blender/scene/pointobject.py index b9a1836d1cd..641d204355d 100644 --- a/src/compas_blender/artists/pointartist.py +++ b/src/compas_blender/scene/pointobject.py @@ -6,16 +6,16 @@ from compas.geometry import Point from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class PointArtist(BlenderArtist, GeometryArtist): - """Artist for drawing points in Blender. +class PointObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing points in Blender. Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` A COMPAS point. **kwargs : dict, optional Additional keyword arguments. @@ -37,7 +37,7 @@ def draw( Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional Color of the point object. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/polygonartist.py b/src/compas_blender/scene/polygonobject.py similarity index 82% rename from src/compas_blender/artists/polygonartist.py rename to src/compas_blender/scene/polygonobject.py index e5dc7bfe01e..54a93e600fb 100644 --- a/src/compas_blender/artists/polygonartist.py +++ b/src/compas_blender/scene/polygonobject.py @@ -9,16 +9,16 @@ from compas_blender import conversions -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject -class PolygonArtist(BlenderArtist, GeometryArtist): - """Artist for drawing polygons in Blender. +class PolygonObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing polygons in Blender. Parameters ---------- - polygon : :class:`~compas.geometry.Polygon` + polygon : :class:`compas.geometry.Polygon` A COMPAS polygon. **kwargs : dict, optional Additional keyword arguments. @@ -37,7 +37,7 @@ def draw( Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional The RGB color of the polygon. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/polyhedronartist.py b/src/compas_blender/scene/polyhedronobject.py similarity index 80% rename from src/compas_blender/artists/polyhedronartist.py rename to src/compas_blender/scene/polyhedronobject.py index da0fa10dd20..303c4da34b1 100644 --- a/src/compas_blender/artists/polyhedronartist.py +++ b/src/compas_blender/scene/polyhedronobject.py @@ -6,18 +6,18 @@ from compas.geometry import Polyhedron from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class PolyhedronArtist(BlenderArtist, GeometryArtist): - """Artist for drawing polyhedron shapes in Blender. +class PolyhedronObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing polyhedron shapes in Blender. Parameters ---------- - polyhedron : :class:`~compas.geometry.Polyhedron` + polyhedron : :class:`compas.geometry.Polyhedron` A COMPAS polyhedron. **kwargs : dict, optional Additional keyword arguments. @@ -30,11 +30,11 @@ def __init__(self, polyhedron: Polyhedron, **kwargs: Any): def draw( self, color: Optional[Color] = None, collection: Optional[str] = None, show_wire: bool = True ) -> List[bpy.types.Object]: - """Draw the polyhedron associated with the artist. + """Draw the polyhedron associated with the scene object. Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional The RGB color of the polyhedron. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/polylineartist.py b/src/compas_blender/scene/polylineobject.py similarity index 81% rename from src/compas_blender/artists/polylineartist.py rename to src/compas_blender/scene/polylineobject.py index 1ef1d54649a..0366904173e 100644 --- a/src/compas_blender/artists/polylineartist.py +++ b/src/compas_blender/scene/polylineobject.py @@ -6,18 +6,18 @@ from compas.geometry import Polyline from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class PolylineArtist(BlenderArtist, GeometryArtist): - """Artist for drawing polylines in Blender. +class PolylineObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing polylines in Blender. Parameters ---------- - polyline : :class:`~compas.geometry.Polyline` + polyline : :class:`compas.geometry.Polyline` A COMPAS polyline. **kwargs : dict, optional Additional keyword arguments. @@ -32,7 +32,7 @@ def draw(self, color: Optional[Color] = None, collection: Optional[str] = None) Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional The RGB color of the polyline. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/artist.py b/src/compas_blender/scene/sceneobject.py similarity index 97% rename from src/compas_blender/artists/artist.py rename to src/compas_blender/scene/sceneobject.py index 917abe2bfda..1307eafafa3 100644 --- a/src/compas_blender/artists/artist.py +++ b/src/compas_blender/scene/sceneobject.py @@ -6,26 +6,26 @@ import compas_blender from compas.colors import Color -from compas.artists import Artist +from compas.scene import SceneObject from compas.geometry import Transformation from compas_blender import conversions -class BlenderArtist(Artist): - """Base class for all Blender artists. +class BlenderSceneObject(SceneObject): + """Base class for all Blender scene objects. Parameters ---------- collection : str | :blender:`bpy.types.Collection`, optional - The Blender scene collection the object(s) created by the artist belong to. + The Blender scene collection the object(s) created by the scene object belong to. **kwargs : dict, optional Additional keyword arguments. Attributes ---------- objects : list[:blender:`bpy.types.Object`] - The Blender objects created by the artist. + The Blender objects created by the scene object. """ diff --git a/src/compas_blender/artists/sphereartist.py b/src/compas_blender/scene/sphereobject.py similarity index 84% rename from src/compas_blender/artists/sphereartist.py rename to src/compas_blender/scene/sphereobject.py index 6cf199322d7..c35bc5968f9 100644 --- a/src/compas_blender/artists/sphereartist.py +++ b/src/compas_blender/scene/sphereobject.py @@ -7,18 +7,18 @@ from compas.geometry import Sphere from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class SphereArtist(BlenderArtist, GeometryArtist): - """Artist for drawing sphere shapes in Blender. +class SphereObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing sphere shapes in Blender. Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + sphere : :class:`compas.geometry.Sphere` A COMPAS sphere. **kwargs : dict, optional Additional keyword arguments. @@ -37,11 +37,11 @@ def draw( show_wire: bool = False, shade_smooth: bool = True, ) -> List[bpy.types.Object]: - """Draw the sphere associated with the artist. + """Draw the sphere associated with the scene object. Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional The RGB color of the sphere. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/surfaceartist.py b/src/compas_blender/scene/surfaceobject.py similarity index 81% rename from src/compas_blender/artists/surfaceartist.py rename to src/compas_blender/scene/surfaceobject.py index 8a40f349d26..6562ecd095b 100644 --- a/src/compas_blender/artists/surfaceartist.py +++ b/src/compas_blender/scene/surfaceobject.py @@ -6,18 +6,18 @@ from compas.geometry import Surface from compas.colors import Color -from compas.artists import GeometryArtist -from compas_blender.artists import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class SurfaceArtist(BlenderArtist, GeometryArtist): - """Artist for drawing surfaces in Blender. +class SurfaceObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing surfaces in Blender. Parameters ---------- - surface : :class:`~compas.geometry.Surface` + surface : :class:`compas.geometry.Surface` A COMPAS surface. **kwargs : dict, optional Additional keyword arguments. @@ -32,7 +32,7 @@ def draw(self, color: Optional[Color] = None, collection: Optional[str] = None) Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional The RGB color of the surface. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/torusartist.py b/src/compas_blender/scene/torusobject.py similarity index 84% rename from src/compas_blender/artists/torusartist.py rename to src/compas_blender/scene/torusobject.py index c16a3963154..808f2fdabce 100644 --- a/src/compas_blender/artists/torusartist.py +++ b/src/compas_blender/scene/torusobject.py @@ -6,18 +6,18 @@ from compas.geometry import Torus from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class TorusArtist(BlenderArtist, GeometryArtist): - """Artist for drawing torus shapes in Blender. +class TorusObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing torus shapes in Blender. Parameters ---------- - torus : :class:`~compas.geometry.Torus` + torus : :class:`compas.geometry.Torus` A COMPAS torus. **kwargs : dict, optional Additional keyword arguments. @@ -36,11 +36,11 @@ def draw( show_wire: bool = False, shade_smooth: bool = True, ) -> bpy.types.Object: - """Draw the torus associated with the artist. + """Draw the torus associated with the scene object. Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional The RGB color of the torus. collection : str, optional The name of the Blender scene collection containing the created object(s). diff --git a/src/compas_blender/artists/vectorartist.py b/src/compas_blender/scene/vectorobject.py similarity index 81% rename from src/compas_blender/artists/vectorartist.py rename to src/compas_blender/scene/vectorobject.py index c8f512ddc3f..99a66f7a8bf 100644 --- a/src/compas_blender/artists/vectorartist.py +++ b/src/compas_blender/scene/vectorobject.py @@ -8,18 +8,18 @@ from compas.geometry import Line from compas.colors import Color -from compas.artists import GeometryArtist -from .artist import BlenderArtist +from compas.scene import GeometryObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class VectorArtist(BlenderArtist, GeometryArtist): - """Artist for drawing vectors in Blender. +class VectorObject(BlenderSceneObject, GeometryObject): + """Scene object for drawing vectors in Blender. Parameters ---------- - primitive : :class:`~compas.geometry.Vector` + primitive : :class:`compas.geometry.Vector` A COMPAS vector. **kwargs : dict, optional Additional keyword arguments. @@ -39,11 +39,11 @@ def draw( Parameters ---------- - color : tuple[float, float, float] | tuple[int, int, int] | :class:`~compas.colors.Color`, optional + color : tuple[float, float, float] | tuple[int, int, int] | :class:`compas.colors.Color`, optional The RGB color of the vector. collection : str, optional The name of the Blender scene collection containing the created object(s). - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional Point of application of the vector. Default is ``Point(0, 0, 0)``. diff --git a/src/compas_blender/artists/volmeshartist.py b/src/compas_blender/scene/volmeshobject.py similarity index 88% rename from src/compas_blender/artists/volmeshartist.py rename to src/compas_blender/scene/volmeshobject.py index b40b87cb437..f0eff14c54f 100644 --- a/src/compas_blender/artists/volmeshartist.py +++ b/src/compas_blender/scene/volmeshobject.py @@ -15,18 +15,18 @@ from compas.geometry import Line from compas.colors import Color -from compas.artists import VolMeshArtist as BaseArtist -from .artist import BlenderArtist +from compas.scene import VolMeshObject as BaseVolMeshObject +from .sceneobject import BlenderSceneObject from compas_blender import conversions -class VolMeshArtist(BlenderArtist, BaseArtist): - """An artist for drawing volumetric mesh data structures in Blender. +class VolMeshObject(BlenderSceneObject, BaseVolMeshObject): + """A scene object for drawing volumetric mesh data structures in Blender. Parameters ---------- - volmesh : :class:`~compas.datastructures.VolMesh` + volmesh : :class:`compas.datastructures.VolMesh` The volmesh data structure. **kwargs : dict, optional Additional keyword arguments. @@ -101,9 +101,9 @@ def draw( cells : list[int], optional A list of cells to draw. The default is None, in which case all cells are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the cells. - The default color is :attr:`VolMeshArtist.default_cellcolor`. + The default color is :attr:`VolMeshObject.default_cellcolor`. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -130,7 +130,7 @@ def draw_vertices( vertices : list[int], optional A list of vertex keys identifying which vertices to draw. Default is None, in which case all vertices are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color specification for the vertices. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -153,7 +153,7 @@ def draw_vertices( for vertex in vertices or self.volmesh.vertices(): # type: ignore name = f"{self.volmesh.name}.vertex.{vertex}" # type: ignore color = self.vertex_color[vertex] # type: ignore - point = self.vertex_xyz[vertex] + point = self.volmesh.vertices_attributes("xyz")[vertex] # there is no such thing as a sphere data block bpy.ops.mesh.primitive_uv_sphere_add(location=point, radius=radius, segments=u, ring_count=v) @@ -177,7 +177,7 @@ def draw_edges( edges : list[tuple[int, int]], optional A list of edge keys (as uv pairs) identifying which edges to draw. The default is None, in which case all edges are drawn. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color specification for the edges. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -194,7 +194,9 @@ def draw_edges( for u, v in edges or self.volmesh.edges(): # type: ignore name = f"{self.volmesh.name}.edge.{u}-{v}" # type: ignore color = self.edge_color[u, v] # type: ignore - curve = conversions.line_to_blender_curve(Line(self.vertex_xyz[u], self.vertex_xyz[v])) + curve = conversions.line_to_blender_curve( + Line(self.volmesh.vertices_attributes("xyz")[u], self.volmesh.vertices_attributes("xyz")[v]) + ) obj = self.create_object(curve, name=name) self.update_object(obj, color=color, collection=collection) # type: ignore @@ -216,7 +218,7 @@ def draw_faces( faces : list[int], optional A list of face keys identifying which faces to draw. The default is None, in which case all faces are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color specification for the faces. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -235,7 +237,7 @@ def draw_faces( for face in faces or self.volmesh.faces(): # type: ignore name = f"{self.volmesh.name}.face.{face}" # type: ignore color = self.face_color[face] # type: ignore - points = [self.vertex_xyz[vertex] for vertex in self.volmesh.face_vertices(face)] # type: ignore + points = [self.volmesh.vertices_attributes("xyz")[vertex] for vertex in self.volmesh.face_vertices(face)] # type: ignore mesh = conversions.polygon_to_blender_mesh(points, name=name) # type: ignore obj = self.create_object(mesh, name=name) @@ -258,7 +260,7 @@ def draw_cells( cells : list[int], optional A list of cells to draw. The default is None, in which case all cells are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the cells. collection : str, optional The name of the Blender scene collection containing the created object(s). @@ -282,7 +284,7 @@ def draw_cells( faces = self.volmesh.cell_faces(cell) # type: ignore vertex_index = dict((vertex, index) for index, vertex in enumerate(vertices)) - vertices = [self.vertex_xyz[vertex] for vertex in vertices] + vertices = [self.volmesh.vertices_attributes("xyz")[vertex] for vertex in vertices] faces = [[vertex_index[vertex] for vertex in self.volmesh.halfface_vertices(face)] for face in faces] # type: ignore mesh = conversions.vertices_and_faces_to_blender_mesh(vertices, faces, name=name) # type: ignore @@ -312,7 +314,7 @@ def draw_vertexnormals( vertices : list[int], optional A selection of vertex normals to draw. Default is to draw all vertex normals. - color : :class:`~compas.colors.Color`, optional + color : :class:`compas.colors.Color`, optional The color specification of the normal vectors. scale : float, optional Scale factor for the vertex normals. @@ -331,7 +333,7 @@ def draw_vertexnormals( for vertex in vertices or self.volmesh.vertices(): # type: ignore name = f"{self.volmesh.name}.vertex.{vertex}.normal" # type: ignore - a = self.vertex_xyz[vertex] + a = self.volmesh.vertices_attributes("xyz")[vertex] n = self.volmesh.vertex_normal(vertex) # type: ignore b = add_vectors(a, scale_vector(n, scale)) @@ -358,7 +360,7 @@ def draw_facenormals( faces : list[int], optional A selection of face normals to draw. Default is to draw all face normals. - color : :class:`~compas.colors.Color`, optional + color : :class:`compas.colors.Color`, optional The color specification of the normal vectors. scale : float, optional Scale factor for the face normals. @@ -377,7 +379,7 @@ def draw_facenormals( for face in faces or self.volmesh.faces(): # type: ignore name = f"{self.volmesh.name}.face.{face}.normal" # type: ignore - a = centroid_points([self.vertex_xyz[vertex] for vertex in self.volmesh.face_vertices(face)]) # type: ignore + a = centroid_points([self.volmesh.vertices_attributes("xyz")[vertex] for vertex in self.volmesh.face_vertices(face)]) # type: ignore n = self.volmesh.face_normal(face) # type: ignore b = add_vectors(a, scale_vector(n, scale)) @@ -413,7 +415,7 @@ def draw_facenormals( # for vertex in self.vertex_text: # labels.append( # { - # "pos": self.vertex_xyz[vertex], + # "pos": self.volmesh.vertices_attributes("xyz")[vertex], # "name": f"{self.volmesh.name}.vertexlabel.{vertex}", # "text": self.vertex_text[vertex], # "color": self.vertex_color[vertex], @@ -441,7 +443,7 @@ def draw_facenormals( # u, v = edge # labels.append( # { - # "pos": centroid_points([self.vertex_xyz[u], self.vertex_xyz[v]]), + # "pos": centroid_points([self.volmesh.vertices_attributes("xyz")[u], self.volmesh.vertices_attributes("xyz")[v]]), # "name": f"{self.volmesh.name}.edgelabel.{u}-{v}", # "text": self.edge_text[edge], # "color": self.edge_color[edge], @@ -468,7 +470,7 @@ def draw_facenormals( # for face in self.face_text: # labels.append( # { - # "pos": centroid_points([self.vertex_xyz[vertex] for vertex in self.volmesh.face_vertices(face)]), + # "pos": centroid_points([self.volmesh.vertices_attributes("xyz")[vertex] for vertex in self.volmesh.face_vertices(face)]), # "name": "{}.facelabel.{}".format(self.volmesh.name, face), # "text": self.face_text[face], # "color": self.face_color[face], diff --git a/src/compas_blender/utilities/drawing.py b/src/compas_blender/utilities/drawing.py index 1a51554712f..8cd008a2e6a 100644 --- a/src/compas_blender/utilities/drawing.py +++ b/src/compas_blender/utilities/drawing.py @@ -630,7 +630,7 @@ def draw_mesh( Parameters ---------- - vertices : list[[float, float, float] | :class:`~compas.geometry.Point`] + vertices : list[[float, float, float] | :class:`compas.geometry.Point`] The vertices of the mesh. faces : list[list[int]] The faces of the mesh. diff --git a/src/compas_ghpython/__init__.py b/src/compas_ghpython/__init__.py index c15758a481c..1f7ce54c592 100644 --- a/src/compas_ghpython/__init__.py +++ b/src/compas_ghpython/__init__.py @@ -1,17 +1,3 @@ -""" -******************************************************************************** -compas_ghpython -******************************************************************************** - -.. currentmodule:: compas_ghpython - -.. toctree:: - :maxdepth: 1 - - compas_ghpython.artists - compas_ghpython.utilities - -""" import io import os import urllib @@ -34,7 +20,7 @@ __all_plugins__ = [ "compas_ghpython.install", "compas_ghpython.uninstall", - "compas_ghpython.artists", + "compas_ghpython.scene", ] diff --git a/src/compas_ghpython/artists/__init__.py b/src/compas_ghpython/artists/__init__.py deleted file mode 100644 index 56427759597..00000000000 --- a/src/compas_ghpython/artists/__init__.py +++ /dev/null @@ -1,101 +0,0 @@ -from __future__ import absolute_import - -from compas.plugins import plugin -from compas.artists import Artist - -from compas.geometry import Box -from compas.geometry import Capsule -from compas.geometry import Circle -from compas.geometry import Cone -from compas.geometry import Curve -from compas.geometry import Cylinder -from compas.geometry import Ellipse -from compas.geometry import Frame -from compas.geometry import Line -from compas.geometry import Point -from compas.geometry import Polygon -from compas.geometry import Polyhedron -from compas.geometry import Polyline -from compas.geometry import Sphere -from compas.geometry import Surface -from compas.geometry import Torus -from compas.geometry import Vector -from compas.geometry import Brep - -from compas.datastructures import Mesh -from compas.datastructures import Network -from compas.datastructures import VolMesh - -from .artist import GHArtist -from .boxartist import BoxArtist -from .capsuleartist import CapsuleArtist -from .circleartist import CircleArtist -from .coneartist import ConeArtist -from .curveartist import CurveArtist -from .cylinderartist import CylinderArtist -from .ellipseartist import EllipseArtist -from .frameartist import FrameArtist -from .lineartist import LineArtist -from .meshartist import MeshArtist -from .networkartist import NetworkArtist -from .pointartist import PointArtist -from .polygonartist import PolygonArtist -from .polyhedronartist import PolyhedronArtist -from .polylineartist import PolylineArtist -from .sphereartist import SphereArtist -from .surfaceartist import SurfaceArtist -from .torusartist import TorusArtist -from .vectorartist import VectorArtist -from .volmeshartist import VolMeshArtist -from .brepartist import BrepArtist - - -@plugin(category="factories", requires=["Rhino"]) -def register_artists(): - Artist.register(Box, BoxArtist, context="Grasshopper") - Artist.register(Capsule, CapsuleArtist, context="Grasshopper") - Artist.register(Circle, CircleArtist, context="Grasshopper") - Artist.register(Cone, ConeArtist, context="Grasshopper") - Artist.register(Curve, CurveArtist, context="Grasshopper") - Artist.register(Cylinder, CylinderArtist, context="Grasshopper") - Artist.register(Ellipse, EllipseArtist, context="Grasshopper") - Artist.register(Frame, FrameArtist, context="Grasshopper") - Artist.register(Line, LineArtist, context="Grasshopper") - Artist.register(Mesh, MeshArtist, context="Grasshopper") - Artist.register(Network, NetworkArtist, context="Grasshopper") - Artist.register(Point, PointArtist, context="Grasshopper") - Artist.register(Polygon, PolygonArtist, context="Grasshopper") - Artist.register(Polyhedron, PolyhedronArtist, context="Grasshopper") - Artist.register(Polyline, PolylineArtist, context="Grasshopper") - Artist.register(Sphere, SphereArtist, context="Grasshopper") - Artist.register(Surface, SurfaceArtist, context="Grasshopper") - Artist.register(Torus, TorusArtist, context="Grasshopper") - Artist.register(Vector, VectorArtist, context="Grasshopper") - Artist.register(VolMesh, VolMeshArtist, context="Grasshopper") - Artist.register(Brep, BrepArtist, context="Grasshopper") - print("GH Artists registered.") - - -__all__ = [ - "GHArtist", - "BoxArtist", - "CapsuleArtist", - "CircleArtist", - "ConeArtist", - "CurveArtist", - "CylinderArtist", - "EllipseArtist", - "FrameArtist", - "LineArtist", - "MeshArtist", - "NetworkArtist", - "PointArtist", - "PolygonArtist", - "PolyhedronArtist", - "PolylineArtist", - "SphereArtist", - "SurfaceArtist", - "TorusArtist", - "VectorArtist", - "VolMeshArtist", -] diff --git a/src/compas_ghpython/artists/torusartist.py b/src/compas_ghpython/artists/torusartist.py deleted file mode 100644 index bd3016b001a..00000000000 --- a/src/compas_ghpython/artists/torusartist.py +++ /dev/null @@ -1,39 +0,0 @@ -from __future__ import print_function -from __future__ import absolute_import -from __future__ import division - -from compas_rhino import conversions - -from compas.artists import GeometryArtist -from .artist import GHArtist - - -class TorusArtist(GHArtist, GeometryArtist): - """Artist for drawing torus shapes. - - Parameters - ---------- - torus : :class:`~compas.geometry.Torus` - A COMPAS torus. - **kwargs : dict, optional - Additional keyword arguments. - - """ - - def __init__(self, torus, **kwargs): - super(TorusArtist, self).__init__(geometry=torus, **kwargs) - - def draw(self): - """Draw the torus associated with the artist. - - Returns - ------- - :rhino:`Rhino.Geometry.Torus` - - """ - geometry = conversions.torus_to_rhino(self.geometry) - - if self.transformation: - geometry.Transform(conversions.transformation_to_rhino(self.transformation)) - - return geometry diff --git a/src/compas_ghpython/components/Compas_ToRhinoGeometry/code.py b/src/compas_ghpython/components/Compas_ToRhinoGeometry/code.py index f152ef89648..1d5ede76f5c 100644 --- a/src/compas_ghpython/components/Compas_ToRhinoGeometry/code.py +++ b/src/compas_ghpython/components/Compas_ToRhinoGeometry/code.py @@ -3,7 +3,7 @@ """ from ghpythonlib.componentbase import executingcomponent as component -from compas.artists import Artist +from compas.scene import SceneObject class CompasToRhinoGeometry(component): @@ -11,4 +11,4 @@ def RunScript(self, cg): if not cg: return None - return Artist(cg).draw() + return SceneObject(cg).draw() diff --git a/src/compas_ghpython/components/__init__.py b/src/compas_ghpython/components/__init__.py index 63578381203..d9187ae98dc 100644 --- a/src/compas_ghpython/components/__init__.py +++ b/src/compas_ghpython/components/__init__.py @@ -1,3 +1,6 @@ +""" +This package provides a small set of functions to easily install and uninstall user-defined GH Components. +""" from __future__ import absolute_import import glob diff --git a/src/compas_ghpython/conversions/__init__.py b/src/compas_ghpython/conversions/__init__.py deleted file mode 100644 index 06fd6602255..00000000000 --- a/src/compas_ghpython/conversions/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -from .meshes import mesh_to_rhino -from .meshes import vertices_and_faces_to_rhino_mesh - -__all__ = [ - "mesh_to_rhino", - "vertices_and_faces_to_rhino_mesh", -] diff --git a/src/compas_ghpython/conversions/meshes.py b/src/compas_ghpython/conversions/meshes.py deleted file mode 100644 index 0301b03a368..00000000000 --- a/src/compas_ghpython/conversions/meshes.py +++ /dev/null @@ -1,105 +0,0 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import rhinoscriptsyntax as rs # type: ignore - -from Rhino.Geometry import Mesh as RhinoMesh # type: ignore -from Rhino.Geometry import Point2f # type: ignore -from Rhino.Geometry import Vector3f # type: ignore - -from System.Array import CreateInstance # type: ignore -from System.Drawing import Color # type: ignore - -try: - from Rhino.Geometry import MeshNgon # type: ignore -except ImportError: - MeshNgon = False - -from compas.geometry import centroid_points -from compas.utilities import pairwise - - -def vertices_and_faces_to_rhino_mesh(vertices, faces, color=None, vertex_normals=None, texture_coordinates=None): - """Convert a list of vertices and faces to a Rhino mesh. - - Parameters - ---------- - vertices : list - A list of vertex coordinates. - faces : list - A list of faces, with each face defined as a list of indices into the list of vertices. - - Returns - ------- - :rhino:`Rhino.Geometry.Mesh` - - """ - rmesh = RhinoMesh() - - for a, b, c in vertices: - rmesh.Vertices.Add(a, b, c) - - for face in faces: - f = len(face) - if f < 3: - continue - if f == 3: - rmesh.Faces.AddFace(*face) - elif f == 4: - rmesh.Faces.AddFace(*face) - else: - if MeshNgon: - centroid = centroid_points([vertices[index] for index in face]) - c = rmesh.Vertices.Add(*centroid) - facets = [] - for i, j in pairwise(face + face[:1]): - facets.append(rmesh.Faces.AddFace(i, j, c)) - ngon = MeshNgon.Create(face, facets) # type: ignore - rmesh.Ngons.AddNgon(ngon) - - if vertex_normals: - count = len(vertex_normals) - normals = CreateInstance(Vector3f, count) - for i, normal in enumerate(vertex_normals): - normals[i] = Vector3f(normal[0], normal[1], normal[2]) - rmesh.Normals.SetNormals(normals) - - if texture_coordinates: - count = len(texture_coordinates) - tcs = CreateInstance(Point2f, count) - for i, tc in enumerate(texture_coordinates): - tcs[i] = Point2f(tc[0], tc[1]) - rmesh.TextureCoordinates.SetTextureCoordinates(tcs) - - if color: - count = len(rmesh.Vertices) - colors = CreateInstance(Color, count) - for i in range(count): - colors[i] = rs.coercecolor(color) - rmesh.VertexColors.SetColors(colors) - - return rmesh - - -def mesh_to_rhino(mesh, color=None, vertex_normals=None, texture_coordinates=None): - """Convert a COMPAS mesh to a Rhino mesh. - - Parameters - ---------- - mesh : :class:`compas.datastructures.Mesh` - A COMPAS mesh. - - Returns - ------- - :class:`Rhino.Geometry.Mesh` - - """ - vertices, faces = mesh.to_vertices_and_faces() - return vertices_and_faces_to_rhino_mesh( - vertices, - faces, - color=color, - vertex_normals=vertex_normals, - texture_coordinates=texture_coordinates, - ) diff --git a/src/compas_ghpython/scene/__init__.py b/src/compas_ghpython/scene/__init__.py new file mode 100644 index 00000000000..39849ce363a --- /dev/null +++ b/src/compas_ghpython/scene/__init__.py @@ -0,0 +1,105 @@ +""" +This package provides scene object plugins for visualising COMPAS objects in Grasshopper. +When working in GH Python components, :class:`compas.scene.SceneObject` will automatically use the corresponding GHPython scene object for each COMPAS object type. +""" +from __future__ import absolute_import + +from compas.plugins import plugin +from compas.scene import SceneObject + +from compas.geometry import Box +from compas.geometry import Capsule +from compas.geometry import Circle +from compas.geometry import Cone +from compas.geometry import Curve +from compas.geometry import Cylinder +from compas.geometry import Ellipse +from compas.geometry import Frame +from compas.geometry import Line +from compas.geometry import Point +from compas.geometry import Polygon +from compas.geometry import Polyhedron +from compas.geometry import Polyline +from compas.geometry import Sphere +from compas.geometry import Surface +from compas.geometry import Torus +from compas.geometry import Vector +from compas.geometry import Brep + +from compas.datastructures import Mesh +from compas.datastructures import Network +from compas.datastructures import VolMesh + +from .sceneobject import GHSceneObject +from .boxobject import BoxObject +from .capsuleobject import CapsuleObject +from .circleobject import CircleObject +from .coneobject import ConeObject +from .curveobject import CurveObject +from .cylinderobject import CylinderObject +from .ellipseobject import EllipseObject +from .frameobject import FrameObject +from .lineobject import LineObject +from .meshobject import MeshObject +from .networkobject import NetworkObject +from .pointobject import PointObject +from .polygonobject import PolygonObject +from .polyhedronobject import PolyhedronObject +from .polylineobject import PolylineObject +from .sphereobject import SphereObject +from .surfaceobject import SurfaceObject +from .torusobject import TorusObject +from .vectorobject import VectorObject +from .volmeshobject import VolMeshObject +from .brepobject import BrepObject + + +@plugin(category="factories", requires=["Rhino"]) +def register_scene_objects(): + SceneObject.register(Box, BoxObject, context="Grasshopper") + SceneObject.register(Capsule, CapsuleObject, context="Grasshopper") + SceneObject.register(Circle, CircleObject, context="Grasshopper") + SceneObject.register(Cone, ConeObject, context="Grasshopper") + SceneObject.register(Curve, CurveObject, context="Grasshopper") + SceneObject.register(Cylinder, CylinderObject, context="Grasshopper") + SceneObject.register(Ellipse, EllipseObject, context="Grasshopper") + SceneObject.register(Frame, FrameObject, context="Grasshopper") + SceneObject.register(Line, LineObject, context="Grasshopper") + SceneObject.register(Mesh, MeshObject, context="Grasshopper") + SceneObject.register(Network, NetworkObject, context="Grasshopper") + SceneObject.register(Point, PointObject, context="Grasshopper") + SceneObject.register(Polygon, PolygonObject, context="Grasshopper") + SceneObject.register(Polyhedron, PolyhedronObject, context="Grasshopper") + SceneObject.register(Polyline, PolylineObject, context="Grasshopper") + SceneObject.register(Sphere, SphereObject, context="Grasshopper") + SceneObject.register(Surface, SurfaceObject, context="Grasshopper") + SceneObject.register(Torus, TorusObject, context="Grasshopper") + SceneObject.register(Vector, VectorObject, context="Grasshopper") + SceneObject.register(VolMesh, VolMeshObject, context="Grasshopper") + SceneObject.register(Brep, BrepObject, context="Grasshopper") + print("GH SceneObjects registered.") + + +__all__ = [ + "GHSceneObject", + "BoxObject", + "CapsuleObject", + "CircleObject", + "ConeObject", + "CurveObject", + "CylinderObject", + "EllipseObject", + "FrameObject", + "LineObject", + "MeshObject", + "NetworkObject", + "PointObject", + "PolygonObject", + "PolyhedronObject", + "PolylineObject", + "SphereObject", + "SurfaceObject", + "TorusObject", + "VectorObject", + "VolMeshObject", +] diff --git a/src/compas_ghpython/artists/boxartist.py b/src/compas_ghpython/scene/boxobject.py similarity index 66% rename from src/compas_ghpython/artists/boxartist.py rename to src/compas_ghpython/scene/boxobject.py index ec186106d11..39412115f14 100644 --- a/src/compas_ghpython/artists/boxartist.py +++ b/src/compas_ghpython/scene/boxobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class BoxArtist(GHArtist, GeometryArtist): - """Artist for drawing box shapes. +class BoxObject(GHSceneObject, GeometryObject): + """Scene object for drawing box shapes. Parameters ---------- - box : :class:`~compas.geometry.Box` + box : :class:`compas.geometry.Box` A COMPAS box. **kwargs : dict, optional Additional keyword arguments. @@ -21,10 +21,10 @@ class BoxArtist(GHArtist, GeometryArtist): """ def __init__(self, box, **kwargs): - super(BoxArtist, self).__init__(geometry=box, **kwargs) + super(BoxObject, self).__init__(geometry=box, **kwargs) def draw(self): - """Draw the box associated with the artist. + """Draw the box associated with the scene object. Returns ------- diff --git a/src/compas_ghpython/artists/brepartist.py b/src/compas_ghpython/scene/brepobject.py similarity index 71% rename from src/compas_ghpython/artists/brepartist.py rename to src/compas_ghpython/scene/brepobject.py index 75ed854f123..ed2cbf7a5b9 100644 --- a/src/compas_ghpython/artists/brepartist.py +++ b/src/compas_ghpython/scene/brepobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class BrepArtist(GHArtist, GeometryArtist): - """An artist for drawing a brep in Grasshopper. +class BrepObject(GHSceneObject, GeometryObject): + """A Scene object for drawing a brep in Grasshopper. Parameters ---------- - brep : :class:`~compas_rhino.geometry.RhinoBrep` + brep : :class:`compas_rhino.geometry.RhinoBrep` The brep to draw. **kwargs : dict, optional Additional keyword arguments. @@ -21,7 +21,7 @@ class BrepArtist(GHArtist, GeometryArtist): """ def __init__(self, brep, **kwargs): - super(BrepArtist, self).__init__(geometry=brep, **kwargs) + super(BrepObject, self).__init__(geometry=brep, **kwargs) def draw(self): """Draw the brep as a Grasshopper geometry. diff --git a/src/compas_ghpython/artists/capsuleartist.py b/src/compas_ghpython/scene/capsuleobject.py similarity index 67% rename from src/compas_ghpython/artists/capsuleartist.py rename to src/compas_ghpython/scene/capsuleobject.py index 371b111fd6b..068e847b604 100644 --- a/src/compas_ghpython/artists/capsuleartist.py +++ b/src/compas_ghpython/scene/capsuleobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class CapsuleArtist(GHArtist, GeometryArtist): - """Artist for drawing capsule shapes. +class CapsuleObject(GHSceneObject, GeometryObject): + """Scene object for drawing capsule shapes. Parameters ---------- - capsule : :class:`~compas.geometry.Capsule` + capsule : :class:`compas.geometry.Capsule` A COMPAS capsule. **kwargs : dict, optional Additional keyword arguments. @@ -21,10 +21,10 @@ class CapsuleArtist(GHArtist, GeometryArtist): """ def __init__(self, capsule, **kwargs): - super(CapsuleArtist, self).__init__(geometry=capsule, **kwargs) + super(CapsuleObject, self).__init__(geometry=capsule, **kwargs) def draw(self): - """Draw the capsule associated with the artist. + """Draw the capsule associated with the scene object. Returns ------- diff --git a/src/compas_ghpython/artists/circleartist.py b/src/compas_ghpython/scene/circleobject.py similarity index 71% rename from src/compas_ghpython/artists/circleartist.py rename to src/compas_ghpython/scene/circleobject.py index 32d14eaa9cb..b6141693464 100644 --- a/src/compas_ghpython/artists/circleartist.py +++ b/src/compas_ghpython/scene/circleobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class CircleArtist(GHArtist, GeometryArtist): - """Artist for drawing circles. +class CircleObject(GHSceneObject, GeometryObject): + """Scene object for drawing circles. Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` A COMPAS circle. **kwargs : dict, optional Additional keyword arguments. @@ -21,7 +21,7 @@ class CircleArtist(GHArtist, GeometryArtist): """ def __init__(self, circle, **kwargs): - super(CircleArtist, self).__init__(geometry=circle, **kwargs) + super(CircleObject, self).__init__(geometry=circle, **kwargs) def draw(self): """Draw the circle. diff --git a/src/compas_ghpython/artists/coneartist.py b/src/compas_ghpython/scene/coneobject.py similarity index 53% rename from src/compas_ghpython/artists/coneartist.py rename to src/compas_ghpython/scene/coneobject.py index f1d624b9c65..6d358d3155b 100644 --- a/src/compas_ghpython/artists/coneartist.py +++ b/src/compas_ghpython/scene/coneobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class ConeArtist(GHArtist, GeometryArtist): - """Artist for drawing cone shapes. +class ConeObject(GHSceneObject, GeometryObject): + """Scene object for drawing cone shapes. Parameters ---------- - shape : :class:`~compas.geometry.Cone` + shape : :class:`compas.geometry.Cone` A COMPAS cone. **kwargs : dict, optional Additional keyword arguments. @@ -21,21 +21,20 @@ class ConeArtist(GHArtist, GeometryArtist): """ def __init__(self, cone, **kwargs): - super(ConeArtist, self).__init__(geometry=cone, **kwargs) + super(ConeObject, self).__init__(geometry=cone, **kwargs) def draw(self): - """Draw the cone associated with the artist. + """Draw the cone associated with the scene object. Returns ------- list[:rhino:`Rhino.Geometry.Brep`] """ - breps = conversions.cone_to_rhino_brep(self.geometry) + brep = conversions.cone_to_rhino_brep(self.geometry) if self.transformation: transformation = conversions.transformation_to_rhino(self.transformation) - for geometry in breps: - geometry.Transform(transformation) + brep.Transform(transformation) - return breps + return brep diff --git a/src/compas_ghpython/artists/curveartist.py b/src/compas_ghpython/scene/curveobject.py similarity index 73% rename from src/compas_ghpython/artists/curveartist.py rename to src/compas_ghpython/scene/curveobject.py index 96530948bf4..00047597a7d 100644 --- a/src/compas_ghpython/artists/curveartist.py +++ b/src/compas_ghpython/scene/curveobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class CurveArtist(GHArtist, GeometryArtist): - """Artist for drawing curves. +class CurveObject(GHSceneObject, GeometryObject): + """Scene object for drawing curves. Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` A COMPAS curve. Other Parameters @@ -24,7 +24,7 @@ class CurveArtist(GHArtist, GeometryArtist): """ def __init__(self, curve, **kwargs): - super(CurveArtist, self).__init__(geometry=curve, **kwargs) + super(CurveObject, self).__init__(geometry=curve, **kwargs) def draw(self): """Draw the curve. diff --git a/src/compas_ghpython/artists/cylinderartist.py b/src/compas_ghpython/scene/cylinderobject.py similarity index 69% rename from src/compas_ghpython/artists/cylinderartist.py rename to src/compas_ghpython/scene/cylinderobject.py index bbec9df0e8e..a85432b2967 100644 --- a/src/compas_ghpython/artists/cylinderartist.py +++ b/src/compas_ghpython/scene/cylinderobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class CylinderArtist(GHArtist, GeometryArtist): - """Artist for drawing cylinder shapes. +class CylinderObject(GHSceneObject, GeometryObject): + """Scene object for drawing cylinder shapes. Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + cylinder : :class:`compas.geometry.Cylinder` A COMPAS cylinder. **kwargs : dict, optional Additional keyword arguments. @@ -21,14 +21,14 @@ class CylinderArtist(GHArtist, GeometryArtist): """ def __init__(self, cylinder, **kwargs): - super(CylinderArtist, self).__init__(geometry=cylinder, **kwargs) + super(CylinderObject, self).__init__(geometry=cylinder, **kwargs) def draw(self, color=None, u=16): - """Draw the cylinder associated with the artist. + """Draw the cylinder associated with the scene object. Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the box. u : int, optional Number of faces in the "u" direction. diff --git a/src/compas_ghpython/artists/ellipseartist.py b/src/compas_ghpython/scene/ellipseobject.py similarity index 58% rename from src/compas_ghpython/artists/ellipseartist.py rename to src/compas_ghpython/scene/ellipseobject.py index 8b4e476a055..cfac19b18e1 100644 --- a/src/compas_ghpython/artists/ellipseartist.py +++ b/src/compas_ghpython/scene/ellipseobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class EllipseArtist(GHArtist, GeometryArtist): - """Artist for drawing ellipses. +class EllipseObject(GHSceneObject, GeometryObject): + """Scene object for drawing ellipses. Parameters ---------- - ellipse : :class:`~compas.geometry.Ellipse` + ellipse : :class:`compas.geometry.Ellipse` A COMPAS ellipse. **kwargs : dict, optional Additional keyword arguments. @@ -21,7 +21,7 @@ class EllipseArtist(GHArtist, GeometryArtist): """ def __init__(self, ellipse, **kwargs): - super(EllipseArtist, self).__init__(geometry=ellipse, **kwargs) + super(EllipseObject, self).__init__(geometry=ellipse, **kwargs) def draw(self): """Draw the ellipse. @@ -32,9 +32,9 @@ def draw(self): """ ellipse = conversions.ellipse_to_rhino(self.geometry) + ellipse = ellipse.ToNurbsCurve() if self.transformation: - transformation = conversions.transformation_to_rhino(self.transformation) - ellipse.Transform(transformation) + ellipse.Transform(conversions.transformation_to_rhino(self.transformation)) return ellipse diff --git a/src/compas_ghpython/artists/frameartist.py b/src/compas_ghpython/scene/frameobject.py similarity index 76% rename from src/compas_ghpython/artists/frameartist.py rename to src/compas_ghpython/scene/frameobject.py index 0dd27c5cc88..b36dc0e6914 100644 --- a/src/compas_ghpython/artists/frameartist.py +++ b/src/compas_ghpython/scene/frameobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class FrameArtist(GHArtist, GeometryArtist): - """Artist for drawing frames. +class FrameObject(GHSceneObject, GeometryObject): + """Scene object for drawing frames. Parameters ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` A COMPAS frame. scale : float, optional The scale of the vectors representing the axes of the frame. @@ -24,19 +24,19 @@ class FrameArtist(GHArtist, GeometryArtist): ---------- scale : float Scale factor that controls the length of the axes. - color_origin : :class:`~compas.colors.Color` + color_origin : :class:`compas.colors.Color` Default is ``Color.black()``. - color_xaxis : :class:`~compas.colors.Color` + color_xaxis : :class:`compas.colors.Color` Default is ``Color.red()``. - color_yaxis : :class:`~compas.colors.Color` + color_yaxis : :class:`compas.colors.Color` Default is ``Color.green()``. - color_zaxis : :class:`~compas.colors.Color` + color_zaxis : :class:`compas.colors.Color` Default is ``Color.blue()``. """ def __init__(self, frame, scale=1.0, **kwargs): - super(FrameArtist, self).__init__(geometry=frame, **kwargs) + super(FrameObject, self).__init__(geometry=frame, **kwargs) self.scale = scale def draw(self): diff --git a/src/compas_ghpython/artists/lineartist.py b/src/compas_ghpython/scene/lineobject.py similarity index 70% rename from src/compas_ghpython/artists/lineartist.py rename to src/compas_ghpython/scene/lineobject.py index 1836b90870c..89ef533974f 100644 --- a/src/compas_ghpython/artists/lineartist.py +++ b/src/compas_ghpython/scene/lineobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class LineArtist(GHArtist, GeometryArtist): - """Artist for drawing lines. +class LineObject(GHSceneObject, GeometryObject): + """Scene object for drawing lines. Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` A COMPAS line. **kwargs : dict, optional Additional keyword arguments. @@ -21,7 +21,7 @@ class LineArtist(GHArtist, GeometryArtist): """ def __init__(self, line, **kwargs): - super(LineArtist, self).__init__(geometry=line, **kwargs) + super(LineObject, self).__init__(geometry=line, **kwargs) def draw(self): """Draw the line. diff --git a/src/compas_ghpython/artists/meshartist.py b/src/compas_ghpython/scene/meshobject.py similarity index 86% rename from src/compas_ghpython/artists/meshartist.py rename to src/compas_ghpython/scene/meshobject.py index e4d3b6512ba..a044f327f2e 100644 --- a/src/compas_ghpython/artists/meshartist.py +++ b/src/compas_ghpython/scene/meshobject.py @@ -2,19 +2,19 @@ from __future__ import division from __future__ import print_function -from compas.artists import MeshArtist as BaseArtist +from compas.scene import MeshObject as BaseMeshObject from compas.colors import Color from compas_rhino import conversions -from compas_rhino.artists._helpers import ngon -from .artist import GHArtist +from compas_rhino.scene._helpers import ngon +from .sceneobject import GHSceneObject -class MeshArtist(GHArtist, BaseArtist): - """Artist for drawing mesh data structures. +class MeshObject(GHSceneObject, BaseMeshObject): + """Scene object for drawing mesh data structures. Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A COMPAS mesh. **kwargs : dict, optional Additional keyword arguments. @@ -22,14 +22,14 @@ class MeshArtist(GHArtist, BaseArtist): """ def __init__(self, mesh, **kwargs): - super(MeshArtist, self).__init__(mesh=mesh, **kwargs) + super(MeshObject, self).__init__(mesh=mesh, **kwargs) def draw(self, color=None, vertexcolors=None, facecolors=None, disjoint=False): """Draw the mesh. Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The color of the mesh. Returns @@ -37,7 +37,7 @@ def draw(self, color=None, vertexcolors=None, facecolors=None, disjoint=False): :rhino:`Rhino.Geometry.Mesh` """ - # the rhino artist can set an overal color and component colors simultaneously + # the rhino scene object can set an overal color and component colors simultaneously # because it can set an overall color on the mesh object attributes # this is not possible in GH (since there is no such object) # either we set an overall color or we set component colors @@ -114,7 +114,7 @@ def draw_faces(self, faces=None, color=None): faces : list[int], optional A selection of faces to draw. The default is None, in which case all faces are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color specification for the faces. Returns diff --git a/src/compas_ghpython/artists/networkartist.py b/src/compas_ghpython/scene/networkobject.py similarity index 85% rename from src/compas_ghpython/artists/networkartist.py rename to src/compas_ghpython/scene/networkobject.py index cffb211564d..599eb841715 100644 --- a/src/compas_ghpython/artists/networkartist.py +++ b/src/compas_ghpython/scene/networkobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import NetworkArtist as BaseArtist -from .artist import GHArtist +from compas.scene import NetworkObject as BaseNetworkObject +from .sceneobject import GHSceneObject -class NetworkArtist(GHArtist, BaseArtist): - """Artist for drawing network data structures. +class NetworkObject(GHSceneObject, BaseNetworkObject): + """Scene object for drawing network data structures. Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A COMPAS network. **kwargs : dict, optional Additional keyword arguments. @@ -21,7 +21,7 @@ class NetworkArtist(GHArtist, BaseArtist): """ def __init__(self, network, **kwargs): - super(NetworkArtist, self).__init__(network=network, **kwargs) + super(NetworkObject, self).__init__(network=network, **kwargs) def draw(self): """Draw the entire network with default color settings. diff --git a/src/compas_ghpython/artists/pointartist.py b/src/compas_ghpython/scene/pointobject.py similarity index 70% rename from src/compas_ghpython/artists/pointartist.py rename to src/compas_ghpython/scene/pointobject.py index 98353c5c929..68e4bd0169e 100644 --- a/src/compas_ghpython/artists/pointartist.py +++ b/src/compas_ghpython/scene/pointobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class PointArtist(GHArtist, GeometryArtist): - """Artist for drawing points. +class PointObject(GHSceneObject, GeometryObject): + """Scene object for drawing points. Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` A COMPAS point. **kwargs : dict, optional Additional keyword arguments. @@ -21,7 +21,7 @@ class PointArtist(GHArtist, GeometryArtist): """ def __init__(self, point, **kwargs): - super(PointArtist, self).__init__(geometry=point, **kwargs) + super(PointObject, self).__init__(geometry=point, **kwargs) def draw(self): """Draw the point. diff --git a/src/compas_ghpython/artists/polygonartist.py b/src/compas_ghpython/scene/polygonobject.py similarity index 76% rename from src/compas_ghpython/artists/polygonartist.py rename to src/compas_ghpython/scene/polygonobject.py index bf194c53e2d..bb976e55d0c 100644 --- a/src/compas_ghpython/artists/polygonartist.py +++ b/src/compas_ghpython/scene/polygonobject.py @@ -6,16 +6,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class PolygonArtist(GHArtist, GeometryArtist): - """Artist for drawing polygons. +class PolygonObject(GHSceneObject, GeometryObject): + """Scene object for drawing polygons. Parameters ---------- - polygon : :class:`~compas.geometry.Polygon` + polygon : :class:`compas.geometry.Polygon` A COMPAS polygon. **kwargs : dict, optional Additional keyword arguments. @@ -23,14 +23,14 @@ class PolygonArtist(GHArtist, GeometryArtist): """ def __init__(self, polygon, **kwargs): - super(PolygonArtist, self).__init__(geometry=polygon, **kwargs) + super(PolygonObject, self).__init__(geometry=polygon, **kwargs) def draw(self, color=None, show_vertices=False, show_edges=False): """Draw the polygon. Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the polygon. Returns diff --git a/src/compas_ghpython/artists/polyhedronartist.py b/src/compas_ghpython/scene/polyhedronobject.py similarity index 70% rename from src/compas_ghpython/artists/polyhedronartist.py rename to src/compas_ghpython/scene/polyhedronobject.py index b140665fa5b..c2d3d28a44f 100644 --- a/src/compas_ghpython/artists/polyhedronartist.py +++ b/src/compas_ghpython/scene/polyhedronobject.py @@ -6,16 +6,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class PolyhedronArtist(GHArtist, GeometryArtist): - """Artist for drawing polyhedron shapes. +class PolyhedronObject(GHSceneObject, GeometryObject): + """Scene object for drawing polyhedron shapes. Parameters ---------- - polyhedron : :class:`~compas.geometry.Polyhedron` + polyhedron : :class:`compas.geometry.Polyhedron` A COMPAS polyhedron. **kwargs : dict, optional Additional keyword arguments. @@ -23,14 +23,14 @@ class PolyhedronArtist(GHArtist, GeometryArtist): """ def __init__(self, polyhedron, **kwargs): - super(PolyhedronArtist, self).__init__(geometry=polyhedron, **kwargs) + super(PolyhedronObject, self).__init__(geometry=polyhedron, **kwargs) def draw(self, color=None): - """Draw the polyhedron associated with the artist. + """Draw the polyhedron associated with the scene object. Parameters ---------- - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The RGB color of the line. Returns diff --git a/src/compas_ghpython/artists/polylineartist.py b/src/compas_ghpython/scene/polylineobject.py similarity index 70% rename from src/compas_ghpython/artists/polylineartist.py rename to src/compas_ghpython/scene/polylineobject.py index 01854df0651..2d871eed75b 100644 --- a/src/compas_ghpython/artists/polylineartist.py +++ b/src/compas_ghpython/scene/polylineobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class PolylineArtist(GHArtist, GeometryArtist): - """Artist for drawing polylines. +class PolylineObject(GHSceneObject, GeometryObject): + """Scene object for drawing polylines. Parameters ---------- - polyline : :class:`~compas.geometry.Polyline` + polyline : :class:`compas.geometry.Polyline` A COMPAS polyline. **kwargs : dict, optional Additional keyword arguments. @@ -21,7 +21,7 @@ class PolylineArtist(GHArtist, GeometryArtist): """ def __init__(self, polyline, **kwargs): - super(PolylineArtist, self).__init__(geometry=polyline, **kwargs) + super(PolylineObject, self).__init__(geometry=polyline, **kwargs) def draw(self): """Draw the polyline. diff --git a/src/compas_ghpython/artists/artist.py b/src/compas_ghpython/scene/sceneobject.py similarity index 54% rename from src/compas_ghpython/artists/artist.py rename to src/compas_ghpython/scene/sceneobject.py index 306e5f1101d..29e5777fb97 100644 --- a/src/compas_ghpython/artists/artist.py +++ b/src/compas_ghpython/scene/sceneobject.py @@ -2,14 +2,14 @@ from __future__ import absolute_import from __future__ import division -from compas.artists import Artist +from compas.scene import SceneObject -class GHArtist(Artist): - """Base class for all GH artists.""" +class GHSceneObject(SceneObject): + """Base class for all GH scene objects.""" def __init__(self, **kwargs): - super(GHArtist, self).__init__(**kwargs) + super(GHSceneObject, self).__init__(**kwargs) def clear(self): raise NotImplementedError diff --git a/src/compas_ghpython/artists/sphereartist.py b/src/compas_ghpython/scene/sphereobject.py similarity index 65% rename from src/compas_ghpython/artists/sphereartist.py rename to src/compas_ghpython/scene/sphereobject.py index 17ba29ea2db..22db157e2ee 100644 --- a/src/compas_ghpython/artists/sphereartist.py +++ b/src/compas_ghpython/scene/sphereobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class SphereArtist(GHArtist, GeometryArtist): - """Artist for drawing sphere shapes. +class SphereObject(GHSceneObject, GeometryObject): + """Scene object for drawing sphere shapes. Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + sphere : :class:`compas.geometry.Sphere` A COMPAS sphere. **kwargs : dict, optional Additional keyword arguments. @@ -21,10 +21,10 @@ class SphereArtist(GHArtist, GeometryArtist): """ def __init__(self, sphere, **kwargs): - super(SphereArtist, self).__init__(geometry=sphere, **kwargs) + super(SphereObject, self).__init__(geometry=sphere, **kwargs) def draw(self): - """Draw the sphere associated with the artist. + """Draw the sphere associated with the scene object. Returns ------- diff --git a/src/compas_ghpython/artists/surfaceartist.py b/src/compas_ghpython/scene/surfaceobject.py similarity index 71% rename from src/compas_ghpython/artists/surfaceartist.py rename to src/compas_ghpython/scene/surfaceobject.py index d786a78c53a..9d7dec02f16 100644 --- a/src/compas_ghpython/artists/surfaceartist.py +++ b/src/compas_ghpython/scene/surfaceobject.py @@ -4,16 +4,16 @@ from compas_rhino import conversions -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class SurfaceArtist(GHArtist, GeometryArtist): - """Artist for drawing surfaces. +class SurfaceObject(GHSceneObject, GeometryObject): + """Scene object for drawing surfaces. Parameters ---------- - surface : :class:`~compas.geometry.Surface` + surface : :class:`compas.geometry.Surface` A COMPAS surface. Other Parameters @@ -24,7 +24,7 @@ class SurfaceArtist(GHArtist, GeometryArtist): """ def __init__(self, surface, **kwargs): - super(SurfaceArtist, self).__init__(geometry=surface, **kwargs) + super(SurfaceObject, self).__init__(geometry=surface, **kwargs) def draw(self): """Draw the surface. diff --git a/src/compas_ghpython/scene/torusobject.py b/src/compas_ghpython/scene/torusobject.py new file mode 100644 index 00000000000..8eabf3b1ba6 --- /dev/null +++ b/src/compas_ghpython/scene/torusobject.py @@ -0,0 +1,38 @@ +from __future__ import print_function +from __future__ import absolute_import +from __future__ import division + +from compas_rhino import conversions + +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject + + +class TorusObject(GHSceneObject, GeometryObject): + """Scene object for drawing torus shapes. + + Parameters + ---------- + torus : :class:`compas.geometry.Torus` + A COMPAS torus. + **kwargs : dict, optional + Additional keyword arguments. + + """ + + def __init__(self, torus, **kwargs): + super(TorusObject, self).__init__(geometry=torus, **kwargs) + + def draw(self): + """Draw the torus associated with the scene object. + + Returns + ------- + :rhino:`Rhino.Geometry.Torus` + + """ + brep = conversions.torus_to_rhino_brep(self.geometry) + if self.transformation: + brep.Transform(conversions.transformation_to_rhino(self.transformation)) + + return brep diff --git a/src/compas_ghpython/artists/vectorartist.py b/src/compas_ghpython/scene/vectorobject.py similarity index 73% rename from src/compas_ghpython/artists/vectorartist.py rename to src/compas_ghpython/scene/vectorobject.py index 09fc409f811..fcd1a3eeadc 100644 --- a/src/compas_ghpython/artists/vectorartist.py +++ b/src/compas_ghpython/scene/vectorobject.py @@ -5,16 +5,16 @@ from compas_rhino import conversions from compas.geometry import Point -from compas.artists import GeometryArtist -from .artist import GHArtist +from compas.scene import GeometryObject +from .sceneobject import GHSceneObject -class VectorArtist(GHArtist, GeometryArtist): - """Artist for drawing vectors. +class VectorObject(GHSceneObject, GeometryObject): + """Scene object for drawing vectors. Parameters ---------- - vector : :class:`~compas.geometry.Vector` + vector : :class:`compas.geometry.Vector` A COMPAS vector. **kwargs : dict, optional Additional keyword arguments. @@ -22,14 +22,14 @@ class VectorArtist(GHArtist, GeometryArtist): """ def __init__(self, vector, **kwargs): - super(VectorArtist, self).__init__(geometry=vector, **kwargs) + super(VectorObject, self).__init__(geometry=vector, **kwargs) def draw(self, point=None, show_point=False): """Draw the vector. Parameters ---------- - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional Point of application of the vector. Default is ``Point(0, 0, 0)``. diff --git a/src/compas_ghpython/artists/volmeshartist.py b/src/compas_ghpython/scene/volmeshobject.py similarity index 83% rename from src/compas_ghpython/artists/volmeshartist.py rename to src/compas_ghpython/scene/volmeshobject.py index 6ef243e9777..c915ddae202 100644 --- a/src/compas_ghpython/artists/volmeshartist.py +++ b/src/compas_ghpython/scene/volmeshobject.py @@ -3,18 +3,18 @@ from __future__ import division from compas_rhino import conversions -from compas_rhino.artists._helpers import ngon +from compas_rhino.scene._helpers import ngon -from compas.artists import VolMeshArtist as BaseArtist -from .artist import GHArtist +from compas.scene import VolMeshObject as BaseVolMeshObject +from .sceneobject import GHSceneObject -class VolMeshArtist(GHArtist, BaseArtist): - """Artist for drawing volmesh data structures. +class VolMeshObject(GHSceneObject, BaseVolMeshObject): + """Scene object for drawing volmesh data structures. Parameters ---------- - volmesh : :class:`~compas.datastructures.VolMesh` + volmesh : :class:`compas.datastructures.VolMesh` A COMPAS volmesh. **kwargs : dict, optional Additional keyword arguments. @@ -22,7 +22,7 @@ class VolMeshArtist(GHArtist, BaseArtist): """ def __init__(self, volmesh, **kwargs): - super(VolMeshArtist, self).__init__(volmesh=volmesh, **kwargs) + super(VolMeshObject, self).__init__(volmesh=volmesh, **kwargs) def draw(self, cells=None, color=None): """Draw a selection of cells. @@ -32,9 +32,9 @@ def draw(self, cells=None, color=None): cells : list[int], optional A list of cells to draw. The default is None, in which case all cells are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the cells. - The default color is :attr:`VolMeshArtist.default_cellcolor`. + The default color is :attr:`VolMeshObject.default_cellcolor`. Returns ------- @@ -95,9 +95,9 @@ def draw_faces(self, faces=None, color=None): faces : list[list[int]], optional A list of faces to draw. The default is None, in which case all faces are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color specification for the faces. - The default color is :attr:`VolMeshArtist.default_facecolor`. + The default color is :attr:`VolMeshObject.default_facecolor`. Returns ------- @@ -127,7 +127,7 @@ def draw_cells(self, cells=None, color=None): cells : list[int], optional A list of cells to draw. The default is None, in which case all cells are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the cells. Returns diff --git a/src/compas_ghpython/utilities/drawing.py b/src/compas_ghpython/utilities/drawing.py index 0765c2a28fd..18523940b46 100644 --- a/src/compas_ghpython/utilities/drawing.py +++ b/src/compas_ghpython/utilities/drawing.py @@ -408,7 +408,7 @@ def draw_network(network): Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` Returns ------- @@ -464,7 +464,7 @@ def draw_brep(brep): Parameters ---------- - brep : :class:`~compas.geometry.RhinoBrep` + brep : :class:`compas.geometry.RhinoBrep` The Brep to draw. Returns diff --git a/src/compas_rhino/__init__.py b/src/compas_rhino/__init__.py index 17715c490c0..1ed0fefd802 100644 --- a/src/compas_rhino/__init__.py +++ b/src/compas_rhino/__init__.py @@ -1,21 +1,3 @@ -""" -************ -compas_rhino -************ - -.. currentmodule:: compas_rhino - -.. toctree:: - :maxdepth: 1 - - compas_rhino.artists - compas_rhino.conduits - compas_rhino.conversions - compas_rhino.forms - compas_rhino.geometry - compas_rhino.utilities - -""" from __future__ import absolute_import import io @@ -59,10 +41,11 @@ __all_plugins__ = [ "compas_rhino.geometry.booleans", - "compas_rhino.geometry.trimesh", + "compas_rhino.geometry.trimesh_curvature", + "compas_rhino.geometry.trimesh_slicing", "compas_rhino.install", "compas_rhino.uninstall", - "compas_rhino.artists", + "compas_rhino.scene", "compas_rhino.geometry.curves", "compas_rhino.geometry.surfaces", "compas_rhino.geometry.brep", diff --git a/src/compas_rhino/artists/__init__.py b/src/compas_rhino/artists/__init__.py deleted file mode 100644 index 5bbd8df3ca8..00000000000 --- a/src/compas_rhino/artists/__init__.py +++ /dev/null @@ -1,123 +0,0 @@ -from __future__ import absolute_import - -from compas.plugins import plugin -from compas.artists import Artist - -from compas.geometry import Circle -from compas.geometry import Ellipse -from compas.geometry import Frame -from compas.geometry import Line -from compas.geometry import Plane -from compas.geometry import Point -from compas.geometry import Polygon -from compas.geometry import Polyline -from compas.geometry import Vector - -from compas.geometry import Box -from compas.geometry import Capsule -from compas.geometry import Cone -from compas.geometry import Cylinder -from compas.geometry import Polyhedron -from compas.geometry import Sphere -from compas.geometry import Torus - -from compas.geometry import Curve -from compas.geometry import Surface -from compas.geometry import Brep - -from compas.datastructures import Mesh -from compas.datastructures import Network -from compas.datastructures import VolMesh - -import compas_rhino - -from .artist import RhinoArtist -from .circleartist import CircleArtist -from .ellipseartist import EllipseArtist -from .frameartist import FrameArtist -from .lineartist import LineArtist -from .planeartist import PlaneArtist -from .pointartist import PointArtist -from .polygonartist import PolygonArtist -from .polylineartist import PolylineArtist -from .vectorartist import VectorArtist - -from .boxartist import BoxArtist -from .capsuleartist import CapsuleArtist -from .coneartist import ConeArtist -from .cylinderartist import CylinderArtist -from .polyhedronartist import PolyhedronArtist -from .sphereartist import SphereArtist -from .torusartist import TorusArtist - -from .meshartist import MeshArtist -from .networkartist import NetworkArtist -from .volmeshartist import VolMeshArtist - -from .curveartist import CurveArtist -from .surfaceartist import SurfaceArtist -from .brepartist import BrepArtist - - -@plugin(category="drawing-utils", pluggable_name="clear", requires=["Rhino"]) -def clear_rhino(): - compas_rhino.clear() - - -@plugin(category="drawing-utils", pluggable_name="redraw", requires=["Rhino"]) -def redraw_rhino(): - compas_rhino.redraw() - - -@plugin(category="factories", requires=["Rhino"]) -def register_artists(): - Artist.register(Circle, CircleArtist, context="Rhino") - Artist.register(Ellipse, EllipseArtist, context="Rhino") - Artist.register(Frame, FrameArtist, context="Rhino") - Artist.register(Line, LineArtist, context="Rhino") - Artist.register(Plane, PlaneArtist, context="Rhino") - Artist.register(Point, PointArtist, context="Rhino") - Artist.register(Polygon, PolygonArtist, context="Rhino") - Artist.register(Polyline, PolylineArtist, context="Rhino") - Artist.register(Vector, VectorArtist, context="Rhino") - Artist.register(Box, BoxArtist, context="Rhino") - Artist.register(Capsule, CapsuleArtist, context="Rhino") - Artist.register(Cone, ConeArtist, context="Rhino") - Artist.register(Cylinder, CylinderArtist, context="Rhino") - Artist.register(Polyhedron, PolyhedronArtist, context="Rhino") - Artist.register(Sphere, SphereArtist, context="Rhino") - Artist.register(Torus, TorusArtist, context="Rhino") - Artist.register(Mesh, MeshArtist, context="Rhino") - Artist.register(Network, NetworkArtist, context="Rhino") - Artist.register(VolMesh, VolMeshArtist, context="Rhino") - Artist.register(Curve, CurveArtist, context="Rhino") - Artist.register(Surface, SurfaceArtist, context="Rhino") - Artist.register(Brep, BrepArtist, context="Rhino") - print("Rhino Artists registered.") - - -__all__ = [ - "RhinoArtist", - "CircleArtist", - "EllipseArtist", - "FrameArtist", - "LineArtist", - "PlaneArtist", - "PointArtist", - "PolygonArtist", - "PolylineArtist", - "VectorArtist", - "BoxArtist", - "CapsuleArtist", - "ConeArtist", - "CylinderArtist", - "PolyhedronArtist", - "SphereArtist", - "TorusArtist", - "MeshArtist", - "NetworkArtist", - "VolMeshArtist", - "CurveArtist", - "SurfaceArtist", - "BrepArtist", -] diff --git a/src/compas_rhino/conduits/faces.py b/src/compas_rhino/conduits/faces.py index 9620deca65d..da5ee140876 100644 --- a/src/compas_rhino/conduits/faces.py +++ b/src/compas_rhino/conduits/faces.py @@ -16,7 +16,7 @@ class FacesConduit(BaseConduit): Parameters ---------- - vertices : list[[float, float, float] | :class:`~compas.geometry.Point`] + vertices : list[[float, float, float] | :class:`compas.geometry.Point`] The coordinates of the vertices of the faces. faces : list[list[int]] The faces defined as lists of indices in `vertices`. diff --git a/src/compas_rhino/conduits/labels.py b/src/compas_rhino/conduits/labels.py index e6733db7984..c9fac7264e8 100644 --- a/src/compas_rhino/conduits/labels.py +++ b/src/compas_rhino/conduits/labels.py @@ -15,7 +15,7 @@ class LabelsConduit(BaseConduit): Parameters ---------- - labels : list[tuple[[float, float, float] | :class:`~compas.geometry.Point`, str]] + labels : list[tuple[[float, float, float] | :class:`compas.geometry.Point`, str]] A list of label tuples. Each tuple contains a position and text for the label. color : list[tuple[tuple[int, int, int], tuple[int, int, int]]], optional @@ -28,7 +28,7 @@ class LabelsConduit(BaseConduit): ---------- color : list[tuple[System.Drawing.Color, System.Drawing.Color]] A color specification per label. - labels : list[tuple[[float, float, float] | :class:`~compas.geometry.Point`, str]] + labels : list[tuple[[float, float, float] | :class:`compas.geometry.Point`, str]] A list of label tuples. Each tuple contains a position and text for the label. diff --git a/src/compas_rhino/conduits/lines.py b/src/compas_rhino/conduits/lines.py index 4f7140a84fb..16f9a0fa4ab 100644 --- a/src/compas_rhino/conduits/lines.py +++ b/src/compas_rhino/conduits/lines.py @@ -16,7 +16,7 @@ class LinesConduit(BaseConduit): Parameters ---------- - lines : list[[point, point] | :class:`~compas.geometry.Line`] + lines : list[[point, point] | :class:`compas.geometry.Line`] A list of start-end point pairs that define the lines. thickness : list[int], optional The thickness of the individual lines. diff --git a/src/compas_rhino/conduits/points.py b/src/compas_rhino/conduits/points.py index 7aab711c6a5..7d677af9783 100644 --- a/src/compas_rhino/conduits/points.py +++ b/src/compas_rhino/conduits/points.py @@ -18,7 +18,7 @@ class PointsConduit(BaseConduit): Parameters ---------- - points : list[[float, float, float] | :class:`~compas.geometry.Point`] + points : list[[float, float, float] | :class:`compas.geometry.Point`] The coordinates of the points. size : list[int], optional The size of the points. diff --git a/src/compas_rhino/conversions/__init__.py b/src/compas_rhino/conversions/__init__.py index 098456f1afc..92e175d39a2 100644 --- a/src/compas_rhino/conversions/__init__.py +++ b/src/compas_rhino/conversions/__init__.py @@ -1,3 +1,6 @@ +""" +This package provides functions to convert between COMPAS data/objects and Blender data/objects. +""" from __future__ import absolute_import from .exceptions import ConversionError diff --git a/src/compas_rhino/conversions/breps.py b/src/compas_rhino/conversions/breps.py index e2fa73de207..9b42590edae 100644 --- a/src/compas_rhino/conversions/breps.py +++ b/src/compas_rhino/conversions/breps.py @@ -21,7 +21,7 @@ def brep_to_rhino(brep): Parameters ---------- - brep : :class:`~compas.geometry.Brep` + brep : :class:`compas.geometry.Brep` Returns ------- @@ -45,7 +45,7 @@ def brep_to_compas_box(brep): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` """ raise NotImplementedError @@ -60,7 +60,7 @@ def brep_to_compas_cone(brep): Returns ------- - :class:`~compas.geometry.Cone` + :class:`compas.geometry.Cone` """ if brep.Faces.Count > 2: @@ -82,7 +82,7 @@ def brep_to_compas_cylinder(brep, tol=None): Returns ------- - :class:`~compas.geometry.Cylinder` + :class:`compas.geometry.Cylinder` """ tol = tol or sc.doc.ModelAbsoluteTolerance @@ -109,7 +109,7 @@ def brep_to_compas_sphere(brep): Returns ------- - :class:`~compas.geometry.Sphere` + :class:`compas.geometry.Sphere` """ if brep.Faces.Count != 1: diff --git a/src/compas_rhino/conversions/curves.py b/src/compas_rhino/conversions/curves.py index 393d9b0608e..2c2e36a486d 100644 --- a/src/compas_rhino/conversions/curves.py +++ b/src/compas_rhino/conversions/curves.py @@ -68,7 +68,7 @@ def line_to_rhino(line): Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` Returns ------- @@ -83,7 +83,7 @@ def line_to_rhino_curve(line): Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` Returns ------- @@ -98,7 +98,7 @@ def polyline_to_rhino(polyline, tol=None): Parameters ---------- - polyline : :class:`~compas.geometry.Polyline` + polyline : :class:`compas.geometry.Polyline` Returns ------- @@ -116,7 +116,7 @@ def polyline_to_rhino_curve(polyline): Parameters ---------- - polyline : :class:`~compas.geometry.Polyline` + polyline : :class:`compas.geometry.Polyline` Returns ------- @@ -131,7 +131,7 @@ def circle_to_rhino(circle): Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` Returns ------- @@ -146,7 +146,7 @@ def circle_to_rhino_curve(circle): Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` Returns ------- @@ -161,7 +161,7 @@ def ellipse_to_rhino(ellipse): Parameters ---------- - ellipse : :class:`~compas.geometry.Ellipse` + ellipse : :class:`compas.geometry.Ellipse` Returns ------- @@ -176,7 +176,7 @@ def ellipse_to_rhino_curve(ellipse): Parameters ---------- - ellipse : :class:`~compas.geometry.Ellipse` + ellipse : :class:`compas.geometry.Ellipse` Returns ------- @@ -191,7 +191,7 @@ def arc_to_rhino(arc): Parameters ---------- - arc : :class:`~compas.geometry.Arc` + arc : :class:`compas.geometry.Arc` The COMPAS Arc to convert. Returns @@ -210,7 +210,7 @@ def curve_to_rhino(curve): Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` Returns ------- @@ -234,7 +234,7 @@ def line_to_compas(line): Returns ------- - :class:`~compas.geometry.Line` + :class:`compas.geometry.Line` """ return Line(point_to_compas(line.From), point_to_compas(line.To)) @@ -249,7 +249,7 @@ def circle_to_compas(circle): Returns ------- - :class:`~compas.geometry.Circle` + :class:`compas.geometry.Circle` """ frame = plane_to_compas(circle.Plane) @@ -265,7 +265,7 @@ def ellipse_to_compas(ellipse): Returns ------- - :class:`~compas.geometry.Ellipse` + :class:`compas.geometry.Ellipse` """ frame = plane_to_compas(ellipse.Plane) @@ -281,7 +281,7 @@ def polyline_to_compas(polyline): Returns ------- - :class:`~compas.geometry.Polyline` + :class:`compas.geometry.Polyline` """ return Polyline([point_to_compas(point) for point in polyline]) @@ -297,7 +297,7 @@ def arc_to_compas(arc): Returns ------- - :class:`~compas.geometry.Arc` + :class:`compas.geometry.Arc` """ frame = plane_to_compas_frame(arc.Plane) @@ -316,7 +316,7 @@ def curve_to_compas_line(curve): Returns ------- - :class:`~compas.geometry.Line` + :class:`compas.geometry.Line` """ if isinstance(curve, RhinoObject): @@ -333,7 +333,7 @@ def curve_to_compas_circle(curve): Returns ------- - :class:`~compas.geometry.Circle` + :class:`compas.geometry.Circle` Raises ------ @@ -358,7 +358,7 @@ def curve_to_compas_ellipse(curve): Returns ------- - :class:`~compas.geometry.Ellipse` + :class:`compas.geometry.Ellipse` Raises ------ @@ -383,7 +383,7 @@ def curve_to_compas_polyline(curve): Returns ------- - :class:`~compas.geometry.Polyline` + :class:`compas.geometry.Polyline` Raises ------ diff --git a/src/compas_rhino/conversions/extrusions.py b/src/compas_rhino/conversions/extrusions.py index aac62383e0a..cea01840d9a 100644 --- a/src/compas_rhino/conversions/extrusions.py +++ b/src/compas_rhino/conversions/extrusions.py @@ -29,7 +29,7 @@ def extrusion_to_compas_box(extrusion): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` """ plane = extrusion.GetPathPlane(0) @@ -50,7 +50,7 @@ def extrusion_to_compas_cylinder(extrusion, tol=None): Returns ------- - :class:`~compas.geometry.Cylinder` + :class:`compas.geometry.Cylinder` """ tol = tol or sc.doc.ModelAbsoluteTolerance @@ -72,7 +72,7 @@ def extrusion_to_compas_torus(extrusion, tol=None): Returns ------- - :class:`~compas.geometry.Torus` + :class:`compas.geometry.Torus` """ tol = tol or sc.doc.ModelAbsoluteTolerance diff --git a/src/compas_rhino/conversions/geometry.py b/src/compas_rhino/conversions/geometry.py index 9184c3e2e62..6ff6e3eefe7 100644 --- a/src/compas_rhino/conversions/geometry.py +++ b/src/compas_rhino/conversions/geometry.py @@ -23,7 +23,7 @@ def point_to_rhino(point): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` Returns ------- @@ -38,7 +38,7 @@ def vector_to_rhino(vector): Parameters ---------- - vector : :class:`~compas.geometry.Vector` + vector : :class:`compas.geometry.Vector` Returns ------- @@ -53,7 +53,7 @@ def plane_to_rhino(plane): Parameters ---------- - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` Returns ------- @@ -68,7 +68,7 @@ def frame_to_rhino_plane(frame): Parameters ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` Returns ------- @@ -83,7 +83,7 @@ def frame_to_rhino(frame): Parameters ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` Returns ------- @@ -98,7 +98,7 @@ def polygon_to_rhino(polygon): Parameters ---------- - polygon : :class:`~compas.geometry.Polygon` + polygon : :class:`compas.geometry.Polygon` Returns ------- @@ -122,7 +122,7 @@ def point_to_compas(point): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` """ return Point(point.X, point.Y, point.Z) @@ -137,7 +137,7 @@ def vector_to_compas(vector): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` """ return Vector(vector.X, vector.Y, vector.Z) @@ -152,7 +152,7 @@ def plane_to_compas(plane): Returns ------- - :class:`~compas.geometry.Plane` + :class:`compas.geometry.Plane` """ return Plane(point_to_compas(plane.Origin), vector_to_compas(plane.Normal)) @@ -167,7 +167,7 @@ def plane_to_compas_frame(plane): Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` """ return Frame( @@ -186,7 +186,7 @@ def polygon_to_compas(polygon): Returns ------- - :class:`~compas.geometry.Polygon` + :class:`compas.geometry.Polygon` """ return Polygon([point_to_compas(point) for point in polygon]) diff --git a/src/compas_rhino/conversions/meshes.py b/src/compas_rhino/conversions/meshes.py index da184d6401c..4df07af69cb 100644 --- a/src/compas_rhino/conversions/meshes.py +++ b/src/compas_rhino/conversions/meshes.py @@ -132,7 +132,7 @@ def vertices_and_faces_to_rhino( Parameters ---------- - vertices : list[[float, float, float] | :class:`~compas.geometry.Point`] + vertices : list[[float, float, float] | :class:`compas.geometry.Point`] A list of point locations. faces : list[list[int]] A list of faces as lists of indices into `vertices`. @@ -241,7 +241,7 @@ def mesh_to_compas(rhinomesh, cls=None): ---------- rhinomesh : :class:`Rhino.Geometry.Mesh` A Rhino mesh object. - cls: :class:`~compas.datastructures.Mesh`, optional + cls: :class:`compas.datastructures.Mesh`, optional The mesh type. Returns diff --git a/src/compas_rhino/conversions/shapes.py b/src/compas_rhino/conversions/shapes.py index a65a243c809..1401382f196 100644 --- a/src/compas_rhino/conversions/shapes.py +++ b/src/compas_rhino/conversions/shapes.py @@ -44,7 +44,7 @@ def box_to_rhino(box): Parameters ---------- - box : :class:`~compas.geometry.Box` + box : :class:`compas.geometry.Box` Returns ------- @@ -64,14 +64,14 @@ def sphere_to_rhino(sphere): Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + sphere : :class:`compas.geometry.Sphere` Returns ------- :rhino:`Rhino.Geometry.Sphere` """ - return RhinoSphere(point_to_rhino(sphere.point), sphere.radius) + return RhinoSphere(point_to_rhino(sphere.frame.point), sphere.radius) def cone_to_rhino(cone): @@ -79,7 +79,7 @@ def cone_to_rhino(cone): Parameters ---------- - cone : :class:`~compas.geometry.Cone` + cone : :class:`compas.geometry.Cone` Returns ------- @@ -96,7 +96,7 @@ def cone_to_rhino_brep(cone): Parameters ---------- - cone : :class:`~compas.geometry.Cone` + cone : :class:`compas.geometry.Cone` A COMPAS cone. Returns @@ -112,7 +112,7 @@ def cylinder_to_rhino(cylinder): Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + cylinder : :class:`compas.geometry.Cylinder` Returns ------- @@ -129,7 +129,7 @@ def cylinder_to_rhino_brep(cylinder): Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + cylinder : :class:`compas.geometry.Cylinder` A COMPAS cylinder. Returns @@ -145,7 +145,7 @@ def capsule_to_rhino_brep(capsule): Parameters ---------- - capsule : :class:`~compas.geometry.Capsule` + capsule : :class:`compas.geometry.Capsule` A COMPAS capsule. Returns @@ -168,7 +168,7 @@ def torus_to_rhino(torus): Parameters ---------- - torus : :class:`~compas.geometry.Torus` + torus : :class:`compas.geometry.Torus` Returns ------- @@ -183,7 +183,7 @@ def torus_to_rhino_brep(torus): Parameters ---------- - torus : :class:`~compas.geometry.Torus` + torus : :class:`compas.geometry.Torus` A COMPAS torus. Returns @@ -209,7 +209,7 @@ def box_to_compas(box): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` """ xsize = box.X.Length @@ -229,7 +229,7 @@ def sphere_to_compas(sphere): Returns ------- - :class:`~compas.geometry.Sphere` + :class:`compas.geometry.Sphere` """ return Sphere(point_to_compas(sphere.Center), sphere.Radius) @@ -244,7 +244,7 @@ def cone_to_compas(cone): Returns ------- - :class:`~compas.geometry.Cone` + :class:`compas.geometry.Cone` """ plane = Plane(cone.BasePoint, vector_to_compas(cone.Plane.Normal).inverted()) @@ -260,7 +260,7 @@ def cylinder_to_compas(cylinder): Returns ------- - :class:`~compas.geometry.Cylinder` + :class:`compas.geometry.Cylinder` """ plane = plane_to_compas(cylinder.BasePlane) @@ -278,7 +278,7 @@ def torus_to_compas(torus): Returns ------- - :class:`~compas.geometry.Torus` + :class:`compas.geometry.Torus` """ frame = plane_to_compas_frame(torus.Plane) diff --git a/src/compas_rhino/conversions/surfaces.py b/src/compas_rhino/conversions/surfaces.py index 592bc326a73..37b9c177760 100644 --- a/src/compas_rhino/conversions/surfaces.py +++ b/src/compas_rhino/conversions/surfaces.py @@ -26,7 +26,7 @@ def surface_to_rhino(surface): Parameters ---------- - surface : :class:`~compas.geometry.Surface` + surface : :class:`compas.geometry.Surface` A COMPAS surface. Returns @@ -152,7 +152,7 @@ def surface_to_compas(surface): Returns ------- - :class:`~compas.geometry.Surface` + :class:`compas.geometry.Surface` """ from compas_rhino.geometry import RhinoNurbsSurface @@ -170,7 +170,7 @@ def surface_to_compas_mesh(surface, cls=None, facefilter=None, cleanup=False): Parameters ---------- - cls : :class:`~compas.datastructures.Mesh`, optional + cls : :class:`compas.datastructures.Mesh`, optional The type of COMPAS mesh. facefilter : callable, optional A filter for selection which Brep faces to include. @@ -184,14 +184,14 @@ def surface_to_compas_mesh(surface, cls=None, facefilter=None, cleanup=False): Returns ------- - :class:`~compas.datastructures.Mesh` + :class:`compas.datastructures.Mesh` The resulting mesh. Examples -------- >>> import compas_rhino >>> from compas_rhino.geometry import RhinoSurface - >>> from compas_rhino.artists import MeshArtist + >>> from compas.scene import Scene >>> def facefilter(face): ... success, w, h = face.GetSurfaceSize() @@ -205,9 +205,9 @@ def surface_to_compas_mesh(surface, cls=None, facefilter=None, cleanup=False): >>> surf = RhinoSurface.from_guid(guid) >>> mesh = surf.to_compas(facefilter=facefilter) - >>> artist = MeshArtist(mesh, layer="Blocks") - >>> artist.clear_layer() - >>> artist.draw() + >>> scene = Scene() + >>> scene.add(mesh, layer="Blocks") + >>> scene.redraw() """ if not surface.HasBrepForm: @@ -289,12 +289,12 @@ def surface_to_compas_quadmesh(surface, nu, nv=None, weld=False, facefilter=None If provided, the filter should return True or False per face. A very simple filter that includes all faces is ``def facefilter(face): return True``. Default parameter value is None in which case all faces are included. - cls: :class:`~compas.geometry.Mesh`, optional + cls: :class:`compas.geometry.Mesh`, optional The type of COMPAS mesh. Returns ------- - :class:`~compas.geometry.Mesh` + :class:`compas.geometry.Mesh` """ nv = nv or nu diff --git a/src/compas_rhino/conversions/transformations.py b/src/compas_rhino/conversions/transformations.py index c9ea60a791c..17bd1e4e112 100644 --- a/src/compas_rhino/conversions/transformations.py +++ b/src/compas_rhino/conversions/transformations.py @@ -10,7 +10,7 @@ def transformation_to_rhino(transformation): Parameters ---------- - transformation : :class:`~compas.geometry.Transformation` + transformation : :class:`compas.geometry.Transformation` COMPAS transformation. Returns diff --git a/src/compas_rhino/geometry/__init__.py b/src/compas_rhino/geometry/__init__.py index c6df0892184..bd47182c18f 100644 --- a/src/compas_rhino/geometry/__init__.py +++ b/src/compas_rhino/geometry/__init__.py @@ -1,3 +1,6 @@ +""" +This package provides plugins for various geometry pluggables using Rhino as the backend. +""" from __future__ import absolute_import from .curves.nurbs import RhinoNurbsCurve @@ -10,7 +13,25 @@ from .brep.edge import RhinoBrepEdge from .brep.trim import RhinoBrepTrim +from .booleans import boolean_difference_mesh_mesh +from .booleans import boolean_union_mesh_mesh +from .booleans import boolean_intersection_mesh_mesh + +from .trimesh_curvature import trimesh_gaussian_curvature +from .trimesh_curvature import trimesh_mean_curvature +from .trimesh_curvature import trimesh_principal_curvature + +from .trimesh_slicing import trimesh_slice + + __all__ = [ + "boolean_difference_mesh_mesh", + "boolean_intersection_mesh_mesh", + "boolean_union_mesh_mesh", + "trimesh_gaussian_curvature", + "trimesh_mean_curvature", + "trimesh_principal_curvature", + "trimesh_slice", "RhinoNurbsCurve", "RhinoNurbsSurface", "RhinoBrep", diff --git a/src/compas_rhino/geometry/booleans/__init__.py b/src/compas_rhino/geometry/booleans.py similarity index 78% rename from src/compas_rhino/geometry/booleans/__init__.py rename to src/compas_rhino/geometry/booleans.py index 969457eb117..42a0240347a 100644 --- a/src/compas_rhino/geometry/booleans/__init__.py +++ b/src/compas_rhino/geometry/booleans.py @@ -13,9 +13,9 @@ def boolean_union_mesh_mesh(A, B, remesh=False): Parameters ---------- - A : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + A : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh A. - B : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + B : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh B. remesh : bool, optional If True, remesh the result. @@ -31,15 +31,18 @@ def boolean_union_mesh_mesh(A, B, remesh=False): return _boolean_operation(A, B, lambda a, b: Rhino.Geometry.Mesh.CreateBooleanUnion([a, b])) +boolean_union_mesh_mesh.__plugin__ = True + + @plugin(category="booleans", requires=["Rhino"]) def boolean_difference_mesh_mesh(A, B, remesh=False): """Compute the boolean difference of two triangle meshes. Parameters ---------- - A : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + A : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh A. - B : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + B : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh B. remesh : bool, optional If True, remesh the result. @@ -55,15 +58,18 @@ def boolean_difference_mesh_mesh(A, B, remesh=False): return _boolean_operation(A, B, lambda a, b: Rhino.Geometry.Mesh.CreateBooleanDifference([a], [b])) +boolean_difference_mesh_mesh.__plugin__ = True + + @plugin(category="booleans", requires=["Rhino"]) def boolean_intersection_mesh_mesh(A, B, remesh=False): """Compute the boolean intersection of two triangle meshes. Parameters ---------- - A : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + A : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh A. - B : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + B : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] The vertices and faces of mesh B. remesh : bool, optional If True, remesh the result. @@ -79,6 +85,9 @@ def boolean_intersection_mesh_mesh(A, B, remesh=False): return _boolean_operation(A, B, lambda a, b: Rhino.Geometry.Mesh.CreateBooleanIntersection([a], [b])) +boolean_intersection_mesh_mesh.__plugin__ = True + + def _boolean_operation(A, B, method): meshes = [] for vertices, faces in [A, B]: diff --git a/src/compas_rhino/geometry/brep/brep.py b/src/compas_rhino/geometry/brep/brep.py index d0b0368c152..3c8e1666f28 100644 --- a/src/compas_rhino/geometry/brep/brep.py +++ b/src/compas_rhino/geometry/brep/brep.py @@ -30,19 +30,19 @@ class RhinoBrep(Brep): ---------- native_brep : :class:`Rhino.Geometry.Brep` The underlying Rhino Brep instance. - vertices : list[:class:`~compas_rhino.geometry.RhinoBrepVertex`], read-only + vertices : list[:class:`compas_rhino.geometry.RhinoBrepVertex`], read-only The list of vertices which comprise this Brep. - points : list[:class:`~compas.geometry.Point`], read-only + points : list[:class:`compas.geometry.Point`], read-only The list of vertex geometries as points in 3D space. - edges : list[:class:`~compas_rhino.geometry.RhinoBrepEdge`], read-only + edges : list[:class:`compas_rhino.geometry.RhinoBrepEdge`], read-only The list of edges which comprise this brep. - trims : list[:class:`~compas_rhino.geometry.RhinoBrepTrim`], read-only + trims : list[:class:`compas_rhino.geometry.RhinoBrepTrim`], read-only The list of trims which comprise this brep. - loops : list[:class:`~compas_rhino.geometry.RhinoBrepLoop`], read-only + loops : list[:class:`compas_rhino.geometry.RhinoBrepLoop`], read-only The list of loops which comprise this brep. - faces : list[:class:`~compas_rhino.geometry.RhinoBrepFace`], read-only + faces : list[:class:`compas_rhino.geometry.RhinoBrepFace`], read-only The list of faces which comprise this brep. - frame : :class:`~compas.geometry.Frame`, read-only + frame : :class:`compas.geometry.Frame`, read-only The brep's origin (Frame.worldXY()). area : float, read-only The calculated area of this brep. @@ -97,7 +97,7 @@ def copy(self, cls=None): Returns ------- - :class:`~compas_rhino.geometry.RhinoBrep` + :class:`compas_rhino.geometry.RhinoBrep` """ # Avoid reconstruction when just copying. for sake of efficiency and stability @@ -181,12 +181,12 @@ def from_box(cls, box): Parameters ---------- - box : :class:`~compas.geometry.Box` + box : :class:`compas.geometry.Box` The box geometry of the brep. Returns ------- - :class:`~compas_rhino.geometry.RhinoBrep` + :class:`compas_rhino.geometry.RhinoBrep` """ rhino_box = box_to_rhino(box) @@ -198,12 +198,12 @@ def from_sphere(cls, sphere): Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + sphere : :class:`compas.geometry.Sphere` The source sphere. Returns ------- - :class:`~compas_rhino.geometry.RhinoBrep` + :class:`compas_rhino.geometry.RhinoBrep` """ rhino_sphere = sphere_to_rhino(sphere) @@ -215,12 +215,12 @@ def from_cylinder(cls, cylinder): Parameters ---------- - box : :class:`~compas.geometry.Box` + box : :class:`compas.geometry.Box` The box geometry of the brep. Returns ------- - :class:`~compas_rhino.geometry.RhinoBrep` + :class:`compas_rhino.geometry.RhinoBrep` """ rhino_cylinder = cylinder_to_rhino(cylinder) @@ -232,12 +232,12 @@ def from_mesh(cls, mesh): Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` The source mesh. Returns ------- - :class:`~compas_rhino.geometry.RhinoBrep` + :class:`compas_rhino.geometry.RhinoBrep` """ rhino_mesh = mesh_to_rhino(mesh) @@ -252,7 +252,7 @@ def transform(self, matrix): Parameters ---------- - matrix: :class:`~compas.geometry.Transformation` + matrix: :class:`compas.geometry.Transformation` The transformation matrix by which to transform this Brep. Returns @@ -267,7 +267,7 @@ def trim(self, trimming_plane, tolerance=TOLERANCE): Parameters ---------- - trimming_plane : :class:`~compas.geometry.Frame` or :class:`~compas.geometry.Plane` + trimming_plane : :class:`compas.geometry.Frame` or :class:`compas.geometry.Plane` The frame or plane to use when trimming. The discarded bit is in the direction of the frame's normal. tolerance : float @@ -293,14 +293,14 @@ def from_boolean_difference(cls, breps_a, breps_b): Parameters ---------- - breps_a : :class:`~compas_rhino.geometry.RhinoBrep` or list(:class:`~compas_rhino.geometry.RhinoBrep`) + breps_a : :class:`compas_rhino.geometry.RhinoBrep` or list(:class:`compas_rhino.geometry.RhinoBrep`) One or more Breps from which to substract. - breps_b : :class:`~compas_rhino.geometry.RhinoBrep` or list(:class:`~compas_rhino.geometry.RhinoBrep`) + breps_b : :class:`compas_rhino.geometry.RhinoBrep` or list(:class:`compas_rhino.geometry.RhinoBrep`) One or more Breps to substract. Returns ------- - list(:class:`~compas_rhino.geometry.RhinoBrep`) + list(:class:`compas_rhino.geometry.RhinoBrep`) list of one or more resulting Breps. """ @@ -321,14 +321,14 @@ def from_boolean_union(cls, breps_a, breps_b): Parameters ---------- - breps_a : :class:`~compas_rhino.geometry.RhinoBrep` or list(:class:`~compas_rhino.geometry.RhinoBrep`) + breps_a : :class:`compas_rhino.geometry.RhinoBrep` or list(:class:`compas_rhino.geometry.RhinoBrep`) One of more breps to join. - breps_b : :class:`~compas_rhino.geometry.RhinoBrep` or list(:class:`~compas_rhino.geometry.RhinoBrep`) + breps_b : :class:`compas_rhino.geometry.RhinoBrep` or list(:class:`compas_rhino.geometry.RhinoBrep`) Another one of more breps to join. Returns ------- - list(:class:`~compas_rhino.geometry.RhinoBrep`) + list(:class:`compas_rhino.geometry.RhinoBrep`) list of one or more resulting Breps. """ @@ -346,14 +346,14 @@ def from_boolean_intersection(cls, breps_a, breps_b): Parameters ---------- - breps_a : :class:`~compas_rhino.geometry.RhinoBrep` or list(:class:`~compas_rhino.geometry.RhinoBrep`) + breps_a : :class:`compas_rhino.geometry.RhinoBrep` or list(:class:`compas_rhino.geometry.RhinoBrep`) One or more Breps to instrsect. - breps_b : :class:`~compas_rhino.geometry.RhinoBrep` or list(:class:`~compas_rhino.geometry.RhinoBrep`) + breps_b : :class:`compas_rhino.geometry.RhinoBrep` or list(:class:`compas_rhino.geometry.RhinoBrep`) Another one or more Breps to intersect. Returns ------- - list(:class:`~compas_rhino.geometry.RhinoBrep`) + list(:class:`compas_rhino.geometry.RhinoBrep`) list of one or more resulting Breps. """ @@ -373,12 +373,12 @@ def split(self, cutter): Parameters ---------- - cutter : :class:`~compas_rhino.geometry.RhinoBrep` + cutter : :class:`compas_rhino.geometry.RhinoBrep` Another Brep to use as a cutter. Returns ------- - list(:class:`~compas_rhino.geometry.RhinoBrep`) + list(:class:`compas_rhino.geometry.RhinoBrep`) list of zero or more resulting Breps. """ diff --git a/src/compas_rhino/geometry/brep/builder.py b/src/compas_rhino/geometry/brep/builder.py index 536b3ffa294..084f89f9b8f 100644 --- a/src/compas_rhino/geometry/brep/builder.py +++ b/src/compas_rhino/geometry/brep/builder.py @@ -132,7 +132,7 @@ def result(self): def add_vertex(self, point): """Add vertext to a new Brep - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` Returns ------- @@ -144,7 +144,7 @@ def add_vertex(self, point): def add_edge(self, edge_curve, start_vertex, end_vertex): """Add edge to the new Brep - edge_curve : :class:`~compas_rhino.geometry.RhinoNurbsCurve` + edge_curve : :class:`compas_rhino.geometry.RhinoNurbsCurve` start_vertex: int index of the vertex at the start of this edge end_vertex: int diff --git a/src/compas_rhino/geometry/brep/edge.py b/src/compas_rhino/geometry/brep/edge.py index 1cc543a279b..fe468ee3b82 100644 --- a/src/compas_rhino/geometry/brep/edge.py +++ b/src/compas_rhino/geometry/brep/edge.py @@ -36,11 +36,11 @@ class RhinoBrepEdge(BrepEdge): ---------- curve : :class:`Rhino.Geometry.Curve3D` The underlying geometry of this edge. - start_vertex : :class:`~compas_rhino.geometry.RhinoBrepVertex`, read-only + start_vertex : :class:`compas_rhino.geometry.RhinoBrepVertex`, read-only The start vertex of this edge (taken from BrepTrim). - end_vertex : :class:`~compas_rhino.geometry.RhinoBrepVertex`, read-only + end_vertex : :class:`compas_rhino.geometry.RhinoBrepVertex`, read-only The end vertex of this edge (taken from BrepTrim). - vertices : list[:class:`~compas_rhino.geometry.RhinoBrepVertex`], read-only + vertices : list[:class:`compas_rhino.geometry.RhinoBrepVertex`], read-only The list of vertices which comprise this edge (start and end) is_circle : bool, read-only True if the geometry of this edge is a circle, False otherwise. @@ -96,12 +96,12 @@ def from_data(cls, data, builder): ---------- data : dict The data dictionary. - builder : :class:`~compas_rhino.geometry.BrepBuilder` + builder : :class:`compas_rhino.geometry.BrepBuilder` The object reconstructing the current Brep. Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` An instance of this object type if the data contained in the dict has the correct schema. """ diff --git a/src/compas_rhino/geometry/brep/face.py b/src/compas_rhino/geometry/brep/face.py index 02986c62fce..dbbbb0e425a 100644 --- a/src/compas_rhino/geometry/brep/face.py +++ b/src/compas_rhino/geometry/brep/face.py @@ -86,12 +86,12 @@ def from_data(cls, data, builder): ---------- data : dict The data dictionary. - builder : :class:`~compas_rhino.geometry.BrepBuilder` + builder : :class:`compas_rhino.geometry.BrepBuilder` The object reconstructing the current Brep. Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` An instance of this object type if the data contained in the dict has the correct schema. """ diff --git a/src/compas_rhino/geometry/brep/loop.py b/src/compas_rhino/geometry/brep/loop.py index 946431b32df..b9aaa447ee6 100644 --- a/src/compas_rhino/geometry/brep/loop.py +++ b/src/compas_rhino/geometry/brep/loop.py @@ -32,9 +32,9 @@ class RhinoBrepLoop(BrepLoop): Attributes ---------- - edges : list[:class:`~compas_rhino.geometry.RhinoBrepLoop`], read-only + edges : list[:class:`compas_rhino.geometry.RhinoBrepLoop`], read-only The list of edges which comprise this loop. - loop_type : :class:`~compas_rhino.geometry.brep.loop.LoopType`, read-only + loop_type : :class:`compas_rhino.geometry.brep.loop.LoopType`, read-only The type of this loop. is_outer : bool, read-only True if this loop is an outer boundary, False otherwise. @@ -83,12 +83,12 @@ def from_data(cls, data, builder): ---------- data : dict The data dictionary. - builder : :class:`~compas_rhino.geometry.BrepFaceBuilder` + builder : :class:`compas_rhino.geometry.BrepFaceBuilder` The object reconstructing the current BrepFace. Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` An instance of this object type if the data contained in the dict has the correct schema. """ diff --git a/src/compas_rhino/geometry/brep/trim.py b/src/compas_rhino/geometry/brep/trim.py index 5def5f2d7b5..bc550f2324e 100644 --- a/src/compas_rhino/geometry/brep/trim.py +++ b/src/compas_rhino/geometry/brep/trim.py @@ -9,7 +9,7 @@ class RhinoBrepTrim(BrepTrim): Attributes ---------- - curve : :class:`~compas.geometry.NurbsCurve`, read_only + curve : :class:`compas.geometry.NurbsCurve`, read_only Returns the geometry for this trim as a 2d curve. iso_status : literal(NONE|X|Y|West|South|East|North) The isoparametric curve direction on the surface. @@ -60,12 +60,12 @@ def from_data(cls, data, builder): ---------- data : dict The data dictionary. - builder : :class:`~compas_rhino.geometry.BrepLoopBuilder` + builder : :class:`compas_rhino.geometry.BrepLoopBuilder` The object reconstructing the current BrepLoop. Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` An instance of this object type if the data contained in the dict has the correct schema. """ diff --git a/src/compas_rhino/geometry/brep/vertex.py b/src/compas_rhino/geometry/brep/vertex.py index 7ba92dcb259..792b5833207 100644 --- a/src/compas_rhino/geometry/brep/vertex.py +++ b/src/compas_rhino/geometry/brep/vertex.py @@ -8,7 +8,7 @@ class RhinoBrepVertex(BrepVertex): Attributes ---------- - point : :class:`~compas.geometry.Point`, read-only + point : :class:`compas.geometry.Point`, read-only The geometry of this vertex as a point in 3D space. """ @@ -48,12 +48,12 @@ def from_data(cls, data, builder): ---------- data : dict The data dictionary. - builder : :class:`~compas_rhino.geometry.BrepBuilder` + builder : :class:`compas_rhino.geometry.BrepBuilder` The object reconstructing the current Brep. Returns ------- - :class:`~compas.data.Data` + :class:`compas.data.Data` An instance of this object type if the data contained in the dict has the correct schema. """ diff --git a/src/compas_rhino/geometry/curves/curve.py b/src/compas_rhino/geometry/curves/curve.py index 8c2bd3d6c96..6c4dd2d4b01 100644 --- a/src/compas_rhino/geometry/curves/curve.py +++ b/src/compas_rhino/geometry/curves/curve.py @@ -28,9 +28,9 @@ class RhinoCurve(Curve): The spatial dimension of the curve. domain : tuple[float, float], read-only The parameter domain. - start : :class:`~compas.geometry.Point`, read-only + start : :class:`compas.geometry.Point`, read-only The point corresponding to the start of the parameter domain. - end : :class:`~compas.geometry.Point`, read-only + end : :class:`compas.geometry.Point`, read-only The point corresponding to the end of the parameter domain. is_closed : bool, read-only True if the curve is closed. @@ -111,7 +111,7 @@ def from_rhino(cls, rhino_curve): Returns ------- - :class:`~compas_rhino.geometry.RhinoCurve` + :class:`compas_rhino.geometry.RhinoCurve` """ curve = cls() @@ -131,7 +131,7 @@ def copy(self): Returns ------- - :class:`~compas_rhino.geometry.RhinoCurve` + :class:`compas_rhino.geometry.RhinoCurve` """ cls = type(self) @@ -144,7 +144,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` A COMPAS transformation. Returns @@ -174,7 +174,7 @@ def point_at(self, t): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` the corresponding point on the curve. """ @@ -191,7 +191,7 @@ def tangent_at(self, t): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The corresponding tangent vector. """ @@ -208,7 +208,7 @@ def curvature_at(self, t): Returns ------- - :class:`~compas.geometry.Vector` + :class:`compas.geometry.Vector` The corresponding curvature vector. """ @@ -225,7 +225,7 @@ def frame_at(self, t): Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` The corresponding local frame. """ @@ -257,14 +257,14 @@ def closest_point(self, point, return_parameter=False): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The test point. return_parameter : bool, optional If True, the parameter corresponding to the closest point should be returned in addition to the point. Returns ------- - :class:`~compas.geometry.Point` | tuple[:class:`~compas.geometry.Point`, float] + :class:`compas.geometry.Point` | tuple[:class:`compas.geometry.Point`, float] If `return_parameter` is False, only the closest point is returned. If `return_parameter` is True, the closest point and the corresponding parameter are returned. @@ -291,7 +291,7 @@ def divide_by_count(self, count, return_points=False): Returns ------- - list[float] | tuple[list[float], list[:class:`~compas.geometry.Point`]] + list[float] | tuple[list[float], list[:class:`compas.geometry.Point`]] If `return_points` is False, the parameters of the discretisation. If `return_points` is True, a list of points in addition to the parameters of the discretisation. @@ -316,7 +316,7 @@ def divide_by_length(self, length, return_points=False): Returns ------- - list[float] | tuple[list[float], list[:class:`~compas.geometry.Point`]] + list[float] | tuple[list[float], list[:class:`compas.geometry.Point`]] If `return_points` is False, the parameters of the discretisation. If `return_points` is True, a list of points in addition to the parameters of the discretisation. @@ -332,7 +332,7 @@ def aabb(self): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` """ box = self.rhino_curve.getBoundingBox(True) # type: ignore diff --git a/src/compas_rhino/geometry/curves/nurbs.py b/src/compas_rhino/geometry/curves/nurbs.py index a899ab17dcb..d912a511bc4 100644 --- a/src/compas_rhino/geometry/curves/nurbs.py +++ b/src/compas_rhino/geometry/curves/nurbs.py @@ -42,7 +42,7 @@ class RhinoNurbsCurve(NurbsCurve, RhinoCurve): Attributes ---------- - points : list[:class:`~compas.geometry.Point`], read-only + points : list[:class:`compas.geometry.Point`], read-only The control points of the curve. weights : list[float], read-only The weights of the control points. @@ -164,7 +164,7 @@ def from_parameters(cls, points, weights, knots, multiplicities, degree, is_peri Parameters ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The control points. weights : list[float] The control point weights. @@ -180,7 +180,7 @@ def from_parameters(cls, points, weights, knots, multiplicities, degree, is_peri Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsCurve` + :class:`compas_rhino.geometry.RhinoNurbsCurve` """ curve = cls() @@ -193,7 +193,7 @@ def from_points(cls, points, degree=3, is_periodic=False): Parameters ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The control points. degree : int, optional The degree of the curve. @@ -202,7 +202,7 @@ def from_points(cls, points, degree=3, is_periodic=False): Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsCurve` + :class:`compas_rhino.geometry.RhinoNurbsCurve` """ points[:] = [point_to_rhino(point) for point in points] @@ -216,7 +216,7 @@ def from_interpolation(cls, points, precision=1e-3): Parameters ---------- - points : list[:class:`~compas.geometry.Point`] + points : list[:class:`compas.geometry.Point`] The control points. precision : float, optional The required precision of the interpolation. @@ -224,7 +224,7 @@ def from_interpolation(cls, points, precision=1e-3): Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsCurve` + :class:`compas_rhino.geometry.RhinoNurbsCurve` """ curve = cls() @@ -237,12 +237,12 @@ def from_interpolation(cls, points, precision=1e-3): # Parameters # ---------- - # circle : :class:`~compas.geometry.Circle` + # circle : :class:`compas.geometry.Circle` # A circle geometry. # Returns # ------- - # :class:`~compas_rhino.geometry.RhinoNurbsCurve` + # :class:`compas_rhino.geometry.RhinoNurbsCurve` # """ # curve = cls() @@ -255,12 +255,12 @@ def from_interpolation(cls, points, precision=1e-3): # Parameters # ---------- - # ellipse : :class:`~compas.geometry.Ellipse` + # ellipse : :class:`compas.geometry.Ellipse` # An ellipse geometry. # Returns # ------- - # :class:`~compas_rhino.geometry.RhinoNurbsCurve` + # :class:`compas_rhino.geometry.RhinoNurbsCurve` # """ # curve = cls() @@ -273,12 +273,12 @@ def from_line(cls, line): Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` A line geometry. Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsCurve` + :class:`compas_rhino.geometry.RhinoNurbsCurve` """ curve = cls() diff --git a/src/compas_rhino/geometry/surfaces/nurbs.py b/src/compas_rhino/geometry/surfaces/nurbs.py index 0e8e214cdc2..d9e7c36cc3d 100644 --- a/src/compas_rhino/geometry/surfaces/nurbs.py +++ b/src/compas_rhino/geometry/surfaces/nurbs.py @@ -115,7 +115,7 @@ class RhinoNurbsSurface(RhinoSurface, NurbsSurface): Attributes ---------- - points: list[list[:class:`~compas.geometry.Point`]] + points: list[list[:class:`compas.geometry.Point`]] The control points of the surface. weights: list[list[float]] The weights of the control points. @@ -202,7 +202,7 @@ def from_data(cls, data): Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsSurface` + :class:`compas_rhino.geometry.RhinoNurbsSurface` The constructed surface. """ @@ -313,7 +313,7 @@ def from_parameters( Parameters ---------- - points : list[list[:class:`~compas.geometry.Point`]] + points : list[list[:class:`compas.geometry.Point`]] The control points. weights : list[list[float]] The weights of the control points. @@ -332,7 +332,7 @@ def from_parameters( Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsSurface` + :class:`compas_rhino.geometry.RhinoNurbsSurface` """ surface = cls() @@ -347,7 +347,7 @@ def from_points(cls, points, degree_u=3, degree_v=3): Parameters ---------- - points : list[list[:class:`~compas.geometry.Point`]] + points : list[list[:class:`compas.geometry.Point`]] The control points. degree_u : int Degree in the U direction. @@ -356,7 +356,7 @@ def from_points(cls, points, degree_u=3, degree_v=3): Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsSurface` + :class:`compas_rhino.geometry.RhinoNurbsSurface` """ # this of course depends on the order in which the points are given. @@ -378,12 +378,12 @@ def from_fill(cls, curve1, curve2): Parameters ---------- - curve1 : :class:`~compas.geometry.NurbsCurve` - curve2 : :class:`~compas.geometry.NurbsCurve` + curve1 : :class:`compas.geometry.NurbsCurve` + curve2 : :class:`compas.geometry.NurbsCurve` Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsSurface` + :class:`compas_rhino.geometry.RhinoNurbsSurface` """ surface = cls() diff --git a/src/compas_rhino/geometry/surfaces/surface.py b/src/compas_rhino/geometry/surfaces/surface.py index 701988fbdd0..08883ff8cc2 100644 --- a/src/compas_rhino/geometry/surfaces/surface.py +++ b/src/compas_rhino/geometry/surfaces/surface.py @@ -88,12 +88,12 @@ def from_corners(cls, corners): Parameters ---------- - corners : list(:class:`~compas.geometry.Point`) + corners : list(:class:`compas.geometry.Point`) 4 points in 3d space to represent the corners of the planar surface. Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsSurface` + :class:`compas_rhino.geometry.RhinoNurbsSurface` """ rhino_points = [Rhino.Geometry.Point3d(corner.x, corner.y, corner.z) for corner in corners] @@ -105,12 +105,12 @@ def from_sphere(cls, sphere): Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + sphere : :class:`compas.geometry.Sphere` The surface's geometry. Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsSurface` + :class:`compas_rhino.geometry.RhinoNurbsSurface` """ sphere = sphere_to_rhino(sphere) @@ -123,12 +123,12 @@ def from_cylinder(cls, cylinder): Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + cylinder : :class:`compas.geometry.Cylinder` The surface's geometry. Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsSurface` + :class:`compas_rhino.geometry.RhinoNurbsSurface` """ cylinder = cylinder_to_rhino(cylinder) @@ -141,12 +141,12 @@ def from_torus(cls, torus): Parameters ---------- - torus : :class:`~compas.geometry.Torus` + torus : :class:`compas.geometry.Torus` The surface's geometry. Returns ------- - :class:`~compas_rhino.geometry.RhinoNurbsSurface` + :class:`compas_rhino.geometry.RhinoNurbsSurface` """ raise NotImplementedError @@ -162,7 +162,7 @@ def from_rhino(cls, rhino_surface): Returns ------- - :class:`~compas_rhino.geometry.RhinoSurface` + :class:`compas_rhino.geometry.RhinoSurface` """ curve = cls() @@ -180,7 +180,7 @@ def from_plane(cls, plane, box): Returns ------- - :class:`~compas_rhino.geometry.RhinoSurface` + :class:`compas_rhino.geometry.RhinoSurface` """ plane = plane_to_rhino(plane) @@ -194,7 +194,7 @@ def from_frame(cls, frame, u_interval, v_interval): Parameters ---------- - frame : :class:`~compas.geometry.Frame` + frame : :class:`compas.geometry.Frame` A frame with point at the center of the wanted plannar surface and x and y axes the direction of u and v respectively. u_interval : tuple(float, float) @@ -230,7 +230,7 @@ def copy(self): Returns ------- - :class:`~compas_rhino.geometry.RhinoSurface` + :class:`compas_rhino.geometry.RhinoSurface` """ cls = type(self) @@ -243,7 +243,7 @@ def transform(self, T): Parameters ---------- - T : :class:`~compas.geometry.Transformation` + T : :class:`compas.geometry.Transformation` A COMPAS transformation. Returns @@ -262,7 +262,7 @@ def u_isocurve(self, u): Returns ------- - :class:`~compas_rhino.geometry.RhinoCurve` + :class:`compas_rhino.geometry.RhinoCurve` """ curve = self.rhino_surface.IsoCurve(1, u) # type: ignore @@ -277,7 +277,7 @@ def v_isocurve(self, v): Returns ------- - :class:`~compas_rhino.geometry.RhinoCurve` + :class:`compas_rhino.geometry.RhinoCurve` """ curve = self.rhino_surface.IsoCurve(0, v) # type: ignore @@ -293,7 +293,7 @@ def point_at(self, u, v): Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` """ point = self.rhino_surface.PointAt(u, v) # type: ignore @@ -334,7 +334,7 @@ def frame_at(self, u, v): Returns ------- - :class:`~compas.geometry.Frame` + :class:`compas.geometry.Frame` """ result, plane = self.rhino_surface.FrameAt(u, v) # type: ignore @@ -350,16 +350,16 @@ def closest_point(self, point, return_parameters=False): Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` The test point. return_parameters : bool, optional If True, return the UV parameters of the closest point as tuple in addition to the point location. Returns ------- - :class:`~compas.geometry.Point` + :class:`compas.geometry.Point` If `return_parameters` is False. - :class:`~compas.geometry.Point`, (float, float) + :class:`compas.geometry.Point`, (float, float) If `return_parameters` is True. """ @@ -382,7 +382,7 @@ def aabb(self, precision=0.0, optimal=False): Returns ------- - :class:`~compas.geometry.Box` + :class:`compas.geometry.Box` """ box = self.rhino_surface.GetBoundingBox(optimal) # type: ignore @@ -393,11 +393,11 @@ def intersections_with_curve(self, curve, tolerance=1e-3, overlap=1e-3): Parameters ---------- - line : :class:`~compas.geometry.Curve` + line : :class:`compas.geometry.Curve` Returns ------- - list[:class:`~compas.geometry.Point`] + list[:class:`compas.geometry.Point`] """ intersections = Rhino.Geometry.Intersect.Intersection.CurveSurface( diff --git a/src/compas_rhino/geometry/trimesh/__init__.py b/src/compas_rhino/geometry/trimesh/__init__.py deleted file mode 100644 index 9bc476dcc20..00000000000 --- a/src/compas_rhino/geometry/trimesh/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from __future__ import absolute_import - -from .curvature import trimesh_gaussian_curvature # noqa: F401 -from .curvature import trimesh_mean_curvature # noqa: F401 -from .curvature import trimesh_principal_curvature # noqa: F401 - -from .slice import trimesh_slice # noqa: F401 diff --git a/src/compas_rhino/geometry/trimesh/curvature.py b/src/compas_rhino/geometry/trimesh_curvature.py similarity index 95% rename from src/compas_rhino/geometry/trimesh/curvature.py rename to src/compas_rhino/geometry/trimesh_curvature.py index a248c6d8888..4e0f2fe3d42 100644 --- a/src/compas_rhino/geometry/trimesh/curvature.py +++ b/src/compas_rhino/geometry/trimesh_curvature.py @@ -23,7 +23,7 @@ def trimesh_gaussian_curvature(M): Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns @@ -108,13 +108,16 @@ def trimesh_gaussian_curvature(M): return K +trimesh_gaussian_curvature.__plugin__ = True + + @plugin(category="trimesh", requires=["Rhino"]) def trimesh_mean_curvature(M): r"""Compute the discrete mean curvature of a triangle mesh. Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns @@ -213,13 +216,16 @@ def trimesh_mean_curvature(M): return H +trimesh_mean_curvature.__plugin__ = True + + @plugin(category="trimesh", requires=["Rhino"]) def trimesh_principal_curvature(M): r"""Compute the principal curvature of a triangle mesh. Parameters ---------- - M : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + M : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] A mesh represented by a list of vertices and a list of faces. Returns @@ -300,6 +306,9 @@ def trimesh_principal_curvature(M): return k1, k2 +trimesh_principal_curvature.__plugin__ = True + + def trimesh_barycentric_area(mesh): # (1) prepare return list areas = [0] * mesh.Vertices.Count diff --git a/src/compas_rhino/geometry/trimesh/slice.py b/src/compas_rhino/geometry/trimesh_slicing.py similarity index 89% rename from src/compas_rhino/geometry/trimesh/slice.py rename to src/compas_rhino/geometry/trimesh_slicing.py index f02f7cd25ba..cc54cf91152 100644 --- a/src/compas_rhino/geometry/trimesh/slice.py +++ b/src/compas_rhino/geometry/trimesh_slicing.py @@ -15,9 +15,9 @@ def trimesh_slice(mesh, planes): Parameters ---------- - mesh : tuple[sequence[[float, float, float] | :class:`~compas.geometry.Point`], sequence[[int, int, int]]] + mesh : tuple[sequence[[float, float, float] | :class:`compas.geometry.Point`], sequence[[int, int, int]]] The mesh to slice. - planes : sequence[[point, vector] | :class:`~compas.geometry.Plane`] + planes : sequence[[point, vector] | :class:`compas.geometry.Plane`] The slicing planes. Returns @@ -62,3 +62,6 @@ def trimesh_slice(mesh, planes): polyline_pts.append(pts) return polyline_pts + + +trimesh_slice.__plugin__ = True diff --git a/src/compas_rhino/scene/__init__.py b/src/compas_rhino/scene/__init__.py new file mode 100644 index 00000000000..ac6ad00e3b0 --- /dev/null +++ b/src/compas_rhino/scene/__init__.py @@ -0,0 +1,127 @@ +""" +This package provides scene object plugins for visualising COMPAS objects in Rhino. +When working in Rhino, :class:`compas.scene.SceneObject` will automatically use the corresponding Rhino scene object for each COMPAS object type. +""" +from __future__ import absolute_import + +from compas.plugins import plugin +from compas.scene import SceneObject + +from compas.geometry import Circle +from compas.geometry import Ellipse +from compas.geometry import Frame +from compas.geometry import Line +from compas.geometry import Plane +from compas.geometry import Point +from compas.geometry import Polygon +from compas.geometry import Polyline +from compas.geometry import Vector + +from compas.geometry import Box +from compas.geometry import Capsule +from compas.geometry import Cone +from compas.geometry import Cylinder +from compas.geometry import Polyhedron +from compas.geometry import Sphere +from compas.geometry import Torus + +from compas.geometry import Curve +from compas.geometry import Surface +from compas.geometry import Brep + +from compas.datastructures import Mesh +from compas.datastructures import Network +from compas.datastructures import VolMesh + +import compas_rhino + +from .sceneobject import RhinoSceneObject +from .circleobject import CircleObject +from .ellipseobject import EllipseObject +from .frameobject import FrameObject +from .lineobject import LineObject +from .planeobject import PlaneObject +from .pointobject import PointObject +from .polygonobject import PolygonObject +from .polylineobject import PolylineObject +from .vectorobject import VectorObject + +from .boxobject import BoxObject +from .capsuleobject import CapsuleObject +from .coneobject import ConeObject +from .cylinderobject import CylinderObject +from .polyhedronobject import PolyhedronObject +from .sphereobject import SphereObject +from .torusobject import TorusObject + +from .meshobject import MeshObject +from .networkobject import NetworkObject +from .volmeshobject import VolMeshObject + +from .curveobject import CurveObject +from .surfaceobject import SurfaceObject +from .brepobject import BrepObject + + +@plugin(category="drawing-utils", pluggable_name="clear", requires=["Rhino"]) +def clear_rhino(): + compas_rhino.clear() + + +@plugin(category="drawing-utils", pluggable_name="redraw", requires=["Rhino"]) +def redraw_rhino(): + compas_rhino.redraw() + + +@plugin(category="factories", requires=["Rhino"]) +def register_scene_objects(): + SceneObject.register(Circle, CircleObject, context="Rhino") + SceneObject.register(Ellipse, EllipseObject, context="Rhino") + SceneObject.register(Frame, FrameObject, context="Rhino") + SceneObject.register(Line, LineObject, context="Rhino") + SceneObject.register(Plane, PlaneObject, context="Rhino") + SceneObject.register(Point, PointObject, context="Rhino") + SceneObject.register(Polygon, PolygonObject, context="Rhino") + SceneObject.register(Polyline, PolylineObject, context="Rhino") + SceneObject.register(Vector, VectorObject, context="Rhino") + SceneObject.register(Box, BoxObject, context="Rhino") + SceneObject.register(Capsule, CapsuleObject, context="Rhino") + SceneObject.register(Cone, ConeObject, context="Rhino") + SceneObject.register(Cylinder, CylinderObject, context="Rhino") + SceneObject.register(Polyhedron, PolyhedronObject, context="Rhino") + SceneObject.register(Sphere, SphereObject, context="Rhino") + SceneObject.register(Torus, TorusObject, context="Rhino") + SceneObject.register(Mesh, MeshObject, context="Rhino") + SceneObject.register(Network, NetworkObject, context="Rhino") + SceneObject.register(VolMesh, VolMeshObject, context="Rhino") + SceneObject.register(Curve, CurveObject, context="Rhino") + SceneObject.register(Surface, SurfaceObject, context="Rhino") + SceneObject.register(Brep, BrepObject, context="Rhino") + print("Rhino SceneObjects registered.") + + +__all__ = [ + "RhinoSceneObject", + "CircleObject", + "EllipseObject", + "FrameObject", + "LineObject", + "PlaneObject", + "PointObject", + "PolygonObject", + "PolylineObject", + "VectorObject", + "BoxObject", + "CapsuleObject", + "ConeObject", + "CylinderObject", + "PolyhedronObject", + "SphereObject", + "TorusObject", + "MeshObject", + "NetworkObject", + "VolMeshObject", + "CurveObject", + "SurfaceObject", + "BrepObject", +] diff --git a/src/compas_rhino/artists/_helpers.py b/src/compas_rhino/scene/_helpers.py similarity index 100% rename from src/compas_rhino/artists/_helpers.py rename to src/compas_rhino/scene/_helpers.py diff --git a/src/compas_rhino/artists/boxartist.py b/src/compas_rhino/scene/boxobject.py similarity index 73% rename from src/compas_rhino/artists/boxartist.py rename to src/compas_rhino/scene/boxobject.py index f13f23e475d..54d5f0c3811 100644 --- a/src/compas_rhino/artists/boxartist.py +++ b/src/compas_rhino/scene/boxobject.py @@ -4,20 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import box_to_rhino from compas_rhino.conversions import transformation_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class BoxArtist(RhinoArtist, GeometryArtist): - """Artist for drawing box shapes. +class BoxObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing box shapes. Parameters ---------- - box : :class:`~compas.geometry.Box` + box : :class:`compas.geometry.Box` A COMPAS box. **kwargs : dict, optional Additional keyword arguments. @@ -25,14 +25,14 @@ class BoxArtist(RhinoArtist, GeometryArtist): """ def __init__(self, box, **kwargs): - super(BoxArtist, self).__init__(geometry=box, **kwargs) + super(BoxObject, self).__init__(geometry=box, **kwargs) def draw(self, color=None): - """Draw the box associated with the artist. + """Draw the box associated with the scene object. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the box. Returns diff --git a/src/compas_rhino/artists/brepartist.py b/src/compas_rhino/scene/brepobject.py similarity index 74% rename from src/compas_rhino/artists/brepartist.py rename to src/compas_rhino/scene/brepobject.py index 0557b4e5e60..29b8d4f5ba6 100644 --- a/src/compas_rhino/artists/brepartist.py +++ b/src/compas_rhino/scene/brepobject.py @@ -7,30 +7,30 @@ from compas.colors import Color from compas_rhino.conversions import brep_to_rhino from compas_rhino.conversions import transformation_to_rhino -from compas.artists import GeometryArtist -from .artist import RhinoArtist +from compas.scene import GeometryObject +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class BrepArtist(RhinoArtist, GeometryArtist): - """An artist for drawing a RhinoBrep. +class BrepObject(RhinoSceneObject, GeometryObject): + """A scene object for drawing a RhinoBrep. Parameters ---------- - brep : :class:`~compas_rhino.geometry.RhinoBrep` + brep : :class:`compas_rhino.geometry.RhinoBrep` The Brep to draw. """ def __init__(self, brep, **kwargs): - super(BrepArtist, self).__init__(geometry=brep, **kwargs) + super(BrepObject, self).__init__(geometry=brep, **kwargs) def draw(self, color=None): """Bakes the Brep into the current document Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the Brep. Returns diff --git a/src/compas_rhino/artists/capsuleartist.py b/src/compas_rhino/scene/capsuleobject.py similarity index 74% rename from src/compas_rhino/artists/capsuleartist.py rename to src/compas_rhino/scene/capsuleobject.py index 65696b44e9f..3e55cf49cba 100644 --- a/src/compas_rhino/artists/capsuleartist.py +++ b/src/compas_rhino/scene/capsuleobject.py @@ -4,20 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import capsule_to_rhino_brep from compas_rhino.conversions import transformation_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class CapsuleArtist(RhinoArtist, GeometryArtist): - """Artist for drawing capsule shapes. +class CapsuleObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing capsule shapes. Parameters ---------- - capsule : :class:`~compas.geometry.Capsule` + capsule : :class:`compas.geometry.Capsule` A COMPAS capsule. **kwargs : dict, optional Additional keyword arguments. @@ -25,14 +25,14 @@ class CapsuleArtist(RhinoArtist, GeometryArtist): """ def __init__(self, capsule, **kwargs): - super(CapsuleArtist, self).__init__(geometry=capsule, **kwargs) + super(CapsuleObject, self).__init__(geometry=capsule, **kwargs) def draw(self, color=None): - """Draw the capsule associated with the artist. + """Draw the capsule associated with the scene object. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the capsule. Returns diff --git a/src/compas_rhino/artists/circleartist.py b/src/compas_rhino/scene/circleobject.py similarity index 76% rename from src/compas_rhino/artists/circleartist.py rename to src/compas_rhino/scene/circleobject.py index ea781c16ca1..a8a8ad7c6db 100644 --- a/src/compas_rhino/artists/circleartist.py +++ b/src/compas_rhino/scene/circleobject.py @@ -4,22 +4,22 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import circle_to_rhino # from compas_rhino.conversions import point_to_rhino from compas_rhino.conversions import transformation_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class CircleArtist(RhinoArtist, GeometryArtist): - """Artist for drawing circles. +class CircleObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing circles. Parameters ---------- - circle : :class:`~compas.geometry.Circle` + circle : :class:`compas.geometry.Circle` A COMPAS circle. **kwargs : dict, optional Additional keyword arguments. @@ -27,14 +27,14 @@ class CircleArtist(RhinoArtist, GeometryArtist): """ def __init__(self, circle, **kwargs): - super(CircleArtist, self).__init__(geometry=circle, **kwargs) + super(CircleObject, self).__init__(geometry=circle, **kwargs) def draw(self, color=None): """Draw the circle. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the circle. Returns diff --git a/src/compas_rhino/artists/coneartist.py b/src/compas_rhino/scene/coneobject.py similarity index 72% rename from src/compas_rhino/artists/coneartist.py rename to src/compas_rhino/scene/coneobject.py index 5ff48444b16..9123305130c 100644 --- a/src/compas_rhino/artists/coneartist.py +++ b/src/compas_rhino/scene/coneobject.py @@ -4,20 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import cone_to_rhino_brep from compas_rhino.conversions import transformation_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class ConeArtist(RhinoArtist, GeometryArtist): - """Artist for drawing cone shapes. +class ConeObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing cone shapes. Parameters ---------- - shape : :class:`~compas.geometry.Cone` + shape : :class:`compas.geometry.Cone` A COMPAS cone. **kwargs : dict, optional Additional keyword arguments. @@ -25,14 +25,14 @@ class ConeArtist(RhinoArtist, GeometryArtist): """ def __init__(self, cone, **kwargs): - super(ConeArtist, self).__init__(geometry=cone, **kwargs) + super(ConeObject, self).__init__(geometry=cone, **kwargs) def draw(self, color=None): - """Draw the cone associated with the artist. + """Draw the cone associated with the scene object. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the cone. Returns diff --git a/src/compas_rhino/artists/curveartist.py b/src/compas_rhino/scene/curveobject.py similarity index 75% rename from src/compas_rhino/artists/curveartist.py rename to src/compas_rhino/scene/curveobject.py index 60f24b65faf..30fcce1c4bb 100644 --- a/src/compas_rhino/artists/curveartist.py +++ b/src/compas_rhino/scene/curveobject.py @@ -4,20 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import curve_to_rhino from compas_rhino.conversions import transformation_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class CurveArtist(RhinoArtist, GeometryArtist): - """Artist for drawing curves. +class CurveObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing curves. Parameters ---------- - curve : :class:`~compas.geometry.Curve` + curve : :class:`compas.geometry.Curve` A COMPAS curve. **kwargs : dict, optional Additional keyword arguments. @@ -25,14 +25,14 @@ class CurveArtist(RhinoArtist, GeometryArtist): """ def __init__(self, curve, **kwargs): - super(CurveArtist, self).__init__(geometry=curve, **kwargs) + super(CurveObject, self).__init__(geometry=curve, **kwargs) def draw(self, color=None): """Draw the curve. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the curve. Returns diff --git a/src/compas_rhino/artists/cylinderartist.py b/src/compas_rhino/scene/cylinderobject.py similarity index 72% rename from src/compas_rhino/artists/cylinderartist.py rename to src/compas_rhino/scene/cylinderobject.py index cfa5b102fe8..f9e726af3fa 100644 --- a/src/compas_rhino/artists/cylinderartist.py +++ b/src/compas_rhino/scene/cylinderobject.py @@ -4,20 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import cylinder_to_rhino_brep from compas_rhino.conversions import transformation_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class CylinderArtist(RhinoArtist, GeometryArtist): - """Artist for drawing cylinder shapes. +class CylinderObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing cylinder shapes. Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + cylinder : :class:`compas.geometry.Cylinder` A COMPAS cylinder. **kwargs : dict, optional Additional keyword arguments. @@ -25,14 +25,14 @@ class CylinderArtist(RhinoArtist, GeometryArtist): """ def __init__(self, cylinder, **kwargs): - super(CylinderArtist, self).__init__(geometry=cylinder, **kwargs) + super(CylinderObject, self).__init__(geometry=cylinder, **kwargs) def draw(self, color=None): - """Draw the cylinder associated with the artist. + """Draw the cylinder associated with the scene object. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the cylinder. Returns diff --git a/src/compas_rhino/artists/ellipseartist.py b/src/compas_rhino/scene/ellipseobject.py similarity index 61% rename from src/compas_rhino/artists/ellipseartist.py rename to src/compas_rhino/scene/ellipseobject.py index c5f115e6f94..4a7d9ce678c 100644 --- a/src/compas_rhino/artists/ellipseartist.py +++ b/src/compas_rhino/scene/ellipseobject.py @@ -4,21 +4,21 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import ellipse_to_rhino from compas_rhino.conversions import transformation_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class EllipseArtist(RhinoArtist, GeometryArtist): - """Artist for drawing ellipses. +class EllipseObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing ellipses. Parameters ---------- - ellipse : :class:`~compas.geometry.Ellipse` + ellipse : :class:`compas.geometry.Ellipse` A COMPAS ellipse. **kwargs : dict, optional Additional keyword arguments. @@ -26,14 +26,14 @@ class EllipseArtist(RhinoArtist, GeometryArtist): """ def __init__(self, ellipse, **kwargs): - super(EllipseArtist, self).__init__(geometry=ellipse, **kwargs) + super(EllipseObject, self).__init__(geometry=ellipse, **kwargs) def draw(self, color=None): """Draw the ellipse. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the ellipse. Returns @@ -45,9 +45,10 @@ def draw(self, color=None): color = Color.coerce(color) or self.color attr = attributes(name=self.geometry.name, color=color, layer=self.layer) - geometry = ellipse_to_rhino(self.geometry) + ellipse = ellipse_to_rhino(self.geometry) + ellipse = ellipse.ToNurbsCurve() if self.transformation: - geometry.Transform(transformation_to_rhino(self.transformation)) + ellipse.Transform(transformation_to_rhino(self.transformation)) - return sc.doc.Objects.AddEllipse(geometry, attr) + return sc.doc.Objects.AddCurve(ellipse, attr) diff --git a/src/compas_rhino/artists/frameartist.py b/src/compas_rhino/scene/frameobject.py similarity index 75% rename from src/compas_rhino/artists/frameartist.py rename to src/compas_rhino/scene/frameobject.py index 2c9d863630a..7e5f4fcac47 100644 --- a/src/compas_rhino/artists/frameartist.py +++ b/src/compas_rhino/scene/frameobject.py @@ -4,19 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import point_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class FrameArtist(RhinoArtist, GeometryArtist): - """Artist for drawing frames. +class FrameObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing frames. Parameters ---------- - frame: :class:`~compas.geometry.Frame` + frame: :class:`compas.geometry.Frame` A COMPAS frame. scale: float, optional Scale factor that controls the length of the axes. @@ -28,19 +29,19 @@ class FrameArtist(RhinoArtist, GeometryArtist): scale : float Scale factor that controls the length of the axes. Default is ``1.0``. - color_origin : :class:`~compas.colors.Color` + color_origin : :class:`compas.colors.Color` Default is ``Color.black()``. - color_xaxis : :class:`~compas.colors.Color` + color_xaxis : :class:`compas.colors.Color` Default is ``Color.red()``. - color_yaxis : :class:`~compas.colors.Color` + color_yaxis : :class:`compas.colors.Color` Default is ``Color.green()``. - color_zaxis : :class:`~compas.colors.Color` + color_zaxis : :class:`compas.colors.Color` Default is ``Color.blue()``. """ def __init__(self, frame, scale=1.0, **kwargs): - super(FrameArtist, self).__init__(geometry=frame, **kwargs) + super(FrameObject, self).__init__(geometry=frame, **kwargs) self.scale = scale or 1.0 self.color_origin = Color.black() self.color_xaxis = Color.red() @@ -88,4 +89,12 @@ def draw(self): self.add_to_group("Frame.{}".format(self.geometry.name), guids) + if self.transformation: + transformation = transformation_to_rhino(self.transformation) + for guid in guids: + obj = sc.doc.Objects.Find(guid) + if obj: + obj.Geometry.Transform(transformation) + obj.CommitChanges() + return guids diff --git a/src/compas_rhino/artists/lineartist.py b/src/compas_rhino/scene/lineobject.py similarity index 64% rename from src/compas_rhino/artists/lineartist.py rename to src/compas_rhino/scene/lineobject.py index a0fe6b6bcd1..f5805147dc0 100644 --- a/src/compas_rhino/artists/lineartist.py +++ b/src/compas_rhino/scene/lineobject.py @@ -4,19 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import line_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class LineArtist(RhinoArtist, GeometryArtist): - """Artist for drawing lines. +class LineObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing lines. Parameters ---------- - line : :class:`~compas.geometry.Line` + line : :class:`compas.geometry.Line` A COMPAS line. **kwargs : dict, optional Additional keyword arguments. @@ -24,14 +25,14 @@ class LineArtist(RhinoArtist, GeometryArtist): """ def __init__(self, line, **kwargs): - super(LineArtist, self).__init__(geometry=line, **kwargs) + super(LineObject, self).__init__(geometry=line, **kwargs) def draw(self, color=None): """Draw the line. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the line. Returns @@ -44,5 +45,7 @@ def draw(self, color=None): attr = attributes(name=self.geometry.name, color=color, layer=self.layer) geometry = line_to_rhino(self.geometry) + if self.transformation: + geometry.Transform(transformation_to_rhino(self.transformation)) return sc.doc.Objects.AddLine(geometry, attr) diff --git a/src/compas_rhino/artists/meshartist.py b/src/compas_rhino/scene/meshobject.py similarity index 91% rename from src/compas_rhino/artists/meshartist.py rename to src/compas_rhino/scene/meshobject.py index 49a07f627b7..31a4c7aa6cd 100644 --- a/src/compas_rhino/artists/meshartist.py +++ b/src/compas_rhino/scene/meshobject.py @@ -12,7 +12,7 @@ from compas.geometry import Sphere import compas_rhino -from compas.artists import MeshArtist as BaseArtist +from compas.scene import MeshObject as BaseMeshObject from compas.colors import Color from compas_rhino.conversions import vertices_and_faces_to_rhino from compas_rhino.conversions import mesh_to_rhino @@ -21,17 +21,17 @@ from compas_rhino.conversions import cylinder_to_rhino_brep from compas_rhino.conversions import sphere_to_rhino from compas_rhino.conversions import transformation_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes from ._helpers import ngon -class MeshArtist(RhinoArtist, BaseArtist): - """Artists for drawing mesh data structures. +class MeshObject(RhinoSceneObject, BaseMeshObject): + """Scene object for drawing mesh data structures. Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + mesh : :class:`compas.datastructures.Mesh` A COMPAS mesh. **kwargs : dict, optional Additional keyword arguments. @@ -39,14 +39,14 @@ class MeshArtist(RhinoArtist, BaseArtist): """ def __init__(self, mesh, **kwargs): - super(MeshArtist, self).__init__(mesh=mesh, **kwargs) + super(MeshObject, self).__init__(mesh=mesh, **kwargs) # ========================================================================== # clear # ========================================================================== def clear(self): - """Delete all objects drawn by this artist. + """Delete all objects drawn by this scene object. Returns ------- @@ -57,7 +57,7 @@ def clear(self): compas_rhino.delete_objects(guids, purge=True) def clear_vertices(self): - """Delete all vertices drawn by this artist. + """Delete all vertices drawn by this scene object. Returns ------- @@ -68,7 +68,7 @@ def clear_vertices(self): compas_rhino.delete_objects(guids, purge=True) def clear_edges(self): - """Delete all edges drawn by this artist. + """Delete all edges drawn by this scene object. Returns ------- @@ -79,7 +79,7 @@ def clear_edges(self): compas_rhino.delete_objects(guids, purge=True) def clear_faces(self): - """Delete all faces drawn by this artist. + """Delete all faces drawn by this scene object. Returns ------- @@ -90,7 +90,7 @@ def clear_faces(self): compas_rhino.delete_objects(guids, purge=True) def clear_vertexnormals(self): - """Delete all vertex normals drawn by this artist. + """Delete all vertex normals drawn by this scene object. Returns ------- @@ -101,7 +101,7 @@ def clear_vertexnormals(self): compas_rhino.delete_objects(guids, purge=True) def clear_facenormals(self): - """Delete all face normals drawn by this artist. + """Delete all face normals drawn by this scene object. Returns ------- @@ -112,7 +112,7 @@ def clear_facenormals(self): compas_rhino.delete_objects(guids, purge=True) def clear_vertexlabels(self): - """Delete all vertex labels drawn by this artist. + """Delete all vertex labels drawn by this scene object. Returns ------- @@ -123,7 +123,7 @@ def clear_vertexlabels(self): compas_rhino.delete_objects(guids, purge=True) def clear_edgelabels(self): - """Delete all edge labels drawn by this artist. + """Delete all edge labels drawn by this scene object. Returns ------- @@ -134,7 +134,7 @@ def clear_edgelabels(self): compas_rhino.delete_objects(guids, purge=True) def clear_facelabels(self): - """Delete all face labels drawn by this artist. + """Delete all face labels drawn by this scene object. Returns ------- @@ -155,7 +155,7 @@ def draw(self, color=None, vertexcolors=None, facecolors=None, disjoint=False): ---------- color : tuple[int, int, int], optional The color of the mesh. - Default is the value of :attr:`MeshArtist.default_color`. + Default is the value of :attr:`MeshObject.default_color`. disjoint : bool, optional If True, draw the faces of the mesh with disjoint vertices. @@ -200,7 +200,7 @@ def draw_vertices(self, vertices=None, color=None, group=None): vertices : list[int], optional A selection of vertices to draw. Default is None, in which case all vertices are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the vertices. group : str, optional The name of a group to join the created Rhino objects in. @@ -238,7 +238,7 @@ def draw_edges(self, edges=None, color=None, text=None, fontheight=10, fontface= edges : list[tuple[int, int]], optional A selection of edges to draw. The default is None, in which case all edges are drawn. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color of the edges. text : dict[tuple[int, int], str], optional A dictionary of edge labels as edge-text pairs. @@ -280,7 +280,7 @@ def draw_faces(self, faces=None, color=None, group=None): faces : list[int], optional A selection of faces to draw. The default is None, in which case all faces are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the faces. text : dict[int, str], optional A dictionary of face labels as face-text pairs. @@ -327,7 +327,7 @@ def draw_vertexlabels(self, text, color=None, group=None, fontheight=10, fontfac ---------- text : dict[int, str] A dictionary of vertex labels as vertex-text pairs. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the vertex labels. group : str, optional The name of a group to join the created Rhino objects in. @@ -372,7 +372,7 @@ def draw_edgelabels(self, text, color=None, group=None, fontheight=10, fontface= ---------- text : dict[tuple[int, int], str] A dictionary of edge labels as edge-text pairs. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color of the edge labels. group : str, optional The name of a group to join the created Rhino objects in. @@ -418,7 +418,7 @@ def draw_facelabels(self, text, color=None, group=None, fontheight=10, fontface= ---------- text : dict[int, str] A dictionary of face labels as face-text pairs. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the face labels. group : str, optional The name of a group to join the created Rhino objects in. @@ -467,7 +467,7 @@ def draw_vertexnormals(self, vertices=None, color=(0, 255, 0), scale=1.0, group= vertices : list[int], optional A selection of vertex normals to draw. Default is to draw all vertex normals. - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The color specification of the normal vectors. scale : float, optional Scale factor for the vertex normals. @@ -507,7 +507,7 @@ def draw_facenormals(self, faces=None, color=(0, 255, 255), scale=1.0, group=Non faces : list[int], optional A selection of face normals to draw. Default is to draw all face normals. - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color`, optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color`, optional The color specification of the normal vectors. scale : float, optional Scale factor for the face normals. @@ -550,7 +550,7 @@ def draw_spheres(self, radius, color=None, group=None): ---------- radius : dict[int, float], optional The radius of the spheres. - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the spheres. group : str, optional The name of a group to join the created Rhino objects in. @@ -588,7 +588,7 @@ def draw_pipes(self, radius, color=None, group=None): ---------- radius : dict[tuple[int, int], float] The radius per edge. - color : tuple[int, int, int] | tuple[float, float, float] | :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : tuple[int, int, int] | tuple[float, float, float] | :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color of the pipes. group : str, optional The name of a group to join the created Rhino objects in. diff --git a/src/compas_rhino/artists/networkartist.py b/src/compas_rhino/scene/networkobject.py similarity index 89% rename from src/compas_rhino/artists/networkartist.py rename to src/compas_rhino/scene/networkobject.py index 7cd757bfa68..1bad68c82ba 100644 --- a/src/compas_rhino/artists/networkartist.py +++ b/src/compas_rhino/scene/networkobject.py @@ -9,21 +9,21 @@ from compas.geometry import Line from compas.geometry import Cylinder from compas.geometry import Sphere -from compas.artists import NetworkArtist as BaseArtist +from compas.scene import NetworkObject as BaseNetworkObject from compas_rhino.conversions import point_to_rhino from compas_rhino.conversions import line_to_rhino from compas_rhino.conversions import sphere_to_rhino from compas_rhino.conversions import cylinder_to_rhino_brep -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class NetworkArtist(RhinoArtist, BaseArtist): - """Artist for drawing network data structures. +class NetworkObject(RhinoSceneObject, BaseNetworkObject): + """Scene object for drawing network data structures. Parameters ---------- - network : :class:`~compas.datastructures.Network` + network : :class:`compas.datastructures.Network` A COMPAS network. **kwargs : dict, optional Additional keyword arguments. @@ -31,14 +31,14 @@ class NetworkArtist(RhinoArtist, BaseArtist): """ def __init__(self, network, **kwargs): - super(NetworkArtist, self).__init__(network=network, **kwargs) + super(NetworkObject, self).__init__(network=network, **kwargs) # ========================================================================== # clear # ========================================================================== def clear(self): - """Delete all objects drawn by this artist. + """Delete all objects drawn by this scene object. Returns ------- @@ -49,7 +49,7 @@ def clear(self): compas_rhino.delete_objects(guids, purge=True) def clear_nodes(self): - """Delete all nodes drawn by this artist. + """Delete all nodes drawn by this scene object. Returns ------- @@ -60,7 +60,7 @@ def clear_nodes(self): compas_rhino.delete_objects(guids, purge=True) def clear_edges(self): - """Delete all edges drawn by this artist. + """Delete all edges drawn by this scene object. Returns ------- @@ -91,9 +91,9 @@ def draw( edges : list[tuple[int, int]], optional A list of edges to draw. The default is None, in which case all edges are drawn. - nodecolor : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + nodecolor : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the nodes. - edgecolor : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + edgecolor : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color of the edges. Returns @@ -115,7 +115,7 @@ def draw_nodes(self, nodes=None, color=None, group=None): nodes : list[int], optional A list of nodes to draw. Default is None, in which case all nodes are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional Color of the nodes. Returns @@ -150,7 +150,7 @@ def draw_edges(self, edges=None, color=None, group=None, show_direction=False): edges : list[tuple[int, int]], optional A list of edges to draw. The default is None, in which case all edges are drawn. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional Color of the edges. group : str, optional The name of a group to add the edges to. @@ -196,7 +196,7 @@ def draw_nodelabels(self, text, color=None, group=None, fontheight=10, fontface= ---------- text : dict[int, str] A dictionary of node labels as node-text pairs. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional Color of the labels. group : str, optional The name of a group to add the labels to. @@ -240,7 +240,7 @@ def draw_edgelabels(self, text, color=None, group=None, fontheight=10, fontface= ---------- text : dict[tuple[int, int], str] A dictionary of edge labels as edge-text pairs. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional Color of the labels. group : str, optional The name of a group to add the labels to. @@ -292,7 +292,7 @@ def draw_spheres(self, radius, color=None, group=None): ---------- radius : dict[int, float], optional The radius of the spheres. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the spheres. group : str, optional The name of a group to join the created Rhino objects in. @@ -330,7 +330,7 @@ def draw_pipes(self, radius, color=None, group=None): ---------- radius : dict[tuple[int, int], float] The radius per edge. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color of the pipes. group : str, optional The name of a group to join the created Rhino objects in. diff --git a/src/compas_rhino/artists/planeartist.py b/src/compas_rhino/scene/planeobject.py similarity index 63% rename from src/compas_rhino/artists/planeartist.py rename to src/compas_rhino/scene/planeobject.py index b5eb788fb51..fa4e8967dd7 100644 --- a/src/compas_rhino/artists/planeartist.py +++ b/src/compas_rhino/scene/planeobject.py @@ -2,16 +2,16 @@ from __future__ import absolute_import from __future__ import division -from compas.artists import GeometryArtist -from .artist import RhinoArtist +from compas.scene import GeometryObject +from .sceneobject import RhinoSceneObject -class PlaneArtist(RhinoArtist, GeometryArtist): - """Artist for drawing planes. +class PlaneObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing planes. Parameters ---------- - plane : :class:`~compas.geometry.Plane` + plane : :class:`compas.geometry.Plane` A COMPAS plane. **kwargs : dict, optional Additional keyword arguments. @@ -19,7 +19,7 @@ class PlaneArtist(RhinoArtist, GeometryArtist): """ def __init__(self, plane, **kwargs): - super(PlaneArtist, self).__init__(geometry=plane, **kwargs) + super(PlaneObject, self).__init__(geometry=plane, **kwargs) def draw(self): """Draw the plane. diff --git a/src/compas_rhino/artists/pointartist.py b/src/compas_rhino/scene/pointobject.py similarity index 57% rename from src/compas_rhino/artists/pointartist.py rename to src/compas_rhino/scene/pointobject.py index caf0c8f09ef..5a7655aa755 100644 --- a/src/compas_rhino/artists/pointartist.py +++ b/src/compas_rhino/scene/pointobject.py @@ -4,19 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import point_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class PointArtist(RhinoArtist, GeometryArtist): - """Artist for drawing points. +class PointObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing points. Parameters ---------- - point : :class:`~compas.geometry.Point` + point : :class:`compas.geometry.Point` A COMPAS point. **kwargs : dict, optional Additional keyword arguments. @@ -24,14 +25,14 @@ class PointArtist(RhinoArtist, GeometryArtist): """ def __init__(self, point, **kwargs): - super(PointArtist, self).__init__(geometry=point, **kwargs) + super(PointObject, self).__init__(geometry=point, **kwargs) def draw(self, color=None): """Draw the point. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the point. Returns @@ -42,4 +43,7 @@ def draw(self, color=None): """ color = Color.coerce(color) or self.color attr = attributes(name=self.geometry.name, color=color, layer=self.layer) - return sc.doc.Objects.AddPoint(point_to_rhino(self.geometry), attr) + geometry = point_to_rhino(self.geometry) + if self.transformation: + geometry.Transform(transformation_to_rhino(self.transformation)) + return sc.doc.Objects.AddPoint(geometry, attr) diff --git a/src/compas_rhino/artists/polygonartist.py b/src/compas_rhino/scene/polygonobject.py similarity index 77% rename from src/compas_rhino/artists/polygonartist.py rename to src/compas_rhino/scene/polygonobject.py index 476107cda13..68520e648b3 100644 --- a/src/compas_rhino/artists/polygonartist.py +++ b/src/compas_rhino/scene/polygonobject.py @@ -4,21 +4,22 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import point_to_rhino from compas_rhino.conversions import line_to_rhino from compas_rhino.conversions import vertices_and_faces_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class PolygonArtist(RhinoArtist, GeometryArtist): - """Artist for drawing polygons. +class PolygonObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing polygons. Parameters ---------- - polygon : :class:`~compas.geometry.Polygon` + polygon : :class:`compas.geometry.Polygon` A COMPAS polygon. **kwargs : dict, optional Additional keyword arguments. @@ -26,14 +27,14 @@ class PolygonArtist(RhinoArtist, GeometryArtist): """ def __init__(self, polygon, **kwargs): - super(PolygonArtist, self).__init__(geometry=polygon, **kwargs) + super(PolygonObject, self).__init__(geometry=polygon, **kwargs) def draw(self, color=None): """Draw the polygon. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the polygon. Returns @@ -48,6 +49,8 @@ def draw(self, color=None): vertices = self.geometry.points faces = self.geometry.faces mesh = vertices_and_faces_to_rhino(vertices, faces) + if self.transformation: + mesh.Transform(transformation_to_rhino(self.transformation)) return sc.doc.Objects.AddMesh(mesh, attr) @@ -56,7 +59,7 @@ def draw_vertices(self, color=None): Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the polygon vertices. Returns @@ -81,7 +84,7 @@ def draw_edges(self, color=None): Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the polygon edges. Returns diff --git a/src/compas_rhino/artists/polyhedronartist.py b/src/compas_rhino/scene/polyhedronobject.py similarity index 56% rename from src/compas_rhino/artists/polyhedronartist.py rename to src/compas_rhino/scene/polyhedronobject.py index 886efa2d07a..fa10f2dbd48 100644 --- a/src/compas_rhino/artists/polyhedronartist.py +++ b/src/compas_rhino/scene/polyhedronobject.py @@ -4,19 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import vertices_and_faces_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class PolyhedronArtist(RhinoArtist, GeometryArtist): - """Artist for drawing polyhedron shapes. +class PolyhedronObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing polyhedron shapes. Parameters ---------- - polyhedron : :class:`~compas.geometry.Polyhedron` + polyhedron : :class:`compas.geometry.Polyhedron` A COMPAS polyhedron. **kwargs : dict, optional Additional keyword arguments. @@ -24,14 +25,14 @@ class PolyhedronArtist(RhinoArtist, GeometryArtist): """ def __init__(self, polyhedron, **kwargs): - super(PolyhedronArtist, self).__init__(geometry=polyhedron, **kwargs) + super(PolyhedronObject, self).__init__(geometry=polyhedron, **kwargs) def draw(self, color=None): - """Draw the polyhedron associated with the artist. + """Draw the polyhedron associated with the scene object. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the polyhedron. Returns @@ -45,5 +46,8 @@ def draw(self, color=None): vertices = [list(vertex) for vertex in self.geometry.vertices] faces = self.geometry.faces + geometry = vertices_and_faces_to_rhino(vertices, faces) + if self.transformation: + geometry.Transform(transformation_to_rhino(self.transformation)) - return sc.doc.Objects.AddMesh(vertices_and_faces_to_rhino(vertices, faces), attr) + return sc.doc.Objects.AddMesh(geometry, attr) diff --git a/src/compas_rhino/artists/polylineartist.py b/src/compas_rhino/scene/polylineobject.py similarity index 68% rename from src/compas_rhino/artists/polylineartist.py rename to src/compas_rhino/scene/polylineobject.py index 4c3f12c3568..b783d4543e8 100644 --- a/src/compas_rhino/artists/polylineartist.py +++ b/src/compas_rhino/scene/polylineobject.py @@ -4,20 +4,21 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import point_to_rhino from compas_rhino.conversions import polyline_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class PolylineArtist(RhinoArtist, GeometryArtist): - """Artist for drawing polylines. +class PolylineObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing polylines. Parameters ---------- - polyline : :class:`~compas.geometry.Polyline` + polyline : :class:`compas.geometry.Polyline` A COMPAS polyline. **kwargs : dict, optional Additional keyword arguments. @@ -25,14 +26,14 @@ class PolylineArtist(RhinoArtist, GeometryArtist): """ def __init__(self, polyline, **kwargs): - super(PolylineArtist, self).__init__(geometry=polyline, **kwargs) + super(PolylineObject, self).__init__(geometry=polyline, **kwargs) def draw(self, color=None): """Draw the polyline. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the polyline. Returns @@ -43,15 +44,18 @@ def draw(self, color=None): """ color = Color.coerce(color) or self.color attr = attributes(name=self.geometry.name, color=color, layer=self.layer) + geometry = polyline_to_rhino(self.geometry) + if self.transformation: + geometry.Transform(transformation_to_rhino(self.transformation)) - return sc.doc.Objects.AddPolyline(polyline_to_rhino(self.geometry), attr) + return sc.doc.Objects.AddPolyline(geometry, attr) def draw_points(self, color=None): """Draw the polyline points. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the polyline points. Returns diff --git a/src/compas_rhino/artists/artist.py b/src/compas_rhino/scene/sceneobject.py similarity index 86% rename from src/compas_rhino/artists/artist.py rename to src/compas_rhino/scene/sceneobject.py index 8ce1a31937e..5afb195b79e 100644 --- a/src/compas_rhino/artists/artist.py +++ b/src/compas_rhino/scene/sceneobject.py @@ -5,11 +5,11 @@ import scriptcontext as sc # type: ignore import compas_rhino -from compas.artists import Artist +from compas.scene import SceneObject -class RhinoArtist(Artist): - """Base class for all Rhino artists. +class RhinoSceneObject(SceneObject): + """Base class for all Rhino scene objects. Parameters ---------- @@ -21,7 +21,7 @@ class RhinoArtist(Artist): """ def __init__(self, layer=None, **kwargs): - super(RhinoArtist, self).__init__(**kwargs) + super(RhinoSceneObject, self).__init__(**kwargs) self.layer = layer def get_group(self, name): @@ -64,7 +64,7 @@ def add_to_group(self, name, guids): sc.doc.Groups.AddToGroup(group.Index, guids) def clear_layer(self): - """Clear the layer of the artist. + """Clear the layer of the scene object. Returns ------- diff --git a/src/compas_rhino/artists/sphereartist.py b/src/compas_rhino/scene/sphereobject.py similarity index 53% rename from src/compas_rhino/artists/sphereartist.py rename to src/compas_rhino/scene/sphereobject.py index 58c8891dd08..d5e5cb27412 100644 --- a/src/compas_rhino/artists/sphereartist.py +++ b/src/compas_rhino/scene/sphereobject.py @@ -4,19 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import sphere_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class SphereArtist(RhinoArtist, GeometryArtist): - """Artist for drawing sphere shapes. +class SphereObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing sphere shapes. Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + sphere : :class:`compas.geometry.Sphere` A COMPAS sphere. **kwargs : dict, optional Additional keyword arguments. @@ -24,14 +25,14 @@ class SphereArtist(RhinoArtist, GeometryArtist): """ def __init__(self, sphere, **kwargs): - super(SphereArtist, self).__init__(geometry=sphere, **kwargs) + super(SphereObject, self).__init__(geometry=sphere, **kwargs) def draw(self, color=None): - """Draw the sphere associated with the artist. + """Draw the sphere associated with the scene object. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the sphere. Returns @@ -42,4 +43,8 @@ def draw(self, color=None): """ color = Color.coerce(color) or self.color attr = attributes(name=self.geometry.name, color=color, layer=self.layer) - return sc.doc.Objects.AddSphere(sphere_to_rhino(self.geometry), attr) + geometry = sphere_to_rhino(self.geometry) + if self.transformation: + geometry.Transform(transformation_to_rhino(self.transformation)) + + return sc.doc.Objects.AddSphere(geometry, attr) diff --git a/src/compas_rhino/artists/surfaceartist.py b/src/compas_rhino/scene/surfaceobject.py similarity index 64% rename from src/compas_rhino/artists/surfaceartist.py rename to src/compas_rhino/scene/surfaceobject.py index 6572d4b06a5..a49bf2dccf6 100644 --- a/src/compas_rhino/artists/surfaceartist.py +++ b/src/compas_rhino/scene/surfaceobject.py @@ -4,19 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import surface_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class SurfaceArtist(RhinoArtist, GeometryArtist): - """Artist for drawing surfaces. +class SurfaceObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing surfaces. Parameters ---------- - surface : :class:`~compas.geometry.Geometry` + surface : :class:`compas.geometry.Geometry` A COMPAS surface. **kwargs : dict, optional Additional keyword arguments. @@ -24,14 +25,14 @@ class SurfaceArtist(RhinoArtist, GeometryArtist): """ def __init__(self, surface, **kwargs): - super(SurfaceArtist, self).__init__(geometry=surface, **kwargs) + super(SurfaceObject, self).__init__(geometry=surface, **kwargs) def draw(self, color=None): """Draw the surface. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the surface. Returns @@ -43,4 +44,6 @@ def draw(self, color=None): color = Color.coerce(color) or self.color attr = attributes(name=self.geometry.name, color=color, layer=self.layer) surface = surface_to_rhino(self.geometry) + if self.transformation: + surface.Transform(transformation_to_rhino(self.transformation)) return sc.doc.Objects.AddSurface(surface, attr) diff --git a/src/compas_rhino/artists/torusartist.py b/src/compas_rhino/scene/torusobject.py similarity index 61% rename from src/compas_rhino/artists/torusartist.py rename to src/compas_rhino/scene/torusobject.py index 53247b91135..662fb802040 100644 --- a/src/compas_rhino/artists/torusartist.py +++ b/src/compas_rhino/scene/torusobject.py @@ -4,19 +4,20 @@ import scriptcontext as sc # type: ignore -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import torus_to_rhino_brep -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class TorusArtist(RhinoArtist, GeometryArtist): - """Artist for drawing torus shapes. +class TorusObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing torus shapes. Parameters ---------- - torus : :class:`~compas.geometry.Torus` + torus : :class:`compas.geometry.Torus` A COMPAS torus. **kwargs : dict, optional Additional keyword arguments. @@ -24,14 +25,14 @@ class TorusArtist(RhinoArtist, GeometryArtist): """ def __init__(self, torus, **kwargs): - super(TorusArtist, self).__init__(geometry=torus, **kwargs) + super(TorusObject, self).__init__(geometry=torus, **kwargs) def draw(self, color=None): - """Draw the torus associated with the artist. + """Draw the torus associated with the scene object. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the torus. Returns @@ -43,4 +44,7 @@ def draw(self, color=None): color = Color.coerce(color) or self.color attr = attributes(name=self.geometry.name, color=color, layer=self.layer) brep = torus_to_rhino_brep(self.geometry) + if self.transformation: + brep.Transform(transformation_to_rhino(self.transformation)) + return sc.doc.Objects.AddBrep(brep, attr) diff --git a/src/compas_rhino/artists/vectorartist.py b/src/compas_rhino/scene/vectorobject.py similarity index 55% rename from src/compas_rhino/artists/vectorartist.py rename to src/compas_rhino/scene/vectorobject.py index 484a41820fa..9f68a13c362 100644 --- a/src/compas_rhino/artists/vectorartist.py +++ b/src/compas_rhino/scene/vectorobject.py @@ -5,19 +5,20 @@ import scriptcontext as sc # type: ignore from compas.geometry import Point -from compas.artists import GeometryArtist +from compas.scene import GeometryObject from compas.colors import Color from compas_rhino.conversions import point_to_rhino -from .artist import RhinoArtist +from compas_rhino.conversions import transformation_to_rhino +from .sceneobject import RhinoSceneObject from ._helpers import attributes -class VectorArtist(RhinoArtist, GeometryArtist): - """Artist for drawing vectors. +class VectorObject(RhinoSceneObject, GeometryObject): + """Scene object for drawing vectors. Parameters ---------- - vector : :class:`~compas.geometry.Vector` + vector : :class:`compas.geometry.Vector` A COMPAS vector. **kwargs : dict, optional Additional keyword arguments. @@ -25,16 +26,16 @@ class VectorArtist(RhinoArtist, GeometryArtist): """ def __init__(self, vector, **kwargs): - super(VectorArtist, self).__init__(geometry=vector, **kwargs) + super(VectorObject, self).__init__(geometry=vector, **kwargs) def draw(self, color=None, point=None): """Draw the vector. Parameters ---------- - color : rgb1 | rgb255 | :class:`~compas.colors.Color`, optional + color : rgb1 | rgb255 | :class:`compas.colors.Color`, optional The RGB color of the vector. - point : [float, float, float] | :class:`~compas.geometry.Point`, optional + point : [float, float, float] | :class:`compas.geometry.Point`, optional Point of application of the vector. Default is ``Point(0, 0, 0)``. @@ -50,5 +51,11 @@ def draw(self, color=None, point=None): point = point or [0, 0, 0] start = Point(*point) end = start + self.geometry - - return sc.doc.Objects.AddLine(point_to_rhino(start), point_to_rhino(end), attr) + start_geometry = point_to_rhino(start) + end_geometry = point_to_rhino(end) + if self.transformation: + transformation = transformation_to_rhino(self.transformation) + start_geometry.Transform(transformation) + end_geometry.Transform(transformation) + + return sc.doc.Objects.AddLine(start_geometry, end_geometry, attr) diff --git a/src/compas_rhino/artists/volmeshartist.py b/src/compas_rhino/scene/volmeshobject.py similarity index 89% rename from src/compas_rhino/artists/volmeshartist.py rename to src/compas_rhino/scene/volmeshobject.py index 6ebc9aca6cc..40c5bfdce3b 100644 --- a/src/compas_rhino/artists/volmeshartist.py +++ b/src/compas_rhino/scene/volmeshobject.py @@ -8,21 +8,21 @@ import compas_rhino from compas.geometry import centroid_points from compas.geometry import Line -from compas.artists import VolMeshArtist as BaseArtist +from compas.scene import VolMeshObject as BaseVolMeshObject from compas_rhino.conversions import point_to_rhino from compas_rhino.conversions import line_to_rhino from compas_rhino.conversions import vertices_and_faces_to_rhino -from .artist import RhinoArtist +from .sceneobject import RhinoSceneObject from ._helpers import attributes from ._helpers import ngon -class VolMeshArtist(RhinoArtist, BaseArtist): - """Artist for drawing volmesh data structures. +class VolMeshObject(RhinoSceneObject, BaseVolMeshObject): + """Scene object for drawing volmesh data structures. Parameters ---------- - volmesh : :class:`~compas.datastructures.VolMesh` + volmesh : :class:`compas.datastructures.VolMesh` A COMPAS volmesh. **kwargs : dict, optional Additional keyword arguments. @@ -30,14 +30,14 @@ class VolMeshArtist(RhinoArtist, BaseArtist): """ def __init__(self, volmesh, **kwargs): - super(VolMeshArtist, self).__init__(volmesh=volmesh, **kwargs) + super(VolMeshObject, self).__init__(volmesh=volmesh, **kwargs) # ========================================================================== # clear # ========================================================================== def clear(self): - """Delete all objects drawn by this artist. + """Delete all objects drawn by this scene object. Returns ------- @@ -48,7 +48,7 @@ def clear(self): compas_rhino.delete_objects(guids, purge=True) def clear_vertices(self): - """Delete all vertices drawn by this artist. + """Delete all vertices drawn by this scene object. Returns ------- @@ -59,7 +59,7 @@ def clear_vertices(self): compas_rhino.delete_objects(guids, purge=True) def clear_edges(self): - """Delete all edges drawn by this artist. + """Delete all edges drawn by this scene object. Returns ------- @@ -70,7 +70,7 @@ def clear_edges(self): compas_rhino.delete_objects(guids, purge=True) def clear_faces(self): - """Delete all faces drawn by this artist. + """Delete all faces drawn by this scene object. Returns ------- @@ -81,7 +81,7 @@ def clear_faces(self): compas_rhino.delete_objects(guids, purge=True) def clear_cells(self): - """Delete all cells drawn by this artist. + """Delete all cells drawn by this scene object. Returns ------- @@ -92,7 +92,7 @@ def clear_cells(self): compas_rhino.delete_objects(guids, purge=True) def clear_vertexlabels(self): - """Delete all vertex labels drawn by this artist. + """Delete all vertex labels drawn by this scene object. Returns ------- @@ -103,7 +103,7 @@ def clear_vertexlabels(self): compas_rhino.delete_objects(guids, purge=True) def clear_edgelabels(self): - """Delete all edge labels drawn by this artist. + """Delete all edge labels drawn by this scene object. Returns ------- @@ -114,7 +114,7 @@ def clear_edgelabels(self): compas_rhino.delete_objects(guids, purge=True) def clear_facelabels(self): - """Delete all face labels drawn by this artist. + """Delete all face labels drawn by this scene object. Returns ------- @@ -136,9 +136,9 @@ def draw(self, cells=None, color=None): cells : list[int], optional A list of cells to draw. The default is None, in which case all cells are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the cells. - The default color is :attr:`VolMeshArtist.default_cellcolor`. + The default color is :attr:`VolMeshObject.default_cellcolor`. Returns ------- @@ -157,7 +157,7 @@ def draw_vertices(self, vertices=None, color=None, group=None): vertices : list[int], optional A list of vertices to draw. Default is None, in which case all vertices are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the vertices. group : str, optional The name of the group in which the vertices are combined. @@ -192,7 +192,7 @@ def draw_edges(self, edges=None, color=None, group=None): edges : list[tuple[int, int]], optional A list of edges to draw. The default is None, in which case all edges are drawn. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color of the edges. group : str, optional The name of the group in which the edges are combined. @@ -230,7 +230,7 @@ def draw_faces(self, faces=None, color=None, group=None): faces : list[int], optional A list of faces to draw. The default is None, in which case all faces are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the faces. group : str, optional The name of the group in which the faces are combined. @@ -270,7 +270,7 @@ def draw_cells(self, cells=None, color=None, group=None): cells : list[int], optional A list of cells to draw. The default is None, in which case all cells are drawn. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the cells. group : str, optional The name of the group in which the cells are combined. @@ -313,7 +313,7 @@ def draw_vertexlabels(self, text, color=None, group=None, fontheight=10, fontfac ---------- text : dict[int, str] A dictionary of vertex labels as vertex-text pairs. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the vertices. group : str, optional The name of the group in which the labels are combined. @@ -358,7 +358,7 @@ def draw_edgelabels(self, text, color=None, group=None, fontheight=10, fontface= ---------- text : dict[tuple[int, int], str], optional A dictionary of edge labels as edge-text pairs. - color : :class:`~compas.colors.Color` | dict[tuple[int, int], :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[tuple[int, int], :class:`compas.colors.Color`], optional The color of the edges. group : str, optional The name of the group in which the labels are combined. @@ -404,7 +404,7 @@ def draw_facelabels(self, text, color=None, group=None, fontheight=10, fontface= ---------- text : dict[int, str] A dictionary of face labels as face-text pairs. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the faces. group : str, optional The name of the group in which the labels are combined. @@ -450,7 +450,7 @@ def draw_celllabels(self, text, color=None, group=None, fontheight=10, fontface= ---------- text : dict[int, str], optional A dictionary of face labels as cell-text pairs. - color : :class:`~compas.colors.Color` | dict[int, :class:`~compas.colors.Color`], optional + color : :class:`compas.colors.Color` | dict[int, :class:`compas.colors.Color`], optional The color of the cells. group : str, optional The name of the group in which the labels are combined. diff --git a/src/compas_rhino/utilities/constructors.py b/src/compas_rhino/utilities/constructors.py index 0fabf73eea4..8b99c03a302 100644 --- a/src/compas_rhino/utilities/constructors.py +++ b/src/compas_rhino/utilities/constructors.py @@ -16,7 +16,7 @@ def volmesh_from_polysurfaces(cls, guids, precision=None): Parameters ---------- - cls : :class:`~compas.datastructures.VolMesh` + cls : :class:`compas.datastructures.VolMesh` The class of volmesh. guids : sequence[str | System.Guid] The *globally unique identifiers* of the polysurfaces. @@ -25,7 +25,7 @@ def volmesh_from_polysurfaces(cls, guids, precision=None): Returns ------- - :class:`~compas.datastructures.Volmesh` + :class:`compas.datastructures.Volmesh` The volumetric mesh object. Notes diff --git a/src/compas_rhino/utilities/drawing.py b/src/compas_rhino/utilities/drawing.py index 89e9337b9fc..55dacf498b6 100644 --- a/src/compas_rhino/utilities/drawing.py +++ b/src/compas_rhino/utilities/drawing.py @@ -756,7 +756,7 @@ def draw_mesh(vertices, faces, name=None, color=None, vertex_color=None, disjoin Parameters ---------- - vertices : list[[float, float, float] | :class:`~compas.geometry.Point`] + vertices : list[[float, float, float] | :class:`compas.geometry.Point`] A list of point locations. faces : list[list[int]] A list of faces as lists of indices into `vertices`. @@ -1080,7 +1080,7 @@ def draw_brep(brep, color=None, **kwargs): Parameters ---------- - brep : :class:`~compas_rhino.geometry.RhinoBrep` + brep : :class:`compas_rhino.geometry.RhinoBrep` The brep to draw. color : tuple[int, int, int] | tuple[float, float, float], optional The color to draw the brep with. diff --git a/tests/compas/artists/test_artists.py b/tests/compas/artists/test_artists.py deleted file mode 100644 index b6f693978bc..00000000000 --- a/tests/compas/artists/test_artists.py +++ /dev/null @@ -1,110 +0,0 @@ -import pytest # noqa: F401 - -import compas -from compas.artists import Artist -from compas.artists.artist import NoArtistContextError - - -if not compas.IPY: - - @pytest.fixture(autouse=True) - def reset_artists(): - # before each test - yield - # after each test, reset artists - Artist.ITEM_ARTIST.clear() - Artist._Artist__ARTISTS_REGISTERED = False # type: ignore - - -def register_fake_context(): - Artist.register(FakeItem, FakeArtist, context="fake") - - -class FakeArtist(Artist): - def draw(self): - pass - - -class FakeSubArtist(Artist): - def draw(self): - pass - - -class FakeItem(object): - pass - - -class FakeSubItem(FakeItem): - pass - - -def test_get_artist_cls_with_orderly_registration(): - Artist.register(FakeItem, FakeArtist, context="fake") - Artist.register(FakeSubItem, FakeSubArtist, context="fake") - item = FakeItem() - artist = Artist(item, context="fake") - assert isinstance(artist, FakeArtist) - - item = FakeSubItem() - artist = Artist(item, context="fake") - assert isinstance(artist, FakeSubArtist) - - -def test_get_artist_cls_with_out_of_order_registration(): - Artist.register(FakeSubItem, FakeSubArtist, context="fake") - Artist.register(FakeItem, FakeArtist, context="fake") - item = FakeItem() - artist = Artist(item, context="fake") - assert isinstance(artist, FakeArtist) - - item = FakeSubItem() - artist = Artist(item, context="fake") - assert isinstance(artist, FakeSubArtist) - - -if not compas.IPY: - - def test_artist_auto_context_discovery(mocker): - mocker.patch("compas.artists.Artist.register_artists") - Artist.register_artists.side_effect = register_fake_context - Artist._Artist__ARTISTS_REGISTERED = False # type: ignore - - item = FakeItem() - artist = Artist(item) - - assert isinstance(artist, FakeArtist) - - def test_artist_auto_context_discovery_viewer(mocker): - mocker.patch("compas.artists.artist.is_viewer_open", return_value=True) - Artist.ITEM_ARTIST["Viewer"] = {FakeItem: FakeArtist} - - item = FakeSubItem() - artist = Artist(item) - - assert isinstance(artist, FakeArtist) - - def test_artist_auto_context_discovery_viewer_priority(mocker): - mocker.patch("compas.artists.artist.is_viewer_open", return_value=True) - - class FakeViewerArtist(FakeArtist): - pass - - class FakePlotterArtist(FakeArtist): - pass - - Artist.ITEM_ARTIST["Viewer"] = {FakeItem: FakeViewerArtist} - Artist.ITEM_ARTIST["Plotter"] = {FakeItem: FakePlotterArtist} - - item = FakeSubItem() - artist = Artist(item) - - assert isinstance(artist, FakeViewerArtist) - - def test_artist_auto_context_discovery_no_context(mocker): - mocker.patch("compas.artists.artist.is_viewer_open", return_value=False) - mocker.patch("compas.artists.artist.compas.is_grasshopper", return_value=False) - mocker.patch("compas.artists.artist.compas.is_rhino", return_value=False) - - with pytest.raises(NoArtistContextError): - item = FakeSubItem() - _ = Artist(item) diff --git a/tests/compas/data/test_json.py b/tests/compas/data/test_json.py index 00ed3e05992..7fed88be666 100644 --- a/tests/compas/data/test_json.py +++ b/tests/compas/data/test_json.py @@ -27,7 +27,7 @@ def test_json_shape(): before = Box(frame=Frame(Point(0, 0, 0), Vector(1, 0, 0), Vector(0, 1, 0)), xsize=1, ysize=1, zsize=1) after = compas.json_loads(compas.json_dumps(before)) assert before.dtype == after.dtype - assert all(a == b for a, b in zip(before.vertices, after.vertices)) + assert all(a == b for a, b in zip(before.to_vertices_and_faces()[0], after.to_vertices_and_faces()[0])) assert before.guid == after.guid diff --git a/tests/compas/data/test_validators.py b/tests/compas/data/test_validators.py index 8516aad53ae..0c10fd4ef73 100644 --- a/tests/compas/data/test_validators.py +++ b/tests/compas/data/test_validators.py @@ -1,135 +1,135 @@ -import compas -import pytest - -from compas.data import is_sequence_of_int -from compas.data import is_sequence_of_uint -from compas.data import is_sequence_of_float - -from compas.data import is_int3 -from compas.data import is_float3 -from compas.data import is_float4x4 - - -@pytest.mark.parametrize( - "sequence,result", - [ - (range(10), True), - (range(+10, -10, -1), True), - (list(range(10)), True), - (list(range(+10, -10, -1)), True), - ([1, 2, 3, 4.0], False), - ([1, 2, "3"], False), - ([], True), - ], -) -def test_is_sequence_of_int(sequence, result): - assert is_sequence_of_int(sequence) is result - - -@pytest.mark.parametrize( - "sequence,result", - [ - (range(10), True), - (range(0, -10, -1), False), - (range(+10, -10, -1), False), - ([1, 2, 3.0], False), - ([1, 2, "3"], False), - ([], True), - ], -) -def test_is_sequence_of_uint(sequence, result): - assert is_sequence_of_uint(sequence) is result - - -@pytest.mark.parametrize( - "sequence,result", - [ - (range(10), False), - (range(+10, -10, -1), False), - ([1, 2, 3.0], False), - ([1, 2, "3"], False), - ([], True), - (map(float, range(10)), True), - (map(float, range(+10, -10, -1)), True), - ], -) -def test_is_sequence_of_float(sequence, result): - assert is_sequence_of_float(sequence) is result - - -@pytest.mark.parametrize( - "sequence,result", - [ - (range(3), True), - (range(+1, -2, -1), True), - (range(4), False), - (range(2), False), - ([1, 2, 3.0], False), - ([1, 2, "3"], False), - ([], False), - ], -) -def test_is_int3(sequence, result): - assert is_int3(sequence) is result - - -@pytest.mark.parametrize( - "sequence,result", - [ - (list(map(float, range(3))), True), - (list(map(float, range(+1, -2, -1))), True), - (list(map(float, range(4))), False), - (list(map(float, range(2))), False), - ([1, 2, 3.0], False), - ([1, 2, "3"], False), - ([], False), - ], -) -def test_is_float3(sequence, result): - assert is_float3(sequence) is result - - -if compas.PY3: - - @pytest.mark.parametrize( - "sequence,result", - [ - (map(float, range(3)), False), - (map(float, range(+1, -2, -1)), False), - ], - ) - def test_is_float3_invalid(sequence, result): - with pytest.raises(TypeError): - assert is_float3(sequence) is result - - -@pytest.mark.parametrize( - "sequence,result", - [ - ([list(map(float, range(4))) for _ in range(4)], True), - ([list(map(float, range(+2, -2, -1))) for _ in range(4)], True), - ([list(map(float, range(5))) for _ in range(4)], False), - ([list(map(float, range(3))) for _ in range(4)], False), - ([list(map(float, range(4))) for _ in range(5)], False), - ([list(map(float, range(4))) for _ in range(3)], False), - ([[1, 2, 3.0, 4.0] for _ in range(4)], False), - ([[1, 2, "3", 4.0] for _ in range(4)], False), - ([], False), - ], -) -def test_is_float4x4(sequence, result): - assert is_float4x4(sequence) is result - - -if compas.PY3: - - @pytest.mark.parametrize( - "sequence,result", - [ - ([map(float, range(4)) for _ in range(4)], True), - ([map(float, range(+2, -2, -1)) for _ in range(4)], True), - ], - ) - def test_is_float4x4_invalid(sequence, result): - with pytest.raises(TypeError): - assert is_float4x4(sequence) is result +# import compas +# import pytest + +# from compas.data import is_sequence_of_int +# from compas.data import is_sequence_of_uint +# from compas.data import is_sequence_of_float + +# from compas.data import is_int3 +# from compas.data import is_float3 +# from compas.data import is_float4x4 + + +# @pytest.mark.parametrize( +# "sequence,result", +# [ +# (range(10), True), +# (range(+10, -10, -1), True), +# (list(range(10)), True), +# (list(range(+10, -10, -1)), True), +# ([1, 2, 3, 4.0], False), +# ([1, 2, "3"], False), +# ([], True), +# ], +# ) +# def test_is_sequence_of_int(sequence, result): +# assert is_sequence_of_int(sequence) is result + + +# @pytest.mark.parametrize( +# "sequence,result", +# [ +# (range(10), True), +# (range(0, -10, -1), False), +# (range(+10, -10, -1), False), +# ([1, 2, 3.0], False), +# ([1, 2, "3"], False), +# ([], True), +# ], +# ) +# def test_is_sequence_of_uint(sequence, result): +# assert is_sequence_of_uint(sequence) is result + + +# @pytest.mark.parametrize( +# "sequence,result", +# [ +# (range(10), False), +# (range(+10, -10, -1), False), +# ([1, 2, 3.0], False), +# ([1, 2, "3"], False), +# ([], True), +# (map(float, range(10)), True), +# (map(float, range(+10, -10, -1)), True), +# ], +# ) +# def test_is_sequence_of_float(sequence, result): +# assert is_sequence_of_float(sequence) is result + + +# @pytest.mark.parametrize( +# "sequence,result", +# [ +# (range(3), True), +# (range(+1, -2, -1), True), +# (range(4), False), +# (range(2), False), +# ([1, 2, 3.0], False), +# ([1, 2, "3"], False), +# ([], False), +# ], +# ) +# def test_is_int3(sequence, result): +# assert is_int3(sequence) is result + + +# @pytest.mark.parametrize( +# "sequence,result", +# [ +# (list(map(float, range(3))), True), +# (list(map(float, range(+1, -2, -1))), True), +# (list(map(float, range(4))), False), +# (list(map(float, range(2))), False), +# ([1, 2, 3.0], False), +# ([1, 2, "3"], False), +# ([], False), +# ], +# ) +# def test_is_float3(sequence, result): +# assert is_float3(sequence) is result + + +# if compas.PY3: + +# @pytest.mark.parametrize( +# "sequence,result", +# [ +# (map(float, range(3)), False), +# (map(float, range(+1, -2, -1)), False), +# ], +# ) +# def test_is_float3_invalid(sequence, result): +# with pytest.raises(TypeError): +# assert is_float3(sequence) is result + + +# @pytest.mark.parametrize( +# "sequence,result", +# [ +# ([list(map(float, range(4))) for _ in range(4)], True), +# ([list(map(float, range(+2, -2, -1))) for _ in range(4)], True), +# ([list(map(float, range(5))) for _ in range(4)], False), +# ([list(map(float, range(3))) for _ in range(4)], False), +# ([list(map(float, range(4))) for _ in range(5)], False), +# ([list(map(float, range(4))) for _ in range(3)], False), +# ([[1, 2, 3.0, 4.0] for _ in range(4)], False), +# ([[1, 2, "3", 4.0] for _ in range(4)], False), +# ([], False), +# ], +# ) +# def test_is_float4x4(sequence, result): +# assert is_float4x4(sequence) is result + + +# if compas.PY3: + +# @pytest.mark.parametrize( +# "sequence,result", +# [ +# ([map(float, range(4)) for _ in range(4)], True), +# ([map(float, range(+2, -2, -1)) for _ in range(4)], True), +# ], +# ) +# def test_is_float4x4_invalid(sequence, result): +# with pytest.raises(TypeError): +# assert is_float4x4(sequence) is result diff --git a/tests/compas/scene/test_scene.py b/tests/compas/scene/test_scene.py new file mode 100644 index 00000000000..18ab4252086 --- /dev/null +++ b/tests/compas/scene/test_scene.py @@ -0,0 +1,110 @@ +import pytest # noqa: F401 + +import compas +from compas.scene import SceneObject +from compas.scene import NoSceneObjectContextError + + +if not compas.IPY: + + @pytest.fixture(autouse=True) + def reset_sceneobjects(): + # before each test + yield + # after each test, reset scene objects + SceneObject.ITEM_SCENEOBJECT.clear() + SceneObject._SceneObject__SCENEOBJECTS_REGISTERED = False # type: ignore + + +def register_fake_context(): + SceneObject.register(FakeItem, FakeSceneObject, context="fake") + + +class FakeSceneObject(SceneObject): + def draw(self): + pass + + +class FakeSubSceneObject(SceneObject): + def draw(self): + pass + + +class FakeItem(object): + pass + + +class FakeSubItem(FakeItem): + pass + + +def test_get_sceneobject_cls_with_orderly_registration(): + SceneObject.register(FakeItem, FakeSceneObject, context="fake") + SceneObject.register(FakeSubItem, FakeSubSceneObject, context="fake") + item = FakeItem() + sceneobject = SceneObject(item, context="fake") + assert isinstance(sceneobject, FakeSceneObject) + + item = FakeSubItem() + sceneobject = SceneObject(item, context="fake") + assert isinstance(sceneobject, FakeSubSceneObject) + + +def test_get_sceneobject_cls_with_out_of_order_registration(): + SceneObject.register(FakeSubItem, FakeSubSceneObject, context="fake") + SceneObject.register(FakeItem, FakeSceneObject, context="fake") + item = FakeItem() + sceneobject = SceneObject(item, context="fake") + assert isinstance(sceneobject, FakeSceneObject) + + item = FakeSubItem() + sceneobject = SceneObject(item, context="fake") + assert isinstance(sceneobject, FakeSubSceneObject) + + +if not compas.IPY: + + def test_sceneobject_auto_context_discovery(mocker): + mocker.patch("compas.scene.SceneObject.register_scene_objects") + SceneObject.register_scene_objects.side_effect = register_fake_context + SceneObject._SceneObject__SCENEOBJECTS_REGISTERED = False # type: ignore + + item = FakeItem() + sceneobject = SceneObject(item) + + assert isinstance(sceneobject, FakeSceneObject) + + def test_sceneobject_auto_context_discovery_viewer(mocker): + mocker.patch("compas.scene.sceneobject.is_viewer_open", return_value=True) + SceneObject.ITEM_SCENEOBJECT["Viewer"] = {FakeItem: FakeSceneObject} + + item = FakeSubItem() + sceneobject = SceneObject(item) + + assert isinstance(sceneobject, FakeSceneObject) + + def test_sceneobject_auto_context_discovery_viewer_priority(mocker): + mocker.patch("compas.scene.sceneobject.is_viewer_open", return_value=True) + + class FakeViewerSceneObject(FakeSceneObject): + pass + + class FakePlotterSceneObject(FakeSceneObject): + pass + + SceneObject.ITEM_SCENEOBJECT["Viewer"] = {FakeItem: FakeViewerSceneObject} + SceneObject.ITEM_SCENEOBJECT["Plotter"] = {FakeItem: FakePlotterSceneObject} + + item = FakeSubItem() + sceneobject = SceneObject(item) + + assert isinstance(sceneobject, FakeViewerSceneObject) + + def test_sceneobject_auto_context_discovery_no_context(mocker): + mocker.patch("compas.scene.sceneobject.is_viewer_open", return_value=False) + mocker.patch("compas.scene.sceneobject.compas.is_grasshopper", return_value=False) + mocker.patch("compas.scene.sceneobject.compas.is_rhino", return_value=False) + + with pytest.raises(NoSceneObjectContextError): + item = FakeSubItem() + _ = SceneObject(item) diff --git a/tests/compas/stubs.py b/tests/compas/stubs.py index 796725f30d6..bcd330aa34b 100644 --- a/tests/compas/stubs.py +++ b/tests/compas/stubs.py @@ -8,7 +8,7 @@ def compas_api(): modules = [ - "compas.artists", + "compas.scene", "compas.data", "compas.datastructures", "compas.files",