Compare commits

...

1147 Commits

Author SHA1 Message Date
d433e8f241 fix: transform offset for object animated with a curve constraint
Related to #214
2021-07-06 14:29:20 +02:00
963a551a1e Merge branch '206-draw-active-mode-in-the-object-presence-overlay-2' into 'develop'
Draw active mode in the object presence overlay

See merge request slumber/multi-user!131
2021-07-01 12:57:01 +00:00
d01a434fb7 fix: Review 2021-07-01 14:53:14 +02:00
3a5a5fc633 fix : draw active mode UI side pannel 2021-07-01 11:58:52 +02:00
8926ab44e1 Merge branch '201-improved-image-support' into 'develop'
Resolve "Improved image support"

See merge request slumber/multi-user!136
2021-07-01 09:55:47 +00:00
a8f96581c5 fix: new mode display 2021-06-30 15:34:03 +02:00
440a4cc1cd feat: add mode visibily 2021-06-29 17:10:59 +02:00
a207c51973 fix: image renamin support
fix: sync Color Space Settings

related to #201
2021-06-29 15:59:26 +02:00
e706c8e0bf Merge branch '209-adding-a-scene-create-node-duplicates' into 'develop'
Resolve "Adding a scene create node duplicates"

See merge request slumber/multi-user!135
2021-06-28 08:30:22 +00:00
e590e896da fix: scene duplicates by using data instead of the update id
Related to #209
2021-06-28 10:27:04 +02:00
4140b62a8e Merge branch '119-add-timeline-marker-sync' into 'develop'
Resolve "Add timeline marker sync"

See merge request slumber/multi-user!133
2021-06-24 15:52:12 +00:00
6d9c9c4532 fix: timeline marker selection
feat: basic test
2021-06-24 17:45:34 +02:00
e9e1911840 Merge branch '208-late-update-logging-error' into 'develop'
Resolve "Late update logging error"

See merge request slumber/multi-user!134
2021-06-24 15:28:56 +00:00
ab350ca7bc fix: late update logging error
Related to #208
2021-06-24 17:24:08 +02:00
0a8f0b5f88 feat: add mode overlay 2021-06-24 16:01:14 +02:00
2238a15c11 feat: initial markers support 2021-06-24 15:51:01 +02:00
de73f022e6 merge 2021-06-24 14:52:07 +02:00
f517205647 fix: doc authors 2021-06-24 14:51:00 +02:00
f33c3d8481 fix: doc version 2021-06-24 14:50:12 +02:00
71c69000ec Merge branch '207-repository-panel-filtering-is-boken' into 'develop'
Resolve "Repository panel filtering is boken"

See merge request slumber/multi-user!132
2021-06-24 12:49:06 +00:00
de1e684b3c fix: name filtering 2021-06-24 14:35:59 +02:00
d87730cffb Merge branch '197-user-selection-bounding-box-glitches-for-non-mesh-objects' into 'develop'
User selection bounding box glitches for non-mesh objects

See merge request slumber/multi-user!129
2021-06-23 16:02:50 +00:00
3f005b86ab fix : add enumerate / remove nb_object 2021-06-23 17:45:01 +02:00
5098e5135d fix: bbox work for non-mesh objects+ins.collection 2021-06-23 17:00:05 +02:00
37cfed489c Merge branch '204-animation-doesn-t-sync-for-gpencil-materials' into 'develop'
Resolve "Animation doesn't sync for materials"

See merge request slumber/multi-user!128
2021-06-22 12:10:23 +00:00
9003abcd18 feat: notes for furtur improvements 2021-06-22 14:06:19 +02:00
a199e0df00 feat: apply bl_apply_child member to force dependencies reloading
fix: node_tree animation dependencies
2021-06-22 11:36:51 +02:00
3774419b7e fix: force push is now pushing the whole node data instead of delta 2021-06-22 10:41:36 +02:00
3e552cb406 feat: gpencil materials animation support 2021-06-22 10:39:40 +02:00
9f381b44c8 fix: material animation support 2021-06-21 18:58:16 +02:00
ad795caed5 fix: only apply repository heads on connection 2021-06-21 18:38:43 +02:00
504dd77405 fix: scene cleaning 2021-06-21 17:10:05 +02:00
82022c9e4d clean: only log ignored update in debug logging level 2021-06-18 15:45:51 +02:00
d81b4dc014 feat: enable delta back for all datablocks execpt gpencil, files and images 2021-06-18 15:30:39 +02:00
63affa079f Merge branch '199-filter-correctly-distant-updates-in-the-depsgraph-handler' into 'develop'
Resolve "Filter correctly distant updates in the depsgraph handler"

See merge request slumber/multi-user!126
2021-06-18 13:12:15 +00:00
fcf5a12dd0 fix: log verbosity level 2021-06-18 15:03:14 +02:00
b0529e4444 refactor: move handlers to hendlers.py 2021-06-18 14:59:56 +02:00
bdfd89c085 feat: temporary store applied update to ignore them. 2021-06-18 14:34:11 +02:00
ff1630f9cc Merge branch '194-smooth-brush-size-reset' into 'develop'
Resolve "Brush deleted on join"

See merge request slumber/multi-user!124
2021-06-16 12:30:31 +00:00
5830fe1abb fix: add items_to_remove 2021-06-16 14:28:26 +02:00
c609f72080 fix: All brushes 2021-06-16 12:29:56 +02:00
a28a6f91bd feat: move testing to blender 2.93 2021-06-15 16:27:49 +02:00
a996f39d3b Merge branch '195-auto-updater-install-a-broken-version-of-the-addon' into 'develop'
Resolve "Auto updater install a broken version of the addon"

See merge request slumber/multi-user!123
2021-06-15 12:54:49 +00:00
7790a16034 fix: download the build artifact instead of the repository default zip
Related to #195
2021-06-15 14:51:37 +02:00
836fdd02b8 Merge branch '192-parent-type-isn-t-synced' into 'develop'
Resolve "Parent type isn't synced"

See merge request slumber/multi-user!122
2021-06-15 09:22:13 +00:00
7cb3482353 fix: parent type and parent bone 2021-06-15 11:20:31 +02:00
041022056c Merge branch 'develop' of gitlab.com:slumber/multi-user into develop 2021-06-14 17:32:50 +02:00
05f3eb1445 fix: update readme 2021-06-14 17:32:05 +02:00
17193bde3a fix: doc server .png names 2021-06-14 14:29:45 +00:00
a14b4313f5 feat: update to develop 2021-06-14 16:12:47 +02:00
b203d9dffd Merge branch '188-intgrate-replication-as-a-submodule' into develop 2021-06-14 16:10:15 +02:00
f64db2155e Merge branch '49-connection-preset-system' into 'develop'
Connection-preset-system

See merge request slumber/multi-user!121
2021-06-14 13:50:58 +00:00
e07ebdeff5 fix: remove ui overwrite class 2021-06-14 15:46:57 +02:00
3d6453f7a2 feat: doc 2021-06-14 15:17:30 +02:00
7421511079 fix: override operator 2021-06-14 15:17:07 +02:00
bc24525cec fix: new UI/UX 2021-06-11 16:57:02 +02:00
699cf578e2 feat: prevent updates in sclupt mode 2021-06-11 16:42:23 +02:00
e9b4afb440 refactor: enable partial delta based replication 2021-06-11 15:28:37 +02:00
0c6491590e fix: admin password root 2021-06-11 12:18:51 +02:00
b87e733ddc fix: name conflict + responsive enum 2021-06-11 12:13:23 +02:00
cb0962b484 feat: server preset working with bad ui/ux 2021-06-10 15:39:12 +02:00
1fc25412ac fix: constraint differential update support 2021-06-10 15:21:25 +02:00
b5405553dc refactor: install replication dependencies in libs 2021-06-09 18:16:43 +02:00
a1b6fb0533 feat: server preset 2021-06-08 17:03:43 +02:00
b6a8a2ec01 Revert "doc: comment ui draw()"
This reverts commit f7c4f5d1fe.
2021-06-08 15:02:53 +02:00
3e41b18af1 Merge branch '49-connection-preset-system' of https://gitlab.com/slumber/multi-user into 49-connection-preset-system 2021-06-08 15:00:50 +02:00
f7c4f5d1fe doc: comment ui draw() 2021-06-08 14:58:57 +02:00
c616054878 tour du python blender 2021-06-07 17:06:41 +02:00
5c08493774 fix 'GraphObjectStore' object has no attribute 'object_store' 2021-06-04 18:30:54 +02:00
af8a138b4f fix: modifier order 2021-06-04 17:17:30 +02:00
6d9216f14a refactor: cleanup repository 2021-06-04 16:07:02 +02:00
fc4fb088bb refactor: repository api clean 2021-06-04 14:02:09 +02:00
98553ba00c refactor: remove get_nodes 2021-06-04 12:13:53 +02:00
1e15a12b10 refactor: remove list 2021-06-04 12:07:54 +02:00
569543650f feat: skip external updates 2021-06-03 15:43:47 +02:00
07358802f7 refactor: fix scene item removal 2021-06-03 15:03:09 +02:00
a059fafe12 feat: add mutate to scene delta 2021-06-03 11:43:24 +02:00
297f68ccfe refactor: only apply node when it is necessary (skip for host) 2021-06-03 11:41:25 +02:00
c9c70d1e08 refactor: stamp datablock during apply 2021-06-03 11:20:54 +02:00
a34f58ef3f fix: cherrypick TCP idle bug 2021-06-02 23:10:13 +02:00
e7b7f38991 fix: change rights 2021-06-02 17:49:22 +02:00
392e0aaaa3 refactor: remove missing parameter 2021-06-02 15:45:11 +02:00
4c774d5d53 refactor: move update user metadata to porcelain 2021-06-02 12:59:53 +02:00
4c4cf8a970 refactor: move rm to porcelain 2021-06-02 11:47:41 +02:00
211d0848c2 fix: replication version 2021-06-02 11:39:37 +02:00
c9665c4719 refactor: move unlock/lock/kick to porcelain 2021-06-02 11:31:23 +02:00
431fe0d840 refactor: move lock/unock to porcelain 2021-06-02 10:22:37 +02:00
df7ca66ad8 fix: repo dumps api 2021-06-02 09:35:55 +02:00
c2d2db78e6 refactor: temporary remove name resolution 2021-06-01 15:47:05 +02:00
ad89a4e389 fix: disable mutable delta for scene 2021-06-01 14:53:17 +02:00
6ca6d4443d refactor: move load/dumps to repository 2021-05-31 11:39:54 +02:00
81c9b5fc06 fix: animation loading 2021-05-21 23:02:42 +02:00
9fddfe084c fix: annotation 2021-05-21 17:29:22 +02:00
ca40523393 fix: apply and resolve 2021-05-21 17:14:28 +02:00
76e28ced21 refactor: remove legacy data 2021-05-21 15:40:45 +02:00
55c6002b28 feat: update version 2021-05-20 17:22:00 +02:00
8d5c8aded3 refacor: code formating 2021-05-20 09:57:44 +02:00
8ebba80b97 refactor: add diff back 2021-05-19 17:44:42 +02:00
50d6c6b3c8 fix: filter 2021-05-19 15:59:36 +02:00
f0b03c50f2 refactor: fix tests 2021-05-19 15:12:11 +02:00
28e83a38e6 refactor: add back armature lightprobes, sound and speaker 2021-05-19 15:05:54 +02:00
2e261cd66b refactor: add particle and lattive back 2021-05-19 14:40:13 +02:00
3f6e4f7333 refactor: add texts back 2021-05-19 14:23:56 +02:00
49fadf084a refactor: add gpencil back 2021-05-19 13:56:42 +02:00
e2e0dc31c1 refactor: add volume and world support 2021-05-19 13:42:34 +02:00
389bbd97d5 refactor: add image and file back 2021-05-19 13:31:57 +02:00
19602691d3 feat: texture 2021-05-19 11:43:01 +02:00
2e2ff5d4bf refactor: add material nodegroup back 2021-05-19 11:25:56 +02:00
fef6559ce0 refactor: add light and camera support back 2021-05-19 10:52:04 +02:00
5f669fd49a refactor: add camera back 2021-05-19 09:55:07 +02:00
330ff08fd3 refactor: add collection back 2021-05-19 09:47:01 +02:00
f3be8f9623 feat: bring back icons 2021-05-19 09:37:50 +02:00
ffb70ab74c refactor: protocol refactoring part 1 (mesh, object, action, scene) 2021-05-18 23:14:09 +02:00
26140eefb2 refactor: clear replicated datablock init states 2021-05-18 18:23:28 +02:00
cdf0433e8a refactor: move fetch to repository 2021-05-18 17:17:10 +02:00
acd70f73bf refactor: add remote
refactor: move push to porcelain
2021-05-18 16:54:07 +02:00
36c3a9ab0b refactor: remove sanitize 2021-05-18 11:01:55 +02:00
cfb1afdd72 Revert "feat: node sanitize on collection and scene update"
This reverts commit fb1c985f31.
2021-05-18 11:00:05 +02:00
4eeb80350e fix: layer info missing 2021-05-18 10:54:13 +02:00
fb1c985f31 feat: node sanitize on collection and scene update 2021-05-17 17:35:34 +02:00
689c2473d6 fix: commit 2021-05-17 17:18:17 +02:00
41620fce90 fix: commit 2021-05-17 17:04:43 +02:00
249bcf827b fix: collection instance bounding box selection 2021-05-17 16:03:01 +02:00
d47eab4f26 refactor: move commit to porcelain 2021-05-17 11:12:18 +02:00
f011089d82 refactor: removed apply from replicated datablock 2021-05-17 10:52:28 +02:00
acc58a1c9f fix: tcp keepalive IDLE time 2021-05-16 22:26:53 +02:00
24d850de9f refactor: get metadata updates optimization back 2021-05-11 11:41:43 +02:00
b045911a59 refactor: get diff back for testing 2021-05-10 12:04:45 +02:00
a67be76422 feat: delta commit 2021-05-09 17:42:56 +02:00
32033c743c feat: update repllication version 2021-05-07 17:10:23 +02:00
5da8650611 fix: get replication version 2021-05-07 16:56:00 +02:00
aec5096f87 feat: update submodule url 2021-05-07 16:12:04 +02:00
fba39b9980 fix: ci with submodules 2021-05-07 15:47:53 +02:00
6af3e4b777 refactor: add threaded data handling back on server side 2021-05-04 16:25:36 +02:00
58d639e9d8 feat: add replication as a submoduke 2021-05-04 14:56:50 +02:00
0efe5d5a10 Merge branch 'remove-services' into 'develop'
refactor: differential revision Stage 1

See merge request slumber/multi-user!119
2021-05-04 12:24:05 +00:00
2ad93cf304 Merge branch 'develop' into remove-services 2021-04-30 16:53:02 +02:00
771d76a98b fix: missing shapekeys attr 2021-04-30 16:51:11 +02:00
1e83241494 feat: remove pull socket 2021-04-30 16:26:20 +02:00
1bcbff3ed4 Merge branch 'develop' into remove-services 2021-04-29 14:41:55 +02:00
9a45fe7125 fix: shapekey animation data 2021-04-29 14:41:11 +02:00
207901afdd Merge branch '184-uv-project-modifier-target-object-doesn-t-sync' into 'develop'
Resolve "UV project modifier target object doesn't sync"

See merge request slumber/multi-user!118
2021-04-29 09:11:47 +00:00
c6eb1ba22f fix: shapekey performances
Related to #187
2021-04-29 11:06:46 +02:00
ba4168d0fd Merge branch 'develop' into remove-services 2021-04-28 16:56:20 +02:00
00e7adf022 fix: Image Empty is not loading.
Related to #186
2021-04-28 10:01:04 +02:00
d9d8ca7ca0 revert: image source replication until a proper fix is done 2021-04-23 15:35:19 +02:00
e8cd271bd8 fix: renable gitlab-ci file 2021-04-23 11:48:01 +02:00
e71af6402c feat: increment addon version 2021-04-23 11:46:29 +02:00
dd1c6a4fc7 feat: enable back ci 2021-04-23 11:45:47 +02:00
7fe1ae83b1 feat: update replication version to the right one 2021-04-23 11:25:15 +02:00
a7ad9d30c3 Merge branch 'develop' into remove-services 2021-04-23 11:21:16 +02:00
14779be1ed feat: support video file as camera background images 2021-04-22 15:52:06 +02:00
a36c3740cc fix: load driver variable without id 2021-04-22 15:00:08 +02:00
d2108facab feat: fcurve modifiers support 2021-04-22 14:52:43 +02:00
e5651151d9 fix: having both animation and drivers on the same object 2021-04-22 14:00:26 +02:00
fb61b380b6 fix: uv_projector modifier
refactor: move modifier related code to dump_modifiers and load_modifier_custom_data
2021-04-22 11:05:34 +02:00
e538752fbc Merge branch 'master' of gitlab.com:slumber/multi-user into develop 2021-04-15 15:31:59 +02:00
53eaaa2fcd fix: auto-updater operator registration for blender 2.93 compatibility 2021-04-15 15:28:59 +02:00
a7e9108bff Merge branch 'develop' into 'master'
v0.3.0

See merge request slumber/multi-user!106
2021-04-14 14:32:24 +00:00
570909a7c4 fix: prevent field from being dumped if unused
fix: bl_object tests
2021-04-14 16:25:21 +02:00
736c3df7c4 feat: remove new particle systems
clean: remove logs
2021-04-14 15:50:53 +02:00
8e606068f3 fix: particle system duplication
feat: update Readme
2021-04-14 15:29:02 +02:00
eb631e2d4b feat: update changelog 0.3.0 release 2021-04-14 14:36:06 +02:00
70641435cc feat: initial rigid body supports 2021-04-14 12:25:16 +02:00
552c649d34 feat: physics forcefield and collision support 2021-04-14 11:49:34 +02:00
d9d5a34653 clean: remove libs 2021-04-14 09:56:07 +02:00
12acd22660 feat: ignore some attributes 2021-04-14 09:54:34 +02:00
826a59085e feat: particle texture slot support 2021-04-14 09:45:18 +02:00
5ee4988aca Merge branch '24-particle-support' into develop 2021-04-13 22:45:27 +02:00
cb85a1db4c feat: dual identification for object parents 2021-04-13 14:37:43 +02:00
5e30e215ab fix: empty node 2021-04-02 16:37:47 +02:00
9f167256d0 fix: node frame trasform 2021-04-02 16:12:51 +02:00
4e19c169b2 fix: node_groups unordered socket loading
fix: geometry_node sample texture handling
fix: geometry node dependencies
2021-04-02 15:51:31 +02:00
9c633c35ec fix: geometry node socket for blender 2.93 2021-04-02 10:01:45 +02:00
9610b50a49 Merge branch '181-geometry-nodes-int-float-inputs-doesn-t-sync' into 'develop'
Resolve "Geometry nodes int/float inputs doesn't sync"

See merge request slumber/multi-user!116
2021-03-31 13:42:26 +00:00
67d18f08e2 fix: Timer not unregistered error
fix: handle correctly unsupported float parameter for geometry nodes
fix: Material loading
2021-03-31 15:38:35 +02:00
9d0d684589 fix: geometry nodes str, float, int loading 2021-03-31 11:19:03 +02:00
2446df4fe3 feat: raise the default timeout to 5 second 2021-03-21 09:28:54 +01:00
07862f1cf0 fix: missing hue_interpolation 2021-03-19 11:07:04 +01:00
3a02711baa feat: faster root management 2021-03-14 20:58:25 +01:00
c7e8002fed fix: apply api
clean: ipc port propertie
2021-03-14 18:32:04 +01:00
f4e7ec6be8 Merge branch 'develop' into 173-differential-revision-milestone-2-replication-refactoring 2021-03-14 17:46:23 +01:00
480818fe85 Merge branch '180-parent-relation-have-doesn-t-keeps-transform' into 'develop'
Resolve "Parenting objects doesn't keeps transform"

See merge request slumber/multi-user!115
2021-03-13 17:35:42 +00:00
b965c80ba5 fix: parent transform
fix: race  condition for COMMON objects

related to #180
2021-03-13 18:32:20 +01:00
235db712fd fix: api 2021-03-11 15:45:48 +01:00
647ac46c01 feat: move apply to porcelain
feat: move data access to repository
feat: object_store layer to repository (with GraphObjectStore)
revert: missing network services
2021-03-09 14:07:59 +01:00
8e3c86561f refactor: move add to porcelain 2021-03-09 10:19:51 +01:00
dba19e831d Merge branch 'develop' into 173-differential-revision-milestone-2-replication-refactoring 2021-03-08 22:16:14 +01:00
93df5ca5fa fix: disconnect callback 2021-03-06 10:20:57 +01:00
b17104c67e fix: naming 2021-03-05 10:35:35 +01:00
b66d0dd4ce Merge branch 'develop' of gitlab.com:slumber/multi-user into develop 2021-03-04 15:49:00 +01:00
9487753307 feat: fix object and collection support for geometry nodes 2021-03-04 15:48:36 +01:00
df1257ca4c Merge branch '179-parent-relation-can-t-be-removed' into 'develop'
Resolve "Parent relation can't be removed"

See merge request slumber/multi-user!113
2021-03-04 13:25:39 +00:00
875b9ce934 feat: temporary disable CI jobs for this branch because of breaking changes 2021-03-04 14:24:03 +01:00
2d638ef76f refactor: interface api changes 2021-03-04 14:22:54 +01:00
cc5a87adb8 fix: prevent matrix_parent_inverse from being reset by loading parents only if its necessary 2021-03-03 11:00:47 +01:00
19c56e590b feat: remove parent as node dependency 2021-03-03 10:03:57 +01:00
d0e80da945 fix: object parenting can't be removed
Related to #179
2021-03-03 09:55:48 +01:00
0ccd0563ea feat: testing doc building with python 3.8 2021-03-02 12:56:12 +00:00
1c3394ce56 feat: sphinx-material theme 2021-03-02 12:46:26 +00:00
d2b63df68e Merge branch '178-move-documentation-hosting-to-gitlab-page' into 'develop'
Resolve "Move documentation hosting to gitlab page"

See merge request slumber/multi-user!112
2021-03-02 09:21:57 +00:00
3d9c78c2f9 doc: only build for master/develop 2021-03-02 10:18:11 +01:00
4726a90a4a doc: reflect doc hosting changes to the Readme.md 2021-03-02 10:16:59 +01:00
73b763d85f fix: job ordering error 2021-03-02 09:09:50 +00:00
5e29c6fe26 Update .gitlab/ci/doc.gitlab-ci.yml 2021-03-02 09:08:39 +00:00
113ab81cbf Update .gitlab/ci/doc.gitlab-ci.yml 2021-03-02 09:07:50 +00:00
d2215b662c feat: update jobs dependencies 2021-03-02 09:06:32 +00:00
238a34d023 feat: needs test to success 2021-03-02 09:05:21 +00:00
55ca8a7b84 Update .gitlab/ci/doc.gitlab-ci.yml 2021-03-02 09:03:19 +00:00
7049c1723d feat: initial CI job for building the documentation for gitlab page 2021-03-02 09:58:06 +01:00
6586647eac Merge branch '177-support-geometry-nodes' into 'develop'
feat: initial support for Geometry Nodes

See merge request slumber/multi-user!110
2021-02-26 16:01:26 +00:00
fb6f170d60 clean: remove prints
doc: add new def docstrings
2021-02-26 14:31:05 +01:00
c1c39438e3 feat: input value support 2021-02-26 12:27:56 +01:00
317fc03f87 feat: geometry node initial support
refactor: resolve datablocks by uuid by devault
fix: modifier texture dependencies
2021-02-26 10:38:50 +01:00
505f3ab770 fix: external depencies removed during undo 2021-02-23 13:20:01 +01:00
209062af4f Merge branch '175-new-object-generated-during-separate-object-operator-doesn-t-sync' into 'develop'
Resolve "New object generated during separate object operator doesn't sync"

See merge request slumber/multi-user!108
2021-02-19 09:05:41 +00:00
88bab2a4c6 fix: separate objects
Related to #175
2021-02-19 10:00:00 +01:00
a91bae3506 fix: reload object after mesh loading to prevent it from loosing vertex_group and shape_keys 2021-02-16 21:58:26 +01:00
0a96643a9f feat: missing attr (seam, sharp) 2021-02-16 15:36:44 +01:00
261d4d9610 Merge branch '172-vertex-group-assignation-doesn-t-sync-correctly' into 'develop'
Resolve "Vertex group assignation doesn't sync correctly"

See merge request slumber/multi-user!107
2021-02-16 10:01:41 +00:00
3293741969 fix: vertex group assignation
Related to #172
2021-02-16 10:58:08 +01:00
3eee8db1ae fix: wrong version number 2021-02-12 17:40:07 +01:00
031b143843 fix: attempt to fix tcp timeout on linux with ZMQ_TCP_KEEPALIVE_IDLE 2021-02-12 17:30:46 +01:00
7dd6e38e3f Merge branch '132-fix-undo-edit-last-operation-redo-handling-2' into 'develop'
Resolve "Fix undo & edit last operation & redo handling"

See merge request slumber/multi-user!87
2021-02-12 13:13:18 +00:00
1dd0235061 clean: timer related settings 2021-02-12 10:49:04 +01:00
cdcb2de786 clean: remove apply related settings
fix: image reloading after modifications
2021-02-12 10:48:29 +01:00
0b88631250 refactor: move session dump_db to replication as session.save 2021-02-09 18:09:39 +01:00
c00b2a2d7d feat: explicit state loading error 2021-02-09 14:20:08 +01:00
1f0f44fdbf clean: materials dump 2021-02-09 14:14:53 +01:00
8262fb9d4e feat: time stamped logs files 2021-02-05 11:50:58 +01:00
c2114b593e Merge branch 'develop' into 132-fix-undo-edit-last-operation-redo-handling-2 2021-02-05 11:35:56 +01:00
7e28ca3fa1 Merge branch '171-add-nurbs-support-only-curve' into 'develop'
Resolve "Add nurbs support (only curve)"

See merge request slumber/multi-user!105
2021-02-05 10:31:21 +00:00
d0bd4193d9 fix: nurbs curve
feat: curve material support
2021-02-05 11:22:11 +01:00
d09479fd47 Merge branch '166-improve-grease-pencil-replication-performances' into '132-fix-undo-edit-last-operation-redo-handling-2'
Resolve "Improve Grease Pencil replication performances"

See merge request slumber/multi-user!100
2021-02-05 09:45:54 +00:00
07cfb85561 Merge branch '170-gpencil-fill-strokes-aren-t-always-working' into '166-improve-grease-pencil-replication-performances'
Resolve "Gpencil fill strokes aren't always working"

See merge request slumber/multi-user!104
2021-02-05 09:30:13 +00:00
cf0d7a1122 fix: temporary for stroke geometry update to fix triangulation with fill materials
Related to 170
2021-02-05 10:25:50 +01:00
3f335c7031 Merge branch 'feature/docupdate_serverlogs' into 'develop'
document how to retrieve cloud-hosted server logs

See merge request slumber/multi-user!103
2021-02-02 19:51:12 +00:00
2180db5206 document how to retrieve cloud-hosted server logs 2021-02-02 19:40:47 +01:00
e6110b4cea Merge branch '132-fix-undo-edit-last-operation-redo-handling-2' into 166-improve-grease-pencil-replication-performances 2021-02-02 11:09:54 +01:00
819598ebd9 Merge branch 'develop' into 132-fix-undo-edit-last-operation-redo-handling-2 2021-02-02 11:09:11 +01:00
1be43f0336 Merge branch '168-holdout-option-for-grease-pencil-materials-isn-t-replicating' into 'develop'
fix: grease pencil material holdout is not synced

See merge request slumber/multi-user!102
2021-02-02 10:08:24 +00:00
6a5ff9a097 fix: grease pencil material holdout is not synced 2021-02-02 11:04:46 +01:00
86cb3d29fb fix: wrong grease pencil frame after layer update 2021-01-29 16:29:27 +01:00
589702dab7 feat: continous update support by toggling the sync_in_editmode flag
Related to #166
2021-01-29 11:54:13 +01:00
ed76210270 Merge branch '132-fix-undo-edit-last-operation-redo-handling-2' into 166-improve-grease-pencil-replication-performances 2021-01-29 11:46:45 +01:00
75c4f42796 Merge branch 'develop' into 132-fix-undo-edit-last-operation-redo-handling-2 2021-01-29 11:46:05 +01:00
1fd54769b9 feat: enable build and deploy for all branch 2021-01-29 11:45:14 +01:00
c4484b4b51 Merge branch '132-fix-undo-edit-last-operation-redo-handling-2' into 166-improve-grease-pencil-replication-performances 2021-01-29 11:43:33 +01:00
4eb787cc0f Merge branch '167-sequencer-strips-does-not-sync-in-132-fix-undo-edit-last-operation-redo-handling-2-branch' into '132-fix-undo-edit-last-operation-redo-handling-2'
Resolve "Sequencer strips does not sync in `132-fix-undo-edit-last-operation-redo-handling-2 branch`"

See merge request slumber/multi-user!101
2021-01-29 10:43:06 +00:00
c855b5a424 clean: removed logs 2021-01-29 11:39:00 +01:00
ee4083c134 feat: evaluate gpencil on layer change/ frame change/ mode change
Related to #166
2021-01-29 11:28:50 +01:00
0325e9d0bd feat: move sequencer to scene 2021-01-29 00:06:41 +01:00
21dc95b5a7 Merge branch 'develop' into 132-fix-undo-edit-last-operation-redo-handling-2 2021-01-28 09:58:27 +01:00
d8161f22f3 fix: syntax error 2021-01-28 09:54:19 +01:00
94f8bff231 fix: envvar synthax error 2021-01-28 09:53:57 +01:00
d3a1094cc2 feat: gitlab CI tag by branch name 2021-01-28 09:48:36 +01:00
d08e0a80a4 Merge branch 'develop' into 132-fix-undo-edit-last-operation-redo-handling-2 2021-01-27 11:15:02 +01:00
26148e9934 Merge branch '165-delete-animations-is-not-synced' into 'develop'
Resolve "Delete animations is not synced"

See merge request slumber/multi-user!97
2021-01-27 10:12:48 +00:00
0a7be03c6f fix: animation data attribute check 2021-01-27 11:06:46 +01:00
b6449a7da2 fix: animation deletion synchronization
Related to #165
2021-01-27 11:01:03 +01:00
36038effdf Merge branch 'develop' into 132-fix-undo-edit-last-operation-redo-handling-2 2021-01-26 15:46:09 +01:00
cb90c196a5 Merge branch '164-duplicating-objects-broke-they-parent-relation' into 'develop'
Resolve "Duplicating objects broke they parent relation"

See merge request slumber/multi-user!96
2021-01-26 14:44:26 +00:00
ae3c9fe43e clean: remove hardcoded parent assignation 2021-01-26 15:42:37 +01:00
2983195af4 fix: objects parenting error 2021-01-26 15:40:00 +01:00
4d69faf186 clan: remove diff_method 2021-01-22 14:24:19 +01:00
2304563b6e Merge branch '163-support-adding-scene-during-the-session' into '132-fix-undo-edit-last-operation-redo-handling-2'
Resolve "Support adding scene during the session"

See merge request slumber/multi-user!95
2021-01-22 10:22:14 +00:00
1cfb4e797e fix: handle none uuid 2021-01-22 11:18:28 +01:00
8f95158f08 feat: initial support for new scenes 2021-01-21 14:48:07 +01:00
5949e3c5cc Merge branch 'develop' of gitlab.com:slumber/multi-user into 132-fix-undo-edit-last-operation-redo-handling-2 2021-01-21 11:06:54 +01:00
790f145022 Merge branch '162-sync-cycles_visibility-settings' into 'develop'
feat: sync cycle visibility settings

See merge request slumber/multi-user!94
2021-01-21 10:05:42 +00:00
ec40862dd0 feat: sync cycle visibility settings 2021-01-21 10:51:28 +01:00
9cc1c92e0e clean: remove unused var 2021-01-20 16:02:15 +01:00
7a716b4c37 feat: auto remove nodes on undo/redo
feat: purge operator
2021-01-15 23:43:35 +01:00
a4ef8a6344 feat: skip update in sculpt mode by default 2021-01-15 23:14:45 +01:00
c5e20085f0 clean: move flush history to the debug logs 2021-01-15 17:02:29 +01:00
f4463f9cfe fix: greace pencil object vertexgroup dump crash by adding a warning 2021-01-15 16:54:36 +01:00
a212445927 clean: remove push timer 2021-01-15 16:41:32 +01:00
89a8891073 fix: RNA removed error by disabling the push timer 2021-01-13 15:49:07 +01:00
52ebb874b0 fix: edit-mode error while pushing 2021-01-13 15:36:41 +01:00
2913e6d5a7 fix: file push 2021-01-13 15:09:10 +01:00
6a00b58600 fix: timeout error on connection 2021-01-13 14:45:23 +01:00
2bde136bb6 fix: annotation tool 2021-01-13 14:24:16 +01:00
f5c77fec3a fix: fail to push collectionsby reverting the commit caching policy 2021-01-12 21:29:36 +01:00
d3211199c4 fix: handler not correctly removed 2021-01-12 13:36:21 +01:00
2d90ea7679 Merge branch '160-undo-performance-improvement' into '132-fix-undo-edit-last-operation-redo-handling-2'
Resolve "Undo performance improvement"

See merge request slumber/multi-user!93
2021-01-12 10:37:10 +00:00
abd846fc8d clean: push timer
feat: purge stagging on pre--redo/undo
2021-01-12 11:33:48 +01:00
e3bd7ea445 feat: improve commit times by using cache from the diff 2021-01-12 10:29:27 +01:00
12bd4a603b feat: added a push timer to control the push frequency 2021-01-11 19:54:57 +01:00
3c31fb5118 Merge branch '158-exception-access-violation-during-undo-redo' into '132-fix-undo-edit-last-operation-redo-handling-2'
Resolve "Exception access violation during Undo/Redo"

See merge request slumber/multi-user!92
2021-01-09 21:38:25 +00:00
c24f70fad5 feat: force to use depsgraph update mode 2021-01-09 22:36:00 +01:00
ca2d8e49b5 feat: update replication 2021-01-06 13:58:58 +01:00
4b1499f6ae fix: construct error 2020-12-29 17:38:21 +01:00
f0c1fe9c87 Merge branch 'develop' into 132-fix-undo-edit-last-operation-redo-handling-2 2020-12-29 14:30:01 +01:00
dfaf1be4ff Merge branch '106-skin-weight-isn-t-properly-replicated' into 'develop'
Resolve "Skin weight isn't properly replicated"

See merge request slumber/multi-user!91
2020-12-24 15:42:46 +00:00
51cb099c4c feat: skin vertices data replication
fix: empty modifiers stask
2020-12-24 16:37:53 +01:00
64731a9198 Merge branch '157-drivers-data-path-index-isn-t-replicated' into 'develop'
fix: multiple drivers with same data_path on different index

See merge request slumber/multi-user!90
2020-12-24 14:01:07 +00:00
213523c8d6 Merge branch '156-constraint-replication-is-broken' into 'develop'
Resolve "Constraint replication is broken"

See merge request slumber/multi-user!89
2020-12-24 14:01:01 +00:00
4fdb72f874 fix: constraints destructor 2020-12-24 14:56:59 +01:00
1412fc638c fix: object constraint dump 2020-12-24 14:56:40 +01:00
7920f67aea fix: multiple drivers with same data_path on different index 2020-12-24 14:46:18 +01:00
a0c0f781e2 feat: update addon version to reflect the future release 2020-12-24 11:07:10 +01:00
ec74ea0038 Merge branch '155-bone-roll-is-not-sync' into 'develop'
Resolve "Bone roll is not sync"

See merge request slumber/multi-user!88
2020-12-24 10:03:50 +00:00
2c016833fd fix: bone roll replication
More info about the issue:
https://devtalk.blender.org/t/how-to-query-determine-the-roll-of-a-bone-in-pose-object-mode/14251/2

Related to #155
2020-12-24 10:53:16 +01:00
3d9da73ab0 feat: flush history on collection and scene update only
feat: enable deploy for undo branch
2020-12-23 18:46:29 +01:00
2f4e30f432 fix: catch runtime error
feat: enable build for undo branch
2020-12-23 17:57:36 +01:00
cd1e535a56 feat: initial undo tests 2020-12-23 17:27:43 +01:00
8a8cc0b322 Merge branch '154-object-display-data-loading-error' into 'develop'
Resolve "Object display data  loading error"

See merge request slumber/multi-user!86
2020-12-22 23:23:26 +00:00
1e64e17ff4 fix: display key error
Related to #154
2020-12-23 00:21:31 +01:00
66b6c06a2c Merge branch 'export_replication_graph' into 'develop'
Export replication graph

See merge request slumber/multi-user!85
2020-12-22 22:31:27 +00:00
45fbc46d8d doc: added initial documentation for auto save 2020-12-22 16:58:00 +01:00
39e3c1dbd5 refactor: change bl_label
Related to https://gitlab.com/slumber/multi-user/-/issues/153
2020-12-22 16:16:06 +01:00
f043b03128 clean: timers interface
feat: cancel autosave operator
2020-12-22 16:04:50 +01:00
ffe419a46e Merge branch 'develop' into 'master'
v0.2.0

See merge request slumber/multi-user!73
2020-12-17 13:34:41 +00:00
d4a0f782aa fix: update CHANGELOG.md to reflect the release note 2020-12-17 14:31:32 +01:00
9273adbd01 doc: change dowload link order (@activemotionpictures) 2020-12-17 14:24:48 +01:00
03b92eb5e7 fix: export menu label name 2020-12-17 14:04:00 +01:00
d0dc61bf66 feat: initial import operator 2020-12-16 11:05:58 +01:00
056b3524e5 feat: gzip to compress graph 2020-12-11 23:02:20 +01:00
16fc4b8c54 feat: added record as a timer 2020-12-10 15:50:43 +01:00
e62f0682a2 feat: initial export test 2020-12-10 13:31:43 +01:00
f463cb82e7 Merge branch '151-volumes-materials-are-not-working' into 'develop'
Resolve "Volumes materials are not working"

See merge request slumber/multi-user!84
2020-12-09 18:08:34 +00:00
54f416e8c3 fead: added materials support for volumes 2020-12-09 19:06:30 +01:00
682c983a64 Merge branch '152-generated-images-are-not-synced' into 'develop'
Resolve "Generated images are not synced"

See merge request slumber/multi-user!83
2020-12-09 17:53:28 +00:00
8015881e29 feat: update replication to fix image file dependencies owners 2020-12-09 18:38:08 +01:00
6e2d36cd00 feat: image autosave 2020-12-09 18:35:29 +01:00
affab2414c feat: exit the session as soon as a Timer crash 2020-12-09 18:34:56 +01:00
af6d54296a feat: parent reloading support for file dependent nodes 2020-12-09 14:49:26 +01:00
2ab0a75608 feat: update CHANGELOG.md to reflect new features 2020-12-03 19:03:40 +01:00
ccb9e55920 doc: Pierre Schiller's video tutorial in hosting section 2020-12-03 16:42:48 +01:00
31254d13c0 Merge branch '147-support-grease-pencil-modifiers' into 'develop'
feat: added initial gpencil modifer support

See merge request slumber/multi-user!81
2020-12-03 14:00:05 +00:00
6fddbb6f5e feat: add gp modifers to the object test 2020-12-03 14:58:10 +01:00
9ee3f26b80 Merge branch '143-add-a-popup-dialog-when-a-timeout-disconnection-occures-fixes' into 'develop'
Resolve "Add a popup dialog when a Timeout disconnection occures"

See merge request slumber/multi-user!80
2020-12-03 13:51:03 +00:00
19c5ca0928 feat: added initial gpencil modifer support
Related to https://gitlab.com/slumber/multi-user/-/issues/147
2020-12-03 14:23:10 +01:00
4bc35d7da4 fix: message unkown 2020-12-03 13:30:54 +01:00
8d19ffd52f feat: use invoke_props_dialog instead of iinvoke_popup 2020-12-03 13:28:45 +01:00
4f506c461a Merge branch '145-support-volume-objects' into 'develop'
Resolve "Support volume objects"

See merge request slumber/multi-user!79
2020-12-02 21:40:51 +00:00
49fcc40db9 feat: add a bsic volume test 2020-12-02 22:36:30 +01:00
8492b537a8 feat: update README 2020-12-02 22:33:12 +01:00
e6e4f6ab7a feat: initial volume support 2020-12-02 18:13:11 +01:00
e073182028 fix: missing replication update 2020-12-02 16:38:57 +01:00
78eb5d948c Merge branch '146-add-support-for-internal-textures' into 'develop'
Resolve "Add support for internal textures"

See merge request slumber/multi-user!78
2020-12-02 15:36:01 +00:00
ac9a0f3733 feat: ignore useless attributes 2020-12-02 16:25:40 +01:00
4e7ade8f38 feat: update the readme 2020-12-02 14:22:56 +01:00
0b25264375 feat: added a basic test texture 2020-12-02 14:21:49 +01:00
1d03fe4975 feat: add initial texture support 2020-12-02 11:24:26 +01:00
1273ab2371 fix: missing troubleshouting section 2020-11-26 18:47:28 +01:00
7dd2ee5e70 Merge branch '143-add-a-popup-dialog-when-a-timeout-disconnection-occures' into 'develop'
Resolve "Add a popup dialog when a Timeout disconnection occures"

See merge request slumber/multi-user!77
2020-11-26 12:37:47 +00:00
c72bb21f20 Merge branch 'develop' into 143-add-a-popup-dialog-when-a-timeout-disconnection-occures 2020-11-26 13:25:46 +01:00
5b43520353 fix: does graph update flag 2020-11-26 12:17:35 +01:00
7e25ca4c84 feat: show exit reason in the disconnection popup 2020-11-26 11:37:51 +01:00
4a4cd5db50 feat: initial notification popup 2020-11-25 22:53:38 +01:00
7f19d45b71 fix: gpencil draw_cyclic missing in 2.91.0 2020-11-25 19:21:22 +01:00
37b3d6d094 fix: replication flag button aligment for blender 2.91.0 2020-11-25 18:36:02 +01:00
64bb715aff fix: python_binary_path deprecation in 2.91.0
More infos here:
https://wiki.blender.org/wiki/Reference/Release_Notes/2.91/Python_API
2020-11-25 18:20:28 +01:00
3024b479d3 Merge branch 'develop' of gitlab.com:slumber/multi-user into develop 2020-11-25 18:09:00 +01:00
abf4462da6 Merge branch 'feature/docupdate_gcloudhost' into 'develop'
Feature/docupdate gcloudhost

See merge request slumber/multi-user!76
2020-11-25 14:10:56 +00:00
aa6827303f doc update & clean - cloud host & updating addon
docs clean images
2020-11-25 14:34:58 +01:00
254e8e8ca1 feat: ignore material output node default values 2020-11-25 14:00:27 +01:00
a63bf66023 feat: push docker image with latest tag 2020-11-25 10:55:52 +01:00
983c5f9020 Minor doc update 2020-11-25 01:22:03 +01:00
9f61335a85 Minor doc update (ways_to_contribute) 2020-11-24 23:11:51 +01:00
ed0c5d9431 Add cloud hosting instructions, updated Dockerfile 2020-11-24 23:00:44 +01:00
46414aef13 fix: version check 2020-11-20 22:06:08 +01:00
3841ed3330 Merge branch '117-handle-correctly-annotation-sync' into 'develop'
Resolve "Handle correctly annotation sync"

See merge request slumber/multi-user!75
2020-11-19 08:05:22 +00:00
47a281faff feat: initial annotation support 2020-11-18 19:13:22 +01:00
f0442861a8 Merge branch '142-improve-grease-pencil-replication-peformances' into 'develop'
Resolve "Improve grease pencil replication peformances"

See merge request slumber/multi-user!74
2020-11-18 16:28:18 +00:00
039225a41c feat: ignore context errors with info logging level 2020-11-18 17:05:41 +01:00
f1ffe37ac7 feat: initial gpencil perf improvement 2020-11-18 16:43:12 +01:00
6ca7b42ab4 feat: handle material inputs lenght errors 2020-11-18 14:49:27 +01:00
fbb32147b9 feat: use pickle Cython implementation when its available 2020-11-14 09:51:17 +01:00
d85db295a5 feat: use pickle protocol 4 2020-11-14 09:30:54 +01:00
0f1850bf2c feat: support color ramps interpolation and color_mode 2020-11-13 14:15:59 +01:00
8f4de7adbf feat(replication): handle error outside the data protocol
refactor(replication): remove background worker
2020-11-13 14:15:11 +01:00
320745aab3 Merge branch '45-vse-support' into 'develop'
Resolve "VSE Support"

See merge request slumber/multi-user!72
2020-11-11 19:38:03 +00:00
40cec39d27 feat: update readme 2020-11-11 18:54:07 +01:00
498616147b feat: support image sequence 2020-11-11 18:52:20 +01:00
30b2f5d32e feat: clear scene sequence on connection 2020-11-11 18:36:00 +01:00
f7e98abb59 Merge branch 'develop' into 45-vse-support 2020-11-11 18:01:34 +01:00
4022f300b3 Merge branch '141-support-shader-node-groups' into 'develop'
Add initial support for shader node groups

See merge request slumber/multi-user!70
2020-11-11 16:58:37 +00:00
cef45dad3c feat: use basic uuid to identify node inputs 2020-11-11 17:52:32 +01:00
30d734c2c1 feat: added initial nodegroup support 2020-11-11 14:09:57 +01:00
4391510d7b refactor: move node_tree io to dedicated def in order to avoid code redundancy. 2020-11-11 10:25:35 +01:00
04a4f7668a Merge branch '138-support-dns-name' into 'develop'
Resolve "Support DNS name"

See merge request slumber/multi-user!69
2020-11-06 21:36:00 +00:00
908c0fa4af feat: dns support 2020-11-06 22:33:33 +01:00
c718e62b33 feat: update replication version to fix server error 2020-11-06 16:52:53 +01:00
2f34bba1fd feat: delete inexistant sequences 2020-11-04 23:37:07 +01:00
db4e495183 fix: ignore strobe default value 2020-11-04 22:55:17 +01:00
c00a7184ff Merge branch 'develop' into 45-vse-support 2020-11-04 22:42:05 +01:00
9c83df45fc feat: bl_sequencer separate implementation 2020-11-04 22:41:24 +01:00
17949003f7 refactor: remove reparent mecanism
fix: empty camera background image
fix: object data reassignation
2020-11-03 23:44:25 +01:00
371d793a13 fix: materials Math and Vector node sync
Related to #137
2020-11-03 23:17:08 +01:00
c710111887 feat: test to hot reload newly installed module 2020-11-03 16:44:42 +01:00
664f7635cc feat: support empty id_root in actions 2020-11-03 16:15:34 +01:00
babecf5ae7 feat: add suport for MOVIE, IMAGE SOUND and EFFECT strips 2020-11-02 18:13:31 +01:00
0bad6895da feat: ground work for sequence support 2020-10-30 16:58:18 +01:00
66e55a7eec feat: improve default session widget hpos settings (@brybalicious) 2020-10-22 17:43:28 +02:00
4e2377cd7f feat: improve default session widget settings (@brybalicious) 2020-10-22 17:41:33 +02:00
f90c12b27f doc: added missing fields
feat: changed session widget defaults
2020-10-22 16:07:19 +02:00
3573db0969 Merge branch '134-revamp-session-status-ui-widget' into 'develop'
Resolve "Revamp session status UI widget"

See merge request slumber/multi-user!67
2020-10-22 13:52:29 +00:00
92bde00a5a feat: store session widget settings to preferences 2020-10-22 15:48:13 +02:00
2c82560d24 fix: grease pencil material 2020-10-22 13:55:26 +02:00
6f364d2b88 feat: session widget position and scale settings
feat: ui_scale is now taken in account for session widget text size
2020-10-21 23:33:44 +02:00
760b52c02b Merge branch '135-empty-and-light-objects-user-selection-highlight-is-broken' into 'develop'
Resolve "Empty and Light objects user selection highlight is broken"

See merge request slumber/multi-user!66
2020-10-21 15:25:42 +00:00
4dd932fc56 fix: empty and light display broken 2020-10-21 17:23:59 +02:00
ba1a03cbfa Merge branch '133-material-renaming-is-unstable' into 'develop'
Resolve "Material renaming is unstable"

See merge request slumber/multi-user!65
2020-10-21 13:17:18 +00:00
18b5fa795c feat: resolve materials from uuid by default and fallback on regular name resolving 2020-10-21 15:10:37 +02:00
1a82ec72e4 fix: change owner call in opterator 2020-10-21 14:40:15 +02:00
804747c73b fix: owning parent when a child is already owned (ex: duplicate linked) 2020-10-21 14:15:42 +02:00
7ee705332f feat: update replication to prevent UnpicklingError from crashing the network Thred 2020-10-20 17:25:50 +02:00
bed33ca6ba Merge branch 'develop' into 'master'
v0.1.1

See merge request slumber/multi-user!54
2020-10-16 09:11:20 +00:00
716c78e380 feat: update changelog 2020-10-16 11:06:41 +02:00
5e4ce4556f doc: update operator descriptions 2020-10-16 10:57:45 +02:00
aa9ea08151 doc: update refresh icon 2020-10-16 10:28:29 +02:00
f56890128e fix: material test by splitting it in a gpencil and nodal material test 2020-10-15 18:08:08 +02:00
8865556229 feat: update CHANGELOG 2020-10-15 18:02:07 +02:00
5bc9b10c12 fix: material gpencil loading 2020-10-15 18:01:54 +02:00
7db3c18213 feat: affect dependencies option in change owner 2020-10-15 17:48:04 +02:00
ff35e34032 feat: update apply ui icon
fix: material property filter
2020-10-15 17:09:50 +02:00
9f8222afa7 fix: handle apply dependencies 2020-10-15 12:11:28 +02:00
1828bfac22 feat: update changelog 2020-10-14 19:25:59 +02:00
3a1087ecb8 Merge branch '131-sync-render-settings-flag-cause-a-race-condition' into 'develop'
Resolve "Sync render settings flag cause a race condition"

See merge request slumber/multi-user!63
2020-10-14 17:16:20 +00:00
b398541787 fix: apply operator 2020-10-14 19:12:28 +02:00
f0b33d8471 fix: race condition in scene sync 2020-10-14 19:11:32 +02:00
5a282a3e22 Merge branch '130-mesh-transfert-is-broken-between-a-hybrid-linux-windows-session' into 'develop'
Resolve "Mesh transfert is broken between a hybrid linux-windows session"

See merge request slumber/multi-user!62
2020-10-14 14:07:59 +00:00
4283fc0fff fix: crash during hybrid session
Related to #130
2020-10-14 16:06:11 +02:00
753f4d3f27 fix: prevent NonAuthorizedOperationError to kill the right managment timer 2020-10-14 00:36:59 +02:00
9dd02b2756 feat: fix binary diff 2020-10-13 17:15:31 +02:00
c74d12c843 fix: handle world empty dependencies 2020-10-13 17:10:25 +02:00
e1d9982276 fix: bl_file diff when clear memory cache is enabled 2020-10-13 17:09:43 +02:00
8861986213 fix: packed image save error 2020-10-13 16:58:48 +02:00
1cb9fb410c feat: material node output default value support
fix: prevent material empty dependencies
2020-10-12 23:10:42 +02:00
c4a8cc4606 Merge branch 'fix_deploy' into 'develop'
Fix deploy

See merge request slumber/multi-user!61
2020-10-12 19:03:47 +00:00
187f11071c feat: enable build and deploy for only master and develop 2020-10-12 21:01:54 +02:00
530fae8cb4 feat: active deploy 2020-10-12 20:24:12 +02:00
6771c371a1 feat: enable deploy back 2020-10-12 20:23:08 +02:00
c844c6e54f clean: keep only active renderer settings (bl_scene.py)
fix: resolve_deps_implementation now only resolve master collection objects (bl_scene.py)
2020-10-12 20:21:08 +02:00
a4d0b1a68b fix: client selection 2020-10-12 18:56:42 +02:00
2fdc11692d fix: handle None bounding box position 2020-10-12 18:15:59 +02:00
dbfca4568f fix: get_preference import syntax 2020-10-12 18:07:09 +02:00
069a528276 feat: test scene with sync render settings enabled 2020-10-12 18:04:54 +02:00
030f2661fd fix: buffer empty for the first diff 2020-10-12 17:13:35 +02:00
e589e3eec4 fix: file not found logging
clean: remove cache for scene diff
2020-10-12 17:12:50 +02:00
04140ced1b fix: collection instance bounding box display 2020-10-12 17:11:46 +02:00
0d9ce43e74 fix: enable binrary differentialback
feat: ignore material node bl_label
2020-10-12 13:33:49 +02:00
d3969b4fd4 Revert "feat: avoid dumping read only properties"
This reverts commit cefaef5c4b.
2020-10-12 10:23:19 +02:00
e21f64ac98 revert: bl_label 2020-10-11 19:20:53 +02:00
b25b380d21 fix: missing bl_idname 2020-10-11 19:11:51 +02:00
1146d9d304 feat: disable render settings sync by default 2020-10-11 19:08:06 +02:00
51b60521e6 feat: update relplication version 2020-10-11 19:07:48 +02:00
035f8a1dcd feat: skipping not required parameters 2020-10-11 19:07:28 +02:00
cefaef5c4b feat: avoid dumping read only properties 2020-10-11 19:06:58 +02:00
4714e60ff7 Merge branch 'develop' of gitlab.com:slumber/multi-user into develop 2020-10-11 15:22:05 +02:00
3eca25ae19 feat: update replication version 2020-10-11 15:10:28 +02:00
96346f8a25 refactor: clean debug logs 2020-10-11 15:06:32 +02:00
a258c2c182 Merge branch 'feature/doc-updates-2' into 'develop'
Feature/doc updates 2

See merge request slumber/multi-user!60
2020-10-09 09:28:36 +00:00
6862df5331 Minor doc update 2020-10-09 01:59:42 +02:00
f271a9d0e3 Updated contribution doc to indicate how to sync with upstream repository 2020-10-09 01:55:45 +02:00
bdff6eb5c9 Updated contribution documentation with how to sync upstream repo 2020-10-09 01:29:01 +02:00
b661407952 Merge branch '128-ui-gizmo-error' into 'develop'
Resolve "UI gizmo error"

See merge request slumber/multi-user!59
2020-10-08 22:50:11 +00:00
d5eb7fda02 fix: ci yaml error 2020-10-09 00:46:52 +02:00
35e8ac9c33 feat: disable deploy until fixed 2020-10-09 00:45:30 +02:00
4453d256b8 feat: update replication version, switched dependency to pyzmq 2020-10-08 23:57:39 +02:00
299e330ec6 fix: internal gizmo error by launching the modal operator from the timer 2020-10-08 23:42:14 +02:00
34b9f7ae27 Merge branch 'master' into develop 2020-10-08 23:14:58 +02:00
9d100d84ad Merge branch 'hotfix/ui-spelling-fixes' into 'master'
Hotfix/ui spelling fixes

See merge request slumber/multi-user!58
2020-10-08 20:58:13 +00:00
2f677c399e UI spelling fixes to preferences.py and ui.py 2020-10-08 22:52:24 +02:00
e967b35c38 Revert "Minor UI spelling errors"
This reverts commit 673c4e69a4.
2020-10-08 21:58:30 +02:00
7bd0a196b4 Merge branch 'feature/doc-updates' into 'develop'
Feature/doc updates

See merge request slumber/multi-user!57
2020-10-08 17:04:37 +00:00
7892b5e9b6 Adding log-level to server startup scripts 2020-10-08 18:35:08 +02:00
f779678c0e Updates to hosting guide and contribution documentation 2020-10-08 18:31:20 +02:00
629fc2d223 feat: update dockerfile 2020-10-08 15:10:32 +02:00
724c2345df refactor: disable force apply during the reparent 2020-10-08 15:00:27 +02:00
673c4e69a4 Minor UI spelling errors 2020-10-08 00:31:56 +02:00
fbfff6c7ec Doc updates clarifying developer workflow, updating hosting instructions 2020-10-08 00:08:23 +02:00
f592294335 Added scripts to conveniently start server instance via docker or replication 2020-10-07 21:20:43 +02:00
8e7be5afde Merge branch '126-draw-refactoring' into 'develop'
Resolve "Draw refactoring"

See merge request slumber/multi-user!55
2020-10-06 14:12:13 +00:00
fc76b2a8e6 fix: avoid to remove inexistant user widget 2020-10-06 16:10:10 +02:00
1a8bcddb74 refactor: formatting 2020-10-06 15:53:29 +02:00
60fba5b9df refactor: use dict to store widgets 2020-10-06 15:46:35 +02:00
be0eb1fa42 clean: remove unused import 2020-10-06 09:45:13 +02:00
93d9bea3ae feat: display session status 2020-10-05 23:38:52 +02:00
022b7f7822 refactor: enable username display again
refactor: avoid to draw the local user
2020-10-05 22:34:43 +02:00
ae34846509 fix: ci syntax 2020-10-05 21:53:14 +02:00
d328077cb0 feat: deploy and build only for master and develop
refactor: carry on presence refactoring
2020-10-05 21:51:54 +02:00
0c4740eef8 fix: import error 2020-10-05 18:48:40 +02:00
d7b2c7e2f6 refactor: started to rewrite presence
fix: weird bounding boxes on various objects types

Related to #55
2020-10-05 18:34:41 +02:00
efbb9e7096 doc: feat changelog 0.1.0 release date 2020-10-05 16:11:04 +02:00
e0b56d8990 Merge branch 'develop' into 'master'
v0.1.0

See merge request slumber/multi-user!43
2020-10-05 13:42:16 +00:00
7a94c21187 doc: update version 2020-10-05 15:37:06 +02:00
0687090f05 feat: update changelog 2020-10-05 15:18:01 +02:00
920744334c Merge branch '125-autobuild-docker-image' into 'develop'
Resolve "Autobuild docker image"

See merge request slumber/multi-user!53
2020-10-05 09:32:57 +00:00
dfa7f98126 refactor: remove useless script 2020-10-05 11:28:45 +02:00
ea530f0f96 featL enable tast and build back 2020-10-03 00:30:37 +02:00
c3546ff74f fix: var name 2020-10-03 00:28:11 +02:00
83aa9b57ec feat: automatic image version 2020-10-03 00:26:44 +02:00
28a265be68 test: login in script 2020-10-03 00:12:39 +02:00
7dfabb16c7 fix: tls 2020-10-03 00:07:07 +02:00
ea5d9371ca feat: login 2020-10-03 00:00:42 +02:00
3df73a0716 feat: find replication version 2020-10-02 23:58:08 +02:00
ae3c994ff1 feat: dind tests 2020-10-02 23:55:04 +02:00
bd73b385b6 feat: dind 2020-10-02 23:52:19 +02:00
f054b1c5f2 fix: trying to use a standard docker image 2020-10-02 23:38:09 +02:00
d083100a2a fix: image directory path 2020-10-02 23:33:50 +02:00
b813b8df9e feat: docker build and push 2020-10-02 23:32:06 +02:00
d0e966ff1a fix: path 2020-10-02 23:29:48 +02:00
56cbf14fe1 refactor: use custom image 2020-10-02 23:27:45 +02:00
8bf55ebd46 feat: apk update 2020-10-02 23:19:34 +02:00
edbc5ee343 feat: apt install 2020-10-02 23:16:46 +02:00
4a92511582 feat: test install python 2020-10-02 23:14:49 +02:00
b42df2cf4a feat: retrieve version 2020-10-02 23:07:25 +02:00
7549466824 fix: ci deploy name 2020-10-02 18:59:25 +02:00
423e71476d feat: update ci 2020-10-02 18:57:50 +02:00
3bc4b20035 feat: CI file and docker image 2020-10-02 18:56:26 +02:00
9966a24b5e feat: update supported types in README.md 2020-10-02 18:04:32 +02:00
577c01a594 Merge branch '124-use-a-global-session-instance-in-replication' into 'develop'
Resolve "use a global session instance in replication"

See merge request slumber/multi-user!52
2020-10-02 15:51:30 +00:00
3d72796c10 refactor: remove old client ref
feat: update changelog
2020-10-02 17:48:56 +02:00
edcbd7b02a feat: display node in error in the repository view 2020-10-02 17:22:14 +02:00
b368c985b8 refactor: session handler encapsulation 2020-10-02 12:11:53 +02:00
cab1a71eaa fix: version 2020-10-02 09:52:21 +02:00
33cb188509 refactor: use replication session global instance 2020-10-02 00:05:33 +02:00
0a3dd9b5b8 fix: missing get_datablock_from_uuid 2020-10-02 00:00:34 +02:00
7fbdbdcc21 feat: show flag in blender overlays panel 2020-10-01 22:55:06 +02:00
8f9d5aabf9 refactor: moved get_datablock_from_uuid to bl_datablock 2020-10-01 22:51:48 +02:00
824d4d6a83 feat: upgrade replication version to fix duplicate during REPARENT
Related to #113
2020-10-01 15:34:36 +02:00
5f4bccbcd9 feat: POLY curves support
During a mesh->curve conversion, curve type spline is changed to POLY. This is adding the support for POLY curves.

Related to #113
2020-10-01 15:33:10 +02:00
8e8e54fe7d Merge branch '122-crash-on-connection' into 'develop'
Resolve "Crash on connection"

See merge request slumber/multi-user!50
2020-10-01 09:17:59 +00:00
04b13cc0b7 refactor: moveconnection handlers to the main thread 2020-10-01 10:58:30 +02:00
ba98875560 fix: version check command format 2020-09-29 17:33:39 +02:00
a9fb84a5c6 fix: world viewport color sync 2020-09-29 11:47:48 +02:00
2f139178d3 feat: update replication version 2020-09-28 22:59:43 +02:00
e466f81600 fix: file handler not properly closed 2020-09-28 22:51:07 +02:00
cb836e30f5 fix: empty uv useless update 2020-09-28 22:50:42 +02:00
152e356dad fix: font/sound loading 2020-09-28 10:40:07 +02:00
7b13e8978b fix: close file handler after quitting the session 2020-09-28 10:32:41 +02:00
e0839fe1fb Merge branch '118-optionnal-active-camera-sync-flag' into 'develop'
Resolve "Optionnal active camera sync flag"

See merge request slumber/multi-user!49
2020-09-25 14:09:31 +00:00
aec3e8b8bf doc: update replication flag section 2020-09-25 15:27:01 +02:00
a89564de6b feat: append synchronization flags to the top
refactor: enable sync render settings by default
2020-09-25 14:26:31 +02:00
e301a10456 feat: active camera sync flag 2020-09-25 11:33:35 +02:00
cfc6ce91bc feat: initial live syncflag support 2020-09-25 11:23:36 +02:00
4f731c6640 fix: implementation not found if a new type is added 2020-09-23 17:37:21 +02:00
9b1b8f11fd feat: sync object hide_render 2020-09-23 16:48:17 +02:00
e742c824fc feat: sync all object show flags except hide_viewport. 2020-09-23 16:47:51 +02:00
6757bbbd30 fix: enable DIFF_BINARY by default 2020-09-23 16:04:31 +02:00
f6a39e4290 fix: scene differential error
fix: bl_file loading error
feat: update replication version
2020-09-23 14:24:57 +02:00
410d8d2f1a feat: display sync 2020-09-23 10:00:08 +02:00
bd64c17f05 feat: update version 2020-09-22 16:36:59 +02:00
dc063b5954 fix: handle file not found exception 2020-09-21 18:52:27 +02:00
0ae34d5702 Merge branch 'file_replication' into 'develop'
Basic file replication interface

See merge request slumber/multi-user!48
2020-09-21 16:17:58 +00:00
167b39f15e doc: added a cache section to the quickstart 2020-09-21 18:14:30 +02:00
9adc0d7d6e clean: remove image testing (until the file replication interface is done) 2020-09-21 17:48:07 +02:00
fb622fa098 fix: get_datablock_users attribute error 2020-09-21 17:37:06 +02:00
c533d4b86a ci: run tests on every branch 2020-09-21 17:31:07 +02:00
6c47e095be feat: cache managenent utility 2020-09-21 16:47:49 +02:00
f992d06b03 feat: handle packed datablock
feat: filecache settings
2020-09-21 12:12:19 +02:00
af3afc1124 feat: use bl_file in bl_image 2020-09-21 00:11:37 +02:00
b77ab2dd05 feat: use bl_file to replicate font and sound files 2020-09-20 23:31:24 +02:00
150054d19c feat: generic file replication ground work 2020-09-20 19:53:51 +02:00
8d2b9e5580 Merge branch '65-sync-speaker-sounds' into 'develop'
Partial support for syncinf speaker sound files

See merge request slumber/multi-user!47
2020-09-19 19:37:43 +00:00
6870331c34 feat: notice 2020-09-19 18:59:03 +02:00
6f73b7fc29 feat: ground work for sound sync 2020-09-19 00:47:46 +02:00
6385830f53 fix: prevent world replication conflict with external addons 2020-09-18 23:38:21 +02:00
b705228f4a feat: support all font file extention 2020-09-18 23:30:50 +02:00
73d2da4c47 fix: ReparentException error
feat: replication protocol version in ui header
2020-09-18 23:25:01 +02:00
b28e7c2149 Merge branch '116-bfon-is-missing' into 'develop'
Resolve "Bfont is missing"

See merge request slumber/multi-user!46
2020-09-18 21:10:13 +00:00
38f06683be fix: bfont is missing
related to #116
2020-09-18 23:09:47 +02:00
62221c9e49 Merge branch '114-support-custom-fonts' into 'develop'
Resolve "Support custom fonts"

See merge request slumber/multi-user!45
2020-09-18 15:05:25 +00:00
e9f416f682 feat: ground work for custom font support 2020-09-18 17:04:24 +02:00
3108a06e89 fix: sync flag missing comma 2020-09-18 16:17:19 +02:00
470df50dc2 fix: bl_image test, disabling texture unload from ram. 2020-09-18 16:02:50 +02:00
d8a94e3f5e fix: image uuid error 2020-09-18 15:58:43 +02:00
47a0efef27 Merge branch '113-support-datablock-conversion' into 'develop'
Resolve "Support datablock conversion"

See merge request slumber/multi-user!44
2020-09-18 13:33:43 +00:00
ca5aebfeff feat: various images format support
feat: world environment image support
2020-09-18 15:25:52 +02:00
fe6ffd19b4 feat: child date renaming support 2020-09-17 23:45:09 +02:00
b9a6ddafe9 fix: object data load 2020-09-17 23:17:51 +02:00
ae71d7757e feat: reparent ground work 2020-09-17 22:47:11 +02:00
34ed5da6f0 fix: logging 2020-09-15 16:33:49 +02:00
2c16f07ae7 doc: update Changelog 2020-09-15 15:05:09 +02:00
60f25359d1 Merge branch '111-improve-the-logging-process' into 'develop'
Resolve "Improve the logging process"

See merge request slumber/multi-user!42
2020-09-15 11:03:42 +00:00
975b50a988 doc: update log related sections 2020-09-15 13:02:50 +02:00
66417dc84a refactor: minor ui cleanup 2020-09-15 12:40:51 +02:00
514f90d602 feat: logging to files
feat: logging level

Related to #111
2020-09-15 12:31:46 +02:00
086876ad2e feat: update version check to handle experimental ones 2020-09-15 12:29:20 +02:00
71c179f32f fix: python version 2020-09-09 11:58:51 +02:00
2399096b07 feat: experimenting a custom testing image 2020-09-09 11:57:34 +02:00
0c4d1aaa5f feat: update changelog to reflect changes 2020-09-09 11:55:53 +02:00
de8fbb0629 feat: update addon updater to support installation from branches (develop and master) 2020-09-09 10:58:02 +02:00
d7396e578c Merge branch '107-optionnal-flag-to-allow-edit-mesh-updates' into 'develop'
Resolve "Optionnal flag to allow edit mesh updates"

See merge request slumber/multi-user!41
2020-09-08 21:11:09 +00:00
7f5b5866f2 feat: usage warning 2020-09-08 23:09:42 +02:00
3eb1af406b doc: reflect advanced settings changes 2020-09-08 22:56:23 +02:00
79ccac915f feat: experimental edit mode update
Related to #107
2020-09-08 22:37:58 +02:00
f5232ccea0 Merge branch 'master' into develop 2020-09-03 17:23:21 +02:00
c599a4e6ea doc: update advanced section 2020-09-03 16:15:49 +02:00
b3230177d8 Merge branch 'feature/event_driven_updates' into develop 2020-09-03 15:59:19 +02:00
f2da4cb8e9 Merge branch 'develop' of gitlab.com:slumber/multi-user into develop 2020-09-02 16:45:08 +02:00
605bcc7581 refactor: bl_collection lint
feat: late update replication
2020-09-02 16:44:11 +02:00
e31d76a641 Merge branch 'fix-pip-require-virtualenv' into 'develop'
Resolve "'zmq' install (and other pip packages) fails when PIP_REQUIRE_VIRTUALENV env var is set to true"

See merge request slumber/multi-user!40
2020-08-28 17:49:27 +00:00
97c2118b7e doc: add comment to explain why unsetting PIP_REQUIRE_VIRTUALENV is required. 2020-08-28 18:12:01 +02:00
352977e442 fix: unset PIP_REQUIRE_VIRTUALENV if set to ensure multi-user can install its packages 2020-08-28 17:23:25 +02:00
a46d5fa227 fix: missing ui error, missing scene 2020-08-28 15:27:46 +02:00
ade736d8a5 refacotr: collection test 2020-08-28 15:01:50 +02:00
d7f7e86015 fix: collection dump 2020-08-28 14:52:56 +02:00
5e7d1e1dda feat: update replication version 2020-08-28 14:20:00 +02:00
fa5f0c7296 fix: replication version 2020-08-28 14:13:20 +02:00
f14d0915c8 feat: same collection management for Scene Master collection 2020-08-28 14:10:09 +02:00
d1e088d229 feat: orhtographic_scale sync 2020-08-28 14:09:10 +02:00
aa35da9c56 refactor: move attribute skipping warnings to debug 2020-08-28 11:28:26 +02:00
f26c3b2606 refactor: use uuid for collection loading 2020-08-28 11:27:03 +02:00
00d60be75b feat: change replication to the pre-release version 2020-08-27 11:40:26 +02:00
bb5b9fe4c8 refactor: move deepdiff dependency to replication 2020-08-27 10:45:54 +02:00
c6af49492e Merge branch 'master' of gitlab.com:slumber/multi-user 2020-08-26 11:35:47 +02:00
6158ef5171 feat: discord link in readme 2020-08-26 11:35:06 +02:00
6475b4fc08 feat: collection insance offset support
Related to #105
2020-08-24 17:49:17 +02:00
e4e09d63ff fix: instanced collection replication
Related to #105
2020-08-24 17:48:14 +02:00
4b07ae0cc3 fix: fix test condition 2020-08-07 15:47:05 +02:00
49a419cbe2 fix: none result while trying to access a node 2020-08-07 15:38:11 +02:00
5d52fb2460 fix: avoid build ci from running on other branch than develop and master 2020-08-07 15:08:08 +02:00
f1e09c1507 Merge branch 'develop' into feature/event_driven_updates 2020-08-07 15:07:17 +02:00
f915c52bd0 fix: loader missing 2020-08-06 15:33:08 +02:00
dee2e77552 fix: modifier assigned vertex groups 2020-08-06 15:26:55 +02:00
7953a2a177 feat: Update CHANGELOG.md 2020-07-31 09:01:01 +00:00
3f0082927e feat: lock movement support 2020-07-29 11:10:35 +02:00
07ffe05a84 feat: enable autoupdater back 2020-07-28 17:26:14 +02:00
09ee1cf826 fix: auto updater download 2020-07-28 17:17:39 +02:00
61bcec98c3 fix: wrong debian version 2020-07-28 13:37:06 +00:00
1c85d436fd feat: missing update 2020-07-28 13:32:33 +00:00
03318026d4 feat: missing zip program 2020-07-28 13:26:54 +00:00
7a0b142d69 feat: zip build artifacts 2020-07-28 13:20:35 +00:00
eb874110f8 Merge branch 'develop' 2020-07-28 14:25:42 +02:00
6e0c7bc332 clean disable armature missing roll 2020-07-28 12:06:58 +02:00
ee83e61b09 fix: None image 2020-07-28 12:05:26 +02:00
99b2dc0539 refactor: increase use line width 2020-07-28 12:05:04 +02:00
53f1118181 refactor: update download links 2020-07-27 17:44:27 +02:00
2791264a92 feat: empty image support 2020-07-24 21:38:00 +02:00
6c2ee0cad3 refactor: lobby ui 2020-07-24 16:02:19 +02:00
20f8c25f55 refactor: timeout update 2020-07-24 14:58:07 +02:00
0224f55104 refactor: change the timeout 2020-07-24 14:57:39 +02:00
644702ebdf feat: client state update as soon a client are in the lobby 2020-07-24 14:56:20 +02:00
9377b2be9b fix: session pannel title 2020-07-24 14:55:14 +02:00
29cbf23142 doc: update hosting guide 2020-07-24 14:53:44 +02:00
a645f71d19 fix: material socket index
Related to #101
2020-07-22 16:41:01 +02:00
909d92a7a1 fix: broken materials links
Related to #102
2020-07-21 16:46:16 +02:00
7ee9089087 feat: use callbacks instead of timers to cleanup session states
refactor: move graph initialization to operators,py
2020-07-17 16:33:39 +02:00
6201c82392 fix: Loading the false scene by default
`get` was giving wrong result inthe  scene initialization routing during the  resolve process

Related to #100
2020-07-17 14:47:52 +02:00
0faf7d9436 fix: initial test to handle #99 2020-07-15 19:08:53 +02:00
e69e61117a fix: Process "Quitting session" does not finish and gets stuck
Related to #101
2020-07-15 14:46:48 +02:00
25e988d423 fix: Unregistration of users
Related to #97
2020-07-15 13:50:46 +02:00
8a3ab895e0 fix: ci blender install 2020-07-14 12:56:34 +00:00
06a8e3c0ab feat: replication update 2020-07-14 14:54:22 +02:00
c1c1628a38 Update .gitlab/ci/test.gitlab-ci.yml 2020-07-14 10:07:30 +00:00
022e3354d9 feat: psutils test 2020-07-14 11:59:45 +02:00
211cb848b9 feat: update replication version 2020-07-14 11:29:30 +02:00
25e233f328 fix: temporary disabled spline IK test until the python api is fixed 2020-07-13 15:57:19 +02:00
9bc3d9b29d feat: dependencies version check 2020-07-13 15:12:15 +02:00
15debf339d feat: auto-update dependencies 2020-07-10 18:00:44 +02:00
56df7d182d clean: remove libs 2020-07-10 17:05:42 +02:00
26e1579e35 feat: update ci 2020-07-10 16:59:47 +02:00
a0e290ad6d feat: remove submodule 2020-07-10 16:59:32 +02:00
092384b2e4 feat: use replication from pip 2020-07-10 16:50:09 +02:00
2dc3654e6c feat: tests
feat: services heartbeats
clean: remove psutil dependency
2020-07-09 22:10:26 +02:00
f37a9efc60 feat: orthographic correction 2020-07-09 15:52:42 +02:00
0c5d323063 clean: remove old modal operator queue 2020-07-09 15:17:45 +02:00
b9f1b8a871 fix: armature operator is not running 2020-07-08 18:09:00 +02:00
2f6d8e1701 feat: initial camera background image support 2020-07-07 17:09:37 +02:00
9e64584f2d fix: ZeroDivisionError: integer division or modulo by zero 2020-07-07 15:50:05 +02:00
154aaf71c8 fix: disable test 2020-07-07 13:32:30 +00:00
ac24ab69ff fix: revert and disable testing until a definitive fix 2020-07-07 13:29:08 +00:00
ad431378f8 fix: test with a debian based image 2020-07-07 13:18:34 +00:00
784506cd95 fix: update build file 2020-07-07 13:07:55 +00:00
eb7542b1dd fix: update test.gitlab-ic.yml 2020-07-07 12:44:58 +00:00
2bc0d18120 fix: another attempt to fix the tests 2020-07-07 12:24:10 +00:00
27f9b8c659 fix: test errors attempt 2020-07-07 11:24:34 +00:00
ae08b40e8b fix: another attempt to fix psutil install on docker 2020-07-07 09:45:48 +00:00
6ce4cc2d47 fix: python dev version 2020-07-07 09:34:50 +00:00
f96d5e0e2f fix: pipeline test 2020-07-07 11:26:30 +02:00
8ec80b5150 fix: test pipeline 2020-07-07 11:22:05 +02:00
691c45b2c2 feat: missing dependencies
feat: update test to blender 2.90.0
2020-07-07 11:11:36 +02:00
25f3e27b7f fix: Python.exe sometimes dont shut down in task manager processes
fix: disconnect attempt when the session is not running

Related to slumber/multi-user#94
2020-07-07 10:58:34 +02:00
e2cdd26b7c feat: update submodule 2020-07-02 14:16:11 +02:00
eb52deade6 fix: initial fix for Snap user: Unknown location error
Related to #95.
2020-07-02 14:14:16 +02:00
0e8bdf7fe5 feat: IPC port is now verified on update.
feat: A wrong ip is filled with the default one 127.0.0.1
2020-07-02 10:12:08 +02:00
b2d1cec7f4 feat: verbose commit errors 2020-06-30 11:14:42 +02:00
29e19c7e05 fix: missing function 2020-06-29 18:49:06 +02:00
dda252729d fix: Client get stuck during initial snapshots
Related to #91
2020-06-29 18:25:30 +02:00
4e4d366a57 fix: wrong download link 2020-06-28 23:24:03 +02:00
fca53a6725 feat: better traceback handling 2020-06-28 21:34:49 +02:00
80f37583cc fix: start empty on local host 2020-06-26 22:46:38 +02:00
5f763906c3 clean: remove print 2020-06-25 13:00:15 +02:00
f64d36d7ed feat: ip string verification 2020-06-24 16:58:44 +02:00
dc6975171c feat: update submodule 2020-06-24 09:55:23 +02:00
e5d3c664a7 feat: update submodule to develop 2020-06-24 09:55:01 +02:00
d11035fd6c doc: dedicated server startup 2020-06-24 09:53:45 +02:00
406039aa21 Merge branch 'dedicated_server' into 'develop'
feat: dedicated server

See merge request slumber/multi-user!38
2020-06-23 21:28:30 +00:00
5e8c4c1455 doc: added hyperlink 2020-06-23 23:23:46 +02:00
92efa89e35 feat: dedicated server command list 2020-06-23 19:20:09 +02:00
d806570ee0 doc: added discord invite link 2020-06-23 19:04:07 +02:00
b414ca31b1 feat: submodule update
doc: dedicated server progress
2020-06-23 18:55:31 +02:00
59bfcede97 doc: orthographic pass 2020-06-23 17:59:56 +02:00
9d8e3a3e7b doc: network connection 2020-06-23 17:52:40 +02:00
788477502d doc: hosting guide progress 2020-06-23 16:21:12 +02:00
226c01df8b doc: hosting guide progress 2020-06-23 00:15:25 +02:00
c57fb0ca67 feat: various fix inculded in submodule update 2020-06-22 18:40:23 +02:00
745c7ca04a clean: operator
feat: update submodules
2020-06-22 18:23:27 +02:00
8ddb86556d clean: remove unused vars from operator.py
doc: carry on hosting guide
2020-06-22 17:25:44 +02:00
b1ccbf72f3 doc: internet guide update 2020-06-22 14:54:18 +02:00
f85001cb1a feat: update changelog 2020-06-22 11:53:17 +02:00
a7371c0566 doc: quickstart advanced section update 2020-06-22 11:44:37 +02:00
3d9c20cc03 doc: update manage data section 2020-06-22 11:02:58 +02:00
661065e51f doc: orthigraphic correction 2020-06-22 10:12:55 +02:00
c1fe033ff3 doc: feat links 2020-06-19 12:09:25 +02:00
3ea45b3cf6 doc: feat manage session section 2020-06-19 11:58:12 +02:00
b385a821d4 doc: quickstart refactoring progress 2020-06-19 11:34:15 +02:00
ac1e1f39b7 doc: feat glossary 2020-06-19 10:50:29 +02:00
41140286e1 feat: missing images 2020-06-18 18:42:06 +02:00
c50313f8b1 doc: feat glossary 2020-06-18 18:06:18 +02:00
2ad626197f doc: revamp progress 2020-06-18 17:06:43 +02:00
e927676e3e doc: update 2020-06-18 15:54:48 +02:00
4531b7fd6d doc: carry on quickstart refactoring 2020-06-18 12:26:18 +02:00
5199a810cd feat: show host serving address 2020-06-17 22:11:20 +02:00
2bdbfb082b doc: quickstart revamp
refactor: ttl start on connection
2020-06-17 19:21:57 +02:00
9e6b1a141d refactor: uui cleanup 2020-06-17 12:10:16 +02:00
9c3afdbd81 doc: update capture 2020-06-16 18:54:17 +02:00
32669cef22 fix: wrong orthograph 2020-06-16 18:50:08 +02:00
cc6d1a35bc doc: update captures 2020-06-16 18:45:53 +02:00
63a36ad5d4 refactor: remove ip from host parameters 2020-06-16 18:25:49 +02:00
bcdefca32c refactor: remove unused STRICT right strategy 2020-06-16 18:04:27 +02:00
88e69711ba fix: connected user display in lobby 2020-06-16 17:15:32 +02:00
1ccfd59e65 feat: ui icons
feat: server cmd update
2020-06-16 16:40:00 +02:00
a201ae4ea6 feat: admin client repository init on connection to an empty server 2020-06-16 15:19:38 +02:00
e9029b1414 feat: connection protocol refactoring 2020-06-16 00:02:02 +02:00
19946794f6 refactor: explicit ui label 2020-06-11 18:35:52 +02:00
3f15092b3a clean: image logs 2020-06-11 16:31:25 +02:00
838df92217 refactor: add an icon for non admin-user 2020-06-11 15:25:58 +02:00
54b01e4513 refacotor: set thost by default 2020-06-11 15:00:51 +02:00
c065b198d4 feat: added an initialization step 2020-06-10 18:43:21 +02:00
12c0dab881 feat: kick command is back in the ui
clean: unused logs
2020-06-10 14:56:03 +02:00
7759234ea3 refactor: cleanup connction operator 2020-06-10 10:15:39 +02:00
ad99a349f7 feat: show admin status in UI
feat: update submodule
2020-06-09 23:56:20 +02:00
fdc7e4678c feat: update submodule
feat: hide uuid
2020-06-09 18:02:53 +02:00
8d040cc304 feat: update submodule 2020-06-05 18:41:05 +02:00
f1c95d03f8 feat: initial work to run a dedicated server 2020-06-04 18:38:03 +02:00
b55faf2d1c fix: Object location is reset to the origin
Related to #84
2020-06-04 16:53:26 +02:00
258f27d96e fix: get undo handlers back to fix undo crashes
related to #32
2020-05-28 12:59:05 +02:00
8027e541c3 fix: package installation on linux
Related to #74
2020-05-27 15:57:57 +02:00
fc1108ab61 feat: Feature Proposal, Documentation and Refactoring issue templates 2020-05-20 11:32:36 +00:00
54bcd41267 fix: wrong scene initialisation 2020-05-16 21:45:42 +02:00
25c19471bb feat: update submodule 2020-05-15 18:23:51 +02:00
9e4e646bb1 Merge branch 'develop' into feature/event_driven_updates 2020-05-15 16:19:47 +02:00
95524fa3e9 Merge branch '29-differential-revision' into develop 2020-05-09 17:05:49 +02:00
07a646aa18 feat: submodule update 2020-05-09 16:34:14 +02:00
67fc19dae1 fix: get hard reference back
fix: image crash
2020-05-08 15:11:18 +02:00
1070cabf7a Merge branch '29-differential-revision' into 'develop'
fix: spot light shape replication

See merge request slumber/multi-user!36
2020-05-01 21:03:18 +00:00
fcc9292e02 fix: spot light shape replication 2020-05-01 22:58:27 +02:00
f3d8f15ab1 Merge branch '29-differential-revision' into 'develop'
Resolve "Implementation cleanup"

See merge request slumber/multi-user!32
2020-04-22 15:24:11 +00:00
4c44c2f1a0 feat: logging cleanup 2020-04-22 17:04:14 +02:00
e7d948049d feat: test build 2020-04-17 15:49:22 +02:00
0ad0f4d62d feat: remove branch build restriction 2020-04-17 15:46:52 +02:00
7df6ab1852 feat: clean log for library import
feat: color curve map for scene test
feat; update submodules
2020-04-17 15:28:17 +02:00
b4d1e04b87 fix: sidebar refresh 2020-04-14 18:56:20 +02:00
2e60bb985f feat: custom panel category 2020-04-14 17:22:28 +02:00
f8fa407a45 Merge branch '29-differential-revision' into feature/event_driven_updates 2020-04-13 11:48:20 +02:00
b2085e80f8 Merge branch 'develop' into 29-differential-revision 2020-04-09 21:45:44 +02:00
95241d4148 feat: start to test operators 2020-04-08 19:41:57 +02:00
03490af042 feat: additional tests 2020-04-08 19:28:02 +02:00
94aeff7b35 feat: new tests
fix: curve diff errors
fix: metaball diff error
fix: scene error
2020-04-08 18:40:02 +02:00
f5452b8aee Update .gitlab/ci/test.gitlab-ci.yml 2020-04-08 10:20:13 +00:00
4f02134b6c feat: expose connection TTL 2020-04-08 11:15:29 +02:00
52b2c25014 fix: wrong dir 2020-04-08 09:09:09 +00:00
d8f68640b5 refactor: test to move test_script 2020-04-08 09:06:36 +00:00
bb2fc2c32b Update .gitlab/ci/test.gitlab-ci.yml 2020-04-08 09:00:47 +00:00
582c908dc4 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-08 08:47:42 +00:00
506284ad1f another ci test 2020-04-08 08:41:24 +00:00
e7e8782c28 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-08 08:18:42 +00:00
3f614cdcef Update test.gitlab-ci.yml 2020-04-07 19:36:44 +00:00
5f1853bbe3 Update test.gitlab-ci.yml 2020-04-07 19:32:40 +00:00
99d64cd411 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 17:14:12 +00:00
607a1f25d3 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 17:12:27 +00:00
b047b48738 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 17:11:05 +00:00
e1688f7f12 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 17:09:12 +00:00
5aa7a1f140 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 17:04:56 +00:00
ca141f9860 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 17:03:15 +00:00
d4d14d57ff Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 17:00:19 +00:00
1789ae20cf Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 16:56:24 +00:00
2e0414f9d5 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 16:55:15 +00:00
52cbf79f39 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 16:54:14 +00:00
e9e06bbf8f Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 16:53:12 +00:00
1f16e07a3c Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 16:52:29 +00:00
e476d44527 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 16:48:40 +00:00
7a09026b6c Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 16:47:52 +00:00
09c724ac53 Update .gitlab/ci/test.gitlab-ci.yml 2020-04-07 16:46:59 +00:00
7152bb825d Update .gitlab/ci/test.gitlab-ci.yml, .gitlab/ci/build.gitlab-ci.yml files 2020-04-07 16:45:26 +00:00
e8d23426d7 Update .gitlab/ci/build.gitlab-ci.yml 2020-04-07 16:43:42 +00:00
dcb593db07 refactor: update ci 2020-04-07 18:39:54 +02:00
3b9a722812 refactor: update ci 2020-04-07 18:23:34 +02:00
7cc0c0ccf8 refactor: update ci 2020-04-07 18:22:01 +02:00
1304489748 feat: update submodule 2020-04-07 18:19:50 +02:00
673a9dd669 feat: more tests 2020-04-07 18:19:17 +02:00
fc15478dfa refactor: remove pointer hard reference
feat: light test
2020-04-07 14:49:43 +02:00
c23b5923ab refactor: cleanup 2020-04-07 09:59:04 +02:00
2d700e83bb feat: update submodule 2020-04-06 15:36:28 +02:00
271f210591 fix: light missing parameters 2020-04-06 15:16:57 +02:00
e65dd1939a refactor: update screen only on client update 2020-04-06 14:47:03 +02:00
76be9092c8 Merge branch 'develop' into 29-differential-revision 2020-04-06 11:48:47 +02:00
3394299e8b fix: view_settings error
fix: empty collection error
2020-04-06 10:38:31 +02:00
56ea93508c Merge branch 'develop' into 24-particle-support 2020-04-03 18:23:29 +02:00
5e6f6ac460 Update CHANGELOG.md 2020-04-03 16:10:34 +00:00
49d676f4f2 feat: documentation update
Added kick option
Added show flag description
Updated captures
2020-04-03 17:27:56 +02:00
4dd4cea3ed Merge branch '48-kick-client-from-host' into 'develop'
Resolve "Kick client from host"

See merge request slumber/multi-user!34
2020-04-03 13:49:36 +00:00
408a16064c feat: update submodule 2020-04-03 15:43:04 +02:00
cfd80dd426 feat: update submodule 2020-04-03 15:39:56 +02:00
0fde356f4b feat: initial kick 2020-04-03 14:59:33 +02:00
427b36ddaf Merge branch '36-sync-render-settings' into 'develop'
Resolve "Sync Render Settings"

See merge request slumber/multi-user!33
2020-04-03 08:19:31 +00:00
1b94e017e6 feat: ignore wrong parameters 2020-04-02 19:36:28 +02:00
b3b2296b06 fix: black and white level errors 2020-04-02 19:21:55 +02:00
9c897745fd feat: optionnal setting on host 2020-04-02 18:42:41 +02:00
0783c625d0 feat: initial render settings replication support 2020-04-02 17:39:14 +02:00
a1036956c3 Merge branch '29-differential-revision' into 'develop'
Feat: implementation refactor progress

See merge request slumber/multi-user!31
2020-04-02 12:04:51 +00:00
bfbf2727ea fix: material error 2020-04-02 12:14:12 +02:00
39766739d2 refactor: move dump_anything to the dump modules 2020-04-01 11:37:05 +02:00
776664149e refactor: imports 2020-04-01 11:34:24 +02:00
fef088e39b refactor: cleanup lattice 2020-04-01 10:23:28 +02:00
31feb2439d refactor: cleanup 2020-03-31 17:52:52 +02:00
e041b2cb91 feat: cleanup 2020-03-31 17:42:14 +02:00
379e7cdf71 refactor: cleanup implementation
feat: np_load_collection for collection attr load/unload
2020-03-31 17:28:32 +02:00
928eccfa23 feat: vertex_color support 2020-03-31 10:13:49 +02:00
9c9d7a31bf feat: cleanup metaballs 2020-03-30 18:50:54 +02:00
d46ea3a117 refactor: change default materials refrash rate to 1s 2020-03-30 18:12:43 +02:00
820c6dad7e refactor: feat dump node 2020-03-30 18:05:33 +02:00
acbf897f5d refactor: rename def 2020-03-30 17:21:28 +02:00
981ac03855 Merge branch 'develop' into 29-differential-revision 2020-03-30 17:15:56 +02:00
c20777f860 feat: update submodule 2020-03-30 17:15:38 +02:00
219973930b fix: annotation settings 2020-03-30 15:01:48 +02:00
79ba63ce85 feat: attribute dump function
refactor: cleanup utils
2020-03-30 14:31:35 +02:00
922538dc3a feat: update submodule 2020-03-27 18:52:23 +01:00
5574059b46 Merge branch '29-differential-revision' into 'develop'
various implementation refactoring

See merge request slumber/multi-user!24
2020-03-27 17:50:34 +00:00
289a49251e refactor: cleanup 2020-03-27 18:18:36 +01:00
ef9e9dbae8 feat: action refactoring 2020-03-27 15:50:25 +01:00
98d86c050b feat: update submodules 2020-03-26 21:11:21 +01:00
3f0c31d771 refactor: cleanup implementation 2020-03-26 19:10:26 +01:00
d7e47e5c14 refactor: clean material 2020-03-26 18:51:35 +01:00
cab4a8876b feat: CurveMapping support 2020-03-26 18:51:19 +01:00
d19932cc3b refactor: change default timers for mesh and gpencil 2020-03-26 17:30:45 +01:00
ea9ee4ead1 fix: mesh materials 2020-03-26 17:23:42 +01:00
667c3cd04d fix: mesh update 2020-03-26 17:13:59 +01:00
6334bfdc01 fix: node_tree dump 2020-03-26 17:13:48 +01:00
2016af33b7 fix: missing light shape 2020-03-26 17:13:30 +01:00
f0a2659b43 fix: collection destructor during loading 2020-03-26 16:10:27 +01:00
489502a783 Merge remote-tracking branch 'origin/develop' into 29-differential-revision 2020-03-26 14:38:41 +01:00
cb6e26513c Merge branch '78-jsondiff-import-issue-during-addon-installation' into 'develop'
Resolve "jsondiff import issue during addon installation"

See merge request slumber/multi-user!30
2020-03-26 13:08:10 +00:00
3680a751aa fix: jsondiff import error
Related to #78
2020-03-26 14:04:47 +01:00
4413785903 feat: missing lines 2020-03-26 12:07:12 +01:00
25825f7aeb feat: blender 2.83 api changes 2020-03-26 11:45:41 +01:00
73019fc0b0 feat: grease pencil progress 2020-03-26 11:12:26 +01:00
6a98e749f9 feat: gpencil dump refactoring 2020-03-26 09:20:41 +01:00
a84fccb3ce feat: camera cleanup 2020-03-25 13:24:12 +01:00
f9222d84ea feat: crease and bevel_wieght support 2020-03-25 11:36:29 +01:00
d7964b645a fix: generated image path error 2020-03-25 10:35:31 +01:00
c3ae56abd2 refactor: cleanup progress 2020-03-25 09:47:20 +01:00
daff548010 feat: uv_layer loading 2020-03-24 19:40:18 +01:00
757dbfd6ab feat: mesh loading progress 2020-03-24 19:09:02 +01:00
01fdf7b35b feat: mesh implementation cleanup progress 2020-03-23 21:49:28 +01:00
90d4bb0e47 feat: mesh dump refactoring wip 2020-03-23 17:55:10 +01:00
01faa94a9a fix: resolve error 2020-03-23 15:29:34 +01:00
b55700862f fix: loadimg error 2020-03-23 13:49:47 +01:00
90a44eb5db fix resolve 2020-03-23 12:09:59 +01:00
fb0760928e feat: verbose errors 2020-03-23 11:04:06 +01:00
8ce53b8413 feat: bl_object clean
Related to #29
2020-03-20 19:31:48 +01:00
2484028b5a feat: cleanup 2020-03-20 16:14:54 +01:00
2fcb4615be feat: GPL headers 2020-03-20 14:56:50 +01:00
653cf7e25a Merge remote-tracking branch 'origin/develop' into 29-differential-revision 2020-03-20 14:28:07 +01:00
aa0b54a054 fix: ui refresh 2020-03-20 14:17:58 +01:00
8d2755060e Merge branch '76-handle-services-timeout-error' into 'develop'
Resolve "Handle services timeout error"

See merge request slumber/multi-user!29
2020-03-20 12:43:41 +00:00
ba9b4ebe70 feat: update submodules 2020-03-20 13:41:42 +01:00
b8f46c2523 fix: service launching error
Related to #76
2020-03-20 11:46:43 +01:00
153ff5b129 Merge branch 'develop' into 29-differential-revision 2020-03-19 18:55:37 +01:00
931301074e refactor: remove badges from README 2020-03-19 17:08:59 +00:00
56e5709a35 refactor: use pickle instead of msgpack 2020-03-19 17:26:30 +01:00
7fa97704bd feat: gitlab-ci 2020-03-19 10:33:19 +00:00
85b3f6e246 feat: bug report template 2020-03-19 10:25:21 +00:00
a0676f4e37 hotfix: wrong download link 2020-03-14 20:30:18 +00:00
5a0be0f6f9 Update README.md 2020-03-14 15:36:48 +00:00
717a2da3de refactor: cleanup progression 2020-03-13 17:13:39 +01:00
4a127e617c feat: cleanup 2020-03-13 15:05:00 +01:00
3f7cb65393 doc: update download links to job builds 2020-03-12 13:39:50 +01:00
cd00813aed Merge branch '71-blender-addon-updater-integration' into 'develop'
Resolve "Blender Addon Updater integration"

See merge request slumber/multi-user!26
2020-03-12 12:28:47 +00:00
511983c7ff feat: remove useless information panel
feat: doc_url field [2.83 update](https://developer.blender.org/D7015)
2020-03-12 13:25:13 +01:00
1e580dbcd6 Update multi_user/__init__.py, .gitlab-ci.yml files 2020-03-12 12:17:30 +00:00
824040660b Update .gitlab-ci.yml 2020-03-12 12:06:27 +00:00
931c683030 Update .gitlab-ci.yml 2020-03-12 12:04:52 +00:00
ff5e56e36c fix: use release 2020-03-12 11:57:54 +01:00
1c6e88ce61 feat: get links from gitlab releases 2020-03-12 11:40:36 +01:00
08b9a35981 Update .gitlab-ci.yml 2020-03-11 22:43:25 +00:00
7db7382c68 Update .gitlab-ci.yml 2020-03-11 22:41:23 +00:00
1e81a2de16 Update .gitlab-ci.yml 2020-03-11 22:38:09 +00:00
624f67a621 Update .gitlab-ci.yml 2020-03-11 22:36:26 +00:00
ffb6c397b8 Test addon build 2020-03-11 22:35:50 +00:00
dbaff5df85 feat: auto_updater script 2020-03-11 22:42:09 +01:00
5f95eadc1d feat: test particle cache access 2020-03-11 18:37:43 +01:00
40ad96b0af feat: initial particle system support
Related to #24
2020-03-11 17:45:56 +01:00
75839e60f0 refactor: cleanup 2020-03-11 15:17:13 +01:00
cd10dbb04d feat: update submodule 2020-03-11 15:09:52 +01:00
7c3ac6aeed Merge branch '29-differential-revision' into 'develop'
Various cleanup

See merge request slumber/multi-user!23
2020-03-11 14:03:05 +00:00
d30f4452be Merge branch 'develop' into '29-differential-revision'
# Conflicts:
#   multi_user/bl_types/bl_curve.py
2020-03-11 14:02:05 +00:00
61a05dc347 fix: curve commit error
Releated to #72
2020-03-10 18:04:06 +01:00
9f59e7b6e8 fix: curve commit error
Releated to #72
2020-03-10 18:00:23 +01:00
30f787f507 refactor: progress on bl_data_io clean 2020-03-09 16:12:18 +01:00
a8da01c8ff feat: start to leanup datablock io api 2020-03-09 15:59:30 +01:00
9df7cd4659 Merge branch '40-multi-scene-workflow' into 'develop'
Resolve "Multi scene workflow"

See merge request slumber/multi-user!22
2020-03-06 12:48:32 +00:00
c281ac4397 feat: update snap user to support snaping accross scenes
Related to #40
2020-03-05 17:31:12 +01:00
250cf91032 feat: show flag for user on an other scene
feat: disable user drawing on other scene

Related to #40
2020-03-05 17:20:04 +01:00
fe9a096ab2 feat: store current scene in user metadata
Related to #40
2020-03-05 16:19:13 +01:00
a6e1566f89 Merge branch '40-multi-scene-workflow' of gitlab.com:slumber/multi-user into feature/event_driven_updates 2020-03-05 16:17:00 +01:00
adeb694b2d feat: one apply timer for all 2020-03-05 15:38:20 +01:00
50d14e663e feat: update sumbodules 2020-03-05 10:56:17 +01:00
9b8d69042d feat: update submodule 2020-03-04 22:28:34 +01:00
b2475081b6 feat: id accessor 2020-03-04 18:28:42 +01:00
aef1d8987c Merge branch '61-config-file-prevents-having-the-addon-on-a-shared-network-location' into feature/event_driven_updates 2020-03-04 14:54:42 +01:00
d8f49ff298 Merge branch '61-config-file-prevents-having-the-addon-on-a-shared-network-location' into 'develop'
Resolve "Config file prevents having the addon on a shared network location"

See merge request slumber/multi-user!20
2020-03-04 13:52:54 +00:00
efa243211b feat: remove headers 2020-03-04 14:12:56 +01:00
f03a3aadff feat: cleanup ui 2020-03-04 12:51:56 +01:00
16147ae2ba feat: custom cache directory in userpref 2020-03-02 11:09:45 +01:00
8e600778ab feat: store addon config in user preference (except runtime vars)
Related to #20
2020-02-28 17:34:30 +01:00
292f76aea5 feat: move diff to observer
feat: logs
2020-02-28 15:39:29 +01:00
28c4ccf1f3 Merge branch 'develop' into feature/event_driven_updates 2020-02-28 14:48:09 +01:00
a7641d6fc9 doc: update version 2020-02-28 14:26:24 +01:00
c7584964fe refactor: change download version 2020-02-28 14:08:52 +01:00
02938d1e40 hotfix: script dir name on linux 2020-02-28 12:28:42 +01:00
2baddd1fc8 Merge branch 'develop' into 'master'
v0.0.2

Closes #69

See merge request slumber/multi-user!19
2020-02-28 10:39:22 +00:00
2703e8c15e feat: update submodule 2020-02-28 11:24:59 +01:00
8468be2690 refactor: disable CI testing until the refactoring 2020-02-28 11:20:47 +01:00
d22586cd6e feat: improve addon bl_infos and changelog 2020-02-27 23:15:31 +01:00
99feeb9b5e refactor: cleanup changelog 2020-02-27 22:51:08 +01:00
d3bb1f043d feat: changelog 2020-02-27 22:38:35 +01:00
8d609a82ff fix: wrong grease pencil frame loading 2020-02-26 17:33:33 +01:00
0cbdc265a3 fix: matrix world apply error
use loc/rot/scale instead of matrix world
2020-02-26 17:02:33 +01:00
57a243798b fix: mesh auto_smooh 2020-02-26 15:37:19 +01:00
a811211061 fix: material roughtness loading
fix: graph pre-load broken

Related to #68
2020-02-26 15:11:27 +01:00
3d2ff10f80 fix: action type loading
Related to #70
2020-02-26 15:01:22 +01:00
ded2d3490f fix: Updates timer doesn't correctly unregister on connection timeout
Close #69
2020-02-26 12:03:48 +01:00
450b18cf16 feat: preload refactoring ground work
Related to #68
2020-02-26 11:41:08 +01:00
414af6388c fix: mathutils.Euler sync error
fix: material dumping errors

added mathutils.Euler to dump anything

Related to #67
2020-02-25 19:20:49 +01:00
549b0b3784 fix: submodule version 2020-02-25 17:40:00 +01:00
fc9ab1a7e6 feat: update submodule 2020-02-25 17:38:43 +01:00
44bffc1850 Merge remote-tracking branch 'origin/develop' into feature/event_driven_updates 2020-02-25 17:37:24 +01:00
e9f556f690 Merge branch '63-image-node-color-space-parameter-not-sync' into 'develop'
Resolve "Image node color space parameter not sync"

See merge request slumber/multi-user!18
2020-02-25 16:13:42 +00:00
d15566daf7 fix: image color space sync 2020-02-25 17:06:40 +01:00
badd4cc247 Merge branch '64-user-selection-incositent-with-active-view_layer' into 'develop'
Resolve "User selection incositent with active view_layer"

See merge request slumber/multi-user!17
2020-02-25 15:51:42 +00:00
0a52b3cf80 fix: User selection incositent with active view_layer 2020-02-25 16:35:26 +01:00
26cec517c0 Merge branch '59-timeout-issue-for-scenes-that-are-large-enough' into 'develop'
Resolve "Timeout issue for scenes that are large enough"

See merge request slumber/multi-user!14
2020-02-25 14:01:51 +00:00
d546bc257a feat: bones custom shapes 2020-02-24 15:49:11 +01:00
e71893c5b6 refactor: cleanup 2020-02-24 14:43:18 +01:00
77979acc42 fix: Denied write access on connection for heavy scene (let blender delayables apply all data for us) 2020-02-23 17:17:11 +01:00
a141e9bfe7 feat: stash on deps graph update 2020-02-23 14:08:45 +01:00
5d576d6f25 fix: modal operator error 2020-02-21 16:52:02 +01:00
6142a09283 fix: quit status 2020-02-21 13:08:24 +01:00
7d989faae6 feat: error handling during disconnection
fix: various session disctonnect error (replication submodule)
2020-02-21 12:00:34 +01:00
56a625ae48 feat: quitting session progress bar 2020-02-20 18:36:53 +01:00
07ce5ddb83 doc: hosting guioe update 2020-02-20 16:09:14 +01:00
93472db01b feat: hosting guide progress 2020-02-20 16:04:03 +01:00
9db7bcb73c fix: wrong file directory 2020-02-20 14:48:10 +01:00
536cf4cf7b doc: refactor folder organization 2020-02-20 14:44:24 +01:00
e21995a36d feat: documentation subsection test 2020-02-20 14:38:15 +01:00
67f1149f65 refactor: cleanup 2020-02-20 14:17:50 +01:00
699bdf5fe0 feat: quitting state 2020-02-20 13:17:28 +01:00
e3d76c37db feat: update submodule version 2020-02-20 11:57:37 +01:00
3d9a320612 feat: update submodule version with service management layer 2020-02-19 18:10:14 +01:00
2d352ec14a feat: show basic service states in ui 2020-02-19 18:07:25 +01:00
386af902a4 Merge branch '60-pip-packages-install-location' into 'develop'
Resolve "pip packages install location"

See merge request slumber/multi-user!15
2020-02-19 16:27:20 +00:00
b9d144f24a feat: services basic ui to track services states 2020-02-19 16:22:06 +01:00
32b24164cf refactor: remove packages installation target directory.
Related to #60
2020-02-19 13:12:09 +01:00
5f2dca4032 feat: update submodule 2020-02-14 16:54:51 +01:00
6a0705a73e feat: increase snap timer refresh rate
fix (replication): unknown user state update
2020-02-14 16:44:53 +01:00
f1020fb072 feat: prevent apply before session in active 2020-02-14 16:02:30 +01:00
65525ca2e1 feat: notice 2020-02-09 23:37:02 +01:00
af53e54aa8 refactor: progress bar update 2020-02-09 00:55:19 +01:00
6975edfb66 feat: simple progress bar 2020-02-09 00:41:00 +01:00
c42c0cb017 refactor: cleanup 2020-02-08 23:25:37 +01:00
378f52a1ab fix: mesh uv loading issue
refacotr: loading status
refactor: cleanup logs
2020-02-08 23:23:00 +01:00
b182632723 feat: show basic progress 2020-02-07 18:09:33 +01:00
8a2d178a4f refactor: state with progression ! 2020-02-07 17:56:58 +01:00
81752e9a23 fix: delayable from accessing session data before its ready
refactor: remove
feat: submodule update
2020-02-07 17:08:36 +01:00
22eb65358b feat: launch server from orchestrator 2020-02-07 14:11:23 +01:00
2034773df6 fix: handle connexion error 2020-02-07 11:34:23 +01:00
5422518a47 fix: lightprobe version support error 2020-02-07 10:50:14 +01:00
210e8aa0fa feat: merged !12 changes (@c2ba) 2020-02-07 10:39:12 +01:00
b0c195c34f feat: update submodule 2020-02-07 00:49:04 +01:00
0753882015 feat: lightprobe warning
refactor: set logging default level to WARNING
2020-02-07 00:48:34 +01:00
cbdf8c94d7 feat: submodule update 2020-02-06 23:22:56 +01:00
6c47e72766 feat: big overal refactoring
Added an orchestrator
Removed ClienfEnventHandler
Exposed IPC Port for local dev

Relative to #59
2020-02-06 18:54:46 +01:00
63294d2fd8 feat: update submodule version 2020-02-05 23:38:56 +01:00
4825e6876c feat: experiment bin diff for meshes 2020-02-05 23:26:53 +01:00
d1501da2f1 feat: cleanup 2020-02-05 16:33:21 +01:00
3b459d5387 refactor: cleanup 2020-02-03 23:18:53 +01:00
6a667b0745 feat: experimental subprocess server 2020-02-03 19:04:08 +01:00
4828a91bd5 Merge branch 'feature/event_driven_updates' into 59-timeout-issue-for-scenes-that-are-large-enough 2020-02-03 11:29:22 +01:00
b6614768c4 fix: mesh dumping performance 2020-02-03 11:22:43 +01:00
30278126f8 Fix unrelated exception when address is in use. (@c2ba)
commit changes from !13 in develop.
2020-01-30 14:25:12 +01:00
fcf4604153 feat: deps graph update handler 2020-01-24 17:52:10 +01:00
332287415e feat: update readme 2020-01-24 15:22:18 +01:00
8e5c4b73a8 Merge branch 'sphinx-documentation' into develop 2020-01-24 14:46:41 +01:00
ff12746fe8 Merge branch 'animation-support' into 'develop'
Animation support

See merge request slumber/multi-user!6
2020-01-24 13:35:22 +00:00
356b61c9ff fix: bone_group index 2020-01-24 14:33:00 +01:00
a5e949d52e feat: bone_group support
Bone group replication support with colorsets (not custom for now)

Related to #18
2020-01-24 13:38:10 +01:00
6191e4ac58 feat: bone layers support
Related to #18
2020-01-24 11:38:04 +01:00
e7744708d9 doc: append introduction 2020-01-23 23:01:27 +01:00
e878bc62ba refactor: rename load 2020-01-23 18:20:56 +01:00
e4b5fd3170 fix: vertex group
Related to #18
2020-01-23 17:59:17 +01:00
da76386dd4 feat: update replication version 2020-01-23 11:38:09 +01:00
3181be0887 feat: lightprobes support !
Caution: Only supported since blender 2.83 since the patch https://developer.blender.org/rBe280c0441bd84e73c47dffb66104ed40af9ea592 .

Related to  #35
2020-01-23 11:02:11 +01:00
e9141c4970 refactor: remove handler error message 2020-01-22 18:40:08 +01:00
ece88f3dda fix: session quit on server lost 2020-01-22 18:37:46 +01:00
c8827c5e4b doc: append way to contribute 2020-01-22 18:02:28 +01:00
8800053fa4 doc: update 2020-01-22 17:05:48 +01:00
87fa6e02e6 doc: update client list section 2020-01-22 16:51:36 +01:00
8b7716ac3c feat: snap time operator
feat: snap operators status

It's now possible to snap to others user time's !

Related to #53.
2020-01-22 16:17:48 +01:00
44e525aec7 feat: update replication version 2020-01-22 15:21:17 +01:00
76a51032b3 Merge branch 'user_metadata' into 'animation-support'
User metadata

See merge request slumber/multi-user!9
2020-01-22 14:20:38 +00:00
e22b036cc9 refactor: user metadata 2020-01-22 15:15:44 +01:00
e253ccd52d refactor: use client metadata 2020-01-22 14:33:34 +01:00
da5406952c feat: progression on user matadata handling 2020-01-22 11:20:04 +01:00
73a2bb56e2 refactoring: user metadata progress 2020-01-21 23:24:44 +01:00
011eba8cc9 refactor: connexion process
Related to #19
2020-01-21 16:25:44 +01:00
07df42d087 feat: progression on session mamnagment 2020-01-20 18:55:03 +01:00
ff932b0cdf feat: connexion infos tests (bugged) 2020-01-19 23:10:22 +01:00
fdb7995cbf feat Ground wrk for disconnect refactoring 2020-01-19 17:21:16 +01:00
e99e6965ec refacto: connected user list
Related to #53
2020-01-17 18:15:37 +01:00
65fd73d6c0 feat: ground work to display user current keyframe
Related to #53
2020-01-16 17:56:43 +01:00
0cb75af583 feat: current pose transmission
Current pose is now replicated over the wire.
It should give visibility on the animation state of a skeleton
and push deeper animation possibilities(ex: a char per user).

Related to #18
2020-01-16 17:18:17 +01:00
cb031bab55 feat: dump and loading mathutils.Quaternion
Related to #18
2020-01-16 16:59:55 +01:00
f8bb544005 refactor: enable matrix transmission back for animated objects
Related to #18
2020-01-16 15:27:37 +01:00
95768f4ea1 docs: fill index.rst
Related to #51
2020-01-16 14:26:54 +01:00
278aa6607d documentation: clean titles 2020-01-16 13:34:48 +01:00
b6f923399f feat: documentation base structure
Related to #51
2020-01-16 12:04:33 +01:00
c2fe5c456b documentation: append quickstart page 2020-01-15 22:05:59 +01:00
5008212739 feat: installation 2020-01-15 19:23:19 +01:00
aa3d24f991 feat: update submodule url to https 2020-01-15 19:05:46 +01:00
3c176d25ed feat: documentation configuration 2020-01-15 18:47:20 +01:00
2eec228c3e feat: undo/redo handler
The solution for now is to resolve datablock references when undo appen.

Related to #32.
2020-01-14 11:49:36 +01:00
f55319c453 feat: resolve refactoring, ground work to resolve undo errors
Related to #32, Undo errors
2020-01-13 18:51:31 +01:00
28ca489fc3 refactor: remove old properties 2019-12-30 11:13:48 +01:00
ea3c9d701b refactor: remove dependencies 2019-12-10 22:07:46 +01:00
a8d97aa43b feat: update replication version 2019-12-05 14:28:19 +01:00
c56b52d069 fix: merge error 2019-12-02 17:38:31 +01:00
d12fe9dd70 Merge branch 'master' into animation-support 2019-12-02 17:36:59 +01:00
315c2903c0 refactor: cleanup
related to #18
2019-12-02 17:34:08 +01:00
a12d32341c fix: bone connection
A temporary fix while I am rewriting armature dump
related to #42.
2019-11-28 17:57:47 +01:00
67b9e1a8cf refactor: cleanup code
Related to #18
2019-11-28 11:25:53 +01:00
dedc5a04e0 feat: basic shape key support
Related to #18
2019-11-27 18:06:17 +01:00
efa2d0eeef feat: driver fcurve loading
Related to #39.
2019-11-25 17:39:46 +01:00
b1f5ca5660 refactor: change has_action, has_driver location to utils
fix: wrong transform update behavior for animated object

Related to #39, #18
2019-11-25 16:18:26 +01:00
2666444007 feat: enable drivers sync
Related to #39
2019-11-25 16:06:08 +01:00
89035ebb85 feat: wip on drivers support.
Related to #39
2019-11-25 16:01:48 +01:00
c43207e9bf fix: armature sync error
Related to #18
2019-11-25 11:04:38 +01:00
0b74f54268 Merge branch '34-selection-visibility-for-non-mesh-objects' into 'master'
Resolve "Selection visibility for non-mesh objects"

Closes #34

See merge request slumber/multi-user!8
2019-11-23 15:00:24 +00:00
af923feecd feat: metaball selection drawing
related to #34
2019-11-22 18:51:24 +01:00
12ba867ee1 fix (WIP): work on quick fix for deselection
Related to #41.
2019-11-22 18:32:39 +01:00
805dd4f319 fix: modifier parameter update
Reload modifiers from scratch to prevent loading error on None object pointer parameter.
Related to #41.
2019-11-22 16:44:50 +01:00
f405662fb8 fix: modifier queue change
A quick attempt to replicate modifier order changes. Related to #41.
2019-11-22 16:32:34 +01:00
43eeb8299e feat: smooth overlay lines
fix: selection flush None object error

related to #34.
2019-11-21 17:14:31 +01:00
ebe6af8082 feat: selection tests for non visible objects
related to #34
2019-11-18 18:14:21 +01:00
27e310bfbf fix: prevent circular dependencies
Related to #30.
2019-11-07 18:42:16 +01:00
8c340d83ac feat: constraints dependencies.
Added  constraints target object as node dependency to respec lading order. Related to #30.
2019-11-07 18:34:06 +01:00
8e2a831015 fix: armature parent loading.
Made uuid based parent loading to prevent duplicata once the parent is resolved.
Related to #23.
2019-11-07 18:14:24 +01:00
9e19b3ca91 feat: bone constraint support
Constraint loading code simplification
Load bones constraints.
Related to #30.
2019-11-07 18:13:06 +01:00
5d3f81081a fix: presence errors whithout 3d viewports 2019-11-07 15:28:47 +01:00
88e7fde848 feat: vertices assignation to vertex groups
Related to #23
2019-11-07 15:27:21 +01:00
07b6b552be fix: armature loading when changing area
Remove useless context checks. Related to #23.
2019-11-07 15:26:32 +01:00
e54ce5962e feat: vertex group loading (still WIP)
Load vertex_group and assign weights to corresponding indexes.
Related to #23.
2019-11-07 14:24:11 +01:00
8e42b729e9 feat: ground work for vertex_group
Started to transfert vertex_group in bl_object.
Related to #18.
2019-11-06 17:55:23 +01:00
b0ea3f1acd feat: object reference improvements
Prevent Objects target from being dumped. Append modifiers target objects to dependencies.
Relative to #18, #28.
2019-11-06 16:35:24 +01:00
7bf676020d feat: basic action support
Feat action implementation(load and dump action fcurve).
Append action reference management into bl_datablock.
Updated each concerned implementation to use the new action managment from bl_datablock
Related to #27.
2019-11-06 14:30:16 +01:00
99649f588c feat: Armature support progress
Remove unecessary context correction . #23
2019-11-05 17:40:44 +01:00
1b3c655829 feat: progress on armature support
Append modal timer operator to execute armature loading in the right context. Related to  #18
2019-11-05 14:22:57 +01:00
cfadc91299 feat: progress on unsupported types
#21
2019-11-04 17:55:41 +01:00
345a5d55e7 fix: AttributeError in presence 2019-11-04 16:42:18 +01:00
8f97091118 fix: connection close on new file opening
#21
2019-11-04 16:16:07 +01:00
7e4d3e6d3f feat: progress on armature loading 2019-11-04 15:31:13 +01:00
bd27da7aa6 feat: expose PORT in hostsettings
related to #21
2019-11-01 16:00:57 +01:00
0abd81f9d1 fix: initialisation warnings
close issue #20
2019-10-28 14:31:03 +01:00
98c65e80fe Update README.md 2019-10-22 14:40:08 +00:00
7336819268 fix: reference lost 2019-10-22 16:37:23 +02:00
89ba3bcf56 Update README.md 2019-10-22 14:14:26 +00:00
9d0350ae22 Update README.md 2019-10-22 14:05:30 +00:00
4aac68e746 Update README.md 2019-10-22 13:56:21 +00:00
db5bcfdd11 Update README.md 2019-10-22 13:55:49 +00:00
25fa05ab20 Update README.md 2019-10-22 13:48:54 +00:00
6c3d6a5dd9 Update README.md 2019-10-22 13:38:34 +00:00
5bae286774 Update README.md 2019-10-22 12:59:12 +00:00
2f5869ea9c Update README.md 2019-10-22 12:40:22 +00:00
f577878fff feat: Readme update 2019-10-22 14:21:18 +02:00
320e824dbf Update README.md 2019-10-22 12:08:28 +00:00
fbf62244fb Update README.md 2019-10-21 08:47:22 +00:00
58962f755c feat: multi-scene workflow 2019-10-16 14:48:32 +02:00
ca0fb7c76f fix: renderer error
clean: logging configuration
2019-10-16 10:53:08 +02:00
485e2527fe feat: prevent changing right on source object of a collection instance 2019-10-15 15:15:46 +02:00
d322531dc0 feat: modal for snap view 2019-10-15 15:04:34 +02:00
6969e386e2 feat: snap user not set same user view 2019-10-15 14:28:34 +02:00
c9c359e226 feat: bump submodule version 2019-10-15 14:14:39 +02:00
add01961f2 feat: nested collection selection hihlight 2019-10-14 17:44:19 +02:00
f84b441321 feat: linked collections 2019-10-14 16:53:07 +02:00
0f863749f5 feat: RGB cure support 2019-10-14 15:56:07 +02:00
68d28e4a66 feat: color_ramp loading 2019-10-14 15:24:08 +02:00
7423bd95c2 feat: bring back annotation support 2019-10-14 14:42:23 +02:00
f5e81b2d92 feat: collection instances support 2019-10-14 14:14:11 +02:00
9915fa83e1 fix: repair broken linked objects 2019-10-14 13:40:41 +02:00
e98ff91a5b refacor: clean resolve implementations 2019-10-14 13:08:31 +02:00
9b79b441cf feat: clean up 2019-10-11 16:21:05 +02:00
727394de5d fix: collection 2019-10-11 15:57:09 +02:00
1d041dcbdd feat: submodule update 2019-10-11 13:28:25 +02:00
b3ba76614a refactor: remove asserts() 2019-10-10 18:17:54 +02:00
d293b36f1e fix: collection dump 2019-10-09 19:14:48 +02:00
960b699e3d feat: cleanup before rollback 2019-10-09 18:50:35 +02:00
2f002be7a8 refactor: remove usunused diff 2019-10-09 14:09:11 +02:00
f2b0e35dcf feat: bump module version 2019-10-08 23:54:12 +02:00
b5910ca5b4 feat: uuid collection editing 2019-10-08 22:24:58 +02:00
5e1f019f24 feat: uuid based selection 2019-10-08 21:48:45 +02:00
e047874dbd feat: differential ground work 2019-10-08 18:45:46 +02:00
688b57578c refactor: change buffer to data 2019-10-07 18:31:49 +02:00
411d77643e feat: start to resolve data by uuid 2019-10-07 17:32:56 +02:00
5867d39a52 refactor: remove diff from instances 2019-10-07 16:28:38 +02:00
7eccef5c82 refactor: remove diff definition from implementations 2019-10-07 16:28:04 +02:00
7afb80864e feat: prevent to crash on apply 2019-10-03 18:30:46 +02:00
2e9c3a48a2 fix: gpencil frame 2019-10-03 18:28:13 +02:00
117928de48 feat: dynamic hide_select 2019-10-03 13:23:59 +02:00
16974ac0de feat: initial work on ttl 2019-10-03 00:08:03 +02:00
8155836a12 fix: material image_node loading 2019-10-02 17:28:00 +02:00
2fb0069214 fix: None material error 2019-10-02 17:10:56 +02:00
3d69e96c9f refacor: update to new def 2019-10-02 16:20:41 +02:00
7c9decdded fix: bl_ related errors 2019-10-02 16:19:44 +02:00
98999f09bb feat: move presence update to a draw handler 2019-10-02 14:03:07 +02:00
5819a40a30 fix: selection update error 2019-10-02 14:02:30 +02:00
93be6ae6cc fix: selection right 2019-10-02 14:01:45 +02:00
14ccb68cf7 Update README.md 2019-10-01 09:13:43 +00:00
0ec7da0210 Update README.md 2019-09-30 21:59:53 +00:00
49552bbdb4 Update README.md 2019-09-30 21:52:34 +00:00
2aef9a3e63 Update README.md 2019-09-30 20:05:52 +00:00
11eb31af98 feat: add replication again
feat: non existent config folder
2019-09-30 22:04:54 +02:00
207199adc9 refactor: file organisation 2019-09-30 21:34:58 +02:00
92a5a875a4 Update README.md 2019-09-30 18:49:30 +00:00
e47dba5775 Update README.md 2019-09-30 18:48:07 +00:00
4dccf8d319 Update README.md 2019-09-30 18:47:03 +00:00
0919579dd1 fix: link in readme 2019-09-30 20:29:28 +02:00
b2d3f5de6a feat: cleanup readme 2019-09-30 20:26:20 +02:00
c39e741618 Merge branch 'slumber-master-patch-24169' into 'master'
Update README.md

See merge request slumber/multi-user!5
2019-09-30 16:44:09 +00:00
f60c3937e5 Update README.md 2019-09-30 16:43:59 +00:00
5d3aa19170 Merge branch 'slumber-master-patch-54146' into 'master'
Deleted CHANGELOG

See merge request slumber/multi-user!4
2019-09-30 16:42:53 +00:00
b8eb3680c2 Deleted CHANGELOG 2019-09-30 16:42:41 +00:00
07ae67edaf fix: non existing user configuration
feat:  update readme
2019-09-30 18:41:04 +02:00
203 changed files with 15701 additions and 24799 deletions

10
.gitignore vendored
View File

@ -6,4 +6,12 @@ __pycache__/
.vscode
cache
config
*.code-workspace
*.code-workspace
multi_user_updater/
# sphinx build folder
_build
# ignore generated zip generated from blender_addon_tester
*.zip
libs

13
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,13 @@
stages:
- test
- build
- deploy
- doc
include:
- local: .gitlab/ci/test.gitlab-ci.yml
- local: .gitlab/ci/build.gitlab-ci.yml
- local: .gitlab/ci/deploy.gitlab-ci.yml
- local: .gitlab/ci/doc.gitlab-ci.yml

View File

@ -0,0 +1,12 @@
build:
stage: build
needs: ["test"]
image: debian:stable-slim
script:
- rm -rf tests .git .gitignore script
artifacts:
name: multi_user
paths:
- multi_user
variables:
GIT_SUBMODULE_STRATEGY: recursive

View File

@ -0,0 +1,21 @@
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

@ -0,0 +1,16 @@
pages:
stage: doc
needs: ["deploy"]
image: python
script:
- pip install -U sphinx sphinx_rtd_theme sphinx-material
- sphinx-build -b html ./docs public
artifacts:
paths:
- public
only:
refs:
- master
- develop

View File

@ -0,0 +1,7 @@
test:
stage: test
image: slumber/blender-addon-testing:latest
script:
- python3 scripts/test_addon.py
variables:
GIT_SUBMODULE_STRATEGY: recursive

View File

@ -0,0 +1,46 @@
<!---
Please read this!
Before opening a new issue, make sure to search for keywords in the issues
filtered by the "bug" label:
- https://gitlab.com/slumber/multi-user/-/issues?scope=all&utf8=✓&label_name[]=bug
and verify the issue you're about to submit isn't a duplicate.
--->
### Summary
(Summarize the bug encountered concisely)
* Addon version: (your addon-version)
* Blender version: (your blender version)
* OS: (your os windows/linux/mac)
### Steps to reproduce
(How one can reproduce the issue - this is very important)
### Example Project [optionnal]
(If possible, please create an example project that exhibits the problematic behavior, and link to it here in the bug report)
### What is the current *bug* behavior?
(What actually happens)
### Relevant logs and/or screenshots
(Paste any relevant logs - please use code blocks (```) to format console output,
logs, and code as it's tough to read otherwise.)
### Possible fixes [optionnal]
(If you can, link to the line of code that might be responsible for the problem)
/label ~type::bug
/cc @project-manager

View File

@ -0,0 +1,30 @@
### Problem to solve
<!-- Include the following detail as necessary:
* What feature(s) affected?
* What docs or doc section affected? Include links or paths.
* Is there a problem with a specific document, or a feature/process that's not addressed sufficiently in docs?
* Any other ideas or requests?
-->
### Further details
<!--
* Any concepts, procedures, reference info we could add to make it easier to successfully use the multi-user addom?
* Include use cases, benefits, and/or goals for this work.
-->
### Proposal
<!-- Further specifics for how can we solve the problem. -->
### Who can address the issue
<!-- What if any special expertise is required to resolve this issue? -->
### Other links/references
<!-- E.g. related GitLab issues/MRs -->
/label ~type::documentation
/cc @project-manager

View File

@ -0,0 +1,18 @@
### Problem to solve
<!-- What problem do we solve? Try to define the who/what/why of the opportunity as a user story. For example, "As a (who), I want (what), so I can (why/value)." -->
### Proposal
<!-- How are we going to solve the problem?-->
### Further details
<!-- Include use cases, benefits, goals, or any other details that will help us understand the problem better. -->
### Links / references
/label ~type::feature request
/cc @project-manager

View File

@ -0,0 +1,34 @@
## Summary
<!--
Please briefly describe what part of the code base needs to be refactored.
-->
## Improvements
<!--
Explain the benefits of refactoring this code.
-->
## Risks
<!--
Please list features that can break because of this refactoring and how you intend to solve that.
-->
## Involved components
<!--
List files or directories that will be changed by the refactoring.
-->
## Optional: Intended side effects
<!--
If the refactoring involves changes apart from the main improvements (such as a better UI), list them here.
It may be a good idea to create separate issues and link them here.
-->
/label ~type::refactoring
/cc @project-manager

6
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "libs/replication"]
path = libs/replication
url = git@gitlab.com:slumber/replication.git
[submodule "multi_user/libs/replication"]
path = multi_user/libs/replication
url = https://gitlab.com/slumber/replication.git

View File

@ -1,26 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
## [v0.0.1]
### Added
- Functionnal chat test
## [v0.0.2]
### Added
- Property map shared between clients
- Callbacks to push modifications to the blender scene
- Observer Pattern for live property monitoring
- ID to identify properties owner (For primitive right managment)
### Removed
- Chat mecanism ( Will come back after the complete modularity refactoring)
- Unused files and sub-modules
## [v0.0.5]
### Added
- queued communication between threads
- various fixes
- multithreaded archiecture
- curve, gpencil support
- rightmanagment

189
CHANGELOG.md Normal file
View File

@ -0,0 +1,189 @@
# Changelog
All notable changes to this project will be documented in this file.
## [0.0.2] - 2020-02-28
### Added
- Blender animation features support (alpha).
- Action.
- Armature (Unstable).
- Shape key.
- Drivers.
- Constraints.
- Snap to user timeline tool.
- Light probes support (only since 2.83).
- Metaballs support.
- Improved modifiers support.
- Online documentation.
- Improved Undo handling.
- Improved overall session handling:
- Time To Leave : ensure clients/server disconnect automatically on connection lost.
- Ping: show clients latency.
- Non-blocking connection.
- Connection state tracking.
- Service communication layer to manage background daemons.
### Changed
- UI revamp:
- Show users frame.
- Expose IPC(inter process communication) port.
- New user list.
- Progress bar to track connection status.
- Right management takes view-layer in account for object selection.
- Use a basic BFS approach for replication graph pre-load.
- Serialization is now based on marshal (2x performance improvements).
- Let pip chose python dependencies install path.
## [0.0.3] - 2020-07-29
### Added
- Auto updater support
- Big Performances improvements on Meshes, Gpencils, Actions
- Multi-scene workflow support
- Render setting synchronization
- Kick command
- Dedicated server with a basic command set
- Administrator session status
- Tests
- Blender 2.83-2.90 support
### Changed
- Config is now stored in blender user preference
- Documentation update
- Connection protocol
- UI revamp:
- user localization
- repository init
### Removed
- Unused strict right management strategy
- Legacy config management system
## [0.1.0] - 2020-10-05
### Added
- Dependency graph driven updates [experimental]
- Edit Mode updates
- Late join mechanism
- Sync Axis lock replication
- Sync collection offset
- Sync camera orthographic scale
- Sync custom fonts
- Sync sound files
- Logging configuration (file output and level)
- Object visibility type replication
- Optionnal sync for active camera
- Curve->Mesh conversion
- Mesh->gpencil conversion
### Changed
- Auto updater now handle installation from branches
- Use uuid for collection loading
- Moved session instance to replication package
### Fixed
- Prevent unsupported data types to crash the session
- Modifier vertex group assignation
- World sync
- Snapshot UUID error
- The world is not synchronized
## [0.1.1] - 2020-10-16
### Added
- Session status widget
- Affect dependencies during change owner
- Dedicated server managment scripts(@brybalicious)
### Changed
- Refactored presence.py
- Reset button UI icon
- Documentation `How to contribute` improvements (@brybalicious)
- Documentation `Hosting guide` improvements (@brybalicious)
- Show flags are now available from the viewport overlay
### Fixed
- Render sync race condition (causing scene errors)
- Binary differentials
- Hybrid session crashes between Linux/Windows
- Materials node default output value
- Right selection
- Client node rights changed to COMMON after disconnecting from the server
- Collection instances selection draw
- Packed image save error
- Material replication
- UI spelling errors (@brybalicious)
## [0.2.0] - 2020-12-17
### Added
- Documentation `Troubleshouting` section (@brybalicious)
- Documentation `Update` section (@brybalicious)
- Documentation `Cloud Hosting Walkthrough` (@brybalicious)
- Support DNS name
- Sync annotations
- Sync volume objects
- Sync material node_goups
- Sync VSE
- Sync grease pencil modifiers
- Sync textures (modifier only)
- Session status widget
- Disconnection popup
- Popup with disconnection reason
### Changed
- Improved GPencil performances
### Fixed
- Texture paint update
- Various documentation fixes section (@brybalicious)
- Empty and Light object selection highlights
- Material renaming
- Default material nodes input parameters
- blender 2.91 python api compatibility
## [0.3.0] - 2021-04-14
### Added
- Curve material support
- Cycle visibility settings
- Session save/load operator
- Add new scene support
- Physic initial support
- Geometry node initial support
- Blender 2.93 compatibility
### Changed
- Host documentation on Gitlab Page
- Event driven update (from the blender deps graph)
### Fixed
- Vertex group assignation
- Parent relation can't be removed
- Separate object
- Delete animation
- Sync missing holdout option for grease pencil material
- Sync missing `skin_vertices`
- Exception access violation during Undo/Redo
- Sync missing armature bone Roll
- Sync missing driver data_path
- Constraint replication

132
README.md
View File

@ -1,108 +1,86 @@
# Multi-user blender addon
# MULTI-USER for blender
> Enable real-time collaborative workflow inside blender
<img src="https://i.imgur.com/X0B7O1Q.gif" width=600>
:warning: Under development, use it at your own risks. Currently tested on Windows platform. :warning:
This tool 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.
This tool 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 datablocks across the wire.
## Quick installation
## Installation
1. Download latest release [multi_user.zip](https://gitlab.com/slumber/multi-user/-/jobs/artifacts/master/download?job=build).
2. Run blender as administrator (dependencies installation).
3. Install last_version.zip from your addon preferences.
1. Download lastest release here.
2. Install last_version.zip from your addon preferences
[Dependencies](#dependencies) will be automatically added to your blender python during installation.
## Usage
Settings are under: `View3D -> Sidebar -> Multiuser`
See the [documentation](https://slumber.gitlab.io/multi-user/index.html) for details.
### Before starting
## Troubleshooting
#### 1. User
See the [troubleshooting guide](https://slumber.gitlab.io/multi-user/getting_started/troubleshooting.html) for tips on the most common issues.
_All user-related infos fields._
## Current development status
![settings](medias/user.png)
Currently, not all data-block are supported for replication over the wire. The following list summarizes the status for each ones.
- **name**: username.
- **color**: color used to represent the user into other user workspaces.
| Name | Status | Comment |
| -------------- | :----: | :----------------------------------------------------------: |
| action | ✔️ | |
| camera | ✔️ | |
| collection | ✔️ | |
| gpencil | ✔️ | |
| image | ✔️ | |
| mesh | ✔️ | |
| material | ✔️ | |
| node_groups | ✔️ | Material & Geometry only |
| geometry nodes | ✔️ | |
| metaball | ✔️ | |
| object | ✔️ | |
| texts | ✔️ | |
| scene | ✔️ | |
| world | ✔️ | |
| volumes | ✔️ | |
| lightprobes | ✔️ | |
| physics | ✔️ | |
| curve | ❗ | Nurbs surfaces not supported |
| textures | ❗ | Supported for modifiers/materials/geo nodes only |
| armature | ❗ | Not stable |
| particles | ❗ | The cache isn't syncing. |
| speakers | ❗ | [Partial](https://gitlab.com/slumber/multi-user/-/issues/65) |
| vse | ❗ | Mask and Clip not supported yet |
| libraries | ❗ | Partial |
| nla | ❌ | |
| texts | ❌ | [Planned](https://gitlab.com/slumber/multi-user/-/issues/81) |
| compositing | ❌ | [Planned](https://gitlab.com/slumber/multi-user/-/issues/46) |
#### 2. Network
_Session-related managment tools_
:warning: If you host a session over internet, special network configuration is needed :warning:
| Host | Join |
| :------------------------------------------- | :----------------------------- |
| asd |
| ![host_panel](medias/host.png) | ![join_panel](medias/join.png) |
| Start empty: Cleanup the file before hosting | IP: host ip |
| | Port: host port |
#### 2.1 Advanced
![properties](medias/properties.png)
**Right strategy** (only host) enable you to choose between a strict and a relaxed pattern:
- **Strict**: Host is the king, by default the host own each properties, only him can grant modification rights.
- **Common**: Each properties are under common rights by default, on selection, a property is only modifiable by the owner.
_On each strategy, when a user is the owner he can choose to pass his rights to somemone else._
**Propertie frequency gird** allow to set a custom replication frequency for each type of datablock
### In-session
#### Connected users
![users](medias/users.png)
This pannel displays all connected users, including you. The **camera button** allow you to focus on a user.
#### Properties outliner
![properties](medias/properties_in_session.png)
## Current development statut
Actually, not all datablock are supported for replication over the wire. The following list summarizes the status for each ones.
| Name | Statut | Comment |
| ---------- | :----------------: | :--------: |
| action | :x: | WIP |
| armature | :x: | WIP |
| camera | :white_check_mark: | |
| collection | :white_check_mark: | |
| curve | :white_check_mark: | Not tested |
| gpencil | :white_check_mark: | |
| image | :white_check_mark: | Local only |
| mesh | :white_check_mark: | |
| material | :white_check_mark: | |
| metaball | :x: | |
| object | :white_check_mark: | |
| scene | :white_check_mark: | |
| world | :white_check_mark: | |
### Performance issues
Since this addon is writen in pure python for a prototyping purpose, perfomance could be better from all perspective. Soon I will start to port the multi-user addon concept to a blender branch.
Since this addon is written in pure python for a research purpose, performances could be better from all perspective.
I'm working on it.
## Dependencies
| Dependencies | Version | Needed |
| ------------ | :-----: | -----: |
| ZeroMQ | latest | yes |
| msgpack | latest | yes |
| PyYAML | latest | yes |
| Replication | latest | yes |
## Contributing
1. Fork it (<https://gitlab.com/yourname/yourproject/fork>)
2. Create your feature branch (`git checkout -b feature/fooBar`)
3. Commit your changes (`git commit -am 'Add some fooBar'`)
4. Push to the branch (`git push origin feature/fooBar`)
5. Create a new Pull Request
See [contributing section](https://slumber.gitlab.io/multi-user/ways_to_contribute.html) of the documentation.
Feel free to [join the discord server](https://discord.gg/aBPvGws) to chat, seek help and contribute.
## Licensing
See [license](LICENSE)

View File

@ -1,287 +0,0 @@
bl_info = {
"name": "Multi-User",
"author": "CUBE CREATIVE",
"description": "",
"blender": (2, 80, 0),
"location": "",
"warning": "Unstable addon, use it at your own risks",
"category": "Collaboration"
}
import logging
import os
import random
import sys
import bpy
from bpy.app.handlers import persistent
from . import environment, utils, presence
from .libs.replication.replication.constants import RP_COMMON
# TODO: remove dependency as soon as replication will be installed as a module
DEPENDENCIES = {
("zmq","zmq"),
("msgpack","msgpack"),
("yaml","pyyaml"),
("jsondiff","jsondiff")
}
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)
#TODO: refactor config
# UTILITY FUNCTIONS
def generate_supported_types():
stype_dict = {'supported_types':{}}
for type in bl_types.types_to_register():
_type = getattr(bl_types, type)
props = {}
props['bl_delay_refresh']=_type.bl_delay_refresh
props['bl_delay_apply']=_type.bl_delay_apply
props['use_as_filter'] = False
props['icon'] = _type.bl_icon
props['auto_push']=_type.bl_automatic_push
props['bl_name']=_type.bl_id
stype_dict['supported_types'][_type.bl_rep_class.__name__] = props
return stype_dict
def client_list_callback(scene, context):
from . import operators
from .bl_types.bl_user import BlUser
items = [(RP_COMMON, RP_COMMON, "")]
username = bpy.context.window_manager.session.username
cli = operators.client
if cli:
client_keys = cli.list(filter=BlUser)
for k in client_keys:
name = cli.get(uuid=k).buffer["name"]
name_desc = name
if name == username:
name_desc += " (self)"
items.append((name, name_desc, ""))
return items
def randomColor():
r = random.random()
v = random.random()
b = random.random()
return [r, v, b]
class ReplicatedDatablock(bpy.types.PropertyGroup):
'''name = StringProperty() '''
type_name: bpy.props.StringProperty()
bl_name: bpy.props.StringProperty()
bl_delay_refresh: bpy.props.FloatProperty()
bl_delay_apply: bpy.props.FloatProperty()
use_as_filter: bpy.props.BoolProperty(default=True)
auto_push: bpy.props.BoolProperty(default=True)
icon: bpy.props.StringProperty()
class SessionProps(bpy.types.PropertyGroup):
username: bpy.props.StringProperty(
name="Username",
default="user_{}".format(utils.random_string_digits())
)
ip: bpy.props.StringProperty(
name="ip",
description='Distant host ip',
default="127.0.0.1"
)
user_uuid: bpy.props.StringProperty(
name="user_uuid",
default="None"
)
port: bpy.props.IntProperty(
name="port",
description='Distant host port',
default=5555
)
add_property_depth: bpy.props.IntProperty(
name="add_property_depth",
default=1
)
outliner_filter: bpy.props.StringProperty(name="None")
is_admin: bpy.props.BoolProperty(
name="is_admin",
default=False
)
init_scene: bpy.props.BoolProperty(
name="init_scene",
default=True
)
start_empty: bpy.props.BoolProperty(
name="start_empty",
default=True
)
active_object: bpy.props.PointerProperty(
name="active_object", type=bpy.types.Object)
session_mode: bpy.props.EnumProperty(
name='session_mode',
description='session mode',
items={
('HOST', 'hosting', 'host a session'),
('CONNECT', 'connexion', 'connect to a session')},
default='HOST')
right_strategy: bpy.props.EnumProperty(
name='right_strategy',
description='right strategy',
items={
('STRICT', 'strict', 'strict right repartition'),
('COMMON', 'common', 'relaxed right repartition')},
default='COMMON')
client_color: bpy.props.FloatVectorProperty(
name="client_instance_color",
subtype='COLOR',
default=randomColor())
clients: bpy.props.EnumProperty(
name="clients",
description="client enum",
items=client_list_callback)
enable_presence: bpy.props.BoolProperty(
name="Presence overlay",
description='Enable overlay drawing module',
default=True,
update=presence.update_presence
)
presence_show_selected: bpy.props.BoolProperty(
name="Show selected objects",
description='Enable selection overlay ',
default=True,
update=presence.update_overlay_settings
)
presence_show_user: bpy.props.BoolProperty(
name="Show users",
description='Enable user overlay ',
default=True,
update=presence.update_overlay_settings
)
supported_datablock: bpy.props.CollectionProperty(
type=ReplicatedDatablock,
)
session_filter: bpy.props.CollectionProperty(
type=ReplicatedDatablock,
)
filter_owned: bpy.props.BoolProperty(
name="filter_owned",
description='Show only owned datablocks',
default=True
)
use_select_right: bpy.props.BoolProperty(
name="Selection right",
description='Change right on selection',
default=True
)
def load(self):
config = environment.load_config()
if "username" in config.keys():
self.username = config["username"]
self.ip = config["ip"]
self.port = config["port"]
self.start_empty = config["start_empty"]
self.enable_presence = config["enable_presence"]
self.client_color = config["client_color"]
else:
logger.error("Fail to read user config")
if len(self.supported_datablock)>0:
self.supported_datablock.clear()
if "supported_types" not in config:
config = generate_supported_types()
for datablock in config["supported_types"].keys():
rep_value = self.supported_datablock.add()
rep_value.name = datablock
rep_value.type_name = datablock
config_block = config["supported_types"][datablock]
rep_value.bl_delay_refresh = config_block['bl_delay_refresh']
rep_value.bl_delay_apply = config_block['bl_delay_apply']
rep_value.icon = config_block['icon']
rep_value.auto_push = config_block['auto_push']
rep_value.bl_name = config_block['bl_name']
def save(self,context):
config = environment.load_config()
config["username"] = self.username
config["ip"] = self.ip
config["port"] = self.port
config["start_empty"] = self.start_empty
config["enable_presence"] = self.enable_presence
config["client_color"] = [self.client_color.r,self.client_color.g,self.client_color.b]
for bloc in self.supported_datablock:
config_block = config["supported_types"][bloc.type_name]
config_block['bl_delay_refresh'] = bloc.bl_delay_refresh
config_block['bl_delay_apply'] = bloc.bl_delay_apply
config_block['use_as_filter'] = bloc.use_as_filter
config_block['icon'] = bloc.icon
config_block['auto_push'] = bloc.auto_push
config_block['bl_name'] = bloc.bl_name
environment.save_config(config)
classes = (
ReplicatedDatablock,
SessionProps,
)
libs = os.path.dirname(os.path.abspath(__file__))+"\\libs\\replication"
@persistent
def load_handler(dummy):
import bpy
bpy.context.window_manager.session.load()
def register():
if libs not in sys.path:
sys.path.append(libs)
environment.setup(DEPENDENCIES,bpy.app.binary_path_python)
from . import presence
from . import operators
from . import ui
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.WindowManager.session = bpy.props.PointerProperty(
type=SessionProps)
bpy.types.ID.uuid = bpy.props.StringProperty(default="")
bpy.context.window_manager.session.load()
presence.register()
operators.register()
ui.register()
bpy.app.handlers.load_post.append(load_handler)
def unregister():
from . import presence
from . import operators
from . import ui
presence.unregister()
ui.unregister()
operators.unregister()
del bpy.types.WindowManager.session
for cls in reversed(classes):
bpy.utils.unregister_class(cls)

View File

@ -1,25 +0,0 @@
__all__ = [
'bl_user',
'bl_object',
'bl_mesh',
'bl_camera',
'bl_collection',
'bl_curve',
'bl_gpencil',
'bl_image',
'bl_light',
'bl_scene',
'bl_material',
'bl_library',
'bl_armature',
'bl_action',
'bl_world',
'bl_metaball'
] # Order here defines execution order
from . import *
from ..libs.replication.replication.data import ReplicatedDataFactory
def types_to_register():
return __all__

View File

@ -1,69 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
# WIP
class BlAction(BlDatablock):
def load(self, data, target):
utils.dump_anything.load(target, data)
def construct(self, data):
return bpy.data.actions.new(data["name"])
def load(self, data, target):
pass
# # find target object
# object_ = bpy.context.scene.objects.active
# if object_ is None:
# raise RuntimeError("Nothing is selected.")
# if object_.mode != 'POSE': # object must be in pose mode
# raise RuntimeError("Object must be in pose mode.")
# if object_.animation_data.action is None:
# raise RuntimeError("Object needs an active action.")
def dump(self, pointer=None):
assert(pointer)
data = utils.dump_datablock(pointer, 1)
dumper = utils.dump_anything.Dumper()
dumper.depth = 2
data["fcurves"] = []
for fcurve in self.pointer.fcurves:
fc = {
"data_path": fcurve.data_path,
"dumped_array_index": fcurve.array_index,
"keyframe_points": []
}
for k in fcurve.keyframe_points:
fc["keyframe_points"].append(
dumper.dump(k)
)
data["fcurves"].append(fc)
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.actions.get(self.buffer['name'])
def diff(self):
return False
def is_valid(self):
return bpy.data.actions.get(self.buffer['name'])
bl_id = "actions"
bl_class = bpy.types.Action
bl_rep_class = BlAction
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True
bl_icon = 'ACTION_TWEAK'

View File

@ -1,107 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from ..libs.overrider import Overrider
from .. import utils
from .. import presence
from .bl_datablock import BlDatablock
# WIP
class BlArmature(BlDatablock):
def construct(self, data):
return bpy.data.armatures.new(data["name"])
def load(self, data, target):
# Load parent object
if data['user'] not in bpy.data.objects.keys():
parent_object = bpy.data.objects.new(data['user'], self.pointer)
else:
parent_object = bpy.data.objects[data['user']]
is_object_in_master = (data['user_collection'][0] == "Master Collection")
#TODO: recursive parent collection loading
# Link parent object to the collection
if is_object_in_master:
parent_collection = bpy.data.scenes[data['user_scene'][0]].collection
elif data['user_collection'][0] not in bpy.data.collections.keys():
parent_collection = bpy.data.collections.new(data['user_collection'][0])
else:
parent_collection = bpy.data.collections[data['user_collection'][0]]
if parent_object.name not in parent_collection.objects:
parent_collection.objects.link(parent_object)
# Link parent collection to the scene master collection
if not is_object_in_master and parent_collection.name not in bpy.data.scenes[data['user_scene'][0]].collection.children:
bpy.data.scenes[data['user_scene'][0]].collection. children.link(parent_collection)
# utils.dump_anything.load(target, data)
# with Overrider(name="bpy_",parent=bpy.context) as bpy_:
area, region, rv3d = presence.view3d_find()
bpy.context.view_layer.objects.active = parent_object
# override = bpy.context.copy()
# override['window'] = bpy.data.window_managers[0].windows[0]
# override['mode'] = 'EDIT_ARMATURE'
# override['window_manager'] = bpy.data.window_managers[0]
# override['area'] = area
# override['region'] = region
# override['screen'] = bpy.data.window_managers[0].windows[0].screen
bpy.ops.object.mode_set(mode='EDIT')
for bone in data['bones']:
if bone not in self.pointer.edit_bones:
new_bone = self.pointer.edit_bones.new(bone)
else:
new_bone = self.pointer.edit_bones[bone]
new_bone.tail = data['bones'][bone]['tail_local']
new_bone.head = data['bones'][bone]['head_local']
new_bone.tail_radius = data['bones'][bone]['tail_radius']
new_bone.head_radius = data['bones'][bone]['head_radius']
if 'parent' in data['bones'][bone]:
new_bone.parent = self.pointer.edit_bones[data['bones'][bone]['parent']['name']]
new_bone.use_connect = data['bones'][bone]['use_connect']
bpy.ops.object.mode_set(mode='OBJECT')
# bpy_.mode = 'EDIT_ARMATURE'
# bpy_.active_object = armature
# bpy_.selected_objects = [armature]
def dump(self, pointer=None):
assert(pointer)
data = utils.dump_datablock(pointer, 4)
#get the parent Object
object_users = utils.get_datablock_users(pointer)[0]
data['user'] = object_users.name
#get parent collection
container_users = utils.get_datablock_users(object_users)
data['user_collection'] = [item.name for item in container_users if isinstance(item,bpy.types.Collection)]
data['user_scene'] = [item.name for item in container_users if isinstance(item,bpy.types.Scene)]
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.armatures.get(self.buffer['name'])
def diff(self):
False
def is_valid(self):
return bpy.data.armatures.get(self.buffer['name'])
bl_id = "armatures"
bl_class = bpy.types.Armature
bl_rep_class = BlArmature
bl_delay_refresh = 1
bl_delay_apply = 0
bl_automatic_push = True
bl_icon = 'ARMATURE_DATA'

View File

@ -1,68 +0,0 @@
from jsondiff import diff
import bpy
import mathutils
from .. import utils
from .bl_datablock import BlDatablock
class BlCamera(BlDatablock):
def load(self, data, target):
utils.dump_anything.load(target, data)
dof_settings = data.get('dof')
# DOF settings
if dof_settings:
utils.dump_anything.load(target.dof, dof_settings)
def construct(self, data):
return bpy.data.cameras.new(data["name"])
def dump(self, pointer=None):
assert(pointer)
dumper = utils.dump_anything.Dumper()
dumper.depth = 2
dumper.include_filter = [
"name",
'type',
'lens',
'lens_unit',
'shift_x',
'shift_y',
'clip_start',
'clip_end',
'dof',
'use_dof',
'sensor_fit',
'sensor_width',
'focus_object',
'focus_distance',
'aperture_fstop',
'aperture_blades',
'aperture_rotation',
'aperture_ratio',
]
return dumper.dump(pointer)
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.cameras.get(self.buffer['name'])
def diff(self):
return (self.bl_diff() or
len(diff(self.dump(pointer=self.pointer), self.buffer)))
def is_valid(self):
return bpy.data.cameras.get(self.buffer['name'])
bl_id = "cameras"
bl_class = bpy.types.Camera
bl_rep_class = BlCamera
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True
bl_icon = 'CAMERA_DATA'

View File

@ -1,71 +0,0 @@
import bpy
import mathutils
from .. import utils
from .bl_datablock import BlDatablock
class BlCollection(BlDatablock):
def construct(self,data):
return bpy.data.collections.new(data["name"])
def load(self, data, target):
# Load other meshes metadata
# dump_anything.load(target, data)
# link objects
for object in data["objects"]:
if object not in target.objects.keys():
target.objects.link(bpy.data.objects[object])
for object in target.objects.keys():
if object not in data["objects"]:
target.objects.unlink(bpy.data.objects[object])
# Link childrens
for collection in data["children"]:
if collection not in target.children.keys():
# if bpy.data.collections.find(collection) == -1:
target.children.link(
bpy.data.collections[collection])
for collection in target.children.keys():
if collection not in data["children"]:
target.collection.children.unlink(
bpy.data.collections[collection])
utils.dump_anything.load(target, data)
def dump(self, pointer=None):
assert(pointer)
return utils.dump_datablock(pointer, 4)
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.collections.get(self.buffer['name'])
def diff(self):
return (self.bl_diff() or
len(self.pointer.objects) != len(self.buffer['objects']) or
len(self.pointer.children) != len(self.buffer['children']))
def resolve_dependencies(self):
deps = []
for child in self.pointer.children:
deps.append(child)
for object in self.pointer.objects:
deps.append(object)
return deps
def is_valid(self):
return bpy.data.collections.get(self.buffer['name'])
bl_id = "collections"
bl_icon = 'FILE_FOLDER'
bl_class = bpy.types.Collection
bl_rep_class = BlCollection
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True

View File

@ -1,65 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
class BlCurve(BlDatablock):
def construct(self, data):
return bpy.data.curves.new(data["name"], 'CURVE')
def load(self, data, target):
utils.dump_anything.load(target, data)
target.splines.clear()
# load splines
for spline in data['splines']:
new_spline = target.splines.new(data['splines'][spline]['type'])
utils.dump_anything.load(new_spline, data['splines'][spline])
# Load curve geometry data
for bezier_point_index in data['splines'][spline]["bezier_points"]:
if bezier_point_index != 0:
new_spline.bezier_points.add(1)
utils.dump_anything.load(
new_spline.bezier_points[bezier_point_index], data['splines'][spline]["bezier_points"][bezier_point_index])
for point_index in data['splines'][spline]["points"]:
new_spline.points.add(1)
utils.dump_anything.load(
new_spline.points[point_index], data['splines'][spline]["points"][point_index])
def dump(self, pointer=None):
assert(pointer)
data = utils.dump_datablock(pointer, 1)
data['splines'] = {}
dumper = utils.dump_anything.Dumper()
dumper.depth = 3
for index,spline in enumerate(pointer.splines):
spline_data = {}
spline_data['points'] = dumper.dump(spline.points)
spline_data['bezier_points'] = dumper.dump(spline.bezier_points)
spline_data['type'] = dumper.dump(spline.type)
data['splines'][index] = spline_data
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.curves.get(self.buffer['name'])
def diff(self):
return (self.bl_diff() or
len(diff(self.dump(pointer=self.pointer), self.buffer)) > 1)
def is_valid(self):
return bpy.data.curves.get(self.buffer['name'])
bl_id = "curves"
bl_class = bpy.types.Curve
bl_rep_class = BlCurve
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True
bl_icon = 'CURVE_DATA'

View File

@ -1,62 +0,0 @@
import bpy
import mathutils
from .. import utils
from ..libs.replication.replication.data import ReplicatedDatablock
from ..libs.replication.replication.constants import UP
class BlDatablock(ReplicatedDatablock):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
pointer = kwargs.get('pointer', None)
buffer = self.buffer
# TODO: use is_library_indirect
self.is_library = (pointer and hasattr(pointer, 'library') and
pointer.library) or \
(buffer and 'library' in buffer)
if self.is_library:
self.load = self.load_library
self.dump = self.dump_library
self.diff = self.diff_library
if self.pointer and hasattr(self.pointer, 'uuid'):
self.pointer.uuid = self.uuid
def library_apply(self):
"""Apply stored data
"""
# UP in case we want to reset our pointer data
self.state = UP
def bl_diff(self):
"""Generic datablock diff"""
return self.pointer.name != self.buffer['name']
def construct_library(self, data):
return None
def load_library(self, data, target):
pass
def dump_library(self, pointer=None):
return utils.dump_datablock(pointer, 1)
def diff_library(self):
return False
def resolve_dependencies_library(self):
return [self.pointer.library]
def resolve_dependencies(self):
dependencies = []
if hasattr(self.pointer,'animation_data') and self.pointer.animation_data:
dependencies.append(self.pointer.animation_data.action)
return dependencies
def is_valid(self):
raise NotImplementedError

View File

@ -1,91 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
def load_gpencil_layer(target=None, data=None, create=False):
utils.dump_anything.load(target, data)
for frame in data["frames"]:
try:
tframe = target.frames[frame]
except:
tframe = target.frames.new(frame)
utils.dump_anything.load(tframe, data["frames"][frame])
for stroke in data["frames"][frame]["strokes"]:
try:
tstroke = tframe.strokes[stroke]
except:
tstroke = tframe.strokes.new()
utils.dump_anything.load(
tstroke, data["frames"][frame]["strokes"][stroke])
for point in data["frames"][frame]["strokes"][stroke]["points"]:
p = data["frames"][frame]["strokes"][stroke]["points"][point]
tstroke.points.add(1)
tpoint = tstroke.points[len(tstroke.points)-1]
utils.dump_anything.load(tpoint, p)
class BlGpencil(BlDatablock):
def construct(self, data):
return bpy.data.grease_pencils.new(data["name"])
def load(self, data, target):
for layer in target.layers:
target.layers.remove(layer)
if "layers" in data.keys():
for layer in data["layers"]:
if layer not in target.layers.keys():
gp_layer = target.layers.new(data["layers"][layer]["info"])
else:
gp_layer = target.layers[layer]
load_gpencil_layer(
target=gp_layer, data=data["layers"][layer], create=True)
utils.dump_anything.load(target, data)
target.materials.clear()
if "materials" in data.keys():
for mat in data['materials']:
target.materials.append(bpy.data.materials[mat])
def diff(self):
return (self.bl_diff())
def dump(self, pointer=None):
assert(pointer)
data = utils.dump_datablock(pointer, 2)
utils.dump_datablock_attibutes(
pointer, ['layers'], 9, data)
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.grease_pencils.get(self.buffer['name'])
def resolve_dependencies(self):
deps = []
for material in self.pointer.materials:
deps.append(material)
return deps
def is_valid(self):
return bpy.data.grease_pencils.get(self.buffer['name'])
bl_id = "grease_pencils"
bl_class = bpy.types.GreasePencil
bl_rep_class = BlGpencil
bl_delay_refresh = 5
bl_delay_apply = 5
bl_automatic_push = True
bl_icon = 'GREASEPENCIL'

View File

@ -1,76 +0,0 @@
import bpy
import mathutils
import os
from .. import utils, environment
from .bl_datablock import BlDatablock
def dump_image(image):
pixels = None
if image.source == "GENERATED":
img_name = "{}.png".format(image.name)
image.filepath_raw = os.path.join(environment.CACHE_DIR, img_name)
image.file_format = "PNG"
image.save()
if image.source == "FILE":
image.save()
file = open(image.filepath_raw, "rb")
pixels = file.read()
file.close()
else:
raise ValueError()
return pixels
class BlImage(BlDatablock):
def construct(self, data):
return bpy.data.images.new(
name=data['name'],
width=data['size'][0],
height=data['size'][1]
)
def load(self, data, target):
image = target
img_name = "{}.png".format(image.name)
img_path = os.path.join(environment.CACHE_DIR, img_name)
file = open(img_path, 'wb')
file.write(data["pixels"])
file.close()
image.source = 'FILE'
image.filepath = img_path
def dump(self, pointer=None):
assert(pointer)
data = {}
data['pixels'] = dump_image(pointer)
utils.dump_datablock_attibutes(pointer, [], 2, data)
data = utils.dump_datablock_attibutes(
pointer,
["name", 'size', 'height', 'alpha', 'float_buffer', 'filepath', 'source'],
2,
data)
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.images.get(self.buffer['name'])
def diff(self):
return False
def is_valid(self):
return bpy.data.images.get(self.buffer['name'])
bl_id = "images"
bl_class = bpy.types.Image
bl_rep_class = BlImage
bl_delay_refresh = 0
bl_delay_apply = 0
bl_automatic_push = False
bl_icon = 'IMAGE_DATA'

View File

@ -1,37 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
class BlLibrary(BlDatablock):
def construct(self, data):
with bpy.data.libraries.load(filepath=data["filepath"], link=True) as (sourceData, targetData):
targetData = sourceData
return sourceData
def load(self, data, target):
pass
def dump(self, pointer=None):
assert(pointer)
return utils.dump_datablock(pointer, 1)
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.libraries.get(self.buffer['name'])
def diff(self):
return (self.bl_diff())
def is_valid(self):
return bpy.data.libraries.get(self.buffer['name'])
bl_id = "libraries"
bl_class = bpy.types.Library
bl_rep_class = BlLibrary
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True
bl_icon = 'LIBRARY_DATA_DIRECT'

View File

@ -1,60 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
class BlLight(BlDatablock):
def construct(self, data):
return bpy.data.lights.new(data["name"], data["type"])
def load(self, data, target):
utils.dump_anything.load(target, data)
def dump(self, pointer=None):
assert(pointer)
dumper = utils.dump_anything.Dumper()
dumper.depth = 3
dumper.include_filter = [
"name",
"type",
"color",
"energy",
"specular_factor",
"uuid",
"shadow_soft_size",
"use_custom_distance",
"cutoff_distance",
"use_shadow",
"shadow_buffer_clip_start",
"shadow_buffer_soft",
"shadow_buffer_bias",
"shadow_buffer_bleed_bias",
"contact_shadow_distance",
"contact_shadow_soft_size",
"contact_shadow_bias",
"contact_shadow_thickness"
]
data = dumper.dump(pointer)
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.lights.get(self.buffer['name'])
def diff(self):
return (self.bl_diff() or
len(diff(self.dump(pointer=self.pointer), self.buffer)) > 1)
def is_valid(self):
return bpy.data.lights.get(self.buffer['name'])
bl_id = "lights"
bl_class = bpy.types.Light
bl_rep_class = BlLight
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True
bl_icon = 'LIGHT_DATA'

View File

@ -1,158 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
def load_node(target_node_tree, source):
target_node = target_node_tree.nodes.get(source["name"])
if target_node is None:
node_type = source["bl_idname"]
target_node = target_node_tree.nodes.new(type=node_type)
utils.dump_anything.load(
target_node, source)
if source['type'] == 'TEX_IMAGE':
target_node.image = bpy.data.images[source['image']['name']]
for input in source["inputs"]:
if hasattr(target_node.inputs[input], "default_value"):
target_node.inputs[input].default_value = source["inputs"][input]["default_value"]
def load_link(target_node_tree, source):
input_socket = target_node_tree.nodes[source['to_node']
['name']].inputs[source['to_socket']['name']]
output_socket = target_node_tree.nodes[source['from_node']
['name']].outputs[source['from_socket']['name']]
target_node_tree.links.new(input_socket, output_socket)
class BlMaterial(BlDatablock):
def construct(self, data):
return bpy.data.materials.new(data["name"])
def load(self, data, target):
if data['is_grease_pencil']:
if not target.is_grease_pencil:
bpy.data.materials.create_gpencil_data(target)
utils.dump_anything.load(
target.grease_pencil, data['grease_pencil'])
utils.load_dict(data['grease_pencil'], target.grease_pencil)
elif data["use_nodes"]:
if target.node_tree is None:
target.use_nodes = True
target.node_tree.nodes.clear()
# Load nodes
for node in data["node_tree"]["nodes"]:
load_node(target.node_tree, data["node_tree"]["nodes"][node])
# Load nodes links
target.node_tree.links.clear()
for link in data["node_tree"]["links"]:
load_link(target.node_tree, data["node_tree"]["links"][link])
def dump(self, pointer=None):
assert(pointer)
mat_dumper = utils.dump_anything.Dumper()
mat_dumper.depth = 2
mat_dumper.exclude_filter = [
"preview",
"original",
"uuid",
"users",
"alpha_threshold",
"line_color",
"view_center",
]
node_dumper = utils.dump_anything.Dumper()
node_dumper.depth = 1
node_dumper.exclude_filter = [
"dimensions",
"select",
"bl_height_min",
"bl_height_max",
"bl_width_min",
"bl_width_max",
"bl_width_default",
"hide",
"show_options",
"show_tetxures",
"show_preview",
"outputs",
"width_hidden"
]
input_dumper = utils.dump_anything.Dumper()
input_dumper.depth = 2
input_dumper.include_filter = ["default_value"]
links_dumper = utils.dump_anything.Dumper()
links_dumper.depth = 3
links_dumper.exclude_filter = ["dimensions"]
data = mat_dumper.dump(pointer)
if pointer.use_nodes:
nodes = {}
for node in pointer.node_tree.nodes:
nodes[node.name] = node_dumper.dump(node)
if hasattr(node, 'inputs'):
nodes[node.name]['inputs'] = {}
for i in node.inputs:
if hasattr(i, 'default_value'):
nodes[node.name]['inputs'][i.name] = input_dumper.dump(
i)
data["node_tree"]['nodes'] = nodes
data["node_tree"]["links"] = links_dumper.dump(pointer.node_tree.links)
elif pointer.is_grease_pencil:
utils.dump_datablock_attibutes(pointer, ["grease_pencil"], 3, data)
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.materials.get(self.buffer['name'])
def diff(self):
diff_rev = diff(self.dump(pointer=self.pointer), self.buffer)
return (self.bl_diff() or
len(diff_rev.keys()) > 0)
def resolve_dependencies(self):
# TODO: resolve node group deps
deps = []
if self.pointer.use_nodes:
for node in self.pointer.node_tree.nodes:
if node.type == 'TEX_IMAGE':
deps.append(node.image)
if self.is_library:
deps.append(self.pointer.library)
return deps
def is_valid(self):
return bpy.data.materials.get(self.buffer['name'])
bl_id = "materials"
bl_class = bpy.types.Material
bl_rep_class = BlMaterial
bl_delay_refresh = 10
bl_delay_apply = 10
bl_automatic_push = True
bl_icon = 'MATERIAL_DATA'

View File

@ -1,181 +0,0 @@
import bpy
import bmesh
import mathutils
from .. import utils
from .bl_datablock import BlDatablock
def dump_mesh(mesh, data={}):
import bmesh
mesh_data = data
mesh_buffer = bmesh.new()
mesh_buffer.from_mesh(mesh)
uv_layer = mesh_buffer.loops.layers.uv.verify()
bevel_layer = mesh_buffer.verts.layers.bevel_weight.verify()
skin_layer = mesh_buffer.verts.layers.skin.verify()
verts = {}
for vert in mesh_buffer.verts:
v = {}
v["co"] = list(vert.co)
# vert metadata
v['bevel'] = vert[bevel_layer]
v['normal'] = list(vert.normal)
# v['skin'] = list(vert[skin_layer])
verts[str(vert.index)] = v
mesh_data["verts"] = verts
edges = {}
for edge in mesh_buffer.edges:
e = {}
e["verts"] = [edge.verts[0].index, edge.verts[1].index]
# Edge metadata
e["smooth"] = edge.smooth
edges[edge.index] = e
mesh_data["edges"] = edges
faces = {}
for face in mesh_buffer.faces:
f = {}
fverts = []
for vert in face.verts:
fverts.append(vert.index)
f["verts"] = fverts
f["material_index"] = face.material_index
f["smooth"] = face.smooth
f["normal"] = list(face.normal)
f["index"] = face.index
uvs = []
# Face metadata
for loop in face.loops:
loop_uv = loop[uv_layer]
uvs.append(list(loop_uv.uv))
f["uv"] = uvs
faces[face.index] = f
mesh_data["faces"] = faces
uv_layers = []
for uv_layer in mesh.uv_layers:
uv_layers.append(uv_layer.name)
mesh_data["uv_layers"] = uv_layers
return mesh_data
class BlMesh(BlDatablock):
def construct(self, data):
return bpy.data.meshes.new(data["name"])
def load(self, data, target):
if not target or not target.is_editmode:
# 1 - LOAD MATERIAL SLOTS
material_to_load = []
material_to_load = utils.revers(data["materials"])
target.materials.clear()
# SLots
i = 0
for m in data["material_list"]:
target.materials.append(bpy.data.materials[m])
# 2 - LOAD GEOMETRY
mesh_buffer = bmesh.new()
for i in data["verts"]:
v = mesh_buffer.verts.new(data["verts"][i]["co"])
v.normal = data["verts"][i]["normal"]
mesh_buffer.verts.ensure_lookup_table()
for i in data["edges"]:
verts = mesh_buffer.verts
v1 = data["edges"][i]["verts"][0]
v2 = data["edges"][i]["verts"][1]
edge = mesh_buffer.edges.new([verts[v1], verts[v2]])
edge.smooth = data["edges"][i]["smooth"]
for p in data["faces"]:
verts = []
for v in data["faces"][p]["verts"]:
verts.append(mesh_buffer.verts[v])
if len(verts) > 0:
f = mesh_buffer.faces.new(verts)
uv_layer = mesh_buffer.loops.layers.uv.verify()
f.smooth = data["faces"][p]["smooth"]
f.normal = data["faces"][p]["normal"]
f.index = data["faces"][p]["index"]
f.material_index = data["faces"][p]['material_index']
# UV loading
for i, loop in enumerate(f.loops):
loop_uv = loop[uv_layer]
loop_uv.uv = data["faces"][p]["uv"][i]
mesh_buffer.faces.ensure_lookup_table()
mesh_buffer.to_mesh(target)
# 3 - LOAD METADATA
# uv's
for uv_layer in data['uv_layers']:
target.uv_layers.new(name=uv_layer)
bevel_layer = mesh_buffer.verts.layers.bevel_weight.verify()
skin_layer = mesh_buffer.verts.layers.skin.verify()
utils.dump_anything.load(target, data)
def dump(self, pointer=None):
assert(pointer)
data = utils.dump_datablock(pointer, 2)
data = dump_mesh(pointer, data)
# Fix material index
m_list = []
for material in pointer.materials:
if material:
m_list.append(material.name)
data['material_list'] = m_list
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.meshes.get(self.buffer['name'])
def diff(self):
return (self.bl_diff() or
len(self.pointer.vertices) != len(self.buffer['verts']) or
len(self.pointer.materials) != len(self.buffer['materials']))
def resolve_dependencies(self):
deps = []
for material in self.pointer.materials:
deps.append(material)
return deps
def is_valid(self):
return bpy.data.meshes.get(self.buffer['name'])
bl_id = "meshes"
bl_class = bpy.types.Mesh
bl_rep_class = BlMesh
bl_delay_refresh = 10
bl_delay_apply = 10
bl_automatic_push = True
bl_icon = 'MESH_DATA'

View File

@ -1,48 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
class BlMetaball(BlDatablock):
def construct(self, data):
return bpy.data.metaballs.new(data["name"])
def load(self, data, target):
utils.dump_anything.load(target, data)
target.elements.clear()
for element in data["elements"]:
new_element = target.elements.new(type=data["elements"][element]['type'])
utils.dump_anything.load(new_element, data["elements"][element])
def dump(self, pointer=None):
assert(pointer)
dumper = utils.dump_anything.Dumper()
dumper.depth = 3
dumper.exclude_filter = ["is_editmode"]
data = dumper.dump(pointer)
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.metaballs.get(self.buffer['name'])
def diff(self):
rev = diff(self.dump(pointer=self.pointer), self.buffer)
return (self.bl_diff() or
len(rev) > 0)
def is_valid(self):
return bpy.data.metaballs.get(self.buffer['name'])
bl_id = "metaballs"
bl_class = bpy.types.MetaBall
bl_rep_class = BlMetaball
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True
bl_icon = 'META_BALL'

View File

@ -1,135 +0,0 @@
import bpy
import mathutils
from .. import utils
from .bl_datablock import BlDatablock
from jsondiff import diff
class BlObject(BlDatablock):
def construct(self, data):
pointer = None
if self.is_library:
with bpy.data.libraries.load(filepath=bpy.data.libraries[self.buffer['library']].filepath, link=True) as (sourceData, targetData):
targetData.objects = [
name for name in sourceData.objects if name == self.buffer['name']]
return targetData.objects[self.buffer['name']]
# Object specific constructor...
if "data" not in data:
pass
elif data["data"] in bpy.data.meshes.keys():
pointer = bpy.data.meshes[data["data"]]
elif data["data"] in bpy.data.lights.keys():
pointer = bpy.data.lights[data["data"]]
elif data["data"] in bpy.data.cameras.keys():
pointer = bpy.data.cameras[data["data"]]
elif data["data"] in bpy.data.curves.keys():
pointer = bpy.data.curves[data["data"]]
elif data["data"] in bpy.data.metaballs.keys():
pointer = bpy.data.metaballs[data["data"]]
elif data["data"] in bpy.data.armatures.keys():
pointer = bpy.data.armatures[data["data"]]
elif data["data"] in bpy.data.grease_pencils.keys():
pointer = bpy.data.grease_pencils[data["data"]]
elif data["data"] in bpy.data.curves.keys():
pointer = bpy.data.curves[data["data"]]
return bpy.data.objects.new(data["name"], pointer)
def load(self, data, target):
target.uuid = data['uuid']
target.matrix_world = mathutils.Matrix(data["matrix_world"])
# Load modifiers
if hasattr(target, 'modifiers'):
for local_modifier in target.modifiers:
if local_modifier.name not in data['modifiers']:
target.modifiers.remove(local_modifier)
for modifier in data['modifiers']:
target_modifier = target.modifiers.get(modifier)
if not target_modifier:
target_modifier = target.modifiers.new(
data['modifiers'][modifier]['name'], data['modifiers'][modifier]['type'])
utils.dump_anything.load(
target_modifier, data['modifiers'][modifier])
if 'children' in data.keys():
for child in data['children']:
bpy.data.objects[child].parent = self.pointer
def dump(self, pointer=None):
assert(pointer)
dumper = utils.dump_anything.Dumper()
dumper.depth = 1
dumper.include_filter = [
"name",
"matrix_world",
"rotation_mode",
"parent",
"data",
"uuid",
"children",
"library"
]
data = dumper.dump(pointer)
if self.is_library:
return data
if hasattr(pointer, 'modifiers'):
dumper.include_filter = None
dumper.depth = 3
data["modifiers"] = dumper.dump(pointer.modifiers)
if len(pointer.children) > 0:
childs = []
for child in pointer.children:
childs.append(child.name)
data["children"] = childs
# deps.extend(list(self.pointer.children))
return data
def resolve(self):
assert(self.buffer)
object_name = self.buffer['name']
try:
self.pointer = bpy.data.objects[object_name]
except:
pass
def diff(self):
diff_rev = diff(self.dump(pointer=self.pointer), self.buffer)
return (self.bl_diff() or
len(diff_rev.keys()))
def resolve_dependencies(self):
deps = super().resolve_dependencies()
# Avoid Empty case
if self.pointer.data:
deps.append(self.pointer.data)
if len(self.pointer.children) > 0:
deps.extend(list(self.pointer.children))
if self.is_library:
deps.append(self.pointer.library)
return deps
def is_valid(self):
return bpy.data.objects.get(self.buffer['name'])
bl_id = "objects"
bl_class = bpy.types.Object
bl_rep_class = BlObject
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True
bl_icon = 'OBJECT_DATA'

View File

@ -1,92 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
class BlScene(BlDatablock):
def construct(self, data):
return bpy.data.scenes.new(data["name"])
def load(self, data, target):
target = self.pointer
# Load other meshes metadata
utils.dump_anything.load(target, data)
# Load master collection
for object in data["collection"]["objects"]:
if object not in target.collection.objects.keys():
target.collection.objects.link(bpy.data.objects[object])
for object in target.collection.objects.keys():
if object not in data["collection"]["objects"]:
target.collection.objects.unlink(bpy.data.objects[object])
# load collections
for collection in data["collection"]["children"]:
if collection not in target.collection.children.keys():
target.collection.children.link(
bpy.data.collections[collection])
for collection in target.collection.children.keys():
if collection not in data["collection"]["children"]:
target.collection.children.unlink(
bpy.data.collections[collection])
if 'world' in data.keys():
target.world = bpy.data.worlds[data['world']]
def dump(self, pointer=None):
assert(pointer)
data = {}
scene_dumper = utils.dump_anything.Dumper()
scene_dumper.depth = 1
scene_dumper.include_filter = ['name','world', 'id', 'camera', 'grease_pencil']
data = scene_dumper.dump(pointer)
scene_dumper.depth = 3
scene_dumper.include_filter = ['children','objects','name']
data['collection'] = scene_dumper.dump(pointer.collection)
return data
def resolve(self):
assert(self.buffer)
scene_name = self.buffer['name']
self.pointer = bpy.data.scenes.get(scene_name)
def diff(self):
return (self.bl_diff() or
len(self.pointer.collection.objects) != len(self.buffer['collection']['objects']) or
len(self.pointer.collection.children) != len(self.buffer['collection']['children']))
def resolve_dependencies(self):
deps = []
# child collections
for child in self.pointer.collection.children:
deps.append(child)
# childs objects
for object in self.pointer.objects:
deps.append(object)
# world
if self.pointer.world:
deps.append(self.pointer.world)
return deps
def is_valid(self):
return bpy.data.scenes.get(self.buffer['name'])
bl_id = "scenes"
bl_class = bpy.types.Scene
bl_rep_class = BlScene
bl_delay_refresh = 1
bl_delay_apply = 1
bl_automatic_push = True
bl_icon = 'SCENE_DATA'

View File

@ -1,66 +0,0 @@
import bpy
import mathutils
from .. import utils
from .. import presence
from .bl_datablock import BlDatablock
from ..libs.replication.replication.constants import UP
class BlUser(BlDatablock):
def construct(self, name):
return presence.User()
def load(self, data, target):
target.name = data['name']
target.location = data['location']
target.selected_objects = data['selected_objects']
utils.dump_anything.load(target, data)
def apply(self):
if self.pointer is None:
self.pointer = self.construct(self.buffer)
if self.pointer:
self.load(data=self.buffer, target=self.pointer)
settings = bpy.context.window_manager.session
self.state = UP
#TODO: refactor in order to redraw in cleaner ways
area, region, rv3d = presence.view3d_find()
if presence.renderer and area and region and rv3d and settings.enable_presence:
if settings.presence_show_user:
presence.renderer.draw_client_camera(self.buffer['name'], self.buffer['location'],self.buffer['color'])
if settings.presence_show_selected:
presence.renderer.draw_client_selection(self.buffer['name'], self.buffer['color'],self.buffer['selected_objects'])
presence.refresh_3d_view()
def dump(self,pointer=None):
data = utils.dump_anything.dump(pointer)
data['location'] = pointer.location
data['color'] = pointer.color
data['selected_objects'] = pointer.selected_objects
return data
def diff(self):
if not self.pointer:
return False
if self.pointer.is_dirty:
self.pointer.is_dirty = False
return True
for i,coord in enumerate(self.pointer.location):
if coord != self.buffer['location'][i]:
return True
return False
def is_valid(self):
return True
bl_id = "users"
bl_class = presence.User
bl_rep_class = BlUser
bl_delay_refresh = .2
bl_delay_apply = .2
bl_automatic_push = True
bl_icon = 'CON_ARMATURE'

View File

@ -1,114 +0,0 @@
import bpy
import mathutils
from jsondiff import diff
from .. import utils
from .bl_datablock import BlDatablock
from .bl_material import load_link, load_node
class BlWorld(BlDatablock):
def construct(self, data):
return bpy.data.worlds.new(data["name"])
def load(self, data, target):
if data["use_nodes"]:
if target.node_tree is None:
target.use_nodes = True
target.node_tree.nodes.clear()
for node in data["node_tree"]["nodes"]:
load_node(target.node_tree, data["node_tree"]["nodes"][node])
# Load nodes links
target.node_tree.links.clear()
for link in data["node_tree"]["links"]:
load_link(target.node_tree, data["node_tree"]["links"][link])
def dump(self, pointer=None):
assert(pointer)
world_dumper = utils.dump_anything.Dumper()
world_dumper.depth = 2
world_dumper.exclude_filter = [
"preview",
"original",
"uuid",
"color",
"cycles",
"light_settings"
]
data = world_dumper.dump(pointer)
if pointer.use_nodes:
nodes = {}
dumper = utils.dump_anything.Dumper()
dumper.depth = 2
dumper.exclude_filter = [
"dimensions",
"select",
"bl_height_min",
"bl_height_max",
"bl_width_min",
"bl_width_max",
"bl_width_default",
"hide",
"show_options",
"show_tetxures",
"show_preview",
"outputs",
"preview",
"original",
"width_hidden"
]
for node in pointer.node_tree.nodes:
nodes[node.name] = dumper.dump(node)
if hasattr(node, 'inputs'):
nodes[node.name]['inputs'] = {}
for i in node.inputs:
input_dumper = utils.dump_anything.Dumper()
input_dumper.depth = 2
input_dumper.include_filter = ["default_value"]
if hasattr(i, 'default_value'):
nodes[node.name]['inputs'][i.name] = input_dumper.dump(
i)
data["node_tree"]['nodes'] = nodes
utils.dump_datablock_attibutes(
pointer.node_tree, ["links"], 3, data['node_tree'])
return data
def resolve(self):
assert(self.buffer)
self.pointer = bpy.data.worlds.get(self.buffer['name'])
def diff(self):
diff_rev = diff(self.dump(pointer=self.pointer), self.buffer)
return (self.bl_diff() or
len(diff_rev.keys()) > 0)
def resolve_dependencies(self):
deps = []
if self.pointer.use_nodes:
for node in self.pointer.node_tree.nodes:
if node.type == 'TEX_IMAGE':
deps.append(node.image)
if self.is_library:
deps.append(self.pointer.library)
return deps
def is_valid(self):
return bpy.data.worlds.get(self.buffer['name'])
bl_id = "worlds"
bl_class = bpy.types.World
bl_rep_class = BlWorld
bl_delay_refresh = 4
bl_delay_apply = 4
bl_automatic_push = True
bl_icon = 'WORLD_DATA'

View File

@ -1,169 +0,0 @@
import logging
import bpy
from . import operators, presence, utils
from .bl_types.bl_user import BlUser
from .libs.replication.replication.constants import FETCHED, RP_COMMON
logger = logging.getLogger(__name__)
class Delayable():
"""Delayable task interface
"""
def register(self):
raise NotImplementedError
def execute(self):
raise NotImplementedError
def unregister(self):
raise NotImplementedError
class Timer(Delayable):
"""Timer binder interface for blender
Run a bpy.app.Timer in the background looping at the given rate
"""
def __init__(self, duration=1):
self._timeout = duration
self._running = True
def register(self):
"""Register the timer into the blender timer system
"""
bpy.app.timers.register(self.main)
def main(self):
self.execute()
if self._running:
return self._timeout
def execute(self):
"""Main timer loop
"""
raise NotImplementedError
def unregister(self):
"""Unnegister the timer of the blender timer system
"""
if bpy.app.timers.is_registered(self.main):
bpy.app.timers.unregister(self.main)
self._running = False
class ApplyTimer(Timer):
def __init__(self, timout=1, target_type=None):
self._type = target_type
super().__init__(timout)
def execute(self):
if operators.client:
nodes = operators.client.list(filter=self._type)
for node in nodes:
node_ref = operators.client.get(uuid=node)
if node_ref.state == FETCHED:
operators.client.apply(uuid=node)
class DynamicRightSelectTimer(Timer):
def __init__(self, timout=1):
super().__init__(timout)
self.last_selection = []
def execute(self):
if operators.client:
users = operators.client.list(filter=BlUser)
for user in users:
user_ref = operators.client.get(uuid=user)
settings = bpy.context.window_manager.session
# Other user
if user_ref.buffer['name'] != settings.username:
user_selection = user_ref.buffer['selected_objects']
for obj in bpy.data.objects:
obj.hide_select = obj.name in user_selection
# Local user
elif user_ref.pointer:
current_selection = utils.get_selected_objects(
bpy.context.scene)
if current_selection != self.last_selection:
user_ref.pointer.update_selected_objects(bpy.context)
right_strategy = operators.client.get_config()[
'right_strategy']
if right_strategy == RP_COMMON:
obj_common = [
o for o in self.last_selection if o not in current_selection]
obj_ours = [
o for o in current_selection if o not in self.last_selection]
# change old selection right to common
for obj in obj_common:
_object = bpy.data.objects.get(obj)
node = operators.client.get(reference=_object)
if node and node.owner == settings.username:
operators.client.change_owner(
node.uuid, RP_COMMON)
# change new selection to our
for obj in obj_ours:
node = operators.client.get(
reference=bpy.data.objects[obj])
if node and node.owner == RP_COMMON:
operators.client.change_owner(
node.uuid, settings.username)
self.last_selection = current_selection
class RedrawTimer(Timer):
def __init__(self, timout=1, target_type=None):
self._type = target_type
super().__init__(timout)
def execute(self):
if presence.renderer:
presence.refresh_3d_view()
class Draw(Delayable):
def __init__(self):
self._handler = None
def register(self):
self._handler = bpy.types.SpaceView3D.draw_handler_add(
self.execute, (), 'WINDOW', 'POST_VIEW')
def execute(self):
raise NotImplementedError()
def unregister(self):
try:
bpy.types.SpaceView3D.draw_handler_remove(
self._handler, "WINDOW")
except:
logger.error("draw already unregistered")
class ClientUpdate(Draw):
def __init__(self, client_uuid=None):
assert(client_uuid)
self._client_uuid = client_uuid
super().__init__()
def execute(self):
if self._client_uuid and operators.client:
client = operators.client.get(uuid=self._client_uuid)
if client:
client.pointer.update_location()

20
docs/Makefile Normal file
View File

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 MiB

8
docs/about/index.rst Normal file
View File

@ -0,0 +1,8 @@
About
=====
.. toctree::
:maxdepth: 1
:name: toc-about
introduction

View File

@ -0,0 +1,15 @@
============
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.
.. figure:: img/about_chain.gif
:align: center
The linear workflow problems
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.

98
docs/conf.py Normal file
View File

@ -0,0 +1,98 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'multi-user'
copyright = '2020, Swann Martinez'
author = 'Swann Martinez, Poochy, Fabian'
# The full version, including alpha/beta/rc tags
release = '0.5.0-develop'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = ".rst"
# The master toctree document.
master_doc = "index"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'python'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# 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'
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
if on_rtd:
using_rtd_theme = True
# 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)
# 'display_version': True, # Display the docs version
# 'navigation_depth': 4, # Depth of the headers shown in the navigation bar
}
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'multiusrdoc'
# sphinx-notfound-page
# https://github.com/readthedocs/sphinx-notfound-page
notfound_context = {
'title': 'Page Not Found',
'body': '''
<h1>Page Not Found</h1>
<p>Sorry, we couldn't find that page.</p>
<p>Try using the search box or go to the homepage.</p>
''',
}
# Enable directives that insert the contents of external files
file_insertion_enabled = False

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.

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.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

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: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 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.

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

@ -0,0 +1,12 @@
===============
Getting started
===============
.. toctree::
:maxdepth: 1
:name: toc-getting-started
install
quickstart
troubleshooting
glossary

View File

@ -0,0 +1,58 @@
============
Installation
============
.. hint::
The process is the same for linux, mac and windows.
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).
3. Install **multi-user.zip** from your addon preferences.
Once the addon is succesfully installed, I strongly recommend you to follow the :ref:`quickstart`
tutorial.
.. _update-version:
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

@ -0,0 +1,483 @@
.. _quickstart:
===========
Quick start
===========
.. hint::
*All session-related settings are located under: `View3D -> Sidebar -> Multiuser panel`*
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:
- :ref:`how-to-host`
- :ref:`how-to-join`
- :ref:`how-to-manage`
.. _how-to-host:
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.
* **Location**: Where the user is actually working.
* **Frame**: When (on which frame) the user is 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 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

@ -0,0 +1,19 @@
.. _troubleshooting:
===============
Troubleshooting
===============
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
- Make sure to allow Blender through your firewall
.. hint:: Your firewall may have additional settings like Ransomware protection, or you may need to enable both Blender and Python on private and/or public Networks
- Solve problems with your connection quality
- 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.

BIN
docs/img/homepage_ban.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

66
docs/index.rst Normal file
View File

@ -0,0 +1,66 @@
=====================================
Welcome to Multi-user's documentation
=====================================
.. 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.
.. warning:: Under development, use it at your own risks.
Main Features
=============
- Collaborative workflow in blender
- Viewport users presence (active selection, POV)
- Datablocks right managment
- Tested under Windows
Community
=========
A `discord server <https://discord.gg/aBPvGws>`_ have been created to provide help for new users and
organize collaborative creation sessions.
Status
======
.. image:: img/homepage_roadmap.png
Follow the `roadmap <https://gitlab.com/slumber/multi-user/-/boards/929107>`_ to be aware of last news.
Documentation is organized into the following sections:
.. toctree::
:maxdepth: 1
:caption: About
:name: sec-about
about/introduction
.. toctree::
:maxdepth: 1
:caption: Getting started
:name: sec-learn
getting_started/install
getting_started/quickstart
getting_started/glossary
getting_started/troubleshooting
.. toctree::
:maxdepth: 1
:caption: Tutorials
:name: sec-tutorials
tutorials/hosting_guide
.. toctree::
:maxdepth: 1
:caption: Community
:name: sec-community
ways_to_contribute

35
docs/make.bat Normal file
View File

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

View File

@ -0,0 +1,731 @@
.. _internet-guide:
=======================
Hosting on the internet
=======================
.. 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>`_).
This tutorial aims to guide you toward hosting a collaborative multi-user session on the internet.
Hosting a session can be achieved in several ways:
- :ref:`host-blender`: hosting a session directly from the blender add-on panel.
- :ref:`host-dedicated`: hosting a session directly from the command line interface on a computer without blender.
- :ref:`host-cloud`: hosting a session on a dedicated cloud server such as Google Cloud's free tier.
.. _host-blender:
--------------------
From blender
--------------------
By default your router doesn't allow anyone to share you connection.
In order grant the server access to people from internet you have two main option:
* The :ref:`connection-sharing`: the easiest way.
* The :ref:`port-forwarding`: this way is the most unsecure. If you have no networking knowledge, you should definitely follow :ref:`connection-sharing`.
.. _connection-sharing:
Using a connection sharing solution
-----------------------------------
You can either follow `Pierre Schiller's <https://www.youtube.com/c/activemotionpictures/featured>`_ excellent video tutorial or jump to the `text tutorial <zt-installation_>`_.
.. raw:: html
<p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/xV4R5AukkVw" frameborder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</p>
Many third party software like `ZEROTIER <https://www.zerotier.com/download/>`_ (Free) or `HAMACHI <https://vpn.net/>`_ (Free until 5 users) allow you to share your private network with other people.
For the example I'm gonna use ZeroTier because it's free and open source.
.. _zt-installation:
1. Installation
^^^^^^^^^^^^^^^
Let's start by downloading and installing ZeroTier:
https://www.zerotier.com/download/
Once installed, launch it.
2. Network creation
^^^^^^^^^^^^^^^^^^^
To create a ZeroTier private network you need to register a ZeroTier account `on my.zerotier.com <https://my.zerotier.com/login>`_
(click on **login** then register on the bottom)
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).
.. figure:: img/hosting_guide_head_network.png
:align: center
:width: 450px
ZeroTier user homepage
Hit 'Create a network'(see image below) and go to the network settings.
.. figure:: img/hosting_guide_create_network.png
:align: center
:width: 450px
Admin password
Now that the network is created, let's configure it.
In the Settings section(see image below), you can change the network name to what you want.
Make sure that the field **Access Control** is set to **PRIVATE**.
.. hint::
If you set the Access Control to PUBLIC, anyone will be able to join without
your confirmation. It is easier to set up but less secure.
.. figure:: img/hosting_guide_network_settings.png
:align: center
:width: 450px
Network settings
That's all for the network setup !
Now let's connect everyone.
.. _network-authorization:
3. Network authorization
^^^^^^^^^^^^^^^^^^^^^^^^
Since your ZeroTier network is Private, you will need to authorize each new user
to connect to it.
For each user you want to add, do the following step:
1. Get the client **ZeroTier id** by right clicking on the ZeroTier tray icon and click on the `Node ID`, it will copy it.
.. figure:: img/hosting_guide_get_node.png
:align: center
:width: 450px
Get the ZeroTier client id
2. Go to the network settings in the Member section and paste the Node ID into the Manually Add Member field.
.. figure:: img/hosting_guide_add_node.png
:align: center
:width: 450px
Add the client to network-authorized users
4. Network connection
^^^^^^^^^^^^^^^^^^^^^
To connect to the ZeroTier network, get the network id from the network settings (see image).
.. figure:: img/hosting_guide_get_id.png
:align: center
:width: 450px
Now we are ready to join the network !
Right click on the ZeroTier tray icon and select **Join Network** !
.. figure:: img/hosting_guide_join_network.png
:align: center
:width: 450px
.. figure:: img/hosting_guide_join.png
:align: center
Joining the network
Past the network id and check ``Allow Managed`` then click on join !
You should be connected to the network.
Let's check the connection status. Right click on the tray icon and click on **Show Networks...**.
.. figure:: img/hosting_guide_show_network.png
:align: center
:width: 450px
Show network status
.. figure:: img/hosting_guide_network_status.png
:align: center
Network status.
The network status must be **OK** for each user(like in the picture above) otherwise it means that you are not connected to the network.
If you see something like **ACCESS_DENIED**, it means that you were not authorized to join the network. Please check the section :ref:`network-authorization`
This is it for the ZeroTier network setup. Now everything should be setup to use the multi-user add-on over internet ! You can now follow the :ref:`quickstart` guide to start using the multi-user add-on !
.. _port-forwarding:
Using port-forwarding
---------------------
The port forwarding method consists of configuring your network router to deny most traffic with a firewall, but to then allow particular internet traffic (like a multiuser connection) through the firewall on specified ports.
In order to know which ports are used by the add-on, please check the :ref:`port-setup` section.
To set up port forwarding for each port you can follow this `guide <https://www.wikihow.com/Set-Up-Port-Forwarding-on-a-Router>`_ for example.
Once you have set up the network you can follow the :ref:`quickstart` guide to begin using the multi-user add-on !
.. _host-dedicated:
--------------------------
From the dedicated server
--------------------------
.. warning::
The dedicated server is developed to run directly on an internet server (like a VPS (Virtual Private Server)). You can also run it at home on a LAN but for internet hosting you need to follow the :ref:`port-forwarding` setup first. Please see :ref:`host-cloud` for a detailed walkthrough of cloud hosting using Google Cloud.
The dedicated server allows you to host a session with simplicity from any location.
It was developed to improve internet hosting performance (for example poor latency).
The dedicated server can be run in two ways:
- :ref:`cmd-line`
- :ref:`docker`
.. Note:: There are shell scripts to conveniently start a dedicated server via either of these approaches available in the gitlab repository. See section: :ref:`serverstartscripts`
.. _cmd-line:
Using a regular command line
----------------------------
You can run the dedicated server on any platform by following these steps:
1. Firstly, download and intall python 3 (3.6 or above).
2. Install the latest version of the replication library:
.. code-block:: bash
python -m pip install replication==0.1.13
4. Launch the server with:
.. code-block:: bash
replication.server
.. hint::
You can also specify a custom **port** (-p), **timeout** (-t), **admin password** (-pwd), **log level (ERROR, WARNING, INFO or DEBUG)** (-l) and **log file** (-lf) with the following optional arguments
.. code-block:: bash
replication.server -p 5555 -pwd admin -t 5000 -l INFO -lf server.log
Here, for example, a server is instantiated on port 5555, with password 'admin', a 5 second timeout, and logging enabled.
As soon as the dedicated server is running, you can connect to it from blender by following :ref:`how-to-join`.
.. hint::
Some server commands are available to enable administrators to manage a multi-user session. Check :ref:`dedicated-management` to learn more.
.. _docker:
Using a pre-configured image on docker engine
---------------------------------------------
Launching the dedicated server from a docker server is simple as running:
.. code-block:: bash
docker run -d \
-p 5555-5560:5555-5560 \
-e port=5555 \
-e log_level=DEBUG \
-e password=admin \
-e timeout=5000 \
registry.gitlab.com/slumber/multi-user/multi-user-server:latest
Please use the :latest tag, or otherwise use the URL of the most recent container available in the `multi-user container registry <https://gitlab.com/slumber/multi-user/container_registry/1174180>`_. As soon as the dedicated server is running, you can connect to it from blender by following :ref:`how-to-join`.
You can check that your container is running, and find its ID and name with:
.. code-block:: bash
docker ps
.. _docker-logs:
Viewing logs in a docker container
----------------------------------
Logs for the server running in a docker container can be accessed by outputting the container logs to a log file. First, you'll need to know your container ID, which you can find by running:
.. code-block:: bash
docker ps
Then, output the container logs to a file:
.. code-block:: bash
docker logs your-container-id >& dockerserver.log
.. Note:: If using WSL2 on Windows 10 (Windows Subsystem for Linux), it is preferable to run a dedicated server via regular command line approach (or the associated startup script) from within Windows - docker desktop for windows 10 usually uses the WSL2 backend where it is available.
.. This may not be true. Need to write up how to locally start a docker container from WSL2
Downloading logs from a docker container on a cloud-hosted server
-----------------------------------------------------------------
If you'd like to pull the log files from a cloud-hosted server to submit to a developer for review, a simple process using SSH and SCP is as follows:
First SSH into your instance. You can either open the `VM Instances console <https://console.cloud.google.com/compute/instances>`_ and use the browser terminal provided by Google Cloud (I had the best luck using the Google Chrome browser)... or you can see `here <https://cloud.google.com/compute/docs/instances/connecting-advanced#thirdpartytools>`_ for how to set up your instance for SSH access from your local terminal.
If using SSH from your terminal, first generate SSH keys (setting their access permissions to e.g. chmod 400 level whereby only the user has permissions) and submit the public key to the cloud-hosted VM instance, storing the private key on your local machine.
Then, SSH into your cloud server from your local terminal, with the following command:
.. code-block:: bash
ssh -i PATH_TO_PRIVATE_KEY USERNAME@EXTERNAL_IP_ADDRESS
Use the private key which corresponds to the public key you uploaded, and the username associated with that key (visible in the Google Cloud console for your VM Instance). Use the external IP address for the server, available from the `VM Instances console <https://console.cloud.google.com/compute/instances>`_
e.g.
.. code-block:: bash
ssh -i ~/.ssh/id_rsa user@xxx.xxx.xxx.xxx
Once you've connected to the server's secure shell, you can generate a log file from the docker container running the replication server. First, you'll need to know your container ID, which you can find by running:
.. code-block:: bash
docker ps
If you're cloud-hosting with e.g. Google Cloud, your container will be the one associated with the `registry address <https://gitlab.com/slumber/multi-user/container_registry/1174180>`_ where your Docker image was located. e.g. registry.gitlab.com/slumber/multi-user/multi-user-server:latest
To view the docker container logs, run:
.. code-block:: bash
docker logs your-container-name
OR
.. code-block:: bash
docker logs your-container-id
To save the output to a file, run:
.. code-block:: bash
docker logs your-container-id >& dockerserver.log
Now that the server logs are available in a file, we can disconnect from the secure shell (SSH), and then copy the file to the local machine using SCP. In your local terminal, execute the following:
.. code-block:: bash
scp -i PATH_TO_PRIVATE_KEY USERNAME@EXTERNAL_IP_ADDRESS:"dockerserver.log" LOCAL_PATH_TO_COPY_FILE_TO
e.g.
.. code-block:: bash
scp -i ~/.ssh/id_rsa user@xxx.xxx.xxx.xxx:"dockerserver.log" .
This copies the file dockerserver.log generated in the previous step to the current directory on the local machine. From there, you can send it to the multi-user maintainers for review.
.. Note:: See these `notes <https://cloud.google.com/compute/docs/containers/deploying-containers?_ga=2.113663175.-1396941296.1606125558#viewing_container_logs>`_ for how to check server logs on Google Cloud using other tools.
.. _serverstartscripts:
Server startup scripts
----------------------
Convenient scripts are available in the Gitlab repository: https://gitlab.com/slumber/multi-user/scripts/startup_scripts/
Simply run the relevant script in a shell on the host machine to start a server with one line of code via replication directly or via a docker container. Choose between the two methods:
.. code-block:: bash
./start-server.sh
or
.. code-block:: bash
./run-dockerfile.sh
.. hint::
Once your server is up and running, some commands are available to manage the session :ref:`dedicated-management`
.. _dedicated-management:
Dedicated server management
---------------------------
Here is the list of available commands from the dedicated server:
- ``help`` or ``?``: Show all commands. Or, use ``help <command>`` to learn about another command
- ``exit`` or ``Ctrl+C`` : Stop the server.
- ``kick username``: kick the provided user.
- ``users``: list all online users.
Also, see :ref:`how-to-manage` for more details on managing a server.
.. _cloud-dockermanage:
Managing a docker server from the command line
----------------------------------------------
If you want to be able to manage a server running within a docker container, open the terminal on the host machine (or SSH in, if you are using cloud hosting), and then run
.. code-block:: bash
docker ps
to find your container id, and then
.. code-block:: bash
docker attach your-container-id
to attach to the STDOUT from the container. There, you can issue the server management commands detailed in :ref:`dedicated-management`. Type ``?`` and hit return/enter to see the available commands. Also, see :ref:`how-to-manage` for more details on managing a server.
.. _port-setup:
----------
Port setup
----------
The multi-user network architecture is based on a client-server model. The communication protocol uses four ports to communicate with clients:
* Commands: command transmission (such as **snapshots**, **change_rights**, etc.) [user-nominated port]
* Subscriber : pull data [Commands port + 1]
* Publisher : push data [Commands port + 2]
* TTL (time to leave) : used to ping each client [Commands port + 3]
To know which ports will be used, you just have to read the port in your preferences.
.. figure:: img/hosting_guide_port.png
:align: center
:alt: Port
:width: 200px
Port in host settings
In the picture below we have setup our port to **5555** so the four ports will be:
* Commands: **5555** (5555)
* Subscriber: **5556** (5555 +1)
* Publisher: **5557** (5555 +2)
* TTL: **5558** (5555 +3)
Those four ports need to be accessible from the client otherwise multi-user won't work at all !
.. _host-cloud:
-------------------------
Cloud Hosting Walkthrough
-------------------------
The following is a walkthrough for how to set up a multi-user dedicated server instance on a cloud hosting provider - in this case, `Google Cloud <https://www.cloud.google.com>`_. Google Cloud is a powerful hosting service with a worldwide network of servers. It offers a free trial which provides free cloud hosting for 90 days, and then a free tier which runs indefinitely thereafter, so long as you stay within the `usage limits <https://cloud.google.com/free/docs/gcp-free-tier#free-tier-usage-limits>`_. ^^Thanks to community member @NotFood for the tip!
Cloud hosting is a little more complicated to set up, but it can be valuable if you are trying to host a session with multiple friends scattered about planet earth. This can resolve issues with data replication or slowdowns due to poor latency of some users (high ping). This guide may seem technical, but if you follow the steps, you should be able to succeed in hosting an internet server to co-create with other multi-user creators around the world.
Setup Process
-------------
1. Sign Up for Google Cloud
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Let's start by activating an account with Google Cloud. Go to https://www.cloud.google.com and click 'Get Started For Free'
.. figure:: img/hosting_guide_gcloud_1.jpg
:align: center
:width: 450px
Google will ask you to login/signup, and to set up a billing account (Don't worry. It will not be charged unless you explicitly enable billing and then run over your `free credit allowance <https://cloud.google.com/free/docs/gcp-free-tier>`_). You will need to choose a billing country (relevant for `tax purposes <https://cloud.google.com/billing/docs/resources/vat-overview>`_). You will choose your server location at a later step.
2. Enable Billing and Compute Engine API
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
From here on, we will mostly stick to the instructions provided `here <https://cloud.google.com/compute/docs/quickstart-linux>`_. Nevertheless, the instructions for multi-user specifically are as follows.
In order to set up a Virtual Machine (VM) to host your server, you will need to enable the billing account which was created during your signup process. From your `console <https://console.cloud.google.com/getting-started>`_, click on 'Go to Checklist' and then 'Create a Billing Account', following the prompts to choose the billing account that was created for you upon signup.
.. figure:: img/hosting_guide_gcloud_2.jpg
:align: center
:width: 300px
.. figure:: img/hosting_guide_gcloud_3.jpg
:align: center
:width: 300px
.. figure:: img/hosting_guide_gcloud_4.jpg
:align: center
:width: 300px
.. figure:: img/hosting_guide_gcloud_5.jpg
:align: center
:width: 300px
.. figure:: img/hosting_guide_gcloud_6.jpg
:align: center
:width: 300px
Now hit 'Set Account', and go back to your `console <https://console.cloud.google.com/getting-started>`_.
Now enable the Compute Engine API. Click `here <https://console.cloud.google.com/apis/api/compute.googleapis.com/overview>`_ to enable.
.. figure:: img/hosting_guide_gcloud_7.jpg
:align: center
:width: 300px
3. Create a Linux Virtual Machine Instance
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Continue following the `instructions <https://cloud.google.com/compute/docs/quickstart-linux#create_a_virtual_machine_instance>`_ to create a VM instance. However, once you've finished step 2 of 'Create a virtual machine instance', use the settings and steps for multi-user as follows.
.. _server-location:
3.1 Choose a Server Location
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The most important settings which you will need to choose for your specific case are the server Region and Zone. You must choose a location which will provide the best ping for all of your fellow creators.
All you need to know is that you'll probably want to choose a location near to where most of your collaborators are located. If your friends are spread out, somewhere in the middle which distributes the ping evenly to all users is best.
You can use `this map <https://cloud.google.com/about/locations/>`_ to make a rough guess of the best server location, if you know your friends' locations.
.. figure:: img/hosting_guide_gcloud_9.jpg
:align: center
:width: 450px
A much better approach is to have your users run a ping test for Google Cloud's servers at https://www.gcping.com/
Have your collaborators open this webpage from their fastest browser, and press the play button. The play button turns to a stop icon while the ping test is running. When it is complete, the play button returns. You may need to refresh your browser to get this to work. You can replay the test to add more server locations to the scan, and stop when you are satisfied that the results are consistent.
Now, gather your friends' data, and work down each user's list from the top, until you find the first location which gives roughly the same ping for all users.
In general, global (using load balancing) will provide the best results, but beyond that, the US Central servers e.g. IOWA generally turn out best for a globally distributed bunch of creators. When in doubt, choose between the servers offered under the `free tier <https://cloud.google.com/free/docs/gcp-free-tier>`_
- Oregon: *us-west1*
- Iowa: *us-central1*
- South Carolina: *us-east1*
For the following example, the server which gave the most balanced, and lowest average ping between two friends based in Europe and Australia was in Iowa. Salt Lake City would also be an excellent choice.
.. figure:: img/hosting_guide_gcloud_10.jpg
:align: center
:width: 450px
Left - European User | Right - Australian User
Now, input this server location in the 'Region' field for your instance, and leave the default zone which is then populated.
.. Note:: You can read `here <https://cloud.google.com/solutions/best-practices-compute-engine-region-selection>`_ for a deeper understanding about how to choose a good server location.
3.2 Configure the VM
^^^^^^^^^^^^^^^^^^^^
You can deploy the replication server to your VM in either of the ways mentioned at :ref:`host-dedicated`. That is, you can set it up :ref:`cmd-line` or :ref:`docker`. We will go through both options in this walkthrough. See :ref:`container_v_direct` for more details on how to choose. Deploying a container is the recommended approach.
.. _cloud-container:
Option 1 - Deploy a container
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you are familiar with Docker, you'll appreciate that it makes life a little simpler for us. While configuring your instance, you can check **Deploy a container to this VM instance** and copy in the URL of the latest docker image available from the `multi-user container registry <https://gitlab.com/slumber/multi-user/container_registry/1174180>`_ to the *Container image* field, or use the tag ``:latest``
.. figure:: img/hosting_guide_gcloud_8b.jpg
:align: center
:width: 450px
Your configuration with Docker should look like this
Make sure to choose the amount of memory you'd like your server to be able to handle (how much memory does your blender scene require?). In this example, I've chosen 4GB of RAM.
Click on **Advanced container options** and turn on *Allocate a buffer for STDIN* and *Allocate a pseudo-TTY* just in case you want to run an interactive shell in your container.
.. _cloud-optional-parameters:
Optional server parameters
^^^^^^^^^^^^^^^^^^^^^^^^^^
The default Docker image essentially runs the equivalent of:
.. code-block:: bash
replication.server -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.
.. Note:: If you'd like to configure different server options from the default docker configuration, you can insert your options here by expanding 'Advanced container options'
For example, I would like to launch my server with a different administrator password than the default, my own log filename, and a shorter 3-second (3000ms) timeout. I'll click *Add argument* under **Command arguments** and paste the following command with options into the "command arguments" field:
.. code-block:: bash
python3 -m replication.server -pwd supersecretpassword -p 5555 -t 3000 -l DEBUG -lf logname.log
Now, my configuration should look like this:
.. figure:: img/hosting_guide_gcloud_8c.jpg
:align: center
:width: 450px
The rest of the settings are now complete. Hit **Create** and your instance will go live. If you've taken this approach, you're already almost there! Skip to :ref:`cloud-firewall`.
.. hint:: You can find further information on configuration options `here <https://cloud.google.com/compute/docs/containers/configuring-options-to-run-containers>`_. Also, see these `notes <https://cloud.google.com/compute/docs/containers/deploying-containers?_ga=2.113663175.-1396941296.1606125558#viewing_container_logs>`_ for other options when deploying your server inside a container, including how to access the server's logs.
.. _cloud-direct:
Option 2 - Over SSH
^^^^^^^^^^^^^^^^^^^
Otherwise, we can run the dedicated server ourselves from the command-line over SSH.
While creating your instance, keep the default settings mentioned in the `guide <https://cloud.google.com/compute/docs/quickstart-linux#create_a_virtual_machine_instance>`_, however at step 4, choose Debian version 10. Also, there is no need to enable HTTP so skip step 6.
.. figure:: img/hosting_guide_gcloud_8a.jpg
:align: center
:width: 450px
Your configuration should look like this
Make sure to choose the amount of memory you'd like your server to be able to handle (how much memory does your blender scene require?). In this example, I've chosen 4GB of RAM.
Now, finally, click 'Create' to generate your Virtual Machine Instance.
.. _cloud-firewall:
4. Setting up Firewall and opening Ports
----------------------------------------
Now that your VM is instanced, you'll need to set up firewall rules, and open the ports required by multi-user. The documentation for VM firewalls on google cloud is `here <https://cloud.google.com/vpc/docs/using-firewalls#listing-rules-vm>`_.
First, go to the dashboard showing your `VM instances <https://console.cloud.google.com/compute/instances>`_ and note the 'External IP' address for later. This is the address of your server. Then, click 'Set up Firewall Rules'.
.. figure:: img/hosting_guide_gcloud_11.jpg
:align: center
:width: 450px
Note down your External IP
Now you will need to create two rules. One to enable communication inbound to your server (ingress), and another to enable outbound communication from your server (egress). Click 'Create Firewall'
.. figure:: img/hosting_guide_gcloud_12.jpg
:align: center
:width: 450px
Now create a rule exactly as in the image below for the outbound communication (egress).
.. figure:: img/hosting_guide_gcloud_13.jpg
:align: center
:width: 450px
Egress
.. Note:: If you set a different port number in :ref:`cloud-optional-parameters`, then use the ports indicated in :ref:`port-setup`
And another rule exactly as in the image below for the inbound communication (ingress).
.. figure:: img/hosting_guide_gcloud_14.jpg
:align: center
:width: 450px
Ingress
Finally, your firewall configuration should look like this.
.. figure:: img/hosting_guide_gcloud_15.jpg
:align: center
:width: 450px
Final Firewall Configuration
5. Install Replication Server into Virtual Machine
--------------------------------------------------
.. Note:: Skip to :ref:`initialise-server` if you've opted to launch the server by deploying a container. Your server is already live!
Now that we have set up our Virtual Machine instance, we can SSH into it, and install the Replication Server. Open the `VM Instances console <https://console.cloud.google.com/compute/instances>`_ once more, and SSH into your instance. It's easiest to use the browser terminal provided by Google Cloud (I had the best luck using the Google Chrome browser), but you can also see `here <https://cloud.google.com/compute/docs/instances/connecting-advanced#thirdpartytools>`_ for how to set up your instance for SSH access from your terminal.
.. figure:: img/hosting_guide_gcloud_16.jpg
:align: center
:width: 450px
Now, a terminal window should pop up in a new browser window looking something like this:
.. figure:: img/hosting_guide_gcloud_17.jpg
:align: center
:width: 450px
Remember, you had set up the VM with Debian 10. This comes with Python 3.7.3 already installed. The only dependency missing is to set up pip3. So, run:
.. code-block:: bash
sudo apt install python3-pip
.. figure:: img/hosting_guide_gcloud_18.jpg
:align: center
:width: 450px
And now lets install the latest version of replication:
.. code-block:: bash
sudo pip3 install replication==0.1.13
6. Launch Replication Server on VM Instance
-------------------------------------------
We're finally ready to launch the server. Simply run:
.. code-block:: bash
python3 -m replication.server -p 5555 -pwd admin -t 5000 -l INFO -lf server.log
See :ref:`cmd-line` for a description of optional parameters
And your replication server is live! It should stay running in the terminal window until you close it. Copy the external IP that you noted down earlier, available `here <https://console.cloud.google.com/networking/addresses/list>`_ and now you can open Blender and connect to your server!
.. _initialise-server:
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. Input your external IP, and make sure you're set to JOIN the server. Then, click CONNECT.
.. figure:: img/hosting_guide_gcloud_19.jpg
:align: center
:width: 200px
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!
Hopefully, your cloud server setup has improved your group's overall ping readings, and you're in for a smooth and trouble-free co-creation session.
.. Note:: If you should so desire, pay attention to your credit and follow the steps `here <https://cloud.google.com/compute/docs/quickstart-linux#clean-up>`_ to close your instance at your discretion.
.. _container_v_direct:
Should I deploy a Docker Container or launch a server from Linux VM command-line?
------------------------------------------------------
- Directly from Linux VM - This approach gives you control over your session more easily. However, your server may time out once your SSH link to the server is interrupted (for example, if the admin's computer goes to sleep).
- Deploy a Docker Container - This is the recommended approach. This approach is better for leaving a session running without supervision. It can however be more complicated to manage. Use this approach if you'd like a consistent experience with others in the multi-user community, pulling from the most up-to-date docker image maintained by @swann in the multi-user container registry.

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

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