<p align="center">
<br>
<img src="docs/source/assets/simulate_library.png" width="400"/>
<br>
</p>
<p align="center">
<a href="https://github.com/huggingface/simulate/blob/main/LICENSE">
<img alt="GitHub" src="https://img.shields.io/github/license/huggingface/datasets.svg?color=blue">
</a>
<a href="https://github.com/huggingface/simulate/releases">
<img alt="GitHub release" src="https://img.shields.io/github/release/huggingface/diffusers.svg">
</a>
<a href="CODE_OF_CONDUCT.md">
<img alt="Contributor Covenant" src="https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg">
</a>
</p>
# Simulate
Simulate is a library for easily creating and sharing simulation environments for intelligent agents (e.g. reinforcement learning) or synthetic data generation.
## Install
Install Simulate (preferentially in a virtual environment) with a simple `pip install simulate`
*Note*: `vtk` is not built for Apple Silicon with Python 3.8. Please install with >3.9 in that case.
### Install for contribution (from [CONTRIBUTING.md](CONTRIBUTING.md))
Create a virtual env and then install the code style/quality tools as well as the code base locally
```
pip install --upgrade simulate
```
Before you merge a PR, fix the style (we use `isort` + `black`)
```
make style
```
## Quick tour
Simulate's API is inspired by the great [Kubric's API](https://github.com/google-research/kubric).
The user create a `Scene` and add `Assets` in it (objects, cameras, lights etc).
Once the scene is created, you can save and share it as a file. This is a gIFT file, aka a JSON file with associated resources.
You can also render the scene or do simulations using one of the backend rendering/simulation engines (at the moment Unity, Blender and Godot).
The saving/sharing format is engine agnostic and using a graphic industry standard.
Let's do a quick exploration together.
```
import simulate as sm
scene = sm.Scene()
```
### Project Structure
The Python API is located in src/simulate. It allows creation and loading of scenes, and sending commands to the backend.
We provide several backends to render and/or run the scene.
The default backend requires no specific installation and is based on [pyvista](https://docs.pyvista.org/user-guide/index.html). It allows one to quick render/explored scene but doesn't handle physics simulation.
To allow physic simulations, the Unity backend can for instance be used by setting `engine="unity"` (and soon the Godot and Blender Engines backend as well). A Unity build will be automatically downloaded (if not already) and spawed to run simulations. Alternatively, one can download and use the Unity editor themself, which must then be opened with Unity version 2021.3.2f1.
### Loading a scene from the Hub or a local file
Loading a scene from a local file or the Hub is done with `Scene.create_from()`, saving locally or pushing to the Hub with `scene.save()` or `scene.push_to_hub()`:
```
from simulate import Scene
scene = Scene.create_from('tests/test_assets/fixtures/Box.gltf') # either local (priority) or on the Hub with full path to file
scene = Scene.create_from('simulate-tests/Box/glTF/Box.gltf', is_local=False) # Set priority to the Hub file
scene.save('local_dir/file.gltf') # Save to a local file
scene.push_to_hub('simulate-tests/Debug/glTF/Box.gltf') # Save to the Hub - use a token if necessary
scene.show()
```
<p align="center">
<br>
<img src="https://user-images.githubusercontent.com/10695622/191554717-acba4764-a4f4-4609-834a-39ddb50b844a.png" width="400"/>
<br>
<p>
### Creating a Scene and adding/managing Objects in the scene
Basic example of creating a scene with a plane and a sphere above it:
```
import simulate as sm
scene = sm.Scene()
scene += sm.Plane() + sm.Sphere(position=[0, 1, 0], radius=0.2)
>>> scene
>>> Scene(dimensionality=3, engine='PyVistaEngine')
>>> └── plane_01 (Plane - Mesh: 121 points, 100 cells)
>>> └── sphere_02 (Sphere - Mesh: 842 points, 870 cells)
scene.show()
```
An object (as well as the Scene) is just a node in a tree provided with optional mesh (under the hood created/stored/edited as a [`pyvista.PolyData`](https://docs.pyvista.org/api/core/_autosummary/pyvista.PolyData.html#pyvista-polydata) or [`pyvista.MultiBlock`](https://docs.pyvista.org/api/core/_autosummary/pyvista.MultiBlock.html#pyvista-multiblock) objects) and material and/or light, camera, agents special objects.
The following objects creation helpers are currently provided:
- `Object3D` any object with a mesh and/or material
- `Plane`
- `Sphere`
- `Capsule`
- `Cylinder`
- `Box`
- `Cone`
- `Line`
- `MultipleLines`
- `Tube`
- `Polygon`
- `Ring`
- `Text3D`
- `Triangle`
- `Rectangle`
- `Circle`
- `StructuredGrid`
- ... (see the doc)
Many of these objects can be visualized by running the following [example](https://github.com/huggingface/simulate/tree/main/examples/objects.py):
```
python examples/basic/objects.py
```
<p align="center">
<br>
<img src="https://user-images.githubusercontent.com/10695622/191562825-49d4c692-a1ed-44e9-bdb9-da5f0bfb9828.png" width="400"/>
<br>
<p>
### Objects are organized in a tree structure
Adding/removing objects:
- Using the addition (`+`) operator (or alternatively the method `.add(object)`) will add an object as a child of a previous object.
- Objects can be removed with the subtraction (`-`) operator or the `.remove(object)` command.
- Several objects can be added at once by adding a list/tuple to the scene.
- The whole scene can be cleared with `.clear()`.
- To add a nested object, just add it to the object under which it should be nested, e.g. `scene.sphere += sphere_child`.
Accessing objects:
- Objects can be directly accessed as attributes of their parents using their names (given with `name` attribute at creation or automatically generated from the class name + creation counter).
- Objects can also be accessed from their names with `.get_node(name)`.
- The names of the object are enforced to be unique (on save/show).
- Various `tree_*` attributes are available on any node to quickly navegate or list part of the tree of nodes.
Here are a couple of examples of manipulations:
```
# Add two copy of the sphere to the scene as children of the root node (using list will add all objects on the same level)
# Using `.copy()` will create a copy of an object (the copy doesn't have any parent or children)
scene += [scene.plane_01.sphere_02.copy(), scene.plane_01.sphere_02.copy()]
>>> scene
>>> Scene(dimensionality=3, engine='pyvista')
>>> ├── plane_01 (Plane - Mesh: 121 points, 100 cells)
>>> │ └── sphere_02 (Sphere - Mesh: 842 points, 870 cells)
>>> ├── sphere_03 (Sphere - Mesh: 842 points, 870 cells)
>>> └── sphere_04 (Sphere - Mesh: 842 points, 870 cells)
# Remove the last added sphere
>>> scene.remove(scene.sphere_04)
>>> Scene(dimensionality=3, engine='pyvista')
>>> ├── plane_01 (Plane - Mesh: 121 points, 100 cells)
>>> │ └── sphere_02 (Sphere - Mesh: 842 points, 870 cells)
>>> └── sphere_03 (Sphere - Mesh: 842 points, 870 cells)
```
### Editing and moving objects
Objects can be easily translated, rotated, scaled
Here are a couple of examples:
```
# Let's translate our floor (with the first sphere, it's child)
scene.plane_01.translate_x(1)
# Let's scale the second sphere uniformly
scene.sphere_03.scale(0.1)
# Inspect the current position and scaling values
print(scene.plane_01.position)
>>> array([1., 0., 0.])
print(scene.sphere_03.scaling)
>>> array([0.1, 0.1, 0.1])
# We can also translate from a vector and rotate from a quaternion or along the various axis
```
Editing objects:
- mesh of the object can be edited with all the manipulation operator provided by [pyvista](https://docs.pyvista.org/user-guide/index.html)
## Visualization engine
A default visualization engine is provided with the vtk backend of [`pyvista`](https://docs.pyvista.org/user-guide/index.html).
Starting the visualization engine can be done simply with `.show()`.
```
scene.show()
```
You can find bridges to other rendering/simulation engines in the `integrations` directory.
## Tips
If you are running on GCP, remember not to install `pyvistaqt`, and if you did so, uninstall it in your environment, since QT doesn't work well on GCP.
## Citation
```bibtex
@misc{simulate,
author = {Thomas Wolf, Edward Beeching, Carl Cochet, Dylan Ebert, Alicia Machado, Nathan Lambert, Clément Romac},
title = {Simulate},
year = {2022},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/huggingface/simulate}}
}
```
Raw data
{
"_id": null,
"home_page": "https://github.com/huggingface/simulate",
"name": "simulate",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "simulation environments synthetic data datasets machine learning",
"author": "HuggingFace Inc.",
"author_email": "thomas@huggingface.co",
"download_url": "https://files.pythonhosted.org/packages/89/25/a26df0edb7c65b88a5b3ec252d7caa34a3399c60cc226ac7ab2702a27a54/simulate-0.1.2.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n <br>\n <img src=\"docs/source/assets/simulate_library.png\" width=\"400\"/>\n <br>\n</p>\n<p align=\"center\">\n <a href=\"https://github.com/huggingface/simulate/blob/main/LICENSE\">\n <img alt=\"GitHub\" src=\"https://img.shields.io/github/license/huggingface/datasets.svg?color=blue\">\n </a>\n <a href=\"https://github.com/huggingface/simulate/releases\">\n <img alt=\"GitHub release\" src=\"https://img.shields.io/github/release/huggingface/diffusers.svg\">\n </a>\n <a href=\"CODE_OF_CONDUCT.md\"> \n <img alt=\"Contributor Covenant\" src=\"https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg\">\n </a>\n</p>\n\n# Simulate\n\nSimulate is a library for easily creating and sharing simulation environments for intelligent agents (e.g. reinforcement learning) or synthetic data generation.\n\n## Install\n\nInstall Simulate (preferentially in a virtual environment) with a simple `pip install simulate`\n*Note*: `vtk` is not built for Apple Silicon with Python 3.8. Please install with >3.9 in that case.\n\n### Install for contribution (from [CONTRIBUTING.md](CONTRIBUTING.md))\n\nCreate a virtual env and then install the code style/quality tools as well as the code base locally\n```\npip install --upgrade simulate\n```\nBefore you merge a PR, fix the style (we use `isort` + `black`)\n```\nmake style\n```\n\n## Quick tour\n\nSimulate's API is inspired by the great [Kubric's API](https://github.com/google-research/kubric).\nThe user create a `Scene` and add `Assets` in it (objects, cameras, lights etc).\n\nOnce the scene is created, you can save and share it as a file. This is a gIFT file, aka a JSON file with associated resources.\n\nYou can also render the scene or do simulations using one of the backend rendering/simulation engines (at the moment Unity, Blender and Godot).\n\nThe saving/sharing format is engine agnostic and using a graphic industry standard.\n\nLet's do a quick exploration together. \n\n```\nimport simulate as sm\n\nscene = sm.Scene()\n```\n\n### Project Structure\n\nThe Python API is located in src/simulate. It allows creation and loading of scenes, and sending commands to the backend.\n\nWe provide several backends to render and/or run the scene.\nThe default backend requires no specific installation and is based on [pyvista](https://docs.pyvista.org/user-guide/index.html). It allows one to quick render/explored scene but doesn't handle physics simulation.\nTo allow physic simulations, the Unity backend can for instance be used by setting `engine=\"unity\"` (and soon the Godot and Blender Engines backend as well). A Unity build will be automatically downloaded (if not already) and spawed to run simulations. Alternatively, one can download and use the Unity editor themself, which must then be opened with Unity version 2021.3.2f1.\n\n### Loading a scene from the Hub or a local file\n\nLoading a scene from a local file or the Hub is done with `Scene.create_from()`, saving locally or pushing to the Hub with `scene.save()` or `scene.push_to_hub()`:\n\n```\nfrom simulate import Scene\n\nscene = Scene.create_from('tests/test_assets/fixtures/Box.gltf') # either local (priority) or on the Hub with full path to file\nscene = Scene.create_from('simulate-tests/Box/glTF/Box.gltf', is_local=False) # Set priority to the Hub file\n\nscene.save('local_dir/file.gltf') # Save to a local file\nscene.push_to_hub('simulate-tests/Debug/glTF/Box.gltf') # Save to the Hub - use a token if necessary\n\nscene.show()\n```\n<p align=\"center\">\n <br>\n <img src=\"https://user-images.githubusercontent.com/10695622/191554717-acba4764-a4f4-4609-834a-39ddb50b844a.png\" width=\"400\"/>\n <br>\n<p>\n\n### Creating a Scene and adding/managing Objects in the scene\n\nBasic example of creating a scene with a plane and a sphere above it:\n```\nimport simulate as sm\n\nscene = sm.Scene()\nscene += sm.Plane() + sm.Sphere(position=[0, 1, 0], radius=0.2)\n\n>>> scene\n>>> Scene(dimensionality=3, engine='PyVistaEngine')\n>>> \u2514\u2500\u2500 plane_01 (Plane - Mesh: 121 points, 100 cells)\n>>> \u2514\u2500\u2500 sphere_02 (Sphere - Mesh: 842 points, 870 cells)\n\nscene.show()\n```\n\nAn object (as well as the Scene) is just a node in a tree provided with optional mesh (under the hood created/stored/edited as a [`pyvista.PolyData`](https://docs.pyvista.org/api/core/_autosummary/pyvista.PolyData.html#pyvista-polydata) or [`pyvista.MultiBlock`](https://docs.pyvista.org/api/core/_autosummary/pyvista.MultiBlock.html#pyvista-multiblock) objects) and material and/or light, camera, agents special objects.\n\nThe following objects creation helpers are currently provided:\n- `Object3D` any object with a mesh and/or material\n- `Plane`\n- `Sphere`\n- `Capsule`\n- `Cylinder`\n- `Box`\n- `Cone`\n- `Line`\n- `MultipleLines`\n- `Tube`\n- `Polygon`\n- `Ring`\n- `Text3D`\n- `Triangle`\n- `Rectangle`\n- `Circle`\n- `StructuredGrid`\n- ... (see the doc)\n\nMany of these objects can be visualized by running the following [example](https://github.com/huggingface/simulate/tree/main/examples/objects.py):\n```\npython examples/basic/objects.py\n```\n<p align=\"center\">\n <br>\n <img src=\"https://user-images.githubusercontent.com/10695622/191562825-49d4c692-a1ed-44e9-bdb9-da5f0bfb9828.png\" width=\"400\"/>\n <br>\n<p>\n\n### Objects are organized in a tree structure\n\nAdding/removing objects:\n- Using the addition (`+`) operator (or alternatively the method `.add(object)`) will add an object as a child of a previous object.\n- Objects can be removed with the subtraction (`-`) operator or the `.remove(object)` command.\n- Several objects can be added at once by adding a list/tuple to the scene.\n- The whole scene can be cleared with `.clear()`.\n- To add a nested object, just add it to the object under which it should be nested, e.g. `scene.sphere += sphere_child`.\n\nAccessing objects:\n- Objects can be directly accessed as attributes of their parents using their names (given with `name` attribute at creation or automatically generated from the class name + creation counter).\n- Objects can also be accessed from their names with `.get_node(name)`.\n- The names of the object are enforced to be unique (on save/show).\n- Various `tree_*` attributes are available on any node to quickly navegate or list part of the tree of nodes.\n\nHere are a couple of examples of manipulations:\n\n```\n# Add two copy of the sphere to the scene as children of the root node (using list will add all objects on the same level)\n# Using `.copy()` will create a copy of an object (the copy doesn't have any parent or children)\nscene += [scene.plane_01.sphere_02.copy(), scene.plane_01.sphere_02.copy()]\n\n>>> scene\n>>> Scene(dimensionality=3, engine='pyvista')\n>>> \u251c\u2500\u2500 plane_01 (Plane - Mesh: 121 points, 100 cells)\n>>> \u2502 \u2514\u2500\u2500 sphere_02 (Sphere - Mesh: 842 points, 870 cells)\n>>> \u251c\u2500\u2500 sphere_03 (Sphere - Mesh: 842 points, 870 cells)\n>>> \u2514\u2500\u2500 sphere_04 (Sphere - Mesh: 842 points, 870 cells)\n\n# Remove the last added sphere\n>>> scene.remove(scene.sphere_04)\n>>> Scene(dimensionality=3, engine='pyvista')\n>>> \u251c\u2500\u2500 plane_01 (Plane - Mesh: 121 points, 100 cells)\n>>> \u2502 \u2514\u2500\u2500 sphere_02 (Sphere - Mesh: 842 points, 870 cells)\n>>> \u2514\u2500\u2500 sphere_03 (Sphere - Mesh: 842 points, 870 cells)\n```\n\n### Editing and moving objects\n\nObjects can be easily translated, rotated, scaled\n\nHere are a couple of examples:\n```\n# Let's translate our floor (with the first sphere, it's child)\nscene.plane_01.translate_x(1)\n\n# Let's scale the second sphere uniformly\nscene.sphere_03.scale(0.1)\n\n# Inspect the current position and scaling values\nprint(scene.plane_01.position)\n>>> array([1., 0., 0.])\nprint(scene.sphere_03.scaling)\n>>> array([0.1, 0.1, 0.1])\n\n# We can also translate from a vector and rotate from a quaternion or along the various axis\n```\n\nEditing objects:\n- mesh of the object can be edited with all the manipulation operator provided by [pyvista](https://docs.pyvista.org/user-guide/index.html)\n\n## Visualization engine\n\nA default visualization engine is provided with the vtk backend of [`pyvista`](https://docs.pyvista.org/user-guide/index.html).\n\nStarting the visualization engine can be done simply with `.show()`.\n```\nscene.show()\n```\n\nYou can find bridges to other rendering/simulation engines in the `integrations` directory.\n\n## Tips\n\nIf you are running on GCP, remember not to install `pyvistaqt`, and if you did so, uninstall it in your environment, since QT doesn't work well on GCP.\n\n## Citation\n```bibtex\n@misc{simulate,\n author = {Thomas Wolf, Edward Beeching, Carl Cochet, Dylan Ebert, Alicia Machado, Nathan Lambert, Cl\u00e9ment Romac},\n title = {Simulate},\n year = {2022},\n publisher = {GitHub},\n journal = {GitHub repository},\n howpublished = {\\url{https://github.com/huggingface/simulate}}\n}\n```\n\n\n",
"bugtrack_url": null,
"license": "Apache 2.0",
"summary": "HuggingFace community-driven open-source library of simulation environments",
"version": "0.1.2",
"split_keywords": [
"simulation",
"environments",
"synthetic",
"data",
"datasets",
"machine",
"learning"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "47637a3a455dd237d93d7580e1f6a9cc",
"sha256": "7dbf16f4046fe24afd0e3f5f389b60c89ce7b8b03caac22388a1e2562d7e4bbc"
},
"downloads": -1,
"filename": "simulate-0.1.2-cp310-cp310-macosx_12_0_arm64.whl",
"has_sig": false,
"md5_digest": "47637a3a455dd237d93d7580e1f6a9cc",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 543483,
"upload_time": "2022-12-01T03:27:20",
"upload_time_iso_8601": "2022-12-01T03:27:20.728131Z",
"url": "https://files.pythonhosted.org/packages/80/6e/6c96ba7c466390c350f50b65b6ec63444c63c6893bed27f5c2681639b1d3/simulate-0.1.2-cp310-cp310-macosx_12_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "3e0aff8c7116b3a7f49f083684eb8147",
"sha256": "1f1e01a21d7caef2cbde8b6c242528ca43ee3830b7b08bcbcf285edea56759b5"
},
"downloads": -1,
"filename": "simulate-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "3e0aff8c7116b3a7f49f083684eb8147",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 138782,
"upload_time": "2022-12-01T03:27:23",
"upload_time_iso_8601": "2022-12-01T03:27:23.429958Z",
"url": "https://files.pythonhosted.org/packages/89/25/a26df0edb7c65b88a5b3ec252d7caa34a3399c60cc226ac7ab2702a27a54/simulate-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-12-01 03:27:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "huggingface",
"github_project": "simulate",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "simulate"
}