Render Layers and Collections (merge from render-layers)

Design Documents
----------------

* https://wiki.blender.org/index.php/Dev:2.8/Source/Layers

* https://wiki.blender.org/index.php/Dev:2.8/Source/DataDesignRevised

User Commit Log
---------------

* New Layer and Collection system to replace render layers and viewport layers.

* A layer is a set of collections of objects (and their drawing options) required for specific tasks.

* A collection is a set of objects, equivalent of the old layers in Blender. A collection can be shared across multiple layers.

* All Scenes have a master collection that all other collections are children of.

* New collection "context" tab (in Properties Editor)

* New temporary viewport "collections" panel to control per-collection
visibility

Missing User Features
---------------------

* Collection "Filter"
  Option to add objects based on their names

* Collection Manager operators
  The existing buttons  are placeholders

* Collection Manager drawing
  The editor main region is empty

* Collection Override

* Per-Collection engine settings
  This will come as a separate commit, as part of the clay-engine branch

Dev Commit Log
--------------

* New DNA file (DNA_layer_types.h) with the new structs
  We are replacing Base by a new extended Base while keeping it backward
  compatible with some legacy settings (i.e., lay, flag_legacy).

  Renamed all Base to BaseLegacy to make it clear the areas of code that
  still need to be converted

  Note: manual changes were required on - deg_builder_nodes.h, rna_object.c, KX_Light.cpp

* Unittesting for main syncronization requirements
  - read, write, add/copy/remove objects, copy scene, collection
  link/unlinking, context)

* New Editor: Collection Manager
  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 doesn't include the editors/space_collections/ draw and util files

    - The drawing code itself will be implemented separately by Julian

* Base / Object:
  A little note about them. Original Blender code would try to keep them
  in sync through the code, juggling flags back and forth. This will now
  be handled by Depsgraph, keeping Object and Bases more separated
  throughout the non-rendering code.

  Scene.base is being cleared in doversion, and the old viewport drawing
  code was poorly converted to use the new bases while the new viewport
  code doesn't get merged and replace the old one.

Python API Changes
------------------

```
- scene.layers
+ # no longer exists

- scene.objects
+ scene.scene_layers.active.objects

- scene.objects.active
+ scene.render_layers.active.objects.active

- bpy.context.scene.objects.link()
+ bpy.context.scene_collection.objects.link()

- bpy_extras.object_utils.object_data_add(context, obdata, operator=None, use_active_layer=True, name=None)
+ bpy_extras.object_utils.object_data_add(context, obdata, operator=None, name=None)

- bpy.context.object.select
+ bpy.context.object.select = True
+ bpy.context.object.select = False
+ bpy.context.object.select_get()
+ bpy.context.object.select_set(action='SELECT')
+ bpy.context.object.select_set(action='DESELECT')

-AddObjectHelper.layers
+ # no longer exists
```
This commit is contained in:
Dalai Felinto 2017-02-07 10:18:38 +01:00
parent 97fa285ae1
commit aeb8e81f27
186 changed files with 6300 additions and 2286 deletions

@ -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

@ -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):

@ -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)

@ -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)

@ -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'}

@ -102,7 +102,7 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
m.range_max = max_dist
return {'FINISHED'}
# Find selected mesh objects
selection = [ob for ob in scene.objects if ob.select and ob.type == 'MESH' and ob.name != ref.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 from the reference to mesh vertices
min_dist = sys.float_info.max

@ -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'}

@ -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:

@ -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",

@ -0,0 +1,79 @@
# ##### 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")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

@ -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)
@ -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)

@ -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__)

@ -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,74 @@ 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.prop(collection, "hide_select", 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'

@ -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')

@ -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

@ -341,7 +341,7 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx)
{
Base *base = static_cast<Base *>(m_scene->base.first);
BaseLegacy *base = static_cast<BaseLegacy *>(m_scene->base.first);
while (base) {
Object *ob = base->object;
@ -366,7 +366,7 @@ void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx)
void AbcExporter::createTransformWritersFlat()
{
Base *base = static_cast<Base *>(m_scene->base.first);
BaseLegacy *base = static_cast<BaseLegacy *>(m_scene->base.first);
while (base) {
Object *ob = base->object;
@ -445,7 +445,7 @@ void AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupl
void AbcExporter::createShapeWriters(EvaluationContext *eval_ctx)
{
Base *base = static_cast<Base *>(m_scene->base.first);
BaseLegacy *base = static_cast<BaseLegacy *>(m_scene->base.first);
while (base) {
Object *ob = base->object;

@ -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 Base;
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__ */

@ -40,12 +40,16 @@ extern "C" {
struct ARegion;
struct bScreen;
struct CacheFile;
struct LayerCollection;
struct ListBase;
struct Main;
struct Object;
struct Base;
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);

@ -33,6 +33,7 @@
* \author nzc
*/
struct BaseLegacy;
struct Base;
struct EvaluationContext;
struct Group;
@ -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);

@ -0,0 +1,189 @@
/*
* ***** 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 /* BaseLegacy to Base related TODO */
#define TODO_LAYER_OPERATORS /* collection mamanger and property panel operators */
#define TODO_LAYER /* generic todo */
struct Base;
struct ID;
struct LayerCollection;
struct Main;
struct Object;
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 Base *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 Base *selbase);
void BKE_scene_layer_base_flag_recalculate(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);
/* 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) \
{ \
Base *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_) \
{ \
/* flush all the data to objects*/ \
Base *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__ */

@ -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
*/

@ -35,12 +35,13 @@ extern "C" {
#include "BLI_compiler_attrs.h"
struct Base;
struct BaseLegacy;
struct EvaluationContext;
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)
@ -255,7 +256,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);

@ -38,10 +38,11 @@ extern "C" {
#endif
struct AviCodecData;
struct Base;
struct BaseLegacy;
struct EvaluationContext;
struct Main;
struct Object;
struct Base;
struct QuicktimeCodecData;
struct RenderData;
struct SceneRenderLayer;
@ -61,7 +62,7 @@ struct Main;
_base; \
_base = _setlooper_base_step(&_sce_iter, _base)
struct Base *_setlooper_base_step(struct Scene **sce_iter, struct Base *base);
struct BaseLegacy *_setlooper_base_step(struct Scene **sce_iter, struct BaseLegacy *base);
void free_avicodecdata(struct AviCodecData *acd);
void free_qtcodecdata(struct QuicktimeCodecData *acd);
@ -70,13 +71,15 @@ 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);
struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
void BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
struct BaseLegacy *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
struct BaseLegacy *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
struct BaseLegacy *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
void BKE_scene_base_unlink(struct Scene *sce, struct BaseLegacy *base);
void BKE_scene_base_deselect_all(struct Scene *sce);
void BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
void BKE_scene_base_select(struct Scene *sce, struct BaseLegacy *selbase);
/* Scene base iteration function.
* Define struct here, so no need to bother with alloc/free it.
@ -90,10 +93,14 @@ typedef struct SceneBaseIter {
} SceneBaseIter;
int BKE_scene_base_iter_next(struct EvaluationContext *eval_ctx, struct SceneBaseIter *iter,
struct Scene **scene, int val, struct Base **base, struct Object **ob);
struct Scene **scene, int val, struct BaseLegacy **base, struct Object **ob);
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 BaseLegacy *base);
void BKE_scene_base_flag_sync_from_object(struct BaseLegacy *base);
void BKE_scene_object_base_flag_sync_from_base(struct Base *base);
void BKE_scene_object_base_flag_sync_from_object(struct Base *base);
void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);

@ -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

@ -283,7 +283,7 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
/* tweak the object ordering to trick depsgraph into making MotionPath calculations run faster */
static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
{
Base *base, *baseNext;
BaseLegacy *base, *baseNext;
MPathTarget *mpt;
/* make sure our temp-tag isn't already in use */
@ -321,7 +321,7 @@ static void motionpaths_calc_update_scene(Scene *scene)
BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, scene->lay);
}
else { /* otherwise we can optimize by restricting updates */
Base *base, *last = NULL;
BaseLegacy *base, *last = NULL;
/* only stuff that moves or needs display still */
DAG_scene_update_flags(G.main, scene, scene->lay, true, false);

@ -205,7 +205,7 @@ float BKE_cachefile_time_offset(CacheFile *cache_file, const float time, const f
/* TODO(kevin): replace this with some depsgraph mechanism, or something similar. */
void BKE_cachefile_clean(Scene *scene, CacheFile *cache_file)
{
for (Base *base = scene->base.first; base; base = base->next) {
for (BaseLegacy *base = scene->base.first; base; base = base->next) {
Object *ob = base->object;
ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache);

@ -853,7 +853,7 @@ static Object *camera_multiview_advanced(Scene *scene, Object *camera, const cha
}
if (name[0] != '\0') {
Base *base = BKE_scene_base_find_by_name(scene, name);
BaseLegacy *base = BKE_scene_base_find_by_name(scene, name);
if (base) {
return base->object;
}

@ -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);
}
}

@ -514,7 +514,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
// collision object will exclude self
Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, int layer, unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
{
Base *base;
BaseLegacy *base;
Object **objs;
GroupObject *go;
unsigned int numobj= 0, maxobj= 100;
@ -596,7 +596,7 @@ ListBase *get_collider_cache(Scene *scene, Object *self, Group *group)
}
else {
Scene *sce_iter;
Base *base;
BaseLegacy *base;
/* add objects in same layer in scene */
for (SETLOOPER(scene, sce_iter, base)) {

@ -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);

@ -488,7 +488,7 @@ static void scene_setSubframe(Scene *scene, float subframe)
static int surface_getBrushFlags(DynamicPaintSurface *surface, const Scene *scene)
{
Base *base = NULL;
BaseLegacy *base = NULL;
GroupObject *go = NULL;
Object *brushObj = NULL;
ModifierData *md = NULL;
@ -5780,7 +5780,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
* Loop through surface's target paint objects and do painting
*/
{
Base *base = NULL;
BaseLegacy *base = NULL;
GroupObject *go = NULL;
Object *brushObj = NULL;
ModifierData *md = NULL;

@ -209,7 +209,7 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
EffectorWeights *weights, bool for_simulation)
{
Base *base;
BaseLegacy *base;
unsigned int layer= ob_src->lay;
ListBase *effectors = NULL;

@ -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;
}

@ -0,0 +1,684 @@
/*
* ***** 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 */
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 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 (Base *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 NULL;
}
/* Base */
Base *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
{
return BLI_findptr(&sl->object_bases, ob, offsetof(Base, object));
}
void BKE_scene_layer_base_deselect_all(SceneLayer *sl)
{
Base *base;
for (base = sl->object_bases.first; base; base = base->next) {
base->flag &= ~BASE_SELECTED;
}
}
void BKE_scene_layer_base_select(struct SceneLayer *sl, Base *selbase)
{
sl->basact = selbase;
if ((selbase->flag & BASE_SELECTABLED) != 0) {
selbase->flag |= BASE_SELECTED;
}
}
static void scene_layer_object_base_unref(SceneLayer* sl, Base *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) {
Base *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 (Base *base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_SELECTABLED) == 0) {
base->flag &= ~BASE_SELECTED;
}
}
}
/**
* Return the base if existent, or create it if necessary
* Always bump the refcount
*/
static Base *object_base_add(SceneLayer *sl, Object *ob)
{
Base *base;
base = BKE_scene_layer_base_find(sl, ob);
if (base == NULL) {
base = MEM_callocN(sizeof(Base), "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);
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)
{
Base *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;
}
BLI_addtail(&lc->object_bases, BLI_genericNodeN(base));
BKE_scene_layer_base_flag_recalculate(sl);
}
static void layer_collection_object_remove(SceneLayer *sl, LayerCollection *lc, Object *ob)
{
Base *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_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) {
Base *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;
}
/* ---------------------------------------------------------------------- */
/* Iterators */
static void object_bases_Iterator_begin(Iterator *iter, void *data_in, const int flag)
{
SceneLayer *sl = data_in;
Base *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)
{
Base *base = ((Base *)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 = ((Base *)iter->current)->object;
}
}
static void objects_Iterator_next(Iterator *iter, const int flag)
{
object_bases_Iterator_next(iter, flag);
if (iter->valid) {
iter->current = ((Base *)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 */
}

@ -68,6 +68,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"
@ -354,7 +355,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
Scene *scene = (Scene *) id;
ToolSettings *toolsett = scene->toolsettings;
SceneRenderLayer *srl;
Base *base;
BaseLegacy *legacy_base;
CALLBACK_INVOKE(scene->camera, IDWALK_CB_NOP);
CALLBACK_INVOKE(scene->world, IDWALK_CB_USER);
@ -411,8 +412,28 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER);
for (base = scene->base.first; base; base = base->next) {
CALLBACK_INVOKE(base->object, IDWALK_CB_USER);
for (legacy_base = scene->base.first; legacy_base; legacy_base = legacy_base->next) {
CALLBACK_INVOKE(legacy_base->object, IDWALK_CB_USER);
}
SceneCollection *sc;
FOREACH_SCENE_COLLECTION(scene, sc)
{
for (LinkData *link = sc->objects.first; link; link = link->next) {
CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
}
for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
}
}
FOREACH_SCENE_COLLECTION_END
SceneLayer *sl;
for (sl = scene->render_layers.first; sl; sl = sl->next) {
for (Base *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) {

@ -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"
@ -242,7 +243,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
/* Some reamapping unfortunately require extra and/or specific handling, tackle those here. */
static void libblock_remap_data_preprocess_scene_base_unlink(
IDRemap *r_id_remap_data, Scene *sce, Base *base, const bool skip_indirect, const bool is_indirect)
IDRemap *r_id_remap_data, Scene *sce, BaseLegacy *base, const bool skip_indirect, const bool is_indirect)
{
if (skip_indirect && is_indirect) {
r_id_remap_data->skipped_indirect++;
@ -258,6 +259,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)) {
@ -272,7 +289,16 @@ 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. */
Base *base, *base_next;
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
BaseLegacy *base, *base_next;
for (base = sce->base.first; base; base = base_next) {
base_next = base->next;
libblock_remap_data_preprocess_scene_base_unlink(
@ -282,8 +308,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);
BaseLegacy *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);
@ -329,7 +358,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 {
@ -342,23 +371,17 @@ 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;
for (BaseLegacy *base = sce->base.first; base; base = base->next) {
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;
}
}
}

@ -316,7 +316,7 @@ bool BKE_mball_is_basis_for(Object *ob1, Object *ob2)
void BKE_mball_properties_copy(Scene *scene, Object *active_object)
{
Scene *sce_iter = scene;
Base *base;
BaseLegacy *base;
Object *ob;
MetaBall *active_mball = (MetaBall *)active_object->data;
int basisnr, obnr;
@ -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 (Base *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;
}
}
}
}

@ -1080,7 +1080,7 @@ static void polygonize(PROCESS *process)
static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scene, Object *ob)
{
Scene *sce_iter = scene;
Base *base;
BaseLegacy *base;
Object *bob;
MetaBall *mb;
const MetaElem *ml;
@ -1102,7 +1102,7 @@ static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scen
zero_size = 0;
ml = NULL;
if (bob == ob && (base->flag & OB_FROMDUPLI) == 0) {
if (bob == ob && (base->flag_legacy & OB_FROMDUPLI) == 0) {
mb = ob->data;
if (mb->editelems) ml = mb->editelems->first;

@ -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--;
}
}
}
}

@ -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"
@ -153,7 +154,7 @@ void BKE_object_workob_clear(Object *workob)
void BKE_object_update_base_layer(struct Scene *scene, Object *ob)
{
Base *base = scene->base.first;
BaseLegacy *base = scene->base.first;
while (base) {
if (base->object == ob) base->lay = ob->lay;
@ -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;
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;
}
@ -2542,11 +2545,11 @@ void BKE_scene_foreach_display_point(
Scene *scene, View3D *v3d, const short flag,
void (*func_cb)(const float[3], void *), void *user_data)
{
Base *base;
BaseLegacy *base;
Object *ob;
for (base = FIRSTBASE; base; base = base->next) {
if (BASE_VISIBLE_BGMODE(v3d, scene, base) && (base->flag & flag) == flag) {
if (BASE_VISIBLE_BGMODE(v3d, scene, base) && (base->flag_legacy & flag) == flag) {
ob = base->object;
if ((ob->transflag & OB_DUPLI) == 0) {
@ -3351,7 +3354,7 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
{
LinkNode *links = NULL;
Base *base;
BaseLegacy *base;
/* Remove markers from all objects */
for (base = scene->base.first; base; base = base->next) {
@ -3395,7 +3398,7 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
/* child relationship */
if (includeFilter & (OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE)) {
Base *local_base;
BaseLegacy *local_base;
for (local_base = scene->base.first; local_base; local_base = local_base->next) {
if (BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, local_base)) {
@ -3441,18 +3444,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);
}
}

@ -241,7 +241,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
else {
unsigned int lay = ctx->scene->lay;
int baseid = 0;
Base *base;
BaseLegacy *base;
for (base = ctx->scene->base.first; base; base = base->next, baseid++) {
Object *ob = base->object;

@ -2896,7 +2896,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
Base *base;
BaseLegacy *base;
int distr=0, alloc=0, skip=0;
if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)

@ -3541,7 +3541,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
Main *bmain = baker->main;
Scene *scene = baker->scene;
Scene *sce_iter; /* SETLOOPER macro only */
Base *base;
BaseLegacy *base;
ListBase pidlist;
PTCacheID *pid = &baker->pid;
PointCache *cache = NULL;

@ -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"
@ -154,13 +156,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;
BaseLegacy *legacy_base, *olegacy_base;
if (type == SCE_COPY_EMPTY) {
ListBase rl, rv;
@ -214,14 +269,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 +299,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 (Base *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 +556,16 @@ 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;
}
void BKE_scene_init(Scene *sce)
@ -820,6 +915,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)
@ -835,9 +936,9 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
return sce;
}
Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
BaseLegacy *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
{
Base *base;
BaseLegacy *base;
for (base = scene->base.first; base; base = base->next) {
if (STREQ(base->object->id.name + 2, name)) {
@ -848,9 +949,9 @@ Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
return base;
}
Base *BKE_scene_base_find(Scene *scene, Object *ob)
BaseLegacy *BKE_scene_base_find(Scene *scene, Object *ob)
{
return BLI_findptr(&scene->base, ob, offsetof(Base, object));
return BLI_findptr(&scene->base, ob, offsetof(BaseLegacy, object));
}
/**
@ -861,11 +962,10 @@ Base *BKE_scene_base_find(Scene *scene, Object *ob)
void BKE_scene_set_background(Main *bmain, Scene *scene)
{
Scene *sce;
Base *base;
BaseLegacy *base;
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 +997,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) */
}
@ -924,7 +1018,7 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name)
/* Used by metaballs, return *all* objects (including duplis) existing in the scene (including scene's sets) */
int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
Scene **scene, int val, Base **base, Object **ob)
Scene **scene, int val, BaseLegacy **base, Object **ob)
{
bool run_again = true;
@ -1006,7 +1100,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
}
/* handle dupli's */
if (iter->dupob) {
(*base)->flag |= OB_FROMDUPLI;
(*base)->flag_legacy |= OB_FROMDUPLI;
*ob = iter->dupob->ob;
iter->phase = F_DUPLI;
@ -1025,7 +1119,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
}
else if (iter->phase == F_DUPLI) {
iter->phase = F_SCENE;
(*base)->flag &= ~OB_FROMDUPLI;
(*base)->flag_legacy &= ~OB_FROMDUPLI;
if (iter->dupli_refob) {
/* Restore last object's real matrix. */
@ -1052,7 +1146,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
Object *BKE_scene_camera_find(Scene *sc)
{
Base *base;
BaseLegacy *base;
for (base = sc->base.first; base; base = base->next)
if (base->object->type == OB_CAMERA)
@ -1154,28 +1248,32 @@ char *BKE_scene_find_last_marker_name(Scene *scene, int frame)
return best_marker ? best_marker->name : NULL;
}
Base *BKE_scene_base_add(Scene *sce, Object *ob)
void BKE_scene_remove_rigidbody_object(Scene *scene, Object *ob)
{
Base *b = MEM_callocN(sizeof(*b), __func__);
/* 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);
}
BaseLegacy *BKE_scene_base_add(Scene *sce, Object *ob)
{
BaseLegacy *b = MEM_callocN(sizeof(*b), __func__);
BLI_addhead(&sce->base, b);
b->object = ob;
b->flag = ob->flag;
b->flag_legacy = ob->flag;
b->lay = ob->lay;
return b;
}
void BKE_scene_base_unlink(Scene *sce, Base *base)
void BKE_scene_base_unlink(Scene *sce, BaseLegacy *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;
@ -1183,18 +1281,20 @@ void BKE_scene_base_unlink(Scene *sce, Base *base)
void BKE_scene_base_deselect_all(Scene *sce)
{
Base *b;
BaseLegacy *b;
for (b = sce->base.first; b; b = b->next) {
b->flag &= ~SELECT;
b->object->flag = b->flag;
b->flag_legacy &= ~SELECT;
int flag = b->object->flag & (OB_FROMGROUP);
b->object->flag = b->flag_legacy;
b->object->flag |= flag;
}
}
void BKE_scene_base_select(Scene *sce, Base *selbase)
void BKE_scene_base_select(Scene *sce, BaseLegacy *selbase)
{
selbase->flag |= SELECT;
selbase->object->flag = selbase->flag;
selbase->flag_legacy |= SELECT;
selbase->object->flag = selbase->flag_legacy;
sce->basact = selbase;
}
@ -1492,15 +1592,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);
}
}
@ -1588,7 +1680,7 @@ float get_render_aosss_error(const RenderData *r, float error)
}
/* helper function for the SETLOOPER macro */
Base *_setlooper_base_step(Scene **sce_iter, Base *base)
BaseLegacy *_setlooper_base_step(Scene **sce_iter, BaseLegacy *base)
{
if (base && base->next) {
/* common case, step to the next */
@ -1596,12 +1688,12 @@ Base *_setlooper_base_step(Scene **sce_iter, Base *base)
}
else if (base == NULL && (*sce_iter)->base.first) {
/* first time looping, return the scenes first base */
return (Base *)(*sce_iter)->base.first;
return (BaseLegacy *)(*sce_iter)->base.first;
}
else {
/* reached the end, get the next base in the set */
while ((*sce_iter = (*sce_iter)->set)) {
base = (Base *)(*sce_iter)->base.first;
base = (BaseLegacy *)(*sce_iter)->base.first;
if (base) {
return base;
}
@ -1648,24 +1740,56 @@ bool BKE_scene_uses_blender_game(const Scene *scene)
void BKE_scene_base_flag_to_objects(struct Scene *scene)
{
Base *base = scene->base.first;
BaseLegacy *base = scene->base.first;
while (base) {
base->object->flag = base->flag;
BKE_scene_base_flag_sync_from_base(base);
base = base->next;
}
}
void BKE_scene_base_flag_from_objects(struct Scene *scene)
{
Base *base = scene->base.first;
BaseLegacy *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(BaseLegacy *base)
{
Object *ob = base->object;
/* keep the object only flags untouched */
int flag = ob->flag & OB_FROMGROUP;
ob->flag = base->flag_legacy;
ob->flag |= flag;
}
void BKE_scene_base_flag_sync_from_object(BaseLegacy *base)
{
base->flag_legacy = base->object->flag;
}
void BKE_scene_object_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_object_base_flag_sync_from_object(Base *base)
{
base->flag = base->object->flag;
}
void BKE_scene_disable_color_management(Scene *scene)
{
ColorManagedDisplaySettings *display_settings = &scene->display_settings;

@ -698,7 +698,7 @@ static float calc_voxel_transp(float *result, float *input, int res[3], int *pix
static int get_lamp(Scene *scene, float *light)
{
Base *base_tmp = NULL;
BaseLegacy *base_tmp = NULL;
int found_lamp = 0;
// try to find a lamp, preferably local

@ -530,7 +530,7 @@ static void ccd_build_deflector_hash(Scene *scene, Group *group, Object *vertexo
}
}
else {
for (Base *base = scene->base.first; base; base = base->next) {
for (BaseLegacy *base = scene->base.first; base; base = base->next) {
/*Only proceed for mesh object in same layer */
if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
ob= base->object;
@ -576,7 +576,7 @@ static void ccd_update_deflector_hash(Scene *scene, Group *group, Object *vertex
}
}
else {
for (Base *base = scene->base.first; base; base = base->next) {
for (BaseLegacy *base = scene->base.first; base; base = base->next) {
/*Only proceed for mesh object in same layer */
if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
ob= base->object;
@ -986,7 +986,7 @@ static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer)
}
}
else {
for (Base *base = scene->base.first; base; base= base->next) {
for (BaseLegacy *base = scene->base.first; base; base= base->next) {
if ( (base->lay & layer) && base->object->pd) {
if (base->object->pd->deflect)
return 1;

@ -782,7 +782,7 @@ void BKE_sound_read_waveform(bSound *sound, short *stop)
void BKE_sound_update_scene(Main *bmain, struct Scene *scene)
{
Object *ob;
Base *base;
BaseLegacy *base;
NlaTrack *track;
NlaStrip *strip;
Speaker *speaker;

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

@ -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__ */

@ -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

@ -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

@ -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"
@ -5630,11 +5633,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;
BaseLegacy *base_legacy, *base_legacy_next;
Sequence *seq;
SceneLayer *sl;
SceneRenderLayer *srl;
FreestyleModuleConfig *fmc;
FreestyleLineSet *fls;
@ -5684,17 +5705,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);
}
}
@ -5780,6 +5801,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 (Base *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,
@ -5883,12 +5913,42 @@ 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_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_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;
sce->theDag = NULL;
@ -6139,6 +6199,19 @@ 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);
}
}
/* ************ READ WM ***************** */
@ -6482,6 +6555,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;
@ -6867,6 +6944,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;
}
}
}
}
@ -7261,6 +7342,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);
@ -7457,7 +7542,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 */
}
}
}
@ -8389,6 +8474,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! */
@ -8400,8 +8486,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)
@ -9484,9 +9570,24 @@ 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;
BaseLegacy *base;
SceneRenderLayer *srl;
FreestyleModuleConfig *module;
FreestyleLineSet *lineset;
@ -9553,6 +9654,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)
@ -9799,7 +9902,7 @@ static bool object_in_any_scene(Main *mainvar, Object *ob)
static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Library *lib, const short flag)
{
Object *ob;
Base *base;
BaseLegacy *base;
const unsigned int active_lay = (flag & FILE_ACTIVELAY) ? BKE_screen_view3d_layer_active(v3d, scene) : 0;
const bool is_link = (flag & FILE_LINK) != 0;
@ -9820,7 +9923,7 @@ static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Libra
}
if (do_it) {
base = MEM_callocN(sizeof(Base), __func__);
base = MEM_callocN(sizeof(BaseLegacy), __func__);
BLI_addtail(&scene->base, base);
if (active_lay) {
@ -9835,7 +9938,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);
@ -9851,7 +9954,7 @@ static void give_base_to_groups(
Main *mainvar, Scene *scene, View3D *v3d, Library *UNUSED(lib), const short UNUSED(flag))
{
Group *group;
Base *base;
BaseLegacy *base;
Object *ob;
const unsigned int active_lay = BKE_screen_view3d_layer_active(v3d, scene);
@ -9868,8 +9971,8 @@ static void give_base_to_groups(
/* assign the base */
base = BKE_scene_base_add(scene, ob);
base->flag |= SELECT;
base->object->flag = base->flag;
base->flag_legacy |= SELECT;
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;
@ -9951,10 +10054,10 @@ static ID *link_named_part(
static void link_object_postprocess(ID *id, Scene *scene, View3D *v3d, const short flag)
{
if (scene) {
Base *base;
BaseLegacy *base;
Object *ob;
base = MEM_callocN(sizeof(Base), "app_nam_part");
base = MEM_callocN(sizeof(BaseLegacy), "app_nam_part");
BLI_addtail(&scene->base, base);
ob = (Object *)id;
@ -9967,12 +10070,12 @@ static void link_object_postprocess(ID *id, Scene *scene, View3D *v3d, const sho
ob->mode = OB_MODE_OBJECT;
base->lay = ob->lay;
base->object = ob;
base->flag = ob->flag;
base->flag_legacy = ob->flag;
id_us_plus_no_lib((ID *)ob);
if (flag & FILE_AUTOSELECT) {
base->flag |= SELECT;
base->object->flag = base->flag;
base->flag_legacy |= SELECT;
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 */
}
}

@ -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

@ -736,7 +736,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 250) {
bScreen *screen;
Scene *scene;
Base *base;
BaseLegacy *base;
Material *ma;
Camera *cam;
Mesh *me;

@ -0,0 +1,181 @@
/*
* ***** 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_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 (BaseLegacy *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 (BaseLegacy *base = scene->base.first; base; base = base->next) {
Base *ob_base = BKE_scene_layer_base_find(sl, base->object);
if ((base->flag_legacy & 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 (BaseLegacy *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));
}
}
}
}

@ -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"
@ -2626,10 +2627,34 @@ 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_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_layer_collections(wd, &lc->layer_collections);
}
}
static void write_scenes(WriteData *wd, ListBase *scebase)
{
Scene *sce;
Base *base;
BaseLegacy *base;
Editing *ed;
Sequence *seq;
MetaStack *ms;
@ -2641,6 +2666,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
ToolSettings *tos;
FreestyleModuleConfig *fmc;
FreestyleLineSet *fls;
SceneLayer *sl;
sce = scebase->first;
while (sce) {
@ -2656,7 +2682,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
/* direct data */
base = sce->base.first;
while (base) {
writestruct(wd, DATA, Base, 1, base);
writestruct(wd, DATA, BaseLegacy, 1, base);
base = base->next;
}
@ -2846,6 +2872,14 @@ 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, Base, &sl->object_bases);
write_layer_collections(wd, &sl->layer_collections);
}
sce = sce->id.next;
}
@ -3167,6 +3201,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;
}

@ -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"
@ -264,7 +265,7 @@ void DocumentImporter::finish()
for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
Object *ob = *it;
Base *base = BKE_scene_base_find(sce, ob);
BaseLegacy *base = BKE_scene_base_find(sce, ob);
if (base) {
BLI_remlink(&sce->base, base);
BKE_libblock_free_us(G.main, base->object);
@ -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);

@ -66,7 +66,7 @@ EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettin
bool EffectsExporter::hasEffects(Scene *sce)
{
Base *base = (Base *)sce->base.first;
BaseLegacy *base = (BaseLegacy *)sce->base.first;
while (base) {
Object *ob = base->object;

@ -338,7 +338,7 @@ void DepsgraphNodeBuilder::begin_build(Main *bmain) {
}
void DepsgraphNodeBuilder::build_group(Scene *scene,
Base *base,
BaseLegacy *base,
Group *group)
{
ID *group_id = &group->id;
@ -387,7 +387,7 @@ SubgraphDepsNode *DepsgraphNodeBuilder::build_subgraph(Group *group)
return subgraph_node;
}
void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
void DepsgraphNodeBuilder::build_object(Scene *scene, BaseLegacy *base, Object *ob)
{
const bool has_object = (ob->id.tag & LIB_TAG_DOIT);
IDDepsNode *id_node = (has_object)

@ -32,7 +32,10 @@
#include "intern/depsgraph_types.h"
struct Base;
/* XXX: Temporary solution to get proper Baselegacy. */
#include "DNA_scene_types.h"
struct BaseLegacy;
struct CacheFile;
struct bGPdata;
struct ListBase;
@ -126,8 +129,8 @@ struct DepsgraphNodeBuilder {
void build_scene(Main *bmain, Scene *scene);
SubgraphDepsNode *build_subgraph(Group *group);
void build_group(Scene *scene, Base *base, Group *group);
void build_object(Scene *scene, Base *base, Object *ob);
void build_group(Scene *scene, BaseLegacy *base, Group *group);
void build_object(Scene *scene, BaseLegacy *base, Object *ob);
void build_object_transform(Scene *scene, Object *ob);
void build_object_constraints(Scene *scene, Object *ob);
void build_pose_constraints(Object *ob, bPoseChannel *pchan);

@ -79,7 +79,7 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene)
}
/* scene objects */
LINKLIST_FOREACH (Base *, base, &scene->base) {
LINKLIST_FOREACH (BaseLegacy *, base, &scene->base) {
Object *ob = base->object;
/* object itself */

@ -45,7 +45,7 @@
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_operation.h"
struct Base;
struct BaseLegacy;
struct bGPdata;
struct CacheFile;
struct ListBase;

@ -74,7 +74,7 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene)
}
/* scene objects */
LINKLIST_FOREACH (Base *, base, &scene->base) {
LINKLIST_FOREACH (BaseLegacy *, base, &scene->base) {
Object *ob = base->object;
/* object itself */

@ -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)

@ -631,7 +631,7 @@ static bAnimChannelType ACF_SCENE =
static int acf_object_icon(bAnimListElem *ale)
{
Base *base = (Base *)ale->data;
BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
/* icon depends on object-type */
@ -666,7 +666,7 @@ static int acf_object_icon(bAnimListElem *ale)
/* name for object */
static void acf_object_name(bAnimListElem *ale, char *name)
{
Base *base = (Base *)ale->data;
BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
/* just copy the name... */
@ -686,7 +686,7 @@ static bool acf_object_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRN
/* check if some setting exists for this channel */
static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
Base *base = (Base *)ale->data;
BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
switch (setting) {
@ -743,7 +743,7 @@ static int acf_object_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
/* get pointer to the setting */
static void *acf_object_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Base *base = (Base *)ale->data;
BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
/* clear extra return data first */

@ -57,6 +57,7 @@
#include "BKE_context.h"
#include "BKE_mask.h"
#include "BKE_global.h"
#include "BKE_scene.h"
#include "UI_view2d.h"
@ -2682,31 +2683,31 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
{
bDopeSheet *ads = (bDopeSheet *)ac->data;
Scene *sce = (Scene *)ads->source;
Base *base = (Base *)ale->data;
BaseLegacy *base = (BaseLegacy *)ale->data;
Object *ob = base->object;
AnimData *adt = ob->adt;
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
base->flag ^= SELECT;
ob->flag = base->flag;
base->flag_legacy ^= SELECT;
BKE_scene_base_flag_sync_from_base(base);
if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
Base *b;
BaseLegacy *b;
/* deselect all */
/* 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;
b->flag_legacy &= ~SELECT;
BKE_scene_base_flag_sync_from_base(b);
if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
}
/* select object now */
base->flag |= SELECT;
base->flag_legacy |= SELECT;
ob->flag |= SELECT;
if (adt) adt->flag |= ADT_UI_SELECTED;
}

@ -601,7 +601,7 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
}
case ANIMTYPE_OBJECT:
{
Base *base = (Base *)data;
BaseLegacy *base = (BaseLegacy *)data;
Object *ob = base->object;
ale->flag = ob->flag;
@ -1683,7 +1683,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
if (ads->filterflag & ADS_FILTER_GP_3DONLY) {
Scene *scene = (Scene *)ads->source;
Base *base;
BaseLegacy *base;
/* Active scene's GPencil block first - No parent item needed... */
if (scene->gpd) {
@ -1714,7 +1714,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
}
/* check selection and object type filters */
if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == scene->basact)*/) ) {
if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag_legacy & SELECT) /*|| (base == scene->basact)*/) ) {
/* only selected should be shown */
continue;
}
@ -2573,7 +2573,7 @@ static size_t animdata_filter_ds_obanim(bAnimContext *ac, ListBase *anim_data, b
}
/* get animation channels from object2 */
static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, BaseLegacy *base, int filter_mode)
{
ListBase tmp_data = {NULL, NULL};
Object *ob = base->object;
@ -2629,7 +2629,7 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
/* check if filtering by selection */
// XXX: double-check on this - most of the time, a lot of tools need to filter out these channels!
if (ANIMCHANNEL_SELOK((base->flag & SELECT))) {
if (ANIMCHANNEL_SELOK((base->flag_legacy & SELECT))) {
/* check if filtering by active status */
if (ANIMCHANNEL_ACTIVEOK(ob)) {
ANIMCHANNEL_NEW_CHANNEL(base, ANIMTYPE_OBJECT, ob);
@ -2853,7 +2853,7 @@ static size_t animdata_filter_dopesheet_movieclips(bAnimContext *ac, ListBase *a
}
/* Helper for animdata_filter_dopesheet() - For checking if an object should be included or not */
static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base, int filter_mode)
static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, BaseLegacy *base, int filter_mode)
{
Object *ob = base->object;
@ -2906,7 +2906,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base
}
/* check selection and object type filters */
if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/)) {
if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag_legacy & SELECT) /*|| (base == sce->basact)*/)) {
/* only selected should be shown */
return false;
}
@ -2927,28 +2927,28 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base
/* Helper for animdata_filter_ds_sorted_bases() - Comparison callback for two Base pointers... */
static int ds_base_sorting_cmp(const void *base1_ptr, const void *base2_ptr)
{
const Base *b1 = *((const Base **)base1_ptr);
const Base *b2 = *((const Base **)base2_ptr);
const BaseLegacy *b1 = *((const BaseLegacy **)base1_ptr);
const BaseLegacy *b2 = *((const BaseLegacy **)base2_ptr);
return strcmp(b1->object->id.name + 2, b2->object->id.name + 2);
}
/* Get a sorted list of all the bases - for inclusion in dopesheet (when drawing channels) */
static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, Scene *scene, int filter_mode, size_t *r_usable_bases)
static BaseLegacy **animdata_filter_ds_sorted_bases(bDopeSheet *ads, Scene *scene, int filter_mode, size_t *r_usable_bases)
{
/* Create an array with space for all the bases, but only containing the usable ones */
size_t tot_bases = BLI_listbase_count(&scene->base);
size_t num_bases = 0;
Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases");
for (Base *base = scene->base.first; base; base = base->next) {
BaseLegacy **sorted_bases = MEM_mallocN(sizeof(BaseLegacy *) * tot_bases, "Dopesheet Usable Sorted Bases");
for (BaseLegacy *base = scene->base.first; base; base = base->next) {
if (animdata_filter_base_is_ok(ads, scene, base, filter_mode)) {
sorted_bases[num_bases++] = base;
}
}
/* Sort this list of pointers (based on the names) */
qsort(sorted_bases, num_bases, sizeof(Base *), ds_base_sorting_cmp);
qsort(sorted_bases, num_bases, sizeof(BaseLegacy *), ds_base_sorting_cmp);
/* Return list of sorted bases */
*r_usable_bases = num_bases;
@ -3002,7 +3002,7 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
{
/* Filter list of bases (i.e. objects), sort them, then add their contents normally... */
// TODO: Cache the old sorted order - if the set of bases hasn't changed, don't re-sort...
Base **sorted_bases;
BaseLegacy **sorted_bases;
size_t num_bases;
sorted_bases = animdata_filter_ds_sorted_bases(ads, scene, filter_mode, &num_bases);
@ -3022,7 +3022,7 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
/* Filter and add contents of each base (i.e. object) without them sorting first
* NOTE: This saves performance in cases where order doesn't matter
*/
for (Base *base = scene->base.first; base; base = base->next) {
for (BaseLegacy *base = scene->base.first; base; base = base->next) {
if (animdata_filter_base_is_ok(ads, scene, base, filter_mode)) {
/* since we're still here, this object should be usable */
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);

@ -1124,7 +1124,7 @@ static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool
if (camera) {
Scene *scene = CTX_data_scene(C);
Base *base;
BaseLegacy *base;
TimeMarker *marker;
int sel = 0;

@ -938,7 +938,7 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *bl
int filter;
bAnimListElem dummychan = {NULL};
Base dummybase = {NULL};
BaseLegacy dummybase = {NULL};
if (ob == NULL)
return;

@ -193,7 +193,7 @@ static short ob_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, Object *o
int ret = 0;
bAnimListElem dummychan = {NULL};
Base dummybase = {NULL};
BaseLegacy dummybase = {NULL};
if (ob == NULL)
return 0;

@ -37,7 +37,7 @@ struct wmOperatorType;
struct bContext;
struct Scene;
struct Object;
struct Base;
struct BaseLegacy;
struct bAction;
struct bPoseChannel;
@ -248,7 +248,7 @@ void armature_select_mirrored(struct bArmature *arm);
void armature_tag_unselect(struct bArmature *arm);
void *get_nearest_bone(struct bContext *C, short findunsel, int x, int y);
void *get_bone_from_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer, short hits, short findunsel, bool do_nearest);
void *get_bone_from_selectbuffer(struct Scene *scene, struct BaseLegacy *base, unsigned int *buffer, short hits, short findunsel, bool do_nearest);
int bone_looper(struct Object *ob, struct Bone *bone, void *data,
int (*bone_func)(struct Object *, struct Bone *, void *));

@ -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"
@ -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,6 +580,7 @@ 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;
@ -602,14 +604,18 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
/* TODO: use context iterators for this? */
CTX_DATA_BEGIN(C, Base *, 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);

@ -74,7 +74,7 @@ Bone *get_indexed_bone(Object *ob, int index)
/* See if there are any selected bones in this buffer */
/* only bones from base are checked on */
void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short findunsel, bool do_nearest)
void *get_bone_from_selectbuffer(Scene *scene, BaseLegacy *base, unsigned int *buffer, short hits, short findunsel, bool do_nearest)
{
Object *obedit = scene->obedit; // XXX get from context
Bone *bone;

@ -142,7 +142,7 @@ void BIF_makeListTemplates(const bContext *C)
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
Base *base;
BaseLegacy *base;
int index = 0;
if (TEMPLATES_HASH != NULL) {

@ -132,7 +132,7 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
/* called from editview.c, for mode-less pose selection */
/* assumes scene obact and basact is still on old situation */
int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits,
int ED_do_pose_selectbuffer(Scene *scene, BaseLegacy *base, unsigned int *buffer, short hits,
bool extend, bool deselect, bool toggle, bool do_nearest)
{
Object *ob = base->object;

@ -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,6 +1271,7 @@ 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;
Curve *oldcu, *newcu;
@ -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;
@ -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);
}
}
}

@ -420,6 +420,7 @@ 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;
@ -429,8 +430,8 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
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);

@ -1128,7 +1128,7 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
Object *ob;
Curve *cu;
Nurb *nu = NULL;
Base *base_orig = BASACT, *base_new = NULL;
BaseLegacy *base_orig = BASACT, *base_new = NULL;
float minmax_weights[2] = {1.0f, 0.0f};
/* camera framing */
@ -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_legacy |= SELECT;
BKE_scene_base_flag_sync_from_base(base_new);
}
/* --- */

@ -204,7 +204,7 @@ bGPdata *ED_gpencil_data_get_active(const bContext *C)
// XXX: this should be removed... We really shouldn't duplicate logic like this!
bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d)
{
Base *base = scene->basact;
BaseLegacy *base = scene->basact;
bGPdata *gpd = NULL;
/* We have to make sure active object is actually visible and selected, else we must use default scene gpd,
* to be consistent with ED_gpencil_data_get_active's behavior.

@ -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 */

@ -35,7 +35,7 @@ extern "C" {
#endif
struct bArmature;
struct Base;
struct BaseLegacy;
struct bContext;
struct Bone;
struct bPoseChannel;
@ -44,6 +44,7 @@ struct ListBase;
struct MeshDeformModifierData;
struct DerivedMesh;
struct Object;
struct Base;
struct ReportList;
struct Scene;
struct ViewContext;
@ -130,7 +131,7 @@ void ED_armature_ebone_listbase_temp_clear(struct ListBase *lb);
void ED_armature_deselect_all(struct Object *obedit);
void ED_armature_deselect_all_visible(struct Object *obedit);
int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer,
int ED_do_pose_selectbuffer(struct Scene *scene, struct BaseLegacy *base, unsigned int *buffer,
short hits, bool extend, bool deselect, bool toggle, bool do_nearest);
bool ED_armature_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
int join_armature_exec(struct bContext *C, struct wmOperator *op);

@ -35,14 +35,16 @@
extern "C" {
#endif
struct Base;
struct BaseLegacy;
struct EnumPropertyItem;
struct ID;
struct Main;
struct ModifierData;
struct Object;
struct Base;
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);
@ -98,14 +100,20 @@ void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMa
const bool do_connected);
/* send your own notifier for select! */
void ED_base_object_select(struct Base *base, short mode);
void ED_base_object_select(struct BaseLegacy *base, short mode);
/* includes notifier */
void ED_base_object_activate(struct bContext *C, struct Base *base);
void ED_base_object_activate(struct bContext *C, struct BaseLegacy *base);
void ED_base_object_free_and_unlink(struct Main *bmain, struct Scene *scene, struct Base *base);
void ED_object_base_select(struct Base *base, short mode);
void ED_object_base_activate(struct bContext *C, struct Base *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 BaseLegacy *base, struct Object *ob);
void ED_base_object_sync_from_object(struct BaseLegacy *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 Base *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, struct Base *base, int dupflag);
void ED_object_parent(struct Object *ob, struct Object *parent, const int type, const char *substr);
@ -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);

@ -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);

@ -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 */

@ -109,7 +109,7 @@ enum TfmMode {
bool calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
struct TransInfo;
struct Base;
struct BaseLegacy;
struct Scene;
struct Object;
struct wmOperator;

@ -37,7 +37,7 @@ struct BMEdge;
struct BMFace;
struct BMVert;
struct BPoint;
struct Base;
struct BaseLegacy;
struct BezTriple;
struct BoundBox;
struct EditBone;
@ -187,7 +187,7 @@ void pose_foreachScreenBone(
void ED_view3d_project_float_v2_m4(const struct ARegion *ar, const float co[3], float r_co[2], float mat[4][4]);
void ED_view3d_project_float_v3_m4(const struct ARegion *ar, const float co[3], float r_co[3], float mat[4][4]);
eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct Base *base);
eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct BaseLegacy *base);
/* *** short *** */
eV3DProjStatus ED_view3d_project_short_ex(const struct ARegion *ar, float perspmat[4][4], const bool is_local,
@ -353,7 +353,7 @@ struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
int alpha_mode, int samples, bool full_samples, const char *viewname,
struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
struct BaseLegacy *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);
void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]);
bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);

@ -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 */

@ -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__ */

@ -597,7 +597,7 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int
const int mval[2] = {
mx - ar->winrct.xmin,
my - ar->winrct.ymin};
Base *base;
BaseLegacy *base;
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);

@ -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)

@ -1576,7 +1576,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)) {

@ -167,6 +167,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;
@ -1208,6 +1211,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)
@ -2859,7 +2867,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)

@ -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,7 +3011,7 @@ enum {
MESH_SEPARATE_LOOSE = 2,
};
static Base *mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
static Base *mesh_separate_tagged(Main *bmain, Scene *scene, SceneLayer *sl, Base *base_old, BMesh *bm_old)
{
Base *base_new;
Object *obedit = base_old->object;
@ -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, Base *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,7 +3165,7 @@ 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, Base *base_old, BMesh *bm_old)
{
BMFace *f_cmp, *f;
BMIter iter;
@ -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, Base *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,6 +3280,7 @@ 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;
@ -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);
@ -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);

@ -551,7 +551,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
Base *base;
BaseLegacy *base;
Image *ima = NULL;
Mesh *me;
Object *obedit;

@ -326,7 +326,7 @@ static bool buildNavMesh(const RecastData *recastParams, int nverts, float *vert
}
static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh,
Base *base, unsigned int lay)
BaseLegacy *base, unsigned int lay)
{
float co[3], rot[3];
BMEditMesh *em;
@ -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;
BaseLegacy *navmeshBase = NULL;
CTX_DATA_BEGIN (C, Base *, 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;
}
}

@ -526,7 +526,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);
}
}
}

@ -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"
@ -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) {
@ -830,7 +832,7 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
{
Scene *scene = CTX_data_scene(C);
Base *base = NULL;
BaseLegacy *base = NULL;
Image *ima = NULL;
Object *ob = NULL;
@ -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);
}
}
}
@ -1329,6 +1319,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
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;
@ -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);
@ -1589,7 +1577,7 @@ static int convert_poll(bContext *C)
}
/* Helper for convert_exec */
static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object *ob)
static Base *duplibase_for_convert(Main *bmain, Scene *scene, SceneLayer *sl, Base *base, Object *ob)
{
Object *obn;
Base *basen;
@ -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,6 +1600,7 @@ static int 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);
Base *basen = NULL, *basact = NULL;
Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C);
DerivedMesh *dm;
@ -1631,7 +1615,7 @@ static int convert_exec(bContext *C, wmOperator *op)
/* don't forget multiple users! */
{
Base *base;
BaseLegacy *base;
for (base = scene->base.first; base; base = base->next) {
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 Base *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;
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)
Base *ED_object_add_duplicate(Main *bmain, Scene *scene, SceneLayer *sl, Base *base, int dupflag)
{
Base *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,6 +2220,7 @@ 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;
@ -2248,19 +2228,19 @@ static int duplicate_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
Base *basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
Base *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);
Base *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;

@ -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);
Base *base = BASACT, *newbase = NULL;
SceneLayer *sl = CTX_data_scene_layer(C);
BaseLegacy *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;
@ -1709,7 +1710,7 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
/* restore, BKE_object_add sets active */
BASACT = base;
base->flag |= SELECT;
base->flag_legacy |= SELECT;
/* make our new target the new object */
*tar_ob = obt;

@ -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))
@ -698,7 +506,7 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
{
//XXX no longer used - to be removed - replaced by game_properties_copy_exec
bProperty *prop;
Base *base;
BaseLegacy *base;
int nr, tot = 0;
char *str;
@ -758,7 +566,7 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob)
{
//XXX no longer used - to be removed - replaced by logicbricks_copy_exec
Base *base;
BaseLegacy *base;
for (base = FIRSTBASE; base; base = base->next) {
if (base->object != ob) {
@ -844,7 +652,7 @@ static void copy_texture_space(Object *to, Object *ob)
static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
{
Object *ob;
Base *base;
BaseLegacy *base;
Curve *cu, *cu1;
Nurb *nu;
bool do_depgraph_update = false;
@ -1512,7 +1320,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d)
{
/* all selected objects with an image map: scale in image aspect */
Base *base;
BaseLegacy *base;
Object *ob;
Material *ma;
Tex *tex;

@ -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;
@ -151,7 +150,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
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;
@ -221,7 +220,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
/* Remove groups from selected objects */
CTX_DATA_BEGIN (C, Base *, 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)
{
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;
@ -315,7 +312,7 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
/* now remove all selected objects from the group */
CTX_DATA_BEGIN (C, Base *, 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 */
@ -367,7 +363,7 @@ static int group_create_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, 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);
@ -560,8 +553,10 @@ static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select o
CTX_DATA_BEGIN (C, Base *, 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;

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