Compare commits

...

265 Commits

Author SHA1 Message Date
Dalai Felinto
6f6f3a524a Another fixup for rB6cdb3845 (Added collection props getter/setter)
Values were getting clamped
2017-02-06 10:49:55 +01:00
71c8db2a0c Build Clay engine by default 2017-02-03 17:51:04 +01:00
Dalai Felinto
2b04710d61 UI: use the "USE" flag for collection settings
Note, this should be a proper uiTemplate, but a pure python approach seems to work fine for now
2017-02-03 16:16:39 +01:00
Dalai Felinto
35fb0e341b RNA: macros to wrap collection settings use 2017-02-03 16:16:39 +01:00
Dalai Felinto
83fea5307b layer: getter/setter for USE flag 2017-02-03 16:16:39 +01:00
Dalai Felinto
6644ff25f2 Update collection engine setings when updating collection values 2017-02-03 16:16:39 +01:00
Dalai Felinto
7f2da487a6 Placeholder for depsgraph evaluation of collection engine settings 2017-02-03 16:16:39 +01:00
41ba828131 Fix bplayer (c) 2017-02-03 15:18:32 +01:00
Dalai Felinto
79924fce49 RNA: use new getter/setter functions for LayerEngineSettings 2017-02-03 15:06:11 +01:00
Dalai Felinto
865a0de03d Fixup for rB6cdb3845 (Added collection props getter/setter) 2017-02-03 15:05:11 +01:00
4a84884e99 Fix warnings 2017-02-03 14:52:33 +01:00
7203aa24f9 New CMake flag for Clay Engine 2017-02-03 14:38:11 +01:00
9fb97e3f85 Fix hang infinite loop 2017-02-03 14:37:50 +01:00
0ee52a5741 Get rid of runtime data struct. 2017-02-03 13:33:59 +01:00
6cdb3845a3 Added collection settings getter/setter 2017-02-03 13:33:59 +01:00
8a22429db2 Change settings order 2017-02-03 13:33:59 +01:00
Dalai Felinto
a8ce1c98fe Set COLLECTION_PROP_USE when setting a layer_engine_settings property
We still need depsgraph to evaluate those changes
2017-02-03 12:23:01 +01:00
Dalai Felinto
5a9cd6a14d Util function to create CollectionEngineSettings
This may be run by Depsgraph, as well as internal layercollection create routines
2017-02-03 12:23:01 +01:00
Dalai Felinto
fa2bf9381b Util function to free CollectionEngineSettings
This may be run by Depsgraph, as well as internal layercollection free routines
2017-02-03 12:23:01 +01:00
Dalai Felinto
e1b13c0fa7 Fix storage of CollectionSettings in DNA_object_types.h 2017-02-03 12:23:01 +01:00
Dalai Felinto
85f7ad95ed Remove unused enum values (COLLECTION_PROP_TYPE_POINTER/BOOL) 2017-02-03 12:23:01 +01:00
0e3ba7cf41 More lamp work 2017-02-02 22:19:23 +01:00
e148661d8d Use vec2 for screen space stuff 2017-02-02 21:44:14 +01:00
6f1bdaab9d Lamp sunrays and shadow circles 2017-02-02 21:39:58 +01:00
8641fa1397 Fix unfreed memory 2017-02-02 17:15:26 +01:00
b12d2fb922 Fix warnings 2017-02-02 17:03:21 +01:00
e572cf1239 Fix depth not cleared 2017-02-02 16:54:34 +01:00
f695c9861f Bypass wires. 2017-02-02 16:54:15 +01:00
c1057ac196 Fix ogl warnings. 2017-02-02 16:28:16 +01:00
b1add8e5bd Fix assert 2017-02-02 16:23:21 +01:00
92a2b444b0 Added Lamp screen space visual 2017-02-02 14:17:29 +01:00
0ccfa297f9 Start of Lamp drawing 2017-02-02 11:58:24 +01:00
6144721778 Groundline/GroundPoint shader for lights 2017-02-02 11:58:24 +01:00
Dalai Felinto
003c64757d Clay Engine per-collection settings
Note: this is still not used by rendering
2017-02-02 11:26:36 +01:00
Dalai Felinto
0b834c4fd9 Introduce Per-Collection Render settings
Pending:

* UI template for those settings (showing USE)
* Depsgraph evaluation of them (to flush into objects)
* RNA to see if a settings is being used
2017-02-02 11:26:36 +01:00
0651227c4a Fixing Memory Leak 2017-02-01 14:32:48 +01:00
160c643131 Implemented All Empties type drawing 2017-02-01 13:58:49 +01:00
Dalai Felinto
a19607ca56 Silence more warnings
This should silence the current warnings, and gives us real warnings if
the bContext data is tampered with.
2017-02-01 11:59:59 +01:00
Dalai Felinto
0526088819 Silence warning
There is still a warning because of `DST.context = C;` which discards
'const' qualifier. I find this a legit problem, I suspect we are not
suppose to store bContext at all.
2017-02-01 11:47:03 +01:00
85194046e6 Giving Overlay Edges a try 2017-02-01 00:28:16 +01:00
242715b843 Code cleanup 2017-01-31 17:27:19 +01:00
81db4d2b43 Added wire outlines 2017-01-31 17:27:05 +01:00
641828bf85 Code Cleanup 2017-01-31 16:15:06 +01:00
Dalai Felinto
f6b66e76e1 Use new temporary depsgraph
The idea is to use only Object, never Base
2017-01-31 15:21:40 +01:00
Dalai Felinto
dd4c638c0d Remove unused function (silence warning) 2017-01-31 15:20:40 +01:00
Dalai Felinto
71d7c57997 Merge branch 'render-layers' into clay-engine 2017-01-31 15:06:51 +01:00
Dalai Felinto
835f9742e6 Depsgraph hack: DEG_OBJECT_ITER and base_flag
This is a temporary iterator that flushes the base flag to the object
2017-01-31 15:06:34 +01:00
481785f153 Merge branch 'render-layers' of git.blender.org:blender into clay-engine 2017-01-31 14:03:00 +01:00
581b0c9a4f More Object mode work. 2017-01-31 14:01:23 +01:00
Dalai Felinto
a6191d0e27 UI: temporary panels for layer/collections 2017-01-31 13:06:26 +01:00
Dalai Felinto
6064ffdc83 bpy.ops.collections.* accessible outside collection editor 2017-01-31 13:05:26 +01:00
Dalai Felinto
c955b77f7d bpy.ops.collections.select()
When we introduce overrides we will extend it to have override_index,
and if it is -1, only set the collection
2017-01-31 13:05:23 +01:00
Dalai Felinto
a0e4ae5d37 bpy.ops.collections.collection_new() 2017-01-31 13:05:19 +01:00
Dalai Felinto
7f498b4bde Remove old layers bitflag from viewport 3d header template 2017-01-31 11:46:02 +01:00
Dalai Felinto
fb5682412d Let scene_collection and layer_collection to have the same fallback 2017-01-31 11:45:09 +01:00
c4c3951c4f Initial implementation of instancing 2017-01-31 11:44:40 +01:00
75d6a30cc2 Show Render Layer panel to clay engine. 2017-01-31 11:44:40 +01:00
Dalai Felinto
64b07e866a Add icon to collection panel 2017-01-31 10:52:09 +01:00
Dalai Felinto
52e1728a12 Fix logic for bpy.context.scene_collection 2017-01-31 10:46:06 +01:00
Dalai Felinto
910f16576d Unittest: refresh blender between tests 2017-01-31 10:14:46 +01:00
Dalai Felinto
5fa0315a75 Mesh batch caches should not be stored in file 2017-01-30 18:31:29 +01:00
Dalai Felinto
a35a66f702 Properties Editor: Collection context 2017-01-30 18:24:33 +01:00
Dalai Felinto
f35d38e5a7 Collections Editor: populate header with operators 2017-01-30 18:23:51 +01:00
Dalai Felinto
45b9dee8bd SceneCollection.objects.active_index (for user interface) 2017-01-30 18:23:05 +01:00
Dalai Felinto
8605eb9c97 Collection related operators barebones
Those are the operators for the collections editor, and the collection property panel
2017-01-30 18:21:36 +01:00
Dalai Felinto
1bfc6e79ee RNA: collection override 2017-01-30 18:21:34 +01:00
Dalai Felinto
f51c34185e bpy.context.layer_collection 2017-01-30 18:21:07 +01:00
f2e217938e Fixed unfreed memory 2017-01-30 15:35:12 +01:00
106f415ddd Fix crash on read file 2017-01-30 15:17:03 +01:00
b86e5a9fbf Fixed Pointer problem. Now materials are working. 2017-01-30 15:09:35 +01:00
12bac207c7 Added scene.active_engine_settings 2017-01-30 14:41:58 +01:00
Dalai Felinto
3da834e83c Collection Editor based on patch by Julian Eisel
This is extracted from the layer-manager branch. With the following
changes:

* Renamed references of layer manager to collections manager
* I didn't include the editors/space_collections/ draw and util files.

I still need to bring the drawing code here, so we see something.
2017-01-30 14:20:31 +01:00
Dalai Felinto
dce8ef49ff Layers: allow anonymous collection, and set active collection when linking it 2017-01-30 14:15:07 +01:00
08675b94ef Fixed Engine name length 2017-01-30 13:03:30 +01:00
ba4a30c71b Fix read/writefile.c 2017-01-30 12:19:51 +01:00
e15c16f11c Changes to DNA/RNA. Follow same layout as sensors. 2017-01-30 02:24:18 +01:00
744f26b612 Change in DNA/RNA. Still missing freeing and read/write. 2017-01-29 00:55:46 +01:00
5bf60530e5 Added switch to test viewport cache 2017-01-27 17:17:01 +01:00
Dalai Felinto
86887fe1c5 Temporarily prevent crash on edit mode 2017-01-27 15:20:19 +01:00
Dalai Felinto
29669db7d7 Merge remote-tracking branch 'origin/render-layers' into clay-engine 2017-01-27 12:46:39 +01:00
efa401b086 Introduce Dynamic Batches + Relationship lines + Clear some matrix warnings 2017-01-27 11:18:16 +01:00
4c416aea3b Merge branch 'render-layers' of git.blender.org:blender into clay-engine
# Conflicts:
#	source/blender/makesdna/DNA_scene_types.h
2017-01-26 19:49:09 +01:00
Dalai Felinto
c1742b88a4 Merge remote-tracking branch 'origin/blender2.8' into render-layers
Note:

renamed blo_do_versions_after_linking_280 to do_versions_after_linking_280 to following the pattern of do_versions_after_linking_270
2017-01-26 19:17:22 +01:00
Dalai Felinto
8f673cb40c Fix blenderplayer build 2017-01-26 19:01:49 +01:00
fcd5880d12 Fix include compilation error on MSVC 2015. 2017-01-26 18:51:22 +01:00
92e5dfbeed Fix compilation error on windows 2017-01-26 18:33:24 +01:00
Dalai Felinto
40aa8a1c79 Fixup for selected_objects context
This was making crash happen for any operation :/ shame on me
2017-01-26 18:27:30 +01:00
Dalai Felinto
51f77a10eb Fixup in doversioning 2017-01-26 18:25:08 +01:00
00c3c6824d Integrated MBC functions. Added Object centers and empties. 2017-01-26 15:56:40 +01:00
Dalai Felinto
e346927111 Remove unused panels (layer_passes and layer_options) 2017-01-25 18:02:58 +01:00
Dalai Felinto
dd61b7d346 Add scene active layer 2017-01-25 18:02:09 +01:00
Dalai Felinto
99e8618202 Remove scene layer and collection from context 2017-01-25 17:01:39 +01:00
72ff78a951 Merge branch 'render-layers' of git.blender.org:blender into clay-engine
# Conflicts:
#	source/blender/editors/space_view3d/drawobject.c
2017-01-25 12:28:52 +01:00
95e9790704 Fix compile error 2017-01-25 12:21:43 +01:00
Dalai Felinto
212e5d60d3 Merge remote-tracking branch 'origin/blender2.8' into render-layers 2017-01-25 10:17:38 +01:00
c5ed943479 Clay Material work. 2017-01-23 18:36:30 +01:00
Dalai Felinto
673a149e87 Merge remote-tracking branch 'origin/blender2.8' into render-layers 2017-01-23 11:17:09 +01:00
efa46d7db0 Initial support of Uniform Buffer objects 2017-01-23 09:54:54 +01:00
bbbb8405b6 Removed Batch storage
Also lots of renaming
Small visual tweaks
Material Settings Struct is now shared by Scene and material
2017-01-20 01:11:42 +01:00
Dalai Felinto
f8e4999656 I hereby declare layers syncing fully implemented! 2017-01-19 18:25:18 +01:00
Dalai Felinto
1edabaee72 curve convert and mesh separation working 2017-01-19 18:25:18 +01:00
Dalai Felinto
8a8e5055e3 Refactor mball util function, untested
I have not address MBalls directly, so there are probably other parts that are required to conform to the new code before consider than useful
2017-01-19 18:25:18 +01:00
Dalai Felinto
adcb6a1b90 Handle main object dupli functions
Missing: mesh separation, material split, mesh conversion (curve to mesh)
2017-01-19 18:25:18 +01:00
Dalai Felinto
971aa5f838 unittest: bpy.ops.object.duplicate 2017-01-19 18:25:18 +01:00
Dalai Felinto
caf59d3709 Use more of the FOREACH macros in screen_context.c 2017-01-19 17:15:19 +01:00
Dalai Felinto
bd14352a01 object/base iterator refactor + add FOREACH_VISIBLE_BASE 2017-01-19 12:07:12 +01:00
Dalai Felinto
32662bc95d Using static for prototypes 2017-01-19 12:06:18 +01:00
76dead8603 Basic Implementation of GTAO :
There is still artifacts to remove and optimisation to do.
2017-01-18 18:55:56 +01:00
Dalai Felinto
550446bade Tag areas of code that require TODO_LAYER_COPY 2017-01-18 15:41:27 +01:00
Dalai Felinto
10db593060 Merge remote-tracking branch 'origin/blender2.8' into render-layers
Manual fix: collection.c layer.c
2017-01-18 15:40:05 +01:00
Dalai Felinto
03fc433e18 Fix unittest for cases where we set render_layer but not scene_collection 2017-01-18 11:59:26 +01:00
Dalai Felinto
597cafb873 Fix context operator test
We needed a fallback for the cases where the layer was specified but not a scene_collection
2017-01-18 11:56:28 +01:00
Dalai Felinto
53eabca4e8 BKE_scene_layer_has_collection
Util function to check if a SceneCollection is linked to a SceneLayer

This is needed for corner cases of bpy.context.scene_collection when the context render_layer mismatches the context scene_collection.
2017-01-18 11:48:40 +01:00
Dalai Felinto
096f251122 Left-over from previous commit (remove OBJECT_OT_move_to_layer) 2017-01-17 17:58:56 +01:00
Dalai Felinto
b3ce0625c6 Remove OBJECT_OT_move_to_layer 2017-01-17 17:45:08 +01:00
Dalai Felinto
ef7dc52b53 Link objects in scene using ObjectBase 2017-01-17 17:42:32 +01:00
Dalai Felinto
74ba736fc4 Update selected_editable_bases to use ObjectBase 2017-01-17 15:33:46 +01:00
Dalai Felinto
78b630844b Remove base from BKE_object_groups_clear 2017-01-17 15:32:55 +01:00
Dalai Felinto
b1ff8e8703 Remove OB_FROMGROUP from base, and add util funcs to sync base/object flags
I still want to remove the syncing of base/object flags. But for now
this will at least help future refactor.
2017-01-17 14:58:41 +01:00
Dalai Felinto
216273d9e9 ObjectBase need a flag for from_dupli temp objects 2017-01-17 14:13:53 +01:00
e6bba9fa3a Edge AO improvement when geometry is over the background. 2017-01-17 12:59:39 +01:00
Dalai Felinto
fd99d52448 Fixup on versioning (re: selected objects) 2017-01-17 12:46:31 +01:00
Dalai Felinto
c36cdb92d6 Update selectable_bases to use ObjectBase 2017-01-16 17:49:35 +01:00
Dalai Felinto
9ddb221aab Update visible_bases to use ObjectBase 2017-01-16 17:04:02 +01:00
Dalai Felinto
5ff3dd5d97 Fix logic for BKE_scene_layer_base_flag_recalculate 2017-01-16 16:36:53 +01:00
Dalai Felinto
d2f97224b5 Remove select by layer operator 2017-01-16 15:12:58 +01:00
Dalai Felinto
10754500b0 Add BASE_SELECTABLED flag 2017-01-16 15:12:58 +01:00
Dalai Felinto
8a3dd31658 Rename: BASE_VISIBLE > BASE_VISIBLED
BASE_VISIBLE was already defined on DNA_scene_types.h
2017-01-16 15:12:58 +01:00
Dalai Felinto
911c31c201 Remove object hide operators 2017-01-16 15:12:58 +01:00
Dalai Felinto
c21e00683c Remove outliner restrict options for objects (and groups) 2017-01-16 15:12:58 +01:00
Dalai Felinto
0ad3979a6c Implement update of selected/visible based on collection tree 2017-01-16 10:54:34 +01:00
Dalai Felinto
c4e34a84e0 Outliner: initial work for render-layers
Remove Base references, still need to do some adjustments
2017-01-13 18:34:18 +01:00
Dalai Felinto
baad441362 FOREACH_VISIBLE_OBJECT macro
Also adding a new flag value for ObjectBase to store visibility.

I still need this to be synced, but the idea is to centralize the
logic of tree evluation, and keep the visibility cached.
2017-01-13 18:34:18 +01:00
Dalai Felinto
533965db73 Initial syncing of selection and visibility flag
When we make a collection invisible or unselectable, selected object have to be re-evaluated
Same goes for when we add a new object, its base visibility has to be
refreshed.

TODO also add a call for this when we remove a scene collection, or
unlink a scene layer.
2017-01-13 18:34:18 +01:00
33ca692256 Added object mode wires to new drawing pipeline. 2017-01-13 18:25:06 +01:00
Dalai Felinto
988024063f Use ObjectBase only to delete objects 2017-01-13 11:21:20 +01:00
Dalai Felinto
07d571ea22 Remove Bases onces and for all
This officially makes the viewport not draw anything, until we get the
new ObjectBase * to use.

This is easily revertable, but for now I prefer to make sure this is not
in the way of refactoring.
2017-01-12 18:23:01 +01:00
Dalai Felinto
0fba4655bf Updated python files to use select_get/_set() [not addons] 2017-01-12 17:51:09 +01:00
e954a6b8bc Fix crash. 2017-01-12 12:29:58 +01:00
306711c7ab Separate SSAO code & add orthographic support 2017-01-12 01:15:16 +01:00
382ade4c29 Added saturation and value slider + fix versioning 2017-01-11 19:48:51 +01:00
2c3d9f2762 Merge remote-tracking branch 'origin/render-layers' into clay-engine
# Conflicts:
#	source/blender/editors/space_view3d/drawobject.c
#	source/blender/gpu/intern/gpu_viewport.c
2017-01-11 17:41:18 +01:00
ddd95b9712 Fixed versionning 2017-01-11 17:38:00 +01:00
a94b4c2ff0 Fix Crash and Unfreed Memory 2017-01-11 16:58:08 +01:00
fd7f78d89f Introduce Batch storage. 2017-01-11 16:34:02 +01:00
Dalai Felinto
d97c6c36b8 Fix mem freed twice 2017-01-11 16:20:10 +01:00
Dalai Felinto
051f0a0b15 _free() functions should not clear the pointer itself 2017-01-11 15:54:56 +01:00
Dalai Felinto
a80d94c289 BLI_assert fix 2017-01-11 15:54:26 +01:00
Dalai Felinto
4180ca9b92 Doversion: set selected objects for "Render Layer" 2017-01-11 12:58:54 +01:00
Dalai Felinto
6d68195a9b Doversion: set active object for "Render Layer"
We don't do it for the other render layers (the ones converted from
SceneRenderLayer)
2017-01-11 12:58:25 +01:00
Dalai Felinto
345eb6f7cc RNA: object.select_get/set(action={'SELECT', 'DESELECT', 'TOGGLE'}) 2017-01-11 12:48:36 +01:00
Dalai Felinto
ec65bc6e76 Introduce ObjectBase rna wrapper for bpy.context.active_base 2017-01-11 11:45:41 +01:00
Dalai Felinto
b00cfb77cd Use active_object instead of active_base for edit mode enter
(prevent a crash after recent Base > ObjectBase commit)
2017-01-11 11:05:22 +01:00
Dalai Felinto
70ddef82b7 Merge remote-tracking branch 'origin/blender2.8' into render-layers 2017-01-11 09:47:30 +01:00
8c3a98e583 Added Matcap HSV variation (only Hue exposed). 2017-01-11 01:49:03 +01:00
89d99b6b77 Added matcap rotation 2017-01-10 23:52:13 +01:00
1ceeac2cab Use overall matcap colors as AO color avoiding completelly dark areas. 2017-01-10 22:03:57 +01:00
Dalai Felinto
d89274e83a Merge remote-tracking branch 'origin/blender2.8' into render-layers 2017-01-10 18:37:06 +01:00
Dalai Felinto
a771249d7d Add new objects and some Base > ObjectBase convertion
New objects are properly added to the correct collection, and are synced
into the correct collections.
2017-01-10 17:56:31 +01:00
c8162c5a2c Added SSAO to give cavity / Edge highlight effect. 2017-01-10 17:33:30 +01:00
Dalai Felinto
143c869bd0 Fix selected_objects iterator 2017-01-10 16:17:22 +01:00
Dalai Felinto
33ee18ad6f rename ob_base > base, it will simplify further refactors 2017-01-10 16:17:22 +01:00
Dalai Felinto
d16bfecde1 Removing Bases from clay.c and other fixes
Listbase was used wrongly in draw_manager, using LinkData elements now
2017-01-09 17:52:06 +01:00
Dalai Felinto
2ad2b23911 Merge remote-tracking branch 'origin/render-layers' into clay-engine 2017-01-09 16:35:25 +01:00
Dalai Felinto
052b45ac2a Fixup for iterator
(this is a placeholder anyways, what we really need is DEG_OBJECT_ITER()
2017-01-09 16:33:42 +01:00
Dalai Felinto
551852f4ca Adding FOREACH_OBJECT iterator 2017-01-09 16:17:04 +01:00
c9c0d6c24f Add properties to clay material (not exposed yet) 2017-01-09 15:06:17 +01:00
Dalai Felinto
1020914980 unittest: check context overriden passed to operator 2017-01-06 18:13:32 +01:00
Dalai Felinto
9f333a0889 unittest: use proper setUpModule class method() 2017-01-06 18:01:08 +01:00
Dalai Felinto
7e57905385 unittest: use assertEqual instead of assertTrue
(thanks to Sybren Stuvel)
2017-01-06 16:37:15 +01:00
ca4618bdbf Apply changes GPU_texture change. 2017-01-06 14:39:34 +01:00
2cf79f41fe Modifications to GPU_texture:
-Remove NPOT check as it should be supported by default with OGL 3.3
-All custom texture creation follow the same path now
-Now explicit texture format is required when creating a custom texture (Non RGBA8)
-Support for arrays of textures
2017-01-06 14:38:36 +01:00
Dalai Felinto
6933bb4e9a Fixup for bpy.context.scene_collection 2017-01-06 14:31:48 +01:00
Dalai Felinto
b5d41b1d71 RNA: bpy.context.scene_collection
We will need this for UI eventually, and now I need this to update the
Python add object routine.
2017-01-05 18:25:29 +01:00
Dalai Felinto
71e5e87f01 Unittest debug options, set context via override and bpy.context.scene_collection
For some reason ID is not being passed when we get SceneCollection from
bpy.context. This test fails in that case.
2017-01-05 18:24:28 +01:00
5333b2aa00 (Clay) Free memory + lots of renaming/reorganizing
Signed-off-by: Clément Foucault <foucault.clem@gmail.com>
2017-01-05 16:13:20 +01:00
c990364559 Merge remote-tracking branch 'origin/render-layers' into clay-engine 2017-01-05 11:28:28 +01:00
624f3c254f (Clay) Added Render settings:
- Default clay settings inside Scene RNA
- Material clay settings RNA is here and will be used once we can render multiple meshes
2017-01-05 11:28:11 +01:00
Dalai Felinto
d80372c9f4 handle objects removal only on preprocess 2017-01-04 18:34:49 +01:00
Dalai Felinto
7bd56f207d Merge remote-tracking branch 'origin/blender2.8' into render-layers 2017-01-04 18:27:14 +01:00
Dalai Felinto
ac6019e079 unittest: del via operator fixup 2017-01-04 18:26:13 +01:00
Dalai Felinto
ac80793592 Include object unlinking in library_remap preprocessing 2017-01-04 18:19:51 +01:00
Dalai Felinto
f8dd25afb8 remove objects from collections when ED_base_object_free_and_unlink 2017-01-04 18:04:32 +01:00
0c4776280d More work on Clay engine:
- Calculate normals with dfdy while waiting for a proper way to draw mesh normals.
- Added initial support for 2d texture arrays.
- Better API naming.
- Generate Matcap texture arrays and draw with it.
2017-01-04 11:01:14 +01:00
Dalai Felinto
3bdd555159 Massive fixup on BLI_iterator and the iterators using it 2017-01-03 18:21:15 +01:00
Dalai Felinto
36c34b96b3 From review: handle post processing of objects after they are removed 2017-01-03 16:46:05 +01:00
Dalai Felinto
caed6aad4b unittest: object delete 2017-01-03 16:42:57 +01:00
Dalai Felinto
b89b1b58b2 From review: proper handle of library_query 2017-01-03 11:48:42 +01:00
fe0df0a972 Beginning Clay Viewport Engine :
- Added temporary draw_mesh function to render edit mesh
- DRW_draw_batch_list allows to render a list of objects with optimal state change
- All viewport rendering is done offscreen for the moment

Signed-off-by: Clément Foucault <foucault.clem@gmail.com>
2017-01-03 10:44:24 +01:00
Dalai Felinto
e758b9d869 unittest: fixup 2017-01-02 14:22:46 +01:00
Dalai Felinto
2fa175eb8a Revert "Make sure new objects go to the correct (active) collection"
This reverts commit c51a32554e.
2016-12-23 19:25:29 +01:00
Dalai Felinto
2c55b4cbc8 Revert "Fix warning"
This reverts commit 280da49595.
2016-12-23 19:25:21 +01:00
Dalai Felinto
66bc0616fc unittest: object_add 2016-12-23 18:17:06 +01:00
Dalai Felinto
eae6e02759 unittest: active_collection_index 2016-12-23 17:42:35 +01:00
Dalai Felinto
7ba2a5feb5 bpy.context.render_layer 2016-12-23 17:04:10 +01:00
Dalai Felinto
280da49595 Fix warning 2016-12-23 15:59:33 +01:00
Dalai Felinto
ee6214dc80 Merge remote-tracking branch 'origin/blender2.8' into render-layers
Include manual changes to accomodate new do_versions_after_liblink
2016-12-23 15:56:13 +01:00
Dalai Felinto
c51a32554e Make sure new objects go to the correct (active) collection 2016-12-23 15:34:36 +01:00
Dalai Felinto
95e183b7f4 unittest touch ups 2016-12-22 12:14:46 +01:00
Dalai Felinto
a9cc4d0c5c render_layer.collections.link/unlink() 2016-12-22 12:14:32 +01:00
Dalai Felinto
4d998fb373 unittest: new layer, layer_collection_link/unlink 2016-12-21 19:14:44 +01:00
Dalai Felinto
5e79ebce13 Fixup for rna_SceneCollection_remove 2016-12-21 18:44:43 +01:00
Dalai Felinto
52c4adc4df Debug UI revamp 2016-12-21 18:44:42 +01:00
Dalai Felinto
c8978b160d unittest: syncing when unlinking a collection 2016-12-21 18:44:42 +01:00
Dalai Felinto
5c22ade95a Syncing: update layercollection tree when an object is unlinked
Note: filtering is not implemented/fully considered yet
2016-12-21 18:05:22 +01:00
Dalai Felinto
d550554d0c unittest: make tests more granular 2016-12-21 17:41:50 +01:00
Dalai Felinto
18ee712bf1 Layers: unittest to cover unlinking of objects 2016-12-21 17:41:50 +01:00
Dalai Felinto
a6cf5cfe9c Syncing: an object added to a scenecollection
Also changed the ObjectBase->refcount logic a bit, to simplify
further implementations of syncing.
2016-12-21 17:41:50 +01:00
Dalai Felinto
0abcddf470 Syncing: update layercollection tree when a new scenecollection is added 2016-12-21 12:27:50 +01:00
Dalai Felinto
1abef41657 Add nesting collections into unittest 2016-12-20 16:27:09 +01:00
Dalai Felinto
51984897d8 Temporary UI for layer/collections (for debug/testing) 2016-12-20 15:59:13 +01:00
Dalai Felinto
a508029fbc Make hide/hide_select icons dynamic 2016-12-20 15:37:23 +01:00
Dalai Felinto
619cbca39f From review: "doxygen"
I do not compile doxygen (assuming it is compiled, I do not even know). But it does not hurt to add the extra * everywhere
2016-12-20 11:21:10 +01:00
Dalai Felinto
72bd463127 Merge remote-tracking branch 'origin/blender2.8' into render-layers 2016-12-20 10:58:10 +01:00
Dalai Felinto
42bb135480 Fresh morning fixup of iterator logics
(and fix unfreed memory)
2016-12-20 10:42:26 +01:00
Dalai Felinto
9d2b6b56ac Fixup on BKE_scene_objects_Iterator_next 2016-12-19 18:13:47 +01:00
Dalai Felinto
d4cebc998b Use FOREACH_OBJECT_FLAG in more places 2016-12-19 17:57:45 +01:00
Dalai Felinto
60aa0b5b15 Reworked logic of iterators
otherwise I could not get different iterators based on a flag (SELECT), which is used everywhere in object_relations.c
The alternative would be to split every function in object_relations.c into _all, and _selected
2016-12-19 17:57:05 +01:00
Dalai Felinto
f59b6ff410 Using an iterator to go over objects, and use this for library_query
This is not the ideal iterator (it loops over the scene collection tree 3x).
One solution (I want to discuss with Bastien Montagne @mont29) is whether to store the *parent of a SceneCollection to help with that. That would speed things up, and cost less memory.

We do not even need to store it in the file, since it can be re-generated at read time
2016-12-19 14:11:58 +01:00
Dalai Felinto
57a5f2ef44 Iterator util function 2016-12-19 10:49:11 +01:00
Dalai Felinto
a3fd4274cf From review: curly brackets reinforcement
(even though the other related functions are not following this rule ... How I miss a code refactor dev!)
2016-12-16 16:04:47 +01:00
Dalai Felinto
0da8957bc5 From review: move nodetree syncing of layers to util function 2016-12-16 16:03:00 +01:00
Dalai Felinto
75b7a25014 From review: do_versions_after_linking skipped on undo 2016-12-16 15:53:23 +01:00
Dalai Felinto
29961ad597 From review: blo_do_versions_280_after_linking > blo_do_versions_after_linking_280 2016-12-16 15:51:17 +01:00
Dalai Felinto
3f9432b76a From review: use typedef for callbacks 2016-12-16 15:50:08 +01:00
Dalai Felinto
59fbc6db8d Merge remote-tracking branch 'origin/blender2.8' into render-layers 2016-12-16 14:46:17 +01:00
Dalai Felinto
c75e7516c3 Merge remote-tracking branch 'origin/blender2.8' into render-layers
plus manual rna fixup
2016-12-13 13:03:57 +01:00
Dalai Felinto
b7a42fe69f unittest: test cleanup 2016-12-12 13:08:58 +01:00
Dalai Felinto
3839afe03d Layers: change the API so that we can run a function on every object of the scene
use tag to make sure we call each object only once
2016-12-12 12:56:40 +01:00
Dalai Felinto
c96c3c8bbe Scene copy (full or link) working for layers
I'm using the flags in the objects instead of bases.
2016-12-12 12:12:42 +01:00
Dalai Felinto
ef6a35b0af scenelayer: unittest more granular, for debugging 2016-12-12 11:52:58 +01:00
Dalai Felinto
df8d4299a2 Unittest scene copy 2016-12-07 18:19:51 +01:00
Dalai Felinto
6fdd6f7d7c Unitest: doversion, write and read test for layers 2016-12-07 15:37:19 +01:00
Dalai Felinto
dddf38dc42 Fix new scenes should have a default renderlayer 2016-12-06 19:17:12 +01:00
Dalai Felinto
3c3c818d1b Fix all unfreed memory 2016-12-06 19:13:02 +01:00
Dalai Felinto
a2e81fa2e9 Final cleanup of read/write to have things in the right order (pure cosmetic) 2016-12-06 16:37:13 +01:00
Dalai Felinto
866b3268a5 Fix write of nested LayerCollections (and DNA cleanup) 2016-12-06 16:20:36 +01:00
Dalai Felinto
97109b654e Fix stupidest mistake (objects > filter_objects) 2016-12-06 15:57:04 +01:00
Dalai Felinto
6e6750a06a Fixing writing objects 2016-12-06 14:48:49 +01:00
Dalai Felinto
8146a4498a Fix writing nested scene collections 2016-12-06 14:16:42 +01:00
Dalai Felinto
3acb83c6f4 Use pointer for master collection
This allows this pointer to be used, otherwise the pointer is not written
2016-12-05 21:52:38 +01:00
Dalai Felinto
d0ef44218e Rename: collections > scene/layer_collections 2016-12-05 20:43:02 +01:00
Dalai Felinto
4ad8789a38 Read/Write, first take 2016-12-05 20:20:17 +01:00
Dalai Felinto
1db50e9a88 Fix objects not disappearing after unlinking collection 2016-12-05 14:58:26 +01:00
Dalai Felinto
87330b4729 RNA: layer.objects.selected
Instead of exposing the base I think this may be nicer for the API. We still need a way to change select for a layer though (expose the ObjectBase perhaps? :/)
2016-12-03 02:44:06 +01:00
Dalai Felinto
2b09fb3f30 layer.engine 2016-12-03 02:23:44 +01:00
Dalai Felinto
d085e62693 layer.objects.active 2016-12-03 02:23:44 +01:00
Dalai Felinto
89d20732a1 layer.active_collection
This one is straight from the "layers" branch. I nailed it quite nicely there, so it was simply a matter of bringing it over :)
2016-12-03 02:23:44 +01:00
Dalai Felinto
bc2321025b Shuffle code around to re-order functions 2016-12-03 02:23:43 +01:00
Dalai Felinto
52fdf5d06c layer.objects 2016-12-03 02:23:43 +01:00
Dalai Felinto
63780823a7 DNA documentation 2016-12-03 00:33:03 +01:00
Dalai Felinto
f304e2e273 BKE_collection_remove: (also first of five of the syncing functions) 2016-12-02 23:57:14 +01:00
Dalai Felinto
84d94fc06f RNA layer collections 2016-12-02 22:57:48 +01:00
Dalai Felinto
25f1e97408 Fixup for new layers 2016-12-02 22:16:14 +01:00
Dalai Felinto
d2b91a1c7c Rename CollectionBase > LayerCollection 2016-12-02 18:31:17 +01:00
Dalai Felinto
3c65f2f542 More RNA: objects, objects_filter (for SceneCollection), .new, remove 2016-12-02 17:50:53 +01:00
Dalai Felinto
b4799b23ec RNA (start), and some refactor (scene.main_collection)
Instead of storing a libstbase in scene, we simply store a collection, the api (RNA) is much more clear now
2016-12-02 16:29:10 +01:00
Dalai Felinto
91d7c345d4 Rename Collection > SceneCollection
We may want to re-use part of this struct (or concept) for groups and armatures. But filter is something specific to SceneCollections, so may as well keep it in a separate struct, and re-evaluate that once/if we get to it.
2016-12-02 12:43:08 +01:00
Dalai Felinto
bc66ca246c DNA fixups 2016-12-02 11:33:43 +01:00
Dalai Felinto
477fc97bd5 Renaming RenderLayer > SceneLayer
RenderLayer was the struct for RenderResult, better not to clash namespace here. For the Python API we still stick to scene.render_layers
2016-12-01 19:13:40 +01:00
Dalai Felinto
58acb05061 Add description for the functions 2016-11-30 13:04:09 +01:00
Dalai Felinto
cb11ab9b09 More versioning, and more DNA 2016-11-30 12:39:55 +01:00
Dalai Felinto
8d55fe9899 Start of versioning and more work 2016-11-29 18:24:00 +01:00
Dalai Felinto
dc3154b29f New DNA for layers 2016-11-29 15:23:26 +01:00
Dalai Felinto
34520c0ffc Barebones for dna files 2016-11-29 15:15:51 +01:00
179 changed files with 12541 additions and 2446 deletions

View File

@@ -242,6 +242,8 @@ endif()
option(WITH_PLAYER "Build Player" OFF)
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
option(WITH_CLAY_ENGINE "Enable New Clay engine (Breaks Mac and Intel compatibility)" ON)
# Compositor
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)

View File

@@ -566,6 +566,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
bf_editor_space_userpref
bf_editor_space_view3d
bf_editor_space_clip
bf_editor_space_collections
bf_editor_transform
bf_editor_util
@@ -597,6 +598,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
bf_modifiers
bf_bmesh
bf_gpu
bf_draw
bf_blenloader
bf_blenkernel
bf_physics

View File

@@ -103,9 +103,9 @@ def add_object_align_init(context, operator):
return location * rotation
def object_data_add(context, obdata, operator=None, use_active_layer=True, name=None):
def object_data_add(context, obdata, operator=None, name=None):
"""
Add an object using the view context and preference to to initialize the
Add an object using the view context and preference to initialize the
location, rotation and layer.
:arg context: The context to use.
@@ -117,52 +117,24 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
:arg name: Optional name
:type name: string
:return: the newly created object in the scene.
:rtype: :class:`bpy.types.ObjectBase`
:rtype: :class:`bpy.types.Object`
"""
scene = context.scene
layer = context.render_layer
scene_collection = context.scene_collection
# ugh, could be made nicer
for ob in scene.objects:
ob.select = False
bpy.ops.object.select_all(action='DESELECT')
if name is None:
name = "Object" if obdata is None else obdata.name
obj_new = bpy.data.objects.new(name, obdata)
base = scene.objects.link(obj_new)
base.select = True
v3d = None
if context.space_data and context.space_data.type == 'VIEW_3D':
v3d = context.space_data
if v3d and v3d.local_view:
base.layers_from_view(context.space_data)
if operator is not None and any(operator.layers):
base.layers = operator.layers
else:
if use_active_layer:
if v3d and v3d.local_view:
base.layers[scene.active_layer] = True
else:
if v3d and not v3d.lock_camera_and_layers:
base.layers = [True if i == v3d.active_layer
else False for i in range(len(v3d.layers))]
else:
base.layers = [True if i == scene.active_layer
else False for i in range(len(scene.layers))]
else:
if v3d:
base.layers_from_view(context.space_data)
if operator is not None:
operator.layers = base.layers
scene_collection.objects.link(obj_new)
obj_new.select_set(action='SELECT')
obj_new.matrix_world = add_object_align_init(context, operator)
obj_act = scene.objects.active
obj_act = layer.objects.active
# XXX
# caused because entering edit-mode does not add a empty undo slot!
@@ -174,8 +146,8 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
_obdata = bpy.data.meshes.new(name)
obj_act = bpy.data.objects.new(_obdata.name, _obdata)
obj_act.matrix_world = obj_new.matrix_world
scene.objects.link(obj_act)
scene.objects.active = obj_act
scene_collection.objects.link(obj_act)
layer.objects.active = obj_act
bpy.ops.object.mode_set(mode='EDIT')
# need empty undo step
bpy.ops.ed.undo_push(message="Enter Editmode")
@@ -185,7 +157,7 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
obj_act.select = True
obj_act.select_set(action='SELECT')
scene.update() # apply location
# scene.objects.active = obj_new
@@ -200,16 +172,14 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
bpy.ops.object.join() # join into the active.
if obdata:
bpy.data.meshes.remove(obdata)
# base is freed, set to active object
base = scene.object_bases.active
bpy.ops.object.mode_set(mode='EDIT')
else:
scene.objects.active = obj_new
layer.objects.active = obj_new
if context.user_preferences.edit.use_enter_edit_mode:
bpy.ops.object.mode_set(mode='EDIT')
return base
return obj_new
class AddObjectHelper:
@@ -230,12 +200,6 @@ class AddObjectHelper:
name="Rotation",
subtype='EULER',
)
layers = BoolVectorProperty(
name="Layers",
size=20,
subtype='LAYER',
options={'HIDDEN', 'SKIP_SAVE'},
)
@classmethod
def poll(self, context):

View File

@@ -330,7 +330,6 @@ kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', shift=True)
kmi.properties.unselected = True
kmi = km.keymap_items.new('object.hide_render_clear', 'H', 'PRESS', ctrl=True, alt=True)
kmi = km.keymap_items.new('object.hide_render_set', 'H', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS')
kmi = km.keymap_items.new('object.delete', 'X', 'PRESS')
kmi.properties.use_global = False
kmi = km.keymap_items.new('object.delete', 'X', 'PRESS', shift=True)

View File

@@ -384,7 +384,6 @@ kmi = km.keymap_items.new('object.hide_view_clear', 'H', 'PRESS', shift=True, ct
kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', alt=True)
kmi.properties.unselected = True
kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS')
kmi = km.keymap_items.new('object.delete', 'BACK_SPACE', 'PRESS')
kmi = km.keymap_items.new('object.delete', 'DEL', 'PRESS')
kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)

View File

@@ -232,7 +232,7 @@ class CLIP_OT_track_to_empty(Operator):
ob = None
ob = bpy.data.objects.new(name=track.name, object_data=None)
ob.select = True
ob.select_set(action='SELECT')
context.scene.objects.link(ob)
context.scene.objects.active = ob
@@ -506,7 +506,7 @@ object's movement caused by this constraint"""
# XXX, should probably use context.selected_editable_objects
# since selected objects can be from a lib or in hidden layer!
for ob in scene.objects:
if ob.select:
if ob.select_set(action='SELECT'):
self._bake_object(scene, ob)
return {'FINISHED'}

View File

@@ -74,7 +74,7 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
self.report({'ERROR'}, "Unexpected modifier type: " + m.type)
return {'CANCELLED'}
# Find selected mesh objects
selection = [ob for ob in scene.objects if ob.select and ob.type == 'MESH' and ob.name != source.name]
selection = [ob for ob in scene.objects if ob.select_get() and ob.type == 'MESH' and ob.name != source.name]
if selection:
# Compute the min/max distance between selected mesh objects and the source
min_dist = sys.float_info.max

View File

@@ -81,16 +81,18 @@ class SelectPattern(Operator):
# Can be pose bones or objects
for item in items:
if pattern_match(item.name, self.pattern):
item.select = True
# hrmf, perhaps there should be a utility function for this.
if is_ebone:
item.select = True
item.select_head = True
item.select_tail = True
if item.use_connect:
item_parent = item.parent
if item_parent is not None:
item_parent.select_tail = True
else:
item.select_set(action='SELECT')
return {'FINISHED'}
@@ -136,7 +138,7 @@ class SelectCamera(Operator):
bpy.ops.object.select_all(action='DESELECT')
scene.objects.active = camera
camera.hide = False
camera.select = True
camera.select_set(action='SELECT')
return {'FINISHED'}
return {'CANCELLED'}
@@ -202,7 +204,7 @@ class SelectHierarchy(Operator):
bpy.ops.object.select_all(action='DESELECT')
for obj in select_new:
obj.select = True
obj.select_set(action='SELECT')
scene.objects.active = act_new
return {'FINISHED'}
@@ -644,8 +646,8 @@ class MakeDupliFace(Operator):
ob_new.use_dupli_faces_scale = True
ob_new.dupli_faces_scale = 1.0 / SCALE_FAC
ob_inst.select = True
ob_new.select = True
ob_inst.select_set(action='SELECT')
ob_new.select_set(action='SELECT')
def execute(self, context):
self._main(context)
@@ -664,7 +666,7 @@ class IsolateTypeRender(Operator):
for obj in context.visible_objects:
if obj.select:
if obj.select_get():
obj.hide_render = False
else:
if obj.type == act_type:
@@ -1029,8 +1031,8 @@ class LodGenerate(Operator):
for level in ob.lod_levels[1:]:
level.object.hide = level.object.hide_render = True
lod.select = False
ob.select = True
lod.select_set(action='DESELECT')
ob.select_set(action='SELECT')
scene.objects.active = ob
return {'FINISHED'}

View File

@@ -63,7 +63,7 @@ class CopyRigidbodySettings(Operator):
# deselect all but mesh objects
for o in context.selected_objects:
if o.type != 'MESH':
o.select = False
o.select_set(action='DESELECT')
elif o.rigid_body is None:
# Add rigidbody to object!
scene.objects.active = o
@@ -125,7 +125,7 @@ class BakeToKeyframes(Operator):
# filter objects selection
for obj in context.selected_objects:
if not obj.rigid_body or obj.rigid_body.type != 'ACTIVE':
obj.select = False
obj.select_set(action='DESELECT')
objects = context.selected_objects
@@ -258,7 +258,7 @@ class ConnectRigidBodies(Operator):
ob.location = loc
context.scene.objects.link(ob)
context.scene.objects.active = ob
ob.select = True
ob.select_set(action='SELECT')
bpy.ops.rigidbody.constraint_add()
con_obj = context.active_object
@@ -303,7 +303,7 @@ class ConnectRigidBodies(Operator):
# restore selection
bpy.ops.object.select_all(action='DESELECT')
for obj in objects:
obj.select = True
obj.select_set(action='SELECT')
scene.objects.active = obj_act
return {'FINISHED'}
else:

View File

@@ -29,6 +29,7 @@ if "bpy" in locals():
_modules = [
"properties_animviz",
"properties_collection",
"properties_constraint",
"properties_data_armature",
"properties_data_bone",
@@ -69,6 +70,7 @@ _modules = [
"space_graph",
"space_image",
"space_info",
"space_collections",
"space_logic",
"space_nla",
"space_node",

View File

@@ -0,0 +1,128 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
import bpy
from bpy.types import Panel, UIList
class CollectionButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "collection"
class COLLECTION_PT_context_collection(CollectionButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
def draw(self, context):
layout = self.layout
space = context.space_data
collection = context.layer_collection
name = collection.name
if name == 'Master Collection':
layout.label(text=name, icon='COLLAPSEMENU')
else:
layout.prop(collection, "name", text="", icon='COLLAPSEMENU')
class COLLECTION_UL_objects(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.Object)
ob = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(ob.name, icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
class COLLECTION_PT_objects(CollectionButtonsPanel, Panel):
bl_label = "Objects"
def draw(self, context):
layout = self.layout
scene = context.scene
collection = context.scene_collection
row = layout.row()
row.template_list("COLLECTION_UL_objects", "name", collection, "objects", collection.objects, "active_index", rows=2)
col = row.column(align=True)
col.operator("collections.objects_add", icon='ZOOMIN', text="")
col.operator("collections.objects_remove", icon='ZOOMOUT', text="")
row = layout.row(align=True)
row.operator("collections.objects_select", text="Select")
row.operator("collections.objects_deselect", text="Deselect")
def template_engine_settings(col, settings, name, use_icon_view=False):
icons = {
False: 'ZOOMIN',
True: 'X',
}
use_name = "{0}_use".format(name)
use = getattr(settings, use_name)
row = col.row()
col = row.column()
col.active = use
if use_icon_view:
col.template_icon_view(settings, name)
else:
col.prop(settings, name)
row.prop(settings, "{}_use".format(name), text="", icon=icons[use], emboss=False)
class COLLECTION_PT_clay_settings(CollectionButtonsPanel, Panel):
bl_label = "Render Settings"
COMPAT_ENGINES = {'BLENDER_CLAY'}
@classmethod
def poll(cls, context):
scene = context.scene
return scene and (scene.render.engine in cls.COMPAT_ENGINES)
def draw(self, context):
layout = self.layout
collection = context.layer_collection
settings = collection.get_engine_settings()
col = layout.column()
template_engine_settings(col, settings, "type")
template_engine_settings(col, settings, "matcap_icon", use_icon_view=True)
template_engine_settings(col, settings, "matcap_rotation")
template_engine_settings(col, settings, "matcap_hue")
template_engine_settings(col, settings, "matcap_saturation")
template_engine_settings(col, settings, "matcap_value")
template_engine_settings(col, settings, "ssao_factor_cavity")
template_engine_settings(col, settings, "ssao_factor_edge")
template_engine_settings(col, settings, "ssao_distance")
template_engine_settings(col, settings, "ssao_attenuation")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

View File

@@ -106,7 +106,7 @@ class MaterialButtonsPanel:
class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY'}
@classmethod
def poll(cls, context):
@@ -1052,5 +1052,25 @@ class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel):
_context_path = "material"
_property_type = bpy.types.Material
class MATERIAL_PT_clay_settings(MaterialButtonsPanel, Panel):
bl_label = "Matcap"
COMPAT_ENGINES = {'BLENDER_CLAY'}
def draw(self, context):
layout = self.layout;
settings = context.material.clay_settings
# layout.template_icon_view(settings, "matcap_icon")
# layout.prop(settings, "type")
# layout.prop(settings, "matcap_rotation")
# layout.prop(settings, "matcap_hue")
# layout.prop(settings, "matcap_saturation")
# layout.prop(settings, "matcap_value")
# layout.prop(settings, "ssao_factor_cavity")
# layout.prop(settings, "ssao_factor_edge")
# layout.prop(settings, "ssao_distance")
# layout.prop(settings, "ssao_attenuation")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

View File

@@ -584,5 +584,24 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
sub.prop(rd, "bake_user_scale", text="User Scale")
class RENDER_PT_clay(RenderButtonsPanel, Panel):
bl_label = "Default Clay"
COMPAT_ENGINES = {'BLENDER_CLAY'}
def draw(self, context):
layout = self.layout;
settings = context.scene.active_engine_settings
layout.template_icon_view(settings, "matcap_icon")
layout.prop(settings, "matcap_rotation")
layout.prop(settings, "matcap_hue")
layout.prop(settings, "matcap_saturation")
layout.prop(settings, "matcap_value")
layout.prop(settings, "ssao_factor_cavity")
layout.prop(settings, "ssao_factor_edge")
layout.prop(settings, "ssao_distance")
layout.prop(settings, "ssao_attenuation")
layout.prop(settings, "ssao_samples")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

View File

@@ -35,7 +35,7 @@ class RenderLayerButtonsPanel:
class RENDERLAYER_UL_renderlayers(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.SceneRenderLayer)
# assert(isinstance(item, bpy.types.SceneLayer)
layer = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(layer, "name", text="", icon_value=icon, emboss=False)
@@ -48,7 +48,7 @@ class RENDERLAYER_UL_renderlayers(UIList):
class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
bl_label = "Layer List"
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY'}
def draw(self, context):
layout = self.layout
@@ -62,7 +62,7 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
row = layout.row()
col = row.column()
col.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
col.template_list("RENDERLAYER_UL_renderlayers", "", scene, "render_layers", scene.render_layers, "active_index", rows=2)
col = row.column()
sub = col.column(align=True)
@@ -71,103 +71,6 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
col.prop(rd, "use_single_layer", icon_only=True)
class RENDERLAYER_PT_layer_options(RenderLayerButtonsPanel, Panel):
bl_label = "Layer"
COMPAT_ENGINES = {'BLENDER_RENDER'}
def draw(self, context):
layout = self.layout
scene = context.scene
rd = scene.render
rl = rd.layers.active
split = layout.split()
col = split.column()
col.prop(scene, "layers", text="Scene")
col.label(text="")
col.prop(rl, "light_override", text="Lights")
col.prop(rl, "material_override", text="Material")
col = split.column()
col.prop(rl, "layers", text="Layer")
col.prop(rl, "layers_zmask", text="Mask Layer")
layout.separator()
layout.label(text="Include:")
split = layout.split()
col = split.column()
col.prop(rl, "use_zmask")
row = col.row()
row.prop(rl, "invert_zmask", text="Negate")
row.active = rl.use_zmask
col.prop(rl, "use_all_z")
col = split.column()
col.prop(rl, "use_solid")
col.prop(rl, "use_halo")
col.prop(rl, "use_ztransp")
col = split.column()
col.prop(rl, "use_sky")
col.prop(rl, "use_edge_enhance")
col.prop(rl, "use_strand")
if bpy.app.build_options.freestyle:
row = col.row()
row.prop(rl, "use_freestyle")
row.active = rd.use_freestyle
class RENDERLAYER_PT_layer_passes(RenderLayerButtonsPanel, Panel):
bl_label = "Passes"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@staticmethod
def draw_pass_type_buttons(box, rl, pass_type):
# property names
use_pass_type = "use_pass_" + pass_type
exclude_pass_type = "exclude_" + pass_type
# draw pass type buttons
row = box.row()
row.prop(rl, use_pass_type)
row.prop(rl, exclude_pass_type, text="")
def draw(self, context):
layout = self.layout
scene = context.scene
rd = scene.render
rl = rd.layers.active
split = layout.split()
col = split.column()
col.prop(rl, "use_pass_combined")
col.prop(rl, "use_pass_z")
col.prop(rl, "use_pass_vector")
col.prop(rl, "use_pass_normal")
col.prop(rl, "use_pass_uv")
col.prop(rl, "use_pass_mist")
col.prop(rl, "use_pass_object_index")
col.prop(rl, "use_pass_material_index")
col.prop(rl, "use_pass_color")
col = split.column()
col.prop(rl, "use_pass_diffuse")
self.draw_pass_type_buttons(col, rl, "specular")
self.draw_pass_type_buttons(col, rl, "shadow")
self.draw_pass_type_buttons(col, rl, "emit")
self.draw_pass_type_buttons(col, rl, "ambient_occlusion")
self.draw_pass_type_buttons(col, rl, "environment")
self.draw_pass_type_buttons(col, rl, "indirect")
self.draw_pass_type_buttons(col, rl, "reflection")
self.draw_pass_type_buttons(col, rl, "refraction")
class RENDERLAYER_UL_renderviews(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.SceneRenderView)

View File

@@ -0,0 +1,41 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
import bpy
from bpy.types import Header, Menu
class COLLECTIONS_HT_header(Header):
bl_space_type = 'COLLECTION_MANAGER'
def draw(self, context):
layout = self.layout
layout.template_header()
row = layout.row(align=True)
row.operator("collections.collection_new", text="", icon='NEW')
row.operator("collections.override_new", text="", icon='LINK_AREA')
row.operator("collections.collection_link", text="", icon='LINKED')
row.operator("collections.collection_unlink", text="", icon='UNLINKED')
row.operator("collections.delete", text="", icon='X')
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

View File

@@ -634,7 +634,6 @@ class VIEW3D_MT_select_object(Menu):
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
layout.operator("object.select_random", text="Random")
layout.operator("object.select_mirror", text="Mirror")
layout.operator("object.select_by_layer", text="Select All by Layer")
layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...")
layout.operator("object.select_camera", text="Select Camera")
@@ -1311,15 +1310,6 @@ class VIEW3D_MT_object(Menu):
layout.separator()
if is_local_view:
layout.operator_context = 'EXEC_REGION_WIN'
layout.operator("object.move_to_layer", text="Move out of Local View")
layout.operator_context = 'INVOKE_REGION_WIN'
else:
layout.operator("object.move_to_layer", text="Move to Layer...")
layout.menu("VIEW3D_MT_object_showhide")
layout.operator_menu_enum("object.convert", "target")
@@ -1597,17 +1587,6 @@ class VIEW3D_MT_object_quick_effects(Menu):
layout.operator("object.quick_fluid")
class VIEW3D_MT_object_showhide(Menu):
bl_label = "Show/Hide"
def draw(self, context):
layout = self.layout
layout.operator("object.hide_view_clear", text="Show Hidden")
layout.operator("object.hide_view_set", text="Hide Selected").unselected = False
layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True
class VIEW3D_MT_make_single_user(Menu):
bl_label = "Make Single User"
@@ -3167,6 +3146,72 @@ class VIEW3D_PT_viewport_debug(Panel):
col.row(align=True).prop(view, "debug_background", expand=True)
class VIEW3D_PT_collections_editor(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Collections"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return context.space_data
def draw(self, context):
layout = self.layout
layer = context.render_layer
active_collection = context.layer_collection
col = layout.column()
box = col.box()
index = -1
for collection in layer.collections:
index = self._draw_layer_collection(box, index, active_collection, collection, True, True)
row = layout.row(align=True)
row.operator("collections.collection_new", text="", icon='NEW')
row.operator("collections.override_new", text="", icon='LINK_AREA')
row.operator("collections.collection_link", text="", icon='LINKED')
row.operator("collections.collection_unlink", text="", icon='UNLINKED')
row.operator("collections.delete", text="", icon='X')
def _draw_layer_collection(self, box, index, active_collection, collection, is_active, is_draw, depth=0):
index += 1
nested_collections = collection.collections
if is_draw:
row = box.row()
row.active = is_active
is_collection_selected = (collection == active_collection)
if is_collection_selected:
sub_box = row.box()
row = sub_box.row()
row.label(text="{0}{1}{2}".format(
" " * depth,
u'\u21b3 ' if depth else "",
collection.name))
row.prop(collection, "hide", text="", emboss=False)
row.operator("collections.select", text="", icon='BLANK1' if is_collection_selected else 'HAND', emboss=False).collection_index=index
if nested_collections:
row.prop(collection, "is_unfolded", text="", emboss=False)
else:
row.label(icon='BLANK1')
if not collection.is_unfolded:
is_draw = False
is_active &= not collection.hide
for nested_collection in nested_collections:
index = self._draw_layer_collection(box, index, active_collection, nested_collection, is_active, is_draw, depth + 1)
return index
class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'

View File

@@ -18,7 +18,7 @@ bpy.ops.object.select_all(action='DESELECT')
for obj in selection:
obj.select = True
obj.select_set(action='SELECT')
# some exporters only use the active object
scene.objects.active = obj
@@ -31,7 +31,7 @@ for obj in selection:
## Can be used for multiple formats
# bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
obj.select = False
obj.select_set(action='DESELECT')
print("written:", fn)
@@ -39,4 +39,4 @@ for obj in selection:
scene.objects.active = obj_active
for obj in selection:
obj.select = True
obj.select_set(action='SELECT')

View File

@@ -67,7 +67,7 @@ def main(context, event):
# now we have the object under the mouse cursor,
# we could do lots of stuff but for the example just select.
if best_obj is not None:
best_obj.select = True
best_obj.select_set(action='SELECT')
context.scene.objects.active = best_obj

View File

@@ -100,6 +100,7 @@ add_subdirectory(windowmanager)
add_subdirectory(blenkernel)
add_subdirectory(blenlib)
add_subdirectory(bmesh)
add_subdirectory(draw)
add_subdirectory(render)
add_subdirectory(blenfont)
add_subdirectory(blentranslation)

View File

@@ -0,0 +1,91 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Dalai Felinto
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __BKE_COLLECTION_H__
#define __BKE_COLLECTION_H__
/** \file blender/blenkernel/BKE_collection.h
* \ingroup bke
*/
#include "BLI_ghash.h"
#include "BLI_iterator.h"
#include "DNA_listBase.h"
#ifdef __cplusplus
extern "C" {
#endif
struct Iterator;
struct SceneCollection;
struct Object;
struct ObjectBase;
struct Main;
struct Scene;
struct SceneCollection *BKE_collection_add(struct Scene *scene, struct SceneCollection *sc_parent, const char *name);
bool BKE_collection_remove(struct Scene *scene, struct SceneCollection *sc);
struct SceneCollection *BKE_collection_master(struct Scene *scene);
void BKE_collection_master_free(struct Scene *scene);
void BKE_collection_object_add(struct Scene *scene, struct SceneCollection *sc, struct Object *object);
void BKE_collection_object_add_from(struct Scene *scene, struct Object *ob_src, struct Object *ob_dst);
void BKE_collection_object_remove(struct Main *bmain, struct Scene *scene, struct SceneCollection *sc, struct Object *object, const bool free_us);
void BKE_collections_object_remove(struct Main *bmain, struct Scene *scene, struct Object *object, const bool free_us);
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
typedef void (*BKE_scene_collections_Cb)(struct SceneCollection *ob, void *data);
void BKE_scene_collections_callback(struct Scene *scene, BKE_scene_collections_Cb callback, void *data);
void BKE_scene_objects_callback(struct Scene *scene, BKE_scene_objects_Cb callback, void *data);
/* iterators */
void BKE_scene_collections_Iterator_begin(struct Iterator *iter, void *data_in);
void BKE_scene_collections_Iterator_next(struct Iterator *iter);
void BKE_scene_collections_Iterator_end(struct Iterator *iter);
void BKE_scene_objects_Iterator_begin(struct Iterator *iter, void *data_in);
void BKE_scene_objects_Iterator_next(struct Iterator *iter);
void BKE_scene_objects_Iterator_end(struct Iterator *iter);
#define FOREACH_SCENE_COLLECTION(scene, _sc) \
ITER_BEGIN(BKE_scene_collections_Iterator_begin, \
BKE_scene_collections_Iterator_next, \
BKE_scene_collections_Iterator_end, \
scene, _sc)
#define FOREACH_SCENE_COLLECTION_END \
ITER_END
#define FOREACH_SCENE_OBJECT(scene, _ob) \
ITER_BEGIN(BKE_scene_objects_Iterator_begin, \
BKE_scene_objects_Iterator_next, \
BKE_scene_objects_Iterator_end, \
scene, _ob)
#define FOREACH_SCENE_OBJECT_END \
ITER_END
#ifdef __cplusplus
}
#endif
#endif /* __BKE_COLLECTION_H__ */

View File

@@ -40,12 +40,16 @@ extern "C" {
struct ARegion;
struct bScreen;
struct CacheFile;
struct LayerCollection;
struct ListBase;
struct Main;
struct Object;
struct ObjectBase;
struct PointerRNA;
struct ReportList;
struct Scene;
struct SceneCollection;
struct SceneLayer;
struct ScrArea;
struct SpaceLink;
struct View3D;
@@ -166,6 +170,7 @@ struct SpaceAction *CTX_wm_space_action(const bContext *C);
struct SpaceInfo *CTX_wm_space_info(const bContext *C);
struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C);
struct SpaceClip *CTX_wm_space_clip(const bContext *C);
struct SpaceCollections *CTX_wm_space_collections(const bContext *C);
void CTX_wm_manager_set(bContext *C, struct wmWindowManager *wm);
void CTX_wm_window_set(bContext *C, struct wmWindow *win);
@@ -239,6 +244,9 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
struct Main *CTX_data_main(const bContext *C);
struct Scene *CTX_data_scene(const bContext *C);
struct LayerCollection *CTX_data_layer_collection(const bContext *C);
struct SceneCollection *CTX_data_scene_collection(const bContext *C);
struct SceneLayer *CTX_data_scene_layer(const bContext *C);
struct ToolSettings *CTX_data_tool_settings(const bContext *C);
const char *CTX_data_mode_string(const bContext *C);
@@ -263,7 +271,7 @@ int CTX_data_selectable_objects(const bContext *C, ListBase *list);
int CTX_data_selectable_bases(const bContext *C, ListBase *list);
struct Object *CTX_data_active_object(const bContext *C);
struct Base *CTX_data_active_base(const bContext *C);
struct ObjectBase *CTX_data_active_base(const bContext *C);
struct Object *CTX_data_edit_object(const bContext *C);
struct Image *CTX_data_edit_image(const bContext *C);

View File

@@ -34,6 +34,7 @@
*/
struct Base;
struct ObjectBase;
struct EvaluationContext;
struct Group;
struct Main;
@@ -44,8 +45,8 @@ void BKE_group_free(struct Group *group);
struct Group *BKE_group_add(struct Main *bmain, const char *name);
struct Group *BKE_group_copy(struct Main *bmain, struct Group *group);
void BKE_group_make_local(struct Main *bmain, struct Group *group, const bool lib_local);
bool BKE_group_object_add(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
bool BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
bool BKE_group_object_add(struct Group *group, struct Object *ob);
bool BKE_group_object_unlink(struct Group *group, struct Object *ob);
struct Group *BKE_group_object_find(struct Group *group, struct Object *ob);
bool BKE_group_object_exists(struct Group *group, struct Object *ob);
bool BKE_group_object_cyclic_check(struct Main *bmain, struct Object *object, struct Group *group);

View File

@@ -0,0 +1,217 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Dalai Felinto
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __BKE_LAYER_H__
#define __BKE_LAYER_H__
/** \file blender/blenkernel/BKE_layer.h
* \ingroup bke
*/
#include "BKE_collection.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TODO_LAYER_SYNC /* syncing of SceneCollection and LayerCollection trees*/
#define TODO_LAYER_SYNC_FILTER /* syncing of filter_objects across all trees */
#define TODO_LAYER_OVERRIDE /* CollectionOverride */
#define TODO_LAYER_CONTEXT /* get/set current (context) SceneLayer */
#define TODO_LAYER_BASE /* Base to ObjectBase related TODO */
#define TODO_LAYER_OPERATORS /* collection mamanger and property panel operators */
#define TODO_LAYER_DEPSGRAPH /* placeholder for real Depsgraph fix */
#define TODO_LAYER /* generic todo */
struct CollectionEngineSettings;
struct LayerCollection;
struct ID;
struct ListBase;
struct Main;
struct Object;
struct ObjectBase;
struct RenderEngine;
struct Scene;
struct SceneCollection;
struct SceneLayer;
struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name);
bool BKE_scene_layer_remove(struct Main *bmain, struct Scene *scene, struct SceneLayer *sl);
void BKE_scene_layer_free(struct SceneLayer *sl);
void BKE_scene_layer_engine_set(struct SceneLayer *sl, const char *engine);
void BKE_scene_layer_selected_objects_tag(struct SceneLayer *sl, const int tag);
struct SceneLayer *BKE_scene_layer_find_from_collection(struct Scene *scene, struct LayerCollection *lc);
struct ObjectBase *BKE_scene_layer_base_find(struct SceneLayer *sl, struct Object *ob);
void BKE_scene_layer_base_deselect_all(struct SceneLayer *sl);
void BKE_scene_layer_base_select(struct SceneLayer *sl, struct ObjectBase *selbase);
void BKE_scene_layer_base_flag_recalculate(struct SceneLayer *sl);
void BKE_scene_layer_engine_settings_recalculate(struct SceneLayer *sl);
void BKE_scene_layer_engine_settings_update(struct SceneLayer *sl);
void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc);
struct LayerCollection *BKE_layer_collection_active(struct SceneLayer *sl);
int BKE_layer_collection_count(struct SceneLayer *sl);
int BKE_layer_collection_findindex(struct SceneLayer *sl, struct LayerCollection *lc);
struct LayerCollection *BKE_collection_link(struct SceneLayer *sl, struct SceneCollection *sc);
void BKE_collection_unlink(struct SceneLayer *sl, struct LayerCollection *lc);
bool BKE_scene_layer_has_collection(struct SceneLayer *sl, struct SceneCollection *sc);
bool BKE_scene_has_object(struct Scene *scene, struct Object *ob);
/* syncing */
void BKE_layer_sync_new_scene_collection(struct Scene *scene, const struct SceneCollection *sc_parent, struct SceneCollection *sc);
void BKE_layer_sync_object_link(struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
void BKE_layer_sync_object_unlink(struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
/* override */
void BKE_collection_override_datablock_add(struct LayerCollection *lc, const char *data_path, struct ID *id);
/* engine settings */
typedef void (*CollectionEngineSettingsCB)(struct RenderEngine *engine, struct CollectionEngineSettings *ces);
struct CollectionEngineSettings *BKE_layer_collection_engine_get(struct LayerCollection *lc, const char *engine_name);
void BKE_layer_collection_engine_settings_callback_register(struct Main *bmain, const char *engine_name, CollectionEngineSettingsCB func);
void BKE_layer_collection_engine_settings_callback_free(void);
void BKE_layer_collection_engine_settings_create(struct ListBase *lb, const char *engine_name);
void BKE_layer_collection_engine_settings_free(struct ListBase *lb);
void BKE_collection_engine_property_add_float(struct CollectionEngineSettings *ces, const char *name, float value);
void BKE_collection_engine_property_add_int(struct CollectionEngineSettings *ces, const char *name, int value);
struct CollectionEngineProperty *BKE_collection_engine_property_get(struct CollectionEngineSettings *ces, const char *name);
int BKE_collection_engine_property_value_get_int(struct CollectionEngineSettings *ces, const char *name);
float BKE_collection_engine_property_value_get_float(struct CollectionEngineSettings *ces, const char *name);
void BKE_collection_engine_property_value_set_int(struct CollectionEngineSettings *ces, const char *name, int value);
void BKE_collection_engine_property_value_set_float(struct CollectionEngineSettings *ces, const char *name, float value);
bool BKE_collection_engine_property_use_get(struct CollectionEngineSettings *ces, const char *name);
void BKE_collection_engine_property_use_set(struct CollectionEngineSettings *ces, const char *name, bool value);
/* iterators */
void BKE_selected_objects_Iterator_begin(Iterator *iter, void *data_in);
void BKE_selected_objects_Iterator_next(Iterator *iter);
void BKE_selected_objects_Iterator_end(Iterator *iter);
void BKE_visible_objects_Iterator_begin(Iterator *iter, void *data_in);
void BKE_visible_objects_Iterator_next(Iterator *iter);
void BKE_visible_objects_Iterator_end(Iterator *iter);
void BKE_visible_bases_Iterator_begin(Iterator *iter, void *data_in);
void BKE_visible_bases_Iterator_next(Iterator *iter);
void BKE_visible_bases_Iterator_end(Iterator *iter);
#define FOREACH_SELECTED_OBJECT(sl, _ob) \
ITER_BEGIN(BKE_selected_objects_Iterator_begin, \
BKE_selected_objects_Iterator_next, \
BKE_selected_objects_Iterator_end, \
sl, _ob)
#define FOREACH_SELECTED_OBJECT_END \
ITER_END
#define FOREACH_VISIBLE_OBJECT(sl, _ob) \
ITER_BEGIN(BKE_visible_objects_Iterator_begin, \
BKE_visible_objects_Iterator_next, \
BKE_visible_objects_Iterator_end, \
sl, _ob)
#define FOREACH_VISIBLE_OBJECT_END \
ITER_END
#define FOREACH_VISIBLE_BASE(sl, _object_base) \
ITER_BEGIN(BKE_visible_bases_Iterator_begin, \
BKE_visible_bases_Iterator_next, \
BKE_visible_bases_Iterator_end, \
sl, _object_base)
#define FOREACH_VISIBLE_BASE_END \
ITER_END
#define FOREACH_OBJECT(sl, _ob) \
{ \
ObjectBase *base; \
for (base = sl->object_bases.first; base; base = base->next) { \
_ob = base->object;
#define FOREACH_OBJECT_END \
} \
}
#define FOREACH_OBJECT_FLAG(scene, sl, flag, _ob) \
{ \
IteratorBeginCb func_begin; \
IteratorCb func_next, func_end; \
void *data_in; \
\
if (flag == SELECT) { \
func_begin = &BKE_selected_objects_Iterator_begin; \
func_next = &BKE_selected_objects_Iterator_next; \
func_end = &BKE_selected_objects_Iterator_end; \
data_in = sl; \
} \
else { \
func_begin = BKE_scene_objects_Iterator_begin; \
func_next = BKE_scene_objects_Iterator_next; \
func_end = BKE_scene_objects_Iterator_end; \
data_in = scene; \
} \
ITER_BEGIN(func_begin, func_next, func_end, data_in, _ob)
#define FOREACH_OBJECT_FLAG_END \
ITER_END \
}
/* temporary hacky solution waiting for final depsgraph evaluation */
#define DEG_OBJECT_ITER(sl_, ob_) \
{ \
/* temporary solution, waiting for depsgraph update */ \
BKE_scene_layer_engine_settings_update(sl); \
\
/* flush all the data to objects*/ \
ObjectBase *base_; \
for (base_ = sl->object_bases.first; base_; base_ = base_->next) { \
ob_ = base_->object; \
ob_->base_flag = base_->flag;
#define DEG_OBJECT_ITER_END \
} \
}
#ifdef __cplusplus
}
#endif
#endif /* __BKE_LAYER_H__ */

View File

@@ -687,6 +687,13 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Node Tree
*/
void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, const int layer_index);
/* -------------------------------------------------------------------- */
/** \name Shader Nodes
*/

View File

@@ -41,6 +41,7 @@ struct Scene;
struct Object;
struct BoundBox;
struct View3D;
struct SceneLayer;
struct SoftBody;
struct BulletSoftBody;
struct MovieClip;
@@ -89,9 +90,9 @@ struct Object *BKE_object_add_only_object(
int type, const char *name)
ATTR_NONNULL(1) ATTR_RETURNS_NONNULL;
struct Object *BKE_object_add(
struct Main *bmain, struct Scene *scene,
struct Main *bmain, struct Scene *scene, struct SceneLayer *sl,
int type, const char *name)
ATTR_NONNULL(1, 2) ATTR_RETURNS_NONNULL;
ATTR_NONNULL(1, 2, 3) ATTR_RETURNS_NONNULL;
void *BKE_object_obdata_add_from_type(
struct Main *bmain,
int type, const char *name)
@@ -260,7 +261,7 @@ typedef enum eObjectSet {
struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter);
struct LinkNode *BKE_object_groups(struct Object *ob);
void BKE_object_groups_clear(struct Scene *scene, struct Base *base, struct Object *object);
void BKE_object_groups_clear(struct Object *object);
struct KDTree *BKE_object_as_kdtree(struct Object *ob, int *r_tot);

View File

@@ -42,6 +42,7 @@ struct Base;
struct EvaluationContext;
struct Main;
struct Object;
struct ObjectBase;
struct QuicktimeCodecData;
struct RenderData;
struct SceneRenderLayer;
@@ -70,6 +71,8 @@ void BKE_scene_free(struct Scene *sce);
void BKE_scene_init(struct Scene *sce);
struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
void BKE_scene_remove_rigidbody_object(struct Scene *scene, struct Object *ob);
/* base functions */
struct Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
@@ -94,6 +97,10 @@ int BKE_scene_base_iter_next(struct EvaluationContext *eval_ctx, struct SceneBas
void BKE_scene_base_flag_to_objects(struct Scene *scene);
void BKE_scene_base_flag_from_objects(struct Scene *scene);
void BKE_scene_base_flag_sync_from_base(struct Base *base);
void BKE_scene_base_flag_sync_from_object(struct Base *base);
void BKE_scene_object_base_flag_sync_from_base(struct ObjectBase *base);
void BKE_scene_object_base_flag_sync_from_object(struct ObjectBase *base);
void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);

View File

@@ -85,6 +85,7 @@ set(SRC
intern/camera.c
intern/cdderivedmesh.c
intern/cloth.c
intern/collection.c
intern/collision.c
intern/colortools.c
intern/constraint.c
@@ -157,6 +158,7 @@ set(SRC
intern/pbvh_bmesh.c
intern/pointcache.c
intern/property.c
intern/layer.c
intern/report.c
intern/rigidbody.c
intern/sca.c
@@ -214,6 +216,7 @@ set(SRC
BKE_ccg.h
BKE_cdderivedmesh.h
BKE_cloth.h
BKE_collection.h
BKE_collision.h
BKE_colortools.h
BKE_constraint.h
@@ -274,6 +277,7 @@ set(SRC
BKE_pbvh.h
BKE_pointcache.h
BKE_property.h
BKE_layer.h
BKE_report.h
BKE_rigidbody.h
BKE_sca.h

View File

@@ -0,0 +1,455 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Dalai Felinto
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenkernel/intern/collection.c
* \ingroup bke
*/
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BLI_iterator.h"
#include "BLI_listbase.h"
#include "BLT_translation.h"
#include "BLI_string_utils.h"
#include "BKE_collection.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "DNA_ID.h"
#include "DNA_layer_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
/**
* Add a collection to a collection ListBase and syncronize all render layers
* The ListBase is NULL when the collection is to be added to the master collection
*/
SceneCollection *BKE_collection_add(Scene *scene, SceneCollection *sc_parent, const char *name)
{
SceneCollection *sc_master = BKE_collection_master(scene);
SceneCollection *sc = MEM_callocN(sizeof(SceneCollection), "New Collection");
if (!name) {
name = DATA_("New Collection");
}
if (!sc_parent) {
sc_parent = sc_master;
}
BLI_strncpy(sc->name, name, sizeof(sc->name));
BLI_uniquename(&sc_master->scene_collections, sc, DATA_("Collection"), '.', offsetof(SceneCollection, name), sizeof(sc->name));
BLI_addtail(&sc_parent->scene_collections, sc);
BKE_layer_sync_new_scene_collection(scene, sc_parent, sc);
return sc;
}
/**
* Free the collection items recursively
*/
static void collection_free(SceneCollection *sc)
{
for (LinkData *link = sc->objects.first; link; link = link->next) {
id_us_min(link->data);
}
BLI_freelistN(&sc->objects);
for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
id_us_min(link->data);
}
BLI_freelistN(&sc->filter_objects);
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
collection_free(nsc);
}
BLI_freelistN(&sc->scene_collections);
}
/**
* Unlink the collection recursively
* return true if unlinked
*/
static bool collection_remlink(SceneCollection *sc_parent, SceneCollection *sc_gone)
{
for (SceneCollection *sc = sc_parent->scene_collections.first; sc; sc = sc->next)
{
if (sc == sc_gone) {
BLI_remlink(&sc_parent->scene_collections, sc_gone);
return true;
}
if (collection_remlink(sc, sc_gone)) {
return true;
}
}
return false;
}
/**
* Recursively remove any instance of this SceneCollection
*/
static void layer_collection_remove(SceneLayer *sl, ListBase *lb, const SceneCollection *sc)
{
LayerCollection *lc = lb->first;
while(lc) {
if (lc->scene_collection == sc) {
BKE_layer_collection_free(sl, lc);
BLI_remlink(lb, lc);
LayerCollection *lc_next = lc->next;
MEM_freeN(lc);
lc = lc_next;
/* only the "top-level" layer collections may have the
* same SceneCollection in a sibling tree.
*/
if (lb != &sl->layer_collections) {
return;
}
}
else {
layer_collection_remove(sl, &lc->layer_collections, sc);
lc = lc->next;
}
}
}
/**
* Remove a collection from the scene, and syncronize all render layers
*/
bool BKE_collection_remove(Scene *scene, SceneCollection *sc)
{
SceneCollection *sc_master = BKE_collection_master(scene);
/* the master collection cannot be removed */
if (sc == sc_master) {
return false;
}
/* unlink from the respective collection tree */
if (!collection_remlink(sc_master, sc)) {
BLI_assert(false);
}
/* clear the collection items */
collection_free(sc);
/* check all layers that use this collection and clear them */
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
layer_collection_remove(sl, &sl->layer_collections, sc);
BKE_scene_layer_base_flag_recalculate(sl);
sl->active_collection = 0;
}
MEM_freeN(sc);
return true;
}
/**
* Returns the master collection
*/
SceneCollection *BKE_collection_master(Scene *scene)
{
return scene->collection;
}
/**
* Free (or release) any data used by the master collection (does not free the master collection itself).
* Used only to clear the entire scene data since it's not doing re-syncing of the LayerCollection tree
*/
void BKE_collection_master_free(Scene *scene){
collection_free(BKE_collection_master(scene));
}
static void collection_object_add(Scene *scene, SceneCollection *sc, Object *ob)
{
BLI_addtail(&sc->objects, BLI_genericNodeN(ob));
id_us_plus((ID *)ob);
BKE_layer_sync_object_link(scene, sc, ob);
}
/**
* Add object to collection
*/
void BKE_collection_object_add(Scene *scene, SceneCollection *sc, Object *ob)
{
if (BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) {
/* don't add the same object twice */
return;
}
collection_object_add(scene, sc, ob);
}
/**
* Add object to all collections that reference objects is in
* (used to copy objects)
*/
void BKE_collection_object_add_from(Scene *scene, Object *ob_src, Object *ob_dst)
{
SceneCollection *sc;
FOREACH_SCENE_COLLECTION(scene, sc)
{
if (BLI_findptr(&sc->objects, ob_src, offsetof(LinkData, data))) {
collection_object_add(scene, sc, ob_dst);
}
}
FOREACH_SCENE_COLLECTION_END
}
/**
* Remove object from collection
*/
void BKE_collection_object_remove(Main *bmain, Scene *scene, SceneCollection *sc, Object *ob, const bool free_us)
{
LinkData *link = BLI_findptr(&sc->objects, ob, offsetof(LinkData, data));
if (link == NULL) {
return;
}
BLI_remlink(&sc->objects, link);
MEM_freeN(link);
TODO_LAYER_SYNC_FILTER; /* need to remove all instances of ob in scene collections -> filter_objects */
BKE_layer_sync_object_unlink(scene, sc, ob);
if (free_us) {
BKE_libblock_free_us(bmain, ob);
}
else {
id_us_min(&ob->id);
}
}
/**
* Remove object from all collections of scene
*/
void BKE_collections_object_remove(Main *bmain, Scene *scene, Object *ob, const bool free_us)
{
BKE_scene_remove_rigidbody_object(scene, ob);
SceneCollection *sc;
FOREACH_SCENE_COLLECTION(scene, sc)
{
BKE_collection_object_remove(bmain, scene, sc, ob, free_us);
}
FOREACH_SCENE_COLLECTION_END
}
/* ---------------------------------------------------------------------- */
/* Iteractors */
/* scene collection iteractor */
typedef struct SceneCollectionsIteratorData {
Scene *scene;
void **array;
int tot, cur;
} SceneCollectionsIteratorData;
static void scene_collection_callback(SceneCollection *sc, BKE_scene_collections_Cb callback, void *data)
{
callback(sc, data);
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
scene_collection_callback(nsc, callback, data);
}
}
static void scene_collections_count(SceneCollection *UNUSED(sc), void *data)
{
int *tot = data;
(*tot)++;
}
static void scene_collections_build_array(SceneCollection *sc, void *data)
{
SceneCollection ***array = data;
**array = sc;
(*array)++;
}
static void scene_collections_array(Scene *scene, SceneCollection ***collections_array, int *tot)
{
SceneCollection *sc = BKE_collection_master(scene);
SceneCollection **array;
*collections_array = NULL;
*tot = 0;
if (scene == NULL)
return;
scene_collection_callback(sc, scene_collections_count, tot);
if (*tot == 0)
return;
*collections_array = array = MEM_mallocN(sizeof(SceneCollection *) * (*tot), "SceneCollectionArray");
scene_collection_callback(sc, scene_collections_build_array, &array);
}
/**
* Only use this in non-performance critical situations
* (it iterates over all scene collections twice)
*/
void BKE_scene_collections_Iterator_begin(Iterator *iter, void *data_in)
{
Scene *scene = data_in;
SceneCollectionsIteratorData *data = MEM_callocN(sizeof(SceneCollectionsIteratorData), __FUNCTION__);
data->scene = scene;
iter->data = data;
scene_collections_array(scene, (SceneCollection ***)&data->array, &data->tot);
BLI_assert(data->tot != 0);
data->cur = 0;
iter->current = data->array[data->cur];
iter->valid = true;
}
void BKE_scene_collections_Iterator_next(struct Iterator *iter)
{
SceneCollectionsIteratorData *data = iter->data;
if (++data->cur < data->tot) {
iter->current = data->array[data->cur];
}
else {
iter->valid = false;
}
}
void BKE_scene_collections_Iterator_end(struct Iterator *iter)
{
SceneCollectionsIteratorData *data = iter->data;
if (data) {
if (data->array) {
MEM_freeN(data->array);
}
MEM_freeN(data);
}
iter->valid = false;
}
/* scene objects iteractor */
typedef struct SceneObjectsIteratorData {
GSet *visited;
LinkData *link;
Iterator scene_collection_iter;
} SceneObjectsIteratorData;
void BKE_scene_objects_Iterator_begin(Iterator *iter, void *data_in)
{
Scene *scene = data_in;
SceneObjectsIteratorData *data = MEM_callocN(sizeof(SceneObjectsIteratorData), __FUNCTION__);
iter->data = data;
/* lookup list ot make sure each object is object called once */
data->visited = BLI_gset_ptr_new(__func__);
/* we wrap the scenecollection iterator here to go over the scene collections */
BKE_scene_collections_Iterator_begin(&data->scene_collection_iter, scene);
SceneCollection *sc = data->scene_collection_iter.current;
iter->current = sc->objects.first;
if (iter->current == NULL) {
BKE_scene_objects_Iterator_next(iter);
}
}
/**
* Gets the next unique object
*/
static LinkData *object_base_next(GSet *gs, LinkData *link)
{
if (link == NULL) {
return NULL;
}
LinkData *link_next = link->next;
if (link_next) {
Object *ob = link_next->data;
if (!BLI_gset_haskey(gs, ob)) {
BLI_gset_add(gs, ob);
return link_next;
}
else {
return object_base_next(gs, link_next);
}
}
return NULL;
}
void BKE_scene_objects_Iterator_next(Iterator *iter)
{
SceneObjectsIteratorData *data = iter->data;
LinkData *link = object_base_next(data->visited, data->link);
if (link) {
data->link = link;
iter->current = link->data;
}
else {
/* if this is the last object of this ListBase look at the next SceneCollection */
SceneCollection *sc;
BKE_scene_collections_Iterator_next(&data->scene_collection_iter);
do {
sc = data->scene_collection_iter.current;
/* get the first unique object of this collection */
LinkData *new_link = object_base_next(data->visited, sc->objects.first);
if (new_link) {
data->link = new_link;
iter->current = data->link->data;
return;
}
BKE_scene_collections_Iterator_next(&data->scene_collection_iter);
} while (data->scene_collection_iter.valid);
if (!data->scene_collection_iter.valid) {
iter->valid = false;
}
}
}
void BKE_scene_objects_Iterator_end(Iterator *iter)
{
SceneObjectsIteratorData *data = iter->data;
if (data) {
BKE_scene_collections_Iterator_end(&data->scene_collection_iter);
BLI_gset_free(data->visited, NULL);
MEM_freeN(data);
}
}

View File

@@ -47,6 +47,7 @@
#include "BLT_translation.h"
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_screen.h"
#include "BKE_sound.h"
@@ -814,6 +815,14 @@ struct SpaceClip *CTX_wm_space_clip(const bContext *C)
return NULL;
}
struct SpaceCollections *CTX_wm_space_collections(const bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
if (sa && sa->spacetype == SPACE_COLLECTIONS)
return sa->spacedata.first;
return NULL;
}
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
{
C->wm.manager = wm;
@@ -836,8 +845,9 @@ void CTX_wm_window_set(bContext *C, wmWindow *win)
void CTX_wm_screen_set(bContext *C, bScreen *screen)
{
C->wm.screen = screen;
if (C->wm.screen)
C->data.scene = C->wm.screen->scene;
if (C->wm.screen) {
CTX_data_scene_set(C, C->wm.screen->scene);
}
C->wm.area = NULL;
C->wm.region = NULL;
}
@@ -896,6 +906,62 @@ Scene *CTX_data_scene(const bContext *C)
return C->data.scene;
}
SceneLayer *CTX_data_scene_layer(const bContext *C)
{
SceneLayer *sl;
if (ctx_data_pointer_verify(C, "render_layer", (void *)&sl)) {
return sl;
}
else {
Scene *scene = CTX_data_scene(C);
sl = BLI_findlink(&scene->render_layers, scene->active_layer);
BLI_assert(sl);
return sl;
}
}
/**
* This is tricky. Sometimes the user overrides the render_layer
* but not the scene_collection. In this case what to do?
*
* If the scene_collection is linked to the SceneLayer we use it.
* Otherwise we fallback to the active one of the SceneLayer.
*/
LayerCollection *CTX_data_layer_collection(const bContext *C)
{
SceneLayer *sl = CTX_data_scene_layer(C);
LayerCollection *lc;
if (ctx_data_pointer_verify(C, "layer_collection", (void *)&lc)) {
if (BKE_scene_layer_has_collection(sl, lc->scene_collection)) {
return lc;
}
}
/* fallback */
return BKE_layer_collection_active(sl);
}
SceneCollection *CTX_data_scene_collection(const bContext *C)
{
SceneCollection *sc;
if (ctx_data_pointer_verify(C, "scene_collection", (void *)&sc)) {
if (BKE_scene_layer_has_collection(CTX_data_scene_layer(C), sc)) {
return sc;
}
}
LayerCollection *lc = CTX_data_layer_collection(C);
if (lc) {
return lc->scene_collection;
}
/* fallback */
Scene *scene = CTX_data_scene(C);
return BKE_collection_master(scene);
}
int CTX_data_mode_enum(const bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
@@ -1034,7 +1100,7 @@ struct Object *CTX_data_active_object(const bContext *C)
return ctx_data_pointer_get(C, "active_object");
}
struct Base *CTX_data_active_base(const bContext *C)
struct ObjectBase *CTX_data_active_base(const bContext *C)
{
return ctx_data_pointer_get(C, "active_base");
}

View File

@@ -130,18 +130,11 @@ static bool group_object_add_internal(Group *group, Object *ob)
return true;
}
bool BKE_group_object_add(Group *group, Object *object, Scene *scene, Base *base)
bool BKE_group_object_add(Group *group, Object *object)
{
if (group_object_add_internal(group, object)) {
if ((object->flag & OB_FROMGROUP) == 0) {
if (scene && base == NULL)
base = BKE_scene_base_find(scene, object);
object->flag |= OB_FROMGROUP;
if (base)
base->flag |= OB_FROMGROUP;
}
return true;
}
@@ -208,18 +201,12 @@ bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group)
return group_object_cyclic_check_internal(object, group);
}
bool BKE_group_object_unlink(Group *group, Object *object, Scene *scene, Base *base)
bool BKE_group_object_unlink(Group *group, Object *object)
{
if (group_object_unlink_internal(group, object)) {
/* object can be NULL */
if (object && BKE_group_object_find(NULL, object) == NULL) {
if (scene && base == NULL)
base = BKE_scene_base_find(scene, object);
object->flag &= ~OB_FROMGROUP;
if (base)
base->flag &= ~OB_FROMGROUP;
}
return true;
}

View File

@@ -0,0 +1,924 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Dalai Felinto
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenkernel/intern/layer.c
* \ingroup bke
*/
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_string_utils.h"
#include "BLT_translation.h"
#include "BKE_layer.h"
#include "BKE_collection.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "DNA_ID.h"
#include "DNA_layer_types.h"
#include "DNA_object_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
/* prototype */
struct CollectionEngineSettingsCB_Type;
static void layer_collection_free(SceneLayer *sl, LayerCollection *lc);
static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc);
static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc);
static void collection_engine_settings_create(ListBase *lb, struct CollectionEngineSettingsCB_Type *ces_type);
static void layer_collection_create_engine_settings(LayerCollection *lc);
static void object_bases_Iterator_next(Iterator *iter, const int flag);
/* RenderLayer */
/**
* Add a new renderlayer
* by default, a renderlayer has the master collection
*/
SceneLayer *BKE_scene_layer_add(Scene *scene, const char *name)
{
if (!name) {
name = DATA_("Render Layer");
}
SceneLayer *sl = MEM_callocN(sizeof(SceneLayer), "Scene Layer");
sl->flag |= SCENE_LAYER_RENDER;
BLI_addtail(&scene->render_layers, sl);
/* unique name */
BLI_strncpy_utf8(sl->name, name, sizeof(sl->name));
BLI_uniquename(&scene->render_layers, sl, DATA_("SceneLayer"), '.', offsetof(SceneLayer, name), sizeof(sl->name));
SceneCollection *sc = BKE_collection_master(scene);
layer_collection_add(sl, &sl->layer_collections, sc);
return sl;
}
bool BKE_scene_layer_remove(Main *bmain, Scene *scene, SceneLayer *sl)
{
const int act = BLI_findindex(&scene->render_layers, sl);
if (act == -1) {
return false;
}
else if ( (scene->render_layers.first == scene->render_layers.last) &&
(scene->render_layers.first == sl))
{
/* ensure 1 layer is kept */
return false;
}
BLI_remlink(&scene->render_layers, sl);
BKE_scene_layer_free(sl);
MEM_freeN(sl);
scene->active_layer = 0;
/* TODO WORKSPACE: set active_layer to 0 */
for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree) {
BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
}
}
return true;
}
/**
* Free (or release) any data used by this SceneLayer (does not free the SceneLayer itself).
*/
void BKE_scene_layer_free(SceneLayer *sl)
{
sl->basact = NULL;
BLI_freelistN(&sl->object_bases);
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
layer_collection_free(NULL, lc);
}
BLI_freelistN(&sl->layer_collections);
}
/**
* Set the render engine of a renderlayer
*/
void BKE_scene_layer_engine_set(SceneLayer *sl, const char *engine)
{
BLI_strncpy_utf8(sl->engine, engine, sizeof(sl->engine));
}
/**
* Tag all the selected objects of a renderlayer
*/
void BKE_scene_layer_selected_objects_tag(SceneLayer *sl, const int tag)
{
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_SELECTED) != 0) {
base->object->flag |= tag;
}
else {
base->object->flag &= ~tag;
}
}
}
static bool find_scene_collection_in_scene_collections(ListBase *lb, const LayerCollection *lc)
{
for (LayerCollection *lcn = lb->first; lcn; lcn = lcn->next) {
if (lcn == lc) {
return true;
}
if (find_scene_collection_in_scene_collections(&lcn->layer_collections, lc)) {
return true;
}
}
return false;
}
/**
* Find the SceneLayer a LayerCollection belongs to
*/
SceneLayer *BKE_scene_layer_find_from_collection(Scene *scene, LayerCollection *lc)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
if (find_scene_collection_in_scene_collections(&sl->layer_collections, lc)) {
return sl;
}
}
return false;
}
/* ObjectBase */
ObjectBase *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
{
return BLI_findptr(&sl->object_bases, ob, offsetof(ObjectBase, object));
}
void BKE_scene_layer_base_deselect_all(SceneLayer *sl)
{
ObjectBase *base;
for (base = sl->object_bases.first; base; base = base->next) {
base->flag &= ~BASE_SELECTED;
}
}
void BKE_scene_layer_base_select(struct SceneLayer *sl, ObjectBase *selbase)
{
sl->basact = selbase;
if ((selbase->flag & BASE_SELECTABLED) != 0) {
selbase->flag |= BASE_SELECTED;
}
}
static void scene_layer_object_base_unref(SceneLayer* sl, ObjectBase *base)
{
base->refcount--;
/* It only exists in the RenderLayer */
if (base->refcount == 0) {
if (sl->basact == base) {
sl->basact = NULL;
}
BLI_remlink(&sl->object_bases, base);
MEM_freeN(base);
}
}
static void layer_collection_base_flag_recalculate(LayerCollection *lc, const bool tree_is_visible, const bool tree_is_selectable)
{
bool is_visible = tree_is_visible && ((lc->flag & COLLECTION_VISIBLE) != 0);
/* an object can only be selected if it's visible */
bool is_selectable = tree_is_selectable && is_visible && ((lc->flag & COLLECTION_SELECTABLE) != 0);
for (LinkData *link = lc->object_bases.first; link; link = link->next) {
ObjectBase *base = link->data;
if (is_visible) {
base->flag |= BASE_VISIBLED;
}
else {
base->flag &= ~BASE_VISIBLED;
}
if (is_selectable) {
base->flag |= BASE_SELECTABLED;
}
else {
base->flag &= ~BASE_SELECTABLED;
}
}
for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
layer_collection_base_flag_recalculate(lcn, is_visible, is_selectable);
}
}
/**
* Re-evaluate the ObjectBase flags for SceneLayer
*/
void BKE_scene_layer_base_flag_recalculate(SceneLayer *sl)
{
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
layer_collection_base_flag_recalculate(lc, true, true);
}
/* if base is not selectabled, clear select */
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_SELECTABLED) == 0) {
base->flag &= ~BASE_SELECTED;
}
}
BKE_scene_layer_engine_settings_recalculate(sl);
}
/**
* Tag Scene Layer to recalculation
*
* Temporary function, waiting for real depsgraph
*/
void BKE_scene_layer_engine_settings_recalculate(struct SceneLayer *sl)
{
sl->flag |= SCENE_LAYER_ENGINE_DIRTY;
}
/**
* Re-calculate the engine settings for all the objects in SceneLayer
*
* Temporary function, waiting for real depsgraph
*/
void BKE_scene_layer_engine_settings_update(struct SceneLayer *sl)
{
if ((sl->flag & SCENE_LAYER_ENGINE_DIRTY) == 0) {
return;
}
/* do the complete settings update */
TODO_LAYER_DEPSGRAPH;
sl->flag &= ~SCENE_LAYER_ENGINE_DIRTY;
}
/**
* Return the base if existent, or create it if necessary
* Always bump the refcount
*/
static ObjectBase *object_base_add(SceneLayer *sl, Object *ob)
{
ObjectBase *base;
base = BKE_scene_layer_base_find(sl, ob);
if (base == NULL) {
base = MEM_callocN(sizeof(ObjectBase), "Object Base");
/* do not bump user count, leave it for SceneCollections */
base->object = ob;
BLI_addtail(&sl->object_bases, base);
}
base->refcount++;
return base;
}
/* LayerCollection */
/**
* When freeing the entire SceneLayer at once we don't bother with unref
* otherwise SceneLayer is passed to keep the syncing of the LayerCollection tree
*/
static void layer_collection_free(SceneLayer *sl, LayerCollection *lc)
{
if (sl) {
for (LinkData *link = lc->object_bases.first; link; link = link->next) {
scene_layer_object_base_unref(sl, link->data);
}
}
BLI_freelistN(&lc->object_bases);
BLI_freelistN(&lc->overrides);
BKE_layer_collection_engine_settings_free(&lc->engine_settings);
for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
layer_collection_free(sl, nlc);
}
BLI_freelistN(&lc->layer_collections);
}
/**
* Free (or release) LayerCollection from SceneLayer
* (does not free the LayerCollection itself).
*/
void BKE_layer_collection_free(SceneLayer *sl, LayerCollection *lc)
{
layer_collection_free(sl, lc);
}
/* LayerCollection */
/**
* Recursively get the collection for a given index
*/
static LayerCollection *collection_from_index(ListBase *lb, const int number, int *i)
{
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
if (*i == number) {
return lc;
}
(*i)++;
LayerCollection *lc_nested = collection_from_index(&lc->layer_collections, number, i);
if (lc_nested) {
return lc_nested;
}
}
return NULL;
}
/**
* Get the active collection
*/
LayerCollection *BKE_layer_collection_active(SceneLayer *sl)
{
int i = 0;
return collection_from_index(&sl->layer_collections, sl->active_collection, &i);
}
/**
* Recursively get the count of collections
*/
static int collection_count(ListBase *lb)
{
int i = 0;
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
i += collection_count(&lc->layer_collections) + 1;
}
return i;
}
/**
* Get the total number of collections
* (including all the nested collections)
*/
int BKE_layer_collection_count(SceneLayer *sl)
{
return collection_count(&sl->layer_collections);
}
/**
* Recursively get the index for a given collection
*/
static int index_from_collection(ListBase *lb, LayerCollection *lc, int *i)
{
for (LayerCollection *lcol = lb->first; lcol; lcol = lcol->next) {
if (lcol == lc) {
return *i;
}
(*i)++;
int i_nested = index_from_collection(&lcol->layer_collections, lc, i);
if (i_nested != -1) {
return i_nested;
}
}
return -1;
}
/**
* Return -1 if not found
*/
int BKE_layer_collection_findindex(SceneLayer *sl, LayerCollection *lc)
{
int i = 0;
return index_from_collection(&sl->layer_collections, lc, &i);
}
/**
* Link a collection to a renderlayer
* The collection needs to be created separately
*/
LayerCollection *BKE_collection_link(SceneLayer *sl, SceneCollection *sc)
{
LayerCollection *lc = layer_collection_add(sl, &sl->layer_collections, sc);
sl->active_collection = BKE_layer_collection_findindex(sl, lc);
return lc;
}
/**
* Unlink a collection base from a renderlayer
* The corresponding collection is not removed from the master collection
*/
void BKE_collection_unlink(SceneLayer *sl, LayerCollection *lc)
{
BKE_layer_collection_free(sl, lc);
BKE_scene_layer_base_flag_recalculate(sl);
BLI_remlink(&sl->layer_collections, lc);
MEM_freeN(lc);
sl->active_collection = 0;
}
static void layer_collection_object_add(SceneLayer *sl, LayerCollection *lc, Object *ob)
{
ObjectBase *base = object_base_add(sl, ob);
/* only add an object once - prevent SceneCollection->objects and
* SceneCollection->filter_objects to add the same object */
if (BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data))) {
return;
}
BKE_scene_layer_base_flag_recalculate(sl);
BLI_addtail(&lc->object_bases, BLI_genericNodeN(base));
}
static void layer_collection_object_remove(SceneLayer *sl, LayerCollection *lc, Object *ob)
{
ObjectBase *base;
base = BKE_scene_layer_base_find(sl, ob);
LinkData *link = BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data));
BLI_remlink(&lc->object_bases, link);
MEM_freeN(link);
scene_layer_object_base_unref(sl, base);
}
static void layer_collection_objects_populate(SceneLayer *sl, LayerCollection *lc, ListBase *objects)
{
for (LinkData *link = objects->first; link; link = link->next) {
layer_collection_object_add(sl, lc, link->data);
}
}
static void layer_collection_populate(SceneLayer *sl, LayerCollection *lc, SceneCollection *sc)
{
layer_collection_objects_populate(sl, lc, &sc->objects);
layer_collection_objects_populate(sl, lc, &sc->filter_objects);
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
layer_collection_add(sl, &lc->layer_collections, nsc);
}
}
static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc)
{
LayerCollection *lc = MEM_callocN(sizeof(LayerCollection), "Collection Base");
BLI_addtail(lb, lc);
lc->scene_collection = sc;
lc->flag = COLLECTION_VISIBLE + COLLECTION_SELECTABLE + COLLECTION_FOLDED;
layer_collection_create_engine_settings(lc);
layer_collection_populate(sl, lc, sc);
return lc;
}
/* ---------------------------------------------------------------------- */
/**
* See if render layer has the scene collection linked directly, or indirectly (nested)
*/
bool BKE_scene_layer_has_collection(struct SceneLayer *sl, struct SceneCollection *sc)
{
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
if (find_layer_collection_by_scene_collection(lc, sc) != NULL) {
return true;
}
}
return false;
}
/**
* See if the object is in any of the scene layers of the scene
*/
bool BKE_scene_has_object(Scene *scene, Object *ob)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
ObjectBase *base = BKE_scene_layer_base_find(sl, ob);
if (base) {
return true;
}
}
return false;
}
/* ---------------------------------------------------------------------- */
/* Syncing */
static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc)
{
if (lc->scene_collection == sc) {
return lc;
}
for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
LayerCollection *found = find_layer_collection_by_scene_collection(nlc, sc);
if (found) {
return found;
}
}
return NULL;
}
/**
* Add a new LayerCollection for all the SceneLayers that have sc_parent
*/
void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc_parent, SceneCollection *sc)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
LayerCollection *lc_parent = find_layer_collection_by_scene_collection(lc, sc_parent);
if (lc_parent) {
layer_collection_add(sl, &lc_parent->layer_collections, sc);
}
}
}
}
/**
* Add a corresponding ObjectBase to all the equivalent LayerCollection
*/
void BKE_layer_sync_object_link(Scene *scene, SceneCollection *sc, Object *ob)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
if (found) {
layer_collection_object_add(sl, found, ob);
}
}
}
}
/**
* Remove the equivalent object base to all layers that have this collection
* also remove all reference to ob in the filter_objects
*/
void BKE_layer_sync_object_unlink(Scene *scene, SceneCollection *sc, Object *ob)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
if (found) {
layer_collection_object_remove(sl, found, ob);
}
}
BKE_scene_layer_base_flag_recalculate(sl);
}
}
/* ---------------------------------------------------------------------- */
/* Override */
/**
* Add a new datablock override
*/
void BKE_collection_override_datablock_add(LayerCollection *UNUSED(lc), const char *UNUSED(data_path), ID *UNUSED(id))
{
TODO_LAYER_OVERRIDE;
}
/* ---------------------------------------------------------------------- */
/* Engine Settings */
ListBase R_engines_settings_callbacks = {NULL, NULL};
typedef struct CollectionEngineSettingsCB_Type {
struct CollectionEngineSettingsCB_Type *next, *prev;
char name[MAX_NAME]; /* engine name */
CollectionEngineSettingsCB callback;
} CollectionEngineSettingsCB_Type;
static void create_engine_settings_layer_collection(LayerCollection *lc, CollectionEngineSettingsCB_Type *ces_type)
{
if (BKE_layer_collection_engine_get(lc, ces_type->name)) {
return;
}
collection_engine_settings_create(&lc->engine_settings, ces_type);
for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
create_engine_settings_layer_collection(lcn, ces_type);
}
}
static void create_engines_settings_scene(Scene *scene, CollectionEngineSettingsCB_Type *ces_type)
{
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
create_engine_settings_layer_collection(lc, ces_type);
}
}
}
void BKE_layer_collection_engine_settings_callback_register(
Main *bmain, const char *engine_name, CollectionEngineSettingsCB func)
{
CollectionEngineSettingsCB_Type *ces_type;
/* cleanup in case it existed */
ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name));
if (ces_type) {
BLI_remlink(&R_engines_settings_callbacks, ces_type);
MEM_freeN(ces_type);
}
ces_type = MEM_callocN(sizeof(CollectionEngineSettingsCB_Type), "collection_engine_type");
BLI_strncpy_utf8(ces_type->name, engine_name, sizeof(ces_type->name));
ces_type->callback = func;
BLI_addtail(&R_engines_settings_callbacks, ces_type);
if (bmain) {
/* populate all of the collections of the scene with those settings */
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
create_engines_settings_scene(scene, ces_type);
}
}
}
void BKE_layer_collection_engine_settings_callback_free(void)
{
BLI_freelistN(&R_engines_settings_callbacks);
}
static void collection_engine_settings_create(ListBase *lb, CollectionEngineSettingsCB_Type *ces_type)
{
/* create callback data */
CollectionEngineSettings *ces = MEM_callocN(sizeof(CollectionEngineSettings), "Collection Engine Settings");
BLI_strncpy_utf8(ces->name, ces_type->name, sizeof(ces->name));
BLI_addtail(lb, ces);
/* call callback */
ces_type->callback(NULL, ces);
}
/**
* Initialize a CollectionEngineSettings
*
* Usually we would pass LayerCollection->engine_settings
* But depsgraph uses this for Object->collection_settings
*/
void BKE_layer_collection_engine_settings_create(ListBase *lb, const char *engine_name)
{
CollectionEngineSettingsCB_Type *ces_type;
ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name));
BLI_assert(ces_type);
collection_engine_settings_create(lb, ces_type);
}
/**
* Free the CollectionEngineSettings ListBase
*
* Usually we would pass LayerCollection->engine_settings
* But depsgraph uses this for Object->collection_settings
*/
void BKE_layer_collection_engine_settings_free(ListBase *lb)
{
for (CollectionEngineSettings *cse = lb->first; cse; cse = cse->next) {
BLI_freelistN(&cse->properties);
}
BLI_freelistN(lb);
}
/**
* Initialize the render settings for a single LayerCollection
*/
static void layer_collection_create_engine_settings(LayerCollection *lc)
{
CollectionEngineSettingsCB_Type *ces_type;
for (ces_type = R_engines_settings_callbacks.first; ces_type; ces_type = ces_type->next) {
create_engine_settings_layer_collection(lc, ces_type);
}
}
/**
* Return layer collection engine settings for specified engine
*/
CollectionEngineSettings *BKE_layer_collection_engine_get(LayerCollection *lc, const char *engine_name)
{
CollectionEngineSettings *ces;
ces = BLI_findstring(&lc->engine_settings, engine_name, offsetof(CollectionEngineSettings, name));
return ces;
}
/* ---------------------------------------------------------------------- */
/* Engine Settings Properties */
void BKE_collection_engine_property_add_float(CollectionEngineSettings *ces, const char *name, float value)
{
CollectionEnginePropertyFloat *prop;
prop = MEM_callocN(sizeof(CollectionEnginePropertyFloat), "collection engine settings float");
prop->data.type = COLLECTION_PROP_TYPE_FLOAT;
BLI_strncpy_utf8(prop->data.name, name, sizeof(prop->data.name));
prop->value = value;
BLI_addtail(&ces->properties, prop);
}
void BKE_collection_engine_property_add_int(CollectionEngineSettings *ces, const char *name, int value)
{
CollectionEnginePropertyInt *prop;
prop = MEM_callocN(sizeof(CollectionEnginePropertyInt), "collection engine settings int");
prop->data.type = COLLECTION_PROP_TYPE_INT;
BLI_strncpy_utf8(prop->data.name, name, sizeof(prop->data.name));
prop->value = value;
BLI_addtail(&ces->properties, prop);
}
CollectionEngineProperty *BKE_collection_engine_property_get(CollectionEngineSettings *ces, const char *name)
{
return BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
}
int BKE_collection_engine_property_value_get_int(CollectionEngineSettings *ces, const char *name)
{
CollectionEnginePropertyInt *prop;
prop = (CollectionEnginePropertyInt *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
return prop->value;
}
float BKE_collection_engine_property_value_get_float(CollectionEngineSettings *ces, const char *name)
{
CollectionEnginePropertyFloat *prop;
prop = (CollectionEnginePropertyFloat *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
return prop->value;
}
void BKE_collection_engine_property_value_set_int(CollectionEngineSettings *ces, const char *name, int value)
{
CollectionEnginePropertyInt *prop;
prop = (CollectionEnginePropertyInt *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
prop->value = value;
prop->data.flag |= COLLECTION_PROP_USE;
}
void BKE_collection_engine_property_value_set_float(CollectionEngineSettings *ces, const char *name, float value)
{
CollectionEnginePropertyFloat *prop;
prop = (CollectionEnginePropertyFloat *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
prop->value = value;
prop->data.flag |= COLLECTION_PROP_USE;
}
bool BKE_collection_engine_property_use_get(CollectionEngineSettings *ces, const char *name)
{
CollectionEngineProperty *prop;
prop = (CollectionEngineProperty *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
return ((prop->flag & COLLECTION_PROP_USE) != 0);
}
void BKE_collection_engine_property_use_set(CollectionEngineSettings *ces, const char *name, bool value)
{
CollectionEngineProperty *prop;
prop = (CollectionEngineProperty *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
if (value) {
prop->flag |= COLLECTION_PROP_USE;
}
else {
prop->flag &= ~COLLECTION_PROP_USE;
}
}
/* ---------------------------------------------------------------------- */
/* Iterators */
static void object_bases_Iterator_begin(Iterator *iter, void *data_in, const int flag)
{
SceneLayer *sl = data_in;
ObjectBase *base = sl->object_bases.first;
/* when there are no objects */
if (base == NULL) {
iter->valid = false;
return;
}
iter->valid = true;
iter->data = base;
if ((base->flag & flag) == 0) {
object_bases_Iterator_next(iter, flag);
}
else {
iter->current = base;
}
}
static void object_bases_Iterator_next(Iterator *iter, const int flag)
{
ObjectBase *base = ((ObjectBase *)iter->data)->next;
while (base) {
if ((base->flag & flag) != 0) {
iter->current = base;
iter->data = base;
return;
}
base = base->next;
}
iter->current = NULL;
iter->valid = false;
}
static void objects_Iterator_begin(Iterator *iter, void *data_in, const int flag)
{
object_bases_Iterator_begin(iter, data_in, flag);
if (iter->valid) {
iter->current = ((ObjectBase *)iter->current)->object;
}
}
static void objects_Iterator_next(Iterator *iter, const int flag)
{
object_bases_Iterator_next(iter, flag);
if (iter->valid) {
iter->current = ((ObjectBase *)iter->current)->object;
}
}
void BKE_selected_objects_Iterator_begin(Iterator *iter, void *data_in)
{
objects_Iterator_begin(iter, data_in, BASE_SELECTED);
}
void BKE_selected_objects_Iterator_next(Iterator *iter)
{
objects_Iterator_next(iter, BASE_SELECTED);
}
void BKE_selected_objects_Iterator_end(Iterator *UNUSED(iter))
{
/* do nothing */
}
void BKE_visible_objects_Iterator_begin(Iterator *iter, void *data_in)
{
objects_Iterator_begin(iter, data_in, BASE_VISIBLED);
}
void BKE_visible_objects_Iterator_next(Iterator *iter)
{
objects_Iterator_next(iter, BASE_VISIBLED);
}
void BKE_visible_objects_Iterator_end(Iterator *UNUSED(iter))
{
/* do nothing */
}
void BKE_visible_bases_Iterator_begin(Iterator *iter, void *data_in)
{
object_bases_Iterator_begin(iter, data_in, BASE_VISIBLED);
}
void BKE_visible_bases_Iterator_next(Iterator *iter)
{
object_bases_Iterator_next(iter, BASE_VISIBLED);
}
void BKE_visible_bases_Iterator_end(Iterator *UNUSED(iter))
{
/* do nothing */
}

View File

@@ -67,6 +67,7 @@
#include "BLI_linklist_stack.h"
#include "BKE_animsys.h"
#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_fcurve.h"
#include "BKE_library.h"
@@ -333,7 +334,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
Scene *scene = (Scene *) id;
ToolSettings *toolsett = scene->toolsettings;
SceneRenderLayer *srl;
Base *base;
Base *legacy_base;
CALLBACK_INVOKE(scene->camera, IDWALK_NOP);
CALLBACK_INVOKE(scene->world, IDWALK_USER);
@@ -390,8 +391,28 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
CALLBACK_INVOKE(scene->gpd, IDWALK_USER);
for (base = scene->base.first; base; base = base->next) {
CALLBACK_INVOKE(base->object, IDWALK_USER);
for (legacy_base = scene->base.first; legacy_base; legacy_base = legacy_base->next) {
CALLBACK_INVOKE(legacy_base->object, IDWALK_USER);
}
SceneCollection *sc;
FOREACH_SCENE_COLLECTION(scene, sc)
{
for (LinkData *link = sc->objects.first; link; link = link->next) {
CALLBACK_INVOKE_ID(link->data, IDWALK_USER);
}
for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
CALLBACK_INVOKE_ID(link->data, IDWALK_USER);
}
}
FOREACH_SCENE_COLLECTION_END
SceneLayer *sl;
for (sl = scene->render_layers.first; sl; sl = sl->next) {
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
CALLBACK_INVOKE(base->object, IDWALK_NOP);
}
}
for (TimeMarker *marker = scene->markers.first; marker; marker = marker->next) {

View File

@@ -71,6 +71,7 @@
#include "BKE_brush.h"
#include "BKE_camera.h"
#include "BKE_cachefile.h"
#include "BKE_collection.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
@@ -254,6 +255,22 @@ static void libblock_remap_data_preprocess_scene_base_unlink(
}
}
/* Some remapping unfortunately require extra and/or specific handling, tackle those here. */
static void libblock_remap_data_preprocess_scene_object_unlink(
IDRemap *r_id_remap_data, Scene *sce, Object *ob, const bool skip_indirect, const bool is_indirect)
{
if (skip_indirect && is_indirect) {
r_id_remap_data->skipped_indirect++;
r_id_remap_data->skipped_refcounted++;
}
else {
BKE_collections_object_remove(r_id_remap_data->bmain, sce, ob, false);
if (!is_indirect) {
r_id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT;
}
}
}
static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
{
switch (GS(r_id_remap_data->id->name)) {
@@ -268,6 +285,15 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
/* In case we are unlinking... */
if (!r_id_remap_data->old_id) {
/* ... everything from scene. */
Object *ob_iter;
FOREACH_SCENE_OBJECT(sce, ob_iter)
{
libblock_remap_data_preprocess_scene_object_unlink(
r_id_remap_data, sce, ob_iter, skip_indirect, is_indirect);
}
FOREACH_SCENE_OBJECT_END
Base *base, *base_next;
for (base = sce->base.first; base; base = base_next) {
base_next = base->next;
@@ -278,8 +304,11 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
else if (GS(r_id_remap_data->old_id->name) == ID_OB) {
/* ... a specific object from scene. */
Object *old_ob = (Object *)r_id_remap_data->old_id;
Base *base = BKE_scene_base_find(sce, old_ob);
libblock_remap_data_preprocess_scene_object_unlink(
r_id_remap_data, sce, old_ob, skip_indirect, is_indirect);
Base *base = BKE_scene_base_find(sce, old_ob);
if (base) {
libblock_remap_data_preprocess_scene_base_unlink(
r_id_remap_data, sce, base, skip_indirect, is_indirect);
@@ -325,7 +354,7 @@ static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain,
}
if (new_ob == NULL) { /* We need to remove NULL-ified groupobjects... */
for (Group *group = bmain->group.first; group; group = group->id.next) {
BKE_group_object_unlink(group, NULL, NULL, NULL);
BKE_group_object_unlink(group, NULL);
}
}
else {
@@ -339,22 +368,16 @@ static void libblock_remap_data_postprocess_group_scene_unlink(Main *UNUSED(bmai
/* Note that here we assume no object has no base (i.e. all objects are assumed instanced
* in one scene...). */
for (Base *base = sce->base.first; base; base = base->next) {
if (base->flag & OB_FROMGROUP) {
Object *ob = base->object;
Object *ob = base->object;
if (ob->flag & OB_FROMGROUP) {
Group *grp = BKE_group_object_find(NULL, ob);
if (ob->flag & OB_FROMGROUP) {
Group *grp = BKE_group_object_find(NULL, ob);
/* Unlinked group (old_id) is still in bmain... */
if (grp && (&grp->id == old_id || grp->id.us == 0)) {
grp = BKE_group_object_find(grp, ob);
}
if (!grp) {
ob->flag &= ~OB_FROMGROUP;
}
/* Unlinked group (old_id) is still in bmain... */
if (grp && (&grp->id == old_id || grp->id.us == 0)) {
grp = BKE_group_object_find(grp, ob);
}
if (!(ob->flag & OB_FROMGROUP)) {
base->flag &= ~OB_FROMGROUP;
if (!grp) {
ob->flag &= ~OB_FROMGROUP;
}
}
}

View File

@@ -111,6 +111,12 @@ void BKE_material_free(Material *ma)
BKE_icon_id_delete((ID *)ma);
BKE_previewimg_free(&ma->preview);
for (MaterialEngineSettings *mes = ma->engines_settings.first; mes; mes = mes->next) {
if (mes->data)
MEM_SAFE_FREE(mes->data);
}
BLI_freelistN(&ma->engines_settings);
}
void BKE_material_init(Material *ma)
@@ -248,6 +254,8 @@ Material *BKE_material_copy(Main *bmain, Material *ma)
BLI_listbase_clear(&man->gpumaterial);
/* TODO Duplicate Engine Settings and set runtime to NULL */
BKE_id_copy_ensure_local(bmain, &ma->id, &man->id);
return man;
@@ -279,6 +287,8 @@ Material *localize_material(Material *ma)
man->nodetree = ntreeLocalize(ma->nodetree);
BLI_listbase_clear(&man->gpumaterial);
/* TODO Duplicate Engine Settings and set runtime to NULL */
return man;
}
@@ -1698,6 +1708,7 @@ void copy_matcopybuf(Material *ma)
matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, G.main, false);
matcopybuf.preview = NULL;
BLI_listbase_clear(&matcopybuf.gpumaterial);
/* TODO Duplicate Engine Settings and set runtime to NULL */
matcopied = 1;
}

View File

@@ -359,27 +359,25 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
*/
Object *BKE_mball_basis_find(Scene *scene, Object *basis)
{
Scene *sce_iter = scene;
Base *base;
Object *ob, *bob = basis;
Object *bob = basis;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
SceneBaseIter iter;
EvaluationContext *eval_ctx = G.main->eval_ctx;
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
BKE_scene_base_iter_next(eval_ctx, &iter, &sce_iter, 0, NULL, NULL);
while (BKE_scene_base_iter_next(eval_ctx, &iter, &sce_iter, 1, &base, &ob)) {
if ((ob->type == OB_MBALL) && !(base->flag & OB_FROMDUPLI)) {
if (ob != bob) {
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
Object *ob = base->object;
if ((ob->type == OB_MBALL) && !(base->flag & OB_FROMDUPLI)) {
if (ob != bob) {
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
/* object ob has to be in same "group" ... it means, that it has to have same base of its name */
if (STREQ(obname, basisname)) {
if (obnr < basisnr) {
basis = ob;
basisnr = obnr;
/* object ob has to be in same "group" ... it means, that it has to have same base of its name */
if (STREQ(obname, basisname)) {
if (obnr < basisnr) {
basis = ob;
basisnr = obnr;
}
}
}
}

View File

@@ -47,7 +47,7 @@
/* Mesh Interface */
#define MESH_RENDER_FUNCTION(func_name) \
if (me->edit_btmesh) { \
if (me->edit_btmesh && me->edit_btmesh->derivedFinal) { \
return mesh_bmesh_##func_name(me); \
} \
else { \

View File

@@ -3776,3 +3776,20 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
return true;
}
/* -------------------------------------------------------------------- */
/* NodeTree kernel functions */
void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
{
for (bNode *node = ntree->nodes.first; node; node = node->next) {
if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
if (node->custom1 == layer_index) {
node->custom1 = 0;
}
else if (node->custom1 > layer_index) {
node->custom1--;
}
}
}
}

View File

@@ -91,6 +91,7 @@
#include "BKE_icons.h"
#include "BKE_key.h"
#include "BKE_lamp.h"
#include "BKE_layer.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
@@ -677,23 +678,25 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
/* general add: to scene, with layer from area and default name */
/* creates minimum required data, but without vertices etc. */
Object *BKE_object_add(
Main *bmain, Scene *scene,
Main *bmain, Scene *scene, SceneLayer *sl,
int type, const char *name)
{
Object *ob;
Base *base;
ObjectBase *base;
LayerCollection *lc;
ob = BKE_object_add_only_object(bmain, type, name);
ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
ob->lay = scene->lay;
base = BKE_scene_base_add(scene, ob);
BKE_scene_base_deselect_all(scene);
BKE_scene_base_select(scene, base);
DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
lc = BKE_layer_collection_active(sl);
BKE_collection_object_add(scene, lc->scene_collection, ob);
base = BKE_scene_layer_base_find(sl, ob);
BKE_scene_layer_base_deselect_all(sl);
BKE_scene_layer_base_select(sl, base);
DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
@@ -3492,18 +3495,11 @@ struct LinkNode *BKE_object_groups(Object *ob)
return group_linknode;
}
void BKE_object_groups_clear(Scene *scene, Base *base, Object *object)
void BKE_object_groups_clear(Object *ob)
{
Group *group = NULL;
BLI_assert((base == NULL) || (base->object == object));
if (scene && base == NULL) {
base = BKE_scene_base_find(scene, object);
}
while ((group = BKE_group_object_find(group, base->object))) {
BKE_group_object_unlink(group, object, scene, base);
while ((group = BKE_group_object_find(group, ob))) {
BKE_group_object_unlink(group, ob);
}
}

View File

@@ -67,6 +67,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_cachefile.h"
#include "BKE_collection.h"
#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
#include "BKE_editmesh.h"
@@ -78,6 +79,7 @@
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_remap.h"
#include "BKE_linestyle.h"
@@ -107,6 +109,7 @@
const char *RE_engine_id_BLENDER_RENDER = "BLENDER_RENDER";
const char *RE_engine_id_BLENDER_GAME = "BLENDER_GAME";
const char *RE_engine_id_BLENDER_CLAY = "BLENDER_CLAY";
const char *RE_engine_id_CYCLES = "CYCLES";
void free_avicodecdata(AviCodecData *acd)
@@ -154,13 +157,66 @@ static void remove_sequencer_fcurves(Scene *sce)
}
}
/* copy SceneCollection tree but keep pointing to the same objects */
static void scene_collection_copy(SceneCollection *scn, SceneCollection *sc)
{
BLI_duplicatelist(&scn->objects, &sc->objects);
for (LinkData *link = scn->objects.first; link; link = link->next) {
id_us_plus(link->data);
}
BLI_duplicatelist(&scn->filter_objects, &sc->filter_objects);
for (LinkData *link = scn->filter_objects.first; link; link = link->next) {
id_us_plus(link->data);
}
BLI_duplicatelist(&scn->scene_collections, &sc->scene_collections);
SceneCollection *nscn = scn->scene_collections.first; /* nested SceneCollection new */
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
scene_collection_copy(nscn, nsc);
nscn = nscn->next;
}
}
/* Find the equivalent SceneCollection in the new tree */
static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *scn, SceneCollection *sc)
{
if (sc == sc_reference) {
return scn;
}
SceneCollection *nscn = scn->scene_collections.first; /* nested master collection new */
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
SceneCollection *found = scene_collection_from_new_tree(sc_reference, nscn, nsc);
if (found) {
return found;
}
nscn = nscn->next;
}
return NULL;
}
/* recreate the LayerCollection tree */
static void layer_collections_recreate(SceneLayer *sl, ListBase *lb, SceneCollection *mcn, SceneCollection *mc)
{
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
SceneCollection *sc = scene_collection_from_new_tree(lc->scene_collection, mcn, mc);
BLI_assert(sc);
/* instead of syncronizing both trees we simply re-create it */
BKE_collection_link(sl, sc);
}
}
Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
{
Scene *scen;
SceneRenderLayer *srl, *new_srl;
FreestyleLineSet *lineset;
ToolSettings *ts;
Base *base, *obase;
Base *legacy_base, *olegacy_base;
if (type == SCE_COPY_EMPTY) {
ListBase rl, rv;
@@ -214,14 +270,14 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
BKE_libblock_relink_ex(bmain, scen->nodetree, &sce->id, &scen->id, false);
}
obase = sce->base.first;
base = scen->base.first;
while (base) {
id_us_plus(&base->object->id);
if (obase == sce->basact) scen->basact = base;
olegacy_base = sce->base.first;
legacy_base = scen->base.first;
while (legacy_base) {
id_us_plus(&legacy_base->object->id);
if (olegacy_base == sce->basact) scen->basact = legacy_base;
obase = obase->next;
base = base->next;
olegacy_base = olegacy_base->next;
legacy_base = legacy_base->next;
}
/* copy action and remove animation used by sequencer */
@@ -244,6 +300,36 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
}
new_srl = new_srl->next;
}
/* layers and collections */
scen->collection = MEM_dupallocN(sce->collection);
SceneCollection *mcn = BKE_collection_master(scen);
SceneCollection *mc = BKE_collection_master(sce);
/* recursively creates a new SceneCollection tree */
scene_collection_copy(mcn, mc);
BLI_duplicatelist(&scen->render_layers, &sce->render_layers);
SceneLayer *new_sl = scen->render_layers.first;
for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
/* we start fresh with no overrides and no visibility flags set
* instead of syncing both trees we simply unlink and relink the scene collection */
BLI_listbase_clear(&new_sl->layer_collections);
BLI_listbase_clear(&new_sl->object_bases);
layer_collections_recreate(new_sl, &sl->layer_collections, mcn, mc);
if (sl->basact) {
Object *active_ob = sl->basact->object;
for (ObjectBase *base = new_sl->object_bases.first; base; base = base->next) {
if (base->object == active_ob) {
new_sl->basact = base;
break;
}
}
}
new_sl = new_sl->next;
}
}
/* copy color management settings */
@@ -471,6 +557,23 @@ void BKE_scene_free(Scene *sce)
BKE_previewimg_free(&sce->preview);
curvemapping_free_data(&sce->r.mblur_shutter_curve);
for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
BKE_scene_layer_free(sl);
}
BLI_freelistN(&sce->render_layers);
/* Master Collection */
BKE_collection_master_free(sce);
MEM_freeN(sce->collection);
sce->collection = NULL;
/* Runtime Engine Data */
for (RenderEngineSettings *res = sce->engines_settings.first; res; res = res->next) {
if (res->data)
MEM_freeN(res->data);
}
BLI_freelistN(&sce->engines_settings);
}
void BKE_scene_init(Scene *sce)
@@ -820,6 +923,12 @@ void BKE_scene_init(Scene *sce)
sce->toolsettings->gpencil_v2d_align = GP_PROJECT_VIEWSPACE;
sce->toolsettings->gpencil_seq_align = GP_PROJECT_VIEWSPACE;
sce->toolsettings->gpencil_ima_align = GP_PROJECT_VIEWSPACE;
/* Master Collection */
sce->collection = MEM_callocN(sizeof(SceneCollection), "Master Collection");
BLI_strncpy(sce->collection->name, "Master Collection", sizeof(sce->collection->name));
BKE_scene_layer_add(sce, "Render Layer");
}
Scene *BKE_scene_add(Main *bmain, const char *name)
@@ -865,7 +974,6 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
Object *ob;
Group *group;
GroupObject *go;
int flag;
/* check for cyclic sets, for reading old files but also for definite security (py?) */
BKE_scene_validate_setscene(bmain, scene);
@@ -897,13 +1005,7 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
ob->lay = base->lay;
/* group patch... */
base->flag &= ~(OB_FROMGROUP);
flag = ob->flag & (OB_FROMGROUP);
base->flag |= flag;
/* not too nice... for recovering objects with lost data */
//if (ob->pose == NULL) base->flag &= ~OB_POSEMODE;
ob->flag = base->flag;
BKE_scene_base_flag_sync_from_base(base);
}
/* no full animation update, this to enable render code to work (render code calls own animation updates) */
}
@@ -1154,6 +1256,15 @@ char *BKE_scene_find_last_marker_name(Scene *scene, int frame)
return best_marker ? best_marker->name : NULL;
}
void BKE_scene_remove_rigidbody_object(Scene *scene, Object *ob)
{
/* remove rigid body constraint from world before removing object */
if (ob->rigidbody_constraint)
BKE_rigidbody_remove_constraint(scene, ob);
/* remove rigid body object from world before removing object */
if (ob->rigidbody_object)
BKE_rigidbody_remove_object(scene, ob);
}
Base *BKE_scene_base_add(Scene *sce, Object *ob)
{
@@ -1169,13 +1280,8 @@ Base *BKE_scene_base_add(Scene *sce, Object *ob)
void BKE_scene_base_unlink(Scene *sce, Base *base)
{
/* remove rigid body constraint from world before removing object */
if (base->object->rigidbody_constraint)
BKE_rigidbody_remove_constraint(sce, base->object);
/* remove rigid body object from world before removing object */
if (base->object->rigidbody_object)
BKE_rigidbody_remove_object(sce, base->object);
BKE_scene_remove_rigidbody_object(sce, base->object);
BLI_remlink(&sce->base, base);
if (sce->basact == base)
sce->basact = NULL;
@@ -1187,7 +1293,9 @@ void BKE_scene_base_deselect_all(Scene *sce)
for (b = sce->base.first; b; b = b->next) {
b->flag &= ~SELECT;
int flag = b->object->flag & (OB_FROMGROUP);
b->object->flag = b->flag;
b->object->flag |= flag;
}
}
@@ -1492,15 +1600,7 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree) {
bNode *node;
for (node = sce->nodetree->nodes.first; node; node = node->next) {
if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
if (node->custom1 == act)
node->custom1 = 0;
else if (node->custom1 > act)
node->custom1--;
}
}
BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
}
}
@@ -1651,7 +1751,7 @@ void BKE_scene_base_flag_to_objects(struct Scene *scene)
Base *base = scene->base.first;
while (base) {
base->object->flag = base->flag;
BKE_scene_base_flag_sync_from_base(base);
base = base->next;
}
}
@@ -1661,11 +1761,43 @@ void BKE_scene_base_flag_from_objects(struct Scene *scene)
Base *base = scene->base.first;
while (base) {
base->flag = base->object->flag;
BKE_scene_base_flag_sync_from_object(base);
base = base->next;
}
}
void BKE_scene_base_flag_sync_from_base(Base *base)
{
Object *ob = base->object;
/* keep the object only flags untouched */
int flag = ob->flag & OB_FROMGROUP;
ob->flag = base->flag;
ob->flag |= flag;
}
void BKE_scene_base_flag_sync_from_object(Base *base)
{
base->flag = base->object->flag;
}
void BKE_scene_object_base_flag_sync_from_base(ObjectBase *base)
{
Object *ob = base->object;
/* keep the object only flags untouched */
int flag = ob->flag & OB_FROMGROUP;
ob->flag = base->flag;
ob->flag |= flag;
}
void BKE_scene_object_base_flag_sync_from_object(ObjectBase *base)
{
base->flag = base->object->flag;
}
void BKE_scene_disable_color_management(Scene *scene)
{
ColorManagedDisplaySettings *display_settings = &scene->display_settings;

View File

@@ -32,6 +32,7 @@
* \ingroup bli
*/
#include "BLI_blenlib.h"
#include "BLI_sys_types.h" /* for bool */
#include "BLI_compiler_attrs.h"

View File

@@ -0,0 +1,54 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Dalai Felinto
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __BLI_ITERATOR_H__
#define __BLI_ITERATOR_H__
/** \file BLI_iterator.h
* \ingroup bli
*/
typedef struct Iterator {
void *current; /* current pointer we iterate over */
void *data; /* stored data required for this iterator */
bool valid;
} Iterator;
typedef void (*IteratorCb)(Iterator *iter);
typedef void (*IteratorBeginCb)(Iterator *iter, void *data_in);
#define ITER_BEGIN(callback_begin, callback_next, callback_end, _data_in, _data_out) \
{ \
IteratorCb callback_end_func = callback_end; \
Iterator iter_macro; \
for (callback_begin(&iter_macro, _data_in); \
iter_macro.valid; \
callback_next(&iter_macro)) \
{ \
_data_out = iter_macro.current;
#define ITER_END \
} \
callback_end_func(&iter_macro); \
}
#endif /* __BLI_ITERATOR_H__ */

View File

@@ -155,6 +155,7 @@ set(SRC
BLI_hash_md5.h
BLI_hash_mm2a.h
BLI_heap.h
BLI_iterator.h
BLI_jitter.h
BLI_kdopbvh.h
BLI_kdtree.h

View File

@@ -53,6 +53,7 @@ set(SRC
intern/versioning_250.c
intern/versioning_260.c
intern/versioning_270.c
intern/versioning_280.c
intern/versioning_defaults.c
intern/versioning_legacy.c
intern/writefile.c

View File

@@ -72,6 +72,7 @@
#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_layer_types.h"
#include "DNA_lamp_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_meta_types.h"
@@ -102,6 +103,8 @@
#include "DNA_movieclip_types.h"
#include "DNA_mask_types.h"
#include "RNA_access.h"
#include "MEM_guardedalloc.h"
#include "BLI_endian_switch.h"
@@ -3967,6 +3970,7 @@ static void lib_link_material(FileData *fd, Main *main)
static void direct_link_material(FileData *fd, Material *ma)
{
int a;
MaterialEngineSettings *mes;
ma->adt = newdataadr(fd, ma->adt);
direct_link_animdata(fd, ma->adt);
@@ -3987,6 +3991,11 @@ static void direct_link_material(FileData *fd, Material *ma)
ma->preview = direct_link_preview_image(fd, ma->preview);
BLI_listbase_clear(&ma->gpumaterial);
link_list(fd, &ma->engines_settings);
for (mes = ma->engines_settings.first; mes; mes = mes->next) {
mes->data = newdataadr(fd, mes->data);
}
}
/* ************ READ PARTICLE SETTINGS ***************** */
@@ -4607,6 +4616,7 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->bb = NULL;
mesh->edit_btmesh = NULL;
mesh->batch_cache = NULL;
/* happens with old files */
if (mesh->mselect == NULL) {
@@ -5548,6 +5558,7 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->bb = NULL;
ob->derivedDeform = NULL;
ob->derivedFinal = NULL;
ob->collection_settings = NULL;
BLI_listbase_clear(&ob->gpulamp);
link_list(fd, &ob->pc_ids);
@@ -5629,11 +5640,29 @@ static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
}
#endif
static void lib_link_scene_collection(FileData *fd, Library *lib, SceneCollection *sc)
{
for (LinkData *link = sc->objects.first; link; link = link->next) {
link->data = newlibadr_us(fd, lib, link->data);
BLI_assert(link->data);
}
for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
link->data = newlibadr_us(fd, lib, link->data);
BLI_assert(link->data);
}
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
lib_link_scene_collection(fd, lib, nsc);
}
}
static void lib_link_scene(FileData *fd, Main *main)
{
Scene *sce;
Base *base, *next;
Base *base_legacy, *base_legacy_next;
Sequence *seq;
SceneLayer *sl;
SceneRenderLayer *srl;
FreestyleModuleConfig *fmc;
FreestyleLineSet *fls;
@@ -5683,17 +5712,17 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->particle.shape_object = newlibadr(fd, sce->id.lib, sce->toolsettings->particle.shape_object);
for (base = sce->base.first; base; base = next) {
next = base->next;
for (base_legacy = sce->base.first; base_legacy; base_legacy = base_legacy_next) {
base_legacy_next = base_legacy->next;
base->object = newlibadr_us(fd, sce->id.lib, base->object);
base_legacy->object = newlibadr_us(fd, sce->id.lib, base_legacy->object);
if (base->object == NULL) {
if (base_legacy->object == NULL) {
blo_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB: object lost from scene: '%s'"),
sce->id.name + 2);
BLI_remlink(&sce->base, base);
if (base == sce->basact) sce->basact = NULL;
MEM_freeN(base);
BLI_remlink(&sce->base, base_legacy);
if (base_legacy == sce->basact) sce->basact = NULL;
MEM_freeN(base_legacy);
}
}
@@ -5779,6 +5808,15 @@ static void lib_link_scene(FileData *fd, Main *main)
/* Motion Tracking */
sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip);
lib_link_scene_collection(fd, sce->id.lib, sce->collection);
for (sl = sce->render_layers.first; sl; sl = sl->next) {
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
/* we only bump the use count for the collection objects */
base->object = newlibadr(fd, sce->id.lib, base->object);
}
}
#ifdef USE_SETSCENE_CHECK
if (sce->set != NULL) {
/* link flag for scenes with set would be reset later,
@@ -5882,13 +5920,54 @@ static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *vi
direct_link_curvemapping(fd, view_settings->curve_mapping);
}
static void direct_link_scene_collection(FileData *fd, SceneCollection *sc)
{
link_list(fd, &sc->objects);
link_list(fd, &sc->filter_objects);
link_list(fd, &sc->scene_collections);
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
direct_link_scene_collection(fd, nsc);
}
}
static void direct_link_engine_settings(FileData *fd, ListBase *lb)
{
link_list(fd, lb);
for (CollectionEngineSettings *ces = lb->first; ces; ces = ces->next) {
link_list(fd, &ces->properties);
}
}
static void direct_link_layer_collections(FileData *fd, ListBase *lb)
{
link_list(fd, lb);
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
lc->scene_collection = newdataadr(fd, lc->scene_collection);
link_list(fd, &lc->object_bases);
for (LinkData *link = lc->object_bases.first; link; link = link->next) {
link->data = newdataadr(fd, link->data);
}
link_list(fd, &lc->overrides);
direct_link_engine_settings(fd, &lc->engine_settings);
direct_link_layer_collections(fd, &lc->layer_collections);
}
}
static void direct_link_scene(FileData *fd, Scene *sce)
{
Editing *ed;
Sequence *seq;
MetaStack *ms;
RigidBodyWorld *rbw;
SceneLayer *sl;
SceneRenderLayer *srl;
RenderEngineSettings *res;
sce->theDag = NULL;
sce->depsgraph = NULL;
@@ -6138,6 +6217,24 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->preview = direct_link_preview_image(fd, sce->preview);
direct_link_curvemapping(fd, &sce->r.mblur_shutter_curve);
/* this runs before the very first doversion */
if (sce->collection) {
sce->collection = newdataadr(fd, sce->collection);
direct_link_scene_collection(fd, sce->collection);
}
link_list(fd, &sce->render_layers);
for (sl = sce->render_layers.first; sl; sl = sl->next) {
link_list(fd, &sl->object_bases);
sl->basact = newdataadr(fd, sl->basact);
direct_link_layer_collections(fd, &sl->layer_collections);
}
link_list(fd, &sce->engines_settings);
for (res = sce->engines_settings.first; res; res = res->next) {
res->data = newdataadr(fd, res->data);
}
}
/* ************ READ WM ***************** */
@@ -6481,6 +6578,10 @@ static void lib_link_screen(FileData *fd, Main *main)
slogic->gpd = newlibadr_us(fd, sc->id.lib, slogic->gpd);
}
else if (sl->spacetype == SPACE_COLLECTIONS) {
SpaceCollections *slayer = (SpaceCollections *)sl;
slayer->flag |= SC_COLLECTION_DATA_REFRESH;
}
}
}
sc->id.tag &= ~LIB_TAG_NEED_LINK;
@@ -6866,6 +6967,10 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
slogic->gpd = restore_pointer_by_name(id_map, (ID *)slogic->gpd, USER_REAL);
}
else if (sl->spacetype == SPACE_COLLECTIONS) {
SpaceCollections *slayer = (SpaceCollections *)sl;
slayer->flag |= SC_COLLECTION_DATA_REFRESH;
}
}
}
}
@@ -7260,6 +7365,10 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
sclip->scopes.track_preview = NULL;
sclip->scopes.ok = 0;
}
else if (sl->spacetype == SPACE_COLLECTIONS) {
SpaceCollections *slayer = (SpaceCollections *)sl;
slayer->flag |= SC_COLLECTION_DATA_REFRESH;
}
}
BLI_listbase_clear(&sa->actionzones);
@@ -7456,7 +7565,7 @@ static void lib_link_group(FileData *fd, Main *main)
if (add_us) {
id_us_ensure_real(&group->id);
}
BKE_group_object_unlink(group, NULL, NULL, NULL); /* removes NULL entries */
BKE_group_object_unlink(group, NULL); /* removes NULL entries */
}
}
}
@@ -8388,6 +8497,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
blo_do_versions_250(fd, lib, main);
blo_do_versions_260(fd, lib, main);
blo_do_versions_270(fd, lib, main);
blo_do_versions_280(fd, lib, main);
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
@@ -8399,8 +8509,8 @@ static void do_versions_after_linking(Main *main)
{
// printf("%s for %s (%s), %d.%d\n", __func__, main->curlib ? main->curlib->name : main->name,
// main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile);
do_versions_after_linking_270(main);
do_versions_after_linking_280(main);
}
static void lib_link_all(FileData *fd, Main *main)
@@ -9483,6 +9593,21 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
}
}
static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc)
{
for (LinkData *link = sc->objects.first; link; link = link->next) {
expand_doit(fd, mainvar, link->data);
}
for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
expand_doit(fd, mainvar, link->data);
}
for (SceneCollection *nsc= sc->scene_collections.first; nsc; nsc = nsc->next) {
expand_scene_collection(fd, mainvar, nsc);
}
}
static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
{
Base *base;
@@ -9552,6 +9677,8 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
}
expand_doit(fd, mainvar, sce->clip);
expand_scene_collection(fd, mainvar, sce->collection);
}
static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
@@ -9834,7 +9961,7 @@ static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Libra
base->object = ob;
base->lay = ob->lay;
base->flag = ob->flag;
BKE_scene_base_flag_sync_from_object(base);
CLAMP_MIN(ob->id.us, 0);
id_us_plus_no_lib((ID *)ob);
@@ -9868,7 +9995,7 @@ static void give_base_to_groups(
/* assign the base */
base = BKE_scene_base_add(scene, ob);
base->flag |= SELECT;
base->object->flag = base->flag;
BKE_scene_base_flag_sync_from_base(base);
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
scene->basact = base;
@@ -9971,7 +10098,7 @@ static void link_object_postprocess(ID *id, Scene *scene, View3D *v3d, const sho
if (flag & FILE_AUTOSELECT) {
base->flag |= SELECT;
base->object->flag = base->flag;
BKE_scene_base_flag_sync_from_base(base);
/* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
}
}

View File

@@ -34,6 +34,8 @@
#define __READFILE_H__
#include "zlib.h"
#include "DNA_sdna_types.h"
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h" /* for ReportType */
struct OldNewMap;
@@ -169,8 +171,10 @@ void blo_do_versions_pre250(struct FileData *fd, struct Library *lib, struct Mai
void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main *main);
void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *main);
void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *main);
void blo_do_versions_280(struct FileData *fd, struct Library *lib, struct Main *main);
void do_versions_after_linking_270(struct Main *main);
void do_versions_after_linking_280(struct Main *main);
#endif

View File

@@ -0,0 +1,182 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Dalai Felinto
*
* ***** END GPL LICENSE BLOCK *****
*
*/
/** \file blender/blenloader/intern/versioning_280.c
* \ingroup blenloader
*/
/* allow readfile to use deprecated functionality */
#define DNA_DEPRECATED_ALLOW
#include "DNA_object_types.h"
#include "DNA_layer_types.h"
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
#include "DNA_genfile.h"
#include "BKE_collection.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLO_readfile.h"
#include "readfile.h"
#include "MEM_guardedalloc.h"
void do_versions_after_linking_280(Main *main)
{
if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
/* since we don't have access to FileData we check the (always valid) first render layer instead */
if (scene->render_layers.first == NULL) {
SceneCollection *sc_master = BKE_collection_master(scene);
BLI_strncpy(sc_master->name, "Master Collection", sizeof(sc_master->name));
SceneCollection *collections[20] = {NULL};
bool is_visible[20];
int lay_used = 0;
for (int i = 0; i < 20; i++) {
char name[MAX_NAME];
BLI_snprintf(name, sizeof(collections[i]->name), "%d", i + 1);
collections[i] = BKE_collection_add(scene, sc_master, name);
is_visible[i] = (scene->lay & (1 << i));
}
for (Base *base = scene->base.first; base; base = base->next) {
lay_used |= base->lay & ((1 << 20) - 1); /* ignore localview */
for (int i = 0; i < 20; i++) {
if ((base->lay & (1 << i)) != 0) {
BKE_collection_object_add(scene, collections[i], base->object);
}
}
}
scene->active_layer = 0;
if (!BKE_scene_uses_blender_game(scene)) {
for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) {
SceneLayer *sl = BKE_scene_layer_add(scene, srl->name);
BKE_scene_layer_engine_set(sl, scene->r.engine);
if (srl->mat_override) {
BKE_collection_override_datablock_add((LayerCollection *)sl->layer_collections.first, "material", (ID *)srl->mat_override);
}
if (srl->light_override && BKE_scene_uses_blender_internal(scene)) {
/* not sure how we handle this, pending until we design the override system */
TODO_LAYER_OVERRIDE;
}
if (srl->lay != scene->lay) {
/* unlink master collection */
BKE_collection_unlink(sl, sl->layer_collections.first);
/* add new collection bases */
for (int i = 0; i < 20; i++) {
if ((srl->lay & (1 << i)) != 0) {
BKE_collection_link(sl, collections[i]);
}
}
}
/* TODO: passes, samples, mask_layesr, exclude, ... */
}
if (BLI_findlink(&scene->render_layers, scene->r.actlay)) {
scene->active_layer = scene->r.actlay;
}
}
SceneLayer *sl = BKE_scene_layer_add(scene, "Render Layer");
/* In this particular case we can safely assume the data struct */
LayerCollection *lc = ((LayerCollection *)sl->layer_collections.first)->layer_collections.first;
for (int i = 0; i < 20; i++) {
if (!is_visible[i]) {
lc->flag &= ~COLLECTION_VISIBLE;
}
lc = lc->next;
}
/* but we still need to make the flags synced */
BKE_scene_layer_base_flag_recalculate(sl);
/* convert active base */
if (scene->basact) {
sl->basact = BKE_scene_layer_base_find(sl, scene->basact->object);
}
/* convert selected bases */
for (Base *base = scene->base.first; base; base = base->next) {
ObjectBase *ob_base = BKE_scene_layer_base_find(sl, base->object);
if ((base->flag & SELECT) != 0) {
if ((ob_base->flag & BASE_SELECTABLED) != 0) {
ob_base->flag |= BASE_SELECTED;
}
}
else {
ob_base->flag &= ~BASE_SELECTED;
}
}
/* TODO: copy scene render data to layer */
/* Cleanup */
for (int i = 0; i < 20; i++) {
if ((lay_used & (1 << i)) == 0) {
BKE_collection_remove(scene, collections[i]);
}
}
/* remove bases once and for all */
for (Base *base = scene->base.first; base; base = base->next) {
id_us_min(&base->object->id);
}
BLI_freelistN(&scene->base);
scene->basact = NULL;
}
}
}
}
void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
{
if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
if (!DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "render_layers")) {
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
/* Master Collection */
scene->collection = MEM_callocN(sizeof(SceneCollection), "Master Collection");
BLI_strncpy(scene->collection->name, "Master Collection", sizeof(scene->collection->name));
}
}
}
}

View File

@@ -120,6 +120,7 @@
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_lamp_types.h"
#include "DNA_layer_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
@@ -1893,6 +1894,8 @@ static void write_objects(WriteData *wd, ListBase *idbase)
writelist(wd, DATA, LinkData, &ob->pc_ids);
writelist(wd, DATA, LodLevel, &ob->lodlevels);
ob->collection_settings = NULL;
}
write_previews(wd, ob->preview);
@@ -2270,6 +2273,7 @@ static void write_meshes(WriteData *wd, ListBase *idbase)
CustomData_reset(&mesh->pdata);
CustomData_reset(&mesh->ldata);
mesh->edit_btmesh = NULL;
mesh->batch_cache = NULL;
/* now fill in polys to mfaces */
/* XXX This breaks writing design, by using temp allocated memory, which will likely generate
@@ -2467,6 +2471,21 @@ static void write_textures(WriteData *wd, ListBase *idbase)
mywrite_flush(wd);
}
static void write_material_engines_settings(WriteData *wd, ListBase *lb)
{
for (MaterialEngineSettings *res = lb->first; res; res = res->next) {
writestruct(wd, DATA, MaterialEngineSettings, 1, res);
if (STREQ(res->name, RE_engine_id_BLENDER_CLAY)) {
writestruct(wd, DATA, MaterialEngineSettingsClay, 1, res->data);
}
else {
/* No engine matched */
/* error: don't know how to write this file */
}
}
}
static void write_materials(WriteData *wd, ListBase *idbase)
{
Material *ma;
@@ -2503,6 +2522,8 @@ static void write_materials(WriteData *wd, ListBase *idbase)
}
write_previews(wd, ma->preview);
write_material_engines_settings(wd, &ma->engines_settings);
}
ma = ma->id.next;
}
@@ -2625,6 +2646,67 @@ static void write_paint(WriteData *wd, Paint *p)
}
}
static void write_scene_collection(WriteData *wd, SceneCollection *sc)
{
writestruct(wd, DATA, SceneCollection, 1, sc);
writelist(wd, DATA, LinkData, &sc->objects);
writelist(wd, DATA, LinkData, &sc->filter_objects);
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
write_scene_collection(wd, nsc);
}
}
static void write_collection_engine_settings(WriteData *wd, ListBase *lb)
{
for (CollectionEngineSettings *ces = lb->first; ces; ces = ces->next) {
writestruct(wd, DATA, CollectionEngineSettings, 1, ces);
for (CollectionEngineProperty *prop = ces->properties.first; prop; prop = prop->next) {
switch (prop->type) {
case COLLECTION_PROP_TYPE_FLOAT:
writestruct(wd, DATA, CollectionEnginePropertyFloat, 1, prop);
break;
case COLLECTION_PROP_TYPE_INT:
writestruct(wd, DATA, CollectionEnginePropertyInt, 1, prop);
break;
default:
; /* error: don't know how to write this file */
}
}
}
}
static void write_layer_collections(WriteData *wd, ListBase *lb)
{
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
writestruct(wd, DATA, LayerCollection, 1, lc);
writelist(wd, DATA, LinkData, &lc->object_bases);
writelist(wd, DATA, CollectionOverride, &lc->overrides);
write_collection_engine_settings(wd, &lc->engine_settings);
write_layer_collections(wd, &lc->layer_collections);
}
}
static void write_render_engines_settings(WriteData *wd, ListBase *lb)
{
for (RenderEngineSettings *res = lb->first; res; res = res->next) {
writestruct(wd, DATA, RenderEngineSettings, 1, res);
if (STREQ(res->name, RE_engine_id_BLENDER_CLAY)) {
writestruct(wd, DATA, RenderEngineSettingsClay, 1, res->data);
}
else {
/* No engine matched */
/* error: don't know how to write this file */
}
}
}
static void write_scenes(WriteData *wd, ListBase *scebase)
{
Scene *sce;
@@ -2640,6 +2722,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
ToolSettings *tos;
FreestyleModuleConfig *fmc;
FreestyleLineSet *fls;
SceneLayer *sl;
sce = scebase->first;
while (sce) {
@@ -2845,6 +2928,16 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
write_previews(wd, sce->preview);
write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve);
write_scene_collection(wd, sce->collection);
for (sl = sce->render_layers.first; sl; sl = sl->next) {
writestruct(wd, DATA, SceneLayer, 1, sl);
writelist(wd, DATA, ObjectBase, &sl->object_bases);
write_layer_collections(wd, &sl->layer_collections);
}
write_render_engines_settings(wd, &sce->engines_settings);
sce = sce->id.next;
}
@@ -3166,6 +3259,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
else if (sl->spacetype == SPACE_INFO) {
writestruct(wd, DATA, SpaceInfo, 1, sl);
}
else if (sl->spacetype == SPACE_COLLECTIONS) {
writestruct(wd, DATA, SpaceCollections, 1, sl);
}
sl = sl->next;
}

View File

@@ -57,6 +57,7 @@ extern "C" {
#include "BLI_fileops.h"
#include "BKE_camera.h"
#include "BKE_collection.h"
#include "BKE_main.h"
#include "BKE_lamp.h"
#include "BKE_library.h"
@@ -418,7 +419,7 @@ Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Nod
Object *obn = BKE_object_copy(G.main, source_ob);
DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
BKE_scene_base_add(sce, obn);
BKE_collection_object_add_from(sce, source_ob, obn);
if (instance_node) {
anim_importer.read_node_transform(instance_node, obn);

View File

@@ -26,37 +26,53 @@
set(INC
.
intern
nodes
operations
engines/clay
../blenkernel
../blenlib
../blentranslation
../imbuf
../depsgraph
../makesdna
../makesrna
../windowmanager
../nodes
../nodes/composite
../nodes/intern
../gpu
../editors/include
../editors/space_view3d
../render/extern/include
../render/intern/include
../../../extern/clew/include
../../../intern/glew-mx
../../../intern/guardedalloc
../../../intern/atomic
)
set(INC_SYS
${GLEW_INCLUDE_PATH}
)
set(SRC
DRW_defines.h
intern/draw_manager.c
intern/draw_mode_pass.c
intern/draw_cache.c
engines/clay/clay.c
intern/DRW_render.h
intern/draw_mode_pass.h
intern/draw_cache.h
engines/clay/clay.h
./DRW_engine.h
)
if(WITH_CLAY_ENGINE)
add_definitions(-DWITH_CLAY_ENGINE)
endif()
data_to_c_simple(engines/clay/shaders/clay_frag.glsl SRC)
data_to_c_simple(engines/clay/shaders/clay_vert.glsl SRC)
data_to_c_simple(engines/clay/shaders/ssao_alchemy.glsl SRC)
data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
list(APPEND INC
)
endif()
blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}")

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file DRW_engine.h
* \ingroup draw
*/
#ifndef __DRW_ENGINE_H__
#define __DRW_ENGINE_H__
//#define WITH_VIEWPORT_CACHE_TEST
struct DRWPass;
struct Material;
struct Scene;
void DRW_engines_init(void);
void DRW_engines_free(void);
/* This is here because GPUViewport needs it */
void DRW_pass_free(struct DRWPass *pass);
/* Settings */
void *DRW_material_settings_get(struct Material *ma, const char *engine_name);
void *DRW_render_settings_get(struct Scene *scene, const char *engine_name);
#endif /* __DRW_ENGINE_H__ */

View File

@@ -0,0 +1,722 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
#include "DRW_render.h"
#include "BKE_icons.h"
#include "BKE_main.h"
#include "BLI_dynstr.h"
#include "BLI_rand.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "UI_resources.h"
#include "UI_interface_icons.h"
#include "clay.h"
#ifdef WITH_CLAY_ENGINE
/* Shaders */
extern char datatoc_clay_frag_glsl[];
extern char datatoc_clay_vert_glsl[];
extern char datatoc_ssao_alchemy_glsl[];
extern char datatoc_ssao_groundtruth_glsl[];
/* Storage */
/* UBOs data needs to be 16 byte aligned (size of vec4) */
/* Reminder : float, int, bool are 4 bytes */
typedef struct CLAY_UBO_Material {
float ssao_params_var[4];
/* - 16 -*/
float matcap_hsv[3];
float matcap_id; /* even float encoding have enough precision */
/* - 16 -*/
float matcap_rot[2];
float pad[2]; /* ensure 16 bytes alignement */
} CLAY_UBO_Material; /* 48 bytes */
typedef struct CLAY_UBO_Storage {
CLAY_UBO_Material materials[512]; /* 512 = 9 bit material id */
} CLAY_UBO_Storage;
static struct CLAY_data {
/* Depth Pre Pass */
struct GPUShader *depth_sh;
/* Shading Pass */
struct GPUShader *clay_sh;
/* Materials Parameter UBO */
struct GPUUniformBuffer *mat_ubo;
CLAY_UBO_Storage mat_storage;
short ubo_flag;
/* Matcap textures */
struct GPUTexture *matcap_array;
float matcap_colors[24][3];
/* Ssao */
float winmat[4][4];
float viewvecs[3][4];
float ssao_params[4];
struct GPUTexture *jitter_tx;
struct GPUTexture *sampling_tx;
} data = {NULL};
/* CLAY_data.ubo_flag */
enum {
CLAY_UBO_CLEAR = (1 << 0),
CLAY_UBO_REFRESH = (1 << 1),
};
/* keep it under MAX_BUFFERS */
typedef struct CLAY_FramebufferList{
/* default */
struct GPUFrameBuffer *default_fb;
/* engine specific */
struct GPUFrameBuffer *downsample_depth;
} CLAY_FramebufferList;
/* keep it under MAX_TEXTURES */
typedef struct CLAY_TextureList{
/* default */
struct GPUTexture *color;
struct GPUTexture *depth;
/* engine specific */
struct GPUTexture *depth_low;
} CLAY_TextureList;
/* for clarity follow the same layout as CLAY_TextureList */
enum {
SCENE_COLOR,
SCENE_DEPTH,
SCENE_DEPTH_LOW,
};
/* keep it under MAX_PASSES */
typedef struct CLAY_PassList{
/* default */
struct DRWPass *non_meshes_pass;
struct DRWPass *ob_center_pass;
/* engine specific */
struct DRWPass *depth_pass;
struct DRWPass *clay_pass;
struct DRWPass *wire_overlay_pass;
struct DRWPass *wire_outline_pass;
} CLAY_PassList;
//#define GTAO
/* Functions */
static void add_icon_to_rect(PreviewImage *prv, float *final_rect, int layer)
{
int image_size = prv->w[0] * prv->h[0];
float *new_rect = &final_rect[image_size * 4 * layer];
IMB_buffer_float_from_byte(new_rect, (unsigned char *)prv->rect[0], IB_PROFILE_SRGB, IB_PROFILE_SRGB,
false, prv->w[0], prv->h[0], prv->w[0], prv->w[0]);
/* Find overall color */
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
data.matcap_colors[layer][0] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 0];
data.matcap_colors[layer][1] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 1];
data.matcap_colors[layer][2] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 2];
}
}
data.matcap_colors[layer][0] /= 16.0f * 2.0f; /* the * 2 is to darken for shadows */
data.matcap_colors[layer][1] /= 16.0f * 2.0f;
data.matcap_colors[layer][2] /= 16.0f * 2.0f;
}
static struct GPUTexture *load_matcaps(PreviewImage *prv[24], int nbr)
{
struct GPUTexture *tex;
int w = prv[0]->w[0];
int h = prv[0]->h[0];
float *final_rect = MEM_callocN(sizeof(float) * 4 * w * h * nbr, "Clay Matcap array rect");
for (int i = 0; i < nbr; ++i) {
add_icon_to_rect(prv[i], final_rect, i);
BKE_previewimg_free(&prv[i]);
}
tex = DRW_texture_create_2D_array(w, h, nbr, DRW_TEX_RGBA_8, DRW_TEX_FILTER, final_rect);
MEM_freeN(final_rect);
return tex;
}
static int matcap_to_index(int matcap)
{
if (matcap == ICON_MATCAP_02) return 1;
else if (matcap == ICON_MATCAP_03) return 2;
else if (matcap == ICON_MATCAP_04) return 3;
else if (matcap == ICON_MATCAP_05) return 4;
else if (matcap == ICON_MATCAP_06) return 5;
else if (matcap == ICON_MATCAP_07) return 6;
else if (matcap == ICON_MATCAP_08) return 7;
else if (matcap == ICON_MATCAP_09) return 8;
else if (matcap == ICON_MATCAP_10) return 9;
else if (matcap == ICON_MATCAP_11) return 10;
else if (matcap == ICON_MATCAP_12) return 11;
else if (matcap == ICON_MATCAP_13) return 12;
else if (matcap == ICON_MATCAP_14) return 13;
else if (matcap == ICON_MATCAP_15) return 14;
else if (matcap == ICON_MATCAP_16) return 15;
else if (matcap == ICON_MATCAP_17) return 16;
else if (matcap == ICON_MATCAP_18) return 17;
else if (matcap == ICON_MATCAP_19) return 18;
else if (matcap == ICON_MATCAP_20) return 19;
else if (matcap == ICON_MATCAP_21) return 20;
else if (matcap == ICON_MATCAP_22) return 21;
else if (matcap == ICON_MATCAP_23) return 22;
else if (matcap == ICON_MATCAP_24) return 23;
return 0;
}
static struct GPUTexture *create_spiral_sample_texture(int numsaples)
{
struct GPUTexture *tex;
float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * numsaples, "concentric_tex");
const float numsaples_inv = 1.0f / numsaples;
int i;
/* arbitrary number to ensure we don't get conciding samples every circle */
const float spirals = 7.357;
for (i = 0; i < numsaples; i++) {
float r = (i + 0.5f) * numsaples_inv;
float phi = r * spirals * (float)(2.0 * M_PI);
texels[i][0] = r * cosf(phi);
texels[i][1] = r * sinf(phi);
}
tex = DRW_texture_create_1D(numsaples, DRW_TEX_RG_16, 0, (float *)texels);
MEM_freeN(texels);
return tex;
}
static struct GPUTexture *create_jitter_texture(void)
{
float jitter[64 * 64][2];
int i;
/* TODO replace by something more evenly distributed like blue noise */
for (i = 0; i < 64 * 64; i++) {
#ifdef GTAO
jitter[i][0] = BLI_frand();
jitter[i][1] = BLI_frand();
#else
jitter[i][0] = 2.0f * BLI_frand() - 1.0f;
jitter[i][1] = 2.0f * BLI_frand() - 1.0f;
normalize_v2(jitter[i]);
#endif
}
return DRW_texture_create_2D(64, 64, DRW_TEX_RG_16, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
}
static void clay_material_settings_init(MaterialEngineSettingsClay *ma)
{
ma->matcap_icon = ICON_MATCAP_01;
ma->matcap_rot = 0.0f;
ma->matcap_hue = 0.5f;
ma->matcap_sat = 0.5f;
ma->matcap_val = 0.5f;
ma->ssao_distance = 0.2;
ma->ssao_attenuation = 1.0f;
ma->ssao_factor_cavity = 1.0f;
ma->ssao_factor_edge = 1.0f;
}
RenderEngineSettings *CLAY_render_settings_create(void)
{
RenderEngineSettingsClay *settings = MEM_callocN(sizeof(RenderEngineSettingsClay), "RenderEngineSettingsClay");
clay_material_settings_init((MaterialEngineSettingsClay *)settings);
settings->ssao_samples = 32;
return (RenderEngineSettings *)settings;
}
MaterialEngineSettings *CLAY_material_settings_create(void)
{
MaterialEngineSettingsClay *settings = MEM_callocN(sizeof(MaterialEngineSettingsClay), "MaterialEngineSettingsClay");
clay_material_settings_init(settings);
return (MaterialEngineSettings *)settings;
}
static void CLAY_engine_init(const bContext *C)
{
Main *bmain = CTX_data_main(C);
/* Create Texture Array */
if (!data.matcap_array) {
PreviewImage *prv[24]; /* For now use all of the 24 internal matcaps */
/* TODO only load used matcaps */
prv[0] = UI_icon_to_preview(ICON_MATCAP_01);
prv[1] = UI_icon_to_preview(ICON_MATCAP_02);
prv[2] = UI_icon_to_preview(ICON_MATCAP_03);
prv[3] = UI_icon_to_preview(ICON_MATCAP_04);
prv[4] = UI_icon_to_preview(ICON_MATCAP_05);
prv[5] = UI_icon_to_preview(ICON_MATCAP_06);
prv[6] = UI_icon_to_preview(ICON_MATCAP_07);
prv[7] = UI_icon_to_preview(ICON_MATCAP_08);
prv[8] = UI_icon_to_preview(ICON_MATCAP_09);
prv[9] = UI_icon_to_preview(ICON_MATCAP_10);
prv[10] = UI_icon_to_preview(ICON_MATCAP_11);
prv[11] = UI_icon_to_preview(ICON_MATCAP_12);
prv[12] = UI_icon_to_preview(ICON_MATCAP_13);
prv[13] = UI_icon_to_preview(ICON_MATCAP_14);
prv[14] = UI_icon_to_preview(ICON_MATCAP_15);
prv[15] = UI_icon_to_preview(ICON_MATCAP_16);
prv[16] = UI_icon_to_preview(ICON_MATCAP_17);
prv[17] = UI_icon_to_preview(ICON_MATCAP_18);
prv[18] = UI_icon_to_preview(ICON_MATCAP_19);
prv[19] = UI_icon_to_preview(ICON_MATCAP_20);
prv[20] = UI_icon_to_preview(ICON_MATCAP_21);
prv[21] = UI_icon_to_preview(ICON_MATCAP_22);
prv[22] = UI_icon_to_preview(ICON_MATCAP_23);
prv[23] = UI_icon_to_preview(ICON_MATCAP_24);
data.matcap_array = load_matcaps(prv, 24);
}
/* AO Jitter */
if (!data.jitter_tx) {
data.jitter_tx = create_jitter_texture();
}
/* AO Samples */
/* TODO use hammersley sequence */
if (!data.sampling_tx) {
data.sampling_tx = create_spiral_sample_texture(500);
}
/* Depth prepass */
if (!data.depth_sh) {
data.depth_sh = DRW_shader_create_3D_depth_only();
}
if (!data.mat_ubo) {
data.mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL);
}
/* Shading pass */
if (!data.clay_sh) {
DynStr *ds = BLI_dynstr_new();
const char *max_mat =
"#define MAX_MATERIAL 512\n"
"#define USE_ROTATION\n"
"#define USE_AO\n"
"#define USE_HSV\n";
char *matcap_with_ao;
BLI_dynstr_append(ds, datatoc_clay_frag_glsl);
#ifdef GTAO
BLI_dynstr_append(ds, datatoc_ssao_groundtruth_glsl);
#else
BLI_dynstr_append(ds, datatoc_ssao_alchemy_glsl);
#endif
matcap_with_ao = BLI_dynstr_get_cstring(ds);
data.clay_sh = DRW_shader_create(datatoc_clay_vert_glsl, NULL, matcap_with_ao, max_mat);
BLI_dynstr_free(ds);
MEM_freeN(matcap_with_ao);
}
/* Cleanup all runtime data loaded from file */
for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
/* Using render settings as material settings */
MaterialEngineSettingsClay *res = DRW_render_settings_get(sce, RE_engine_id_BLENDER_CLAY);
res->flag = CLAY_OUTDATED;
res->ubo_index = -1;
/* Update Collections Materials */
for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
CollectionEngineSettings *ces;
ces = BKE_layer_collection_engine_get(lc, RE_engine_id_BLENDER_CLAY);
if (ces) { /* May not exists */
BKE_collection_engine_property_value_set_int(ces, "flag", CLAY_OUTDATED);
BKE_collection_engine_property_value_set_int(ces, "ubo_index", -1);
}
}
}
}
data.ubo_flag |= CLAY_UBO_REFRESH;
}
static void CLAY_ssao_setup(void)
{
float invproj[4][4];
float dfdyfacs[2];
bool is_persp = DRW_viewport_is_persp_get();
/* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */
float viewvecs[3][4] = {
{-1.0f, -1.0f, -1.0f, 1.0f},
{1.0f, -1.0f, -1.0f, 1.0f},
{-1.0f, 1.0f, -1.0f, 1.0f}
};
int i;
float *size = DRW_viewport_size_get();
RenderEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY);
DRW_get_dfdy_factors(dfdyfacs);
data.ssao_params[0] = settings->ssao_samples;
data.ssao_params[1] = size[0] / 64.0;
data.ssao_params[2] = size[1] / 64.0;
data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
/* invert the view matrix */
DRW_viewport_matrix_get(data.winmat, DRW_MAT_WIN);
invert_m4_m4(invproj, data.winmat);
/* convert the view vectors to view space */
for (i = 0; i < 3; i++) {
mul_m4_v4(invproj, viewvecs[i]);
/* normalized trick see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
if (is_persp)
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
viewvecs[i][3] = 1.0;
copy_v4_v4(data.viewvecs[i], viewvecs[i]);
}
/* we need to store the differences */
data.viewvecs[1][0] -= data.viewvecs[0][0];
data.viewvecs[1][1] = data.viewvecs[2][1] - data.viewvecs[0][1];
/* calculate a depth offset as well */
if (!is_persp) {
float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
mul_m4_v4(invproj, vec_far);
mul_v3_fl(vec_far, 1.0f / vec_far[3]);
data.viewvecs[1][2] = vec_far[2] - data.viewvecs[0][2];
}
}
static DRWShadingGroup *CLAY_shgroup_create(DRWPass *pass, int *UNUSED(material_id))
{
const int depthloc = 0, matcaploc = 1, jitterloc = 2, sampleloc = 3;
//CLAY_UBO_Material *mat = &data.mat_storage.materials[0];
DRWShadingGroup *grp = DRW_shgroup_create(data.clay_sh, pass);
DRW_shgroup_uniform_vec2(grp, "screenres", DRW_viewport_size_get(), 1);
DRW_shgroup_uniform_buffer(grp, "depthtex", SCENE_DEPTH, depthloc);
DRW_shgroup_uniform_texture(grp, "matcaps", data.matcap_array, matcaploc);
DRW_shgroup_uniform_mat4(grp, "WinMatrix", (float *)data.winmat);
DRW_shgroup_uniform_vec4(grp, "viewvecs", (float *)data.viewvecs, 3);
DRW_shgroup_uniform_vec4(grp, "ssao_params", data.ssao_params, 1);
DRW_shgroup_uniform_vec3(grp, "matcaps_color", (float *)data.matcap_colors, 24);
//DRW_shgroup_uniform_int(grp, "material_id", material_id, 1);
#ifndef GTAO
DRW_shgroup_uniform_texture(grp, "ssao_jitter", data.jitter_tx, jitterloc);
DRW_shgroup_uniform_texture(grp, "ssao_samples", data.sampling_tx, sampleloc);
#endif
return grp;
}
static void update_ubo_storage(float matcap_rot, float matcap_hue, float matcap_sat, float matcap_val,
float ssao_distance, float ssao_factor_cavity, float ssao_factor_edge,
float ssao_attenuation, int matcap_icon, unsigned int current_id)
{
CLAY_UBO_Material *ubo = &data.mat_storage.materials[current_id];
ubo->matcap_rot[0] = cosf(matcap_rot * 3.14159f * 2.0f);
ubo->matcap_rot[1] = sinf(matcap_rot * 3.14159f * 2.0f);
ubo->matcap_hsv[0] = matcap_hue + 0.5f;
ubo->matcap_hsv[1] = matcap_sat * 2.0f;
ubo->matcap_hsv[2] = matcap_val * 2.0f;
ubo->ssao_params_var[0] = ssao_distance;
ubo->ssao_params_var[1] = ssao_factor_cavity;
ubo->ssao_params_var[2] = ssao_factor_edge;
ubo->ssao_params_var[3] = ssao_attenuation;
ubo->matcap_id = matcap_to_index(matcap_icon);
}
static void CLAY_update_material_ubo(const struct bContext *C)
{
Main *bmain = CTX_data_main(C);
/* Update Default materials */
for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
/* Using render settings as material settings */
MaterialEngineSettingsClay *res = DRW_render_settings_get(sce, RE_engine_id_BLENDER_CLAY);
if (res->flag & CLAY_OUTDATED)
data.ubo_flag |= CLAY_UBO_REFRESH;
if (res->matcap_icon < ICON_MATCAP_01 ||
res->matcap_icon > ICON_MATCAP_24)
{
res->matcap_icon = ICON_MATCAP_01;
}
res->flag &= ~CLAY_OUTDATED;
/* Update Collections Materials */
for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
CollectionEngineSettings *ces;
ces = BKE_layer_collection_engine_get(lc, RE_engine_id_BLENDER_CLAY);
BKE_collection_engine_property_value_set_int(ces, "flag", 0);
BKE_collection_engine_property_value_set_int(ces, "ubo_index", 0);
}
}
}
if (data.ubo_flag & CLAY_UBO_REFRESH) {
int current_id = 0;
/* Default materials */
for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
MaterialEngineSettingsClay *res = DRW_render_settings_get(sce, RE_engine_id_BLENDER_CLAY);
update_ubo_storage(res->matcap_rot, res->matcap_hue, res->matcap_sat, res->matcap_val,
res->ssao_distance, res->ssao_factor_cavity, res->ssao_factor_edge,
res->ssao_attenuation, res->matcap_icon, current_id);
current_id++;
for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
/* TODO */
current_id++;
}
}
current_id++;
}
DRW_uniformbuffer_update(data.mat_ubo, &data.mat_storage);
}
data.ubo_flag = 0;
}
static void CLAY_create_cache(CLAY_PassList *passes, const struct bContext *C)
{
SceneLayer *sl = CTX_data_scene_layer(C);
DRWShadingGroup *default_shgrp, *depthbatch;
/* Depth Pass */
{
passes->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
depthbatch = DRW_shgroup_create(data.depth_sh, passes->depth_pass);
}
/* Clay Pass */
{
MaterialEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY);
passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
default_shgrp = CLAY_shgroup_create(passes->clay_pass, &settings->ubo_index);
DRW_shgroup_uniform_block(default_shgrp, "material_block", data.mat_ubo, 0);
}
/* Object Mode */
{
DRW_pass_setup_common(&passes->wire_overlay_pass,
&passes->wire_outline_pass,
&passes->non_meshes_pass,
&passes->ob_center_pass);
}
/* TODO Create hash table of batch based on material id*/
Object *ob;
DEG_OBJECT_ITER(sl, ob)
{
if ((ob->base_flag & BASE_VISIBLED) == 0) {
continue;
}
struct Batch *geom;
//bool do_outlines;
switch (ob->type) {
case OB_MESH:
geom = DRW_cache_surface_get(ob);
/* Add everything for now */
DRW_shgroup_call_add(depthbatch, geom, ob->obmat);
DRW_shgroup_call_add(default_shgrp, geom, ob->obmat);
//DRW_shgroup_wire_overlay(passes->wire_overlay_pass, ob);
//do_outlines = ((ob->base_flag & BASE_SELECTED) != 0);
//DRW_shgroup_wire_outline(passes->wire_outline_pass, ob, false, false, do_outlines);
/* When encountering a new material :
* - Create new Batch
* - Initialize Batch
* - Push it to the hash table
* - The pass takes care of inserting it
* next to the same shader calls */
/* Free hash table */
break;
case OB_LAMP:
case OB_CAMERA:
case OB_EMPTY:
default:
DRW_shgroup_non_meshes(passes->non_meshes_pass, ob);
break;
}
DRW_shgroup_object_center(passes->ob_center_pass, ob);
DRW_shgroup_relationship_lines(passes->non_meshes_pass, ob);
}
DEG_OBJECT_ITER_END
}
static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context)
{
/* This function may run for multiple viewports
* so get the current viewport buffers */
CLAY_FramebufferList *buffers = NULL;
CLAY_TextureList *textures = NULL;
CLAY_PassList *passes = NULL;
DRW_viewport_init(context, (void **)&buffers, (void **)&textures, (void **)&passes);
CLAY_engine_init(context);
CLAY_update_material_ubo(context);
/* TODO : tag to refresh by the deps graph */
/* ideally only refresh when objects are added/removed */
/* or render properties / materials change */
#ifdef WITH_VIEWPORT_CACHE_TEST
static bool once = false;
#endif
if (DRW_viewport_cache_is_dirty()
#ifdef WITH_VIEWPORT_CACHE_TEST
&& !once
#endif
) {
#ifdef WITH_VIEWPORT_CACHE_TEST
once = true;
#endif
CLAY_create_cache(passes, context);
}
/* Start Drawing */
DRW_draw_background();
/* Pass 1 : Depth pre-pass */
DRW_draw_pass(passes->depth_pass);
/* Pass 2 (Optionnal) : Separated Downsampled AO */
DRW_framebuffer_texture_detach(textures->depth);
/* TODO */
/* Pass 3 : Shading */
CLAY_ssao_setup();
DRW_draw_pass(passes->clay_pass);
/* Pass 4 : Overlays */
DRW_framebuffer_texture_attach(buffers->default_fb, textures->depth, 0);
//DRW_draw_pass(passes->wire_overlay_pass);
//DRW_draw_pass(passes->wire_outline_pass);
DRW_draw_pass(passes->non_meshes_pass);
DRW_draw_pass(passes->ob_center_pass);
/* Always finish by this */
DRW_state_reset();
}
static void CLAY_collection_settings_create(RenderEngine *UNUSED(engine), CollectionEngineSettings *ces)
{
BLI_assert(ces);
BKE_collection_engine_property_add_int(ces, "matcap_icon", ICON_MATCAP_01);
BKE_collection_engine_property_add_int(ces, "type", CLAY_MATCAP_NONE);
BKE_collection_engine_property_add_float(ces, "matcap_rotation", 0.0f);
BKE_collection_engine_property_add_float(ces, "matcap_hue", 0.5f);
BKE_collection_engine_property_add_float(ces, "matcap_saturation", 0.5f);
BKE_collection_engine_property_add_float(ces, "matcap_value", 0.5f);
BKE_collection_engine_property_add_float(ces, "ssao_distance", 0.2f);
BKE_collection_engine_property_add_float(ces, "ssao_attenuation", 1.0f);
BKE_collection_engine_property_add_float(ces, "ssao_factor_cavity", 1.0f);
BKE_collection_engine_property_add_float(ces, "ssao_factor_edge", 1.0f);
/* Runtime data (not display in settings) */
BKE_collection_engine_property_add_int(ces, "ubo_index", -1);
BKE_collection_engine_property_add_int(ces, "flag", CLAY_OUTDATED);
}
void clay_engine_free(void)
{
/* data.depth_sh Is builtin so it's automaticaly freed */
if (data.clay_sh) {
DRW_shader_free(data.clay_sh);
}
if (data.matcap_array) {
DRW_texture_free(data.matcap_array);
}
if (data.jitter_tx) {
DRW_texture_free(data.jitter_tx);
}
if (data.sampling_tx) {
DRW_texture_free(data.sampling_tx);
}
if (data.mat_ubo) {
DRW_uniformbuffer_free(data.mat_ubo);
}
}
RenderEngineType viewport_clay_type = {
NULL, NULL,
"BLENDER_CLAY", N_("Clay"), RE_INTERNAL | RE_USE_OGL_PIPELINE,
NULL, NULL, NULL, NULL, &CLAY_view_draw, NULL, &CLAY_collection_settings_create,
{NULL, NULL, NULL}
};
#endif

View File

@@ -19,7 +19,18 @@
*
*/
#ifndef __DRW_DEFINES_H__
#define __DRW_DEFINES_H__
/** \file clay.h
* \ingroup DNA
*/
#endif /* __DRW_DEFINES_H__ */
#ifndef __ENGINE_CLAY_H__
#define __ENGINE_CLAY_H__
extern RenderEngineType viewport_clay_type;
struct RenderEngineSettings *CLAY_render_settings_create(void);
struct MaterialEngineSettings *CLAY_material_settings_create(void);
void clay_engine_free(void);
#endif /* __ENGINE_CLAY_H__ */

View File

@@ -0,0 +1,207 @@
uniform vec2 screenres;
uniform sampler2D depthtex;
uniform mat4 WinMatrix;
/* Matcap */
uniform sampler2DArray matcaps;
uniform vec3 matcaps_color[24];
/* Screen Space Occlusion */
/* store the view space vectors for the corners of the view frustum here.
* It helps to quickly reconstruct view space vectors by using uv coordinates,
* see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
uniform vec4 viewvecs[3];
uniform vec4 ssao_params;
uniform sampler2D ssao_jitter;
uniform sampler1D ssao_samples;
/* Material Parameters packed in an UBO */
struct Material {
vec4 ssao_params_var;
vec4 matcap_hsv_id;
vec4 matcap_rot; /* vec4 to ensure 16 bytes alignement (don't trust compiler) */
};
layout(std140) uniform material_block {
Material matcaps_param[MAX_MATERIAL];
};
int mat_id;
/* Aliases */
#define ssao_samples_num ssao_params.x
#define jitter_tilling ssao_params.yz
#define dfdy_sign ssao_params.w
#define matcap_hsv matcaps_param[mat_id].matcap_hsv_id.xyz
#define matcap_index matcaps_param[mat_id].matcap_hsv_id.w
#define matcap_rotation matcaps_param[mat_id].matcap_rot.xy
in vec3 normal;
out vec4 fragColor;
/* TODO Move this to SSAO modules */
/* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer
* we change the factors from the article to fit the OpennGL model. */
vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth)
{
if (WinMatrix[3][3] == 0.0) {
/* Perspective */
float d = 2.0 * depth - 1.0;
float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]);
return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz);
}
else {
/* Orthographic */
vec3 offset = vec3(uvcoords, depth);
return viewvecs[0].xyz + offset * viewvecs[1].xyz;
}
}
/* TODO remove this when switching to geometric normals */
vec3 calculate_view_space_normal(in vec3 viewposition)
{
vec3 normal = cross(normalize(dFdx(viewposition)), dfdy_sign * normalize(dFdy(viewposition)));
return normalize(normal);
}
#ifdef USE_HSV
void rgb_to_hsv(vec3 rgb, out vec3 outcol)
{
float cmax, cmin, h, s, v, cdelta;
vec3 c;
cmax = max(rgb[0], max(rgb[1], rgb[2]));
cmin = min(rgb[0], min(rgb[1], rgb[2]));
cdelta = cmax - cmin;
v = cmax;
if (cmax != 0.0)
s = cdelta / cmax;
else {
s = 0.0;
h = 0.0;
}
if (s == 0.0) {
h = 0.0;
}
else {
c = (vec3(cmax, cmax, cmax) - rgb.xyz) / cdelta;
if (rgb.x == cmax) h = c[2] - c[1];
else if (rgb.y == cmax) h = 2.0 + c[0] - c[2];
else h = 4.0 + c[1] - c[0];
h /= 6.0;
if (h < 0.0)
h += 1.0;
}
outcol = vec3(h, s, v);
}
void hsv_to_rgb(vec3 hsv, out vec3 outcol)
{
float i, f, p, q, t, h, s, v;
vec3 rgb;
h = hsv[0];
s = hsv[1];
v = hsv[2];
if (s == 0.0) {
rgb = vec3(v, v, v);
}
else {
if (h == 1.0)
h = 0.0;
h *= 6.0;
i = floor(h);
f = h - i;
rgb = vec3(f, f, f);
p = v * (1.0 - s);
q = v * (1.0 - (s * f));
t = v * (1.0 - (s * (1.0 - f)));
if (i == 0.0) rgb = vec3(v, t, p);
else if (i == 1.0) rgb = vec3(q, v, p);
else if (i == 2.0) rgb = vec3(p, v, t);
else if (i == 3.0) rgb = vec3(p, q, v);
else if (i == 4.0) rgb = vec3(t, p, v);
else rgb = vec3(v, p, q);
}
outcol = rgb;
}
void hue_sat(float hue, float sat, float value, inout vec3 col)
{
vec3 hsv;
rgb_to_hsv(col, hsv);
hsv.x += hue;
hsv.x -= floor(hsv.x);
hsv.y *= sat;
hsv.y = clamp(hsv.y, 0.0, 1.0);
hsv.z *= value;
hsv.z = clamp(hsv.z, 0.0, 1.0);
hsv_to_rgb(hsv, col);
}
#endif
#ifdef USE_AO
/* Prototype */
void ssao_factors(in float depth, in vec3 normal, in vec3 position, in vec2 screenco, out float cavities, out float edges);
#endif
void main() {
vec2 screenco = vec2(gl_FragCoord.xy) / screenres;
float depth = texture(depthtex, screenco).r;
vec3 position = get_view_space_from_depth(screenco, depth);
vec3 normal = calculate_view_space_normal(position);
//mat_id = int(screenco.x*3.0);
/* Manual Depth test */
/* Doing this test earlier gives problem with dfdx calculations
* TODO move this before when we have proper geometric normals */
if (gl_FragCoord.z > depth + 1e-5)
discard;
#ifdef USE_ROTATION
/* Rotate texture coordinates */
vec2 rotY = vec2(-matcap_rotation.y, matcap_rotation.x);
vec2 texco = abs(vec2(dot(normal.xy, matcap_rotation), dot(normal.xy, rotY)) * .49 + 0.5);
#else
vec2 texco = abs(normal.xy * .49 + 0.5);
#endif
vec3 col = texture(matcaps, vec3(texco, matcap_index)).rgb;
#ifdef USE_AO
float cavity, edges;
ssao_factors(depth, normal, position, screenco, cavity, edges);
col *= mix(vec3(1.0), matcaps_color[int(matcap_index)], cavity);
#endif
#ifdef USE_HSV
hue_sat(matcap_hsv.x, matcap_hsv.y, matcap_hsv.z, col);
#endif
#ifdef USE_AO
/* Apply highlights after hue shift */
col *= edges + 1.0;
#endif
fragColor = vec4(col, 1.0);
}

View File

@@ -0,0 +1,20 @@
uniform mat4 ModelViewProjectionMatrix;
uniform mat3 NormalMatrix;
#if __VERSION__ == 120
attribute vec3 pos;
attribute vec3 nor;
varying vec3 normal;
#else
in vec3 pos;
in vec3 nor;
out vec3 normal;
#endif
void main()
{
normal = normalize(NormalMatrix * nor);
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
}

View File

@@ -0,0 +1,73 @@
#define ssao_distance matcaps_param[mat_id].ssao_params_var.x
#define ssao_factor_cavity matcaps_param[mat_id].ssao_params_var.y
#define ssao_factor_edge matcaps_param[mat_id].ssao_params_var.z
#define ssao_attenuation matcaps_param[mat_id].ssao_params_var.w
/* from The Alchemy screen-space ambient obscurance algorithm
* http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */
void ssao_factors(in float depth, in vec3 normal, in vec3 position, in vec2 screenco, out float cavities, out float edges)
{
/* take the normalized ray direction here */
vec2 rotX = texture2D(ssao_jitter, screenco.xy * jitter_tilling).rg;
vec2 rotY = vec2(-rotX.y, rotX.x);
/* find the offset in screen space by multiplying a point
* in camera space at the depth of the point by the projection matrix. */
vec2 offset;
float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3];
offset.x = WinMatrix[0][0] * ssao_distance / homcoord;
offset.y = WinMatrix[1][1] * ssao_distance / homcoord;
/* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
offset *= 0.5;
cavities = edges = 0.0;
int x;
int num_samples = int(ssao_samples_num);
for (x = 0; x < num_samples; x++) {
/* TODO : optimisation replace by constant */
vec2 dir_sample = texture1D(ssao_samples, (float(x) + 0.5) / ssao_samples_num).rg;
/* rotate with random direction to get jittered result */
vec2 dir_jittered = vec2(dot(dir_sample, rotX), dot(dir_sample, rotY));
vec2 uvcoords = screenco.xy + dir_jittered * offset;
if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0)
continue;
float depth_new = texture2D(depthtex, uvcoords).r;
/* Handle Background case */
bool is_background = (depth_new == 1.0);
/* This trick provide good edge effect even if no neighboor is found. */
vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new);
if (is_background)
pos_new.z -= ssao_distance;
vec3 dir = pos_new - position;
float len = length(dir);
float f_cavities = dot(dir, normal);
float f_edge = -f_cavities;
float f_bias = 0.05 * len + 0.0001;
float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation));
/* use minor bias here to avoid self shadowing */
if (f_cavities > -f_bias)
cavities += f_cavities * attenuation;
if (f_edge > f_bias)
edges += f_edge * attenuation;
}
cavities /= ssao_samples_num;
edges /= ssao_samples_num;
/* don't let cavity wash out the surface appearance */
cavities = clamp(cavities * ssao_factor_cavity, 0.0, 1.0);
edges = edges * ssao_factor_edge;
}

View File

@@ -0,0 +1,120 @@
#define ssao_distance matcaps_param[mat_id].ssao_params_var.x
#define ssao_factor_cavity matcaps_param[mat_id].ssao_params_var.y
#define ssao_factor_edge matcaps_param[mat_id].ssao_params_var.z
#define ssao_attenuation matcaps_param[mat_id].ssao_params_var.w
/* Based on Practical Realtime Strategies for Accurate Indirect Occlusion
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx */
#define COSINE_WEIGHTING
float integrate_arc(in float h1, in float h2, in float gamma, in float n_proj_len)
{
float a = 0.0;
#ifdef COSINE_WEIGHTING
float cos_gamma = cos(gamma);
float sin_gamma_2 = 2.0 * sin(gamma);
a += -cos(2.0 * h1 - gamma) + cos_gamma + h1 * sin_gamma_2;
a += -cos(2.0 * h2 - gamma) + cos_gamma + h2 * sin_gamma_2;
a *= 0.25; /* 1/4 */
a *= n_proj_len;
#else
/* Uniform weighting (slide 59) */
a += 1 - cos(h1);
a += 1 - cos(h2);
#endif
return a;
}
float get_max_horizon(in vec2 co, in vec3 x, in vec3 omega_o, in float h)
{
if (co.x > 1.0 || co.x < 0.0 || co.y > 1.0 || co.y < 0.0)
return h;
float depth = texture2D(depthtex, co).r;
/* Background case */
if (depth == 1.0)
return h;
vec3 s = get_view_space_from_depth(co, depth); /* s View coordinate */
vec3 omega_s = s - x;
float len = length(omega_s);
if (len < ssao_distance) {
omega_s /= len;
h = max(h, dot(omega_s, omega_o));
}
return h;
}
void ssao_factors(in float depth, in vec3 normal, in vec3 position, in vec2 screenco, out float cavities, out float edges)
{
/* Renaming */
vec3 omega_o = -normalize(position); /* viewvec */
vec2 x_ = screenco; /* x^ Screen coordinate */
vec3 x = position; /* x view space coordinate */
#ifdef SPATIAL_DENOISE
float noise_dir = (1.0 / 16.0) * float(((int(gl_FragCoord.x + gl_FragCoord.y) & 0x3) << 2) + (int(gl_FragCoord.x) & 0x3));
float noise_offset = (1.0 / 4.0) * float(int(gl_FragCoord.y - gl_FragCoord.x) & 0x3);
#else
float noise_dir = (1.0 / 16.0) * float(((int(gl_FragCoord.x + gl_FragCoord.y) & 0x3) << 2) + (int(gl_FragCoord.x) & 0x3));
float noise_offset = (0.5 / 16.0) + (1.0 / 16.0) * float(((int(gl_FragCoord.x - gl_FragCoord.y) & 0x3) << 2) + (int(gl_FragCoord.x) & 0x3));
#endif
const float phi_step = 16.0;
const float theta_step = 16.0;
const float m_pi = 3.14159265358979323846;
vec2 pixel_ratio = vec2(screenres.y / screenres.x, 1.0);
vec2 pixel_size = vec2(1.0) / screenres.xy;
float min_stride = length(pixel_size);
float homcco = WinMatrix[2][3] * position.z + WinMatrix[3][3];
float n = max(min_stride * theta_step, ssao_distance / homcco); /* Search distance */
/* Integral over PI */
float A = 0.0;
for (float i = 0.0; i < phi_step; i++) {
float phi = m_pi * ((noise_dir + i) / phi_step);
vec2 t_phi = vec2(cos(phi), sin(phi)); /* Screen space direction */
/* Search maximum horizon angles Theta1 and Theta2 */
float theta1 = -1.0, theta2 = -1.0; /* init at cos(pi) */
for (float j = 0.0; j < theta_step; j++) {
vec2 s_ = t_phi * pixel_ratio * n * ((j + noise_offset)/ theta_step); /* s^ Screen coordinate */
vec2 co;
co = x_ + s_;
theta1 = get_max_horizon(co, x, omega_o, theta1);
co = x_ - s_;
theta2 = get_max_horizon(co, x, omega_o, theta2);
}
/* (Slide 54) */
theta1 = -acos(theta1);
theta2 = acos(theta2);
/* Projecting Normal to Plane P defined by t_phi and omega_o */
vec3 h = normalize(cross(vec3(t_phi, 0.0), omega_o)); /* Normal vector to Integration plane */
vec3 t = cross(h, omega_o); /* Normal vector to plane */
vec3 n_proj = normal - h * dot(normal, h);
float n_proj_len = length(n_proj);
vec3 n_proj_norm = normalize(n_proj);
/* Clamping thetas (slide 58) */
float gamma = sign(dot(n_proj_norm, t)) * acos(dot(normal, omega_o)); /* Angle between view vec and normal */
theta1 = gamma + max(theta1 - gamma, -m_pi * 0.5);
theta2 = gamma + min(theta2 - gamma, m_pi * 0.5);
/* Solving inner integral */
A += integrate_arc(theta1, theta2, gamma, n_proj_len);
}
A /= phi_step;
cavities = 1.0 - A;
edges = 0.0;
}

View File

@@ -0,0 +1,221 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file DRW_render.h
* \ingroup draw
*/
/* This is the Render Functions used by Realtime engines to draw with OpenGL */
#ifndef __DRW_RENDER_H__
#define __DRW_RENDER_H__
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_scene.h"
#include "BLI_listbase.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
#include "BLI_string.h"
#include "BLT_translation.h"
#include "DNA_object_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
#include "draw_mode_pass.h"
#include "draw_cache.h"
#include "MEM_guardedalloc.h"
#include "RE_engine.h"
//#define WITH_VIEWPORT_CACHE_TEST
struct GPUFrameBuffer;
struct GPUShader;
struct GPUTexture;
struct GPUUniformBuffer;
struct Object;
struct Batch;
typedef struct DRWUniform DRWUniform;
typedef struct DRWInterface DRWInterface;
typedef struct DRWPass DRWPass;
typedef struct DRWShadingGroup DRWShadingGroup;
/* Textures */
typedef enum {
DRW_TEX_RGBA_8,
DRW_TEX_RGBA_16,
DRW_TEX_RGBA_32,
DRW_TEX_RGB_8,
DRW_TEX_RGB_16,
DRW_TEX_RGB_32,
DRW_TEX_RG_8,
DRW_TEX_RG_16,
DRW_TEX_RG_32,
DRW_TEX_R_8,
DRW_TEX_R_16,
DRW_TEX_R_32,
DRW_TEX_DEPTH_16,
DRW_TEX_DEPTH_24,
DRW_TEX_DEPTH_32,
} DRWTextureFormat;
typedef enum {
DRW_TEX_FILTER = (1 << 0),
DRW_TEX_WRAP = (1 << 1),
DRW_TEX_COMPARE = (1 << 2),
} DRWTextureFlag;
struct GPUTexture *DRW_texture_create_1D(
int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels);
struct GPUTexture *DRW_texture_create_2D(
int w, int h, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels);
struct GPUTexture *DRW_texture_create_2D_array(
int w, int h, int d, DRWTextureFormat UNUSED(format), DRWTextureFlag flags, const float *fpixels);
void DRW_texture_free(struct GPUTexture *tex);
/* UBOs */
struct GPUUniformBuffer *DRW_uniformbuffer_create(int size, const void *data);
void DRW_uniformbuffer_update(struct GPUUniformBuffer *ubo, const void *data);
void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo);
/* Buffers */
/* DRWFboTexture->format */
#define DRW_BUF_DEPTH_16 1
#define DRW_BUF_DEPTH_24 2
#define DRW_BUF_R_8 3
#define DRW_BUF_R_16 4
#define DRW_BUF_R_32 5
#define DRW_BUF_RG_8 6
#define DRW_BUF_RG_16 7
#define DRW_BUF_RG_32 8
#define DRW_BUF_RGB_8 9
#define DRW_BUF_RGB_16 10
#define DRW_BUF_RGB_32 11
#define DRW_BUF_RGBA_8 12
#define DRW_BUF_RGBA_16 13
#define DRW_BUF_RGBA_32 14
#define MAX_FBO_TEX 5
typedef struct DRWFboTexture {
struct GPUTexture **tex;
int format;
} DRWFboTexture;
void DRW_framebuffer_init(struct GPUFrameBuffer **fb, int width, int height, DRWFboTexture textures[MAX_FBO_TEX], int texnbr);
void DRW_framebuffer_bind(struct GPUFrameBuffer *fb);
void DRW_framebuffer_texture_attach(struct GPUFrameBuffer *fb, struct GPUTexture *tex, int slot);
void DRW_framebuffer_texture_detach(struct GPUTexture *tex);
/* Shaders */
struct GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_3D_depth_only(void);
void DRW_shader_free(struct GPUShader *shader);
/* Batches */
typedef enum {
DRW_STATE_WRITE_DEPTH = (1 << 0),
DRW_STATE_WRITE_COLOR = (1 << 1),
DRW_STATE_DEPTH_LESS = (1 << 2),
DRW_STATE_DEPTH_EQUAL = (1 << 3),
DRW_STATE_CULL_BACK = (1 << 4),
DRW_STATE_CULL_FRONT = (1 << 5),
DRW_STATE_WIRE = (1 << 6),
DRW_STATE_WIRE_LARGE = (1 << 7),
DRW_STATE_POINT = (1 << 8),
DRW_STATE_STIPPLE_2 = (1 << 9),
DRW_STATE_STIPPLE_3 = (1 << 10),
DRW_STATE_STIPPLE_4 = (1 << 11),
DRW_STATE_BLEND = (1 << 12),
} DRWState;
/* Used by DRWShadingGroup.dyntype */
#define DRW_DYN_POINTS 1
#define DRW_DYN_LINES 2
#define DRW_DYN_INSTANCE 3
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Batch *geom, float (*obmat)[4]);
void DRW_shgroup_state_set(DRWShadingGroup *shgroup, DRWState state);
void DRW_shgroup_dyntype_set(DRWShadingGroup *shgroup, int type);
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const struct GPUTexture *tex, int loc);
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const struct GPUUniformBuffer *ubo, int loc);
void DRW_shgroup_uniform_buffer(DRWShadingGroup *shgroup, const char *name, const int value, int loc);
void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const bool *value, int arraysize);
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize);
void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize);
void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize);
void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize);
void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize);
void DRW_shgroup_uniform_ivec2(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize);
void DRW_shgroup_uniform_ivec3(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize);
void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float *value);
void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float *value);
/* Passes */
DRWPass *DRW_pass_create(const char *name, DRWState state);
DRWShadingGroup *DRW_pass_nth_shgroup_get(DRWPass *pass, int n);
/* Viewport */
typedef enum {
DRW_MAT_PERS,
DRW_MAT_WIEW,
DRW_MAT_WIN,
} DRWViewportMatrixType;
void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes);
void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type);
float *DRW_viewport_size_get(void);
float *DRW_viewport_screenvecs_get(void);
float *DRW_viewport_pixelsize_get(void);
bool DRW_viewport_is_persp_get(void);
bool DRW_viewport_cache_is_dirty(void);
/* Settings */
#ifndef __DRW_ENGINE_H__
void *DRW_material_settings_get(Material *ma, const char *engine_name);
void *DRW_render_settings_get(Scene *scene, const char *engine_name);
#endif /* __DRW_ENGINE_H__ */
/* Draw commands */
void DRW_draw_background(void);
void DRW_centercircle(const float co[3]);
void DRW_draw_pass(DRWPass *pass);
void DRW_state_reset(void);
/* Other */
void DRW_get_dfdy_factors(float dfdyfac[2]);
#endif /* __DRW_RENDER_H__ */

View File

@@ -0,0 +1,543 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file draw_cache.c
* \ingroup draw
*/
#include "DNA_scene_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BKE_mesh_render.h"
#include "GPU_batch.h"
#include "draw_cache.h"
static struct DRWShapeCache{
Batch *drw_single_vertice;
Batch *drw_fullscreen_quad;
Batch *drw_plain_axes;
Batch *drw_single_arrow;
Batch *drw_single_arrow_line;
Batch *drw_cube;
Batch *drw_circle;
Batch *drw_empty_sphere;
Batch *drw_empty_cone;
Batch *drw_arrows;
Batch *drw_lamp;
Batch *drw_lamp_sunrays;
} SHC = {NULL};
void DRW_shape_cache_free(void)
{
if (SHC.drw_single_vertice)
Batch_discard_all(SHC.drw_single_vertice);
if (SHC.drw_fullscreen_quad)
Batch_discard_all(SHC.drw_fullscreen_quad);
if (SHC.drw_plain_axes)
Batch_discard_all(SHC.drw_plain_axes);
if (SHC.drw_single_arrow)
Batch_discard_all(SHC.drw_single_arrow);
if (SHC.drw_single_arrow_line)
Batch_discard_all(SHC.drw_single_arrow_line);
if (SHC.drw_cube)
Batch_discard_all(SHC.drw_cube);
if (SHC.drw_circle)
Batch_discard_all(SHC.drw_circle);
if (SHC.drw_empty_sphere)
Batch_discard_all(SHC.drw_empty_sphere);
if (SHC.drw_empty_cone)
Batch_discard_all(SHC.drw_empty_cone);
if (SHC.drw_arrows)
Batch_discard_all(SHC.drw_arrows);
if (SHC.drw_lamp)
Batch_discard_all(SHC.drw_lamp);
if (SHC.drw_lamp_sunrays)
Batch_discard_all(SHC.drw_lamp_sunrays);
}
/* Quads */
Batch *DRW_cache_fullscreen_quad_get(void)
{
if (!SHC.drw_fullscreen_quad) {
float v1[2] = {-1.0f, -1.0f};
float v2[2] = { 1.0f, -1.0f};
float v3[2] = {-1.0f, 1.0f};
float v4[2] = { 1.0f, 1.0f};
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 6);
setAttrib(vbo, pos_id, 0, v1);
setAttrib(vbo, pos_id, 1, v2);
setAttrib(vbo, pos_id, 2, v3);
setAttrib(vbo, pos_id, 3, v2);
setAttrib(vbo, pos_id, 4, v3);
setAttrib(vbo, pos_id, 5, v4);
SHC.drw_fullscreen_quad = Batch_create(GL_TRIANGLES, vbo, NULL);
}
return SHC.drw_fullscreen_quad;
}
/* Common */
Batch *DRW_cache_cube_get(void)
{
if (!SHC.drw_cube) {
const GLfloat verts[8][3] = {
{-1.0f, -1.0f, -1.0f},
{-1.0f, -1.0f, 1.0f},
{-1.0f, 1.0f, -1.0f},
{-1.0f, 1.0f, 1.0f},
{ 1.0f, -1.0f, -1.0f},
{ 1.0f, -1.0f, 1.0f},
{ 1.0f, 1.0f, -1.0f},
{ 1.0f, 1.0f, 1.0f}
};
const GLubyte indices[24] = {0,1,1,3,3,2,2,0,0,4,4,5,5,7,7,6,6,4,1,5,3,7,2,6};
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 24);
for (int i = 0; i < 24; ++i) {
setAttrib(vbo, pos_id, i, verts[indices[i]]);
}
SHC.drw_cube = Batch_create(GL_LINES, vbo, NULL);
}
return SHC.drw_cube;
}
Batch *DRW_cache_circle_get(void)
{
#define CIRCLE_RESOL 32
if (!SHC.drw_circle) {
float v[3] = {0.0f, 0.0f, 0.0f};
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2);
for (int a = 0; a < CIRCLE_RESOL; a++) {
v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
v[2] = 0.0f;
setAttrib(vbo, pos_id, a * 2, v);
v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
v[2] = 0.0f;
setAttrib(vbo, pos_id, a * 2 + 1, v);
}
SHC.drw_circle = Batch_create(GL_LINES, vbo, NULL);
}
return SHC.drw_circle;
#undef CIRCLE_RESOL
}
/* Empties */
Batch *DRW_cache_plain_axes_get(void)
{
if (!SHC.drw_plain_axes) {
int axis;
float v1[3] = {0.0f, 0.0f, 0.0f};
float v2[3] = {0.0f, 0.0f, 0.0f};
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 6);
for (axis = 0; axis < 3; axis++) {
v1[axis] = 1.0f;
v2[axis] = -1.0f;
setAttrib(vbo, pos_id, axis * 2, v1);
setAttrib(vbo, pos_id, axis * 2 + 1, v2);
/* reset v1 & v2 to zero for next axis */
v1[axis] = v2[axis] = 0.0f;
}
SHC.drw_plain_axes = Batch_create(GL_LINES, vbo, NULL);
}
return SHC.drw_plain_axes;
}
Batch *DRW_cache_single_arrow_get(Batch **line)
{
if (!SHC.drw_single_arrow_line || !SHC.drw_single_arrow) {
float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3], v3[3];
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
/* Line */
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 2);
setAttrib(vbo, pos_id, 0, v1);
v1[2] = 1.0f;
setAttrib(vbo, pos_id, 1, v1);
SHC.drw_single_arrow_line = Batch_create(GL_LINES, vbo, NULL);
/* Square Pyramid */
vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 12);
v2[0] = 0.035f; v2[1] = 0.035f;
v3[0] = -0.035f; v3[1] = 0.035f;
v2[2] = v3[2] = 0.75f;
for (int sides = 0; sides < 4; sides++) {
if (sides % 2 == 1) {
v2[0] = -v2[0];
v3[1] = -v3[1];
}
else {
v2[1] = -v2[1];
v3[0] = -v3[0];
}
setAttrib(vbo, pos_id, sides * 3 + 0, v1);
setAttrib(vbo, pos_id, sides * 3 + 1, v2);
setAttrib(vbo, pos_id, sides * 3 + 2, v3);
}
SHC.drw_single_arrow = Batch_create(GL_TRIANGLES, vbo, NULL);
}
*line = SHC.drw_single_arrow_line;
return SHC.drw_single_arrow;
}
Batch *DRW_cache_empty_sphere_get(void)
{
#define NSEGMENTS 16
if (!SHC.drw_empty_sphere) {
/* a single ring of vertices */
float p[NSEGMENTS][2];
for (int i = 0; i < NSEGMENTS; ++i) {
float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
p[i][0] = cosf(angle);
p[i][1] = sinf(angle);
}
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, NSEGMENTS * 2 * 3);
for (int axis = 0; axis < 3; ++axis) {
for (int i = 0; i < NSEGMENTS; ++i) {
for (int j = 0; j < 2; ++j) {
float cv[2], v[3];
cv[0] = p[(i+j) % NSEGMENTS][0];
cv[1] = p[(i+j) % NSEGMENTS][1];
if (axis == 0)
v[0] = cv[0], v[1] = cv[1], v[2] = 0.0f;
else if (axis == 1)
v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1];
else
v[0] = 0.0f, v[1] = cv[0], v[2] = cv[1];
setAttrib(vbo, pos_id, i*2 + j + (NSEGMENTS * 2 * axis), v);
}
}
}
SHC.drw_empty_sphere = Batch_create(GL_LINES, vbo, NULL);
}
return SHC.drw_empty_sphere;
#undef NSEGMENTS
}
Batch *DRW_cache_empty_cone_get(void)
{
#define NSEGMENTS 8
if (!SHC.drw_empty_cone) {
/* a single ring of vertices */
float p[NSEGMENTS][2];
for (int i = 0; i < NSEGMENTS; ++i) {
float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
p[i][0] = cosf(angle);
p[i][1] = sinf(angle);
}
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, NSEGMENTS * 4);
for (int i = 0; i < NSEGMENTS; ++i) {
float cv[2], v[3];
cv[0] = p[(i) % NSEGMENTS][0];
cv[1] = p[(i) % NSEGMENTS][1];
/* cone sides */
v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1];
setAttrib(vbo, pos_id, i*4, v);
v[0] = 0.0f, v[1] = 2.0f, v[2] = 0.0f;
setAttrib(vbo, pos_id, i*4 + 1, v);
/* end ring */
v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1];
setAttrib(vbo, pos_id, i*4 + 2, v);
cv[0] = p[(i+1) % NSEGMENTS][0];
cv[1] = p[(i+1) % NSEGMENTS][1];
v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1];
setAttrib(vbo, pos_id, i*4 + 3, v);
}
SHC.drw_empty_cone = Batch_create(GL_LINES, vbo, NULL);
}
return SHC.drw_empty_cone;
#undef NSEGMENTS
}
Batch *DRW_cache_arrows_get(void)
{
if (!SHC.drw_arrows) {
float v1[3] = {0.0, 0.0, 0.0};
float v2[3] = {0.0, 0.0, 0.0};
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
/* Line */
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 6 * 3);
for (int axis = 0; axis < 3; axis++) {
const int arrow_axis = (axis == 0) ? 1 : 0;
v2[axis] = 1.0f;
setAttrib(vbo, pos_id, axis * 6 + 0, v1);
setAttrib(vbo, pos_id, axis * 6 + 1, v2);
v1[axis] = 0.85f;
v1[arrow_axis] = -0.08f;
setAttrib(vbo, pos_id, axis * 6 + 2, v1);
setAttrib(vbo, pos_id, axis * 6 + 3, v2);
v1[arrow_axis] = 0.08f;
setAttrib(vbo, pos_id, axis * 6 + 4, v1);
setAttrib(vbo, pos_id, axis * 6 + 5, v2);
/* reset v1 & v2 to zero */
v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f;
}
SHC.drw_arrows = Batch_create(GL_LINES, vbo, NULL);
}
return SHC.drw_arrows;
}
/* Lamps */
Batch *DRW_cache_lamp_get(void)
{
#define NSEGMENTS 8
if (!SHC.drw_lamp) {
float v[2];
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, NSEGMENTS * 2);
for (int a = 0; a < NSEGMENTS; a++) {
v[0] = sinf((2.0f * M_PI * a) / ((float)NSEGMENTS));
v[1] = cosf((2.0f * M_PI * a) / ((float)NSEGMENTS));
setAttrib(vbo, pos_id, a * 2, v);
v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)NSEGMENTS));
v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)NSEGMENTS));
setAttrib(vbo, pos_id, a * 2 + 1, v);
}
SHC.drw_lamp = Batch_create(GL_LINES, vbo, NULL);
}
return SHC.drw_lamp;
#undef NSEGMENTS
}
Batch *DRW_cache_lamp_sunrays_get(void)
{
if (!SHC.drw_lamp_sunrays) {
float v[2], v1[2], v2[2];
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 16);
for (int a = 0; a < 8; a++) {
v[0] = sinf((2.0f * M_PI * a) / 8.0f);
v[1] = cosf((2.0f * M_PI * a) / 8.0f);
mul_v2_v2fl(v1, v, 1.2f);
mul_v2_v2fl(v2, v, 2.5f);
setAttrib(vbo, pos_id, a * 2, v1);
setAttrib(vbo, pos_id, a * 2 + 1, v2);
}
SHC.drw_lamp_sunrays = Batch_create(GL_LINES, vbo, NULL);
}
return SHC.drw_lamp_sunrays;
}
/* Object Center */
Batch *DRW_cache_single_vert_get(void)
{
if (!SHC.drw_single_vertice) {
float v1[3] = {0.0f, 0.0f, 0.0f};
/* Position Only 3D format */
static VertexFormat format = { 0 };
static unsigned pos_id;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 1);
setAttrib(vbo, pos_id, 0, v1);
SHC.drw_single_vertice = Batch_create(GL_POINTS, vbo, NULL);
}
return SHC.drw_single_vertice;
}
/* Meshes */
Batch *DRW_cache_wire_overlay_get(Object *ob)
{
Batch *overlay_wire = NULL;
BLI_assert(ob->type == OB_MESH);
Mesh *me = ob->data;
#if 1 /* new version not working */
overlay_wire = BKE_mesh_batch_cache_get_overlay_edges(me);
#else
overlay_wire = BKE_mesh_batch_cache_get_all_edges(me);
#endif
return overlay_wire;
}
Batch *DRW_cache_wire_outline_get(Object *ob)
{
Batch *fancy_wire = NULL;
BLI_assert(ob->type == OB_MESH);
Mesh *me = ob->data;
fancy_wire = BKE_mesh_batch_cache_get_fancy_edges(me);
return fancy_wire;
}
Batch *DRW_cache_surface_get(Object *ob)
{
Batch *surface = NULL;
BLI_assert(ob->type == OB_MESH);
Mesh *me = ob->data;
surface = BKE_mesh_batch_cache_get_all_triangles(me);
return surface;
}
#if 0 /* TODO */
struct Batch *DRW_cache_surface_material_get(Object *ob, int nr) {
/* TODO */
return NULL;
}
#endif

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file draw_cache.h
* \ingroup draw
*/
#ifndef __DRAW_CACHE_H__
#define __DRAW_CACHE_H__
struct Batch;
struct Object;
void DRW_shape_cache_free(void);
/* Common Shapes */
struct Batch *DRW_cache_fullscreen_quad_get(void);
struct Batch *DRW_cache_single_vert_get(void);
/* Empties */
struct Batch *DRW_cache_plain_axes_get(void);
struct Batch *DRW_cache_single_arrow_get(struct Batch **line);
struct Batch *DRW_cache_cube_get(void);
struct Batch *DRW_cache_circle_get(void);
struct Batch *DRW_cache_empty_sphere_get(void);
struct Batch *DRW_cache_empty_cone_get(void);
struct Batch *DRW_cache_arrows_get(void);
/* Lamps */
struct Batch *DRW_cache_lamp_get(void);
struct Batch *DRW_cache_lamp_sunrays_get(void);
/* Meshes */
struct Batch *DRW_cache_wire_overlay_get(struct Object *ob);
struct Batch *DRW_cache_wire_outline_get(struct Object *ob);
struct Batch *DRW_cache_surface_get(struct Object *ob);
#endif /* __DRAW_CACHE_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,787 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file blender/draw/draw_mode_pass.c
* \ingroup draw
*/
#include "DNA_userdef_types.h"
#include "GPU_shader.h"
#include "UI_resources.h"
#include "BKE_global.h"
#include "draw_mode_pass.h"
/* ************************** OBJECT MODE ******************************* */
/* Store list of shading group for easy access*/
/* Empties */
static DRWShadingGroup *plain_axes_wire;
static DRWShadingGroup *plain_axes_active;
static DRWShadingGroup *plain_axes_select;
static DRWShadingGroup *plain_axes_transform;
static DRWShadingGroup *plain_axes_group;
static DRWShadingGroup *plain_axes_group_active;
static DRWShadingGroup *cube_wire;
static DRWShadingGroup *cube_active;
static DRWShadingGroup *cube_select;
static DRWShadingGroup *cube_transform;
static DRWShadingGroup *cube_group;
static DRWShadingGroup *cube_group_active;
static DRWShadingGroup *circle_wire;
static DRWShadingGroup *circle_active;
static DRWShadingGroup *circle_select;
static DRWShadingGroup *circle_transform;
static DRWShadingGroup *circle_group;
static DRWShadingGroup *circle_group_active;
static DRWShadingGroup *sphere_wire;
static DRWShadingGroup *sphere_active;
static DRWShadingGroup *sphere_select;
static DRWShadingGroup *sphere_transform;
static DRWShadingGroup *sphere_group;
static DRWShadingGroup *sphere_group_active;
static DRWShadingGroup *cone_wire;
static DRWShadingGroup *cone_active;
static DRWShadingGroup *cone_select;
static DRWShadingGroup *cone_transform;
static DRWShadingGroup *cone_group;
static DRWShadingGroup *cone_group_active;
static DRWShadingGroup *single_arrow_wire;
static DRWShadingGroup *single_arrow_active;
static DRWShadingGroup *single_arrow_select;
static DRWShadingGroup *single_arrow_transform;
static DRWShadingGroup *single_arrow_group;
static DRWShadingGroup *single_arrow_group_active;
static DRWShadingGroup *single_arrow_line_wire;
static DRWShadingGroup *single_arrow_line_active;
static DRWShadingGroup *single_arrow_line_select;
static DRWShadingGroup *single_arrow_line_transform;
static DRWShadingGroup *single_arrow_line_group;
static DRWShadingGroup *single_arrow_line_group_active;
static DRWShadingGroup *arrows_wire;
static DRWShadingGroup *arrows_active;
static DRWShadingGroup *arrows_select;
static DRWShadingGroup *arrows_transform;
static DRWShadingGroup *arrows_group;
static DRWShadingGroup *arrows_group_active;
/* Lamps */
static DRWShadingGroup *lamp_center;
static DRWShadingGroup *lamp_center_group;
static DRWShadingGroup *lamp_groundpoint;
static DRWShadingGroup *lamp_groundline;
static DRWShadingGroup *lamp_circle;
static DRWShadingGroup *lamp_circle_active;
static DRWShadingGroup *lamp_circle_select;
static DRWShadingGroup *lamp_circle_transform;
static DRWShadingGroup *lamp_circle_group;
static DRWShadingGroup *lamp_circle_group_active;
static DRWShadingGroup *lamp_circle_shadow;
static DRWShadingGroup *lamp_circle_shadow_active;
static DRWShadingGroup *lamp_circle_shadow_select;
static DRWShadingGroup *lamp_circle_shadow_transform;
static DRWShadingGroup *lamp_circle_shadow_group;
static DRWShadingGroup *lamp_circle_shadow_group_active;
static DRWShadingGroup *lamp_sunrays;
static DRWShadingGroup *lamp_sunrays_active;
static DRWShadingGroup *lamp_sunrays_select;
static DRWShadingGroup *lamp_sunrays_transform;
static DRWShadingGroup *lamp_sunrays_group;
static DRWShadingGroup *lamp_sunrays_group_active;
/* Helpers */
static DRWShadingGroup *relationship_lines;
/* Objects Centers */
static DRWShadingGroup *center_active;
static DRWShadingGroup *center_selected;
static DRWShadingGroup *center_deselected;
static DRWShadingGroup *shgroup_instance_uniform_color(DRWPass *pass, float color[4])
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE);
DRWShadingGroup *grp = DRW_shgroup_create(sh_inst, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_INSTANCE);
return grp;
}
static DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4])
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_LINES);
return grp;
}
static DRWShadingGroup *shgroup_dynpoints_uniform_color(DRWPass *pass, float color[4], float *size)
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_SMOOTH);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_uniform_float(grp, "size", size, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
DRW_shgroup_state_set(grp, DRW_STATE_POINT);
return grp;
}
static DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, float color[4])
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
return grp;
}
static DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float color[4])
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
DRW_shgroup_state_set(grp, DRW_STATE_POINT);
return grp;
}
static DRWShadingGroup *shgroup_lamp(DRWPass *pass, float color[4], float *size)
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_LAMP_COMMON);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_uniform_float(grp, "size", size, 1);
DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
DRW_shgroup_uniform_vec3(grp, "screen_vecs", DRW_viewport_screenvecs_get(), 2);
DRW_shgroup_dyntype_set(grp, DRW_DYN_INSTANCE);
DRW_shgroup_state_set(grp, DRW_STATE_STIPPLE_3);
return grp;
}
/* This Function setup the passes needed for the mode rendering.
* The passes are populated by the rendering engine using the DRW_shgroup_* functions. */
void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPass **non_meshes, DRWPass **ob_center)
{
/* Theses are defined for the whole application so make sure they rely on global settings */
static float colorWire[4], colorWireEdit[4];
static float colorActive[4], colorSelect[4], colorTransform[4], colorGroup[4], colorGroupActive[4];
static float colorEmpty[4], colorLamp[4], colorCamera[4], colorSpeaker[4];
static float lampCenterSize, lampCircleRad, lampCircleShadowRad, colorLampNoAlpha[4];
UI_GetThemeColor4fv(TH_WIRE, colorWire);
UI_GetThemeColor4fv(TH_WIRE_EDIT, colorWireEdit);
UI_GetThemeColor4fv(TH_ACTIVE, colorActive);
UI_GetThemeColor4fv(TH_SELECT, colorSelect);
UI_GetThemeColor4fv(TH_TRANSFORM, colorTransform);
UI_GetThemeColor4fv(TH_GROUP_ACTIVE, colorGroupActive);
UI_GetThemeColor4fv(TH_GROUP, colorGroup);
UI_GetThemeColor4fv(TH_LAMP, colorLamp);
UI_GetThemeColor4fv(TH_LAMP, colorLampNoAlpha);
UI_GetThemeColor4fv(TH_SPEAKER, colorSpeaker);
UI_GetThemeColor4fv(TH_CAMERA, colorCamera);
UI_GetThemeColor4fv(TH_EMPTY, colorEmpty);
colorLampNoAlpha[3] = 1.0f;
if (wire_overlay) {
/* This pass can draw mesh edges top of Shaded Meshes without any Z fighting */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND;
*wire_overlay = DRW_pass_create("Wire Overlays Pass", state);
}
if (wire_outline) {
/* This pass can draw mesh outlines and/or fancy wireframe */
/* Fancy wireframes are not meant to be occluded (without Z offset) */
/* Outlines and Fancy Wires use the same VBO */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
*wire_outline = DRW_pass_create("Wire + Outlines Pass", state);
}
if (non_meshes) {
/* Non Meshes Pass (Camera, empties, lamps ...) */
DRWShadingGroup *grp;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
state |= DRW_STATE_WIRE;
*non_meshes = DRW_pass_create("Non Meshes Pass", state);
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
/* Empties */
plain_axes_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
plain_axes_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
plain_axes_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
plain_axes_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
plain_axes_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
plain_axes_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
cube_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
cube_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
cube_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
cube_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
cube_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
cube_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
circle_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
circle_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
circle_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
circle_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
circle_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
circle_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
sphere_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
sphere_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
sphere_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
sphere_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
sphere_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
sphere_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
cone_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
cone_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
cone_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
cone_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
cone_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
cone_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
single_arrow_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
single_arrow_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
single_arrow_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
single_arrow_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
single_arrow_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
single_arrow_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
single_arrow_line_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
single_arrow_line_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
single_arrow_line_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
single_arrow_line_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
single_arrow_line_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
single_arrow_line_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
arrows_wire = shgroup_instance_uniform_color(*non_meshes, colorEmpty);
arrows_active = shgroup_instance_uniform_color(*non_meshes, colorActive);
arrows_select = shgroup_instance_uniform_color(*non_meshes, colorSelect);
arrows_transform = shgroup_instance_uniform_color(*non_meshes, colorTransform);
arrows_group = shgroup_instance_uniform_color(*non_meshes, colorGroup);
arrows_group_active = shgroup_instance_uniform_color(*non_meshes, colorGroupActive);
/* Lamps */
lampCenterSize = (U.obcenter_dia + 1.5f) * U.pixelsize;
lampCircleRad = U.pixelsize * 9.0f;
lampCircleShadowRad = lampCircleRad + U.pixelsize * 3.0f;
/* TODO
* for now we create 3 times the same VBO with only lamp center coordinates
* but ideally we would only create it once */
lamp_center = shgroup_dynpoints_uniform_color(*non_meshes, colorLampNoAlpha, &lampCenterSize);
lamp_center_group = shgroup_dynpoints_uniform_color(*non_meshes, colorGroup, &lampCenterSize);
lamp_circle = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleRad);
lamp_circle_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleRad);
lamp_circle_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleRad);
lamp_circle_transform = shgroup_lamp(*non_meshes, colorTransform, &lampCircleRad);
lamp_circle_group = shgroup_lamp(*non_meshes, colorGroup, &lampCircleRad);
lamp_circle_group_active = shgroup_lamp(*non_meshes, colorGroupActive, &lampCircleRad);
lamp_circle_shadow = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleShadowRad);
lamp_circle_shadow_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleShadowRad);
lamp_circle_shadow_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleShadowRad);
lamp_circle_shadow_transform = shgroup_lamp(*non_meshes, colorTransform, &lampCircleShadowRad);
lamp_circle_shadow_group = shgroup_lamp(*non_meshes, colorGroup, &lampCircleShadowRad);
lamp_circle_shadow_group_active = shgroup_lamp(*non_meshes, colorGroupActive, &lampCircleShadowRad);
lamp_sunrays = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleRad);
lamp_sunrays_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleRad);
lamp_sunrays_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleRad);
lamp_sunrays_transform = shgroup_lamp(*non_meshes, colorTransform, &lampCircleRad);
lamp_sunrays_group = shgroup_lamp(*non_meshes, colorGroup, &lampCircleRad);
lamp_sunrays_group_active = shgroup_lamp(*non_meshes, colorGroupActive, &lampCircleRad);
lamp_groundline = shgroup_groundlines_uniform_color(*non_meshes, colorLamp);
lamp_groundpoint = shgroup_groundpoints_uniform_color(*non_meshes, colorLamp);
/* Stipple Wires */
grp = DRW_shgroup_create(sh, *non_meshes);
DRW_shgroup_state_set(grp, DRW_STATE_STIPPLE_2);
grp = DRW_shgroup_create(sh, *non_meshes);
DRW_shgroup_state_set(grp, DRW_STATE_STIPPLE_3);
grp = DRW_shgroup_create(sh, *non_meshes);
DRW_shgroup_state_set(grp, DRW_STATE_STIPPLE_4);
/* Relationship Lines */
relationship_lines = shgroup_dynlines_uniform_color(*non_meshes, colorWire);
DRW_shgroup_state_set(relationship_lines, DRW_STATE_STIPPLE_3);
}
if (ob_center) {
/* Object Center pass grouped by State */
DRWShadingGroup *grp;
static float colorDeselect[4], outlineColor[4];
static float outlineWidth, size;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT;
*ob_center = DRW_pass_create("Obj Center Pass", state);
outlineWidth = 1.0f * U.pixelsize;
size = U.obcenter_dia * U.pixelsize + outlineWidth;
//UI_GetThemeColorShadeAlpha4fv(TH_ACTIVE, 0, -80, colorActive);
//UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -80, colorSelect);
UI_GetThemeColorShadeAlpha4fv(TH_TRANSFORM, 0, -80, colorDeselect);
UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, outlineColor);
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH);
/* Active */
grp = DRW_shgroup_create(sh, *ob_center);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
DRW_shgroup_uniform_float(grp, "size", &size, 1);
DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
DRW_shgroup_uniform_vec4(grp, "color", colorActive, 1);
DRW_shgroup_uniform_vec4(grp, "outlineColor", outlineColor, 1);
center_active = grp;
/* Select */
grp = DRW_shgroup_create(sh, *ob_center);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
DRW_shgroup_uniform_vec4(grp, "color", colorSelect, 1);
center_selected = grp;
/* Deselect */
grp = DRW_shgroup_create(sh, *ob_center);
DRW_shgroup_dyntype_set(grp, DRW_DYN_POINTS);
DRW_shgroup_uniform_vec4(grp, "color", colorDeselect, 1);
center_deselected = grp;
}
}
/* ******************************************** WIRES *********************************************** */
/* TODO FINISH */
static int draw_object_wire_theme(Object *ob)
{
const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0;
/* confusing logic here, there are 2 methods of setting the color
* 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
*
* note: no theme yet for 'colindex' */
int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE;
if (//(scene->obedit == NULL) &&
((G.moving & G_TRANSFORM_OBJ) != 0) &&
((ob->base_flag & BASE_SELECTED) != 0))
{
theme_id = TH_TRANSFORM;
}
else {
/* Sets the 'theme_id' or fallback to wire */
if ((ob->flag & OB_FROMGROUP) != 0) {
if ((ob->base_flag & BASE_SELECTED) != 0) {
/* uses darker active color for non-active + selected */
theme_id = TH_GROUP_ACTIVE;
// if (scene->basact != base) {
// theme_shade = -16;
// }
}
else {
theme_id = TH_GROUP;
}
}
else {
if ((ob->base_flag & BASE_SELECTED) != 0) {
theme_id = //scene->basact == base ? TH_ACTIVE :
TH_SELECT;
}
else {
if (ob->type == OB_LAMP) theme_id = TH_LAMP;
else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER;
else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA;
else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY;
/* fallback to TH_WIRE */
}
}
}
return theme_id;
}
void DRW_shgroup_wire_overlay(DRWPass *wire_overlay, Object *ob)
{
#if 1
struct Batch *geom = DRW_cache_wire_overlay_get(ob);
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_OVERLAY);
DRWShadingGroup *grp = DRW_shgroup_create(sh, wire_overlay);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
DRW_shgroup_call_add(grp, geom, ob->obmat);
#else
static float col[4] = {0.0f, 0.0f, 0.0f, 1.0f};
struct Batch *geom = DRW_cache_wire_overlay_get(ob);
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, wire_overlay);
DRW_shgroup_uniform_vec4(grp, "color", col, 1);
DRW_shgroup_call_add(grp, geom, ob->obmat);
#endif
}
void DRW_shgroup_wire_outline(DRWPass *wire_outline, Object *ob,
const bool do_front, const bool do_back, const bool do_outline)
{
GPUShader *sh;
struct Batch *geom = DRW_cache_wire_outline_get(ob);
/* Get color */
/* TODO get the right color depending on ob state (Groups, overides etc..) */
static float frontcol[4], backcol[4], color[4];
UI_GetThemeColor4fv(TH_ACTIVE, color);
copy_v4_v4(frontcol, color);
copy_v4_v4(backcol, color);
backcol[3] = 0.333f;
frontcol[3] = 0.667f;
#if 1 /* New wire */
bool is_perps = DRW_viewport_is_persp_get();
static bool bTrue = true;
static bool bFalse = false;
/* Note (TODO) : this requires cache to be discarded on ortho/perp switch
* It may be preferable (or not depending on performance implication)
* to introduce a shader uniform switch */
if (is_perps) {
sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_FRONT_BACK_PERSP);
}
else {
sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
}
if (do_front || do_back) {
bool *bFront = (do_front) ? &bTrue : &bFalse;
bool *bBack = (do_back) ? &bTrue : &bFalse;
DRWShadingGroup *grp = DRW_shgroup_create(sh, wire_outline);
DRW_shgroup_state_set(grp, DRW_STATE_WIRE);
DRW_shgroup_uniform_vec4(grp, "frontColor", frontcol, 1);
DRW_shgroup_uniform_vec4(grp, "backColor", backcol, 1);
DRW_shgroup_uniform_bool(grp, "drawFront", bFront, 1);
DRW_shgroup_uniform_bool(grp, "drawBack", bBack, 1);
DRW_shgroup_uniform_bool(grp, "drawSilhouette", &bFalse, 1);
DRW_shgroup_call_add(grp, geom, ob->obmat);
}
if (do_outline) {
DRWShadingGroup *grp = DRW_shgroup_create(sh, wire_outline);
DRW_shgroup_state_set(grp, DRW_STATE_WIRE_LARGE);
DRW_shgroup_uniform_vec4(grp, "silhouetteColor", color, 1);
DRW_shgroup_uniform_bool(grp, "drawFront", &bFalse, 1);
DRW_shgroup_uniform_bool(grp, "drawBack", &bFalse, 1);
DRW_shgroup_uniform_bool(grp, "drawSilhouette", &bTrue, 1);
DRW_shgroup_call_add(grp, geom, ob->obmat);
}
#else /* Old (flat) wire */
sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, wire_outline);
DRW_shgroup_state_set(grp, DRW_STATE_WIRE_LARGE);
DRW_shgroup_uniform_vec4(grp, "color", frontcol, 1);
DRW_shgroup_call_add(grp, geom, ob->obmat);
#endif
}
/* ***************************** NON MESHES ********************** */
static void DRW_draw_lamp(Object *ob)
{
struct Batch *center = DRW_cache_single_vert_get();
struct Batch *lamp = DRW_cache_lamp_get();
struct Batch *sunrays = DRW_cache_lamp_sunrays_get();
Lamp *la = ob->data;
int theme_id = draw_object_wire_theme(ob);
/* Don't draw the center if it's selected or active */
if (theme_id == TH_GROUP)
DRW_shgroup_call_add(lamp_center_group, center, ob->obmat);
else if (theme_id == TH_LAMP)
DRW_shgroup_call_add(lamp_center, center, ob->obmat);
/* First circle */
if (theme_id == TH_ACTIVE)
DRW_shgroup_call_add(lamp_circle_active, lamp, ob->obmat);
else if (theme_id == TH_SELECT)
DRW_shgroup_call_add(lamp_circle_select, lamp, ob->obmat);
else if (theme_id == TH_GROUP)
DRW_shgroup_call_add(lamp_circle_group, lamp, ob->obmat);
else if (theme_id == TH_GROUP_ACTIVE)
DRW_shgroup_call_add(lamp_circle_group_active, lamp, ob->obmat);
else if (theme_id == TH_TRANSFORM)
DRW_shgroup_call_add(lamp_circle_transform, lamp, ob->obmat);
else
DRW_shgroup_call_add(lamp_circle, lamp, ob->obmat);
/* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
if (la->type != LA_HEMI) {
if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
if (theme_id == TH_ACTIVE)
DRW_shgroup_call_add(lamp_circle_shadow_active, lamp, ob->obmat);
else if (theme_id == TH_SELECT)
DRW_shgroup_call_add(lamp_circle_shadow_select, lamp, ob->obmat);
else if (theme_id == TH_GROUP)
DRW_shgroup_call_add(lamp_circle_shadow_group, lamp, ob->obmat);
else if (theme_id == TH_GROUP_ACTIVE)
DRW_shgroup_call_add(lamp_circle_shadow_group_active, lamp, ob->obmat);
else if (theme_id == TH_TRANSFORM)
DRW_shgroup_call_add(lamp_circle_shadow_transform, lamp, ob->obmat);
else
DRW_shgroup_call_add(lamp_circle_shadow, lamp, ob->obmat);
}
}
/* Sunrays */
if (la->type == LA_SUN) {
if (theme_id == TH_ACTIVE)
DRW_shgroup_call_add(lamp_sunrays_active, sunrays, ob->obmat);
else if (theme_id == TH_SELECT)
DRW_shgroup_call_add(lamp_sunrays_select, sunrays, ob->obmat);
else if (theme_id == TH_GROUP)
DRW_shgroup_call_add(lamp_sunrays_group, sunrays, ob->obmat);
else if (theme_id == TH_GROUP_ACTIVE)
DRW_shgroup_call_add(lamp_sunrays_group_active, sunrays, ob->obmat);
else if (theme_id == TH_TRANSFORM)
DRW_shgroup_call_add(lamp_sunrays_transform, sunrays, ob->obmat);
else
DRW_shgroup_call_add(lamp_sunrays, sunrays, ob->obmat);
}
/* Line and point going to the ground */
DRW_shgroup_call_add(lamp_groundline, center, ob->obmat);
DRW_shgroup_call_add(lamp_groundpoint, center, ob->obmat);
}
static void DRW_draw_empty(Object *ob)
{
struct Batch *geom, *geom2;
DRWShadingGroup *grp, *grp2;
int theme_id = draw_object_wire_theme(ob);
switch (ob->empty_drawtype) {
case OB_PLAINAXES:
if (theme_id == TH_ACTIVE)
grp = plain_axes_active;
else if (theme_id == TH_SELECT)
grp = plain_axes_select;
else if (theme_id == TH_GROUP_ACTIVE)
grp = plain_axes_group_active;
else if (theme_id == TH_GROUP)
grp = plain_axes_group;
else if (theme_id == TH_TRANSFORM)
grp = plain_axes_transform;
else
grp = plain_axes_wire;
geom = DRW_cache_plain_axes_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_SINGLE_ARROW:
if (theme_id == TH_ACTIVE) {
grp = single_arrow_active;
grp2 = single_arrow_line_active;
}
else if (theme_id == TH_SELECT) {
grp = single_arrow_select;
grp2 = single_arrow_line_select;
}
else if (theme_id == TH_GROUP_ACTIVE) {
grp = single_arrow_group_active;
grp2 = single_arrow_line_group_active;
}
else if (theme_id == TH_GROUP) {
grp = single_arrow_group;
grp2 = single_arrow_line_group;
}
else if (theme_id == TH_TRANSFORM) {
grp = single_arrow_transform;
grp2 = single_arrow_line_transform;
}
else {
grp = single_arrow_wire;
grp2 = single_arrow_line_wire;
}
geom = DRW_cache_single_arrow_get(&geom2);
DRW_shgroup_call_add(grp, geom, ob->obmat);
DRW_shgroup_call_add(grp2, geom2, ob->obmat);
break;
case OB_CUBE:
if (theme_id == TH_ACTIVE)
grp = cube_active;
else if (theme_id == TH_SELECT)
grp = cube_select;
else if (theme_id == TH_GROUP_ACTIVE)
grp = cube_group_active;
else if (theme_id == TH_GROUP)
grp = cube_group;
else if (theme_id == TH_TRANSFORM)
grp = cube_transform;
else
grp = cube_wire;
geom = DRW_cache_cube_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_CIRCLE:
if (theme_id == TH_ACTIVE)
grp = circle_active;
else if (theme_id == TH_SELECT)
grp = circle_select;
else if (theme_id == TH_GROUP_ACTIVE)
grp = circle_group_active;
else if (theme_id == TH_GROUP)
grp = circle_group;
else if (theme_id == TH_TRANSFORM)
grp = circle_transform;
else
grp = circle_wire;
geom = DRW_cache_circle_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_EMPTY_SPHERE:
if (theme_id == TH_ACTIVE)
grp = sphere_active;
else if (theme_id == TH_SELECT)
grp = sphere_select;
else if (theme_id == TH_GROUP_ACTIVE)
grp = sphere_group_active;
else if (theme_id == TH_GROUP)
grp = sphere_group;
else if (theme_id == TH_TRANSFORM)
grp = sphere_transform;
else
grp = sphere_wire;
geom = DRW_cache_empty_sphere_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_EMPTY_CONE:
if (theme_id == TH_ACTIVE)
grp = cone_active;
else if (theme_id == TH_SELECT)
grp = cone_select;
else if (theme_id == TH_GROUP_ACTIVE)
grp = cone_group_active;
else if (theme_id == TH_GROUP)
grp = cone_group;
else if (theme_id == TH_TRANSFORM)
grp = cone_transform;
else
grp = cone_wire;
geom = DRW_cache_empty_cone_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
break;
case OB_ARROWS:
default:
if (theme_id == TH_ACTIVE)
grp = arrows_active;
else if (theme_id == TH_SELECT)
grp = arrows_select;
else if (theme_id == TH_GROUP_ACTIVE)
grp = arrows_group_active;
else if (theme_id == TH_GROUP)
grp = arrows_group;
else if (theme_id == TH_TRANSFORM)
grp = arrows_transform;
else
grp = arrows_wire;
geom = DRW_cache_arrows_get();
DRW_shgroup_call_add(grp, geom, ob->obmat);
/* TODO Missing axes names */
break;
}
}
void DRW_shgroup_non_meshes(DRWPass *UNUSED(non_meshes), Object *ob)
{
switch (ob->type) {
case OB_LAMP:
DRW_draw_lamp(ob);
break;
case OB_CAMERA:
case OB_EMPTY:
DRW_draw_empty(ob);
default:
break;
}
}
void DRW_shgroup_relationship_lines(DRWPass *UNUSED(non_meshes), Object *ob)
{
if (ob->parent) {
struct Batch *geom = DRW_cache_single_vert_get();
DRW_shgroup_call_add(relationship_lines, geom, ob->obmat);
DRW_shgroup_call_add(relationship_lines, geom, ob->parent->obmat);
}
}
/* ***************************** COMMON **************************** */
void DRW_shgroup_object_center(DRWPass *UNUSED(ob_center), Object *ob)
{
struct Batch *geom = DRW_cache_single_vert_get();
if ((ob->base_flag & BASE_SELECTED) != 0) {
DRW_shgroup_call_add(center_selected, geom, ob->obmat);
}
else if (0) {
DRW_shgroup_call_add(center_deselected, geom, ob->obmat);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file draw_mode_pass.h
* \ingroup draw
*/
#ifndef __DRAW_MODE_PASS_H__
#define __DRAW_MODE_PASS_H__
#include "DRW_render.h"
struct DRWPass;
struct Batch;
struct Object;
void DRW_pass_setup_common(struct DRWPass **wire_overlay, struct DRWPass **wire_outline, struct DRWPass **non_meshes, struct DRWPass **ob_center);
void DRW_shgroup_wire_overlay(struct DRWPass *wire_overlay, struct Object *ob);
void DRW_shgroup_wire_outline(
struct DRWPass *wire_outline, struct Object *ob, const bool do_front, const bool do_back, const bool do_outline);
void DRW_shgroup_non_meshes(struct DRWPass *non_meshes, struct Object *ob);
void DRW_shgroup_relationship_lines(struct DRWPass *non_meshes, struct Object *ob);
void DRW_shgroup_object_center(struct DRWPass *ob_center, struct Object *ob);
#endif /* __DRAW_MODE_PASS_H__ */

View File

@@ -47,6 +47,7 @@ if(WITH_BLENDER)
add_subdirectory(space_graph)
add_subdirectory(space_image)
add_subdirectory(space_info)
add_subdirectory(space_collections)
add_subdirectory(space_logic)
add_subdirectory(space_nla)
add_subdirectory(space_node)

View File

@@ -57,6 +57,7 @@
#include "BKE_context.h"
#include "BKE_mask.h"
#include "BKE_global.h"
#include "BKE_scene.h"
#include "UI_view2d.h"
@@ -2690,7 +2691,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
if (selectmode == SELECT_INVERT) {
/* swap select */
base->flag ^= SELECT;
ob->flag = base->flag;
BKE_scene_base_flag_sync_from_base(base);
if (adt) adt->flag ^= ADT_UI_SELECTED;
}
@@ -2701,7 +2702,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
/* TODO: should this deselect all other types of channels too? */
for (b = sce->base.first; b; b = b->next) {
b->flag &= ~SELECT;
b->object->flag = b->flag;
BKE_scene_base_flag_sync_from_base(b);
if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
}

View File

@@ -50,6 +50,7 @@
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -268,7 +269,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
if (!arm || arm->edbo)
return OPERATOR_CANCELLED;
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN(C, ObjectBase *, base, selected_editable_bases)
{
if (base->object == ob) {
ok = true;
@@ -290,7 +291,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
pose = ob->pose;
ob->mode &= ~OB_MODE_POSE;
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN(C, ObjectBase *, base, selected_editable_bases)
{
if ((base->object->type == OB_ARMATURE) && (base->object != ob)) {
tJoinArmature_AdtFixData afd = {NULL};
@@ -400,7 +401,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
}
/* Free the old object data */
ED_base_object_free_and_unlink(bmain, scene, base);
ED_base_object_free_and_unlink(bmain, scene, base->object);
}
}
CTX_DATA_END;
@@ -579,9 +580,10 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
Object *oldob, *newob;
Base *oldbase, *newbase;
ObjectBase *oldbase, *newbase;
/* sanity checks */
if (obedit == NULL)
@@ -600,16 +602,20 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
/* 1) only edit-base selected */
/* TODO: use context iterators for this? */
CTX_DATA_BEGIN(C, Base *, base, visible_bases)
CTX_DATA_BEGIN(C, ObjectBase *, base, visible_bases)
{
if (base->object == obedit) base->flag |= SELECT;
else base->flag &= ~SELECT;
if (base->object == obedit) {
ED_object_base_select(base, BA_SELECT);
}
else {
ED_object_base_select(base, BA_DESELECT);
}
}
CTX_DATA_END;
/* 1) store starting settings and exit editmode */
oldob = obedit;
oldbase = BASACT;
oldbase = sl->basact;
oldob->mode &= ~OB_MODE_POSE;
//oldbase->flag &= ~OB_POSEMODE;
@@ -617,13 +623,13 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
ED_armature_edit_free(obedit->data);
/* 2) duplicate base */
newbase = ED_object_add_duplicate(bmain, scene, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
newbase = ED_object_add_duplicate(bmain, scene, sl, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
DAG_relations_tag_update(bmain);
newob = newbase->object;
newbase->flag &= ~SELECT;
newbase->flag &= ~BASE_SELECTED;
/* 3) remove bones that shouldn't still be around on both armatures */
separate_armature_bones(oldob, 1);
separate_armature_bones(newob, 0);

View File

@@ -2518,7 +2518,7 @@ void BIF_retargetArmature(bContext *C)
printf("Reeb Graph created\n");
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
Object *ob = base->object;

View File

@@ -81,7 +81,7 @@ Object *ED_pose_object_from_context(bContext *C)
}
/* This function is used to process the necessary updates for */
void ED_armature_enter_posemode(bContext *C, Base *base)
void ED_armature_enter_posemode(bContext *C, ObjectBase *base)
{
ReportList *reports = CTX_wm_reports(C);
Object *ob = base->object;
@@ -107,7 +107,7 @@ void ED_armature_enter_posemode(bContext *C, Base *base)
//ED_object_toggle_modes(C, ob->mode);
}
void ED_armature_exit_posemode(bContext *C, Base *base)
void ED_armature_exit_posemode(bContext *C, ObjectBase *base)
{
if (base) {
Object *ob = base->object;

View File

@@ -50,6 +50,7 @@
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -1270,8 +1271,9 @@ static int separate_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Object *oldob, *newob;
Base *oldbase, *newbase;
ObjectBase *oldbase, *newbase;
Curve *oldcu, *newcu;
EditNurb *newedit;
ListBase newnurb = {NULL, NULL};
@@ -1297,7 +1299,7 @@ static int separate_exec(bContext *C, wmOperator *op)
}
/* 2. duplicate the object and data */
newbase = ED_object_add_duplicate(bmain, scene, oldbase, 0); /* 0 = fully linked */
newbase = ED_object_add_duplicate(bmain, scene, sl, oldbase, 0); /* 0 = fully linked */
DAG_relations_tag_update(bmain);
newob = newbase->object;
@@ -5961,7 +5963,7 @@ int join_curve_exec(bContext *C, wmOperator *op)
int a;
bool ok = false;
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN(C, ObjectBase *, base, selected_editable_bases)
{
if (base->object == ob) {
ok = true;
@@ -5981,7 +5983,7 @@ int join_curve_exec(bContext *C, wmOperator *op)
/* trasnform all selected curves inverse in obact */
invert_m4_m4(imat, ob->obmat);
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN(C, ObjectBase *, base, selected_editable_bases)
{
if (base->object->type == ob->type) {
if (base->object != ob) {
@@ -6024,7 +6026,7 @@ int join_curve_exec(bContext *C, wmOperator *op)
}
}
ED_base_object_free_and_unlink(bmain, scene, base);
ED_base_object_free_and_unlink(bmain, scene, base->object);
}
}
}

View File

@@ -420,17 +420,18 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Curve *cu;
Object *obedit;
Base *base;
ObjectBase *base;
struct TextLine *tmp;
int nchars = 0, nbytes = 0;
char *s;
int a;
float rot[3] = {0.f, 0.f, 0.f};
obedit = BKE_object_add(bmain, scene, OB_FONT, NULL);
base = scene->basact;
obedit = BKE_object_add(bmain, scene, sl, OB_FONT, NULL);
base = sl->basact;
/* seems to assume view align ? TODO - look into this, could be an operator option */
ED_object_base_init_transform(C, base, NULL, rot);

View File

@@ -1217,7 +1217,8 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
/* set the layer and select */
base_new->lay = ob->lay = base_orig ? base_orig->lay : BKE_screen_view3d_layer_active(v3d, scene);
base_new->flag = ob->flag = base_new->flag | SELECT;
base_new->flag |= SELECT;
BKE_scene_base_flag_sync_from_base(base_new);
}
/* --- */

View File

@@ -49,6 +49,7 @@ struct ColorManagedDisplaySettings;
void fdrawline(float x1, float y1, float x2, float y2); /* DEPRECATED */
void fdrawbox(float x1, float y1, float x2, float y2); /* DEPRECATED */
void fdrawbox_filled(float x1, float y1, float x2, float y2);
void sdrawline(int x1, int y1, int x2, int y2); /* DEPRECATED */
void sdrawbox(int x1, int y1, int x2, int y2); /* DEPRECATED */

View File

@@ -44,6 +44,7 @@ struct ListBase;
struct MeshDeformModifierData;
struct DerivedMesh;
struct Object;
struct ObjectBase;
struct ReportList;
struct Scene;
struct ViewContext;
@@ -183,8 +184,8 @@ void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag);
void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag);
/* poseobject.c */
void ED_armature_exit_posemode(struct bContext *C, struct Base *base);
void ED_armature_enter_posemode(struct bContext *C, struct Base *base);
void ED_armature_exit_posemode(struct bContext *C, struct ObjectBase *base);
void ED_armature_enter_posemode(struct bContext *C, struct ObjectBase *base);
void ED_pose_de_selectall(struct Object *ob, int select_mode, const bool ignore_visibility);
void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select);
void ED_pose_recalculate_paths(struct Scene *scene, struct Object *ob);

View File

@@ -41,8 +41,10 @@ struct ID;
struct Main;
struct ModifierData;
struct Object;
struct ObjectBase;
struct ReportList;
struct Scene;
struct SceneLayer;
struct bConstraint;
struct bContext;
struct bPoseChannel;
@@ -53,6 +55,7 @@ struct wmOperatorType;
struct PointerRNA;
struct PropertyRNA;
struct EnumPropertyItem;
struct LayerTree;
/* object_edit.c */
struct Object *ED_object_context(struct bContext *C); /* context.object */
@@ -89,7 +92,6 @@ bool ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct
struct Object *par, int partype, const bool xmirror, const bool keep_transform,
const int vert_par[3]);
void ED_object_parent_clear(struct Object *ob, const int type);
struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob);
void ED_keymap_proportional_cycle(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
@@ -102,10 +104,16 @@ void ED_base_object_select(struct Base *base, short mode);
/* includes notifier */
void ED_base_object_activate(struct bContext *C, struct Base *base);
void ED_base_object_free_and_unlink(struct Main *bmain, struct Scene *scene, struct Base *base);
void ED_object_base_select(struct ObjectBase *base, short mode);
void ED_object_base_activate(struct bContext *C, struct ObjectBase *base);
void ED_base_object_free_and_unlink(struct Main *bmain, struct Scene *scene, struct Object *ob);
void ED_base_object_sync_from_base(struct Base *base, struct Object *ob);
void ED_base_object_sync_from_object(struct Base *base, struct Object *ob);
/* single object duplicate, if (dupflag == 0), fully linked, else it uses the flags given */
struct Base *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, struct Base *base, int dupflag);
struct ObjectBase *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, struct ObjectBase *base, int dupflag);
void ED_object_parent(struct Object *ob, struct Object *parent, const int type, const char *substr);
@@ -126,7 +134,7 @@ bool ED_object_editmode_calc_active_center(struct Object *obedit, const bool sel
void ED_object_location_from_view(struct bContext *C, float loc[3]);
void ED_object_rotation_from_view(struct bContext *C, float rot[3], const char align_axis);
void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]);
void ED_object_base_init_transform(struct bContext *C, struct ObjectBase *base, const float loc[3], const float rot[3]);
float ED_object_new_primitive_matrix(
struct bContext *C, struct Object *editob,
const float loc[3], const float rot[3], float primmat[4][4]);
@@ -191,7 +199,7 @@ void ED_object_modifier_clear(struct Main *bmain, struct Object *ob);
int ED_object_modifier_move_down(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_move_up(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_convert(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
struct Object *ob, struct ModifierData *md);
struct SceneLayer *sl, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_apply(struct ReportList *reports, struct Scene *scene,
struct Object *ob, struct ModifierData *md, int mode);
int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md);

View File

@@ -162,6 +162,7 @@ int ED_operator_image_active(struct bContext *C);
int ED_operator_nla_active(struct bContext *C);
int ED_operator_logic_active(struct bContext *C);
int ED_operator_info_active(struct bContext *C);
int ED_operator_collections_active(struct bContext *C);
int ED_operator_console_active(struct bContext *C);

View File

@@ -58,6 +58,7 @@ void ED_spacetype_logic(void);
void ED_spacetype_console(void);
void ED_spacetype_userpref(void);
void ED_spacetype_clip(void);
void ED_spacetype_collections(void);
/* calls for instancing and freeing spacetype static data
* called in WM_init_exit */

View File

@@ -212,6 +212,9 @@ enum {
UI_BUT_ALIGN_STITCH_TOP = (1 << 18),
UI_BUT_ALIGN_STITCH_LEFT = (1 << 19),
UI_BUT_ALIGN_ALL = (UI_BUT_ALIGN | UI_BUT_ALIGN_STITCH_TOP | UI_BUT_ALIGN_STITCH_LEFT),
/* Another hack, in some rare cases we don't want any text margin */
UI_BUT_TEXT_NO_MARGIN = (1 << 20),
};
/* scale fixed button widths by this to account for DPI */

View File

@@ -83,5 +83,6 @@ struct PreviewImage *UI_icon_to_preview(int icon_id);
int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, const bool big);
int UI_idcode_icon_get(const int idcode);
int UI_colorset_icon_get(const int set_idx);
#endif /* __UI_INTERFACE_ICONS_H__ */

View File

@@ -1385,6 +1385,14 @@ int UI_idcode_icon_get(const int idcode)
}
}
/**
* \param set_idx: A value from #rna_enum_color_sets_items.
*/
int UI_colorset_icon_get(const int set_idx)
{
return (set_idx < 1) ? ICON_NONE : VICO_COLORSET_01_VEC - 1 + set_idx;
}
static void icon_draw_at_size(
float x, float y, int icon_id, float aspect, float alpha,
enum eIconSizes size, const bool nocreate)

View File

@@ -1575,7 +1575,10 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
}
}
if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) {
if (but->drawflag & UI_BUT_TEXT_NO_MARGIN) {
/* skip */
}
else if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) {
rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
}
else if ((but->drawflag & UI_BUT_TEXT_RIGHT)) {

View File

@@ -165,6 +165,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case SPACE_CLIP:
ts = &btheme->tclip;
break;
case SPACE_COLLECTIONS:
ts = &btheme->tcollections;
break;
default:
ts = &btheme->tv3d;
break;
@@ -1206,6 +1209,11 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tclip.strip_select, 0xff, 0x8c, 0x00, 0xff);
btheme->tclip.handle_vertex_size = 5;
ui_theme_space_init_handles_color(&btheme->tclip);
/* space collection manager */
btheme->tcollections = btheme->tv3d;
rgba_char_args_set_fl(btheme->tcollections.back, 0.42, 0.42, 0.42, 1.0);
rgba_char_args_set(btheme->tcollections.hilite, 255, 140, 25, 255); /* selected files */
}
void ui_style_init_default(void)
@@ -2834,7 +2842,11 @@ void init_userdef_do_versions(void)
* (keep this block even if it becomes empty).
*/
{
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
btheme->tcollections = btheme->tv3d;
rgba_char_args_set_fl(btheme->tcollections.back, 0.42, 0.42, 0.42, 1.0);
rgba_char_args_set(btheme->tcollections.hilite, 255, 140, 25, 255); /* selected files */
}
}
if (U.pixelsize == 0.0f)

View File

@@ -47,6 +47,7 @@
#include "BLI_rand.h"
#include "BLI_sort_utils.h"
#include "BKE_layer.h"
#include "BKE_material.h"
#include "BKE_context.h"
#include "BKE_deform.h"
@@ -3010,9 +3011,9 @@ enum {
MESH_SEPARATE_LOOSE = 2,
};
static Base *mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
static ObjectBase *mesh_separate_tagged(Main *bmain, Scene *scene, SceneLayer *sl, ObjectBase *base_old, BMesh *bm_old)
{
Base *base_new;
ObjectBase *base_new;
Object *obedit = base_old->object;
BMesh *bm_new;
@@ -3031,11 +3032,11 @@ static Base *mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMe
CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
base_new = ED_object_add_duplicate(bmain, scene, base_old, USER_DUP_MESH);
base_new = ED_object_add_duplicate(bmain, scene, sl, base_old, USER_DUP_MESH);
/* DAG_relations_tag_update(bmain); */ /* normally would call directly after but in this case delay recalc */
assign_matarar(base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
ED_base_object_select(base_new, BA_SELECT);
ED_object_base_select(base_new, BA_SELECT);
BMO_op_callf(bm_old, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
"duplicate geom=%hvef dest=%p", BM_ELEM_TAG, bm_new);
@@ -3057,7 +3058,7 @@ static Base *mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMe
return base_new;
}
static bool mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
static bool mesh_separate_selected(Main *bmain, Scene *scene, SceneLayer *sl, ObjectBase *base_old, BMesh *bm_old)
{
/* we may have tags from previous operators */
BM_mesh_elem_hflag_disable_all(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, false);
@@ -3065,7 +3066,7 @@ static bool mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BM
/* sel -> tag */
BM_mesh_elem_hflag_enable_test(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, true, false, BM_ELEM_SELECT);
return (mesh_separate_tagged(bmain, scene, base_old, bm_old) != NULL);
return (mesh_separate_tagged(bmain, scene, sl, base_old, bm_old) != NULL);
}
/* flush a hflag to from verts to edges/faces */
@@ -3164,14 +3165,14 @@ static void mesh_separate_material_assign_mat_nr(Main *bmain, Object *ob, const
}
}
static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
static bool mesh_separate_material(Main *bmain, Scene *scene, SceneLayer *sl, ObjectBase *base_old, BMesh *bm_old)
{
BMFace *f_cmp, *f;
BMIter iter;
bool result = false;
while ((f_cmp = BM_iter_at_index(bm_old, BM_FACES_OF_MESH, NULL, 0))) {
Base *base_new;
ObjectBase *base_new;
const short mat_nr = f_cmp->mat_nr;
int tot = 0;
@@ -3205,7 +3206,7 @@ static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BM
}
/* Move selection into a separate object */
base_new = mesh_separate_tagged(bmain, scene, base_old, bm_old);
base_new = mesh_separate_tagged(bmain, scene, sl, base_old, bm_old);
if (base_new) {
mesh_separate_material_assign_mat_nr(bmain, base_new->object, mat_nr);
}
@@ -3216,7 +3217,7 @@ static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BM
return result;
}
static bool mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
static bool mesh_separate_loose(Main *bmain, Scene *scene, SceneLayer *sl, ObjectBase *base_old, BMesh *bm_old)
{
int i;
BMEdge *e;
@@ -3269,7 +3270,7 @@ static bool mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh
bm_mesh_hflag_flush_vert(bm_old, BM_ELEM_TAG);
/* Move selection into a separate object */
result |= (mesh_separate_tagged(bmain, scene, base_old, bm_old) != NULL);
result |= (mesh_separate_tagged(bmain, scene, sl, base_old, bm_old) != NULL);
}
return result;
@@ -3279,11 +3280,12 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
const int type = RNA_enum_get(op->ptr, "type");
int retval = 0;
if (ED_operator_editmesh(C)) {
Base *base = CTX_data_active_base(C);
ObjectBase *base = CTX_data_active_base(C);
BMEditMesh *em = BKE_editmesh_from_object(base->object);
if (type == 0) {
@@ -3299,13 +3301,13 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
/* editmode separate */
switch (type) {
case MESH_SEPARATE_SELECTED:
retval = mesh_separate_selected(bmain, scene, base, em->bm);
retval = mesh_separate_selected(bmain, scene, sl, base, em->bm);
break;
case MESH_SEPARATE_MATERIAL:
retval = mesh_separate_material(bmain, scene, base, em->bm);
retval = mesh_separate_material(bmain, scene, sl, base, em->bm);
break;
case MESH_SEPARATE_LOOSE:
retval = mesh_separate_loose(bmain, scene, base, em->bm);
retval = mesh_separate_loose(bmain, scene, sl, base, em->bm);
break;
default:
BLI_assert(0);
@@ -3323,7 +3325,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
}
/* object mode separate */
CTX_DATA_BEGIN(C, Base *, base_iter, selected_editable_bases)
CTX_DATA_BEGIN(C, ObjectBase *, base_iter, selected_editable_bases)
{
Object *ob = base_iter->object;
if (ob->type == OB_MESH) {
@@ -3340,10 +3342,10 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
switch (type) {
case MESH_SEPARATE_MATERIAL:
retval_iter = mesh_separate_material(bmain, scene, base_iter, bm_old);
retval_iter = mesh_separate_material(bmain, scene, sl, base_iter, bm_old);
break;
case MESH_SEPARATE_LOOSE:
retval_iter = mesh_separate_loose(bmain, scene, base_iter, bm_old);
retval_iter = mesh_separate_loose(bmain, scene, sl, base_iter, bm_old);
break;
default:
BLI_assert(0);

View File

@@ -461,14 +461,15 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
static int navmesh_create_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
LinkNode *obs = NULL;
Base *navmeshBase = NULL;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
if (base->object->type == OB_MESH) {
if (base->object->body_type == OB_BODY_TYPE_NAVMESH) {
if (!navmeshBase || base == scene->basact) {
if (!navmeshBase || base == sl->basact) {
navmeshBase = base;
}
}

View File

@@ -109,7 +109,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
/* count & check */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
if (base->object->type == OB_MESH) {
me = base->object->data;
@@ -188,7 +188,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
/* first pass over objects - copying materials and vertexgroups across */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
/* only act if a mesh, and not the one we're joining to */
if ((ob != base->object) && (base->object->type == OB_MESH)) {
@@ -302,7 +302,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/* inverse transform for all selected meshes in this object */
invert_m4_m4(imat, ob->obmat);
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
/* only join if this is a mesh */
if (base->object->type == OB_MESH) {
@@ -481,7 +481,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/* free base, now that data is merged */
if (base->object != ob)
ED_base_object_free_and_unlink(bmain, scene, base);
ED_base_object_free_and_unlink(bmain, scene, base->object);
}
}
CTX_DATA_END;
@@ -589,7 +589,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
KeyBlock *kb;
bool ok = false, nonequal_verts = false;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
if (base->object == ob) continue;
@@ -622,7 +622,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
}
/* now ready to add new keys from selected meshes */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
if (base->object == ob) continue;

View File

@@ -63,6 +63,7 @@
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_camera.h"
#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
@@ -73,6 +74,7 @@
#include "BKE_group.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
@@ -204,7 +206,7 @@ void ED_object_rotation_from_view(bContext *C, float rot[3], const char align_ax
}
}
void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], const float rot[3])
void ED_object_base_init_transform(bContext *C, ObjectBase *base, const float loc[3], const float rot[3])
{
Object *ob = base->object;
Scene *scene = CTX_data_scene(C);
@@ -405,10 +407,11 @@ Object *ED_object_add_type(
bContext *C,
int type, const char *name,
const float loc[3], const float rot[3],
bool enter_editmode, unsigned int layer)
bool enter_editmode, unsigned int UNUSED(layer))
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob;
/* for as long scene has editmode... */
@@ -416,13 +419,12 @@ Object *ED_object_add_type(
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */
/* deselects all, sets scene->basact */
ob = BKE_object_add(bmain, scene, type, name);
BASACT->lay = ob->lay = layer;
ob = BKE_object_add(bmain, scene, sl, type, name);
/* editor level activate, notifiers */
ED_base_object_activate(C, BASACT);
ED_object_base_activate(C, sl->basact);
/* more editor stuff */
ED_object_base_init_transform(C, BASACT, loc, rot);
ED_object_base_init_transform(C, sl->basact, loc, rot);
/* Ignore collisions by default for non-mesh objects */
if (type != OB_MESH) {
@@ -1109,21 +1111,19 @@ static void object_delete_check_glsl_update(Object *ob)
/* remove base from a specific scene */
/* note: now unlinks constraints as well */
void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base)
void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
{
if (BKE_library_ID_is_indirectly_used(bmain, base->object) &&
ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0)
if (BKE_library_ID_is_indirectly_used(bmain, ob) &&
ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0)
{
/* We cannot delete indirectly used object... */
printf("WARNING, undeletable object '%s', should have been catched before reaching this function!",
base->object->id.name + 2);
ob->id.name + 2);
return;
}
BKE_scene_base_unlink(scene, base);
object_delete_check_glsl_update(base->object);
BKE_libblock_free_us(bmain, base->object);
MEM_freeN(base);
object_delete_check_glsl_update(ob);
BKE_collections_object_remove(bmain, scene, ob, true);
DAG_id_type_tag(bmain, ID_OB);
}
@@ -1139,56 +1139,46 @@ static int object_delete_exec(bContext *C, wmOperator *op)
if (CTX_data_edit_object(C))
return OPERATOR_CANCELLED;
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, base->object);
if (base->object->id.tag & LIB_TAG_INDIRECT) {
const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, ob);
if (ob->id.tag & LIB_TAG_INDIRECT) {
/* Can this case ever happen? */
BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", base->object->id.name + 2);
BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2);
continue;
}
else if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) {
else if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) {
BKE_reportf(op->reports, RPT_WARNING,
"Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
base->object->id.name + 2, scene->id.name + 2);
ob->id.name + 2, scene->id.name + 2);
continue;
}
/* remove from Grease Pencil parent */
for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl->parent != NULL) {
Object *ob = gpl->parent;
Object *curob = base->object;
if (ob == curob) {
if (gpl->parent == ob) {
gpl->parent = NULL;
}
}
}
}
/* deselect object -- it could be used in other scenes */
base->object->flag &= ~SELECT;
/* remove from current scene only */
ED_base_object_free_and_unlink(bmain, scene, base);
ED_base_object_free_and_unlink(bmain, scene, ob);
changed = true;
if (use_global) {
Scene *scene_iter;
Base *base_other;
for (scene_iter = bmain->scene.first; scene_iter; scene_iter = scene_iter->id.next) {
if (scene_iter != scene && !ID_IS_LINKED_DATABLOCK(scene_iter)) {
base_other = BKE_scene_base_find(scene_iter, base->object);
if (base_other) {
if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) {
BKE_reportf(op->reports, RPT_WARNING,
"Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
base->object->id.name + 2, scene_iter->id.name + 2);
break;
}
ED_base_object_free_and_unlink(bmain, scene_iter, base_other);
if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) {
BKE_reportf(op->reports, RPT_WARNING,
"Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
ob->id.name + 2, scene_iter->id.name + 2);
break;
}
ED_base_object_free_and_unlink(bmain, scene_iter, ob);
}
}
}
@@ -1324,11 +1314,12 @@ static bool dupliobject_cmp(const void *a_, const void *b_)
return false;
}
static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
static void make_object_duplilist_real(bContext *C, Scene *scene, ObjectBase *base,
const bool use_base_parent,
const bool use_hierarchy)
{
Main *bmain = CTX_data_main(C);
SceneLayer *sl = CTX_data_scene_layer(C);
ListBase *lb;
DupliObject *dob;
GHash *dupli_gh = NULL, *parent_gh = NULL;
@@ -1352,7 +1343,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
}
for (dob = lb->first; dob; dob = dob->next) {
Base *basen;
ObjectBase *basen;
Object *ob = ID_NEW_SET(dob->ob, BKE_object_copy(bmain, dob->ob));
/* font duplis can have a totcol without material, we get them from parent
@@ -1360,12 +1351,10 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
*/
if (ob->mat == NULL) ob->totcol = 0;
basen = MEM_dupallocN(base);
basen->flag &= ~(OB_FROMDUPLI | OB_FROMGROUP);
ob->flag = basen->flag;
basen->lay = base->lay;
BLI_addhead(&scene->base, basen); /* addhead: othwise eternal loop */
basen->object = ob;
BKE_collection_object_add_from(scene, dob->ob, ob);
basen = BKE_scene_layer_base_find(sl, ob);
BKE_scene_object_base_flag_sync_from_base(basen);
/* make sure apply works */
BKE_animdata_free(&ob->id, true);
@@ -1380,7 +1369,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
BLI_listbase_clear(&ob->constraints);
ob->curve_cache = NULL;
ob->transflag &= ~OB_DUPLI;
ob->lay = base->lay;
copy_m4_m4(ob->obmat, dob->mat);
BKE_object_apply_mat4(ob, ob->obmat, false, false);
@@ -1507,7 +1495,7 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op)
BKE_main_id_clear_newpoins(bmain);
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
make_object_duplilist_real(C, scene, base, use_base_parent, use_hierarchy);
@@ -1589,10 +1577,10 @@ static int convert_poll(bContext *C)
}
/* Helper for convert_exec */
static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object *ob)
static ObjectBase *duplibase_for_convert(Main *bmain, Scene *scene, SceneLayer *sl, ObjectBase *base, Object *ob)
{
Object *obn;
Base *basen;
ObjectBase *basen;
if (ob == NULL) {
ob = base->object;
@@ -1600,16 +1588,11 @@ static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object
obn = BKE_object_copy(bmain, ob);
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
BKE_collection_object_add_from(scene, ob, obn);
basen = MEM_mallocN(sizeof(Base), "duplibase");
*basen = *base;
BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */
basen->object = obn;
basen->flag |= SELECT;
obn->flag |= SELECT;
base->flag &= ~SELECT;
ob->flag &= ~SELECT;
basen = BKE_scene_layer_base_find(sl, obn);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_select(basen, BA_DESELECT);
return basen;
}
@@ -1617,7 +1600,8 @@ static int convert_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Base *basen = NULL, *basact = NULL;
SceneLayer *sl = CTX_data_scene_layer(C);
ObjectBase *basen = NULL, *basact = NULL;
Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C);
DerivedMesh *dm;
Curve *cu;
@@ -1655,7 +1639,7 @@ static int convert_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
ob = base->object;
@@ -1678,7 +1662,7 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
basen = duplibase_for_convert(bmain, scene, base, NULL);
basen = duplibase_for_convert(bmain, scene, sl, base, NULL);
newob = basen->object;
/* decrement original mesh's usage count */
@@ -1703,7 +1687,7 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
basen = duplibase_for_convert(bmain, scene, base, NULL);
basen = duplibase_for_convert(bmain, scene, sl, base, NULL);
newob = basen->object;
/* decrement original mesh's usage count */
@@ -1735,7 +1719,7 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
basen = duplibase_for_convert(bmain, scene, base, NULL);
basen = duplibase_for_convert(bmain, scene, sl, base, NULL);
newob = basen->object;
/* decrement original curve's usage count */
@@ -1806,7 +1790,7 @@ static int convert_exec(bContext *C, wmOperator *op)
if (target == OB_MESH) {
if (keep_original) {
basen = duplibase_for_convert(bmain, scene, base, NULL);
basen = duplibase_for_convert(bmain, scene, sl, base, NULL);
newob = basen->object;
/* decrement original curve's usage count */
@@ -1841,7 +1825,7 @@ static int convert_exec(bContext *C, wmOperator *op)
if (!(baseob->flag & OB_DONE)) {
baseob->flag |= OB_DONE;
basen = duplibase_for_convert(bmain, scene, base, baseob);
basen = duplibase_for_convert(bmain, scene, sl, base, baseob);
newob = basen->object;
mb = newob->data;
@@ -1892,23 +1876,21 @@ static int convert_exec(bContext *C, wmOperator *op)
if (!keep_original) {
if (mballConverted) {
Base *base, *base_next;
for (base = scene->base.first; base; base = base_next) {
base_next = base->next;
ob = base->object;
Object *ob_mball;
FOREACH_SCENE_OBJECT(scene, ob_mball)
{
if (ob->type == OB_MBALL) {
if (ob->flag & OB_DONE) {
Object *ob_basis = NULL;
if (BKE_mball_is_basis(ob) ||
((ob_basis = BKE_mball_basis_find(scene, ob)) && (ob_basis->flag & OB_DONE)))
if (BKE_mball_is_basis(ob_mball) ||
((ob_basis = BKE_mball_basis_find(scene, ob_mball)) && (ob_basis->flag & OB_DONE)))
{
ED_base_object_free_and_unlink(bmain, scene, base);
ED_base_object_free_and_unlink(bmain, scene, ob_mball);
}
}
}
}
FOREACH_SCENE_OBJECT_END
}
/* delete object should renew depsgraph */
@@ -1920,12 +1902,12 @@ static int convert_exec(bContext *C, wmOperator *op)
if (basact) {
/* active base was changed */
ED_base_object_activate(C, basact);
BASACT = basact;
ED_object_base_activate(C, basact);
BASACT_NEW = basact;
}
else if (BASACT->object->flag & OB_DONE) {
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT->object);
WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT->object);
else if (BASACT_NEW->object->flag & OB_DONE) {
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT_NEW->object);
WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT_NEW->object);
}
DAG_relations_tag_update(bmain);
@@ -1967,18 +1949,17 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* used below, assumes id.new is correct */
/* leaves selection of base/object unaltered */
/* Does set ID->newid pointers. */
static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base, int dupflag)
static ObjectBase *object_add_duplicate_internal(Main *bmain, Scene *scene, SceneLayer *sl, Object *ob, int dupflag)
{
#define ID_NEW_REMAP_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; }
#define ID_NEW_REMAP_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; }
Base *basen = NULL;
ObjectBase *basen = NULL;
Material ***matarar;
Object *ob, *obn;
Object *obn;
ID *id;
int a, didit;
ob = base->object;
if (ob->mode & OB_MODE_POSE) {
; /* nothing? */
}
@@ -1986,20 +1967,18 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
basen = MEM_mallocN(sizeof(Base), "duplibase");
*basen = *base;
BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */
basen->object = obn;
BKE_collection_object_add_from(scene, ob, obn);
basen = BKE_scene_layer_base_find(sl, obn);
/* 1) duplis should end up in same group as the original
* 2) Rigid Body sim participants MUST always be part of a group...
*/
// XXX: is 2) really a good measure here?
if ((basen->flag & OB_FROMGROUP) || ob->rigidbody_object || ob->rigidbody_constraint) {
if ((ob->flag & OB_FROMGROUP) != 0 || ob->rigidbody_object || ob->rigidbody_constraint) {
Group *group;
for (group = bmain->group.first; group; group = group->id.next) {
if (BKE_group_object_exists(group, ob))
BKE_group_object_add(group, obn, scene, basen);
BKE_group_object_add(group, obn);
}
}
@@ -2207,14 +2186,14 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
* note: don't call this within a loop since clear_* funcs loop over the entire database.
* note: caller must do DAG_relations_tag_update(bmain);
* this is not done automatic since we may duplicate many objects in a batch */
Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag)
ObjectBase *ED_object_add_duplicate(Main *bmain, Scene *scene, SceneLayer *sl, ObjectBase *base, int dupflag)
{
Base *basen;
ObjectBase *basen;
Object *ob;
clear_sca_new_poins(); /* BGE logic */
basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
basen = object_add_duplicate_internal(bmain, scene, sl, base->object, dupflag);
if (basen == NULL) {
return NULL;
}
@@ -2241,26 +2220,27 @@ static int duplicate_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
const bool linked = RNA_boolean_get(op->ptr, "linked");
int dupflag = (linked) ? 0 : U.dupflag;
clear_sca_new_poins(); /* BGE logic */
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_bases)
{
Base *basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
ObjectBase *basen = object_add_duplicate_internal(bmain, scene, sl, base->object, dupflag);
/* note that this is safe to do with this context iterator,
* the list is made in advance */
ED_base_object_select(base, BA_DESELECT);
ED_object_base_select(base, BA_DESELECT);
if (basen == NULL) {
continue;
}
/* new object becomes active */
if (BASACT == base)
ED_base_object_activate(C, basen);
if (BASACT_NEW == base)
ED_object_base_activate(C, basen);
if (basen->object->data) {
DAG_id_tag_update(basen->object->data, 0);
@@ -2308,9 +2288,9 @@ static int add_named_exec(bContext *C, wmOperator *op)
wmWindow *win = CTX_wm_window(C);
const wmEvent *event = win ? win->eventstate : NULL;
Main *bmain = CTX_data_main(C);
View3D *v3d = CTX_wm_view3d(C); /* may be NULL */
Scene *scene = CTX_data_scene(C);
Base *basen, *base;
SceneLayer *sl = CTX_data_scene_layer(C);
ObjectBase *basen;
Object *ob;
const bool linked = RNA_boolean_get(op->ptr, "linked");
int dupflag = (linked) ? 0 : U.dupflag;
@@ -2325,22 +2305,17 @@ static int add_named_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
base = MEM_callocN(sizeof(Base), "duplibase");
base->object = ob;
base->flag = ob->flag;
/* prepare dupli */
clear_sca_new_poins(); /* BGE logic */
basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
basen = object_add_duplicate_internal(bmain, scene, sl, ob, dupflag);
BKE_scene_object_base_flag_sync_from_object(basen);
if (basen == NULL) {
MEM_freeN(base);
BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated");
return OPERATOR_CANCELLED;
}
basen->lay = basen->object->lay = BKE_screen_view3d_layer_active(v3d, scene);
basen->object->restrictflag &= ~OB_RESTRICT_VIEW;
if (event) {
@@ -2351,8 +2326,8 @@ static int add_named_exec(bContext *C, wmOperator *op)
ED_view3d_cursor3d_position(C, basen->object->loc, mval);
}
ED_base_object_select(basen, BA_SELECT);
ED_base_object_activate(C, basen);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_activate(C, basen);
copy_object_set_idnew(C);
@@ -2360,8 +2335,6 @@ static int add_named_exec(bContext *C, wmOperator *op)
DAG_relations_tag_update(bmain);
MEM_freeN(base);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT | ND_OB_ACTIVE, scene);
return OPERATOR_FINISHED;

View File

@@ -116,7 +116,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
bool ok = true;
int a;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
ob = base->object;
@@ -310,7 +310,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
Mesh *me;
ClearFlag clear_flag = 0;
@@ -330,7 +330,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
CTX_DATA_END;
}
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
MultiresBakeRender bkr = {NULL};
@@ -390,7 +390,7 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
bkj->user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f;
//bkj->reports = op->reports;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
MultiresBakerJobData *data;
int lvl;

View File

@@ -1682,11 +1682,12 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
if ((found == false) && (add)) {
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Base *base = BASACT, *newbase = NULL;
Object *obt;
/* add new target object */
obt = BKE_object_add(bmain, scene, OB_EMPTY, NULL);
obt = BKE_object_add(bmain, scene, sl, OB_EMPTY, NULL);
/* set layers OK */
newbase = BASACT;

View File

@@ -132,189 +132,6 @@ Object *ED_object_active_context(bContext *C)
}
/* ********* clear/set restrict view *********/
static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
Scene *scene = CTX_data_scene(C);
Base *base;
bool changed = false;
/* XXX need a context loop to handle such cases */
for (base = FIRSTBASE; base; base = base->next) {
if ((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) {
if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) {
base->flag |= SELECT;
}
base->object->flag = base->flag;
base->object->restrictflag &= ~OB_RESTRICT_VIEW;
changed = true;
}
}
if (changed) {
DAG_id_type_tag(bmain, ID_OB);
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_hide_view_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clear Restrict View";
ot->description = "Reveal the object by setting the hide flag";
ot->idname = "OBJECT_OT_hide_view_clear";
/* api callbacks */
ot->exec = object_hide_view_clear_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int object_hide_view_set_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
bool changed = false;
const bool unselected = RNA_boolean_get(op->ptr, "unselected");
CTX_DATA_BEGIN(C, Base *, base, visible_bases)
{
if (!unselected) {
if (base->flag & SELECT) {
base->flag &= ~SELECT;
base->object->flag = base->flag;
base->object->restrictflag |= OB_RESTRICT_VIEW;
changed = true;
if (base == BASACT) {
ED_base_object_activate(C, NULL);
}
}
}
else {
if (!(base->flag & SELECT)) {
base->object->restrictflag |= OB_RESTRICT_VIEW;
changed = true;
if (base == BASACT) {
ED_base_object_activate(C, NULL);
}
}
}
}
CTX_DATA_END;
if (changed) {
DAG_id_type_tag(bmain, ID_OB);
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_hide_view_set(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Restrict View";
ot->description = "Hide the object by setting the hide flag";
ot->idname = "OBJECT_OT_hide_view_set";
/* api callbacks */
ot->exec = object_hide_view_set_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
}
/* 99% same as above except no need for scene refreshing (TODO, update render preview) */
static int object_hide_render_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
bool changed = false;
/* XXX need a context loop to handle such cases */
CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
{
if (ob->restrictflag & OB_RESTRICT_RENDER) {
ob->restrictflag &= ~OB_RESTRICT_RENDER;
changed = true;
}
}
CTX_DATA_END;
if (changed)
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
return OPERATOR_FINISHED;
}
void OBJECT_OT_hide_render_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clear Restrict Render";
ot->description = "Reveal the render object by setting the hide render flag";
ot->idname = "OBJECT_OT_hide_render_clear";
/* api callbacks */
ot->exec = object_hide_render_clear_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int object_hide_render_set_exec(bContext *C, wmOperator *op)
{
const bool unselected = RNA_boolean_get(op->ptr, "unselected");
CTX_DATA_BEGIN(C, Base *, base, visible_bases)
{
if (!unselected) {
if (base->flag & SELECT) {
base->object->restrictflag |= OB_RESTRICT_RENDER;
}
}
else {
if (!(base->flag & SELECT)) {
base->object->restrictflag |= OB_RESTRICT_RENDER;
}
}
}
CTX_DATA_END;
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
return OPERATOR_FINISHED;
}
void OBJECT_OT_hide_render_set(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Restrict Render";
ot->description = "Hide the render object by setting the hide render flag";
ot->idname = "OBJECT_OT_hide_render_set";
/* api callbacks */
ot->exec = object_hide_render_set_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
}
/* ******************* toggle editmode operator ***************** */
static bool mesh_needs_keyindex(const Mesh *me)
@@ -465,31 +282,22 @@ void ED_object_editmode_exit(bContext *C, int flag)
void ED_object_editmode_enter(bContext *C, int flag)
{
Scene *scene = CTX_data_scene(C);
Base *base = NULL;
SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob;
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = NULL;
bool ok = false;
if (ID_IS_LINKED_DATABLOCK(scene)) return;
if (sa && sa->spacetype == SPACE_VIEW3D)
v3d = sa->spacedata.first;
if ((flag & EM_IGNORE_LAYER) == 0) {
base = CTX_data_active_base(C); /* active layer checked here for view3d */
ob = CTX_data_active_object(C); /* active layer checked here for view3d */
if (base == NULL) return;
else if (v3d && (base->lay & v3d->lay) == 0) return;
else if (!v3d && (base->lay & scene->lay) == 0) return;
if (ob == NULL) return;
}
else {
base = scene->basact;
ob = sl->basact->object;
}
if (ELEM(NULL, base, base->object, base->object->data)) return;
ob = base->object;
if (ELEM(NULL, ob, ob->data)) return;
/* this checks actual object->data, for cases when other scenes have it in editmode context */
if (BKE_object_is_in_editmode(ob))
@@ -652,7 +460,7 @@ void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
static int posemode_exec(bContext *C, wmOperator *op)
{
Base *base = CTX_data_active_base(C);
ObjectBase *base = CTX_data_active_base(C);
Object *ob = base->object;
const int mode_flag = OB_MODE_POSE;
const bool is_mode_set = (ob->mode & mode_flag) != 0;

View File

@@ -128,7 +128,6 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
int single_group_index = RNA_enum_get(op->ptr, "group");
Group *single_group = group_object_active_find_index(ob, single_group_index);
Group *group;
@@ -145,13 +144,13 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
if (!BKE_group_object_exists(group, ob))
continue;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
if (BKE_group_object_exists(group, base->object))
continue;
if (!BKE_group_object_cyclic_check(bmain, base->object, group)) {
BKE_group_object_add(group, base->object, scene, base);
BKE_group_object_add(group, base->object);
updated = true;
}
else {
@@ -200,8 +199,8 @@ void GROUP_OT_objects_add_active(wmOperatorType *ot)
static int objects_remove_active_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = OBACT;
SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob = OBACT_NEW;
int single_group_index = RNA_enum_get(op->ptr, "group");
Group *single_group = group_object_active_find_index(ob, single_group_index);
Group *group;
@@ -219,9 +218,9 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
if (BKE_group_object_exists(group, ob)) {
/* Remove groups from selected objects */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
BKE_group_object_unlink(group, base->object, scene, base);
BKE_group_object_unlink(group, base->object);
ok = 1;
}
CTX_DATA_END;
@@ -264,11 +263,10 @@ void GROUP_OT_objects_remove_active(wmOperatorType *ot)
static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
BKE_object_groups_clear(scene, base, base->object);
BKE_object_groups_clear(base->object);
}
CTX_DATA_END;
@@ -297,7 +295,6 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
int single_group_index = RNA_enum_get(op->ptr, "group");
Group *single_group = group_object_active_find_index(ob, single_group_index);
Group *group;
@@ -313,9 +310,9 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
continue;
/* now remove all selected objects from the group */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_editable_bases)
{
BKE_group_object_unlink(group, base->object, scene, base);
BKE_group_object_unlink(group, base->object);
updated = true;
}
CTX_DATA_END;
@@ -357,7 +354,6 @@ void GROUP_OT_objects_remove(wmOperatorType *ot)
static int group_create_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Group *group = NULL;
char name[MAX_ID_NAME - 2]; /* id name */
@@ -365,9 +361,9 @@ static int group_create_exec(bContext *C, wmOperator *op)
group = BKE_group_add(bmain, name);
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_bases)
{
BKE_group_object_add(group, base->object, scene, base);
BKE_group_object_add(group, base->object);
}
CTX_DATA_END;
@@ -398,7 +394,6 @@ void GROUP_OT_create(wmOperatorType *ot)
static int group_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
Main *bmain = CTX_data_main(C);
Group *group;
@@ -407,7 +402,7 @@ static int group_add_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
group = BKE_group_add(bmain, "Group");
BKE_group_object_add(group, ob, scene, NULL);
BKE_group_object_add(group, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -432,7 +427,6 @@ void OBJECT_OT_group_add(wmOperatorType *ot)
static int group_link_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
Group *group = BLI_findlink(&bmain->group, RNA_enum_get(op->ptr, "group"));
@@ -457,7 +451,7 @@ static int group_link_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
BKE_group_object_add(group, ob, scene, NULL);
BKE_group_object_add(group, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -490,14 +484,13 @@ void OBJECT_OT_group_link(wmOperatorType *ot)
static int group_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
Group *group = CTX_data_pointer_get_type(C, "group", &RNA_Group).data;
if (!ob || !group)
return OPERATOR_CANCELLED;
BKE_group_object_unlink(group, ob, scene, NULL); /* base will be used if found */
BKE_group_object_unlink(group, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -558,10 +551,12 @@ static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select o
if (!group)
return OPERATOR_CANCELLED;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object)) {
ED_base_object_select(base, BA_SELECT);
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (BKE_group_object_exists(group, base->object)) {
ED_object_base_select(base, BA_SELECT);
}
}
}
CTX_DATA_END;

View File

@@ -445,12 +445,12 @@ static int hook_op_edit_poll(bContext *C)
return 0;
}
static Object *add_hook_object_new(Main *bmain, Scene *scene, Object *obedit)
static Object *add_hook_object_new(Main *bmain, Scene *scene, SceneLayer *sl, Object *obedit)
{
Base *base, *basedit;
Object *ob;
ob = BKE_object_add(bmain, scene, OB_EMPTY, NULL);
ob = BKE_object_add(bmain, scene, sl, OB_EMPTY, NULL);
basedit = BKE_scene_base_find(scene, obedit);
base = scene->basact;
@@ -464,7 +464,7 @@ static Object *add_hook_object_new(Main *bmain, Scene *scene, Object *obedit)
return ob;
}
static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode, ReportList *reports)
static int add_hook_object(Main *bmain, Scene *scene, SceneLayer *sl, Object *obedit, Object *ob, int mode, ReportList *reports)
{
ModifierData *md = NULL;
HookModifierData *hmd = NULL;
@@ -482,7 +482,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
if (mode == OBJECT_ADDHOOK_NEWOB && !ob) {
ob = add_hook_object_new(bmain, scene, obedit);
ob = add_hook_object_new(bmain, scene, sl, obedit);
/* transform cent to global coords for loc */
mul_v3_m4v3(ob->loc, obedit->obmat, cent);
@@ -556,6 +556,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
Object *obsel = NULL;
const bool use_bone = RNA_boolean_get(op->ptr, "use_bone");
@@ -580,7 +581,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
if (add_hook_object(bmain, scene, obedit, obsel, mode, op->reports)) {
if (add_hook_object(bmain, scene, sl, obedit, obsel, mode, op->reports)) {
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
return OPERATOR_FINISHED;
}
@@ -611,9 +612,10 @@ static int object_add_hook_newob_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
if (add_hook_object(bmain, scene, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) {
if (add_hook_object(bmain, scene, sl, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
return OPERATOR_FINISHED;

View File

@@ -70,7 +70,6 @@ void OBJECT_OT_make_local(struct wmOperatorType *ot);
void OBJECT_OT_make_single_user(struct wmOperatorType *ot);
void OBJECT_OT_make_links_scene(struct wmOperatorType *ot);
void OBJECT_OT_make_links_data(struct wmOperatorType *ot);
void OBJECT_OT_move_to_layer(struct wmOperatorType *ot);
void OBJECT_OT_drop_named_material(struct wmOperatorType *ot);
void OBJECT_OT_unlink_data(struct wmOperatorType *ot);
@@ -78,10 +77,6 @@ void OBJECT_OT_unlink_data(struct wmOperatorType *ot);
void OBJECT_OT_mode_set(struct wmOperatorType *ot);
void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot);
void OBJECT_OT_posemode_toggle(struct wmOperatorType *ot);
void OBJECT_OT_hide_view_set(struct wmOperatorType *ot);
void OBJECT_OT_hide_view_clear(struct wmOperatorType *ot);
void OBJECT_OT_hide_render_set(struct wmOperatorType *ot);
void OBJECT_OT_hide_render_clear(struct wmOperatorType *ot);
void OBJECT_OT_proxy_make(struct wmOperatorType *ot);
void OBJECT_OT_shade_smooth(struct wmOperatorType *ot);
void OBJECT_OT_shade_flat(struct wmOperatorType *ot);

View File

@@ -411,7 +411,7 @@ int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *
return 1;
}
int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, SceneLayer *sl, Object *ob, ModifierData *md)
{
Object *obn;
ParticleSystem *psys;
@@ -463,7 +463,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
if (totvert == 0) return 0;
/* add new mesh */
obn = BKE_object_add(bmain, scene, OB_MESH, NULL);
obn = BKE_object_add(bmain, scene, sl, OB_MESH, NULL);
me = obn->data;
me->totvert = totvert;
@@ -1048,10 +1048,11 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, sl, ob, md))
return OPERATOR_CANCELLED;
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -1683,7 +1684,7 @@ static void skin_armature_bone_create(Object *skin_ob,
}
}
static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *skin_ob)
static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, SceneLayer *sl, Object *skin_ob)
{
BLI_bitmap *edges_visited;
DerivedMesh *deform_dm;
@@ -1706,7 +1707,7 @@ static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *
NULL,
me->totvert);
arm_ob = BKE_object_add(bmain, scene, OB_ARMATURE, NULL);
arm_ob = BKE_object_add(bmain, scene, sl, OB_ARMATURE, NULL);
BKE_object_transform_copy(arm_ob, skin_ob);
arm = arm_ob->data;
arm->layer = 1;
@@ -1765,6 +1766,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob = CTX_data_active_object(C), *arm_ob;
Mesh *me = ob->data;
ModifierData *skin_md;
@@ -1776,7 +1778,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
}
/* create new armature */
arm_ob = modifier_skin_armature_create(bmain, scene, ob);
arm_ob = modifier_skin_armature_create(bmain, scene, sl, ob);
/* add a modifier to connect the new armature to the mesh */
arm_md = (ArmatureModifierData *)modifier_new(eModifierType_Armature);

View File

@@ -67,10 +67,6 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_editmode_toggle);
WM_operatortype_append(OBJECT_OT_posemode_toggle);
WM_operatortype_append(OBJECT_OT_proxy_make);
WM_operatortype_append(OBJECT_OT_hide_view_clear);
WM_operatortype_append(OBJECT_OT_hide_view_set);
WM_operatortype_append(OBJECT_OT_hide_render_clear);
WM_operatortype_append(OBJECT_OT_hide_render_set);
WM_operatortype_append(OBJECT_OT_shade_smooth);
WM_operatortype_append(OBJECT_OT_shade_flat);
WM_operatortype_append(OBJECT_OT_paths_calculate);
@@ -90,13 +86,11 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_make_single_user);
WM_operatortype_append(OBJECT_OT_make_links_scene);
WM_operatortype_append(OBJECT_OT_make_links_data);
WM_operatortype_append(OBJECT_OT_move_to_layer);
WM_operatortype_append(OBJECT_OT_select_random);
WM_operatortype_append(OBJECT_OT_select_all);
WM_operatortype_append(OBJECT_OT_select_same_group);
WM_operatortype_append(OBJECT_OT_select_by_type);
WM_operatortype_append(OBJECT_OT_select_by_layer);
WM_operatortype_append(OBJECT_OT_select_linked);
WM_operatortype_append(OBJECT_OT_select_grouped);
WM_operatortype_append(OBJECT_OT_select_mirror);
@@ -382,25 +376,6 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "OBJECT_OT_origin_clear", OKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
/* same as above but for rendering */
WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_clear", HKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_CTRL, 0);
/* conflicts, removing */
#if 0
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)
RNA_boolean_set(kmi->ptr, "unselected", true);
#endif
WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_global", false);

View File

@@ -63,6 +63,7 @@
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_camera.h"
#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
@@ -74,6 +75,7 @@
#include "BKE_fcurve.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
@@ -331,6 +333,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
Object *ob, *gob = ED_object_active_context(C);
GroupObject *go;
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
if (gob->dup_group != NULL) {
go = BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "object"));
@@ -349,7 +352,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
BLI_snprintf(name, sizeof(name), "%s_proxy", ((ID *)(gob ? gob : ob))->name + 2);
/* Add new object for the proxy */
newob = BKE_object_add(bmain, scene, OB_EMPTY, name);
newob = BKE_object_add(bmain, scene, sl, OB_EMPTY, name);
/* set layers OK */
newbase = BASACT; /* BKE_object_add sets active... */
@@ -1305,119 +1308,6 @@ void OBJECT_OT_track_set(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_make_track_types, 0, "Type", "");
}
/************************** Move to Layer Operator *****************************/
static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
{
int values[20], a;
unsigned int lay = 0;
if (!RNA_struct_property_is_set(op->ptr, "layers")) {
/* note: layers are set in bases, library objects work for this */
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
lay |= base->lay;
}
CTX_DATA_END;
for (a = 0; a < 20; a++)
values[a] = (lay & (1 << a)) != 0;
RNA_boolean_set_array(op->ptr, "layers", values);
}
else {
RNA_boolean_get_array(op->ptr, "layers", values);
for (a = 0; a < 20; a++)
if (values[a])
lay |= (1 << a);
}
return lay;
}
static int move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->localvd) {
return WM_operator_confirm_message(C, op, "Move out of Local View");
}
else {
move_to_layer_init(C, op);
return WM_operator_props_popup(C, op, event);
}
}
static int move_to_layer_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
unsigned int lay, local;
/* bool is_lamp = false; */ /* UNUSED */
lay = move_to_layer_init(C, op);
lay &= 0xFFFFFF;
if (lay == 0) return OPERATOR_CANCELLED;
if (v3d && v3d->localvd) {
/* now we can move out of localview. */
/* note: layers are set in bases, library objects work for this */
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
lay = base->lay & ~v3d->lay;
base->lay = lay;
base->object->lay = lay;
base->object->flag &= ~SELECT;
base->flag &= ~SELECT;
/* if (base->object->type == OB_LAMP) is_lamp = true; */
}
CTX_DATA_END;
}
else {
/* normal non localview operation */
/* note: layers are set in bases, library objects work for this */
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
/* upper byte is used for local view */
local = base->lay & 0xFF000000;
base->lay = lay + local;
base->object->lay = base->lay;
/* if (base->object->type == OB_LAMP) is_lamp = true; */
}
CTX_DATA_END;
}
/* warning, active object may be hidden now */
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
DAG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
}
void OBJECT_OT_move_to_layer(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Move to Layer";
ot->description = "Move the object to different layers";
ot->idname = "OBJECT_OT_move_to_layer";
/* api callbacks */
ot->invoke = move_to_layer_invoke;
ot->exec = move_to_layer_exec;
ot->poll = ED_operator_objectmode;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", "");
}
/************************** Link to Scene Operator *****************************/
#if 0
@@ -1440,20 +1330,6 @@ static void link_to_scene(Main *UNUSED(bmain), unsigned short UNUSED(nr))
}
#endif
Base *ED_object_scene_link(Scene *scene, Object *ob)
{
Base *base;
if (BKE_scene_base_find(scene, ob)) {
return NULL;
}
base = BKE_scene_base_add(scene, ob);
id_us_plus(&ob->id);
return base;
}
static int make_links_scene_exec(bContext *C, wmOperator *op)
{
Scene *scene_to = BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene"));
@@ -1473,9 +1349,10 @@ static int make_links_scene_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
SceneCollection *sc_to = BKE_collection_master(scene_to);
CTX_DATA_BEGIN (C, ObjectBase *, base, selected_bases)
{
ED_object_scene_link(scene_to, base->object);
BKE_collection_object_add(scene_to, sc_to, base->object);
}
CTX_DATA_END;
@@ -1531,7 +1408,6 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst
static int make_links_data_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
const int type = RNA_enum_get(op->ptr, "type");
Object *ob_src;
ID *obdata_id;
@@ -1549,7 +1425,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
ob_groups = BKE_object_groups(ob_src);
}
CTX_DATA_BEGIN (C, Base *, base_dst, selected_editable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base_dst, selected_editable_bases)
{
Object *ob_dst = base_dst->object;
@@ -1594,12 +1470,12 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
LinkNode *group_node;
/* first clear groups */
BKE_object_groups_clear(scene, base_dst, ob_dst);
BKE_object_groups_clear(ob_dst);
/* now add in the groups from the link nodes */
for (group_node = ob_groups; group_node; group_node = group_node->next) {
if (ob_dst->dup_group != group_node->link) {
BKE_group_object_add(group_node->link, ob_dst, scene, base_dst);
BKE_group_object_add(group_node->link, ob_dst);
}
else {
is_cycle = true;
@@ -1732,48 +1608,82 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
/**************************** Make Single User ********************************/
static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob, const bool copy_groups)
{
if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) {
/* base gets copy of object */
Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
if (copy_groups) {
if (ob->flag & OB_FROMGROUP) {
obn->flag |= OB_FROMGROUP;
}
}
else {
/* copy already clears */
}
/* remap gpencil parenting */
if (scene->gpd) {
bGPdata *gpd = scene->gpd;
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl->parent == ob) {
gpl->parent = obn;
}
}
}
id_us_min(&ob->id);
return obn;
}
return NULL;
}
static void libblock_relink_scene_collection(SceneCollection *sc)
{
for (LinkData *link = sc->objects.first; link; link = link->next) {
BKE_libblock_relink_to_newid(link->data);
}
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
libblock_relink_scene_collection(nsc);
}
}
static void single_object_users_scene_collection(Main *bmain, Scene *scene, SceneCollection *sc, const int flag, const bool copy_groups)
{
for (LinkData *link = sc->objects.first; link; link = link->next) {
Object *ob = link->data;
/* an object may be in more than one collection */
if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) {
link->data = single_object_users_object(bmain, scene, link->data, copy_groups);
}
}
/* we reset filter objects because they should be regenerated after this */
BLI_freelistN(&sc->filter_objects);
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
single_object_users_scene_collection(bmain, scene, nsc, flag, copy_groups);
}
}
/* Warning, sets ID->newid pointers of objects and groups, but does not clear them. */
static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups)
{
Base *base;
Object *ob, *obn;
Group *group, *groupn;
GroupObject *go;
clear_sca_new_poins(); /* BGE logic */
/* duplicate (must set newid) */
for (base = FIRSTBASE; base; base = base->next) {
ob = base->object;
/* duplicate all the objects of the scene */
SceneCollection *msc = BKE_collection_master(scene);
single_object_users_scene_collection(bmain, scene, msc, flag, copy_groups);
if ((base->flag & flag) == flag) {
if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) {
/* base gets copy of object */
base->object = obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
if (copy_groups) {
if (ob->flag & OB_FROMGROUP) {
obn->flag |= OB_FROMGROUP;
}
}
else {
/* copy already clears */
}
/* remap gpencil parenting */
if (scene->gpd) {
bGPdata *gpd = scene->gpd;
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl->parent == ob) {
gpl->parent = obn;
}
}
}
base->flag = obn->flag;
id_us_min(&ob->id);
}
/* loop over SceneLayers and assign the pointers accordingly */
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
ID_NEW_REMAP(base->object);
}
}
@@ -1806,27 +1716,29 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
if (v3d) ID_NEW_REMAP(v3d->camera);
/* object and group pointers */
for (base = FIRSTBASE; base; base = base->next) {
BKE_libblock_relink_to_newid(&base->object->id);
}
libblock_relink_scene_collection(msc);
set_sca_new_poins();
/* TODO redo filter */
TODO_LAYER_SYNC_FILTER
}
/* not an especially efficient function, only added so the single user
* button can be functional.*/
void ED_object_single_user(Main *bmain, Scene *scene, Object *ob)
{
Base *base;
const bool copy_groups = false;
for (base = FIRSTBASE; base; base = base->next) {
if (base->object == ob) base->flag |= OB_DONE;
else base->flag &= ~OB_DONE;
Object *ob_iter;
FOREACH_SCENE_OBJECT(scene, ob_iter)
{
ob_iter->flag &= ~OB_DONE;
}
FOREACH_SCENE_OBJECT_END
single_object_users(bmain, scene, NULL, OB_DONE, copy_groups);
/* tag only the one object */
ob->flag |= OB_DONE;
single_object_users(bmain, scene, NULL, OB_DONE, false);
BKE_main_id_clear_newpoins(bmain);
}
@@ -1863,6 +1775,8 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
ID *id;
int a;
TODO_LAYER; /* need to use scene->collection base instead of scene->bases */
for (base = FIRSTBASE; base; base = base->next) {
ob = base->object;
if (!ID_IS_LINKED_DATABLOCK(ob) && (base->flag & flag) == flag) {
@@ -1939,31 +1853,27 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
}
}
static void single_object_action_users(Scene *scene, const int flag)
static void single_object_action_users(Scene *scene, SceneLayer *sl, const int flag)
{
Object *ob;
Base *base;
for (base = FIRSTBASE; base; base = base->next) {
ob = base->object;
if (!ID_IS_LINKED_DATABLOCK(ob) && (flag == 0 || (base->flag & SELECT)) ) {
FOREACH_OBJECT_FLAG(scene, sl, flag, ob)
if (!ID_IS_LINKED_DATABLOCK(ob)) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
BKE_animdata_copy_id_action(&ob->id, false);
}
}
FOREACH_OBJECT_FLAG_END
}
static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bool do_textures)
static void single_mat_users(Main *bmain, Scene *scene, SceneLayer *sl, const int flag, const bool do_textures)
{
Object *ob;
Base *base;
Material *ma, *man;
Tex *tex;
int a, b;
for (base = FIRSTBASE; base; base = base->next) {
ob = base->object;
if (!ID_IS_LINKED_DATABLOCK(ob) && (flag == 0 || (base->flag & SELECT)) ) {
Object *ob;
FOREACH_OBJECT_FLAG(scene, sl, flag, ob)
if (!ID_IS_LINKED_DATABLOCK(ob)) {
for (a = 1; a <= ob->totcol; a++) {
ma = give_current_material(ob, a);
if (ma) {
@@ -1992,7 +1902,7 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo
}
}
}
}
FOREACH_OBJECT_FLAG_END
}
static void do_single_tex_user(Main *bmain, Tex **from)
@@ -2096,7 +2006,7 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo
if (full) {
single_obdata_users(bmain, scene, 0);
single_object_action_users(scene, 0);
single_object_action_users(scene, NULL, 0);
single_mat_users_expand(bmain);
single_tex_users_expand(bmain);
}
@@ -2200,7 +2110,7 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene)
base = BKE_scene_base_add(scene, ob);
base->flag |= SELECT;
base->object->flag = base->flag;
BKE_scene_base_flag_sync_from_base(base);
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
changed = true;
@@ -2366,13 +2276,20 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C); /* ok if this is NULL */
const int flag = (RNA_enum_get(op->ptr, "type") == MAKE_SINGLE_USER_SELECTED) ? SELECT : 0;
const bool copy_groups = false;
bool update_deps = false;
if (RNA_boolean_get(op->ptr, "object")) {
single_object_users(bmain, scene, v3d, flag, copy_groups);
if (flag == SELECT) {
BKE_scene_layer_selected_objects_tag(sl, OB_DONE);
single_object_users(bmain, scene, v3d, OB_DONE, copy_groups);
}
else {
single_object_users(bmain, scene, v3d, 0, copy_groups);
}
/* needed since object relationships may have changed */
update_deps = true;
@@ -2383,7 +2300,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
}
if (RNA_boolean_get(op->ptr, "material")) {
single_mat_users(bmain, scene, flag, RNA_boolean_get(op->ptr, "texture"));
single_mat_users(bmain, scene, sl, flag, RNA_boolean_get(op->ptr, "texture"));
}
#if 0 /* can't do this separate from materials */
@@ -2391,7 +2308,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
single_mat_users(scene, flag, true);
#endif
if (RNA_boolean_get(op->ptr, "animation")) {
single_object_action_users(scene, flag);
single_object_action_users(scene, sl, flag);
}
BKE_main_id_clear_newpoins(bmain);

View File

@@ -52,6 +52,7 @@
#include "BKE_context.h"
#include "BKE_group.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_particle.h"
@@ -96,7 +97,7 @@ void ED_base_object_select(Base *base, short mode)
else if (mode == BA_DESELECT) {
base->flag &= ~SELECT;
}
base->object->flag = base->flag;
BKE_scene_base_flag_sync_from_base(base);
}
}
@@ -119,6 +120,33 @@ void ED_base_object_activate(bContext *C, Base *base)
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, NULL);
}
void ED_object_base_select(ObjectBase *base, short mode)
{
if (base) {
if (mode == BA_SELECT) {
if ((base->flag & BASE_SELECTABLED) != 0) {
base->flag |= BASE_SELECTED;
}
}
else if (mode == BA_DESELECT) {
base->flag &= ~BASE_SELECTED;
}
}
}
void ED_object_base_activate(bContext *C, ObjectBase *base)
{
SceneLayer *sl = CTX_data_scene_layer(C);
sl->basact = base;
if (base) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, sl);
}
else {
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, NULL);
}
}
/********************** Selection Operators **********************/
static int objects_selectable_poll(bContext *C)
@@ -145,17 +173,17 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op)
extend = RNA_boolean_get(op->ptr, "extend");
if (extend == 0) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
ED_base_object_select(base, BA_DESELECT);
ED_object_base_select(base, BA_DESELECT);
}
CTX_DATA_END;
}
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if (base->object->type == obtype) {
ED_base_object_select(base, BA_SELECT);
ED_object_base_select(base, BA_SELECT);
}
}
CTX_DATA_END;
@@ -210,38 +238,15 @@ static EnumPropertyItem prop_select_linked_types[] = {
{0, NULL, 0, NULL, NULL}
};
// XXX old animation system
#if 0
static int object_select_all_by_ipo(bContext *C, Ipo *ipo)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
if (base->object->ipo == ipo) {
base->flag |= SELECT;
base->object->flag = base->flag;
changed = true;
}
}
CTX_DATA_END;
return changed;
}
#endif
static bool object_select_all_by_obdata(bContext *C, void *obdata)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if ((base->flag & SELECT) == 0) {
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (base->object->data == obdata) {
base->flag |= SELECT;
base->object->flag = base->flag;
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -255,9 +260,9 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture,
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if ((base->flag & SELECT) == 0) {
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
Object *ob = base->object;
Material *mat1;
int a, b;
@@ -267,7 +272,7 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture,
if (!use_texture) {
if (mat1 == mat) {
base->flag |= SELECT;
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -275,7 +280,7 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture,
for (b = 0; b < MAX_MTEX; b++) {
if (mat1->mtex[b]) {
if (tex == mat1->mtex[b]->tex) {
base->flag |= SELECT;
ED_object_base_select(base, BA_SELECT);
changed = true;
break;
}
@@ -283,8 +288,6 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture,
}
}
}
base->object->flag = base->flag;
}
}
CTX_DATA_END;
@@ -297,14 +300,12 @@ static bool object_select_all_by_dup_group(bContext *C, Object *ob)
bool changed = false;
Group *dup_group = (ob->transflag & OB_DUPLIGROUP) ? ob->dup_group : NULL;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if ((base->flag & SELECT) == 0) {
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
Group *dup_group_other = (base->object->transflag & OB_DUPLIGROUP) ? base->object->dup_group : NULL;
if (dup_group == dup_group_other) {
base->flag |= SELECT;
base->object->flag = base->flag;
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -319,25 +320,23 @@ static bool object_select_all_by_particle(bContext *C, Object *ob)
ParticleSystem *psys_act = psys_get_current(ob);
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if ((base->flag & SELECT) == 0) {
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
/* loop through other particles*/
ParticleSystem *psys;
for (psys = base->object->particlesystem.first; psys; psys = psys->next) {
if (psys->part == psys_act->part) {
base->flag |= SELECT;
ED_object_base_select(base, BA_SELECT);
changed = true;
break;
}
if (base->flag & SELECT) {
if (base->flag & BASE_SELECTED) {
break;
}
}
base->object->flag = base->flag;
}
}
CTX_DATA_END;
@@ -349,13 +348,11 @@ static bool object_select_all_by_library(bContext *C, Library *lib)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if ((base->flag & SELECT) == 0) {
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (lib == base->object->id.lib) {
base->flag |= SELECT;
base->object->flag = base->flag;
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -369,13 +366,11 @@ static bool object_select_all_by_library_obdata(bContext *C, Library *lib)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if ((base->flag & SELECT) == 0) {
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (base->object->data && lib == ((ID *)base->object->data)->lib) {
base->flag |= SELECT;
base->object->flag = base->flag;
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -415,9 +410,9 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
extend = RNA_boolean_get(op->ptr, "extend");
if (extend == 0) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
ED_base_object_select(base, BA_DESELECT);
ED_object_base_select(base, BA_DESELECT);
}
CTX_DATA_END;
}
@@ -517,7 +512,7 @@ enum {
OBJECT_GRPSEL_PARENT = 2,
OBJECT_GRPSEL_SIBLINGS = 3,
OBJECT_GRPSEL_TYPE = 4,
OBJECT_GRPSEL_LAYER = 5,
/*OBJECT_GRPSEL_LAYER = 5,*/
OBJECT_GRPSEL_GROUP = 6,
OBJECT_GRPSEL_HOOK = 7,
OBJECT_GRPSEL_PASS = 8,
@@ -533,7 +528,6 @@ static EnumPropertyItem prop_select_grouped_types[] = {
{OBJECT_GRPSEL_PARENT, "PARENT", 0, "Parent", ""},
{OBJECT_GRPSEL_SIBLINGS, "SIBLINGS", 0, "Siblings", "Shared Parent"},
{OBJECT_GRPSEL_TYPE, "TYPE", 0, "Type", "Shared object type"},
{OBJECT_GRPSEL_LAYER, "LAYER", 0, "Layer", "Shared layers"},
{OBJECT_GRPSEL_GROUP, "GROUP", 0, "Group", "Shared group"},
{OBJECT_GRPSEL_HOOK, "HOOK", 0, "Hook", ""},
{OBJECT_GRPSEL_PASS, "PASS", 0, "Pass", "Render pass Index"},
@@ -548,16 +542,17 @@ static bool select_grouped_children(bContext *C, Object *ob, const bool recursiv
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
if (ob == base->object->parent) {
if (!(base->flag & SELECT)) {
ED_base_object_select(base, BA_SELECT);
if ((base->flag & BASE_SELECTED) == 0) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
if (recursive)
if (recursive) {
changed |= select_grouped_children(C, base->object, 1);
}
}
}
CTX_DATA_END;
@@ -566,20 +561,21 @@ static bool select_grouped_children(bContext *C, Object *ob, const bool recursiv
static bool select_grouped_parent(bContext *C) /* Makes parent active and de-selected OBACT */
{
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C);
ObjectBase *baspar, *basact = CTX_data_active_base(C);
bool changed = false;
Base *baspar, *basact = CTX_data_active_base(C);
if (!basact || !(basact->object->parent)) return 0; /* we know OBACT is valid */
if (!basact || !(basact->object->parent)) {
return 0; /* we know OBACT is valid */
}
baspar = BKE_scene_base_find(scene, basact->object->parent);
baspar = BKE_scene_layer_base_find(sl, basact->object->parent);
/* can be NULL if parent in other scene */
if (baspar && BASE_SELECTABLE(v3d, baspar)) {
ED_base_object_select(baspar, BA_SELECT);
ED_base_object_activate(C, baspar);
ED_object_base_select(baspar, BA_SELECT);
ED_object_base_activate(C, baspar);
changed = true;
}
return changed;
@@ -606,11 +602,13 @@ static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in
return 0;
else if (group_count == 1) {
group = ob_groups[0];
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object)) {
ED_base_object_select(base, BA_SELECT);
changed = true;
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (BKE_group_object_exists(group, base->object)) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
}
CTX_DATA_END;
@@ -661,10 +659,10 @@ static bool select_grouped_siblings(bContext *C, Object *ob)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
if ((base->object->parent == ob->parent) && !(base->flag & SELECT)) {
ED_base_object_select(base, BA_SELECT);
if ((base->object->parent == ob->parent) && ((base->flag & BASE_SELECTED) == 0)) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -677,12 +675,12 @@ static bool select_grouped_lamptype(bContext *C, Object *ob)
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
if (base->object->type == OB_LAMP) {
Lamp *la_test = base->object->data;
if ((la->type == la_test->type) && !(base->flag & SELECT)) {
ED_base_object_select(base, BA_SELECT);
if ((la->type == la_test->type) && ((base->flag & BASE_SELECTED) == 0)) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -694,25 +692,10 @@ static bool select_grouped_type(bContext *C, Object *ob)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
if ((base->object->type == ob->type) && !(base->flag & SELECT)) {
ED_base_object_select(base, BA_SELECT);
changed = true;
}
}
CTX_DATA_END;
return changed;
}
static bool select_grouped_layer(bContext *C, Object *ob)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
if ((base->lay & ob->lay) && !(base->flag & SELECT)) {
ED_base_object_select(base, BA_SELECT);
if ((base->object->type == ob->type) && ((base->flag & BASE_SELECTED) == 0)) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -724,10 +707,10 @@ static bool select_grouped_index_object(bContext *C, Object *ob)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
if ((base->object->index == ob->index) && !(base->flag & SELECT)) {
ED_base_object_select(base, BA_SELECT);
if ((base->object->index == ob->index) && ((base->flag & BASE_SELECTED) == 0)) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -739,10 +722,10 @@ static bool select_grouped_color(bContext *C, Object *ob)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
if (!(base->flag & SELECT) && (compare_v3v3(base->object->col, ob->col, 0.005f))) {
ED_base_object_select(base, BA_SELECT);
if (((base->flag & BASE_SELECTED) == 0) && (compare_v3v3(base->object->col, ob->col, 0.005f))) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -766,10 +749,10 @@ static bool select_grouped_gameprops(bContext *C, Object *ob)
{
bool changed = false;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
if (!(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) {
ED_base_object_select(base, BA_SELECT);
if (((base->flag & BASE_SELECTED) == 0) && (objects_share_gameprop(base->object, ob))) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
}
@@ -804,10 +787,10 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
/* select each object that Keying Set refers to */
/* TODO: perhaps to be more in line with the rest of these, we should only take objects
* if the passed in object is included in this too */
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
/* only check for this object if it isn't selected already, to limit time wasted */
if ((base->flag & SELECT) == 0) {
if ((base->flag & BASE_SELECTED) == 0) {
KS_Path *ksp;
/* this is the slow way... we could end up with > 500 items here,
@@ -816,7 +799,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
/* if id matches, select then stop looping (match found) */
if (ksp->id == (ID *)base->object) {
ED_base_object_select(base, BA_SELECT);
ED_object_base_select(base, BA_SELECT);
changed = true;
break;
}
@@ -838,9 +821,9 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
extend = RNA_boolean_get(op->ptr, "extend");
if (extend == 0) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
ED_base_object_select(base, BA_DESELECT);
ED_object_base_select(base, BA_DESELECT);
changed = true;
}
CTX_DATA_END;
@@ -868,9 +851,6 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
case OBJECT_GRPSEL_TYPE:
changed |= select_grouped_type(C, ob);
break;
case OBJECT_GRPSEL_LAYER:
changed |= select_grouped_layer(C, ob);
break;
case OBJECT_GRPSEL_GROUP:
changed |= select_grouped_group(C, ob);
break;
@@ -928,85 +908,6 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
}
/************************* Select by Layer **********************/
enum {
OB_SEL_LAYERMATCH_EXACT = 1,
OB_SEL_LAYERMATCH_SHARED = 2,
};
static int object_select_by_layer_exec(bContext *C, wmOperator *op)
{
unsigned int layernum;
bool extend;
int match;
extend = RNA_boolean_get(op->ptr, "extend");
layernum = RNA_int_get(op->ptr, "layers");
match = RNA_enum_get(op->ptr, "match");
if (extend == false) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
ED_base_object_select(base, BA_DESELECT);
}
CTX_DATA_END;
}
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
bool ok = false;
switch (match) {
case OB_SEL_LAYERMATCH_EXACT:
/* Mask out bits used for local view, only work on real layer ones, see T45783. */
ok = ((base->lay & ((1 << 20) - 1)) == (1 << (layernum - 1)));
break;
case OB_SEL_LAYERMATCH_SHARED:
ok = (base->lay & (1 << (layernum - 1))) != 0;
break;
default:
break;
}
if (ok) {
ED_base_object_select(base, BA_SELECT);
}
}
CTX_DATA_END;
/* undo? */
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
return OPERATOR_FINISHED;
}
void OBJECT_OT_select_by_layer(wmOperatorType *ot)
{
static EnumPropertyItem match_items[] = {
{OB_SEL_LAYERMATCH_EXACT, "EXACT", 0, "Exact Match", ""},
{OB_SEL_LAYERMATCH_SHARED, "SHARED", 0, "Shared Layers", ""},
{0, NULL, 0, NULL, NULL}
};
/* identifiers */
ot->name = "Select by Layer";
ot->description = "Select all visible objects on a layer";
ot->idname = "OBJECT_OT_select_by_layer";
/* api callbacks */
/*ot->invoke = XXX - need a int grid popup*/
ot->exec = object_select_by_layer_exec;
ot->poll = objects_selectable_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_enum(ot->srna, "match", match_items, OB_SEL_LAYERMATCH_EXACT, "Match", "");
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
RNA_def_int(ot->srna, "layers", 1, 1, 20, "Layer", "", 1, 20);
}
/**************************** (De)select All ****************************/
static int object_select_all_exec(bContext *C, wmOperator *op)
@@ -1018,9 +919,9 @@ static int object_select_all_exec(bContext *C, wmOperator *op)
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if (base->flag & SELECT) {
if ((base->flag & BASE_SELECTED) != 0) {
action = SEL_DESELECT;
break;
}
@@ -1028,21 +929,21 @@ static int object_select_all_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
}
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
switch (action) {
case SEL_SELECT:
ED_base_object_select(base, BA_SELECT);
ED_object_base_select(base, BA_SELECT);
break;
case SEL_DESELECT:
ED_base_object_select(base, BA_DESELECT);
ED_object_base_select(base, BA_DESELECT);
break;
case SEL_INVERT:
if (base->flag & SELECT) {
ED_base_object_select(base, BA_DESELECT);
if ((base->flag & BASE_SELECTED) != 0) {
ED_object_base_select(base, BA_DESELECT);
}
else {
ED_base_object_select(base, BA_SELECT);
ED_object_base_select(base, BA_SELECT);
}
break;
}
@@ -1090,10 +991,13 @@ static int object_select_same_group_exec(bContext *C, wmOperator *op)
return OPERATOR_PASS_THROUGH;
}
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, visible_bases)
{
if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object))
ED_base_object_select(base, BA_SELECT);
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
if (BKE_group_object_exists(group, base->object)) {
ED_object_base_select(base, BA_SELECT);
}
}
}
CTX_DATA_END;
@@ -1124,11 +1028,12 @@ void OBJECT_OT_select_same_group(wmOperatorType *ot)
static int object_select_mirror_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
bool extend;
extend = RNA_boolean_get(op->ptr, "extend");
CTX_DATA_BEGIN (C, Base *, primbase, selected_bases)
CTX_DATA_BEGIN (C, ObjectBase *, primbase, selected_bases)
{
char name_flip[MAXBONENAME];
@@ -1137,15 +1042,15 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op)
if (!STREQ(name_flip, primbase->object->id.name + 2)) {
Object *ob = (Object *)BKE_libblock_find_name(ID_OB, name_flip);
if (ob) {
Base *secbase = BKE_scene_base_find(scene, ob);
ObjectBase *secbase = BKE_scene_layer_base_find(sl, ob);
if (secbase) {
ED_base_object_select(secbase, BA_SELECT);
ED_object_base_select(secbase, BA_SELECT);
}
}
}
if (extend == false) ED_base_object_select(primbase, BA_DESELECT);
if (extend == false) ED_object_base_select(primbase, BA_DESELECT);
}
CTX_DATA_END;
@@ -1180,9 +1085,9 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot)
static bool object_select_more_less(bContext *C, const bool select)
{
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
for (Base *base = scene->base.first; base; base = base->next) {
for (Base *base = sl->object_bases.first; base; base = base->next) {
Object *ob = base->object;
ob->flag &= ~OB_DONE;
ob->id.tag &= ~LIB_TAG_DOIT;
@@ -1206,7 +1111,7 @@ static bool object_select_more_less(bContext *C, const bool select)
for (ctx_base = ctx_base_list.first; ctx_base; ctx_base = ctx_base->next) {
Object *ob = ((Base *)ctx_base->ptr.data)->object;
Object *ob = ((ObjectBase *)ctx_base->ptr.data)->object;
if (ob->parent) {
if ((ob->flag & OB_DONE) != (ob->parent->flag & OB_DONE)) {
ob->id.tag |= LIB_TAG_DOIT;
@@ -1220,10 +1125,10 @@ static bool object_select_more_less(bContext *C, const bool select)
const short select_flag = select ? SELECT : 0;
for (ctx_base = ctx_base_list.first; ctx_base; ctx_base = ctx_base->next) {
Base *base = ctx_base->ptr.data;
ObjectBase *base = ctx_base->ptr.data;
Object *ob = base->object;
if ((ob->id.tag & LIB_TAG_DOIT) && ((ob->flag & SELECT) != select_flag)) {
ED_base_object_select(base, select_mode);
ED_object_base_select(base, select_mode);
changed = true;
}
}
@@ -1302,10 +1207,10 @@ static int object_select_random_exec(bContext *C, wmOperator *op)
RNG *rng = BLI_rng_new_srandom(seed);
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
CTX_DATA_BEGIN (C, ObjectBase *, base, selectable_bases)
{
if (BLI_rng_get_float(rng) < randfac) {
ED_base_object_select(base, select);
ED_object_base_select(base, select);
}
}
CTX_DATA_END;

View File

@@ -89,7 +89,7 @@ bool ED_rigidbody_constraint_add(Main *bmain, Scene *scene, Object *ob, int type
ob->rigidbody_constraint->flag |= RBC_FLAG_NEEDS_VALIDATE;
/* add constraint to rigid body constraint group */
BKE_group_object_add(rbw->constraints, ob, scene, NULL);
BKE_group_object_add(rbw->constraints, ob);
DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
@@ -102,7 +102,7 @@ void ED_rigidbody_constraint_remove(Main *bmain, Scene *scene, Object *ob)
BKE_rigidbody_remove_constraint(scene, ob);
if (rbw)
BKE_group_object_unlink(rbw->constraints, ob, scene, NULL);
BKE_group_object_unlink(rbw->constraints, ob);
DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);

View File

@@ -119,7 +119,7 @@ bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, Re
ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;
/* add object to rigid body group */
BKE_group_object_add(rbw->group, ob, scene, NULL);
BKE_group_object_add(rbw->group, ob);
DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
@@ -133,7 +133,7 @@ void ED_rigidbody_object_remove(Main *bmain, Scene *scene, Object *ob)
BKE_rigidbody_remove_object(scene, ob);
if (rbw)
BKE_group_object_unlink(rbw->group, ob, scene, NULL);
BKE_group_object_unlink(rbw->group, ob);
DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);

View File

@@ -54,6 +54,7 @@
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
@@ -626,11 +627,11 @@ static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
BKE_scene_add_render_layer(scene, NULL);
scene->r.actlay = BLI_listbase_count(&scene->r.layers) - 1;
BKE_scene_layer_add(scene, NULL);
scene->active_layer = BLI_listbase_count(&scene->render_layers) - 1;
DAG_id_tag_update(&scene->id, 0);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
return OPERATOR_FINISHED;
}
@@ -652,10 +653,11 @@ void SCENE_OT_render_layer_add(wmOperatorType *ot)
static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
SceneRenderLayer *rl = BLI_findlink(&scene->r.layers, scene->r.actlay);
SceneLayer *sl = BLI_findlink(&scene->render_layers, scene->active_layer);
if (!BKE_scene_remove_render_layer(CTX_data_main(C), scene, rl))
if (!BKE_scene_layer_remove(CTX_data_main(C), scene, sl)) {
return OPERATOR_CANCELLED;
}
DAG_id_tag_update(&scene->id, 0);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);

View File

@@ -75,6 +75,18 @@ void fdrawbox(float x1, float y1, float x2, float y2)
glEnd();
}
void fdrawbox_filled(float x1, float y1, float x2, float y2)
{
glBegin(GL_POLYGON);
glVertex2f(x1, y1);
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
glEnd();
}
void fdrawcheckerboard(float x1, float y1, float x2, float y2) /* DEPRECATED */
{
unsigned char col1[4] = {40, 40, 40}, col2[4] = {50, 50, 50};

View File

@@ -47,6 +47,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_gpencil.h"
#include "BKE_layer.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
@@ -60,20 +61,8 @@
#include "screen_intern.h"
static unsigned int context_layers(bScreen *sc, Scene *scene, ScrArea *sa_ctx)
{
/* needed for 'USE_ALLSELECT' define, otherwise we end up editing off-screen layers. */
if (sc && sa_ctx && (sa_ctx->spacetype == SPACE_BUTS)) {
const unsigned int lay = BKE_screen_view3d_layer_all(sc);
if (lay) {
return lay;
}
}
return scene->lay;
}
const char *screen_context_dir[] = {
"scene", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
"scene", "render_layer", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
"selected_objects", "selected_bases",
"editable_objects", "editable_bases",
"selected_editable_objects", "selected_editable_bases",
@@ -95,17 +84,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bScreen *sc = CTX_wm_screen(C);
ScrArea *sa = CTX_wm_area(C);
Scene *scene = sc->scene;
Base *base;
#if 0 /* Using the context breaks adding objects in the UI. Need to find out why - campbell */
Object *obact = CTX_data_active_object(C);
Object *obedit = CTX_data_edit_object(C);
base = CTX_data_active_base(C);
#else
SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = scene->obedit;
Object *obact = OBACT;
base = BASACT;
#endif
Object *obact = sl->basact ? sl->basact->object : NULL;
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, screen_context_dir);
@@ -115,84 +96,105 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_id_pointer_set(result, &scene->id);
return 1;
}
else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
const bool visible_objects = CTX_data_equals(member, "visible_objects");
for (base = scene->base.first; base; base = base->next) {
if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) {
if (visible_objects)
CTX_data_id_list_add(result, &base->object->id);
else
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
else if (CTX_data_equals(member, "visible_objects")) {
Object *ob;
FOREACH_VISIBLE_OBJECT(sl, ob)
{
CTX_data_id_list_add(result, &ob->id);
}
FOREACH_VISIBLE_BASE_END
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "selectable_objects")) {
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
CTX_data_id_list_add(result, &base->object->id);
}
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
const bool selectable_objects = CTX_data_equals(member, "selectable_objects");
for (base = scene->base.first; base; base = base->next) {
if (base->lay & lay) {
if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) {
if (selectable_objects)
CTX_data_id_list_add(result, &base->object->id);
else
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
else if (CTX_data_equals(member, "selected_objects")) {
Object *ob;
FOREACH_SELECTED_OBJECT(sl, ob)
{
CTX_data_id_list_add(result, &ob->id);
}
FOREACH_SELECTED_OBJECT_END
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
const bool selected_objects = CTX_data_equals(member, "selected_objects");
for (base = scene->base.first; base; base = base->next) {
if ((base->flag & SELECT) && (base->lay & lay)) {
if (selected_objects)
CTX_data_id_list_add(result, &base->object->id);
else
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
else if (CTX_data_equals(member, "selected_editable_objects")) {
Object *ob;
FOREACH_SELECTED_OBJECT(sl, ob)
{
if (0 == BKE_object_is_libdata(ob)) {
CTX_data_id_list_add(result, &ob->id);
}
}
FOREACH_SELECTED_OBJECT_END
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");
for (base = scene->base.first; base; base = base->next) {
if ((base->flag & SELECT) && (base->lay & lay)) {
if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
if (0 == BKE_object_is_libdata(base->object)) {
if (selected_editable_objects)
CTX_data_id_list_add(result, &base->object->id);
else
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
}
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "editable_objects") || CTX_data_equals(member, "editable_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
const bool editable_objects = CTX_data_equals(member, "editable_objects");
else if (CTX_data_equals(member, "editable_objects")) {
/* Visible + Editable, but not necessarily selected */
for (base = scene->base.first; base; base = base->next) {
if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) {
Object *ob;
FOREACH_VISIBLE_OBJECT(sl, ob)
{
if (0 == BKE_object_is_libdata(ob)) {
CTX_data_id_list_add(result, &ob->id);
}
}
FOREACH_VISIBLE_OBJECT_END
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if ( CTX_data_equals(member, "visible_bases")) {
ObjectBase *base;
FOREACH_VISIBLE_BASE(sl, base)
{
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
FOREACH_VISIBLE_BASE_END
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "selectable_bases")) {
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_SELECTABLED) != 0) {
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "selected_bases")) {
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_SELECTED) != 0) {
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "selected_editable_bases")) {
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_SELECTED) != 0) {
if (0 == BKE_object_is_libdata(base->object)) {
if (editable_objects)
CTX_data_id_list_add(result, &base->object->id);
else
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
else if (CTX_data_equals(member, "editable_bases")) {
/* Visible + Editable, but not necessarily selected */
for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_VISIBLED) != 0) {
if (0 == BKE_object_is_libdata(base->object)) {
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
}
@@ -344,8 +346,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
}
else if (CTX_data_equals(member, "active_base")) {
if (base)
CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base);
if (sl->basact)
CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, sl->basact);
return 1;
}

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