Compare commits

..

14 Commits

Author SHA1 Message Date
Swann
6fc03ad0ee overide pipelines 2021-12-02 16:33:02 +01:00
Swann
5a12b82392 feat tests 2021-12-02 16:30:49 +01:00
Swann
35ee8bc8ec fix build 2021-12-02 16:28:38 +01:00
Swann
cef3cd445c fix buildx 2021-12-02 16:07:17 +01:00
Swann
2b205c4b62 fix buildx 2021-12-02 15:55:16 +01:00
Swann
ed4b26f925 fix doc 2021-12-02 15:45:06 +01:00
Swann
c9758e6f11 fix build 2021-12-02 15:44:00 +01:00
Swann
7152ea9307 fix ci 2021-12-02 15:43:25 +01:00
Swann
0f35031375 fix ci 2021-12-02 15:41:48 +01:00
Swann Martinez
37b0b5040d Update .gitlab-ci.yml file 2021-12-02 14:39:37 +00:00
Swann Martinez
318bd50eec Update .gitlab-ci.yml file 2021-12-02 14:37:58 +00:00
Swann Martinez
fd733d45bf Update .gitlab-ci.yml file 2021-12-02 14:37:37 +00:00
Swann
09af14bc4b fix: job name 2021-12-02 15:35:23 +01:00
Swann
e4e93f7c7f feat:initial arm64 docker image 2021-12-02 15:28:46 +01:00
139 changed files with 906 additions and 1360 deletions

View File

@ -1,13 +1,43 @@
stages: stages:
- test # - test
- build # - build-addon-zip
- deploy # - build-amd64
- doc - build-arm64
# - doc
include: # include:
- local: .gitlab/ci/test.gitlab-ci.yml # # - local: .gitlab/ci/test.gitlab-ci.yml
- local: .gitlab/ci/build.gitlab-ci.yml # # - local: .gitlab/ci/build-addon.gitlab-ci.yml
- local: .gitlab/ci/deploy.gitlab-ci.yml # - local: .gitlab/ci/build-image.gitlab-ci.yml
- local: .gitlab/ci/doc.gitlab-ci.yml # # - local: .gitlab/ci/doc.gitlab-ci.yml
build-arm64:
stage: build-arm64
# needs: ["build-addon-zip"]
image: slumber/docker-python
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: "/certs"
GIT_SUBMODULE_STRATEGY: recursive
services:
- docker:19.03.12-dind
before_script:
- apk add curl
- mkdir -p ~/.docker/cli-plugins
- curl -sSLo ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/$BUILDX_VERSION/buildx-$BUILDX_VERSION.linux-amd64
- chmod +x ~/.docker/cli-plugins/docker-buildx
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- docker info
script:
- RP_VERSION="$(python scripts/get_replication_version.py)"
- VERSION="$(python scripts/get_addon_version.py)"
- echo "Building docker image with replication ${RP_VERSION}"
- docker buildx create arm64 --use
- docker buildx build --platform linux/arm64 --build-arg version={VERSION} --tag registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION}-arm64 ./scripts/docker_server
- echo "Pushing to gitlab registry ${VERSION}-arm64"
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker tag registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION}-arm64 registry.gitlab.com/slumber/multi-user/multi-user-server:${CI_COMMIT_REF_NAME}-arm64
- docker push registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION}-arm64

View File

@ -1,5 +1,5 @@
build: build-addon-zip:
stage: build stage: build-addon-zip
needs: ["test"] needs: ["test"]
image: debian:stable-slim image: debian:stable-slim
script: script:

View File

@ -0,0 +1,50 @@
build-amd64:
stage: build-amd64
needs: ["build-addon-zip"]
image: slumber/docker-python
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: "/certs"
GIT_SUBMODULE_STRATEGY: recursive
services:
- docker:19.03.12-dind
script:
- RP_VERSION="$(python scripts/get_replication_version.py)"
- VERSION="$(python scripts/get_addon_version.py)"
- echo "Building docker image with replication ${RP_VERSION}"
- docker build --build-arg replication_version=${RP_VERSION} --build-arg version={VERSION} -t registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION} ./scripts/docker_server
- echo "Pushing to gitlab registry ${VERSION}"
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker tag registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION} registry.gitlab.com/slumber/multi-user/multi-user-server:${CI_COMMIT_REF_NAME}
- docker push registry.gitlab.com/slumber/multi-user/multi-user-server
build-arm64:
stage: build-arm64
# needs: ["build-addon-zip"]
image: slumber/docker-python
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: "/certs"
GIT_SUBMODULE_STRATEGY: recursive
services:
- docker:19.03.12-dind
before_script:
- apk add curl
- mkdir -p ~/.docker/cli-plugins
- curl -sSLo ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/$BUILDX_VERSION/buildx-$BUILDX_VERSION.linux-amd64
- chmod +x ~/.docker/cli-plugins/docker-buildx
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- docker info
script:
- RP_VERSION="$(python scripts/get_replication_version.py)"
- VERSION="$(python scripts/get_addon_version.py)"
- echo "Building docker image with replication ${RP_VERSION}"
- docker buildx create arm64 --use
- docker buildx build --platform linux/arm64 --build-arg version={VERSION} --tag registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION}-arm64 ./scripts/docker_server
- echo "Pushing to gitlab registry ${VERSION}-arm64"
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker tag registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION}-arm64 registry.gitlab.com/slumber/multi-user/multi-user-server:${CI_COMMIT_REF_NAME}-arm64
- docker push registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION}-arm64

View File

@ -1,21 +0,0 @@
deploy:
stage: deploy
needs: ["build"]
image: slumber/docker-python
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: "/certs"
GIT_SUBMODULE_STRATEGY: recursive
services:
- docker:19.03.12-dind
script:
- RP_VERSION="$(python scripts/get_replication_version.py)"
- VERSION="$(python scripts/get_addon_version.py)"
- echo "Building docker image with replication ${RP_VERSION}"
- docker build --build-arg replication_version=${RP_VERSION} --build-arg version={VERSION} -t registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION} ./scripts/docker_server
- echo "Pushing to gitlab registry ${VERSION}"
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker tag registry.gitlab.com/slumber/multi-user/multi-user-server:${VERSION} registry.gitlab.com/slumber/multi-user/multi-user-server:${CI_COMMIT_REF_NAME}
- docker push registry.gitlab.com/slumber/multi-user/multi-user-server

View File

@ -1,6 +1,6 @@
pages: pages:
stage: doc stage: doc
needs: ["deploy"] needs: ["build-arm64","build-amd64"]
image: python image: python
script: script:
- pip install -U sphinx sphinx_rtd_theme sphinx-material - pip install -U sphinx sphinx_rtd_theme sphinx-material

View File

@ -217,57 +217,3 @@ All notable changes to this project will be documented in this file.
- GPencil fill stroke - GPencil fill stroke
- Sculpt and GPencil brushes deleted when joining a session (@Kysios) - Sculpt and GPencil brushes deleted when joining a session (@Kysios)
- Auto-updater doesn't work for master and develop builds - Auto-updater doesn't work for master and develop builds
## [0.5.0] - 2022-02-10
### Added
- New overall UI and UX (@Kysios)
- Documentation overall update (@Kysios)
- Server presets (@Kysios)
- Server online status (@Kysios)
- Draw connected user color in the user list
- Private session (access protected with a password) (@Kysios)
### Changed
- Dependencies are now installed in the addon folder and correctly cleaned during the addon removal process
### Fixed
- Python 3.10 compatibility (@notfood)
- Blender 3.x compatibility
- Skin vertex radius synchronization (@kromar)
- Sequencer audio strip synchronization
- Crash with empty after a reconnection
## [0.5.1] - 2022-02-10
### Fixed
- Auto updater breaks dependency auto installer
- Auto updater update from tag
## [0.5.2] - 2022-02-18
### Fixed
- Objects not selectable after user leaves session
- Geometry nodes attribute toogle doesn't sync
## [0.5.3] - 2022-03-11
### Changed
- Snapshots logs
### Fixed
- Server crashing during snapshots
- Blender 3.1 numpy loading error during early connection process
- Server docker arguments
## [0.5.5] - 2022-06-12
### Fixed
- Numpy mesh serialization error

View File

@ -1,17 +0,0 @@
=========
Community
=========
Discord
=======
Feel free to join our `discord server <https://discord.gg/aBPvGws>`_ !
You will find help, a way to take part in the project, public collaborative sessions, people to create with, information about the addon's progress and much more.
.. TODO: Make a call on discord get a link / image for evry contributor ?
Contributors
============
Swann, Fabian, NotFood, Poochyc, Valentin, Adrien, Tanguy, Bruno, Gorgio, Axel, Ultr-X, Wuaieyo, Softyoda, Staz, Ikxi, Kysios.

View File

@ -1,32 +0,0 @@
============
Key Features
============
Multi-User is a free and open source blender addon.
It aims to allow multiple users to work on the same scene over the network. Based on a Clients / Server architecture, the data-oriented replication schema replicate blender data-blocks across the wire.
.. warning::
The addon is still in development Be carefull when using it.
On rare occasions, it can happen that your blender scenes become corrupted, think of making backups to avoid losing your projects.
Collaboration
=============
Multi-User allows a strong collaborative workflow between users. Being able to collaborate in this way has opened up new opportunities:
- Being able to create together and in real time on the same 3D scene, with instant feedback.
- Being able to teach directly in the same 3D environment in real time, facilitating communication between the teacher and these students.
- To be able to experiment with several people, to make challenges or simply to have fun.
- And much more !
Easier communication
====================
Thanks to *presence*, the overlay system that Multi-User provides, it is possible to see other users in the 3D space. The *presence* overlay is customizable to match your preferences (visibility, names, options).
Session management
==================
The addon works on a session system. The creator of the session and the administrators have rights that allow them to easily manage the session (backups, user management). In addition, there is a management of datablock rights so that each user can collaborate as they wish.

View File

@ -1,10 +1,8 @@
================ About
About Multi-User =====
================
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 1
:name: toc-about
introduction introduction
features
community

View File

@ -1,6 +1,7 @@
======== ============
The idea Introduction
======== ============
A film is an idea carved along the whole production process by many different peoples. A traditional animation pipeline involve a linear succession of tasks. From storyboard to compositing by passing upon different step, its fundamental work flow is similar to an industrial assembly line. Since each step is almost a department, its common that one person on department B doesn't know what another person did on a previous step in a department A. This lack of visibility/communication could be a source of problems which could produce a bad impact on the final production result. A film is an idea carved along the whole production process by many different peoples. A traditional animation pipeline involve a linear succession of tasks. From storyboard to compositing by passing upon different step, its fundamental work flow is similar to an industrial assembly line. Since each step is almost a department, its common that one person on department B doesn't know what another person did on a previous step in a department A. This lack of visibility/communication could be a source of problems which could produce a bad impact on the final production result.
@ -11,4 +12,4 @@ A film is an idea carved along the whole production process by many different pe
Nowadays it's a known fact that real-time rendering technologies allows to speedup traditional linear production by reducing drastically the iteration time across different steps. All majors industrial CG solutions are moving toward real-time horizons to bring innovative interactive workflows. But this is a microscopic, per-task/solution vision of real-time rendering benefits for the animation production. What if we step-back, get a macroscopic picture of an animation movie pipeline and ask ourself how real-time could change our global workflow ? Could-it bring better ways of working together by giving more visibility between departments during the whole production ? Nowadays it's a known fact that real-time rendering technologies allows to speedup traditional linear production by reducing drastically the iteration time across different steps. All majors industrial CG solutions are moving toward real-time horizons to bring innovative interactive workflows. But this is a microscopic, per-task/solution vision of real-time rendering benefits for the animation production. What if we step-back, get a macroscopic picture of an animation movie pipeline and ask ourself how real-time could change our global workflow ? Could-it bring better ways of working together by giving more visibility between departments during the whole production ?
The multi-user addon is an attempt to experiment real-time parallelism between different production stage. By replicating blender data blocks over the networks, it allows different artists to collaborate on a same scene in real-time. The multi-user addon is an attempt to experiment real-time parallelism between different production stage. By replicating blender data blocks over the networks, it allows different artists to collaborate on a same scene in real-time.

View File

@ -12,16 +12,17 @@
# #
import os import os
import sys import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'Multi-User 0.5.x Documentation' project = 'multi-user'
copyright = '2020, Swann Martinez' copyright = '2020, Swann Martinez'
author = 'Swann Martinez, Poochy, Fabian' author = 'Swann Martinez, Poochy, Fabian'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
version_release = '0.5.5' release = '0.5.0-develop'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------
@ -41,15 +42,12 @@ source_suffix = ".rst"
# The master toctree document. # The master toctree document.
master_doc = "index" master_doc = "index"
# General information about the projet
projet = 'Multi-User %s Doc' % version_release
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs. # This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases. # Usually you set "language" from the command line for these cases.
language = 'en' language = 'python'
# List of patterns, relative to source directory, that match files and # List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
@ -62,59 +60,28 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org # on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org
on_rtd = os.environ.get('READTHEDOCS', None) == 'True' on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
html_theme = "default" import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
try: html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
del sphinx_rtd_theme
except ModuleNotFoundError:
pass
if on_rtd: if on_rtd:
using_rtd_theme = True using_rtd_theme = True
# Theme options
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = { html_theme_options = {
# 'typekit_id': 'hiw1hhg',
# 'analytics_id': '',
# 'sticky_navigation': True # Set to False to disable the sticky nav while scrolling.
# 'logo_only': True, # if we have a html_logo below, this shows /only/ the logo with no title text
'collapse_navigation': False, # Collapse navigation (False makes it tree-like) 'collapse_navigation': False, # Collapse navigation (False makes it tree-like)
# 'display_version': True, # Display the docs version
# 'navigation_depth': 4, # Depth of the headers shown in the navigation bar
} }
# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = []
if html_theme == "sphinx_rtd_theme":
html_theme_options = {
"analytics_id": "UA-1418081-1",
# included in the title
"display_version": False,
"collapse_navigation": True,
"navigation_depth": -1,
}
extensions.append('sphinx_rtd_theme')
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
html_title = "Multi-User Doc"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_logo = "resources/logo.png"
html_favicon = "ressources/favicon.ico"
html_static_path = ["resources"]
if html_theme == "sphinx_rtd_theme":
html_css_files = ["css/theme_overrides.css"]
# -- Options for HTMLHelp output ------------------------------------------ # -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder. # Output file base name for HTML help builder.
htmlhelp_basename = 'Multi-User Manual' htmlhelp_basename = 'multiusrdoc'
# sphinx-notfound-page # sphinx-notfound-page
# https://github.com/readthedocs/sphinx-notfound-page # https://github.com/readthedocs/sphinx-notfound-page

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,117 +0,0 @@
################
General Settings
################
This section contains optional settings to configure before a session.
.. figure:: img/sidepannel_general_settings.png
:align: center
General Settings pannel
---------
User info
---------
.. figure:: img/sidepannel_userinfo.png
:align: center
User Info settings
The **User Info** pannel is here to change your user name and use color.
-------
Network
-------
.. figure:: img/sidepannel_network.png
:align: center
Network settings
**Timeout (in milliseconds)** is the maximum ping authorized before auto-disconnecting.
You should only increase it if you have a bad connection.
-----
Cache
-----
.. figure:: img/sidepannel_cache.png
:align: center
Cache settings
Multi-user allows you to replicate external dependencies such as images (textures, hdris, etc...), movies, and sounds.
On each client, the files will be stored in the multi-user cache folder.
**Cache directory** choose where cached files (images, sound, movies) will be saved.
**Clear memory filecache** will save memory space at runtime by removing the file content from memory as soon as it has been written to the disk.
**Clear cache** will remove all files from the cache folder.
.. warning:: Clearing the cache could break your scene images/movies/sounds if they are used in a blend file! Try saving the blend file and choosing 'Pack all into blend' before clearing the cache.
-------
Logging
-------
.. figure:: img/sidepannel_logging.png
:align: center
Advanced log settings
**log level** allows you to set the level of detail captured in multi-user's logging output. Here is a brief description on the level of detail for each value of the logging parameter:
+-----------+-----------------------------------------------+
| Log level | Description |
+===========+===============================================+
| ERROR | Shows only critical errors |
+-----------+-----------------------------------------------+
| WARNING | Shows only errors (of all kinds) |
+-----------+-----------------------------------------------+
| INFO | Shows only status-related messages and errors |
+-----------+-----------------------------------------------+
| DEBUG | Shows all possible information |
+-----------+-----------------------------------------------+
-----------------
Save session data
-----------------
.. danger::
This is an experimental feature, it is still recommended to use regular .blend save.
The save session data allows you to create a backup of the session data.
When you hit the **save session data** button, the following popup dialog will appear.
It allows you to choose the destination folder and if you want to run an auto-save.
.. figure:: img/quickstart_save_session_data_dialog.png
:align: center
Save session data dialog.
If you enabled the auto-save option, you can cancel it from the **Cancel auto-save** button.
.. figure:: img/quickstart_save_session_data_cancel.png
:align: center
Cancel session autosave.
To import session data backups, use the following **Multiuser session snapshot** import dialog
.. figure:: img/quickstart_import_session_data.png
:align: center
Import session data dialog.
.. note::
It is not yet possible to start a session directly from a backup.
.. _advanced:

View File

@ -0,0 +1,59 @@
========
Glossary
========
.. glossary::
.. _admin:
administrator
*A session administrator can manage users (kick) and hold write access on
each datablock. They can also init a dedicated server repository.*
.. _session-status:
session status
*Located in the title of the multi-user panel, the session status shows
you the connection state.*
.. figure:: img/quickstart_session_status.png
:align: center
Session status in panel title bar
All possible connection states are listed here with their meaning:*
+--------------------+---------------------------------------------------------------------------------------------+
| State | Description |
+--------------------+---------------------------------------------------------------------------------------------+
| WARMING UP DATA | Commiting local data |
+--------------------+---------------------------------------------------------------------------------------------+
| FETCHING | Dowloading snapshot from the server |
+--------------------+---------------------------------------------------------------------------------------------+
| AUTHENTICATION | Initial server authentication |
+--------------------+---------------------------------------------------------------------------------------------+
| ONLINE | Connected to the session |
+--------------------+---------------------------------------------------------------------------------------------+
| PUSHING | Init the server repository by pushing ours |
+--------------------+---------------------------------------------------------------------------------------------+
| INIT | Initial state |
+--------------------+---------------------------------------------------------------------------------------------+
| QUITTING | Exiting the session |
+--------------------+---------------------------------------------------------------------------------------------+
| LAUNCHING SERVICES | Launching local services. Services are spetialized daemons running in the background. ) |
+--------------------+---------------------------------------------------------------------------------------------+
| LOBBY | The lobby is a waiting state triggered when the server repository hasn't been initiated yet |
| | |
| | Once initialized, the server will automatically launch all client in the **LOBBY**. |
+--------------------+---------------------------------------------------------------------------------------------+
.. _common-right:
common right
When a data block is under common right, it is available to everyone for modification.
The rights will be given to the user that selects it first.

View File

@ -1,54 +0,0 @@
.. _how-to-host:
How to host a session
=====================
------------
Local server
------------
The multi-user add-on relies on a Client-Server architecture.
The server is the heart of the collaborative session.
It is what allows user's blender instances to communicate with each other.
In simple terms, *Hosting a session* means *run a local server and connect the local client to it*.
When we say **local server** we mean a server which is accessible from the LAN (Local Area Network) without requiring an internet connection.
.. _local-setup:
When the hosting process starts, the multi-user addon will launch a local server instance.
In the **Hosting** panel configure your server according to:
.. figure:: img/first_time_server_host.png
:align: center
Hosting panel
* **Init the session from**: the session initialisation method.
* **current scenes**: start with the data loaded in the current blend file.
* **an empty scene**: clear the blend file's data and start over.
* **Port**: port on which the server is listening.
* **Server password**: (*optional*) the server password.
* **Admin password**: (*optional*) the session administration password.
Once everything is set up, you can hit the **Host** button to launch the session!
This will do two things:
* Start a local server
* Connect you to it as an :ref:`admin`
.. danger::
By starting from an empty scene, all of the blend data will be removed!
Be sure to save your existing work before launching the session.
-------------
Online server
-------------
However, there are times when you will need to host a session over the internet.
In this case, we strongly recommend that you read the :ref:`hosting_on_internet` tutorial.
During an online session, various actions are available to you, go to :ref:`how-to-manage` section to
learn more about them.

View File

@ -1,104 +0,0 @@
.. _how-to-join:
How to join a session
=====================
This section describes how to join a launched session.
Before starting make sure that you have access to the session **IP address**, **port number** and that you have filled in your **user information** (name and color).
-----------
Server List
-----------
The server list allows you to manage your servers:
.. figure:: img/quickstart_serverlist.png
:align: center
:width: 200px
Server List
To connect to a server, select the one you want to join in the list and click on **Connect**.
To know if the server you want to join is online, you can refresh your server list with the button on the top right corner.
Online status:
- **Red**: server is offline
- **Green**: server is online
.. note::
If a server is secured with a password, a lock will be displayed next to the server name. You first need to enter the password of the server in its preset to join it.
.. figure:: img/quickstart_serverlist_private.png
:align: center
:width: 200px
It is possible to **add**, **delete** and even **modify** a **server preset** with the buttons located on the top right of the server list:
.. figure:: img/quickstart_serverlist_manage_buttons.png
:align: center
:width: 200px
Add, Remove, Edit Server Preset
.. note::
Two server presets are already present when the addon is launched:
- The 'localhost' preset, to join a local session quickly
- The 'public session' preset, to join the public sessions of the multi-user server (official discord to participate : https://discord.gg/aBPvGws)
-------------------
Add a Server Preset
-------------------
To add a server, you must first register it in the server list. Click on the **+** icon and fill in the window with the server settings:
.. figure:: img/quickstart_server_edit.png
:align: center
:width: 350px
Server Preset pop-up
- **Server name**: the name of the server.
- **IP**: the host's IP address.
- **Port**: the host's port number.
- **Server password**: (*optional*) the server password.
- **Admin password**: (*optional*) the session administration password.
Once you've configured every field, you can save the server preset by clicking **OK**.
You can now select it in the server list to join the session !
.. warning:: Be careful, if you don't rename your new preset, or if it has the same name as an existing preset, the old preset will be overwritten.
----------------
Joining a server
----------------
CONNECT
-------
When joining a server that have already be initialise, the session status screen will be **CONNECT**.
You are now connected and can start creating.
.. figure:: img/quickstart_connect.png
:align: center
In session
During an online session, various actions are available to you. Go to :ref:`how-to-manage` to
learn more about them.
LOBBY
-----
When starting a **dedicated server**, the session status screen will take you to the **LOBBY** (see side-panel header).
If the session status is set to **LOBBY** and you are a regular user, you need to wait for the admin to launch the scene (admins have shield next to their names).
If you are the admin, you just need to initialise the session to start it (see image below).
.. figure:: img/quickstart_lobby.png
:align: center
Session initialisation for dedicated server

View File

@ -1,135 +0,0 @@
.. _how-to-manage:
How to manage a session
=======================
The quality of a collaborative session directly depends on the quality of the network connection, and the communication between the users. This section describes
various tools which have been made in an effort to ease the communication between your fellow creators.
Feel free to suggest any ideas for communication tools `here <https://gitlab.com/slumber/multi-user/-/issues/75>`_ .
--------------------
Monitor online users
--------------------
One of the most vital tools is the **Online user panel**. It lists all connected
users' information including your own:
* **Role** : admin/regular user.
* **Username** : name of the user.
* **Mode** : user's active mode (object, sculpt, paint,etc.).
* **Frame**: on which frame the user is working.
* **Location**: where the user is actually working.
* **Ping**: user's connection delay in milliseconds.
.. figure:: img/quickstart_users.png
:align: center
Online user panel
By selecting a user in the list you'll have access to different users' related **actions**.
Those operators allow you to experience the selected user's state in two different dimensions: **SPACE** and **TIME**.
Snapping in space
-----------------
The **CAMERA button** (Also called **snap view** operator) allow you to snap to
the user's viewpoint. To disable the snap, click on the button once again. This action
serves different purposes such as easing the review process, and working together on a large or populated world.
.. hint::
If the target user is located in another scene, the **snap view** operator will send you to their scene.
.. figure:: img/quickstart_snap_camera.gif
:align: center
Snap view in action
Snapping in time
----------------
The **CLOCK button** (Also called **snap time** operator) allows you to snap to
the user's time (current frame). To disable the snap, click on the button once again.
This action helps various multiple creators to work in the same time-frame
(for instance multiple animators).
.. figure:: img/quickstart_snap_time.gif
:align: center
Snap time in action
Kick a user
-----------
.. warning:: Only available for :ref:`admin` !
The **CROSS button** (Also called **kick** operator) allows the administrator to kick the selected user. This can be helpful if a user is acting unruly, but more importantly, if they are experiencing a high ping which is slowing down the scene. Meanwhile, in the target user's world, the session will properly disconnect.
---------------------------
Change replication behavior
---------------------------
During a session, multi-user will replicate all of your local modifications to the scene, to all other users' blender instances.
In order to avoid annoying other users when you are experimenting, you can flag some of your local modifications to be ignored via
various flags present at the top of the panel (see red area in the image below). Those flags are explained in the :ref:`replication` section.
.. figure:: img/quickstart_synchronize.png
:align: center
Session replication flags
-----------
Manage data
-----------
In order to understand replication data managment, a quick introduction to the multi-user data workflow is in order.
The first thing to know: until now, the addon relies on data-based replication. In simple words, it means that it replicates
the resultant output of a user's actions.
To replicate datablocks between clients, multi-user relies on a standard distributed architecture:
- The server stores the "master" version of the work.
- Each client has a local version of the work.
When an artist modifies something in the scene, here is what is happening in the background:
1. Modified data are **COMMITTED** to the local repository.
2. Once committed locally, they are **PUSHED** to the server
3. As soon as the server receives updates, they are stored locally and pushed to every other client
At the top of this data management system, a rights management system prevents
multiple users from modifying the same data at the same time. A datablock may belong to
a connected user or be under :ref:`common-right<**COMMON**>` rights.
.. note::
In a near future, the rights management system will support roles to allow multiple users to
work on different aspects of the same datablock.
The Repository panel (see image below) allows you to monitor, change datablock states and rights manually.
.. figure:: img/quickstart_repository.png
:align: center
Repository panel
The **show only owned** flag allows you to see which datablocks you are currently modifying.
.. warning::
If you are editing a datablock not listed with this flag enabled, it means that you have not been granted the rights to modify it.
So, it won't be updated to other clients!
Here is a quick list of available actions:
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| icon | Action | Description |
+=======================================+===================+====================================================================================+
| .. image:: img/quickstart_push.png | **Push** | push data-block to other clients |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| .. image:: img/quickstart_pull.png | **Pull** | pull last version into blender |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| .. image:: img/quickstart_refresh.png | **Reset** | Reset local change to the server version |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| .. image:: img/quickstart_unlock.png | **Lock/Unlock** | If locked, does nothing. If unlocked, grant modification rights to another user. |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| .. image:: img/quickstart_remove.png | **Delete** | Remove the data-block from network replication |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

View File

@ -3,13 +3,10 @@ Getting started
=============== ===============
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 1
:name: toc-getting-started
install install
update
quickstart quickstart
how-to-join
how-to-host
how-to-manage
troubleshooting troubleshooting
glossary

View File

@ -1,39 +1,58 @@
===================== ============
Installing Multi-User Installation
===================== ============
.. warning:: Under development, use it at your own risks.
Multi-User is often updated. You can keep up to date with the latest changes through the release notes on our `Discord Server <https://discord.com/invite/aBPvGws>`_.
Download
========
`Stable Release <https://gitlab.com/slumber/multi-user/-/jobs/artifacts/master/download?job=build>`__
**Recommended**. A package packed with the latest features and is considered stable without regressions.
`Latest Release <https://gitlab.com/slumber/multi-user/-/jobs/artifacts/develop/download?job=build>`__
**Experimental**. A package updated almost daily to include the newest changes in development.
These versions are not as thoroughly tested as the stable release, and might break.
Install
=======
.. hint:: .. hint::
The process is the same for linux, mac and windows. The process is the same for linux, mac and windows.
1. Download the addon zip file 1. Download `LATEST build <https://gitlab.com/slumber/multi-user/-/jobs/artifacts/develop/download?job=build>`_ or `STABLE build <https://gitlab.com/slumber/multi-user/-/jobs/artifacts/master/download?job=build>`_.
2. Run blender as administrator (to allow python dependencies auto-installation). 2. Run blender as administrator (to allow python dependencies auto-installation).
3. Install **multi-user.zip** from your addon preferences in :menuselection:`Edit --> Preferences --> Add-ons --> Install`. 3. Install **multi-user.zip** from your addon preferences.
.. figure:: img/settings.png Once the addon is succesfully installed, I strongly recommend you to follow the :ref:`quickstart`
:align: center
:width: 500px
The Addon Preferences Pannel
Once the addon is succesfully installed, we strongly recommend you to follow the :ref:`quickstart`
tutorial. tutorial.
.. toctree:: .. _update-version:
:maxdepth: 1
Updates
=======
Multi-User has a built-in auto-update function.
1. Navigate to Edit >> Preferences pane in Blender, and go to the 'Add-ons' section.
2. Search 'multi-user', select the 'Update' tab, click 'Auto-check for Update' and choose the frequency you'd like.
3. Make sure to click the three bars in the bottom-left, and save this to your preferences (userpref.blend).
Sometimes you'd like to perform manual update, or even side-grade or rollback your multi-user version. Perhaps you are trying out new features from the 'develop' branch in a test session.
1. Click on 'Check now for multiuser update'. Multi-user will now find new versions
.. figure:: img/update_1.jpg
:align: center
:width: 300px
Check for updates
2. Select 'Install latest master / old version'
.. figure:: img/update_2.jpg
:align: center
:width: 300px
Install
3. In most cases, select 'master' branch for the latest stable release. The unstable 'develop' branch and older releases are available
.. figure:: img/update_3.jpg
:align: center
:width: 300px
Select version
4. Finally, restart blender to use the updated version
.. figure:: img/update_4.jpg
:align: center
:width: 300px
Restart blender

View File

@ -1,48 +1,486 @@
.. _quickstart: .. _quickstart:
Quick Start ===========
Quick start
=========== ===========
Welcome to the Multi-User manual. .. hint::
You will find here all the documentation necessary for the good use of the addon: :ref:`index-manual` *All session-related settings are located under: `View3D -> Sidebar -> Multiuser panel`*
First of all, let's have a quick look at the Multi-User features.
Username and color
------------------
When you launch the addon for the first time you can find this panel in the Sidebar of your View3D:
.. figure:: img/first_time_menu.png
:align: center
1. Choose a **name** and a **color** that will be specific to you and that will allow others to identify you easily once in session. Don't worry, they can be changed at any time in :menuselection:`Edit --> Prerecences --> Add-ons --> Multi-user` or in :menuselection:`Multi-User Pannel --> General Settings`.
2. Press **Continue**
Multi-User side pannel
----------------------
Once the Multi-User is launched you will arrive directly on the main menu:
.. figure:: img/first_time_server_list.png
:align: center
Three panels are at your disposal:
- **Server list**: You can add, delete and edit server presets according to your preferences. At first launch two servers will already be in your preferences: *Public Session*, the public server of the Multi-User Discord, *Localhost*, to connect locally to your server.
- **Hosting**: To locally host a session with a Blender instance.
- **General Settings**: Include advanced addon settings like *user info*, *server ping*, *cache*, etc.
Session management
------------------
The multi-user addon provides a session management system. The multi-user addon provides a session management system.
In this guide, you will quickly learn how to use the collaborative session management system in three parts: In this guide, you will quickly learn how to use the collaborative session management system in three parts:
- :ref:`how-to-join`
- :ref:`how-to-host` - :ref:`how-to-host`
- :ref:`how-to-join`
- :ref:`how-to-manage` - :ref:`how-to-manage`
For more details on what the addon offers: .. _how-to-host:
.. - :ref: How to host a session
=====================
The multi-user add-on relies on a Client-Server architecture.
The server is the heart of the collaborative session.
It is what allows user's blender instances to communicate with each other.
In simple terms, *Hosting a session* means *run a local server and connect the local client to it*.
When I say **local server** I mean a server which is accessible from the LAN (Local Area Network) without requiring an internet connection.
However, there are times when you will need to host a session over the internet.
In this case, I strongly recommend that you read the :ref:`internet-guide` tutorial.
.. _user-info:
--------------------------------
1. Fill in your user information
--------------------------------
The **User Info** panel (See image below) allows you to customise your online identity.
.. figure:: img/quickstart_user_info.png
:align: center
User info panel
Let's fill in those two fields:
- **name**: your online name.
- **color**: a color used to represent you in other users' workspaces (see image below).
During online sessions, other users will see your selected object and camera highlighted in your profile color.
.. _user-representation:
.. figure:: img/quickstart_user_representation.png
:align: center
User viewport representation aka 'User Presence'
---------------------
2. Set up the network
---------------------
When the hosting process starts, the multi-user addon will launch a local server instance.
In the network panel, select **HOST**.
The **Host sub-panel** (see image below) allows you to configure the server according to:
* **Port**: Port on which the server is listening.
* **Start from**: The session initialisation method.
* **current scenes**: Start with the data loaded in the current blend file.
* **an empty scene**: Clear the blend file's data and start over.
.. danger::
By starting from an empty scene, all of the blend data will be removed!
Be sure to save your existing work before launching the session.
* **Admin password**: The session administration password.
.. figure:: img/quickstart_host.png
:align: center
:alt: host menu
Host network panel
.. note:: Additional configuration setting can be found in the :ref:`advanced` section.
Once everything is set up, you can hit the **HOST** button to launch the session!
This will do two things:
* Start a local server
* Connect you to it as an :ref:`admin`
During an online session, various actions are available to you, go to :ref:`how-to-manage` section to
learn more about them.
.. _how-to-join:
How to join a session
=====================
This section describes how join a launched session.
Before starting make sure that you have access to the session IP address and port number.
--------------------------------
1. Fill in your user information
--------------------------------
Joining a server
=======================
--------------
Network setup
--------------
In the network panel, select **JOIN**.
The **join sub-panel** (see image below) allows you to configure your client to join a
collaborative session which is already hosted.
.. figure:: img/server_preset_image_normal_server.png
:align: center
:width: 200px
Connection pannel
Fill in the fields with your information:
- **IP**: the host's IP address.
- **Port**: the host's port number.
Once you've configured every field, hit the button **CONNECT** to join the session !
When the :ref:`session-status` is **ONLINE** you are online and ready to start co-creating.
.. note::
If you want to have **administrator rights** (see :ref:`admin` ) on the server, just enter the password created by the host in the **Connect as admin** section
.. figure:: img/server_preset_image_admin.png
:align: center
:width: 200px
Admin password
---------------
Server presets
---------------
You can save your server presets in a preset list below the 'JOIN' and 'HOST' buttons. This allows you to quickly access and manage your servers.
To add a server, first enter the ip address and the port (plus the password if needed), then click on the + icon to add a name to your preset. To remove a server from the list, select it and click on the - icon.
.. figure:: img/server_preset_exemple.gif
:align: center
:width: 200px
.. warning:: Be careful, if you don't rename your new preset, or if it has the same name as an existing preset, the old preset will be overwritten.
.. figure:: img/server_preset_image_report.png
:align: center
:width: 200px
.. note::
Two presets are already present when the addon is launched:
- The 'localhost' preset, to host and join a local session quickly
- The 'public session' preset, to join the public sessions of the multi-user server (official discord to participate : https://discord.gg/aBPvGws)
.. note::
Additional configuration settings can be found in the :ref:`advanced` section.
.. note::
When starting a **dedicated server**, the session status screen will take you to the **LOBBY**, awaiting an admin to start the session.
If the session status is set to **LOBBY** and you are a regular user, you need to wait for the admin to launch the scene.
If you are the admin, you just need to initialise the repository to start the session (see image below).
.. figure:: img/quickstart_session_init.png
:align: center
Session initialisation for dedicated server
During an online session, various actions are available to you. Go to :ref:`how-to-manage` to
learn more about them.
.. _how-to-manage:
How to manage a session
=======================
The quality of a collaborative session directly depends on the quality of the network connection, and the communication between the users. This section describes
various tools which have been made in an effort to ease the communication between your fellow creators.
Feel free to suggest any ideas for communication tools `here <https://gitlab.com/slumber/multi-user/-/issues/75>`_ .
---------------------------
Change replication behavior
---------------------------
During a session, multi-user will replicate all of your local modifications to the scene, to all other users' blender instances.
In order to avoid annoying other users when you are experimenting, you can flag some of your local modifications to be ignored via
various flags present at the top of the panel (see red area in the image below). Those flags are explained in the :ref:`replication` section.
.. figure:: img/quickstart_replication.png
:align: center
Session replication flags
--------------------
Monitor online users
--------------------
One of the most vital tools is the **Online user panel**. It lists all connected
users' information including your own:
* **Role** : if a user is an admin or a regular user.
* **Username** : Name of the user.
* **Mode** : User's active editing mode (edit_mesh, paint,etc.).
* **Frame**: When (on which frame) the user is working.
* **Location**: Where the user is actually working.
* **Ping**: user's connection delay in milliseconds
.. figure:: img/quickstart_users.png
:align: center
Online user panel
By selecting a user in the list you'll have access to different users' related **actions**.
Those operators allow you to experience the selected user's state in two different dimensions: **SPACE** and **TIME**.
Snapping in space
-----------------
The **CAMERA button** (Also called **snap view** operator) allow you to snap to
the user's viewpoint. To disable the snap, click on the button once again. This action
serves different purposes such as easing the review process, and working together on a large or populated world.
.. hint::
If the target user is located in another scene, the **snap view** operator will send you to their scene.
.. figure:: img/quickstart_snap_view.gif
:align: center
Snap view in action
Snapping in time
----------------
The **CLOCK button** (Also called **snap time** operator) allows you to snap to
the user's time (current frame). To disable the snap, click on the button once again.
This action helps various multiple creators to work in the same time-frame
(for instance multiple animators).
.. figure:: img/quickstart_snap_time.gif
:align: center
Snap time in action
Kick a user
-----------
.. warning:: Only available for :ref:`admin` !
The **CROSS button** (Also called **kick** operator) allows the administrator to kick the selected user. This can be helpful if a user is acting unruly, but more importantly, if they are experiencing a high ping which is slowing down the scene. Meanwhile, in the target user's world, the session will properly disconnect.
Change users display
--------------------
Presence is the multi-user module responsible for displaying user presence. During the session,
it draw users' related information in your viewport such as:
* Username
* User point of view
* User active mode
* User selection
.. figure:: img/quickstart_presence.png
:align: center
Presence show flags
The presence overlay panel (see image above) allows you to enable/disable
various drawn parts via the following flags:
- **Show session status**: display the session status in the viewport
.. figure:: img/quickstart_status.png
:align: center
- **Text scale**: session status text size
- **Vertical/Horizontal position**: session position in the viewport
- **Show selected objects**: display other users' current selections
- **Show users**: display users' current viewpoint
- **Show different scenes**: display users working on other scenes
-----------
Manage data
-----------
In order to understand replication data managment, a quick introduction to the multi-user data workflow is in order.
The first thing to know: until now, the addon relies on data-based replication. In simple words, it means that it replicates
the resultant output of a user's actions.
To replicate datablocks between clients, multi-user relies on a standard distributed architecture:
- The server stores the "master" version of the work.
- Each client has a local version of the work.
When an artist modifies something in the scene, here is what is happening in the background:
1. Modified data are **COMMITTED** to the local repository.
2. Once committed locally, they are **PUSHED** to the server
3. As soon as the server receives updates, they are stored locally and pushed to every other client
At the top of this data management system, a rights management system prevents
multiple users from modifying the same data at the same time. A datablock may belong to
a connected user or be under :ref:`common-right<**COMMON**>` rights.
.. note::
In a near future, the rights management system will support roles to allow multiple users to
work on different aspects of the same datablock.
The Repository panel (see image below) allows you to monitor, change datablock states and rights manually.
.. figure:: img/quickstart_save_session_data.png
:align: center
Repository panel
The **show only owned** flag allows you to see which datablocks you are currently modifying.
.. warning::
If you are editing a datablock not listed with this flag enabled, it means that you have not been granted the rights to modify it.
So, it won't be updated to other clients!
Here is a quick list of available actions:
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| icon | Action | Description |
+=======================================+===================+====================================================================================+
| .. image:: img/quickstart_push.png | **Push** | push data-block to other clients |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| .. image:: img/quickstart_pull.png | **Pull** | pull last version into blender |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| .. image:: img/quickstart_refresh.png | **Reset** | Reset local change to the server version |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| .. image:: img/quickstart_unlock.png | **Lock/Unlock** | If locked, does nothing. If unlocked, grant modification rights to another user. |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
| .. image:: img/quickstart_remove.png | **Delete** | Remove the data-block from network replication |
+---------------------------------------+-------------------+------------------------------------------------------------------------------------+
Save session data
-----------------
.. danger::
This is an experimental feature, until the stable release it is highly recommended to use regular .blend save.
The save session data allows you to create a backup of the session data.
When you hit the **save session data** button, the following popup dialog will appear.
It allows you to choose the destination folder and if you want to run an auto-save.
.. figure:: img/quickstart_save_session_data_dialog.png
:align: center
Save session data dialog.
If you enabled the auto-save option, you can cancel it from the **Cancel auto-save** button.
.. figure:: img/quickstart_save_session_data_cancel.png
:align: center
Cancel session autosave.
To import session data backups, use the following **Multiuser session snapshot** import dialog
.. figure:: img/quickstart_import_session_data.png
:align: center
Import session data dialog.
.. note::
It is not yet possible to start a session directly from a backup.
.. _advanced:
Advanced settings
=================
This section contains optional settings to configure the session behavior.
.. figure:: img/quickstart_advanced.png
:align: center
Advanced configuration panel
-------
Network
-------
.. figure:: img/quickstart_advanced_network.png
:align: center
Advanced network settings
**Timeout (in milliseconds)** is the maximum ping authorized before auto-disconnecting.
You should only increase it if you have a bad connection.
.. _replication:
-----------
Replication
-----------
.. figure:: img/quickstart_advanced_replication.png
:align: center
Advanced replication settings
**Synchronize render settings** (only host) enable replication of EEVEE and CYCLES render settings to match renders between clients.
**Synchronize active camera** sync the scene's active camera.
**Edit Mode Updates** enable objects to update while you are in Edit_Mode.
.. warning:: Edit Mode Updates kills the session's performance with complex objects (heavy meshes, gpencil, etc...).
**Update method** allows you to change how replication updates are triggered. Until now, two update methods are implemented:
- **Default**: Use external threads to monitor datablocks changes. Slower and less accurate.
- **Despgraph ⚠️**: Use the blender dependency graph to trigger updates. Faster but experimental and unstable !
**Properties frequency grid** set a custom replication frequency for each type of data-block:
- **Refresh**: pushed data update rate (in second)
- **Apply**: pulled data update rate (in second)
-----
Cache
-----
Multi-user allows you to replicate external dependencies such as images (textures, hdris, etc...), movies, and sounds.
On each client, the files will be stored in the multi-user cache folder.
.. figure:: img/quickstart_advanced_cache.png
:align: center
Advanced cache settings
**cache_directory** choose where cached files (images, sound, movies) will be saved.
**Clear memory filecache** will save memory space at runtime by removing the file content from memory as soon as it has been written to the disk.
**Clear cache** will remove all files from the cache folder.
.. warning:: Clearing the cache could break your scene images/movies/sounds if they are used in a blend file! Try saving the blend file and choosing 'Pack all into blend' before clearing the cache.
---
Log
---
.. figure:: img/quickstart_advanced_logging.png
:align: center
Advanced log settings
**log level** allows you to set the level of detail captured in multi-user's logging output. Here is a brief description on the level of detail for each value of the logging parameter:
+-----------+-----------------------------------------------+
| Log level | Description |
+===========+===============================================+
| ERROR | Shows only critical errors |
+-----------+-----------------------------------------------+
| WARNING | Shows only errors (of all kinds) |
+-----------+-----------------------------------------------+
| INFO | Shows only status-related messages and errors |
+-----------+-----------------------------------------------+
| DEBUG | Shows all possible information |
+-----------+-----------------------------------------------+

View File

@ -6,6 +6,7 @@ Troubleshooting
The majority of issues new users experience when first using Multi-User can be solved with a few quick checks. The majority of issues new users experience when first using Multi-User can be solved with a few quick checks.
- Run Blender in Administrator mode
- Update the multi-user addon to the latest version - Update the multi-user addon to the latest version
- Make sure to allow Blender through your firewall - Make sure to allow Blender through your firewall
@ -13,5 +14,6 @@ The majority of issues new users experience when first using Multi-User can be s
- Solve problems with your connection quality - Solve problems with your connection quality
- Minimise the use of large textures or file sizes - Minimise the use of large textures or file sizes
- Avoid using 'Undo'. Use 'delete' instead
Use the #support channel on the multi-user `discord server <https://discord.gg/aBPvGws>`_ to chat, seek help and contribute. Use the #support channel on the multi-user `discord server <https://discord.gg/aBPvGws>`_ to chat, seek help and contribute.

View File

@ -1,57 +0,0 @@
================
Update the Addon
================
Multi-User has a built-in auto-update function in its preferences.
Auto-Update
-----------
1. Enable it by clicking 'Auto-check for Update' and choose the frequency you'd like.
2. **Make sure to click the three bars in the bottom-left, and save this to your preferences**
.. figure:: img/auto_updater_location.png
:align: center
:width: 500px
Update menu in the addon preferences pannel
Manual Update
-------------
Sometimes you'd like to perform manual update, or even side-grade or rollback your multi-user version. Perhaps you are trying out new features from the 'develop' branch in a test session.
1. Click on 'Check now for multiuser update'. Multi-user will now find new versions
.. figure:: img/auto_updater_check.png
:align: center
:width: 500px
Check for updates
1. Select 'Install latest master / old version'
.. figure:: img/auto_updater_last.png
:align: center
:width: 500px
Install
1. In most cases, select 'master' branch for the latest stable release. The unstable 'develop' branch and older releases are available
.. figure:: img/auto_updater_version.png
:align: center
:width: 500px
Select version
4. Finally, restart blender to use the updated version
.. figure:: img/auto_updater_restart.png
:align: center
:width: 500px
Restart blender
.. toctree::
:maxdepth: 1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 KiB

After

Width:  |  Height:  |  Size: 409 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

View File

@ -1,92 +1,66 @@
.. _index-manual:
===================================== =====================================
Multi-user 0.5.0 Reference Manual Welcome to Multi-user's documentation
===================================== =====================================
Welcome to the manual of the Multi-user, a free and open source blender addon. It tool aims to bring multiple users to work on the same .blend over the network.
Join our `discord server <https://discord.gg/aBPvGws>`_ to get help and join collaborative creation sessions.
.. warning:: Still under development
.. image:: img/homepage_ban.png .. image:: img/homepage_ban.png
The multi-user addon is a free and open source blender plugin. It tool aims to bring multiple users to work on the same .blend over the network.
Getting started .. warning:: Under development, use it at your own risks.
===============
.. only:: builder_html and (not singlehtml)
.. container:: tocdescr
.. container:: descr
:doc:`about/index`
.. container:: descr
:doc:`getting_started/install`
.. container:: descr
:doc:`getting_started/quickstart`
.. container:: descr
:doc:`troubleshooting/index`
Sections
Main Features
=============
- Collaborative workflow in blender
- Viewport users presence (active selection, POV)
- Datablocks right managment
- Tested under Windows
Community
========= =========
.. only:: builder_html and (not singlehtml) A `discord server <https://discord.gg/aBPvGws>`_ have been created to provide help for new users and
organize collaborative creation sessions.
.. container:: tocdescr Status
======
.. container:: descr .. image:: img/homepage_roadmap.png
.. figure:: /img/index_ui.png
:target: ui/index.html
:doc:`/ui/index`
An introduction to Multi-User's interface.
.. container:: descr
.. figure:: /img/index_advanced.png
:target: advanced/index.html
:doc:`/general_settings/index`
Overview of the general settings.
.. container:: descr
.. figure:: /img/index_hosting_internet.png
:target: hosting_internet/index.html
:doc:`/hosting_internet/index`
A tutorial to host a collaborative Multi-User session on the internet.
.. .. container:: descr
.. .. figure:: /img/index_workflow.png
.. :target: workflow/index.html
.. :doc:`/workflow/index`
.. A guide to understand collaborative workflow in 3D.
.. only:: latex or epub or singlehtml Follow the `roadmap <https://gitlab.com/slumber/multi-user/-/boards/929107>`_ to be aware of last news.
.. toctree:: Documentation is organized into the following sections:
:maxdepth: 1
.. toctree::
:maxdepth: 1
:caption: About
:name: sec-about
about/introduction
.. toctree::
:maxdepth: 1
:caption: Getting started
:name: sec-learn
about/index.rst getting_started/install
getting_started/index.rst getting_started/quickstart
ui/index.rst getting_started/glossary
general_settings/index.rst getting_started/troubleshooting
hosting_internet/index.rst
troubleshooting/index.rst
ways_to_contribute/index.rst
.. toctree::
:maxdepth: 1
:caption: Tutorials
:name: sec-tutorials
tutorials/hosting_guide
.. toctree::
:maxdepth: 1
:caption: Community
:name: sec-community
ways_to_contribute

View File

@ -1,18 +0,0 @@
/*
* This stylesheet is applied after the theme's default one,
* and thus any overrides or additions can be added here.
*
* More info:
* https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_css_file
*/
/* Allow text to flow around right aligned images */
.align-right {
float: right;
margin: 0 0 24px 24px;
}
/* Prevent images from flowing into other headings */
h1, h2, h3, h4, h5, h6 {
clear: both;
}

View File

@ -1,326 +0,0 @@
/*
* This stylesheet is applied after the theme's default one,
* and thus any overrides or additions can be added here.
*
* More info:
* https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_css_file
*/
h5 {margin-bottom: 5px}
/* Sidebar menu links. */
.wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a:hover {background: #c0c0c0}
.wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a:hover {background: #b5b5b5}
.wy-menu-vertical li.toctree-l4 {font-size: 1em}
.wy-menu-vertical li.current a {border: 0}
.wy-side-nav-search > a:hover {background: none; opacity: 0.9}
.wy-side-nav-search > a.icon::before {content: none}
/* Ensure background of input fields is light color even when a local theme wants it to be dark. */
input[type="text"], input[type="search"], input[type="password"],
input[type="email"], input[type="url"],
input[type="date"], input[type="month"], input[type="week"], input[type="time"],
input[type="datetime"], input[type="datetime-local"],
input[type="number"], input[type="tel"], input[type="color"] {
background-color:#FCFCFC;
}
/* Boxed paragraphs. */
.rst-content .refbox .admonition-title {background-color: #bbb}
.rst-content .refbox {background-color: #e3e3e3}
.rst-content .seealso .admonition-title {background-color: #7a87e6}
.rst-content .seealso {background-color: #e7ebfa}
.rst-content .important .admonition-title {background-color: #ddca3b}
.rst-content .important {background-color: #f6f3a5}
/* refbox =, seealso ( > ), note ( i ), tip i , hint (+), warn / ! \ */
.refbox .admonition-title::before {content:"\f00b"}
.seealso .admonition-title::before{content:"\f138"}
.note .admonition-title::before{content:"\f05a"}
.tip .admonition-title::before{content:"\f129"; width: 0.75em; text-align: center}
.hint .admonition-title::before{content:"\f055"}
.warning .admonition-title::before{content:"\f071"}
/* 'refbox' field. */
.refbox .field-list .field-name, .refbox .field-list .field-body {
padding: 0px;
}
.refbox dl dt {font-weight: normal}
/* Ugly 'red' literals. */
.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal {
color:#404040;
}
/* Literal blocks that use too much padding, make them look like regular literals. */
.rst-content pre.literal-block {
font-size: 75%;
margin:0;
padding:2px 4px;
color:#404040;
background: #ffffff;
white-space: normal;
display: inline;
}
/* Fix definisions with different ids. */
.rst-content dl.simple {
margin-bottom: 0px;
}
/* Fix nested block spacing. */
.rst-content .document dl dt,
.rst-content dd dl,
.rst-content dl.field-list dd > p {
margin: 0;
}
/* Dont indent field lists */
.rst-content dl.field-list dt {
padding-left: 0 !important;
}
/* Fix padding for normal definitions nested in field lists */
.rst-content dl.field-list dd > dl.simple {
padding-top: 12px;
}
/* Without this, paragraphs in bullet points within definition lists have too much vertical padding. */
.rst-content li > p {
margin-bottom: 0px !important;
}
/* TABLE & FIGURE */
/* captions text style */
.rst-content .figure .caption,
.rst-content table.docutils caption,
.rst-content table.field-list caption {
font: italic 90%/18px Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif;
color: #808080;
}
/* Captions top padding. */
.rst-content .figure .caption { margin-top: 4px; }
.rst-content table.docutils caption { padding: 0.5em; }
/* Text word wrap. */
.wy-table-responsive table td,
.wy-table-responsive table th { white-space: normal; }
/* Cell's vertical align. */
/* use "valign" class for middle align. */
.rst-content table.docutils:not(.valign) td { vertical-align: baseline; }
/* Field list align. */
.rst-content table.field-list td { padding-top: 8px; }
/* Table header cells border color. */
.rst-content table.docutils th { border-color: #e1e4e5; }
/* Figure in table margin. */
.rst-content td div.figure {
margin-top: 4px; margin-bottom: 0;
}
/* Figure legend. */
.legend {
font-size: 90%;
color: #484848;
margin-top: -20px;
}
.rst-content dl .legend { margin-top: -10px; }
@media screen and (max-width: 768px){
.wy-table-responsive table:not(.footnote) { min-width: 520px; }
.rst-content table.docutils caption { text-align: left; }
img { width: auto; }
}
/* End TABLE & FIGURE. */
/* Video center. */
iframe {
display: block;
margin: 0 auto 24px auto;
border: 0;
max-width: 100%;
}
/* Copyright font scale down. */
footer p{ font-size: smaller}
.footer-contribute {
display: block;
font-size: smaller;
margin-top: -12px
}
.footer-contribute li {
display: inline;
list-style-type: none;
padding-right: 20px;
}
/* Quotes for Fig. "link". */
a[href^="#fig-"]::before {content: "\201c";}
a[href^="#fig-"]::after {content: "\201d";}
/* Intermediate headline. */
.rubric {font-family: "Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}
/* ".. container::" lead, block text float around image. */
.lead {
clear: both; width: 100%;
}
/* Mark external links. */
a.external {color:#656AE0;}
/* List blender.org as internal. */
.external[href^="https://www.blender.org"], .external[href^="https://docs.blender.org"], .external[href^="https://wiki.blender.org"] {
color:#2980B9;
}
/* Draws a box around menuselection and kbd role. */
.menuselection, .kbd.docutils.literal {
font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif;
font-size: 90%;
font-weight: normal;
background-color: rgba(255, 255, 255, 0.65);
border: solid #E1E4E5 1px;
white-space: nowrap;
padding: 2px 5px;
}
@media screen and (max-width: 420px) {
.menuselection {white-space: normal}
}
.caption .menuselection {
background-color: transparent;
border: none;
}
.caption .kbd {background-color: transparent}
/* Remove indent on line break. */
.rst-content .line-block {margin-left:0px}
/* Applied on main index:sections. */
/* Start section description. */
@media screen and (min-width: 450px){
.tocdescr {
display: flex; display: -webkit-flex;
flex-flow: row wrap; -webkit-flex-flow: row wrap;
justify-content: space-between; -webkit-justify-content: space-between;
align-items: flex-start; -webkit-align-items: flex-start;
align-content: flex-start; -webkit-align-content: flex-start;
list-style-type: none;
margin-bottom: 10px;
}
/* Dan Andreasson on Stack Overflow. */
.tocdescr:after {
content: "";
flex: 1 0 33.3%; -webkit-flex: 1 0 33.3%;
margin-left: 45px;
align-self: stretch; -webkit-align-self: stretch;
}
}
@media screen and (max-width: 450px) {
.tocdescr {
display: flex; display: -webkit-flex;
flex-flow: column wrap; -webkit-flex-flow: column wrap;
justify-content: space-between; -webkit-justify-content: space-between;
align-items: flex-start; -webkit-align-items: flex-start;
align-content: flex-start; -webkit-align-content: flex-start;
list-style-type: none;
margin-bottom: 10px;
}
.tocdescr:after {
content: "";
flex: none; -webkit-flex: none;
}
}
.descr {
flex: 2 0 33.3%; -webkit-flex: 2 0 33.3%;
margin: 10px 15px;
border-radius: .3em;
user-select: none;
}
.descr div.figure {
margin-bottom: 0px;
display: block;
}
.descr img {
border-top-left-radius: .3em;
border-top-right-radius: .3em;
}
.descr dl {margin-bottom: 10px}
.descr dl dt > a {
display: block;
width: 100%;
margin-bottom: 10px;
}
.descr dl dt a em, .descr dl dt a span{
font-weight: bold;
font-style: normal;
font-size: 1.3em;
}
.descr dl dt{padding: 18px 15px 0px!important}
.descr dl dd{
padding: 0px 15px;
font-style: normal;
margin: 0px;
color: #808080;
font-size: 90%;
}
.descr {
box-shadow: rgba(0,0,0,0.05) 0px 1px 4px 0px,
rgba(211,216,223,0.33) 0px 15px 20px -1px;
}
#getting-started .descr {
box-shadow: none;
}
/* End section description. */
/* Start custom toctree. */
.toctree-wrapper .toctree-l1 > a {margin-bottom: 0.15em}
/* Indent all lines following the first. */
.toctree-wrapper * a {
display: block;
width: 90%;
text-indent: -1em;
margin-left: 1em;/*invert indent*/
padding-top: 0.25em;
line-height: 1.25em;
}
/* Underline provided by nested ul (not li). */
.toctree-wrapper * ul {
padding-left: 2em;
border-top: solid #ececec 1px;
}
.toctree-wrapper > ul {margin-left: 1em}
.rst-content .toctree-wrapper ul li ul {
margin-bottom: 0.75em;
padding-top: 0.5em;
}
.rst-content .toctree-wrapper ul li a:hover {color: #25afef}
.rst-content .toctree-wrapper ul li a:visited:hover {color: #C961DA}
.toctree-wrapper .toctree-l1 > a{font-size: 104%}
.toctree-wrapper .toctree-l2 > a{font-size: 102%}
.toctree-wrapper .toctree-l3 > a{font-size: 100%}
.toctree-wrapper .toctree-l1 > ul{border-color: #bfbfbf}
.toctree-wrapper .toctree-l2 > ul{border-color: #e1e0e0}
.toctree-wrapper .toctree-l3 > ul{border-color: #ececec}
/* Remove list styling, css rule hierarchy. */
.rst-content .toctree-wrapper ul li, .rst-content .toctree-wrapper ul li li , .rst-content .toctree-wrapper ul li li li {
list-style-type: none;
margin-left: 0px;
}
/* End custom toctree. */
/* Start genindex consistency. */
.genindextable * strong {font-weight: normal}
.genindex-jumpbox {margin-bottom: 1.245em}
.indextable {margin-bottom: 1.245em}
/* End genindex consistency. */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -1,8 +1,8 @@
.. _hosting_on_internet: .. _internet-guide:
=================== =======================
Hosting on Internet Hosting on the internet
=================== =======================
.. warning:: .. warning::
Until now, those communications are not encrypted but are planned to be in a mid-term future (`status <https://gitlab.com/slumber/multi-user/issues/62>`_). Until now, those communications are not encrypted but are planned to be in a mid-term future (`status <https://gitlab.com/slumber/multi-user/issues/62>`_).
@ -63,7 +63,7 @@ To create a ZeroTier private network you need to register a ZeroTier account `on
Once you account it activated, you can connect to `my.zerotier.com <https://my.zerotier.com/login>`_. Once you account it activated, you can connect to `my.zerotier.com <https://my.zerotier.com/login>`_.
Head up to the **Network** section (highlighted in red in the image below). Head up to the **Network** section (highlighted in red in the image below).
.. figure:: img/hosting_guide_head_network.png .. figure:: img/hosting_guide_head_network.png
:align: center :align: center
:width: 450px :width: 450px
@ -206,9 +206,9 @@ You can run the dedicated server on any platform by following these steps:
.. code-block:: bash .. code-block:: bash
python -m pip install replication python -m pip install replication==0.1.13
3. Launch the server with: 4. Launch the server with:
.. code-block:: bash .. code-block:: bash
@ -562,7 +562,7 @@ The default Docker image essentially runs the equivalent of:
.. code-block:: bash .. code-block:: bash
replication.server -pwd admin -p 5555 -t 5000 -l DEBUG -lf multiuser_server.log replication.serve -pwd admin -p 5555 -t 5000 -l DEBUG -lf multiuser_server.log
This means the server will be launched with 'admin' as the administrator password, run on ports 5555:5558, use a timeout of 5 seconds, verbose 'DEBUG' log level, and with log files written to 'multiuser_server.log'. See :ref:`cmd-line` for a description of optional parameters. This means the server will be launched with 'admin' as the administrator password, run on ports 5555:5558, use a timeout of 5 seconds, verbose 'DEBUG' log level, and with log files written to 'multiuser_server.log'. See :ref:`cmd-line` for a description of optional parameters.
@ -702,11 +702,19 @@ And your replication server is live! It should stay running in the terminal wind
7. Initialise your Server in Blender 7. Initialise your Server in Blender
------------------------------------ ------------------------------------
Once in Blender, make sure your multi-user addon is updated to the latest version. :ref:`update-version`. Then, follow the instructions from :ref:`how-to-join` and connect as an admin user, using the password you launched the server with and the IP adress of the server. Then, click *connect*. Once in Blender, make sure your multi-user addon is updated to the latest version. :ref:`update-version`. Then, follow the instructions from :ref:`how-to-join` and connect as an admin user, using the password you launched the server with. Input your external IP, and make sure you're set to JOIN the server. Then, click CONNECT.
Now as the admin user, you can click on *init* and choose whether to initialise the server with a preloaded scene, or an empty scene. .. figure:: img/hosting_guide_gcloud_19.jpg
:align: center
:width: 200px
Now your session is live! Now as the admin user, you can choose whether to initialise the server with a preloaded scene, or an empty scene
.. figure:: img/hosting_guide_gcloud_20.jpg
:align: center
:width: 200px
Press okay, and now your session is live!
If you made it this far, congratulations! You can now go ahead and share the external IP address with your friends and co-creators and have fun with real-time collaboration in Blender! If you made it this far, congratulations! You can now go ahead and share the external IP address with your friends and co-creators and have fun with real-time collaboration in Blender!

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

Before

Width:  |  Height:  |  Size: 757 KiB

After

Width:  |  Height:  |  Size: 757 KiB

View File

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 214 KiB

View File

Before

Width:  |  Height:  |  Size: 249 KiB

After

Width:  |  Height:  |  Size: 249 KiB

View File

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

View File

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 230 KiB

View File

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 136 KiB

View File

Before

Width:  |  Height:  |  Size: 687 KiB

After

Width:  |  Height:  |  Size: 687 KiB

View File

Before

Width:  |  Height:  |  Size: 635 KiB

After

Width:  |  Height:  |  Size: 635 KiB

Some files were not shown because too many files have changed in this diff Show More