2003-04-26 18:01:01 +00:00
|
|
|
/*
|
2002-10-12 11:37:38 +00:00
|
|
|
* 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
|
Orange branch feature; Material Layering
(WIP, don't bugs for this in tracker yet please!)
- New Panel "Layers" in Material buttons, allows to add unlimited amount
of materials on top of each other.
- Every Layer is actually just another Material, which gets rendered/shaded
(including texture), and then added on top of previous layer with an
operation like Mix, Add, Mult, etc.
- Layers render fully independent, so bumpmaps are not passed on to next
layers.
- Per Layer you can set if it influences Diffuse, Specular or Alpha
- If a Material returns alpha (like from texture), the alpha value is
used for adding the layers too.
- New texture "Map To" channel allows to have a texture work on a Layer
- Each layer, including basis Material, can be turned on/off individually
Notes:
- at this moment, the full shading pass happens for each layer, including
shadow, AO and raytraced mirror or transparency...
- I had to remove old hacks from preview render, which corrected reflected
normals for preview texturing.
- still needs loadsa testing!
2005-12-04 14:32:21 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
|
* 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup blenloader
|
2011-02-27 20:35:41 +00:00
|
|
|
*/
|
|
|
|
|
|
2005-07-27 21:31:44 +00:00
|
|
|
#include "zlib.h"
|
|
|
|
|
|
2008-09-22 15:59:50 +00:00
|
|
|
#include <limits.h>
|
2019-04-17 06:17:24 +02:00
|
|
|
#include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
|
|
|
|
|
#include <stdlib.h> // for getenv atoi
|
|
|
|
|
#include <stddef.h> // for offsetof
|
|
|
|
|
#include <fcntl.h> // for open
|
|
|
|
|
#include <string.h> // for strrchr strncmp strstr
|
|
|
|
|
#include <math.h> // for fabs
|
|
|
|
|
#include <stdarg.h> /* for va_start/end */
|
|
|
|
|
#include <time.h> /* for gmtime */
|
|
|
|
|
#include <ctype.h> /* for isdigit */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2013-02-22 13:35:32 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2004-06-23 18:22:51 +00:00
|
|
|
#ifndef WIN32
|
2019-04-17 06:17:24 +02:00
|
|
|
# include <unistd.h> // for read close
|
2002-10-12 11:37:38 +00:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
# include <io.h> // for open close read
|
2012-04-15 07:54:07 +00:00
|
|
|
# include "winsock2.h"
|
|
|
|
|
# include "BLI_winstuff.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#endif
|
|
|
|
|
|
2011-12-04 06:05:48 +00:00
|
|
|
/* allow readfile to use deprecated functionality */
|
|
|
|
|
#define DNA_DEPRECATED_ALLOW
|
|
|
|
|
|
2009-01-18 10:41:45 +00:00
|
|
|
#include "DNA_anim_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_armature_types.h"
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
#include "DNA_brush_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_camera_types.h"
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
#include "DNA_cachefile_types.h"
|
2008-01-29 21:01:12 +00:00
|
|
|
#include "DNA_cloth_types.h"
|
2018-08-29 15:32:50 +02:00
|
|
|
#include "DNA_collection_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_constraint_types.h"
|
2011-05-24 07:08:58 +00:00
|
|
|
#include "DNA_dynamicpaint_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_effect_types.h"
|
|
|
|
|
#include "DNA_fileglobal_types.h"
|
2008-10-31 23:50:02 +00:00
|
|
|
#include "DNA_genfile.h"
|
2008-07-22 09:53:25 +00:00
|
|
|
#include "DNA_gpencil_types.h"
|
2018-07-31 10:22:19 +02:00
|
|
|
#include "DNA_gpencil_modifier_types.h"
|
|
|
|
|
#include "DNA_shader_fx_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_ipo_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_key_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_lattice_types.h"
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
#include "DNA_layer_types.h"
|
2019-02-27 12:34:56 +11:00
|
|
|
#include "DNA_light_types.h"
|
2013-03-23 03:00:37 +00:00
|
|
|
#include "DNA_linestyle_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_meta_types.h"
|
|
|
|
|
#include "DNA_material_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_mesh_types.h"
|
2004-03-20 22:55:42 +00:00
|
|
|
#include "DNA_meshdata_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_nla_types.h"
|
Christmas coding work!
********* Node editor work:
- To enable Nodes for Materials, you have to set the "Use Nodes"
button, in the new Material buttons "Nodes" Panel or in header
of the Node editor. Doing this will disable Material-Layers.
- Nodes now execute materials ("shaders"), but still only using the
previewrender code.
- Nodes have (optional) previews for rendered images.
- Node headers allow to hide buttons and/or preview image
- Nodes can be dragged larger/smaller (right-bottom corner)
- Nodes can be hidden (minimized) with hotkey H
- CTRL+click on an Input Socket gives a popup with default values.
- Changing Material/Texture or Mix node will adjust Node title.
- Click-drag outside of a Node changes cursor to "Knife' and allows to
draw a rect where to cut Links.
- Added new node types RGBtoBW, Texture, In/Output, ColorRamp
- Material Nodes have options to ouput diffuse or specular, or to use
a negative normal. The input socket 'Normal' will force the material
to use that normal, otherwise it uses the normal from the Material
that has the node tree.
- When drawing a link between two not-matching sockets, Blender inserts
a converting node (now only for value/rgb combos)
- When drawing a link to an input socket that's already in use, the
old link will either disappear or flip to another unused socket.
- A click on a Material Node will activate it, and show all its settings
in the Material Buttons. Active Material Nodes draw the material icon
in red.
- A click on any node will show its options in the Node Panel in the
Material buttons.
- Multiple Output Nodes can be used, to sample contents of a tree, but
only one Output is the real one, which is indicated in a different
color and red material icon.
- Added ThemeColors for node types
- ALT+C will convert existing Material-Layers to Node... this currently
only adds the material/mix nodes and connects them. Dunno if this is
worth a lot of coding work to make perfect?
- Press C to call another "Solve order", which will show all possible
cyclic conflicts (if there are).
- Technical: nodes now use "Type" structs which define the
structure of nodes and in/output sockets. The Type structs store all
fixed info, callbacks, and allow to reconstruct saved Nodes to match
what is required by Blender.
- Defining (new) nodes now is as simple as filling in a fixed
Type struct, plus code some callbacks. A doc will be made!
- Node preview images are by default float
********* Icon drawing:
- Cleanup of how old icons were implemented in new system, making
them 16x16 too, correctly centered *and* scaled.
- Made drawing Icons use float coordinates
- Moved BIF_calcpreview_image() into interface_icons.c, renamed it
icon_from_image(). Removed a lot of unneeded Imbuf magic here! :)
- Skipped scaling and imbuf copying when icons are OK size
********* Preview render:
- Huge cleanup of code....
- renaming BIF_xxx calls that only were used internally
- BIF_previewrender() now accepts an argument for rendering method,
so it supports icons, buttonwindow previewrender and node editor
- Only a single BIF_preview_changed() call now exists, supporting all
signals as needed for buttos and node editor
********* More stuff:
- glutil.c, glaDrawPixelsSafe() and glaDrawPixelsTex() now accept format
argument for GL_FLOAT rects
- Made the ColorBand become a built-in button for interface.c
Was a load of cleanup work in buttons_shading.c...
- removed a load of unneeded glBlendFunc() calls
- Fixed bug in calculating text length for buttons (ancient!)
2005-12-28 15:42:51 +00:00
|
|
|
#include "DNA_node_types.h"
|
2018-02-07 11:14:08 +11:00
|
|
|
#include "DNA_object_fluidsim_types.h"
|
2012-04-30 08:24:44 +00:00
|
|
|
#include "DNA_object_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_packedFile_types.h"
|
2016-12-28 17:30:58 +01:00
|
|
|
#include "DNA_particle_types.h"
|
2017-06-12 20:59:54 +10:00
|
|
|
#include "DNA_lightprobe_types.h"
|
2013-01-23 05:56:22 +00:00
|
|
|
#include "DNA_rigidbody_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_text_types.h"
|
|
|
|
|
#include "DNA_view3d_types.h"
|
|
|
|
|
#include "DNA_screen_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_sdna_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
#include "DNA_sequence_types.h"
|
2009-07-30 15:00:26 +00:00
|
|
|
#include "DNA_smoke_types.h"
|
2011-08-01 11:44:20 +00:00
|
|
|
#include "DNA_speaker_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_sound_types.h"
|
|
|
|
|
#include "DNA_space_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_vfont_types.h"
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
#include "DNA_workspace_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_world_types.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "DNA_movieclip_types.h"
|
2012-06-04 16:42:58 +00:00
|
|
|
#include "DNA_mask_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
#include "RNA_access.h"
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
2010-08-16 05:46:10 +00:00
|
|
|
|
2012-09-03 07:37:38 +00:00
|
|
|
#include "BLI_endian_switch.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BLI_blenlib.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2013-04-24 17:31:09 +00:00
|
|
|
#include "BLI_threads.h"
|
2013-08-03 11:35:09 +00:00
|
|
|
#include "BLI_mempool.h"
|
2018-12-13 15:29:54 +01:00
|
|
|
#include "BLI_ghash.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2015-08-16 17:32:01 +10:00
|
|
|
#include "BLT_translation.h"
|
2012-10-19 16:43:10 +00:00
|
|
|
|
2015-05-12 13:13:36 +05:00
|
|
|
#include "BKE_action.h"
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
#include "BKE_armature.h"
|
2009-02-22 19:31:25 +00:00
|
|
|
#include "BKE_brush.h"
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
#include "BKE_cachefile.h"
|
2014-09-01 17:46:17 +02:00
|
|
|
#include "BKE_cloth.h"
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#include "BKE_collection.h"
|
2018-11-07 18:00:24 +01:00
|
|
|
#include "BKE_colortools.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_constraint.h"
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
#include "BKE_curve.h"
|
2011-12-04 17:24:34 +00:00
|
|
|
#include "BKE_effect.h"
|
2009-01-18 10:41:45 +00:00
|
|
|
#include "BKE_fcurve.h"
|
2019-04-17 06:17:24 +02:00
|
|
|
#include "BKE_global.h" // for G
|
2018-07-31 10:22:19 +02:00
|
|
|
#include "BKE_gpencil.h"
|
|
|
|
|
#include "BKE_gpencil_modifier.h"
|
2018-11-07 18:00:24 +01:00
|
|
|
#include "BKE_idcode.h"
|
|
|
|
|
#include "BKE_idprop.h"
|
2017-02-17 11:02:25 +01:00
|
|
|
#include "BKE_layer.h"
|
2018-11-07 18:00:24 +01:00
|
|
|
#include "BKE_library.h"
|
2016-06-07 16:07:13 +10:00
|
|
|
#include "BKE_library_idmap.h"
|
2017-11-29 15:05:03 +01:00
|
|
|
#include "BKE_library_override.h"
|
2015-10-08 14:21:11 +02:00
|
|
|
#include "BKE_library_query.h"
|
2019-04-17 06:17:24 +02:00
|
|
|
#include "BKE_main.h" // for Main
|
2018-11-07 18:00:24 +01:00
|
|
|
#include "BKE_material.h"
|
2019-04-17 06:17:24 +02:00
|
|
|
#include "BKE_mesh.h" // for ME_ defines (patching)
|
2018-06-05 15:59:53 +02:00
|
|
|
#include "BKE_mesh_runtime.h"
|
2005-07-20 04:14:21 +00:00
|
|
|
#include "BKE_modifier.h"
|
2009-01-06 18:59:03 +00:00
|
|
|
#include "BKE_multires.h"
|
2019-04-17 06:17:24 +02:00
|
|
|
#include "BKE_node.h" // for tree type defines
|
2004-09-13 06:57:24 +00:00
|
|
|
#include "BKE_object.h"
|
2018-07-06 12:40:09 +02:00
|
|
|
#include "BKE_ocean.h"
|
2018-11-07 18:00:24 +01:00
|
|
|
#include "BKE_outliner_treehash.h"
|
2009-08-28 21:47:11 +00:00
|
|
|
#include "BKE_paint.h"
|
2016-12-28 17:30:58 +01:00
|
|
|
#include "BKE_particle.h"
|
|
|
|
|
#include "BKE_pointcache.h"
|
2008-12-19 00:50:21 +00:00
|
|
|
#include "BKE_report.h"
|
2004-09-13 06:57:24 +00:00
|
|
|
#include "BKE_scene.h"
|
2009-12-19 22:40:45 +00:00
|
|
|
#include "BKE_screen.h"
|
2009-12-13 14:56:45 +00:00
|
|
|
#include "BKE_sequencer.h"
|
2018-07-31 10:22:19 +02:00
|
|
|
#include "BKE_shader_fx.h"
|
2009-08-09 21:16:39 +00:00
|
|
|
#include "BKE_sound.h"
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
#include "BKE_workspace.h"
|
2011-12-21 11:01:08 +00:00
|
|
|
|
2018-07-10 15:02:25 +02:00
|
|
|
#include "DRW_engine.h"
|
|
|
|
|
|
2017-04-06 16:13:57 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
|
|
|
|
|
2011-09-05 21:01:50 +00:00
|
|
|
#include "NOD_socket.h"
|
|
|
|
|
|
2019-01-25 17:31:32 +01:00
|
|
|
#include "BLO_blend_defs.h"
|
2019-01-25 17:42:43 +01:00
|
|
|
#include "BLO_blend_validate.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BLO_readfile.h"
|
2004-09-05 13:43:51 +00:00
|
|
|
#include "BLO_undofile.h"
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
|
2011-11-02 18:20:53 +00:00
|
|
|
#include "RE_engine.h"
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "readfile.h"
|
|
|
|
|
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
#include <errno.h>
|
|
|
|
|
|
2016-06-22 07:22:00 +10:00
|
|
|
/**
|
2012-06-30 22:49:33 +00:00
|
|
|
* READ
|
2016-06-22 07:22:00 +10:00
|
|
|
* ====
|
|
|
|
|
*
|
|
|
|
|
* - Existing Library (#Main) push or free
|
|
|
|
|
* - allocate new #Main
|
2012-06-30 22:49:33 +00:00
|
|
|
* - load file
|
2016-06-22 07:22:00 +10:00
|
|
|
* - read #SDNA
|
2012-06-30 22:49:33 +00:00
|
|
|
* - for each LibBlock
|
2016-06-22 07:22:00 +10:00
|
|
|
* - read LibBlock
|
|
|
|
|
* - if a Library
|
|
|
|
|
* - make a new #Main
|
|
|
|
|
* - attach ID's to it
|
|
|
|
|
* - else
|
|
|
|
|
* - read associated 'direct data'
|
|
|
|
|
* - link direct data (internal and to LibBlock)
|
|
|
|
|
* - read #FileGlobal
|
|
|
|
|
* - read #USER data, only when indicated (file is ``~/X.XX/startup.blend``)
|
2012-06-30 22:49:33 +00:00
|
|
|
* - free file
|
2016-06-22 07:22:00 +10:00
|
|
|
* - per Library (per #Main)
|
|
|
|
|
* - read file
|
|
|
|
|
* - read #SDNA
|
|
|
|
|
* - find LibBlocks and attach #ID's to #Main
|
|
|
|
|
* - if external LibBlock
|
|
|
|
|
* - search all #Main's
|
|
|
|
|
* - or it's already read,
|
|
|
|
|
* - or not read yet
|
|
|
|
|
* - or make new #Main
|
|
|
|
|
* - per LibBlock
|
|
|
|
|
* - read recursive
|
|
|
|
|
* - read associated direct data
|
|
|
|
|
* - link direct data (internal and to LibBlock)
|
|
|
|
|
* - free file
|
2012-06-30 22:49:33 +00:00
|
|
|
* - per Library with unread LibBlocks
|
2016-06-22 07:22:00 +10:00
|
|
|
* - read file
|
|
|
|
|
* - read #SDNA
|
|
|
|
|
* - per LibBlock
|
|
|
|
|
* - read recursive
|
|
|
|
|
* - read associated direct data
|
|
|
|
|
* - link direct data (internal and to LibBlock)
|
|
|
|
|
* - free file
|
|
|
|
|
* - join all #Main's
|
2012-06-30 22:49:33 +00:00
|
|
|
* - link all LibBlocks and indirect pointers to libblocks
|
2016-06-22 07:22:00 +10:00
|
|
|
* - initialize #FileGlobal and copy pointers to #Global
|
|
|
|
|
*
|
2019-06-12 09:04:10 +10:00
|
|
|
* \note Still a weak point is the new-address function, that doesn't solve reading from
|
2016-06-22 07:22:00 +10:00
|
|
|
* multiple files at the same time.
|
|
|
|
|
* (added remark: oh, i thought that was solved? will look at that... (ton).
|
2012-10-04 13:26:15 +00:00
|
|
|
*/
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-22 14:42:22 +11:00
|
|
|
/**
|
|
|
|
|
* Delay reading blocks we might not use (especially applies to library linking).
|
2019-02-25 08:54:10 +11:00
|
|
|
* which keeps large arrays in memory from data-blocks we may not even use.
|
|
|
|
|
*
|
|
|
|
|
* \note This is disabled when using compression,
|
|
|
|
|
* while zlib supports seek ist's unusably slow, see: T61880.
|
|
|
|
|
*/
|
|
|
|
|
#define USE_BHEAD_READ_ON_DEMAND
|
2019-02-22 14:42:22 +11:00
|
|
|
|
2015-03-11 00:33:44 +11:00
|
|
|
/* use GHash for BHead name-based lookups (speeds up linking) */
|
|
|
|
|
#define USE_GHASH_BHEAD
|
|
|
|
|
|
2016-06-07 16:07:13 +10:00
|
|
|
/* Use GHash for restoring pointers by name */
|
|
|
|
|
#define USE_GHASH_RESTORE_POINTER
|
|
|
|
|
|
2018-01-16 17:14:57 +01:00
|
|
|
/* Define this to have verbose debug prints. */
|
|
|
|
|
#define USE_DEBUG_PRINT
|
|
|
|
|
|
|
|
|
|
#ifdef USE_DEBUG_PRINT
|
|
|
|
|
# define DEBUG_PRINTF(...) printf(__VA_ARGS__)
|
|
|
|
|
#else
|
|
|
|
|
# define DEBUG_PRINTF(...)
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-03-09 19:45:59 +00:00
|
|
|
/* local prototypes */
|
2019-02-22 18:15:56 +11:00
|
|
|
static void read_libraries(FileData *basefd, ListBase *mainlist);
|
2010-12-03 17:05:21 +00:00
|
|
|
static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
|
2011-04-08 02:21:43 +00:00
|
|
|
static void direct_link_modifiers(FileData *fd, ListBase *lb);
|
2015-03-11 00:33:44 +11:00
|
|
|
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
|
|
|
|
|
static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
|
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
2017-12-01 11:24:21 -02:00
|
|
|
static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
2018-07-31 10:22:19 +02:00
|
|
|
static void direct_link_animdata(FileData *fd, AnimData *adt);
|
|
|
|
|
static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt);
|
2005-03-09 19:45:59 +00:00
|
|
|
|
2019-02-22 13:46:44 +11:00
|
|
|
typedef struct BHeadN {
|
2019-04-17 06:17:24 +02:00
|
|
|
struct BHeadN *next, *prev;
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
2019-04-17 06:17:24 +02:00
|
|
|
/** Use to read the data from the file directly into memory as needed. */
|
|
|
|
|
off64_t file_offset;
|
|
|
|
|
/** When set, the remainder of this allocation is the data, otherwise it needs to be read. */
|
|
|
|
|
bool has_data;
|
2019-02-22 14:42:22 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
struct BHead bhead;
|
2019-02-22 13:46:44 +11:00
|
|
|
} BHeadN;
|
|
|
|
|
|
|
|
|
|
#define BHEADN_FROM_BHEAD(bh) ((BHeadN *)POINTER_OFFSET(bh, -offsetof(BHeadN, bhead)))
|
|
|
|
|
|
2019-02-22 14:42:22 +11:00
|
|
|
/* We could change this in the future, for now it's simplest if only data is delayed
|
|
|
|
|
* because ID names are used in lookup tables. */
|
2019-04-17 06:17:24 +02:00
|
|
|
#define BHEAD_USE_READ_ON_DEMAND(bhead) ((bhead)->code == DATA)
|
2019-02-22 14:42:22 +11:00
|
|
|
|
2012-01-05 09:50:07 +00:00
|
|
|
/* this function ensures that reports are printed,
|
|
|
|
|
* in the case of libraray linking errors this is important!
|
|
|
|
|
*
|
|
|
|
|
* bit kludge but better then doubling up on prints,
|
2012-07-16 23:23:33 +00:00
|
|
|
* we could alternatively have a versions of a report function which forces printing - campbell
|
2012-01-05 09:50:07 +00:00
|
|
|
*/
|
2012-09-23 18:50:56 +00:00
|
|
|
|
2013-11-29 23:16:13 +06:00
|
|
|
void blo_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...)
|
2012-01-05 09:50:07 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
char fixed_buf[1024]; /* should be long enough */
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
va_list args;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
va_start(args, format);
|
|
|
|
|
vsnprintf(fixed_buf, sizeof(fixed_buf), format, args);
|
|
|
|
|
va_end(args);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fixed_buf[sizeof(fixed_buf) - 1] = '\0';
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_report(reports, type, fixed_buf);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (G.background == 0) {
|
|
|
|
|
printf("%s: %s\n", BKE_report_type_str(type), fixed_buf);
|
|
|
|
|
}
|
2012-01-05 09:50:07 +00:00
|
|
|
}
|
|
|
|
|
|
2014-10-19 12:49:01 +02:00
|
|
|
/* for reporting linking messages */
|
|
|
|
|
static const char *library_parent_filepath(Library *lib)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return lib->parent ? lib->parent->filepath : "<direct>";
|
2014-10-19 12:49:01 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name OldNewMap API
|
|
|
|
|
* \{ */
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
typedef struct OldNew {
|
2019-04-17 06:17:24 +02:00
|
|
|
const void *oldp;
|
|
|
|
|
void *newp;
|
|
|
|
|
/* `nr` is "user count" for data, and ID code for libdata. */
|
|
|
|
|
int nr;
|
2018-12-13 15:29:54 +01:00
|
|
|
} OldNew;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
typedef struct OldNewMap {
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Array that stores the actual entries. */
|
|
|
|
|
OldNew *entries;
|
|
|
|
|
int nentries;
|
|
|
|
|
/* Hashmap that stores indices into the `entries` array. */
|
|
|
|
|
int32_t *map;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
int capacity_exp;
|
2018-12-13 15:29:54 +01:00
|
|
|
} OldNewMap;
|
2005-12-15 18:42:02 +00:00
|
|
|
|
2019-05-27 07:54:56 -06:00
|
|
|
#define ENTRIES_CAPACITY(onm) (1ll << (onm)->capacity_exp)
|
|
|
|
|
#define MAP_CAPACITY(onm) (1ll << ((onm)->capacity_exp + 1))
|
2018-12-13 15:29:54 +01:00
|
|
|
#define SLOT_MASK(onm) (MAP_CAPACITY(onm) - 1)
|
|
|
|
|
#define DEFAULT_SIZE_EXP 6
|
|
|
|
|
#define PERTURB_SHIFT 5
|
|
|
|
|
|
|
|
|
|
/* based on the probing algorithm used in Python dicts. */
|
|
|
|
|
#define ITER_SLOTS(onm, KEY, SLOT_NAME, INDEX_NAME) \
|
2019-04-17 06:17:24 +02:00
|
|
|
uint32_t hash = BLI_ghashutil_ptrhash(KEY); \
|
|
|
|
|
uint32_t mask = SLOT_MASK(onm); \
|
|
|
|
|
uint perturb = hash; \
|
|
|
|
|
int SLOT_NAME = mask & hash; \
|
|
|
|
|
int INDEX_NAME = onm->map[SLOT_NAME]; \
|
|
|
|
|
for (;; SLOT_NAME = mask & ((5 * SLOT_NAME) + 1 + perturb), \
|
|
|
|
|
perturb >>= PERTURB_SHIFT, \
|
|
|
|
|
INDEX_NAME = onm->map[SLOT_NAME])
|
2018-12-13 15:29:54 +01:00
|
|
|
|
|
|
|
|
static void oldnewmap_insert_index_in_map(OldNewMap *onm, const void *ptr, int index)
|
|
|
|
|
{
|
2019-04-21 04:40:16 +10:00
|
|
|
ITER_SLOTS (onm, ptr, slot, stored_index) {
|
2019-04-17 06:17:24 +02:00
|
|
|
if (stored_index == -1) {
|
|
|
|
|
onm->map[slot] = index;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-12-13 15:29:54 +01:00
|
|
|
}
|
2005-12-15 18:42:02 +00:00
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
static void oldnewmap_insert_or_replace(OldNewMap *onm, OldNew entry)
|
2005-12-15 18:42:02 +00:00
|
|
|
{
|
2019-04-21 04:40:16 +10:00
|
|
|
ITER_SLOTS (onm, entry.oldp, slot, index) {
|
2019-04-17 06:17:24 +02:00
|
|
|
if (index == -1) {
|
|
|
|
|
onm->entries[onm->nentries] = entry;
|
|
|
|
|
onm->map[slot] = onm->nentries;
|
|
|
|
|
onm->nentries++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (onm->entries[index].oldp == entry.oldp) {
|
|
|
|
|
onm->entries[index] = entry;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-12-15 18:42:02 +00:00
|
|
|
}
|
|
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
static OldNew *oldnewmap_lookup_entry(const OldNewMap *onm, const void *addr)
|
2005-12-13 19:21:56 +00:00
|
|
|
{
|
2019-04-21 04:40:16 +10:00
|
|
|
ITER_SLOTS (onm, addr, slot, index) {
|
2019-04-17 06:17:24 +02:00
|
|
|
if (index >= 0) {
|
|
|
|
|
OldNew *entry = &onm->entries[index];
|
|
|
|
|
if (entry->oldp == addr) {
|
|
|
|
|
return entry;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
static void oldnewmap_clear_map(OldNewMap *onm)
|
2012-05-04 15:42:49 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
memset(onm->map, 0xFF, MAP_CAPACITY(onm) * sizeof(*onm->map));
|
2012-05-04 15:42:49 +00:00
|
|
|
}
|
|
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
static void oldnewmap_increase_size(OldNewMap *onm)
|
2015-08-18 11:22:07 +10:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
onm->capacity_exp++;
|
|
|
|
|
onm->entries = MEM_reallocN(onm->entries, sizeof(*onm->entries) * ENTRIES_CAPACITY(onm));
|
|
|
|
|
onm->map = MEM_reallocN(onm->map, sizeof(*onm->map) * MAP_CAPACITY(onm));
|
|
|
|
|
oldnewmap_clear_map(onm);
|
|
|
|
|
for (int i = 0; i < onm->nentries; i++) {
|
|
|
|
|
oldnewmap_insert_index_in_map(onm, onm->entries[i].oldp, i);
|
|
|
|
|
}
|
2015-08-18 11:22:07 +10:00
|
|
|
}
|
|
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
/* Public OldNewMap API */
|
|
|
|
|
|
|
|
|
|
static OldNewMap *oldnewmap_new(void)
|
2005-12-13 19:21:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
OldNewMap *onm = MEM_callocN(sizeof(*onm), "OldNewMap");
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
onm->capacity_exp = DEFAULT_SIZE_EXP;
|
|
|
|
|
onm->entries = MEM_malloc_arrayN(
|
|
|
|
|
ENTRIES_CAPACITY(onm), sizeof(*onm->entries), "OldNewMap.entries");
|
|
|
|
|
onm->map = MEM_malloc_arrayN(MAP_CAPACITY(onm), sizeof(*onm->map), "OldNewMap.map");
|
|
|
|
|
oldnewmap_clear_map(onm);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return onm;
|
2018-12-13 15:29:54 +01:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
static void oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr)
|
|
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (oldaddr == NULL || newaddr == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (UNLIKELY(onm->nentries == ENTRIES_CAPACITY(onm))) {
|
|
|
|
|
oldnewmap_increase_size(onm);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
OldNew entry;
|
|
|
|
|
entry.oldp = oldaddr;
|
|
|
|
|
entry.newp = newaddr;
|
|
|
|
|
entry.nr = nr;
|
|
|
|
|
oldnewmap_insert_or_replace(onm, entry);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
void blo_do_versions_oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr)
|
2005-12-13 19:21:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(onm, oldaddr, newaddr, nr);
|
2018-12-13 15:29:54 +01:00
|
|
|
}
|
2012-11-10 02:38:16 +00:00
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool increase_users)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
OldNew *entry = oldnewmap_lookup_entry(onm, addr);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (entry == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (increase_users) {
|
2019-04-17 06:17:24 +02:00
|
|
|
entry->nr++;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return entry->newp;
|
2018-12-13 15:29:54 +01:00
|
|
|
}
|
2012-11-10 02:38:16 +00:00
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
/* for libdata, OldNew.nr has ID code, no increment */
|
|
|
|
|
static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *lib)
|
|
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (addr == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ID *id = oldnewmap_lookup_and_inc(onm, addr, false);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (id == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (!lib || id->lib) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return id;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-17 17:06:07 +02:00
|
|
|
static void oldnewmap_free_unused(OldNewMap *onm)
|
2005-12-13 19:21:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int i = 0; i < onm->nentries; i++) {
|
|
|
|
|
OldNew *entry = &onm->entries[i];
|
|
|
|
|
if (entry->nr == 0) {
|
|
|
|
|
MEM_freeN(entry->newp);
|
|
|
|
|
entry->newp = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-17 17:06:07 +02:00
|
|
|
static void oldnewmap_clear(OldNewMap *onm)
|
2005-12-13 19:21:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
onm->capacity_exp = DEFAULT_SIZE_EXP;
|
|
|
|
|
oldnewmap_clear_map(onm);
|
|
|
|
|
onm->nentries = 0;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-17 17:06:07 +02:00
|
|
|
static void oldnewmap_free(OldNewMap *onm)
|
2005-12-13 19:21:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(onm->entries);
|
|
|
|
|
MEM_freeN(onm->map);
|
|
|
|
|
MEM_freeN(onm);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2018-12-13 15:29:54 +01:00
|
|
|
#undef ENTRIES_CAPACITY
|
|
|
|
|
#undef MAP_CAPACITY
|
|
|
|
|
#undef SLOT_MASK
|
|
|
|
|
#undef DEFAULT_SIZE_EXP
|
|
|
|
|
#undef PERTURB_SHIFT
|
|
|
|
|
#undef ITER_SLOTS
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Helper Functions
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void add_main_to_main(Main *mainvar, Main *from)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY];
|
|
|
|
|
int a;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
set_listbasepointers(mainvar, lbarray);
|
|
|
|
|
a = set_listbasepointers(from, fromarray);
|
|
|
|
|
while (a--) {
|
|
|
|
|
BLI_movelisttolist(lbarray[a], fromarray[a]);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void blo_join_main(ListBase *mainlist)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *tojoin, *mainl;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
mainl = mainlist->first;
|
|
|
|
|
while ((tojoin = mainl->next)) {
|
|
|
|
|
add_main_to_main(mainl, tojoin);
|
|
|
|
|
BLI_remlink(mainlist, tojoin);
|
|
|
|
|
BKE_main_free(tojoin);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2018-11-30 14:51:16 +11:00
|
|
|
static void split_libdata(ListBase *lb_src, Main **lib_main_array, const uint lib_main_array_len)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ID *id = lb_src->first, *idnext; id; id = idnext) {
|
|
|
|
|
idnext = id->next;
|
|
|
|
|
|
|
|
|
|
if (id->lib) {
|
|
|
|
|
if (((uint)id->lib->temp_index < lib_main_array_len) &&
|
|
|
|
|
/* this check should never fail, just incase 'id->lib' is a dangling pointer. */
|
|
|
|
|
(lib_main_array[id->lib->temp_index]->curlib == id->lib)) {
|
|
|
|
|
Main *mainvar = lib_main_array[id->lib->temp_index];
|
|
|
|
|
ListBase *lb_dst = which_libbase(mainvar, GS(id->name));
|
|
|
|
|
BLI_remlink(lb_src, id);
|
|
|
|
|
BLI_addtail(lb_dst, id);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
printf("%s: invalid library for '%s'\n", __func__, id->name);
|
|
|
|
|
BLI_assert(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2006-11-25 13:07:28 +00:00
|
|
|
void blo_split_main(ListBase *mainlist, Main *main)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
mainlist->first = mainlist->last = main;
|
|
|
|
|
main->next = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (BLI_listbase_is_empty(&main->libraries)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* (Library.temp_index -> Main), lookup table */
|
|
|
|
|
const uint lib_main_array_len = BLI_listbase_count(&main->libraries);
|
|
|
|
|
Main **lib_main_array = MEM_malloc_arrayN(lib_main_array_len, sizeof(*lib_main_array), __func__);
|
2016-06-07 01:54:59 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
int i = 0;
|
|
|
|
|
for (Library *lib = main->libraries.first; lib; lib = lib->id.next, i++) {
|
|
|
|
|
Main *libmain = BKE_main_new();
|
|
|
|
|
libmain->curlib = lib;
|
|
|
|
|
libmain->versionfile = lib->versionfile;
|
|
|
|
|
libmain->subversionfile = lib->subversionfile;
|
|
|
|
|
BLI_addtail(mainlist, libmain);
|
|
|
|
|
lib->temp_index = i;
|
|
|
|
|
lib_main_array[i] = libmain;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *lbarray[MAX_LIBARRAY];
|
|
|
|
|
i = set_listbasepointers(main, lbarray);
|
|
|
|
|
while (i--) {
|
|
|
|
|
ID *id = lbarray[i]->first;
|
|
|
|
|
if (id == NULL || GS(id->name) == ID_LI) {
|
2019-06-17 12:51:53 +10:00
|
|
|
/* No ID_LI data-lock should ever be linked anyway, but just in case, better be explicit. */
|
2019-04-22 01:10:29 +10:00
|
|
|
continue;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
split_libdata(lbarray[i], lib_main_array, lib_main_array_len);
|
|
|
|
|
}
|
2016-06-07 01:54:59 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(lib_main_array);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2007-11-30 15:12:31 +00:00
|
|
|
static void read_file_version(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead;
|
|
|
|
|
|
|
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
|
|
|
|
if (bhead->code == GLOB) {
|
|
|
|
|
FileGlobal *fg = read_struct(fd, bhead, "Global");
|
|
|
|
|
if (fg) {
|
|
|
|
|
main->subversionfile = fg->subversion;
|
|
|
|
|
main->minversionfile = fg->minversion;
|
|
|
|
|
main->minsubversionfile = fg->minsubversion;
|
|
|
|
|
MEM_freeN(fg);
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
else if (bhead->code == ENDB) {
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (main->curlib) {
|
|
|
|
|
main->curlib->versionfile = main->versionfile;
|
|
|
|
|
main->curlib->subversionfile = main->subversionfile;
|
|
|
|
|
}
|
2007-11-30 15:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-11 00:33:44 +11:00
|
|
|
#ifdef USE_GHASH_BHEAD
|
|
|
|
|
static void read_file_bhead_idname_map_create(FileData *fd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead;
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* dummy values */
|
|
|
|
|
bool is_link = false;
|
|
|
|
|
int code_prev = ENDB;
|
|
|
|
|
uint reserve = 0;
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
|
|
|
|
if (code_prev != bhead->code) {
|
|
|
|
|
code_prev = bhead->code;
|
|
|
|
|
is_link = BKE_idcode_is_valid(code_prev) ? BKE_idcode_is_linkable(code_prev) : false;
|
|
|
|
|
}
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (is_link) {
|
|
|
|
|
reserve += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_assert(fd->bhead_idname_hash == NULL);
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->bhead_idname_hash = BLI_ghash_str_new_ex(__func__, reserve);
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
|
|
|
|
if (code_prev != bhead->code) {
|
|
|
|
|
code_prev = bhead->code;
|
|
|
|
|
is_link = BKE_idcode_is_valid(code_prev) ? BKE_idcode_is_linkable(code_prev) : false;
|
|
|
|
|
}
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (is_link) {
|
|
|
|
|
BLI_ghash_insert(fd->bhead_idname_hash, (void *)blo_bhead_id_name(fd, bhead), bhead);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-11 00:33:44 +11:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2012-05-25 17:13:30 +00:00
|
|
|
static Main *blo_find_main(FileData *fd, const char *filepath, const char *relabase)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *mainlist = fd->mainlist;
|
|
|
|
|
Main *m;
|
|
|
|
|
Library *lib;
|
|
|
|
|
char name1[FILE_MAX];
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_strncpy(name1, filepath, sizeof(name1));
|
|
|
|
|
BLI_cleanup_path(relabase, name1);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
// printf("blo_find_main: relabase %s\n", relabase);
|
|
|
|
|
// printf("blo_find_main: original in %s\n", filepath);
|
|
|
|
|
// printf("blo_find_main: converted to %s\n", name1);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (m = mainlist->first; m; m = m->next) {
|
|
|
|
|
const char *libname = (m->curlib) ? m->curlib->filepath : m->name;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (BLI_path_cmp(name1, libname) == 0) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (G.debug & G_DEBUG) {
|
2019-04-17 06:17:24 +02:00
|
|
|
printf("blo_find_main: found library %s\n", libname);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
m = BKE_main_new();
|
|
|
|
|
BLI_addtail(mainlist, m);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-06-12 09:04:10 +10:00
|
|
|
/* Add library data-block itself to 'main' Main, since libraries are **never** linked data.
|
|
|
|
|
* Fixes bug where you could end with all ID_LI data-blocks having the same name... */
|
2019-04-17 06:17:24 +02:00
|
|
|
lib = BKE_libblock_alloc(mainlist->first, ID_LI, BLI_path_basename(filepath), 0);
|
|
|
|
|
lib->id.us = ID_FAKE_USERS(
|
|
|
|
|
lib); /* Important, consistency with main ID reading code from read_libblock(). */
|
|
|
|
|
BLI_strncpy(lib->name, filepath, sizeof(lib->name));
|
|
|
|
|
BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
m->curlib = lib;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
read_file_version(fd, m);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (G.debug & G_DEBUG) {
|
2019-04-17 06:17:24 +02:00
|
|
|
printf("blo_find_main: added new lib %s\n", filepath);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return m;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name File Parsing
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void switch_endian_bh4(BHead4 *bhead)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* the ID_.. codes */
|
2019-04-22 09:13:00 +10:00
|
|
|
if ((bhead->code & 0xFFFF) == 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
bhead->code >>= 16;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bhead->code != ENDB) {
|
|
|
|
|
BLI_endian_switch_int32(&bhead->len);
|
|
|
|
|
BLI_endian_switch_int32(&bhead->SDNAnr);
|
|
|
|
|
BLI_endian_switch_int32(&bhead->nr);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void switch_endian_bh8(BHead8 *bhead)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* the ID_.. codes */
|
2019-04-22 09:13:00 +10:00
|
|
|
if ((bhead->code & 0xFFFF) == 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
bhead->code >>= 16;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bhead->code != ENDB) {
|
|
|
|
|
BLI_endian_switch_int32(&bhead->len);
|
|
|
|
|
BLI_endian_switch_int32(&bhead->SDNAnr);
|
|
|
|
|
BLI_endian_switch_int32(&bhead->nr);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, int do_endian_swap)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead4 *bhead4 = (BHead4 *)bhead;
|
|
|
|
|
int64_t old;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bhead4->code = bhead8->code;
|
|
|
|
|
bhead4->len = bhead8->len;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bhead4->code != ENDB) {
|
|
|
|
|
/* perform a endian swap on 64bit pointers, otherwise the pointer might map to zero
|
|
|
|
|
* 0x0000000000000000000012345678 would become 0x12345678000000000000000000000000
|
|
|
|
|
*/
|
|
|
|
|
if (do_endian_swap) {
|
|
|
|
|
BLI_endian_switch_int64(&bhead8->old);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* this patch is to avoid a long long being read from not-eight aligned positions
|
|
|
|
|
* is necessary on any modern 64bit architecture) */
|
|
|
|
|
memcpy(&old, &bhead8->old, 8);
|
|
|
|
|
bhead4->old = (int)(old >> 3);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bhead4->SDNAnr = bhead8->SDNAnr;
|
|
|
|
|
bhead4->nr = bhead8->nr;
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void bh8_from_bh4(BHead *bhead, BHead4 *bhead4)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead8 *bhead8 = (BHead8 *)bhead;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bhead8->code = bhead4->code;
|
|
|
|
|
bhead8->len = bhead4->len;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bhead8->code != ENDB) {
|
|
|
|
|
bhead8->old = bhead4->old;
|
|
|
|
|
bhead8->SDNAnr = bhead4->SDNAnr;
|
|
|
|
|
bhead8->nr = bhead4->nr;
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static BHeadN *get_bhead(FileData *fd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHeadN *new_bhead = NULL;
|
|
|
|
|
int readsize;
|
|
|
|
|
|
|
|
|
|
if (fd) {
|
|
|
|
|
if (!fd->is_eof) {
|
|
|
|
|
/* initializing to zero isn't strictly needed but shuts valgrind up
|
|
|
|
|
* since uninitialized memory gets compared */
|
|
|
|
|
BHead8 bhead8 = {0};
|
|
|
|
|
BHead4 bhead4 = {0};
|
|
|
|
|
BHead bhead = {0};
|
|
|
|
|
|
|
|
|
|
/* First read the bhead structure.
|
|
|
|
|
* Depending on the platform the file was written on this can
|
|
|
|
|
* be a big or little endian BHead4 or BHead8 structure.
|
|
|
|
|
*
|
|
|
|
|
* As usual 'ENDB' (the last *partial* bhead of the file)
|
|
|
|
|
* needs some special handling. We don't want to EOF just yet.
|
|
|
|
|
*/
|
|
|
|
|
if (fd->flags & FD_FLAGS_FILE_POINTSIZE_IS_4) {
|
|
|
|
|
bhead4.code = DATA;
|
|
|
|
|
readsize = fd->read(fd, &bhead4, sizeof(bhead4));
|
|
|
|
|
|
|
|
|
|
if (readsize == sizeof(bhead4) || bhead4.code == ENDB) {
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
switch_endian_bh4(&bhead4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
|
|
|
|
|
bh8_from_bh4(&bhead, &bhead4);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* MIN2 is only to quiet '-Warray-bounds' compiler warning. */
|
|
|
|
|
BLI_assert(sizeof(bhead) == sizeof(bhead4));
|
|
|
|
|
memcpy(&bhead, &bhead4, MIN2(sizeof(bhead), sizeof(bhead4)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fd->is_eof = true;
|
|
|
|
|
bhead.len = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
bhead8.code = DATA;
|
|
|
|
|
readsize = fd->read(fd, &bhead8, sizeof(bhead8));
|
|
|
|
|
|
|
|
|
|
if (readsize == sizeof(bhead8) || bhead8.code == ENDB) {
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
switch_endian_bh8(&bhead8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
|
|
|
|
|
bh4_from_bh8(&bhead, &bhead8, (fd->flags & FD_FLAGS_SWITCH_ENDIAN));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* MIN2 is only to quiet '-Warray-bounds' compiler warning. */
|
|
|
|
|
BLI_assert(sizeof(bhead) == sizeof(bhead8));
|
|
|
|
|
memcpy(&bhead, &bhead8, MIN2(sizeof(bhead), sizeof(bhead8)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fd->is_eof = true;
|
|
|
|
|
bhead.len = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* make sure people are not trying to pass bad blend files */
|
|
|
|
|
if (bhead.len < 0) {
|
|
|
|
|
fd->is_eof = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* bhead now contains the (converted) bhead structure. Now read
|
|
|
|
|
* the associated data and put everything in a BHeadN (creative naming !)
|
|
|
|
|
*/
|
|
|
|
|
if (fd->is_eof) {
|
|
|
|
|
/* pass */
|
|
|
|
|
}
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
2019-04-17 06:17:24 +02:00
|
|
|
else if (fd->seek != NULL && BHEAD_USE_READ_ON_DEMAND(&bhead)) {
|
|
|
|
|
/* Delay reading bhead content. */
|
|
|
|
|
new_bhead = MEM_mallocN(sizeof(BHeadN), "new_bhead");
|
|
|
|
|
if (new_bhead) {
|
|
|
|
|
new_bhead->next = new_bhead->prev = NULL;
|
|
|
|
|
new_bhead->file_offset = fd->file_offset;
|
|
|
|
|
new_bhead->has_data = false;
|
|
|
|
|
new_bhead->bhead = bhead;
|
|
|
|
|
off64_t seek_new = fd->seek(fd, bhead.len, SEEK_CUR);
|
|
|
|
|
if (seek_new == -1) {
|
|
|
|
|
fd->is_eof = true;
|
|
|
|
|
MEM_freeN(new_bhead);
|
|
|
|
|
new_bhead = NULL;
|
|
|
|
|
}
|
|
|
|
|
BLI_assert(fd->file_offset == seek_new);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fd->is_eof = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-22 14:42:22 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
else {
|
|
|
|
|
new_bhead = MEM_mallocN(sizeof(BHeadN) + bhead.len, "new_bhead");
|
|
|
|
|
if (new_bhead) {
|
|
|
|
|
new_bhead->next = new_bhead->prev = NULL;
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
2019-04-17 06:17:24 +02:00
|
|
|
new_bhead->file_offset = 0; /* don't seek. */
|
|
|
|
|
new_bhead->has_data = true;
|
2019-02-22 14:42:22 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
new_bhead->bhead = bhead;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
readsize = fd->read(fd, new_bhead + 1, bhead.len);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (readsize != bhead.len) {
|
|
|
|
|
fd->is_eof = true;
|
|
|
|
|
MEM_freeN(new_bhead);
|
|
|
|
|
new_bhead = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fd->is_eof = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* We've read a new block. Now add it to the list
|
|
|
|
|
* of blocks.
|
|
|
|
|
*/
|
|
|
|
|
if (new_bhead) {
|
|
|
|
|
BLI_addtail(&fd->bhead_list, new_bhead);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return new_bhead;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 10:31:17 +11:00
|
|
|
BHead *blo_bhead_first(FileData *fd)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHeadN *new_bhead;
|
|
|
|
|
BHead *bhead = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Rewind the file
|
|
|
|
|
* Read in a new block if necessary
|
|
|
|
|
*/
|
|
|
|
|
new_bhead = fd->bhead_list.first;
|
|
|
|
|
if (new_bhead == NULL) {
|
|
|
|
|
new_bhead = get_bhead(fd);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (new_bhead) {
|
|
|
|
|
bhead = &new_bhead->bhead;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return bhead;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 10:31:17 +11:00
|
|
|
BHead *blo_bhead_prev(FileData *UNUSED(fd), BHead *thisblock)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHeadN *bheadn = BHEADN_FROM_BHEAD(thisblock);
|
|
|
|
|
BHeadN *prev = bheadn->prev;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return (prev) ? &prev->bhead : NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 10:31:17 +11:00
|
|
|
BHead *blo_bhead_next(FileData *fd, BHead *thisblock)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHeadN *new_bhead = NULL;
|
|
|
|
|
BHead *bhead = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (thisblock) {
|
|
|
|
|
/* bhead is actually a sub part of BHeadN
|
|
|
|
|
* We calculate the BHeadN pointer from the BHead pointer below */
|
|
|
|
|
new_bhead = BHEADN_FROM_BHEAD(thisblock);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* get the next BHeadN. If it doesn't exist we read in the next one */
|
|
|
|
|
new_bhead = new_bhead->next;
|
|
|
|
|
if (new_bhead == NULL) {
|
|
|
|
|
new_bhead = get_bhead(fd);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (new_bhead) {
|
|
|
|
|
/* here we do the reverse:
|
|
|
|
|
* go from the BHeadN pointer to the BHead pointer */
|
|
|
|
|
bhead = &new_bhead->bhead;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return bhead;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
|
|
|
|
static bool blo_bhead_read_data(FileData *fd, BHead *thisblock, void *buf)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bool success = true;
|
|
|
|
|
BHeadN *new_bhead = BHEADN_FROM_BHEAD(thisblock);
|
|
|
|
|
BLI_assert(new_bhead->has_data == false && new_bhead->file_offset != 0);
|
|
|
|
|
off64_t offset_backup = fd->file_offset;
|
|
|
|
|
if (UNLIKELY(fd->seek(fd, new_bhead->file_offset, SEEK_SET) == -1)) {
|
|
|
|
|
success = false;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (fd->read(fd, buf, new_bhead->bhead.len) != new_bhead->bhead.len) {
|
|
|
|
|
success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (fd->seek(fd, offset_backup, SEEK_SET) == -1) {
|
|
|
|
|
success = false;
|
|
|
|
|
}
|
|
|
|
|
return success;
|
2019-02-22 14:42:22 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static BHead *blo_bhead_read_full(FileData *fd, BHead *thisblock)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHeadN *new_bhead = BHEADN_FROM_BHEAD(thisblock);
|
|
|
|
|
BHeadN *new_bhead_data = MEM_mallocN(sizeof(BHeadN) + new_bhead->bhead.len, "new_bhead");
|
|
|
|
|
new_bhead_data->bhead = new_bhead->bhead;
|
|
|
|
|
new_bhead_data->file_offset = new_bhead->file_offset;
|
|
|
|
|
new_bhead_data->has_data = true;
|
|
|
|
|
if (!blo_bhead_read_data(fd, thisblock, new_bhead_data + 1)) {
|
|
|
|
|
MEM_freeN(new_bhead_data);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return &new_bhead_data->bhead;
|
2019-02-22 14:42:22 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
#endif /* USE_BHEAD_READ_ON_DEMAND */
|
2019-02-22 14:42:22 +11:00
|
|
|
|
2017-11-05 14:33:18 +11:00
|
|
|
/* Warning! Caller's responsibility to ensure given bhead **is** and ID one! */
|
2019-02-22 10:31:17 +11:00
|
|
|
const char *blo_bhead_id_name(const FileData *fd, const BHead *bhead)
|
Fix T34446: Make Local on linked mesh object: object gets removed if redo function is used.
Root of the issue is that we do not re-read lib data blocks and ID placholders (ID_ID bheads)
in undo context (in `blo_read_file_internal`), because `BLO_read_from_memfile` copies
lib datablocks and Main data directly from oldmain.
The idea being, linked data do not change from undo/redo.
This is valid as long as linked data was not changed by the undo step - but if some
was deleted or localized, it will be missing from oldmain, leading to data loss
(note that does not only concern objects, all linkable data types can be affected,
at least in theory).
This commit addresses that issue by carefully mixing reuse of needed data from oldmain,
and "normal" re-reading of missing one. Makes us swimming in some rather dark waters,
and gives a rather non-easy-to-follow code, but it seems to work quite well,
and only other solution would be to get rid of that optimization
(not re-reading all libs on undo/redo), which is not acceptable.
Also, thanks to @carlosdp for initial investigation of the issue.
Differential Revision: https://developer.blender.org/D1485
2015-10-12 12:15:05 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return (const char *)POINTER_OFFSET(bhead, sizeof(*bhead) + fd->id_name_offs);
|
Fix T34446: Make Local on linked mesh object: object gets removed if redo function is used.
Root of the issue is that we do not re-read lib data blocks and ID placholders (ID_ID bheads)
in undo context (in `blo_read_file_internal`), because `BLO_read_from_memfile` copies
lib datablocks and Main data directly from oldmain.
The idea being, linked data do not change from undo/redo.
This is valid as long as linked data was not changed by the undo step - but if some
was deleted or localized, it will be missing from oldmain, leading to data loss
(note that does not only concern objects, all linkable data types can be affected,
at least in theory).
This commit addresses that issue by carefully mixing reuse of needed data from oldmain,
and "normal" re-reading of missing one. Makes us swimming in some rather dark waters,
and gives a rather non-easy-to-follow code, but it seems to work quite well,
and only other solution would be to get rid of that optimization
(not re-reading all libs on undo/redo), which is not acceptable.
Also, thanks to @carlosdp for initial investigation of the issue.
Differential Revision: https://developer.blender.org/D1485
2015-10-12 12:15:05 +02:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void decode_blender_header(FileData *fd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
char header[SIZEOFBLENDERHEADER], num[4];
|
|
|
|
|
int readsize;
|
|
|
|
|
|
|
|
|
|
/* read in the header data */
|
|
|
|
|
readsize = fd->read(fd, header, sizeof(header));
|
|
|
|
|
|
|
|
|
|
if (readsize == sizeof(header) && STREQLEN(header, "BLENDER", 7) && ELEM(header[7], '_', '-') &&
|
|
|
|
|
ELEM(header[8], 'v', 'V') &&
|
|
|
|
|
(isdigit(header[9]) && isdigit(header[10]) && isdigit(header[11]))) {
|
|
|
|
|
fd->flags |= FD_FLAGS_FILE_OK;
|
|
|
|
|
|
|
|
|
|
/* what size are pointers in the file ? */
|
|
|
|
|
if (header[7] == '_') {
|
|
|
|
|
fd->flags |= FD_FLAGS_FILE_POINTSIZE_IS_4;
|
|
|
|
|
if (sizeof(void *) != 4) {
|
|
|
|
|
fd->flags |= FD_FLAGS_POINTSIZE_DIFFERS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (sizeof(void *) != 8) {
|
|
|
|
|
fd->flags |= FD_FLAGS_POINTSIZE_DIFFERS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* is the file saved in a different endian
|
|
|
|
|
* than we need ?
|
|
|
|
|
*/
|
|
|
|
|
if (((header[8] == 'v') ? L_ENDIAN : B_ENDIAN) != ENDIAN_ORDER) {
|
|
|
|
|
fd->flags |= FD_FLAGS_SWITCH_ENDIAN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* get the version number */
|
|
|
|
|
memcpy(num, header + 9, 3);
|
|
|
|
|
num[3] = 0;
|
|
|
|
|
fd->fileversion = atoi(num);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2016-07-12 12:23:48 +10:00
|
|
|
/**
|
|
|
|
|
* \return Success if the file is read correctly, else set \a r_error_message.
|
|
|
|
|
*/
|
|
|
|
|
static bool read_file_dna(FileData *fd, const char **r_error_message)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead;
|
|
|
|
|
int subversion = 0;
|
|
|
|
|
|
|
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
|
|
|
|
if (bhead->code == GLOB) {
|
|
|
|
|
/* Before this, the subversion didn't exist in 'FileGlobal' so the subversion
|
|
|
|
|
* value isn't accessible for the purpose of DNA versioning in this case. */
|
|
|
|
|
if (fd->fileversion <= 242) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* We can't use read_global because this needs 'DNA1' to be decoded,
|
|
|
|
|
* however the first 4 chars are _always_ the subversion. */
|
|
|
|
|
FileGlobal *fg = (void *)&bhead[1];
|
2019-04-22 09:13:00 +10:00
|
|
|
BLI_STATIC_ASSERT(offsetof(FileGlobal, subvstr) == 0, "Must be first: subvstr")
|
2019-04-17 06:17:24 +02:00
|
|
|
char num[5];
|
|
|
|
|
memcpy(num, fg->subvstr, 4);
|
|
|
|
|
num[4] = 0;
|
|
|
|
|
subversion = atoi(num);
|
|
|
|
|
}
|
|
|
|
|
else if (bhead->code == DNA1) {
|
|
|
|
|
const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
|
|
|
|
|
|
|
|
|
|
fd->filesdna = DNA_sdna_from_data(
|
|
|
|
|
&bhead[1], bhead->len, do_endian_swap, true, r_error_message);
|
|
|
|
|
if (fd->filesdna) {
|
|
|
|
|
blo_do_versions_dna(fd->filesdna, fd->fileversion, subversion);
|
|
|
|
|
fd->compflags = DNA_struct_get_compareflags(fd->filesdna, fd->memsdna);
|
|
|
|
|
/* used to retrieve ID names from (bhead+1) */
|
|
|
|
|
fd->id_name_offs = DNA_elem_offset(fd->filesdna, "ID", "char", "name[]");
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
else if (bhead->code == ENDB) {
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*r_error_message = "Missing DNA block";
|
|
|
|
|
return false;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2006-11-26 21:17:15 +00:00
|
|
|
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
static int *read_file_thumbnail(FileData *fd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead;
|
|
|
|
|
int *blend_thumb = NULL;
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
|
|
|
|
if (bhead->code == TEST) {
|
|
|
|
|
const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
|
|
|
|
|
int *data = (int *)(bhead + 1);
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bhead->len < (2 * sizeof(int))) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (do_endian_swap) {
|
|
|
|
|
BLI_endian_switch_int32(&data[0]);
|
|
|
|
|
BLI_endian_switch_int32(&data[1]);
|
|
|
|
|
}
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
const int width = data[0];
|
|
|
|
|
const int height = data[1];
|
|
|
|
|
if (!BLEN_THUMB_MEMSIZE_IS_VALID(width, height)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (bhead->len < BLEN_THUMB_MEMSIZE_FILE(width, height)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
blend_thumb = data;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (bhead->code != REND) {
|
|
|
|
|
/* Thumbnail is stored in TEST immediately after first REND... */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return blend_thumb;
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name File Data API
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2019-02-24 12:34:41 +11:00
|
|
|
/* Regular file reading. */
|
|
|
|
|
|
|
|
|
|
static int fd_read_data_from_file(FileData *filedata, void *buffer, uint size)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int readsize = read(filedata->filedes, buffer, size);
|
2019-02-24 12:34:41 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (readsize < 0) {
|
|
|
|
|
readsize = EOF;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
filedata->file_offset += readsize;
|
|
|
|
|
}
|
2019-02-24 12:34:41 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return (readsize);
|
2019-02-24 12:34:41 +11:00
|
|
|
}
|
|
|
|
|
|
2019-03-19 20:04:23 +11:00
|
|
|
static off64_t fd_seek_data_from_file(FileData *filedata, off64_t offset, int whence)
|
2019-02-24 12:34:41 +11:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
filedata->file_offset = lseek(filedata->filedes, offset, whence);
|
|
|
|
|
return filedata->file_offset;
|
2019-02-24 12:34:41 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* GZip file reading. */
|
|
|
|
|
|
2018-11-30 14:51:16 +11:00
|
|
|
static int fd_read_gzip_from_file(FileData *filedata, void *buffer, uint size)
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int readsize = gzread(filedata->gzfiledes, buffer, size);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (readsize < 0) {
|
|
|
|
|
readsize = EOF;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
filedata->file_offset += readsize;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return (readsize);
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-24 12:34:41 +11:00
|
|
|
/* Memory reading. */
|
|
|
|
|
|
2018-11-30 14:51:16 +11:00
|
|
|
static int fd_read_from_memory(FileData *filedata, void *buffer, uint size)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* don't read more bytes then there are available in the buffer */
|
|
|
|
|
int readsize = (int)MIN2(size, (uint)(filedata->buffersize - filedata->file_offset));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
memcpy(buffer, filedata->buffer + filedata->file_offset, readsize);
|
|
|
|
|
filedata->file_offset += readsize;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return (readsize);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-24 12:34:41 +11:00
|
|
|
/* MemFile reading. */
|
|
|
|
|
|
2018-11-30 14:51:16 +11:00
|
|
|
static int fd_read_from_memfile(FileData *filedata, void *buffer, uint size)
|
2004-09-05 13:43:51 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
static size_t seek = SIZE_MAX; /* the current position */
|
|
|
|
|
static size_t offset = 0; /* size of previous chunks */
|
|
|
|
|
static MemFileChunk *chunk = NULL;
|
|
|
|
|
size_t chunkoffset, readsize, totread;
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (size == 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return 0;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (seek != (size_t)filedata->file_offset) {
|
|
|
|
|
chunk = filedata->memfile->chunks.first;
|
|
|
|
|
seek = 0;
|
|
|
|
|
|
|
|
|
|
while (chunk) {
|
|
|
|
|
if (seek + chunk->size > (size_t)filedata->file_offset) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
seek += chunk->size;
|
|
|
|
|
chunk = chunk->next;
|
|
|
|
|
}
|
|
|
|
|
offset = seek;
|
|
|
|
|
seek = filedata->file_offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (chunk) {
|
|
|
|
|
totread = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
/* first check if it's on the end if current chunk */
|
|
|
|
|
if (seek - offset == chunk->size) {
|
|
|
|
|
offset += chunk->size;
|
|
|
|
|
chunk = chunk->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* debug, should never happen */
|
|
|
|
|
if (chunk == NULL) {
|
|
|
|
|
printf("illegal read, chunk zero\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chunkoffset = seek - offset;
|
|
|
|
|
readsize = size - totread;
|
|
|
|
|
|
|
|
|
|
/* data can be spread over multiple chunks, so clamp size
|
|
|
|
|
* to within this chunk, and then it will read further in
|
|
|
|
|
* the next chunk */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (chunkoffset + readsize > chunk->size) {
|
2019-04-17 06:17:24 +02:00
|
|
|
readsize = chunk->size - chunkoffset;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
memcpy(POINTER_OFFSET(buffer, totread), chunk->buf + chunkoffset, readsize);
|
|
|
|
|
totread += readsize;
|
|
|
|
|
filedata->file_offset += readsize;
|
|
|
|
|
seek += readsize;
|
|
|
|
|
} while (totread < size);
|
|
|
|
|
|
|
|
|
|
return totread;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
2004-09-05 13:43:51 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static FileData *filedata_new(void)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = MEM_callocN(sizeof(FileData), "FileData");
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->filedes = -1;
|
|
|
|
|
fd->gzfiledes = NULL;
|
2016-07-12 12:53:49 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->memsdna = DNA_sdna_current_get();
|
2016-07-12 12:53:49 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->datamap = oldnewmap_new();
|
|
|
|
|
fd->globmap = oldnewmap_new();
|
|
|
|
|
fd->libmap = oldnewmap_new();
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return fd;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-19 00:50:21 +00:00
|
|
|
static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
|
2005-07-25 18:35:49 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
decode_blender_header(fd);
|
|
|
|
|
|
|
|
|
|
if (fd->flags & FD_FLAGS_FILE_OK) {
|
|
|
|
|
const char *error_message = NULL;
|
|
|
|
|
if (read_file_dna(fd, &error_message) == false) {
|
|
|
|
|
BKE_reportf(
|
|
|
|
|
reports, RPT_ERROR, "Failed to read blend file '%s': %s", fd->relabase, error_message);
|
|
|
|
|
blo_filedata_free(fd);
|
|
|
|
|
fd = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BKE_reportf(
|
|
|
|
|
reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase);
|
|
|
|
|
blo_filedata_free(fd);
|
|
|
|
|
fd = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static FileData *blo_filedata_from_file_descriptor(const char *filepath,
|
|
|
|
|
ReportList *reports,
|
|
|
|
|
int file)
|
|
|
|
|
{
|
|
|
|
|
FileDataReadFn *read_fn = NULL;
|
|
|
|
|
FileDataSeekFn *seek_fn = NULL; /* Optional. */
|
|
|
|
|
|
|
|
|
|
gzFile gzfile = (gzFile)Z_NULL;
|
|
|
|
|
|
|
|
|
|
char header[7];
|
|
|
|
|
|
|
|
|
|
/* Regular file. */
|
|
|
|
|
errno = 0;
|
|
|
|
|
if (read(file, header, sizeof(header)) != sizeof(header)) {
|
|
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
"Unable to read '%s': %s",
|
|
|
|
|
filepath,
|
|
|
|
|
errno ? strerror(errno) : TIP_("insufficient content"));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
lseek(file, 0, SEEK_SET);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Regular file. */
|
|
|
|
|
if (memcmp(header, "BLENDER", sizeof(header)) == 0) {
|
|
|
|
|
read_fn = fd_read_data_from_file;
|
|
|
|
|
seek_fn = fd_seek_data_from_file;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Gzip file. */
|
|
|
|
|
errno = 0;
|
|
|
|
|
if ((read_fn == NULL) &&
|
|
|
|
|
/* Check header magic. */
|
|
|
|
|
(header[0] == 0x1f && header[1] == 0x8b)) {
|
|
|
|
|
gzfile = BLI_gzopen(filepath, "rb");
|
|
|
|
|
if (gzfile == (gzFile)Z_NULL) {
|
|
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
"Unable to open '%s': %s",
|
|
|
|
|
filepath,
|
|
|
|
|
errno ? strerror(errno) : TIP_("unknown error reading file"));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* 'seek_fn' is too slow for gzip, don't set it. */
|
|
|
|
|
read_fn = fd_read_gzip_from_file;
|
|
|
|
|
/* Caller must close. */
|
|
|
|
|
file = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (read_fn == NULL) {
|
|
|
|
|
BKE_reportf(reports, RPT_WARNING, "Unrecognized file format '%s'", filepath);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FileData *fd = filedata_new();
|
|
|
|
|
|
|
|
|
|
fd->filedes = file;
|
|
|
|
|
fd->gzfiledes = gzfile;
|
|
|
|
|
|
|
|
|
|
fd->read = read_fn;
|
|
|
|
|
fd->seek = seek_fn;
|
|
|
|
|
|
|
|
|
|
return fd;
|
2019-02-24 10:46:26 +11:00
|
|
|
}
|
|
|
|
|
|
2019-02-24 23:42:05 +11:00
|
|
|
static FileData *blo_filedata_from_file_open(const char *filepath, ReportList *reports)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
errno = 0;
|
|
|
|
|
const int file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
|
|
|
|
|
if (file == -1) {
|
|
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
"Unable to open '%s': %s",
|
|
|
|
|
filepath,
|
|
|
|
|
errno ? strerror(errno) : TIP_("unknown error reading file"));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
FileData *fd = blo_filedata_from_file_descriptor(filepath, reports, file);
|
|
|
|
|
if ((fd == NULL) || (fd->filedes == -1)) {
|
|
|
|
|
close(file);
|
|
|
|
|
}
|
|
|
|
|
return fd;
|
2019-02-24 23:42:05 +11:00
|
|
|
}
|
|
|
|
|
|
2019-02-24 10:46:26 +11:00
|
|
|
/* cannot be called with relative paths anymore! */
|
|
|
|
|
/* on each new library added, it now checks for the current FileData and expands relativeness */
|
|
|
|
|
FileData *blo_filedata_from_file(const char *filepath, ReportList *reports)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = blo_filedata_from_file_open(filepath, reports);
|
|
|
|
|
if (fd != NULL) {
|
|
|
|
|
/* needed for library_append and read_libraries */
|
|
|
|
|
BLI_strncpy(fd->relabase, filepath, sizeof(fd->relabase));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return blo_decode_and_check(fd, reports);
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
/**
|
2019-04-22 01:10:29 +10:00
|
|
|
* Same as blo_filedata_from_file(), but does not reads DNA data, only header.
|
|
|
|
|
* Use it for light access (e.g. thumbnail reading).
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
*/
|
2019-02-22 10:31:17 +11:00
|
|
|
static FileData *blo_filedata_from_file_minimal(const char *filepath)
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = blo_filedata_from_file_open(filepath, NULL);
|
|
|
|
|
if (fd != NULL) {
|
|
|
|
|
decode_blender_header(fd);
|
|
|
|
|
if (fd->flags & FD_FLAGS_FILE_OK) {
|
|
|
|
|
return fd;
|
|
|
|
|
}
|
|
|
|
|
blo_filedata_free(fd);
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
}
|
|
|
|
|
|
2018-11-30 14:51:16 +11:00
|
|
|
static int fd_read_gzip_from_memory(FileData *filedata, void *buffer, uint size)
|
2012-12-27 15:07:19 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int err;
|
2012-12-29 01:54:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
filedata->strm.next_out = (Bytef *)buffer;
|
|
|
|
|
filedata->strm.avail_out = size;
|
2012-12-29 01:54:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
// Inflate another chunk.
|
|
|
|
|
err = inflate(&filedata->strm, Z_SYNC_FLUSH);
|
2012-12-29 01:54:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (err == Z_STREAM_END) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (err != Z_OK) {
|
|
|
|
|
printf("fd_read_gzip_from_memory: zlib error\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2012-12-29 01:54:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
filedata->file_offset += size;
|
2012-12-29 01:54:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return (size);
|
2012-12-27 15:07:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int fd_read_gzip_from_memory_init(FileData *fd)
|
|
|
|
|
{
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->strm.next_in = (Bytef *)fd->buffer;
|
|
|
|
|
fd->strm.avail_in = fd->buffersize;
|
|
|
|
|
fd->strm.total_out = 0;
|
|
|
|
|
fd->strm.zalloc = Z_NULL;
|
|
|
|
|
fd->strm.zfree = Z_NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (inflateInit2(&fd->strm, (16 + MAX_WBITS)) != Z_OK) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return 0;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2012-12-27 15:07:19 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->read = fd_read_gzip_from_memory;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return 1;
|
2012-12-27 15:07:19 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 10:31:17 +11:00
|
|
|
FileData *blo_filedata_from_memory(const void *mem, int memsize, ReportList *reports)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (!mem || memsize < SIZEOFBLENDERHEADER) {
|
|
|
|
|
BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read") : TIP_("Unable to open"));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
FileData *fd = filedata_new();
|
|
|
|
|
const char *cp = mem;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->buffer = mem;
|
|
|
|
|
fd->buffersize = memsize;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* test if gzip */
|
|
|
|
|
if (cp[0] == 0x1f && cp[1] == 0x8b) {
|
|
|
|
|
if (0 == fd_read_gzip_from_memory_init(fd)) {
|
|
|
|
|
blo_filedata_free(fd);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->read = fd_read_from_memory;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
|
2013-03-26 09:59:43 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return blo_decode_and_check(fd, reports);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 10:40:17 +11:00
|
|
|
FileData *blo_filedata_from_memfile(MemFile *memfile, ReportList *reports)
|
2004-09-05 13:43:51 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (!memfile) {
|
|
|
|
|
BKE_report(reports, RPT_WARNING, "Unable to open blend <memory>");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
FileData *fd = filedata_new();
|
|
|
|
|
fd->memfile = memfile;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->read = fd_read_from_memfile;
|
|
|
|
|
fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return blo_decode_and_check(fd, reports);
|
|
|
|
|
}
|
2004-09-05 13:43:51 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 10:31:17 +11:00
|
|
|
void blo_filedata_free(FileData *fd)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd) {
|
|
|
|
|
if (fd->filedes != -1) {
|
|
|
|
|
close(fd->filedes);
|
|
|
|
|
}
|
2019-02-24 12:34:41 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->gzfiledes != NULL) {
|
|
|
|
|
gzclose(fd->gzfiledes);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->strm.next_in) {
|
|
|
|
|
if (inflateEnd(&fd->strm) != Z_OK) {
|
|
|
|
|
printf("close gzip stream error\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) {
|
|
|
|
|
MEM_freeN((void *)fd->buffer);
|
|
|
|
|
fd->buffer = NULL;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Free all BHeadN data blocks */
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifndef NDEBUG
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_freelistN(&fd->bhead_list);
|
2019-02-22 14:42:22 +11:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Sanity check we're not keeping memory we don't need. */
|
2019-04-21 04:40:16 +10:00
|
|
|
LISTBASE_FOREACH_MUTABLE (BHeadN *, new_bhead, &fd->bhead_list) {
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->seek != NULL && BHEAD_USE_READ_ON_DEMAND(&new_bhead->bhead)) {
|
|
|
|
|
BLI_assert(new_bhead->has_data == 0);
|
|
|
|
|
}
|
|
|
|
|
MEM_freeN(new_bhead);
|
|
|
|
|
}
|
2019-02-22 14:42:22 +11:00
|
|
|
#endif
|
2016-07-12 12:53:49 +10:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->filesdna) {
|
2019-04-17 06:17:24 +02:00
|
|
|
DNA_sdna_free(fd->filesdna);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->compflags) {
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN((void *)fd->compflags);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->datamap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->datamap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->globmap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->globmap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->imamap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->imamap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->movieclipmap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->movieclipmap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->scenemap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->scenemap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->soundmap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->soundmap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->packedmap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->packedmap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->libmap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (fd->bheadmap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(fd->bheadmap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2015-03-11 00:33:44 +11:00
|
|
|
#ifdef USE_GHASH_BHEAD
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->bhead_idname_hash) {
|
|
|
|
|
BLI_ghash_free(fd->bhead_idname_hash, NULL, NULL);
|
|
|
|
|
}
|
2015-03-11 00:33:44 +11:00
|
|
|
#endif
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(fd);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Public Utilities
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
2019-02-22 18:35:07 +11:00
|
|
|
* Check whether given path ends with a blend file compatible extension
|
|
|
|
|
* (`.blend`, `.ble` or `.blend.gz`).
|
2015-10-12 14:21:34 +02:00
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param str: The path to check.
|
2015-10-12 14:21:34 +02:00
|
|
|
* \return true is this path ends with a blender file extension.
|
|
|
|
|
*/
|
2014-01-31 03:09:01 +11:00
|
|
|
bool BLO_has_bfile_extension(const char *str)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const char *ext_test[4] = {".blend", ".ble", ".blend.gz", NULL};
|
|
|
|
|
return BLI_path_extension_check_array(str, ext_test);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
2019-02-22 18:35:07 +11:00
|
|
|
* Try to explode given path into its 'library components'
|
|
|
|
|
* (i.e. a .blend file, id type/group, and data-block itself).
|
2015-10-12 14:21:34 +02:00
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param path: the full path to explode.
|
|
|
|
|
* \param r_dir: the string that'll contain path up to blend file itself ('library' path).
|
2019-02-22 18:35:07 +11:00
|
|
|
* WARNING! Must be #FILE_MAX_LIBEXTRA long (it also stores group and name strings)!
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param r_group: the string that'll contain 'group' part of the path, if any. May be NULL.
|
|
|
|
|
* \param r_name: the string that'll contain data's name part of the path, if any. May be NULL.
|
2015-10-12 14:21:34 +02:00
|
|
|
* \return true if path contains a blend file.
|
|
|
|
|
*/
|
2015-08-18 13:18:50 +02:00
|
|
|
bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name)
|
2009-09-12 19:54:39 +00:00
|
|
|
{
|
2019-04-22 01:10:29 +10:00
|
|
|
/* We might get some data names with slashes,
|
|
|
|
|
* so we have to go up in path until we find blend file itself,
|
2019-04-17 06:17:24 +02:00
|
|
|
* then we now next path item is group, and everything else is data name. */
|
|
|
|
|
char *slash = NULL, *prev_slash = NULL, c = '\0';
|
|
|
|
|
|
|
|
|
|
r_dir[0] = '\0';
|
|
|
|
|
if (r_group) {
|
|
|
|
|
*r_group = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (r_name) {
|
|
|
|
|
*r_name = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if path leads to an existing directory, we can be sure we're not (in) a library */
|
|
|
|
|
if (BLI_is_dir(path)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strcpy(r_dir, path);
|
|
|
|
|
|
|
|
|
|
while ((slash = (char *)BLI_last_slash(r_dir))) {
|
|
|
|
|
char tc = *slash;
|
|
|
|
|
*slash = '\0';
|
|
|
|
|
if (BLO_has_bfile_extension(r_dir) && BLI_is_file(r_dir)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (STREQ(r_dir, BLO_EMBEDDED_STARTUP_BLEND)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (prev_slash) {
|
|
|
|
|
*prev_slash = c;
|
|
|
|
|
}
|
|
|
|
|
prev_slash = slash;
|
|
|
|
|
c = tc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!slash) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (slash[1] != '\0') {
|
|
|
|
|
BLI_assert(strlen(slash + 1) < BLO_GROUP_MAX);
|
|
|
|
|
if (r_group) {
|
|
|
|
|
*r_group = slash + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (prev_slash && (prev_slash[1] != '\0')) {
|
|
|
|
|
BLI_assert(strlen(prev_slash + 1) < MAX_ID_NAME - 2);
|
|
|
|
|
if (r_name) {
|
|
|
|
|
*r_name = prev_slash + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
|
|
|
|
* Does a very light reading of given .blend file to extract its stored thumbnail.
|
|
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param filepath: The path of the file to extract thumbnail from.
|
2015-10-12 14:21:34 +02:00
|
|
|
* \return The raw thumbnail
|
2019-04-22 01:10:29 +10:00
|
|
|
* (MEM-allocated, as stored in file, use #BKE_main_thumbnail_to_imbuf()
|
|
|
|
|
* to convert it to ImBuf image).
|
2015-10-12 14:21:34 +02:00
|
|
|
*/
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
BlendThumbnail *BLO_thumbnail_from_file(const char *filepath)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd;
|
|
|
|
|
BlendThumbnail *data = NULL;
|
|
|
|
|
int *fd_data;
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd = blo_filedata_from_file_minimal(filepath);
|
|
|
|
|
fd_data = fd ? read_file_thumbnail(fd) : NULL;
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd_data) {
|
|
|
|
|
const int width = fd_data[0];
|
|
|
|
|
const int height = fd_data[1];
|
|
|
|
|
if (BLEN_THUMB_MEMSIZE_IS_VALID(width, height)) {
|
|
|
|
|
const size_t sz = BLEN_THUMB_MEMSIZE(width, height);
|
|
|
|
|
data = MEM_mallocN(sz, __func__);
|
|
|
|
|
if (data) {
|
|
|
|
|
BLI_assert((sz - sizeof(*data)) ==
|
|
|
|
|
(BLEN_THUMB_MEMSIZE_FILE(width, height) - (sizeof(*fd_data) * 2)));
|
|
|
|
|
data->width = width;
|
|
|
|
|
data->height = height;
|
|
|
|
|
memcpy(data->rect, &fd_data[2], sz - sizeof(*data));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
blo_filedata_free(fd);
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return data;
|
Make .blend file thumbnail reading simpler and more coherent, read/store them when reading in background mode.
Primary goal of this commit is to fix an annoying issue - when processing and saving .blend
files in background mode you lose their thumbnails, since it can only be generated with
an OpenGL context.
Solution to that is to read .blend thumbnail while reading .blend file (only done in background
mode currently), and store it in Main struct.
Also, this lead to removing .blend file reading code from thumb_blend (no need to have doublons).
We now have a small interface in regular reading code area, which keeps it reasonbaly light
by only reading/parsing header info, and first few BHead blocks.
This makes code reading .blend thumbnail about 3 to 4 times slower than previous highly specialized
one in blend_thumb.c, but overall thumbnail generation of a big .blend files folder only grows
of about 1%, think we can bare with it.
Finally, since thumbnail is now optionally stored in Main struct, it makes it easy to allow user
to define their own custom one (instead of auto-generated one). RNA API for this was not added though,
accessing that kind of .blend meta-data has to be rethought a bit on a bigger level first.
Reviewers: sergey, campbellbarton
Subscribers: Severin, psy-fi
Differential Revision: https://developer.blender.org/D1469
2015-08-27 15:53:23 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Old/New Pointer Map
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* only direct databocks */
|
|
|
|
|
static void *newdataadr(FileData *fd, const void *adr)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
|
2013-08-07 19:29:15 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* only direct databocks */
|
|
|
|
|
static void *newdataadr_no_us(FileData *fd, const void *adr)
|
2013-08-07 19:29:15 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->datamap, adr, false);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* direct datablocks with global linking */
|
|
|
|
|
static void *newglobadr(FileData *fd, const void *adr)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->globmap, adr, true);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* used to restore image data after undo */
|
|
|
|
|
static void *newimaadr(FileData *fd, const void *adr)
|
2006-11-10 10:17:04 +00:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->imamap && adr) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->imamap, adr, true);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2006-11-10 10:17:04 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* used to restore scene data after undo */
|
|
|
|
|
static void *newsceadr(FileData *fd, const void *adr)
|
2018-07-10 15:02:25 +02:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->scenemap && adr) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->scenemap, adr, true);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2018-07-10 15:02:25 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* used to restore movie clip data after undo */
|
|
|
|
|
static void *newmclipadr(FileData *fd, const void *adr)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->movieclipmap && adr) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->movieclipmap, adr, true);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* used to restore sound data after undo */
|
|
|
|
|
static void *newsoundadr(FileData *fd, const void *adr)
|
2014-11-24 18:18:35 +01:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->soundmap && adr) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->soundmap, adr, true);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2014-11-24 18:18:35 +01:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* used to restore packed data after undo */
|
|
|
|
|
static void *newpackedadr(FileData *fd, const void *adr)
|
2012-12-27 15:07:19 +00:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->packedmap && adr) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->packedmap, adr, true);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
|
2012-12-27 15:07:19 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* only lib data */
|
|
|
|
|
static void *newlibadr(FileData *fd, const void *lib, const void *adr)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return oldnewmap_liblookup(fd->libmap, adr, lib);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* only lib data */
|
|
|
|
|
void *blo_do_versions_newlibadr(FileData *fd, const void *lib, const void *adr)
|
2012-05-04 15:42:49 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return newlibadr(fd, lib, adr);
|
2012-05-04 15:42:49 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* increases user number */
|
|
|
|
|
static void *newlibadr_us(FileData *fd, const void *lib, const void *adr)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ID *id = newlibadr(fd, lib, adr);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
id_us_plus_no_lib(id);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return id;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* increases user number */
|
|
|
|
|
void *blo_do_versions_newlibadr_us(FileData *fd, const void *lib, const void *adr)
|
2012-05-04 15:42:49 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return newlibadr_us(fd, lib, adr);
|
2012-05-04 15:42:49 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 14:41:19 +10:00
|
|
|
/* ensures real user */
|
|
|
|
|
static void *newlibadr_real_us(FileData *fd, const void *lib, const void *adr)
|
2016-06-16 19:23:09 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ID *id = newlibadr(fd, lib, adr);
|
2016-06-16 19:23:09 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
id_us_ensure_real(id);
|
2016-06-16 19:23:09 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return id;
|
2016-06-16 19:23:09 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-27 19:25:21 +01:00
|
|
|
static void change_link_placeholder_to_real_ID_pointer_fd(FileData *fd, const void *old, void *new)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int i = 0; i < fd->libmap->nentries; i++) {
|
|
|
|
|
OldNew *entry = &fd->libmap->entries[i];
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (old == entry->newp && entry->nr == ID_LINK_PLACEHOLDER) {
|
|
|
|
|
entry->newp = new;
|
2019-04-22 09:13:00 +10:00
|
|
|
if (new) {
|
2019-04-17 06:17:24 +02:00
|
|
|
entry->nr = GS(((ID *)new)->name);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void change_link_placeholder_to_real_ID_pointer(ListBase *mainlist,
|
|
|
|
|
FileData *basefd,
|
|
|
|
|
void *old,
|
|
|
|
|
void *new)
|
2005-12-16 17:35:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *mainptr;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (mainptr = mainlist->first; mainptr; mainptr = mainptr->next) {
|
|
|
|
|
FileData *fd;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mainptr->curlib) {
|
2019-04-17 06:17:24 +02:00
|
|
|
fd = mainptr->curlib->filedata;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
fd = basefd;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd) {
|
|
|
|
|
change_link_placeholder_to_real_ID_pointer_fd(fd, old, new);
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-12-16 17:35:38 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2008-11-02 00:25:39 +00:00
|
|
|
/* lib linked proxy objects point to our local data, we need
|
|
|
|
|
* to clear that pointer before reading the undo memfile since
|
|
|
|
|
* the object might be removed, it is set again in reading
|
2019-01-30 20:32:28 +01:00
|
|
|
* if the local object still exists.
|
|
|
|
|
* This is only valid for local proxy objects though, linked ones should not be affected here.
|
|
|
|
|
*/
|
2010-10-16 02:40:31 +00:00
|
|
|
void blo_clear_proxy_pointers_from_lib(Main *oldmain)
|
2008-11-02 00:25:39 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Object *ob = oldmain->objects.first;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; ob; ob = ob->id.next) {
|
|
|
|
|
if (ob->id.lib != NULL && ob->proxy_from != NULL && ob->proxy_from->id.lib == NULL) {
|
|
|
|
|
ob->proxy_from = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-11-02 00:25:39 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-10 15:02:25 +02:00
|
|
|
void blo_make_scene_pointer_map(FileData *fd, Main *oldmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Scene *sce = oldmain->scenes.first;
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->scenemap = oldnewmap_new();
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; sce; sce = sce->id.next) {
|
|
|
|
|
if (sce->eevee.light_cache) {
|
|
|
|
|
struct LightCache *light_cache = sce->eevee.light_cache;
|
|
|
|
|
oldnewmap_insert(fd->scenemap, light_cache, light_cache, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-10 15:02:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void blo_end_scene_pointer_map(FileData *fd, Main *oldmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
OldNew *entry = fd->scenemap->entries;
|
|
|
|
|
Scene *sce = oldmain->scenes.first;
|
|
|
|
|
int i;
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* used entries were restored, so we put them to zero */
|
|
|
|
|
for (i = 0; i < fd->scenemap->nentries; i++, entry++) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (entry->nr > 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
entry->newp = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; sce; sce = sce->id.next) {
|
|
|
|
|
sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
|
|
|
|
|
}
|
2018-07-10 15:02:25 +02:00
|
|
|
}
|
|
|
|
|
|
2008-12-19 16:36:15 +00:00
|
|
|
void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
|
2006-11-10 10:17:04 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Image *ima = oldmain->images.first;
|
|
|
|
|
Scene *sce = oldmain->scenes.first;
|
|
|
|
|
int a;
|
|
|
|
|
|
|
|
|
|
fd->imamap = oldnewmap_new();
|
|
|
|
|
|
|
|
|
|
for (; ima; ima = ima->id.next) {
|
|
|
|
|
if (ima->cache) {
|
|
|
|
|
oldnewmap_insert(fd->imamap, ima->cache, ima->cache, 0);
|
|
|
|
|
}
|
|
|
|
|
for (a = 0; a < TEXTARGET_COUNT; a++) {
|
|
|
|
|
if (ima->gputexture[a]) {
|
|
|
|
|
oldnewmap_insert(fd->imamap, ima->gputexture[a], ima->gputexture[a], 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ima->rr) {
|
|
|
|
|
oldnewmap_insert(fd->imamap, ima->rr, ima->rr, 0);
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (RenderSlot *, slot, &ima->renderslots) {
|
|
|
|
|
if (slot->render) {
|
|
|
|
|
oldnewmap_insert(fd->imamap, slot->render, slot->render, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (; sce; sce = sce->id.next) {
|
|
|
|
|
if (sce->nodetree && sce->nodetree->previews) {
|
|
|
|
|
bNodeInstanceHashIterator iter;
|
2019-04-21 04:40:16 +10:00
|
|
|
NODE_INSTANCE_HASH_ITER (iter, sce->nodetree->previews) {
|
2019-04-17 06:17:24 +02:00
|
|
|
bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
|
|
|
|
|
oldnewmap_insert(fd->imamap, preview, preview, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-11-10 10:17:04 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-19 16:36:15 +00:00
|
|
|
/* set old main image ibufs to zero if it has been restored */
|
|
|
|
|
/* this works because freeing old main only happens after this call */
|
|
|
|
|
void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
|
2006-11-10 10:17:04 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
OldNew *entry = fd->imamap->entries;
|
|
|
|
|
Image *ima = oldmain->images.first;
|
|
|
|
|
Scene *sce = oldmain->scenes.first;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* used entries were restored, so we put them to zero */
|
|
|
|
|
for (i = 0; i < fd->imamap->nentries; i++, entry++) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (entry->nr > 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
entry->newp = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (; ima; ima = ima->id.next) {
|
|
|
|
|
ima->cache = newimaadr(fd, ima->cache);
|
|
|
|
|
if (ima->cache == NULL) {
|
|
|
|
|
ima->gpuflag = 0;
|
2019-06-17 11:39:52 +02:00
|
|
|
ima->gpuframenr = INT_MAX;
|
2019-04-17 06:17:24 +02:00
|
|
|
for (i = 0; i < TEXTARGET_COUNT; i++) {
|
|
|
|
|
ima->gputexture[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
ima->rr = NULL;
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (RenderSlot *, slot, &ima->renderslots) {
|
|
|
|
|
slot->render = newimaadr(fd, slot->render);
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (i = 0; i < TEXTARGET_COUNT; i++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ima->gputexture[i] = newimaadr(fd, ima->gputexture[i]);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
ima->rr = newimaadr(fd, ima->rr);
|
|
|
|
|
}
|
|
|
|
|
for (; sce; sce = sce->id.next) {
|
|
|
|
|
if (sce->nodetree && sce->nodetree->previews) {
|
|
|
|
|
bNodeInstanceHash *new_previews = BKE_node_instance_hash_new("node previews");
|
|
|
|
|
bNodeInstanceHashIterator iter;
|
|
|
|
|
|
|
|
|
|
/* reconstruct the preview hash, only using remaining pointers */
|
2019-04-21 04:40:16 +10:00
|
|
|
NODE_INSTANCE_HASH_ITER (iter, sce->nodetree->previews) {
|
2019-04-17 06:17:24 +02:00
|
|
|
bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
|
|
|
|
|
if (preview) {
|
|
|
|
|
bNodePreview *new_preview = newimaadr(fd, preview);
|
|
|
|
|
if (new_preview) {
|
|
|
|
|
bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
|
|
|
|
|
BKE_node_instance_hash_insert(new_previews, key, new_preview);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
BKE_node_instance_hash_free(sce->nodetree->previews, NULL);
|
|
|
|
|
sce->nodetree->previews = new_previews;
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-11-10 10:17:04 +00:00
|
|
|
}
|
|
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MovieClip *clip = oldmain->movieclips.first;
|
|
|
|
|
Scene *sce = oldmain->scenes.first;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->movieclipmap = oldnewmap_new();
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; clip; clip = clip->id.next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (clip->cache) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(fd->movieclipmap, clip->cache, clip->cache, 0);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (clip->tracking.camera.intrinsics) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(
|
|
|
|
|
fd->movieclipmap, clip->tracking.camera.intrinsics, clip->tracking.camera.intrinsics, 0);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; sce; sce = sce->id.next) {
|
|
|
|
|
if (sce->nodetree) {
|
|
|
|
|
bNode *node;
|
2019-04-22 09:13:00 +10:00
|
|
|
for (node = sce->nodetree->nodes.first; node; node = node->next) {
|
|
|
|
|
if (node->type == CMP_NODE_MOVIEDISTORTION) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(fd->movieclipmap, node->storage, node->storage, 0);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set old main movie clips caches to zero if it has been restored */
|
|
|
|
|
/* this works because freeing old main only happens after this call */
|
|
|
|
|
void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
OldNew *entry = fd->movieclipmap->entries;
|
|
|
|
|
MovieClip *clip = oldmain->movieclips.first;
|
|
|
|
|
Scene *sce = oldmain->scenes.first;
|
|
|
|
|
int i;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* used entries were restored, so we put them to zero */
|
|
|
|
|
for (i = 0; i < fd->movieclipmap->nentries; i++, entry++) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (entry->nr > 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
entry->newp = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; clip; clip = clip->id.next) {
|
|
|
|
|
clip->cache = newmclipadr(fd, clip->cache);
|
|
|
|
|
clip->tracking.camera.intrinsics = newmclipadr(fd, clip->tracking.camera.intrinsics);
|
2019-04-02 16:05:22 +02:00
|
|
|
BLI_freelistN(&clip->runtime.gputextures);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; sce; sce = sce->id.next) {
|
|
|
|
|
if (sce->nodetree) {
|
|
|
|
|
bNode *node;
|
2019-04-22 09:13:00 +10:00
|
|
|
for (node = sce->nodetree->nodes.first; node; node = node->next) {
|
|
|
|
|
if (node->type == CMP_NODE_MOVIEDISTORTION) {
|
2019-04-17 06:17:24 +02:00
|
|
|
node->storage = newmclipadr(fd, node->storage);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2014-11-24 18:18:35 +01:00
|
|
|
void blo_make_sound_pointer_map(FileData *fd, Main *oldmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bSound *sound = oldmain->sounds.first;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->soundmap = oldnewmap_new();
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; sound; sound = sound->id.next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sound->waveform) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(fd->soundmap, sound->waveform, sound->waveform, 0);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-11-24 18:18:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set old main sound caches to zero if it has been restored */
|
|
|
|
|
/* this works because freeing old main only happens after this call */
|
|
|
|
|
void blo_end_sound_pointer_map(FileData *fd, Main *oldmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
OldNew *entry = fd->soundmap->entries;
|
|
|
|
|
bSound *sound = oldmain->sounds.first;
|
|
|
|
|
int i;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* used entries were restored, so we put them to zero */
|
|
|
|
|
for (i = 0; i < fd->soundmap->nentries; i++, entry++) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (entry->nr > 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
entry->newp = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; sound; sound = sound->id.next) {
|
|
|
|
|
sound->waveform = newsoundadr(fd, sound->waveform);
|
|
|
|
|
}
|
2014-11-24 18:18:35 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* XXX disabled this feature - packed files also belong in temp saves and quit.blend,
|
|
|
|
|
* to make restore work. */
|
2013-01-13 12:25:56 +00:00
|
|
|
|
2012-12-27 15:07:19 +00:00
|
|
|
static void insert_packedmap(FileData *fd, PackedFile *pf)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(fd->packedmap, pf, pf, 0);
|
|
|
|
|
oldnewmap_insert(fd->packedmap, pf->data, pf->data, 0);
|
2012-12-27 15:07:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void blo_make_packed_pointer_map(FileData *fd, Main *oldmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Image *ima;
|
|
|
|
|
VFont *vfont;
|
|
|
|
|
bSound *sound;
|
|
|
|
|
Library *lib;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->packedmap = oldnewmap_new();
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ima = oldmain->images.first; ima; ima = ima->id.next) {
|
|
|
|
|
ImagePackedFile *imapf;
|
2015-05-31 18:28:28 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ima->packedfile) {
|
2019-04-17 06:17:24 +02:00
|
|
|
insert_packedmap(fd, ima->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2015-05-31 18:28:28 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
|
|
|
|
|
if (imapf->packedfile) {
|
2019-04-17 06:17:24 +02:00
|
|
|
insert_packedmap(fd, imapf->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (vfont = oldmain->fonts.first; vfont; vfont = vfont->id.next) {
|
|
|
|
|
if (vfont->packedfile) {
|
2019-04-17 06:17:24 +02:00
|
|
|
insert_packedmap(fd, vfont->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (sound = oldmain->sounds.first; sound; sound = sound->id.next) {
|
|
|
|
|
if (sound->packedfile) {
|
2019-04-17 06:17:24 +02:00
|
|
|
insert_packedmap(fd, sound->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
}
|
2012-12-27 15:07:19 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (lib = oldmain->libraries.first; lib; lib = lib->id.next) {
|
|
|
|
|
if (lib->packedfile) {
|
2019-04-17 06:17:24 +02:00
|
|
|
insert_packedmap(fd, lib->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
}
|
2012-12-27 15:07:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set old main packed data to zero if it has been restored */
|
|
|
|
|
/* this works because freeing old main only happens after this call */
|
|
|
|
|
void blo_end_packed_pointer_map(FileData *fd, Main *oldmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Image *ima;
|
|
|
|
|
VFont *vfont;
|
|
|
|
|
bSound *sound;
|
|
|
|
|
Library *lib;
|
|
|
|
|
OldNew *entry = fd->packedmap->entries;
|
|
|
|
|
int i;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* used entries were restored, so we put them to zero */
|
|
|
|
|
for (i = 0; i < fd->packedmap->nentries; i++, entry++) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (entry->nr > 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
entry->newp = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ima = oldmain->images.first; ima; ima = ima->id.next) {
|
|
|
|
|
ImagePackedFile *imapf;
|
2015-05-31 18:28:28 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ima->packedfile = newpackedadr(fd, ima->packedfile);
|
2015-05-31 18:28:28 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
imapf->packedfile = newpackedadr(fd, imapf->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (vfont = oldmain->fonts.first; vfont; vfont = vfont->id.next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
vfont->packedfile = newpackedadr(fd, vfont->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2012-12-27 15:07:19 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (sound = oldmain->sounds.first; sound; sound = sound->id.next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sound->packedfile = newpackedadr(fd, sound->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (lib = oldmain->libraries.first; lib; lib = lib->id.next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
lib->packedfile = newpackedadr(fd, lib->packedfile);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2012-12-27 15:07:19 +00:00
|
|
|
}
|
|
|
|
|
|
2006-11-25 13:07:28 +00:00
|
|
|
/* undo file support: add all library pointers in lookup */
|
Fix T34446: Make Local on linked mesh object: object gets removed if redo function is used.
Root of the issue is that we do not re-read lib data blocks and ID placholders (ID_ID bheads)
in undo context (in `blo_read_file_internal`), because `BLO_read_from_memfile` copies
lib datablocks and Main data directly from oldmain.
The idea being, linked data do not change from undo/redo.
This is valid as long as linked data was not changed by the undo step - but if some
was deleted or localized, it will be missing from oldmain, leading to data loss
(note that does not only concern objects, all linkable data types can be affected,
at least in theory).
This commit addresses that issue by carefully mixing reuse of needed data from oldmain,
and "normal" re-reading of missing one. Makes us swimming in some rather dark waters,
and gives a rather non-easy-to-follow code, but it seems to work quite well,
and only other solution would be to get rid of that optimization
(not re-reading all libs on undo/redo), which is not acceptable.
Also, thanks to @carlosdp for initial investigation of the issue.
Differential Revision: https://developer.blender.org/D1485
2015-10-12 12:15:05 +02:00
|
|
|
void blo_add_library_pointer_map(ListBase *old_mainlist, FileData *fd)
|
2006-11-25 13:07:28 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *ptr = old_mainlist->first;
|
|
|
|
|
ListBase *lbarray[MAX_LIBARRAY];
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ptr = ptr->next; ptr; ptr = ptr->next) {
|
|
|
|
|
int i = set_listbasepointers(ptr, lbarray);
|
|
|
|
|
while (i--) {
|
|
|
|
|
ID *id;
|
2019-04-22 09:13:00 +10:00
|
|
|
for (id = lbarray[i]->first; id; id = id->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(fd->libmap, id, id, GS(id->name));
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
Fix T34446: Make Local on linked mesh object: object gets removed if redo function is used.
Root of the issue is that we do not re-read lib data blocks and ID placholders (ID_ID bheads)
in undo context (in `blo_read_file_internal`), because `BLO_read_from_memfile` copies
lib datablocks and Main data directly from oldmain.
The idea being, linked data do not change from undo/redo.
This is valid as long as linked data was not changed by the undo step - but if some
was deleted or localized, it will be missing from oldmain, leading to data loss
(note that does not only concern objects, all linkable data types can be affected,
at least in theory).
This commit addresses that issue by carefully mixing reuse of needed data from oldmain,
and "normal" re-reading of missing one. Makes us swimming in some rather dark waters,
and gives a rather non-easy-to-follow code, but it seems to work quite well,
and only other solution would be to get rid of that optimization
(not re-reading all libs on undo/redo), which is not acceptable.
Also, thanks to @carlosdp for initial investigation of the issue.
Differential Revision: https://developer.blender.org/D1485
2015-10-12 12:15:05 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->old_mainlist = old_mainlist;
|
2006-11-25 13:07:28 +00:00
|
|
|
}
|
2012-05-17 12:59:34 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
2006-11-25 13:07:28 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name DNA Struct Loading
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2016-07-12 11:48:04 +10:00
|
|
|
static void switch_endian_structs(const struct SDNA *filesdna, BHead *bhead)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int blocksize, nblocks;
|
|
|
|
|
char *data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
data = (char *)(bhead + 1);
|
|
|
|
|
blocksize = filesdna->types_size[filesdna->structs[bhead->SDNAnr][0]];
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
nblocks = bhead->nr;
|
|
|
|
|
while (nblocks--) {
|
|
|
|
|
DNA_struct_switch_endian(filesdna, bhead->SDNAnr, data);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
data += blocksize;
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2010-12-03 17:05:21 +00:00
|
|
|
static void *read_struct(FileData *fd, BHead *bh, const char *blockname)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
void *temp = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bh->len) {
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bh_orig = bh;
|
2019-02-26 14:31:14 +11:00
|
|
|
#endif
|
2019-02-22 14:42:22 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* switch is based on file dna */
|
|
|
|
|
if (bh->SDNAnr && (fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
2019-04-17 06:17:24 +02:00
|
|
|
if (BHEADN_FROM_BHEAD(bh)->has_data == false) {
|
|
|
|
|
bh = blo_bhead_read_full(fd, bh);
|
|
|
|
|
if (UNLIKELY(bh == NULL)) {
|
|
|
|
|
fd->flags &= ~FD_FLAGS_FILE_OK;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-26 14:31:14 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
switch_endian_structs(fd->filesdna, bh);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->compflags[bh->SDNAnr] != SDNA_CMP_REMOVED) {
|
|
|
|
|
if (fd->compflags[bh->SDNAnr] == SDNA_CMP_NOT_EQUAL) {
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
2019-04-17 06:17:24 +02:00
|
|
|
if (BHEADN_FROM_BHEAD(bh)->has_data == false) {
|
|
|
|
|
bh = blo_bhead_read_full(fd, bh);
|
|
|
|
|
if (UNLIKELY(bh == NULL)) {
|
|
|
|
|
fd->flags &= ~FD_FLAGS_FILE_OK;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-22 14:42:22 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
temp = DNA_struct_reconstruct(
|
|
|
|
|
fd->memsdna, fd->filesdna, fd->compflags, bh->SDNAnr, bh->nr, (bh + 1));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* SDNA_CMP_EQUAL */
|
|
|
|
|
temp = MEM_mallocN(bh->len, blockname);
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
2019-04-17 06:17:24 +02:00
|
|
|
if (BHEADN_FROM_BHEAD(bh)->has_data) {
|
|
|
|
|
memcpy(temp, (bh + 1), bh->len);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Instead of allocating the bhead, then copying it,
|
|
|
|
|
* read the data from the file directly into the memory. */
|
|
|
|
|
if (UNLIKELY(!blo_bhead_read_data(fd, bh, temp))) {
|
|
|
|
|
fd->flags &= ~FD_FLAGS_FILE_OK;
|
|
|
|
|
MEM_freeN(temp);
|
|
|
|
|
temp = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-22 14:42:22 +11:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
memcpy(temp, (bh + 1), bh->len);
|
2019-02-22 14:42:22 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-02-22 14:42:22 +11:00
|
|
|
#ifdef USE_BHEAD_READ_ON_DEMAND
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bh_orig != bh) {
|
|
|
|
|
MEM_freeN(BHEADN_FROM_BHEAD(bh));
|
|
|
|
|
}
|
2019-02-22 14:42:22 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return temp;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2015-08-08 19:50:11 +02:00
|
|
|
typedef void (*link_list_cb)(FileData *fd, void *data);
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void link_list_ex(FileData *fd, ListBase *lb, link_list_cb callback) /* only direct data */
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Link *ln, *prev;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (BLI_listbase_is_empty(lb)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lb->first = newdataadr(fd, lb->first);
|
|
|
|
|
if (callback != NULL) {
|
|
|
|
|
callback(fd, lb->first);
|
|
|
|
|
}
|
|
|
|
|
ln = lb->first;
|
|
|
|
|
prev = NULL;
|
|
|
|
|
while (ln) {
|
|
|
|
|
ln->next = newdataadr(fd, ln->next);
|
|
|
|
|
if (ln->next != NULL && callback != NULL) {
|
|
|
|
|
callback(fd, ln->next);
|
|
|
|
|
}
|
|
|
|
|
ln->prev = prev;
|
|
|
|
|
prev = ln;
|
|
|
|
|
ln = ln->next;
|
|
|
|
|
}
|
|
|
|
|
lb->last = prev;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void link_list(FileData *fd, ListBase *lb) /* only direct data */
|
2015-08-08 19:50:11 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list_ex(fd, lb, NULL);
|
2015-08-08 19:50:11 +02:00
|
|
|
}
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void link_glob_list(FileData *fd, ListBase *lb) /* for glob data */
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Link *ln, *prev;
|
|
|
|
|
void *poin;
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (BLI_listbase_is_empty(lb)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
poin = newdataadr(fd, lb->first);
|
|
|
|
|
if (lb->first) {
|
|
|
|
|
oldnewmap_insert(fd->globmap, lb->first, poin, 0);
|
|
|
|
|
}
|
|
|
|
|
lb->first = poin;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ln = lb->first;
|
|
|
|
|
prev = NULL;
|
|
|
|
|
while (ln) {
|
|
|
|
|
poin = newdataadr(fd, ln->next);
|
|
|
|
|
if (ln->next) {
|
|
|
|
|
oldnewmap_insert(fd->globmap, ln->next, poin, 0);
|
|
|
|
|
}
|
|
|
|
|
ln->next = poin;
|
|
|
|
|
ln->prev = prev;
|
|
|
|
|
prev = ln;
|
|
|
|
|
ln = ln->next;
|
|
|
|
|
}
|
|
|
|
|
lb->last = prev;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_pointer_array(FileData *fd, void **mat)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int64_t *lpoin, *lmat;
|
|
|
|
|
int *ipoin, *imat;
|
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
|
|
/* manually convert the pointer array in
|
|
|
|
|
* the old dna format to a pointer array in
|
|
|
|
|
* the new dna format.
|
|
|
|
|
*/
|
|
|
|
|
if (*mat) {
|
|
|
|
|
len = MEM_allocN_len(*mat) / fd->filesdna->pointer_size;
|
|
|
|
|
|
|
|
|
|
if (fd->filesdna->pointer_size == 8 && fd->memsdna->pointer_size == 4) {
|
|
|
|
|
ipoin = imat = MEM_malloc_arrayN(len, 4, "newmatar");
|
|
|
|
|
lpoin = *mat;
|
|
|
|
|
|
|
|
|
|
while (len-- > 0) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if ((fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_endian_switch_int64(lpoin);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
*ipoin = (int)((*lpoin) >> 3);
|
|
|
|
|
ipoin++;
|
|
|
|
|
lpoin++;
|
|
|
|
|
}
|
|
|
|
|
MEM_freeN(*mat);
|
|
|
|
|
*mat = imat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fd->filesdna->pointer_size == 4 && fd->memsdna->pointer_size == 8) {
|
|
|
|
|
lpoin = lmat = MEM_malloc_arrayN(len, 8, "newmatar");
|
|
|
|
|
ipoin = *mat;
|
|
|
|
|
|
|
|
|
|
while (len-- > 0) {
|
|
|
|
|
*lpoin = *ipoin;
|
|
|
|
|
ipoin++;
|
|
|
|
|
lpoin++;
|
|
|
|
|
}
|
|
|
|
|
MEM_freeN(*mat);
|
|
|
|
|
*mat = lmat;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID Properties
|
|
|
|
|
* \{ */
|
2006-11-17 04:46:48 +00:00
|
|
|
|
2010-10-14 00:33:39 +00:00
|
|
|
static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
static void IDP_LibLinkProperty(IDProperty *prop, FileData *fd);
|
2006-11-17 04:46:48 +00:00
|
|
|
|
2008-12-31 13:16:37 +00:00
|
|
|
static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData *fd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
IDProperty *array;
|
|
|
|
|
int i;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* since we didn't save the extra buffer, set totallen to len */
|
|
|
|
|
prop->totallen = prop->len;
|
|
|
|
|
prop->data.pointer = newdataadr(fd, prop->data.pointer);
|
2008-12-31 13:16:37 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
array = (IDProperty *)prop->data.pointer;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* note!, idp-arrays didn't exist in 2.4x, so the pointer will be cleared
|
2019-08-01 13:53:25 +10:00
|
|
|
* there's not really anything we can do to correct this, at least don't crash */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (array == NULL) {
|
|
|
|
|
prop->len = 0;
|
|
|
|
|
prop->totallen = 0;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (i = 0; i < prop->len; i++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_DirectLinkProperty(&array[i], switch_endian, fd);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2008-12-31 13:16:37 +00:00
|
|
|
}
|
|
|
|
|
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *fd)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
IDProperty **array;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* since we didn't save the extra buffer, set totallen to len */
|
|
|
|
|
prop->totallen = prop->len;
|
|
|
|
|
prop->data.pointer = newdataadr(fd, prop->data.pointer);
|
|
|
|
|
|
|
|
|
|
if (prop->subtype == IDP_GROUP) {
|
|
|
|
|
test_pointer_array(fd, prop->data.pointer);
|
|
|
|
|
array = prop->data.pointer;
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (i = 0; i < prop->len; i++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_DirectLinkProperty(array[i], switch_endian, fd);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else if (prop->subtype == IDP_DOUBLE) {
|
|
|
|
|
if (switch_endian) {
|
|
|
|
|
BLI_endian_switch_double_array(prop->data.pointer, prop->len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (switch_endian) {
|
|
|
|
|
/* also used for floats */
|
|
|
|
|
BLI_endian_switch_int32_array(prop->data.pointer, prop->len);
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void IDP_DirectLinkString(IDProperty *prop, FileData *fd)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/*since we didn't save the extra string buffer, set totallen to len.*/
|
|
|
|
|
prop->totallen = prop->len;
|
|
|
|
|
prop->data.pointer = newdataadr(fd, prop->data.pointer);
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
static void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, FileData *fd)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *lb = &prop->data.group;
|
|
|
|
|
IDProperty *loop;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, lb);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/*Link child id properties now*/
|
|
|
|
|
for (loop = prop->data.group.first; loop; loop = loop->next) {
|
|
|
|
|
IDP_DirectLinkProperty(loop, switch_endian, fd);
|
|
|
|
|
}
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
2011-02-13 10:52:18 +00:00
|
|
|
static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
switch (prop->type) {
|
|
|
|
|
case IDP_GROUP:
|
|
|
|
|
IDP_DirectLinkGroup(prop, switch_endian, fd);
|
|
|
|
|
break;
|
|
|
|
|
case IDP_STRING:
|
|
|
|
|
IDP_DirectLinkString(prop, fd);
|
|
|
|
|
break;
|
|
|
|
|
case IDP_ARRAY:
|
|
|
|
|
IDP_DirectLinkArray(prop, switch_endian, fd);
|
|
|
|
|
break;
|
|
|
|
|
case IDP_IDPARRAY:
|
|
|
|
|
IDP_DirectLinkIDPArray(prop, switch_endian, fd);
|
|
|
|
|
break;
|
|
|
|
|
case IDP_DOUBLE:
|
|
|
|
|
/* erg, stupid doubles. since I'm storing them
|
|
|
|
|
* in the same field as int val; val2 in the
|
|
|
|
|
* IDPropertyData struct, they have to deal with
|
|
|
|
|
* endianness specifically
|
|
|
|
|
*
|
|
|
|
|
* in theory, val and val2 would've already been swapped
|
|
|
|
|
* if switch_endian is true, so we have to first unswap
|
|
|
|
|
* them then reswap them as a single 64-bit entity.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (switch_endian) {
|
|
|
|
|
BLI_endian_switch_int32(&prop->data.val);
|
|
|
|
|
BLI_endian_switch_int32(&prop->data.val2);
|
|
|
|
|
BLI_endian_switch_int64((int64_t *)&prop->data.val);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case IDP_INT:
|
|
|
|
|
case IDP_FLOAT:
|
|
|
|
|
case IDP_ID:
|
|
|
|
|
break; /* Nothing special to do here. */
|
|
|
|
|
default:
|
|
|
|
|
/* Unknown IDP type, nuke it (we cannot handle unknown types everywhere in code,
|
|
|
|
|
* IDP are way too polymorphic to do it safely. */
|
|
|
|
|
printf(
|
|
|
|
|
"%s: found unknown IDProperty type %d, reset to Integer one !\n", __func__, prop->type);
|
|
|
|
|
/* Note: we do not attempt to free unknown prop, we have no way to know how to do that! */
|
|
|
|
|
prop->type = IDP_INT;
|
|
|
|
|
prop->subtype = 0;
|
|
|
|
|
IDP_Int(prop) = 0;
|
|
|
|
|
}
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-30 13:44:16 +00:00
|
|
|
#define IDP_DirectLinkGroup_OrFree(prop, switch_endian, fd) \
|
2019-04-17 06:17:24 +02:00
|
|
|
_IDP_DirectLinkGroup_OrFree(prop, switch_endian, fd, __func__)
|
|
|
|
|
|
|
|
|
|
static void _IDP_DirectLinkGroup_OrFree(IDProperty **prop,
|
|
|
|
|
int switch_endian,
|
|
|
|
|
FileData *fd,
|
|
|
|
|
const char *caller_func_id)
|
|
|
|
|
{
|
|
|
|
|
if (*prop) {
|
|
|
|
|
if ((*prop)->type == IDP_GROUP) {
|
|
|
|
|
IDP_DirectLinkGroup(*prop, switch_endian, fd);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* corrupt file! */
|
|
|
|
|
printf("%s: found non group data, freeing type %d!\n", caller_func_id, (*prop)->type);
|
|
|
|
|
/* don't risk id, data's likely corrupt. */
|
2019-05-16 14:11:11 +02:00
|
|
|
// IDP_FreePropertyContent(*prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
*prop = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-09-30 13:44:16 +00:00
|
|
|
}
|
|
|
|
|
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
static void IDP_LibLinkProperty(IDProperty *prop, FileData *fd)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!prop) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
switch (prop->type) {
|
|
|
|
|
case IDP_ID: /* PointerProperty */
|
|
|
|
|
{
|
|
|
|
|
void *newaddr = newlibadr_us(fd, NULL, IDP_Id(prop));
|
|
|
|
|
if (IDP_Id(prop) && !newaddr && G.debug) {
|
|
|
|
|
printf("Error while loading \"%s\". Data not found in file!\n", prop->name);
|
|
|
|
|
}
|
|
|
|
|
prop->data.pointer = newaddr;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case IDP_IDPARRAY: /* CollectionProperty */
|
|
|
|
|
{
|
|
|
|
|
IDProperty *idp_array = IDP_IDPArray(prop);
|
|
|
|
|
for (int i = 0; i < prop->len; i++) {
|
|
|
|
|
IDP_LibLinkProperty(&(idp_array[i]), fd);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case IDP_GROUP: /* PointerProperty */
|
|
|
|
|
{
|
|
|
|
|
for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) {
|
|
|
|
|
IDP_LibLinkProperty(loop, fd);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break; /* Nothing to do for other IDProps. */
|
|
|
|
|
}
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read Image Preview
|
|
|
|
|
* \{ */
|
2015-08-10 15:41:28 +02:00
|
|
|
|
|
|
|
|
static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_prv)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
PreviewImage *prv = newdataadr(fd, old_prv);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (prv) {
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < NUM_ICON_SIZES; ++i) {
|
|
|
|
|
if (prv->rect[i]) {
|
|
|
|
|
prv->rect[i] = newdataadr(fd, prv->rect[i]);
|
|
|
|
|
}
|
|
|
|
|
prv->gputexture[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
prv->icon_id = 0;
|
|
|
|
|
prv->tag = 0;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return prv;
|
2015-08-10 15:41:28 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID
|
|
|
|
|
* \{ */
|
2012-10-23 12:38:47 +00:00
|
|
|
|
2017-11-29 15:05:03 +01:00
|
|
|
static void lib_link_id(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *lbarray[MAX_LIBARRAY];
|
|
|
|
|
int base_count, i;
|
2017-11-29 15:05:03 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
base_count = set_listbasepointers(main, lbarray);
|
2017-11-29 15:05:03 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (i = 0; i < base_count; i++) {
|
|
|
|
|
ListBase *lb = lbarray[i];
|
|
|
|
|
ID *id;
|
2017-11-29 15:05:03 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (id = lb->first; id; id = id->next) {
|
2019-06-14 23:16:04 +02:00
|
|
|
if (id->override_library) {
|
|
|
|
|
id->override_library->reference = newlibadr_us(
|
|
|
|
|
fd, id->lib, id->override_library->reference);
|
|
|
|
|
id->override_library->storage = newlibadr_us(fd, id->lib, id->override_library->storage);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-29 15:05:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_id_override_property_operation_cb(FileData *fd, void *data)
|
|
|
|
|
{
|
2019-06-14 23:16:04 +02:00
|
|
|
IDOverrideLibraryPropertyOperation *opop = data;
|
2017-11-29 15:05:03 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
opop->subitem_reference_name = newdataadr(fd, opop->subitem_reference_name);
|
|
|
|
|
opop->subitem_local_name = newdataadr(fd, opop->subitem_local_name);
|
2017-11-29 15:05:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_id_override_property_cb(FileData *fd, void *data)
|
|
|
|
|
{
|
2019-06-14 23:16:04 +02:00
|
|
|
IDOverrideLibraryProperty *op = data;
|
2017-11-29 15:05:03 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
op->rna_path = newdataadr(fd, op->rna_path);
|
|
|
|
|
link_list_ex(fd, &op->operations, direct_link_id_override_property_operation_cb);
|
2017-11-29 15:05:03 +01:00
|
|
|
}
|
|
|
|
|
|
2012-10-23 12:38:47 +00:00
|
|
|
static void direct_link_id(FileData *fd, ID *id)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/*link direct data of ID properties*/
|
|
|
|
|
if (id->properties) {
|
|
|
|
|
id->properties = newdataadr(fd, id->properties);
|
|
|
|
|
/* this case means the data was written incorrectly, it should not happen */
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
}
|
|
|
|
|
id->py_instance = NULL;
|
2017-11-29 15:05:03 +01:00
|
|
|
|
2019-06-17 12:51:53 +10:00
|
|
|
/* That way data-lock reading not going through main read_libblock()
|
2019-04-22 01:10:29 +10:00
|
|
|
* function are still in a clear tag state.
|
2019-06-17 12:51:53 +10:00
|
|
|
* (glowering at certain nodetree fake data-lock here...). */
|
2019-04-17 06:17:24 +02:00
|
|
|
id->tag = 0;
|
2018-04-04 12:00:57 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Link direct data of overrides. */
|
2019-06-14 23:16:04 +02:00
|
|
|
if (id->override_library) {
|
|
|
|
|
id->override_library = newdataadr(fd, id->override_library);
|
|
|
|
|
link_list_ex(fd, &id->override_library->properties, direct_link_id_override_property_cb);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
|
|
|
|
|
if (drawdata) {
|
|
|
|
|
BLI_listbase_clear((ListBase *)drawdata);
|
|
|
|
|
}
|
2012-10-23 12:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read CurveMapping
|
|
|
|
|
* \{ */
|
2009-01-07 04:38:30 +00:00
|
|
|
|
|
|
|
|
/* cuma itself has been read! */
|
|
|
|
|
static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int a;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* flag seems to be able to hang? Maybe old files... not bad to clear anyway */
|
|
|
|
|
cumap->flag &= ~CUMA_PREMULLED;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (a = 0; a < CM_TOT; a++) {
|
|
|
|
|
cumap->cm[a].curve = newdataadr(fd, cumap->cm[a].curve);
|
|
|
|
|
cumap->cm[a].table = NULL;
|
|
|
|
|
cumap->cm[a].premultable = NULL;
|
|
|
|
|
}
|
2009-01-07 04:38:30 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Brush
|
|
|
|
|
* \{ */
|
2018-07-31 10:22:19 +02:00
|
|
|
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
/* library brush linking after fileread */
|
|
|
|
|
static void lib_link_brush(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* only link ID pointers */
|
|
|
|
|
for (Brush *brush = main->brushes.first; brush; brush = brush->id.next) {
|
|
|
|
|
if (brush->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(brush->id.properties, fd);
|
|
|
|
|
|
|
|
|
|
/* brush->(mask_)mtex.obj is ignored on purpose? */
|
|
|
|
|
brush->mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mtex.tex);
|
|
|
|
|
brush->mask_mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mask_mtex.tex);
|
|
|
|
|
brush->clone.image = newlibadr(fd, brush->id.lib, brush->clone.image);
|
|
|
|
|
brush->toggle_brush = newlibadr(fd, brush->id.lib, brush->toggle_brush);
|
|
|
|
|
brush->paint_curve = newlibadr_us(fd, brush->id.lib, brush->paint_curve);
|
|
|
|
|
|
|
|
|
|
/* link default grease pencil palette */
|
|
|
|
|
if (brush->gpencil_settings != NULL) {
|
|
|
|
|
if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
|
|
|
|
|
brush->gpencil_settings->material = newlibadr_us(
|
|
|
|
|
fd, brush->id.lib, brush->gpencil_settings->material);
|
|
|
|
|
|
|
|
|
|
if (!brush->gpencil_settings->material) {
|
|
|
|
|
brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
brush->gpencil_settings->material = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
brush->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_brush(FileData *fd, Brush *brush)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* brush itself has been read */
|
2009-01-07 04:38:30 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* fallof curve */
|
|
|
|
|
brush->curve = newdataadr(fd, brush->curve);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
brush->gradient = newdataadr(fd, brush->gradient);
|
2014-07-21 12:02:05 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (brush->curve) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, brush->curve);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_brush_curve_preset(brush, CURVE_PRESET_SHARP);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2010-07-20 19:39:07 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* grease pencil */
|
|
|
|
|
brush->gpencil_settings = newdataadr(fd, brush->gpencil_settings);
|
|
|
|
|
if (brush->gpencil_settings != NULL) {
|
|
|
|
|
brush->gpencil_settings->curve_sensitivity = newdataadr(
|
|
|
|
|
fd, brush->gpencil_settings->curve_sensitivity);
|
|
|
|
|
brush->gpencil_settings->curve_strength = newdataadr(fd,
|
|
|
|
|
brush->gpencil_settings->curve_strength);
|
|
|
|
|
brush->gpencil_settings->curve_jitter = newdataadr(fd, brush->gpencil_settings->curve_jitter);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (brush->gpencil_settings->curve_sensitivity) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, brush->gpencil_settings->curve_sensitivity);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (brush->gpencil_settings->curve_strength) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, brush->gpencil_settings->curve_strength);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (brush->gpencil_settings->curve_jitter) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, brush->gpencil_settings->curve_jitter);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
brush->preview = NULL;
|
|
|
|
|
brush->icon_imbuf = NULL;
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Palette
|
|
|
|
|
* \{ */
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2017-03-28 10:03:59 +02:00
|
|
|
static void lib_link_palette(FileData *fd, Main *main)
|
2014-07-21 12:02:05 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* only link ID pointers */
|
|
|
|
|
for (Palette *palette = main->palettes.first; palette; palette = palette->id.next) {
|
|
|
|
|
if (palette->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(palette->id.properties, fd);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
palette->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-07-21 12:02:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_palette(FileData *fd, Palette *palette)
|
|
|
|
|
{
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* palette itself has been read */
|
|
|
|
|
link_list(fd, &palette->colors);
|
2014-07-21 12:02:05 +02:00
|
|
|
}
|
|
|
|
|
|
2017-03-28 10:03:59 +02:00
|
|
|
static void lib_link_paint_curve(FileData *fd, Main *main)
|
2014-07-21 12:02:05 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* only link ID pointers */
|
|
|
|
|
for (PaintCurve *pc = main->paintcurves.first; pc; pc = pc->id.next) {
|
|
|
|
|
if (pc->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(pc->id.properties, fd);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
pc->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-07-21 12:02:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_paint_curve(FileData *fd, PaintCurve *pc)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
pc->points = newdataadr(fd, pc->points);
|
2014-07-21 12:02:05 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read PackedFile
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
PackedFile *pf = newpackedadr(fd, oldpf);
|
2015-06-01 13:09:45 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (pf) {
|
|
|
|
|
pf->data = newpackedadr(fd, pf->data);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return pf;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read Animation (legacy for version patching)
|
|
|
|
|
* \{ */
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2012-09-26 20:05:38 +00:00
|
|
|
// XXX deprecated - old animation system
|
2009-01-19 02:26:46 +00:00
|
|
|
static void lib_link_ipo(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Ipo *ipo;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ipo = main->ipo.first; ipo; ipo = ipo->id.next) {
|
|
|
|
|
if (ipo->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IpoCurve *icu;
|
|
|
|
|
for (icu = ipo->curve.first; icu; icu = icu->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (icu->driver) {
|
2019-04-17 06:17:24 +02:00
|
|
|
icu->driver->ob = newlibadr(fd, ipo->id.lib, icu->driver->ob);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
ipo->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-26 20:05:38 +00:00
|
|
|
// XXX deprecated - old animation system
|
2009-01-19 02:26:46 +00:00
|
|
|
static void direct_link_ipo(FileData *fd, Ipo *ipo)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
IpoCurve *icu;
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &(ipo->curve));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (icu = ipo->curve.first; icu; icu = icu->next) {
|
|
|
|
|
icu->bezt = newdataadr(fd, icu->bezt);
|
|
|
|
|
icu->bp = newdataadr(fd, icu->bp);
|
|
|
|
|
icu->driver = newdataadr(fd, icu->driver);
|
|
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2012-09-26 20:05:38 +00:00
|
|
|
// XXX deprecated - old animation system
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bActionStrip *strip;
|
|
|
|
|
bActionModifier *amod;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (strip = striplist->first; strip; strip = strip->next) {
|
|
|
|
|
strip->object = newlibadr(fd, id->lib, strip->object);
|
|
|
|
|
strip->act = newlibadr_us(fd, id->lib, strip->act);
|
|
|
|
|
strip->ipo = newlibadr(fd, id->lib, strip->ipo);
|
2019-04-22 09:13:00 +10:00
|
|
|
for (amod = strip->modifiers.first; amod; amod = amod->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
amod->ob = newlibadr(fd, id->lib, amod->ob);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-26 20:05:38 +00:00
|
|
|
// XXX deprecated - old animation system
|
2009-01-19 02:26:46 +00:00
|
|
|
static void direct_link_nlastrips(FileData *fd, ListBase *strips)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bActionStrip *strip;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, strips);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (strip = strips->first; strip; strip = strip->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &strip->modifiers);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-26 20:05:38 +00:00
|
|
|
// XXX deprecated - old animation system
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbase)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bConstraintChannel *chan;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (chan = chanbase->first; chan; chan = chan->next) {
|
|
|
|
|
chan->ipo = newlibadr_us(fd, id->lib, chan->ipo);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Action
|
|
|
|
|
* \{ */
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2009-05-22 11:19:35 +00:00
|
|
|
static void lib_link_fmodifiers(FileData *fd, ID *id, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FModifier *fcm;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (fcm = list->first; fcm; fcm = fcm->next) {
|
|
|
|
|
/* data for specific modifiers */
|
|
|
|
|
switch (fcm->type) {
|
|
|
|
|
case FMODIFIER_TYPE_PYTHON: {
|
|
|
|
|
FMod_Python *data = (FMod_Python *)fcm->data;
|
|
|
|
|
data->script = newlibadr(fd, id->lib, data->script);
|
2015-07-18 19:02:39 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-05-22 11:19:35 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-17 17:06:07 +02:00
|
|
|
static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
|
2009-01-19 02:26:46 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FCurve *fcu;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (list == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink ID-block references... */
|
|
|
|
|
for (fcu = list->first; fcu; fcu = fcu->next) {
|
|
|
|
|
/* driver data */
|
|
|
|
|
if (fcu->driver) {
|
|
|
|
|
ChannelDriver *driver = fcu->driver;
|
|
|
|
|
DriverVar *dvar;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
|
|
|
|
|
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
|
|
|
|
|
/* only relink if still used */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (tarIndex < dvar->num_targets) {
|
2019-04-17 06:17:24 +02:00
|
|
|
dtar->id = newlibadr(fd, id->lib, dtar->id);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
dtar->id = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
DRIVER_TARGETS_LOOPER_END;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* modifiers */
|
|
|
|
|
lib_link_fmodifiers(fd, id, &fcu->modifiers);
|
|
|
|
|
}
|
2009-05-22 11:19:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* NOTE: this assumes that link_list has already been called on the list */
|
2017-10-17 19:39:10 +03:00
|
|
|
static void direct_link_fmodifiers(FileData *fd, ListBase *list, FCurve *curve)
|
2009-05-22 11:19:35 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FModifier *fcm;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (fcm = list->first; fcm; fcm = fcm->next) {
|
|
|
|
|
/* relink general data */
|
|
|
|
|
fcm->data = newdataadr(fd, fcm->data);
|
|
|
|
|
fcm->curve = curve;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* do relinking of data for specific types */
|
|
|
|
|
switch (fcm->type) {
|
|
|
|
|
case FMODIFIER_TYPE_GENERATOR: {
|
|
|
|
|
FMod_Generator *data = (FMod_Generator *)fcm->data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
data->coefficients = newdataadr(fd, data->coefficients);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
BLI_endian_switch_float_array(data->coefficients, data->arraysize);
|
|
|
|
|
}
|
2015-07-18 19:02:39 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FMODIFIER_TYPE_ENVELOPE: {
|
|
|
|
|
FMod_Envelope *data = (FMod_Envelope *)fcm->data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
data->data = newdataadr(fd, data->data);
|
2015-07-18 19:02:39 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FMODIFIER_TYPE_PYTHON: {
|
|
|
|
|
FMod_Python *data = (FMod_Python *)fcm->data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
data->prop = newdataadr(fd, data->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
2015-07-18 19:02:39 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-22 10:53:22 +00:00
|
|
|
/* NOTE: this assumes that link_list has already been called on the list */
|
2009-01-19 02:26:46 +00:00
|
|
|
static void direct_link_fcurves(FileData *fd, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FCurve *fcu;
|
|
|
|
|
|
|
|
|
|
/* link F-Curve data to F-Curve again (non ID-libs) */
|
|
|
|
|
for (fcu = list->first; fcu; fcu = fcu->next) {
|
|
|
|
|
/* curve data */
|
|
|
|
|
fcu->bezt = newdataadr(fd, fcu->bezt);
|
|
|
|
|
fcu->fpt = newdataadr(fd, fcu->fpt);
|
|
|
|
|
|
|
|
|
|
/* rna path */
|
|
|
|
|
fcu->rna_path = newdataadr(fd, fcu->rna_path);
|
|
|
|
|
|
|
|
|
|
/* group */
|
|
|
|
|
fcu->grp = newdataadr(fd, fcu->grp);
|
|
|
|
|
|
|
|
|
|
/* clear disabled flag - allows disabled drivers to be tried again ([#32155]),
|
|
|
|
|
* but also means that another method for "reviving disabled F-Curves" exists
|
|
|
|
|
*/
|
|
|
|
|
fcu->flag &= ~FCURVE_DISABLED;
|
|
|
|
|
|
|
|
|
|
/* driver */
|
|
|
|
|
fcu->driver = newdataadr(fd, fcu->driver);
|
|
|
|
|
if (fcu->driver) {
|
|
|
|
|
ChannelDriver *driver = fcu->driver;
|
|
|
|
|
DriverVar *dvar;
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Compiled expression data will need to be regenerated
|
|
|
|
|
* (old pointer may still be set here). */
|
2019-04-17 06:17:24 +02:00
|
|
|
driver->expr_comp = NULL;
|
|
|
|
|
driver->expr_simple = NULL;
|
|
|
|
|
|
|
|
|
|
/* give the driver a fresh chance - the operating environment may be different now
|
|
|
|
|
* (addons, etc. may be different) so the driver namespace may be sane now [#32155]
|
|
|
|
|
*/
|
|
|
|
|
driver->flag &= ~DRIVER_FLAG_INVALID;
|
|
|
|
|
|
|
|
|
|
/* relink variables, targets and their paths */
|
|
|
|
|
link_list(fd, &driver->variables);
|
|
|
|
|
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
|
|
|
|
|
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
|
|
|
|
|
/* only relink the targets being used */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (tarIndex < dvar->num_targets) {
|
2019-04-17 06:17:24 +02:00
|
|
|
dtar->rna_path = newdataadr(fd, dtar->rna_path);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
dtar->rna_path = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
DRIVER_TARGETS_LOOPER_END;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* modifiers */
|
|
|
|
|
link_list(fd, &fcu->modifiers);
|
|
|
|
|
direct_link_fmodifiers(fd, &fcu->modifiers, fcu);
|
|
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_action(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bAction *act = main->actions.first; act; act = act->id.next) {
|
|
|
|
|
if (act->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(act->id.properties, fd);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
// XXX deprecated - old animation system <<<
|
|
|
|
|
for (bActionChannel *chan = act->chanbase.first; chan; chan = chan->next) {
|
|
|
|
|
chan->ipo = newlibadr_us(fd, act->id.lib, chan->ipo);
|
|
|
|
|
lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels);
|
|
|
|
|
}
|
|
|
|
|
// >>> XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_fcurves(fd, &act->id, &act->curves);
|
2016-09-30 10:11:29 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) {
|
|
|
|
|
if (marker->camera) {
|
|
|
|
|
marker->camera = newlibadr(fd, act->id.lib, marker->camera);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
act->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_action(FileData *fd, bAction *act)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bActionChannel *achan; // XXX deprecated - old animation system
|
|
|
|
|
bActionGroup *agrp;
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &act->curves);
|
|
|
|
|
link_list(fd, &act->chanbase); // XXX deprecated - old animation system
|
|
|
|
|
link_list(fd, &act->groups);
|
|
|
|
|
link_list(fd, &act->markers);
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
// XXX deprecated - old animation system <<<
|
|
|
|
|
for (achan = act->chanbase.first; achan; achan = achan->next) {
|
|
|
|
|
achan->grp = newdataadr(fd, achan->grp);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &achan->constraintChannels);
|
|
|
|
|
}
|
|
|
|
|
// >>> XXX deprecated - old animation system
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_fcurves(fd, &act->curves);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
|
|
|
|
|
agrp->channels.first = newdataadr(fd, agrp->channels.first);
|
|
|
|
|
agrp->channels.last = newdataadr(fd, agrp->channels.last);
|
|
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2009-07-06 03:44:44 +00:00
|
|
|
static void lib_link_nladata_strips(FileData *fd, ID *id, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
NlaStrip *strip;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (strip = list->first; strip; strip = strip->next) {
|
|
|
|
|
/* check strip's children */
|
|
|
|
|
lib_link_nladata_strips(fd, id, &strip->strips);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* check strip's F-Curves */
|
|
|
|
|
lib_link_fcurves(fd, id, &strip->fcurves);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* reassign the counted-reference to action */
|
|
|
|
|
strip->act = newlibadr_us(fd, id->lib, strip->act);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* fix action id-root (i.e. if it comes from a pre 2.57 .blend file) */
|
2019-04-22 09:13:00 +10:00
|
|
|
if ((strip->act) && (strip->act->idroot == 0)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
strip->act->idroot = GS(id->name);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-07-06 03:44:44 +00:00
|
|
|
}
|
2009-05-22 11:19:35 +00:00
|
|
|
|
2009-07-06 03:44:44 +00:00
|
|
|
static void lib_link_nladata(FileData *fd, ID *id, ListBase *list)
|
2009-05-22 11:19:35 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
NlaTrack *nlt;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* we only care about the NLA strips inside the tracks */
|
|
|
|
|
for (nlt = list->first; nlt; nlt = nlt->next) {
|
|
|
|
|
lib_link_nladata_strips(fd, id, &nlt->strips);
|
|
|
|
|
}
|
2009-07-06 03:44:44 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-17 17:06:07 +02:00
|
|
|
/* This handles Animato NLA-Strips linking
|
2018-06-01 18:19:39 +02:00
|
|
|
* NOTE: this assumes that link_list has already been called on the list
|
2009-07-06 03:44:44 +00:00
|
|
|
*/
|
|
|
|
|
static void direct_link_nladata_strips(FileData *fd, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
NlaStrip *strip;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (strip = list->first; strip; strip = strip->next) {
|
|
|
|
|
/* strip's child strips */
|
|
|
|
|
link_list(fd, &strip->strips);
|
|
|
|
|
direct_link_nladata_strips(fd, &strip->strips);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* strip's F-Curves */
|
|
|
|
|
link_list(fd, &strip->fcurves);
|
|
|
|
|
direct_link_fcurves(fd, &strip->fcurves);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* strip's F-Modifiers */
|
|
|
|
|
link_list(fd, &strip->modifiers);
|
|
|
|
|
direct_link_fmodifiers(fd, &strip->modifiers, NULL);
|
|
|
|
|
}
|
2009-05-22 11:19:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* NOTE: this assumes that link_list has already been called on the list */
|
|
|
|
|
static void direct_link_nladata(FileData *fd, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
NlaTrack *nlt;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (nlt = list->first; nlt; nlt = nlt->next) {
|
|
|
|
|
/* relink list of strips */
|
|
|
|
|
link_list(fd, &nlt->strips);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink strip data */
|
|
|
|
|
direct_link_nladata_strips(fd, &nlt->strips);
|
|
|
|
|
}
|
2009-05-22 11:19:35 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-19 02:26:46 +00:00
|
|
|
/* ------- */
|
|
|
|
|
|
2009-02-11 12:19:42 +00:00
|
|
|
static void lib_link_keyingsets(FileData *fd, ID *id, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
KeyingSet *ks;
|
|
|
|
|
KS_Path *ksp;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* here, we're only interested in the ID pointer stored in some of the paths */
|
|
|
|
|
for (ks = list->first; ks; ks = ks->next) {
|
|
|
|
|
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
|
|
|
|
|
ksp->id = newlibadr(fd, id->lib, ksp->id);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-11 12:19:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* NOTE: this assumes that link_list has already been called on the list */
|
|
|
|
|
static void direct_link_keyingsets(FileData *fd, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
KeyingSet *ks;
|
|
|
|
|
KS_Path *ksp;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* link KeyingSet data to KeyingSet again (non ID-libs) */
|
|
|
|
|
for (ks = list->first; ks; ks = ks->next) {
|
|
|
|
|
/* paths */
|
|
|
|
|
link_list(fd, &ks->paths);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
|
|
|
|
|
/* rna path */
|
|
|
|
|
ksp->rna_path = newdataadr(fd, ksp->rna_path);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-11 12:19:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------- */
|
|
|
|
|
|
2009-01-19 02:26:46 +00:00
|
|
|
static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt)
|
|
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (adt == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* link action data */
|
|
|
|
|
adt->action = newlibadr_us(fd, id->lib, adt->action);
|
|
|
|
|
adt->tmpact = newlibadr_us(fd, id->lib, adt->tmpact);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* fix action id-roots (i.e. if they come from a pre 2.57 .blend file) */
|
2019-04-22 09:13:00 +10:00
|
|
|
if ((adt->action) && (adt->action->idroot == 0)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
adt->action->idroot = GS(id->name);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if ((adt->tmpact) && (adt->tmpact->idroot == 0)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
adt->tmpact->idroot = GS(id->name);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* link drivers */
|
|
|
|
|
lib_link_fcurves(fd, id, &adt->drivers);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* overrides don't have lib-link for now, so no need to do anything */
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* link NLA-data */
|
|
|
|
|
lib_link_nladata(fd, id, &adt->nla_tracks);
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_animdata(FileData *fd, AnimData *adt)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* NOTE: must have called newdataadr already before doing this... */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (adt == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* link drivers */
|
|
|
|
|
link_list(fd, &adt->drivers);
|
|
|
|
|
direct_link_fcurves(fd, &adt->drivers);
|
|
|
|
|
adt->driver_array = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* link overrides */
|
|
|
|
|
// TODO...
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* link NLA-data */
|
|
|
|
|
link_list(fd, &adt->nla_tracks);
|
|
|
|
|
direct_link_nladata(fd, &adt->nla_tracks);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink active track/strip - even though strictly speaking this should only be used
|
|
|
|
|
* if we're in 'tweaking mode', we need to be able to have this loaded back for
|
|
|
|
|
* undo, but also since users may not exit tweakmode before saving (#24535)
|
|
|
|
|
*/
|
|
|
|
|
// TODO: it's not really nice that anyone should be able to save the file in this
|
|
|
|
|
// state, but it's going to be too hard to enforce this single case...
|
|
|
|
|
adt->act_track = newdataadr(fd, adt->act_track);
|
|
|
|
|
adt->actstrip = newdataadr(fd, adt->actstrip);
|
2018-06-17 17:06:07 +02:00
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: CacheFiles
|
|
|
|
|
* \{ */
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
|
|
|
|
static void lib_link_cachefiles(FileData *fd, Main *bmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* only link ID pointers */
|
|
|
|
|
for (CacheFile *cache_file = bmain->cachefiles.first; cache_file;
|
|
|
|
|
cache_file = cache_file->id.next) {
|
|
|
|
|
if (cache_file->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(cache_file->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &cache_file->id, cache_file->adt);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
cache_file->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_cachefile(FileData *fd, CacheFile *cache_file)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&cache_file->object_paths);
|
|
|
|
|
cache_file->handle = NULL;
|
2019-04-04 15:07:37 +02:00
|
|
|
cache_file->handle_filepath[0] = '\0';
|
|
|
|
|
cache_file->handle_readers = NULL;
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink animdata */
|
|
|
|
|
cache_file->adt = newdataadr(fd, cache_file->adt);
|
|
|
|
|
direct_link_animdata(fd, cache_file->adt);
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: WorkSpace
|
|
|
|
|
* \{ */
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
|
|
|
|
static void lib_link_workspaces(FileData *fd, Main *bmain)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
|
|
|
|
|
ListBase *layouts = BKE_workspace_layouts_get(workspace);
|
|
|
|
|
ID *id = (ID *)workspace;
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if ((id->tag & LIB_TAG_NEED_LINK) == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
IDP_LibLinkProperty(id->properties, fd);
|
|
|
|
|
id_us_ensure_real(id);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) {
|
|
|
|
|
layout->screen = newlibadr_us(fd, id->lib, layout->screen);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
layout_next = layout->next;
|
|
|
|
|
if (layout->screen) {
|
|
|
|
|
if (ID_IS_LINKED(id)) {
|
|
|
|
|
layout->screen->winid = 0;
|
|
|
|
|
if (layout->screen->temp) {
|
|
|
|
|
/* delete temp layouts when appending */
|
|
|
|
|
BKE_workspace_layout_remove(bmain, workspace, layout);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
id->tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, BKE_workspace_layouts_get(workspace));
|
|
|
|
|
link_list(fd, &workspace->hook_layout_relations);
|
|
|
|
|
link_list(fd, &workspace->owner_ids);
|
|
|
|
|
link_list(fd, &workspace->tools);
|
|
|
|
|
|
|
|
|
|
for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first; relation;
|
|
|
|
|
relation = relation->next) {
|
|
|
|
|
relation->parent = newglobadr(
|
|
|
|
|
fd, relation->parent); /* data from window - need to access through global oldnew-map */
|
|
|
|
|
relation->value = newdataadr(fd, relation->value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Same issue/fix as in direct_link_workspace_link_scene_data: Can't read workspace data
|
|
|
|
|
* when reading windows, so have to update windows after/when reading workspaces. */
|
|
|
|
|
for (wmWindowManager *wm = main->wm.first; wm; wm = wm->id.next) {
|
|
|
|
|
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
|
|
|
|
WorkSpaceLayout *act_layout = newdataadr(
|
|
|
|
|
fd, BKE_workspace_active_layout_get(win->workspace_hook));
|
|
|
|
|
if (act_layout) {
|
|
|
|
|
BKE_workspace_active_layout_set(win->workspace_hook, act_layout);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) {
|
|
|
|
|
tref->runtime = NULL;
|
|
|
|
|
tref->properties = newdataadr(fd, tref->properties);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&tref->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
workspace->status_text = NULL;
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_workspace_instance_hook(FileData *fd, WorkSpaceInstanceHook *hook, ID *id)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
WorkSpace *workspace = BKE_workspace_active_get(hook);
|
|
|
|
|
BKE_workspace_active_set(hook, newlibadr(fd, id->lib, workspace));
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Node Tree
|
|
|
|
|
* \{ */
|
2009-02-20 16:39:39 +00:00
|
|
|
|
2016-07-14 18:16:05 +02:00
|
|
|
/* Single node tree (also used for material/scene trees), ntree is not NULL */
|
2009-02-20 16:39:39 +00:00
|
|
|
static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(ntree->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &ntree->id, ntree->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ntree->gpd = newlibadr_us(fd, id->lib, ntree->gpd);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-20 20:25:20 +02:00
|
|
|
for (bNode *node = ntree->nodes.first; node; node = node->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
|
|
|
|
|
* of library blocks that implement this.*/
|
|
|
|
|
IDP_LibLinkProperty(node->prop, fd);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
node->id = newlibadr_us(fd, id->lib, node->id);
|
2013-03-18 16:34:57 +00:00
|
|
|
|
2019-04-20 20:25:20 +02:00
|
|
|
for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(sock->prop, fd);
|
|
|
|
|
}
|
2019-04-20 20:25:20 +02:00
|
|
|
for (bNodeSocket *sock = node->outputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(sock->prop, fd);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-20 20:25:20 +02:00
|
|
|
for (bNodeSocket *sock = ntree->inputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(sock->prop, fd);
|
|
|
|
|
}
|
2019-04-20 20:25:20 +02:00
|
|
|
for (bNodeSocket *sock = ntree->outputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(sock->prop, fd);
|
|
|
|
|
}
|
2019-04-20 20:25:20 +02:00
|
|
|
|
|
|
|
|
/* Set node->typeinfo pointers. This is done in lib linking, after the
|
|
|
|
|
* first versioning that can change types still without functions that
|
|
|
|
|
* update the typeinfo pointers. Versioning after lib linking needs
|
|
|
|
|
* these top be valid. */
|
|
|
|
|
ntreeSetTypes(NULL, ntree);
|
|
|
|
|
|
|
|
|
|
/* For nodes with static socket layout, add/remove sockets as needed
|
|
|
|
|
* to match the static layout. */
|
|
|
|
|
if (fd->memfile == NULL) {
|
|
|
|
|
for (bNode *node = ntree->nodes.first; node; node = node->next) {
|
|
|
|
|
node_verify_socket_templates(ntree, node);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-20 16:39:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* library ntree linking after fileread */
|
|
|
|
|
static void lib_link_nodetree(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* only link ID pointers */
|
|
|
|
|
for (bNodeTree *ntree = main->nodetrees.first; ntree; ntree = ntree->id.next) {
|
|
|
|
|
if (ntree->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
lib_link_ntree(fd, &ntree->id, ntree);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ntree->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-20 16:39:39 +00:00
|
|
|
}
|
|
|
|
|
|
2011-09-05 21:01:50 +00:00
|
|
|
static void direct_link_node_socket(FileData *fd, bNodeSocket *sock)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
sock->prop = newdataadr(fd, sock->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sock->link = newdataadr(fd, sock->link);
|
|
|
|
|
sock->typeinfo = NULL;
|
|
|
|
|
sock->storage = newdataadr(fd, sock->storage);
|
|
|
|
|
sock->default_value = newdataadr(fd, sock->default_value);
|
|
|
|
|
sock->cache = NULL;
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
2009-02-20 16:39:39 +00:00
|
|
|
|
|
|
|
|
/* ntree itself has been read! */
|
|
|
|
|
static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* note: writing and reading goes in sync, for speed */
|
|
|
|
|
bNode *node;
|
|
|
|
|
bNodeSocket *sock;
|
|
|
|
|
bNodeLink *link;
|
|
|
|
|
|
|
|
|
|
ntree->init = 0; /* to set callbacks and force setting types */
|
|
|
|
|
ntree->is_updating = false;
|
|
|
|
|
ntree->typeinfo = NULL;
|
|
|
|
|
ntree->interface_type = NULL;
|
|
|
|
|
|
|
|
|
|
ntree->progress = NULL;
|
|
|
|
|
ntree->execdata = NULL;
|
|
|
|
|
|
|
|
|
|
ntree->adt = newdataadr(fd, ntree->adt);
|
|
|
|
|
direct_link_animdata(fd, ntree->adt);
|
|
|
|
|
|
|
|
|
|
ntree->id.recalc &= ~ID_RECALC_ALL;
|
|
|
|
|
|
|
|
|
|
link_list(fd, &ntree->nodes);
|
|
|
|
|
for (node = ntree->nodes.first; node; node = node->next) {
|
|
|
|
|
node->typeinfo = NULL;
|
|
|
|
|
|
|
|
|
|
link_list(fd, &node->inputs);
|
|
|
|
|
link_list(fd, &node->outputs);
|
|
|
|
|
|
|
|
|
|
node->prop = newdataadr(fd, node->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
|
|
|
|
|
link_list(fd, &node->internal_links);
|
|
|
|
|
for (link = node->internal_links.first; link; link = link->next) {
|
|
|
|
|
link->fromnode = newdataadr(fd, link->fromnode);
|
|
|
|
|
link->fromsock = newdataadr(fd, link->fromsock);
|
|
|
|
|
link->tonode = newdataadr(fd, link->tonode);
|
|
|
|
|
link->tosock = newdataadr(fd, link->tosock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (node->type == CMP_NODE_MOVIEDISTORTION) {
|
|
|
|
|
node->storage = newmclipadr(fd, node->storage);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
node->storage = newdataadr(fd, node->storage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (node->storage) {
|
|
|
|
|
/* could be handlerized at some point */
|
2019-06-17 14:16:51 +02:00
|
|
|
switch (node->type) {
|
|
|
|
|
case SH_NODE_CURVE_VEC:
|
|
|
|
|
case SH_NODE_CURVE_RGB:
|
|
|
|
|
case CMP_NODE_TIME:
|
|
|
|
|
case CMP_NODE_CURVE_VEC:
|
|
|
|
|
case CMP_NODE_CURVE_RGB:
|
|
|
|
|
case CMP_NODE_HUECORRECT:
|
|
|
|
|
case TEX_NODE_CURVE_RGB:
|
|
|
|
|
case TEX_NODE_CURVE_TIME: {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, node->storage);
|
2019-06-17 14:16:51 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-06-17 14:16:51 +02:00
|
|
|
case SH_NODE_SCRIPT: {
|
2019-04-17 06:17:24 +02:00
|
|
|
NodeShaderScript *nss = (NodeShaderScript *)node->storage;
|
|
|
|
|
nss->bytecode = newdataadr(fd, nss->bytecode);
|
2019-06-17 14:16:51 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-06-17 14:16:51 +02:00
|
|
|
case SH_NODE_TEX_POINTDENSITY: {
|
2019-04-17 06:17:24 +02:00
|
|
|
NodeShaderTexPointDensity *npd = (NodeShaderTexPointDensity *)node->storage;
|
|
|
|
|
memset(&npd->pd, 0, sizeof(npd->pd));
|
2019-06-17 14:16:51 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-06-17 14:16:51 +02:00
|
|
|
case SH_NODE_TEX_IMAGE: {
|
2019-04-17 06:17:24 +02:00
|
|
|
NodeTexImage *tex = (NodeTexImage *)node->storage;
|
|
|
|
|
tex->iuser.ok = 1;
|
|
|
|
|
tex->iuser.scene = NULL;
|
2019-06-17 14:16:51 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-06-17 14:16:51 +02:00
|
|
|
case SH_NODE_TEX_ENVIRONMENT: {
|
2019-04-17 06:17:24 +02:00
|
|
|
NodeTexEnvironment *tex = (NodeTexEnvironment *)node->storage;
|
|
|
|
|
tex->iuser.ok = 1;
|
|
|
|
|
tex->iuser.scene = NULL;
|
2019-06-17 14:16:51 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-06-17 14:16:51 +02:00
|
|
|
case CMP_NODE_IMAGE:
|
|
|
|
|
case CMP_NODE_R_LAYERS:
|
|
|
|
|
case CMP_NODE_VIEWER:
|
|
|
|
|
case CMP_NODE_SPLITVIEWER: {
|
2019-04-17 06:17:24 +02:00
|
|
|
ImageUser *iuser = node->storage;
|
|
|
|
|
iuser->ok = 1;
|
|
|
|
|
iuser->scene = NULL;
|
2019-06-17 14:16:51 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-06-17 14:16:51 +02:00
|
|
|
case CMP_NODE_CRYPTOMATTE: {
|
2019-04-17 06:17:24 +02:00
|
|
|
NodeCryptomatte *nc = (NodeCryptomatte *)node->storage;
|
|
|
|
|
nc->matte_id = newdataadr(fd, nc->matte_id);
|
2019-06-17 14:16:51 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-06-17 14:16:51 +02:00
|
|
|
case TEX_NODE_IMAGE: {
|
2019-04-17 06:17:24 +02:00
|
|
|
ImageUser *iuser = node->storage;
|
|
|
|
|
iuser->ok = 1;
|
|
|
|
|
iuser->scene = NULL;
|
2019-06-17 14:16:51 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-06-17 14:16:51 +02:00
|
|
|
default:
|
|
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
link_list(fd, &ntree->links);
|
|
|
|
|
|
|
|
|
|
/* and we connect the rest */
|
|
|
|
|
for (node = ntree->nodes.first; node; node = node->next) {
|
|
|
|
|
node->parent = newdataadr(fd, node->parent);
|
|
|
|
|
node->lasty = 0;
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (sock = node->inputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_node_socket(fd, sock);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
for (sock = node->outputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_node_socket(fd, sock);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* interface socket lists */
|
|
|
|
|
link_list(fd, &ntree->inputs);
|
|
|
|
|
link_list(fd, &ntree->outputs);
|
2019-04-22 09:13:00 +10:00
|
|
|
for (sock = ntree->inputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_node_socket(fd, sock);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
for (sock = ntree->outputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_node_socket(fd, sock);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
for (link = ntree->links.first; link; link = link->next) {
|
|
|
|
|
link->fromnode = newdataadr(fd, link->fromnode);
|
|
|
|
|
link->tonode = newdataadr(fd, link->tonode);
|
|
|
|
|
link->fromsock = newdataadr(fd, link->fromsock);
|
|
|
|
|
link->tosock = newdataadr(fd, link->tosock);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ntree->previews) {
|
|
|
|
|
bNodeInstanceHash *new_previews = BKE_node_instance_hash_new("node previews");
|
|
|
|
|
bNodeInstanceHashIterator iter;
|
|
|
|
|
|
2019-04-21 04:40:16 +10:00
|
|
|
NODE_INSTANCE_HASH_ITER(iter, ntree->previews) {
|
2019-04-17 06:17:24 +02:00
|
|
|
bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
|
|
|
|
|
if (preview) {
|
|
|
|
|
bNodePreview *new_preview = newimaadr(fd, preview);
|
|
|
|
|
if (new_preview) {
|
|
|
|
|
bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
|
|
|
|
|
BKE_node_instance_hash_insert(new_previews, key, new_preview);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
BKE_node_instance_hash_free(ntree->previews, NULL);
|
|
|
|
|
ntree->previews = new_previews;
|
|
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
/* XXX TODO */
|
|
|
|
|
ntree->previews = NULL;
|
2013-03-18 16:34:57 +00:00
|
|
|
#endif
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* type verification is in lib-link */
|
2009-02-20 16:39:39 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Armature
|
|
|
|
|
* \{ */
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2010-02-06 11:50:39 +00:00
|
|
|
/* temp struct used to transport needed info to lib_link_constraint_cb() */
|
|
|
|
|
typedef struct tConstraintLinkData {
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd;
|
|
|
|
|
ID *id;
|
2010-02-06 11:50:39 +00:00
|
|
|
} tConstraintLinkData;
|
|
|
|
|
/* callback function used to relink constraint ID-links */
|
2019-04-17 06:17:24 +02:00
|
|
|
static void lib_link_constraint_cb(bConstraint *UNUSED(con),
|
|
|
|
|
ID **idpoin,
|
|
|
|
|
bool is_reference,
|
|
|
|
|
void *userdata)
|
2010-02-06 11:50:39 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
tConstraintLinkData *cld = (tConstraintLinkData *)userdata;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* for reference types, we need to increment the usercounts on load... */
|
|
|
|
|
if (is_reference) {
|
|
|
|
|
/* reference type - with usercount */
|
|
|
|
|
*idpoin = newlibadr_us(cld->fd, cld->id->lib, *idpoin);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* target type - no usercount needed */
|
|
|
|
|
*idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin);
|
|
|
|
|
}
|
2010-02-06 11:50:39 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
tConstraintLinkData cld;
|
|
|
|
|
bConstraint *con;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* legacy fixes */
|
|
|
|
|
for (con = conlist->first; con; con = con->next) {
|
|
|
|
|
/* patch for error introduced by changing constraints (dunno how) */
|
|
|
|
|
/* if con->data type changes, dna cannot resolve the pointer! (ton) */
|
|
|
|
|
if (con->data == NULL) {
|
|
|
|
|
con->type = CONSTRAINT_TYPE_NULL;
|
|
|
|
|
}
|
|
|
|
|
/* own ipo, all constraints have it */
|
|
|
|
|
con->ipo = newlibadr_us(fd, id->lib, con->ipo); // XXX deprecated - old animation system
|
2018-05-02 18:13:15 +02:00
|
|
|
|
2019-06-14 23:16:04 +02:00
|
|
|
/* If linking from a library, clear 'local' library override flag. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (id->lib != NULL) {
|
2019-06-14 23:16:04 +02:00
|
|
|
con->flag &= ~CONSTRAINT_OVERRIDE_LIBRARY_LOCAL;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink all ID-blocks used by the constraints */
|
|
|
|
|
cld.fd = fd;
|
|
|
|
|
cld.id = id;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_constraints_id_loop(conlist, lib_link_constraint_cb, &cld);
|
2010-02-06 11:50:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_constraints(FileData *fd, ListBase *lb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bConstraint *con;
|
|
|
|
|
|
|
|
|
|
link_list(fd, lb);
|
|
|
|
|
for (con = lb->first; con; con = con->next) {
|
|
|
|
|
con->data = newdataadr(fd, con->data);
|
|
|
|
|
|
|
|
|
|
switch (con->type) {
|
|
|
|
|
case CONSTRAINT_TYPE_PYTHON: {
|
|
|
|
|
bPythonConstraint *data = con->data;
|
|
|
|
|
|
|
|
|
|
link_list(fd, &data->targets);
|
|
|
|
|
|
|
|
|
|
data->prop = newdataadr(fd, data->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CONSTRAINT_TYPE_ARMATURE: {
|
|
|
|
|
bArmatureConstraint *data = con->data;
|
|
|
|
|
|
|
|
|
|
link_list(fd, &data->targets);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CONSTRAINT_TYPE_SPLINEIK: {
|
|
|
|
|
bSplineIKConstraint *data = con->data;
|
|
|
|
|
|
|
|
|
|
data->points = newdataadr(fd, data->points);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CONSTRAINT_TYPE_KINEMATIC: {
|
|
|
|
|
bKinematicConstraint *data = con->data;
|
|
|
|
|
|
|
|
|
|
con->lin_error = 0.f;
|
|
|
|
|
con->rot_error = 0.f;
|
|
|
|
|
|
|
|
|
|
/* version patch for runtime flag, was not cleared in some case */
|
|
|
|
|
data->flag &= ~CONSTRAINT_IK_AUTO;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CONSTRAINT_TYPE_CHILDOF: {
|
|
|
|
|
/* XXX version patch, in older code this flag wasn't always set, and is inherent to type */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (con->ownspace == CONSTRAINT_SPACE_POSE) {
|
2019-04-17 06:17:24 +02:00
|
|
|
con->flag |= CONSTRAINT_SPACEONCE;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CONSTRAINT_TYPE_TRANSFORM_CACHE: {
|
|
|
|
|
bTransformCacheConstraint *data = con->data;
|
|
|
|
|
data->reader = NULL;
|
2019-04-04 15:07:37 +02:00
|
|
|
data->reader_object_path[0] = '\0';
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2013-02-23 01:33:47 +00:00
|
|
|
static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bArmature *arm = ob->data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!pose || !arm) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2016-01-09 09:12:06 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* always rebuild to match proxy or lib changes, but on Undo */
|
|
|
|
|
bool rebuild = false;
|
2016-01-09 09:12:06 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->memfile == NULL) {
|
|
|
|
|
if (ob->proxy || ob->id.lib != arm->id.lib) {
|
|
|
|
|
rebuild = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-01-09 09:12:06 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ob->proxy) {
|
|
|
|
|
/* sync proxy layer */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (pose->proxy_layer) {
|
2019-04-17 06:17:24 +02:00
|
|
|
arm->layer = pose->proxy_layer;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2016-01-09 09:12:06 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* sync proxy active bone */
|
|
|
|
|
if (pose->proxy_act_bone[0]) {
|
2019-05-14 21:48:22 +03:00
|
|
|
Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bone) {
|
|
|
|
|
arm->act_bone = bone;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-01-09 09:12:06 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
|
lib_link_constraints(fd, (ID *)ob, &pchan->constraints);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-05-14 21:48:22 +03:00
|
|
|
pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(pchan->prop, fd);
|
2016-01-09 09:12:06 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
pchan->custom = newlibadr_us(fd, arm->id.lib, pchan->custom);
|
|
|
|
|
if (UNLIKELY(pchan->bone == NULL)) {
|
|
|
|
|
rebuild = true;
|
|
|
|
|
}
|
|
|
|
|
else if ((ob->id.lib == NULL) && arm->id.lib) {
|
|
|
|
|
/* local pose selection copied to armature, bit hackish */
|
|
|
|
|
pchan->bone->flag &= ~BONE_SELECTED;
|
|
|
|
|
pchan->bone->flag |= pchan->selectflag;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (rebuild) {
|
|
|
|
|
DEG_id_tag_update_ex(
|
|
|
|
|
bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
|
|
|
|
|
BKE_pose_tag_recalc(bmain, pose);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
static void lib_link_bones(FileData *fd, Bone *bone)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(bone->prop, fd);
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Bone *curbone = bone->childbase.first; curbone; curbone = curbone->next) {
|
|
|
|
|
lib_link_bones(fd, curbone);
|
|
|
|
|
}
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_armature(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bArmature *arm = main->armatures.first; arm; arm = arm->id.next) {
|
|
|
|
|
if (arm->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(arm->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &arm->id, arm->adt);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Bone *curbone = arm->bonebase.first; curbone; curbone = curbone->next) {
|
|
|
|
|
lib_link_bones(fd, curbone);
|
|
|
|
|
}
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
arm->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2012-08-26 11:35:43 +00:00
|
|
|
static void direct_link_bones(FileData *fd, Bone *bone)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Bone *child;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bone->parent = newdataadr(fd, bone->parent);
|
|
|
|
|
bone->prop = newdataadr(fd, bone->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&bone->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bone->bbone_next = newdataadr(fd, bone->bbone_next);
|
|
|
|
|
bone->bbone_prev = newdataadr(fd, bone->bbone_prev);
|
2018-08-05 18:48:05 +03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bone->flag &= ~BONE_DRAW_ACTIVE;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &bone->childbase);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (child = bone->childbase.first; child; child = child->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_bones(fd, child);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_armature(FileData *fd, bArmature *arm)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Bone *bone;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &arm->bonebase);
|
2019-05-14 21:48:22 +03:00
|
|
|
arm->bonehash = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
arm->edbo = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
arm->adt = newdataadr(fd, arm->adt);
|
|
|
|
|
direct_link_animdata(fd, arm->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bone = arm->bonebase.first; bone; bone = bone->next) {
|
|
|
|
|
direct_link_bones(fd, bone);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
arm->act_bone = newdataadr(fd, arm->act_bone);
|
|
|
|
|
arm->act_edbone = NULL;
|
2019-05-14 21:48:22 +03:00
|
|
|
|
|
|
|
|
BKE_armature_bone_hash_make(arm);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Camera
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void lib_link_camera(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Camera *ca = main->cameras.first; ca; ca = ca->id.next) {
|
|
|
|
|
if (ca->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(ca->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &ca->id, ca->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-05-17 16:57:31 +02:00
|
|
|
ca->ipo = newlibadr_us(fd, ca->id.lib, ca->ipo); /* deprecated, for versioning */
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-05-17 16:57:31 +02:00
|
|
|
ca->dof_ob = newlibadr(fd, ca->id.lib, ca->dof_ob); /* deprecated, for versioning */
|
|
|
|
|
ca->dof.focus_object = newlibadr(fd, ca->id.lib, ca->dof.focus_object);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) {
|
|
|
|
|
bgpic->ima = newlibadr_us(fd, ca->id.lib, bgpic->ima);
|
|
|
|
|
bgpic->clip = newlibadr_us(fd, ca->id.lib, bgpic->clip);
|
|
|
|
|
}
|
2017-10-26 21:40:37 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ca->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_camera(FileData *fd, Camera *ca)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ca->adt = newdataadr(fd, ca->adt);
|
|
|
|
|
direct_link_animdata(fd, ca->adt);
|
2017-10-26 21:40:37 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &ca->bg_images);
|
2017-10-26 21:40:37 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) {
|
|
|
|
|
bgpic->iuser.ok = 1;
|
|
|
|
|
bgpic->iuser.scene = NULL;
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Light
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-27 12:02:02 +11:00
|
|
|
static void lib_link_light(FileData *fd, Main *main)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Light *la = main->lights.first; la; la = la->id.next) {
|
|
|
|
|
if (la->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(la->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &la->id, la->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
la->ipo = newlibadr_us(fd, la->id.lib, la->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (la->nodetree) {
|
|
|
|
|
lib_link_ntree(fd, &la->id, la->nodetree);
|
|
|
|
|
la->nodetree->id.lib = la->id.lib;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
la->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-27 12:02:02 +11:00
|
|
|
static void direct_link_light(FileData *fd, Light *la)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
la->adt = newdataadr(fd, la->adt);
|
|
|
|
|
direct_link_animdata(fd, la->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
la->curfalloff = newdataadr(fd, la->curfalloff);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (la->curfalloff) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, la->curfalloff);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2011-11-02 18:55:32 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
la->nodetree = newdataadr(fd, la->nodetree);
|
|
|
|
|
if (la->nodetree) {
|
|
|
|
|
direct_link_id(fd, &la->nodetree->id);
|
|
|
|
|
direct_link_nodetree(fd, la->nodetree);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
la->preview = direct_link_preview_image(fd, la->preview);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Shape Keys
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2013-11-29 23:16:13 +06:00
|
|
|
void blo_do_versions_key_uidgen(Key *key)
|
2012-09-23 18:50:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
KeyBlock *block;
|
2012-09-23 18:50:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
key->uidgen = 1;
|
|
|
|
|
for (block = key->block.first; block; block = block->next) {
|
|
|
|
|
block->uid = key->uidgen++;
|
|
|
|
|
}
|
2012-09-23 18:50:56 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_key(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Key *key = main->shapekeys.first; key; key = key->id.next) {
|
|
|
|
|
BLI_assert((key->id.tag & LIB_TAG_EXTERN) == 0);
|
2015-11-13 15:34:07 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (key->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(key->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &key->id, key->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
key->ipo = newlibadr_us(fd, key->id.lib, key->ipo); // XXX deprecated - old animation system
|
|
|
|
|
key->from = newlibadr(fd, key->id.lib, key->from);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
key->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void switch_endian_keyblock(Key *key, KeyBlock *kb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int elemsize, a, b;
|
|
|
|
|
char *data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
elemsize = key->elemsize;
|
|
|
|
|
data = kb->data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (a = 0; a < kb->totelem; a++) {
|
|
|
|
|
const char *cp = key->elemstr;
|
|
|
|
|
char *poin = data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
while (cp[0]) { /* cp[0] == amount */
|
|
|
|
|
switch (cp[1]) { /* cp[1] = type */
|
|
|
|
|
case IPO_FLOAT:
|
|
|
|
|
case IPO_BPOINT:
|
|
|
|
|
case IPO_BEZTRIPLE:
|
|
|
|
|
b = cp[0];
|
|
|
|
|
BLI_endian_switch_float_array((float *)poin, b);
|
|
|
|
|
poin += sizeof(float) * b;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
cp += 2;
|
|
|
|
|
}
|
|
|
|
|
data += elemsize;
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_key(FileData *fd, Key *key)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
KeyBlock *kb;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &(key->block));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
key->adt = newdataadr(fd, key->adt);
|
|
|
|
|
direct_link_animdata(fd, key->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
key->refkey = newdataadr(fd, key->refkey);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (kb = key->block.first; kb; kb = kb->next) {
|
|
|
|
|
kb->data = newdataadr(fd, kb->data);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
2019-04-17 06:17:24 +02:00
|
|
|
switch_endian_keyblock(key, kb);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Meta Ball
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void lib_link_mball(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (MetaBall *mb = main->metaballs.first; mb; mb = mb->id.next) {
|
|
|
|
|
if (mb->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(mb->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &mb->id, mb->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int a = 0; a < mb->totcol; a++) {
|
|
|
|
|
mb->mat[a] = newlibadr_us(fd, mb->id.lib, mb->mat[a]);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
mb->ipo = newlibadr_us(fd, mb->id.lib, mb->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
mb->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_mball(FileData *fd, MetaBall *mb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
mb->adt = newdataadr(fd, mb->adt);
|
|
|
|
|
direct_link_animdata(fd, mb->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
mb->mat = newdataadr(fd, mb->mat);
|
|
|
|
|
test_pointer_array(fd, (void **)&mb->mat);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &(mb->elems));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&mb->disp);
|
|
|
|
|
mb->editelems = NULL;
|
|
|
|
|
/* mb->edit_elems.first= mb->edit_elems.last= NULL;*/
|
|
|
|
|
mb->lastelem = NULL;
|
|
|
|
|
mb->batch_cache = NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: World
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void lib_link_world(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (World *wrld = main->worlds.first; wrld; wrld = wrld->id.next) {
|
|
|
|
|
if (wrld->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(wrld->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &wrld->id, wrld->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
wrld->ipo = newlibadr_us(
|
|
|
|
|
fd, wrld->id.lib, wrld->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (wrld->nodetree) {
|
|
|
|
|
lib_link_ntree(fd, &wrld->id, wrld->nodetree);
|
|
|
|
|
wrld->nodetree->id.lib = wrld->id.lib;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
wrld->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_world(FileData *fd, World *wrld)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
wrld->adt = newdataadr(fd, wrld->adt);
|
|
|
|
|
direct_link_animdata(fd, wrld->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
wrld->nodetree = newdataadr(fd, wrld->nodetree);
|
|
|
|
|
if (wrld->nodetree) {
|
|
|
|
|
direct_link_id(fd, &wrld->nodetree->id);
|
|
|
|
|
direct_link_nodetree(fd, wrld->nodetree);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
wrld->preview = direct_link_preview_image(fd, wrld->preview);
|
|
|
|
|
BLI_listbase_clear(&wrld->gpumaterial);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: VFont
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2017-03-28 10:03:59 +02:00
|
|
|
static void lib_link_vfont(FileData *fd, Main *main)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (VFont *vf = main->fonts.first; vf; vf = vf->id.next) {
|
|
|
|
|
if (vf->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(vf->id.properties, fd);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
vf->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_vfont(FileData *fd, VFont *vf)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
vf->data = NULL;
|
|
|
|
|
vf->temp_pf = NULL;
|
|
|
|
|
vf->packedfile = direct_link_packedfile(fd, vf->packedfile);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Text
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2017-03-28 10:03:59 +02:00
|
|
|
static void lib_link_text(FileData *fd, Main *main)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Text *text = main->texts.first; text; text = text->id.next) {
|
|
|
|
|
if (text->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(text->id.properties, fd);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
text->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_text(FileData *fd, Text *text)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
TextLine *ln;
|
2018-04-05 15:22:33 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
text->name = newdataadr(fd, text->name);
|
2018-04-05 15:22:33 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
text->compiled = NULL;
|
2018-04-05 15:22:33 +02:00
|
|
|
|
2012-04-22 11:54:53 +00:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
if (text->flags & TXT_ISEXT) {
|
|
|
|
|
BKE_text_reload(text);
|
|
|
|
|
}
|
|
|
|
|
/* else { */
|
2012-04-22 11:54:53 +00:00
|
|
|
#endif
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &text->lines);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
text->curl = newdataadr(fd, text->curl);
|
|
|
|
|
text->sell = newdataadr(fd, text->sell);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ln = text->lines.first; ln; ln = ln->next) {
|
|
|
|
|
ln->line = newdataadr(fd, ln->line);
|
|
|
|
|
ln->format = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ln->len != (int)strlen(ln->line)) {
|
|
|
|
|
printf("Error loading text, line lengths differ\n");
|
|
|
|
|
ln->len = strlen(ln->line);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
text->flags = (text->flags) & ~TXT_ISEXT;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
id_us_ensure_real(&text->id);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Image
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void lib_link_image(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Image *ima = main->images.first; ima; ima = ima->id.next) {
|
|
|
|
|
if (ima->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(ima->id.properties, fd);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ima->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_image(FileData *fd, Image *ima)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ImagePackedFile *imapf;
|
|
|
|
|
|
|
|
|
|
/* for undo system, pointers could be restored */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->imamap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ima->cache = newimaadr(fd, ima->cache);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
ima->cache = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* if not restored, we keep the binded opengl index */
|
|
|
|
|
if (!ima->cache) {
|
|
|
|
|
ima->gpuflag = 0;
|
2019-06-17 11:39:52 +02:00
|
|
|
ima->gpuframenr = INT_MAX;
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int i = 0; i < TEXTARGET_COUNT; i++) {
|
|
|
|
|
ima->gputexture[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
ima->rr = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for (int i = 0; i < TEXTARGET_COUNT; i++) {
|
|
|
|
|
ima->gputexture[i] = newimaadr(fd, ima->gputexture[i]);
|
|
|
|
|
}
|
|
|
|
|
ima->rr = newimaadr(fd, ima->rr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* undo system, try to restore render buffers */
|
|
|
|
|
link_list(fd, &(ima->renderslots));
|
|
|
|
|
if (fd->imamap) {
|
|
|
|
|
LISTBASE_FOREACH (RenderSlot *, slot, &ima->renderslots) {
|
|
|
|
|
slot->render = newimaadr(fd, slot->render);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
LISTBASE_FOREACH (RenderSlot *, slot, &ima->renderslots) {
|
|
|
|
|
slot->render = NULL;
|
|
|
|
|
}
|
|
|
|
|
ima->last_render_slot = ima->render_slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
link_list(fd, &(ima->views));
|
|
|
|
|
link_list(fd, &(ima->packedfiles));
|
|
|
|
|
|
|
|
|
|
if (ima->packedfiles.first) {
|
|
|
|
|
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
|
|
|
|
|
imapf->packedfile = direct_link_packedfile(fd, imapf->packedfile);
|
|
|
|
|
}
|
|
|
|
|
ima->packedfile = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&ima->anims);
|
|
|
|
|
ima->preview = direct_link_preview_image(fd, ima->preview);
|
|
|
|
|
ima->stereo3d_format = newdataadr(fd, ima->stereo3d_format);
|
|
|
|
|
ima->ok = 1;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Curve
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void lib_link_curve(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Curve *cu = main->curves.first; cu; cu = cu->id.next) {
|
|
|
|
|
if (cu->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(cu->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &cu->id, cu->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int a = 0; a < cu->totcol; a++) {
|
|
|
|
|
cu->mat[a] = newlibadr_us(fd, cu->id.lib, cu->mat[a]);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
cu->bevobj = newlibadr(fd, cu->id.lib, cu->bevobj);
|
|
|
|
|
cu->taperobj = newlibadr(fd, cu->id.lib, cu->taperobj);
|
|
|
|
|
cu->textoncurve = newlibadr(fd, cu->id.lib, cu->textoncurve);
|
|
|
|
|
cu->vfont = newlibadr_us(fd, cu->id.lib, cu->vfont);
|
|
|
|
|
cu->vfontb = newlibadr_us(fd, cu->id.lib, cu->vfontb);
|
|
|
|
|
cu->vfonti = newlibadr_us(fd, cu->id.lib, cu->vfonti);
|
|
|
|
|
cu->vfontbi = newlibadr_us(fd, cu->id.lib, cu->vfontbi);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
cu->ipo = newlibadr_us(fd, cu->id.lib, cu->ipo); // XXX deprecated - old animation system
|
|
|
|
|
cu->key = newlibadr_us(fd, cu->id.lib, cu->key);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
cu->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void switch_endian_knots(Nurb *nu)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (nu->knotsu) {
|
|
|
|
|
BLI_endian_switch_float_array(nu->knotsu, KNOTSU(nu));
|
|
|
|
|
}
|
|
|
|
|
if (nu->knotsv) {
|
|
|
|
|
BLI_endian_switch_float_array(nu->knotsv, KNOTSV(nu));
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_curve(FileData *fd, Curve *cu)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Nurb *nu;
|
|
|
|
|
TextBox *tb;
|
|
|
|
|
|
|
|
|
|
cu->adt = newdataadr(fd, cu->adt);
|
|
|
|
|
direct_link_animdata(fd, cu->adt);
|
|
|
|
|
|
|
|
|
|
/* Protect against integer overflow vulnerability. */
|
|
|
|
|
CLAMP(cu->len_wchar, 0, INT_MAX - 4);
|
|
|
|
|
|
|
|
|
|
cu->mat = newdataadr(fd, cu->mat);
|
|
|
|
|
test_pointer_array(fd, (void **)&cu->mat);
|
|
|
|
|
cu->str = newdataadr(fd, cu->str);
|
|
|
|
|
cu->strinfo = newdataadr(fd, cu->strinfo);
|
|
|
|
|
cu->tb = newdataadr(fd, cu->tb);
|
|
|
|
|
|
|
|
|
|
if (cu->vfont == NULL) {
|
|
|
|
|
link_list(fd, &(cu->nurb));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
cu->nurb.first = cu->nurb.last = NULL;
|
|
|
|
|
|
|
|
|
|
tb = MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), "TextBoxread");
|
|
|
|
|
if (cu->tb) {
|
|
|
|
|
memcpy(tb, cu->tb, cu->totbox * sizeof(TextBox));
|
|
|
|
|
MEM_freeN(cu->tb);
|
|
|
|
|
cu->tb = tb;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
cu->totbox = 1;
|
|
|
|
|
cu->actbox = 1;
|
|
|
|
|
cu->tb = tb;
|
|
|
|
|
cu->tb[0].w = cu->linewidth;
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
if (cu->wordspace == 0.0f) {
|
2019-04-17 06:17:24 +02:00
|
|
|
cu->wordspace = 1.0f;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cu->editnurb = NULL;
|
|
|
|
|
cu->editfont = NULL;
|
|
|
|
|
cu->batch_cache = NULL;
|
|
|
|
|
|
|
|
|
|
for (nu = cu->nurb.first; nu; nu = nu->next) {
|
|
|
|
|
nu->bezt = newdataadr(fd, nu->bezt);
|
|
|
|
|
nu->bp = newdataadr(fd, nu->bp);
|
|
|
|
|
nu->knotsu = newdataadr(fd, nu->knotsu);
|
|
|
|
|
nu->knotsv = newdataadr(fd, nu->knotsv);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (cu->vfont == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
nu->charidx = 0;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
switch_endian_knots(nu);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cu->bb = NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Texture
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void lib_link_texture(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Tex *tex = main->textures.first; tex; tex = tex->id.next) {
|
|
|
|
|
if (tex->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(tex->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &tex->id, tex->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
tex->ima = newlibadr_us(fd, tex->id.lib, tex->ima);
|
|
|
|
|
tex->ipo = newlibadr_us(fd, tex->id.lib, tex->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (tex->nodetree) {
|
|
|
|
|
lib_link_ntree(fd, &tex->id, tex->nodetree);
|
|
|
|
|
tex->nodetree->id.lib = tex->id.lib;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
tex->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_texture(FileData *fd, Tex *tex)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
tex->adt = newdataadr(fd, tex->adt);
|
|
|
|
|
direct_link_animdata(fd, tex->adt);
|
2012-05-29 10:21:07 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
tex->coba = newdataadr(fd, tex->coba);
|
Remove Blender Internal and legacy viewport from Blender 2.8.
Brecht authored this commit, but he gave me the honours to actually
do it. Here it goes; Blender Internal. Bye bye, you did great!
* Point density, voxel data, ocean, environment map textures were removed,
as these only worked within BI rendering. Note that the ocean modifier
and the Cycles point density shader node continue to work.
* Dynamic paint using material shading was removed, as this only worked
with BI. If we ever wanted to support this again probably it should go
through the baking API.
* GPU shader export through the Python API was removed. This only worked
for the old BI GLSL shaders, which no longer exists. Doing something
similar for Eevee would be significantly more complicated because it
uses a lot of multiplass rendering and logic outside the shader, it's
probably impractical.
* Collada material import / export code is mostly gone, as it only worked
for BI materials. We need to add Cycles / Eevee material support at some
point.
* The mesh noise operator was removed since it only worked with BI
material texture slots. A displacement modifier can be used instead.
* The delete texture paint slot operator was removed since it only worked
for BI material texture slots. Could be added back with node support.
* Not all legacy viewport features are supported in the new viewport, but
their code was removed. If we need to bring anything back we can look at
older git revisions.
* There is some legacy viewport code that I could not remove yet, and some
that I probably missed.
* Shader node execution code was left mostly intact, even though it is not
used anywhere now. We may eventually use this to replace the texture
nodes with Cycles / Eevee shader nodes.
* The Cycles Bake panel now includes settings for baking multires normal
and displacement maps. The underlying code needs to be merged properly,
and we plan to add back support for multires AO baking and add support
to Cycles baking for features like vertex color, displacement, and other
missing baking features.
* This commit removes DNA and the Python API for BI material, lamp, world
and scene settings. This breaks a lot of addons.
* There is more DNA that can be removed or renamed, where Cycles or Eevee
are reusing some old BI properties but the names are not really correct
anymore.
* Texture slots for materials, lamps and world were removed. They remain
for brushes, particles and freestyle linestyles.
* 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and
other renderers use this to find all panels to show, minus a few panels
that they have their own replacement for.
2018-04-19 17:34:44 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
tex->nodetree = newdataadr(fd, tex->nodetree);
|
|
|
|
|
if (tex->nodetree) {
|
|
|
|
|
direct_link_id(fd, &tex->nodetree->id);
|
|
|
|
|
direct_link_nodetree(fd, tex->nodetree);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
tex->preview = direct_link_preview_image(fd, tex->preview);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
tex->iuser.ok = 1;
|
|
|
|
|
tex->iuser.scene = NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Material
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void lib_link_material(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Material *ma = main->materials.first; ma; ma = ma->id.next) {
|
|
|
|
|
if (ma->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(ma->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &ma->id, ma->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ma->ipo = newlibadr_us(fd, ma->id.lib, ma->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ma->nodetree) {
|
|
|
|
|
lib_link_ntree(fd, &ma->id, ma->nodetree);
|
|
|
|
|
ma->nodetree->id.lib = ma->id.lib;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink grease pencil settings */
|
|
|
|
|
if (ma->gp_style != NULL) {
|
|
|
|
|
MaterialGPencilStyle *gp_style = ma->gp_style;
|
|
|
|
|
if (gp_style->sima != NULL) {
|
|
|
|
|
gp_style->sima = newlibadr_us(fd, ma->id.lib, gp_style->sima);
|
|
|
|
|
}
|
|
|
|
|
if (gp_style->ima != NULL) {
|
|
|
|
|
gp_style->ima = newlibadr_us(fd, ma->id.lib, gp_style->ima);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ma->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_material(FileData *fd, Material *ma)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ma->adt = newdataadr(fd, ma->adt);
|
|
|
|
|
direct_link_animdata(fd, ma->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ma->texpaintslot = NULL;
|
2014-07-21 12:02:05 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ma->nodetree = newdataadr(fd, ma->nodetree);
|
|
|
|
|
if (ma->nodetree) {
|
|
|
|
|
direct_link_id(fd, &ma->nodetree->id);
|
|
|
|
|
direct_link_nodetree(fd, ma->nodetree);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ma->preview = direct_link_preview_image(fd, ma->preview);
|
|
|
|
|
BLI_listbase_clear(&ma->gpumaterial);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ma->gp_style = newdataadr(fd, ma->gp_style);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Particle Settings
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
/* update this also to writefile.c */
|
|
|
|
|
static const char *ptcache_data_struct[] = {
|
2019-04-17 06:17:24 +02:00
|
|
|
"", // BPHYS_DATA_INDEX
|
|
|
|
|
"", // BPHYS_DATA_LOCATION
|
|
|
|
|
"", // BPHYS_DATA_VELOCITY
|
|
|
|
|
"", // BPHYS_DATA_ROTATION
|
|
|
|
|
"", // BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
|
|
|
|
|
"", // BPHYS_DATA_SIZE:
|
|
|
|
|
"", // BPHYS_DATA_TIMES:
|
|
|
|
|
"BoidData", // case BPHYS_DATA_BOIDS:
|
2016-12-28 17:30:58 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void direct_link_pointcache_cb(FileData *fd, void *data)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
PTCacheMem *pm = data;
|
|
|
|
|
PTCacheExtra *extra;
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < BPHYS_TOT_DATA; i++) {
|
|
|
|
|
pm->data[i] = newdataadr(fd, pm->data[i]);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* the cache saves non-struct data without DNA */
|
|
|
|
|
if (pm->data[i] && ptcache_data_struct[i][0] == '\0' && (fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
|
2019-07-02 22:17:22 +10:00
|
|
|
/* data_size returns bytes. */
|
|
|
|
|
int tot = (BKE_ptcache_data_size(i) * pm->totpoint) / sizeof(int);
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
int *poin = pm->data[i];
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_endian_switch_int32_array(poin, tot);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &pm->extradata);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (extra = pm->extradata.first; extra; extra = extra->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
extra->data = newdataadr(fd, extra->data);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_pointcache(FileData *fd, PointCache *cache)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if ((cache->flag & PTCACHE_DISK_CACHE) == 0) {
|
|
|
|
|
link_list_ex(fd, &cache->mem_cache, direct_link_pointcache_cb);
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&cache->mem_cache);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
cache->flag &= ~PTCACHE_SIMULATION_VALID;
|
|
|
|
|
cache->simframe = 0;
|
|
|
|
|
cache->edit = NULL;
|
|
|
|
|
cache->free_edit = NULL;
|
|
|
|
|
cache->cached_frames = NULL;
|
|
|
|
|
cache->cached_frames_len = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_pointcache_list(FileData *fd,
|
|
|
|
|
ListBase *ptcaches,
|
|
|
|
|
PointCache **ocache,
|
|
|
|
|
int force_disk)
|
|
|
|
|
{
|
|
|
|
|
if (ptcaches->first) {
|
|
|
|
|
PointCache *cache = NULL;
|
|
|
|
|
link_list(fd, ptcaches);
|
|
|
|
|
for (cache = ptcaches->first; cache; cache = cache->next) {
|
|
|
|
|
direct_link_pointcache(fd, cache);
|
|
|
|
|
if (force_disk) {
|
|
|
|
|
cache->flag |= PTCACHE_DISK_CACHE;
|
|
|
|
|
cache->step = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*ocache = newdataadr(fd, *ocache);
|
|
|
|
|
}
|
|
|
|
|
else if (*ocache) {
|
|
|
|
|
/* old "single" caches need to be linked too */
|
|
|
|
|
*ocache = newdataadr(fd, *ocache);
|
|
|
|
|
direct_link_pointcache(fd, *ocache);
|
|
|
|
|
if (force_disk) {
|
|
|
|
|
(*ocache)->flag |= PTCACHE_DISK_CACHE;
|
|
|
|
|
(*ocache)->step = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ptcaches->first = ptcaches->last = *ocache;
|
|
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
}
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
|
2011-02-13 10:52:18 +00:00
|
|
|
static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd)
|
2009-12-18 13:08:11 +00:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (pd && pd->tex) {
|
2019-04-17 06:17:24 +02:00
|
|
|
pd->tex = newlibadr_us(fd, id->lib, pd->tex);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (pd && pd->f_source) {
|
2019-04-17 06:17:24 +02:00
|
|
|
pd->f_source = newlibadr(fd, id->lib, pd->f_source);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2009-12-18 13:08:11 +00:00
|
|
|
}
|
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
static void lib_link_particlesettings(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ParticleSettings *part = main->particles.first; part; part = part->id.next) {
|
|
|
|
|
if (part->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(part->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &part->id, part->adt);
|
|
|
|
|
|
|
|
|
|
part->ipo = newlibadr_us(
|
|
|
|
|
fd, part->id.lib, part->ipo); // XXX deprecated - old animation system
|
|
|
|
|
|
|
|
|
|
part->instance_object = newlibadr(fd, part->id.lib, part->instance_object);
|
|
|
|
|
part->instance_collection = newlibadr_us(fd, part->id.lib, part->instance_collection);
|
|
|
|
|
part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
|
|
|
|
|
part->bb_ob = newlibadr(fd, part->id.lib, part->bb_ob);
|
|
|
|
|
part->collision_group = newlibadr(fd, part->id.lib, part->collision_group);
|
|
|
|
|
|
|
|
|
|
lib_link_partdeflect(fd, &part->id, part->pd);
|
|
|
|
|
lib_link_partdeflect(fd, &part->id, part->pd2);
|
|
|
|
|
|
|
|
|
|
if (part->effector_weights) {
|
|
|
|
|
part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
part->effector_weights = BKE_effector_add_weights(part->eff_group);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (part->instance_weights.first && part->instance_collection) {
|
|
|
|
|
for (ParticleDupliWeight *dw = part->instance_weights.first; dw; dw = dw->next) {
|
|
|
|
|
dw->ob = newlibadr(fd, part->id.lib, dw->ob);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_listbase_clear(&part->instance_weights);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (part->boids) {
|
|
|
|
|
BoidState *state = part->boids->states.first;
|
|
|
|
|
BoidRule *rule;
|
|
|
|
|
for (; state; state = state->next) {
|
|
|
|
|
rule = state->rules.first;
|
|
|
|
|
for (; rule; rule = rule->next) {
|
|
|
|
|
switch (rule->type) {
|
|
|
|
|
case eBoidRuleType_Goal:
|
|
|
|
|
case eBoidRuleType_Avoid: {
|
|
|
|
|
BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid *)rule;
|
|
|
|
|
brga->ob = newlibadr(fd, part->id.lib, brga->ob);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case eBoidRuleType_FollowLeader: {
|
|
|
|
|
BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader *)rule;
|
|
|
|
|
brfl->ob = newlibadr(fd, part->id.lib, brfl->ob);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int a = 0; a < MAX_MTEX; a++) {
|
|
|
|
|
MTex *mtex = part->mtex[a];
|
|
|
|
|
if (mtex) {
|
|
|
|
|
mtex->tex = newlibadr_us(fd, part->id.lib, mtex->tex);
|
|
|
|
|
mtex->object = newlibadr(fd, part->id.lib, mtex->object);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
part->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
}
|
|
|
|
|
|
2009-12-18 13:08:11 +00:00
|
|
|
static void direct_link_partdeflect(PartDeflect *pd)
|
|
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (pd) {
|
2019-04-17 06:17:24 +02:00
|
|
|
pd->rng = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2009-12-18 13:08:11 +00:00
|
|
|
}
|
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int a;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
part->adt = newdataadr(fd, part->adt);
|
|
|
|
|
part->pd = newdataadr(fd, part->pd);
|
|
|
|
|
part->pd2 = newdataadr(fd, part->pd2);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_animdata(fd, part->adt);
|
|
|
|
|
direct_link_partdeflect(part->pd);
|
|
|
|
|
direct_link_partdeflect(part->pd2);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
part->clumpcurve = newdataadr(fd, part->clumpcurve);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (part->clumpcurve) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, part->clumpcurve);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
part->roughcurve = newdataadr(fd, part->roughcurve);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (part->roughcurve) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, part->roughcurve);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
part->twistcurve = newdataadr(fd, part->twistcurve);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (part->twistcurve) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, part->twistcurve);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
part->effector_weights = newdataadr(fd, part->effector_weights);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!part->effector_weights) {
|
2019-04-17 06:17:24 +02:00
|
|
|
part->effector_weights = BKE_effector_add_weights(part->eff_group);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &part->instance_weights);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
part->boids = newdataadr(fd, part->boids);
|
|
|
|
|
part->fluid = newdataadr(fd, part->fluid);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (part->boids) {
|
|
|
|
|
BoidState *state;
|
|
|
|
|
link_list(fd, &part->boids->states);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (state = part->boids->states.first; state; state = state->next) {
|
|
|
|
|
link_list(fd, &state->rules);
|
|
|
|
|
link_list(fd, &state->conditions);
|
|
|
|
|
link_list(fd, &state->actions);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (a = 0; a < MAX_MTEX; a++) {
|
|
|
|
|
part->mtex[a] = newdataadr(fd, part->mtex[a]);
|
|
|
|
|
}
|
2018-01-15 06:57:26 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Protect against integer overflow vulnerability. */
|
|
|
|
|
CLAMP(part->trail_count, 1, 100000);
|
2016-12-28 17:30:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ParticleSystem *psys, *psysnext;
|
|
|
|
|
|
|
|
|
|
for (psys = particles->first; psys; psys = psysnext) {
|
|
|
|
|
psysnext = psys->next;
|
|
|
|
|
|
|
|
|
|
psys->part = newlibadr_us(fd, id->lib, psys->part);
|
|
|
|
|
if (psys->part) {
|
|
|
|
|
ParticleTarget *pt = psys->targets.first;
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (; pt; pt = pt->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
pt->ob = newlibadr(fd, id->lib, pt->ob);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
psys->parent = newlibadr(fd, id->lib, psys->parent);
|
|
|
|
|
psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
|
|
|
|
|
|
|
|
|
|
if (psys->clmd) {
|
|
|
|
|
/* XXX - from reading existing code this seems correct but intended usage of
|
|
|
|
|
* pointcache /w cloth should be added in 'ParticleSystem' - campbell */
|
|
|
|
|
psys->clmd->point_cache = psys->pointcache;
|
|
|
|
|
psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = NULL;
|
|
|
|
|
psys->clmd->coll_parms->group = newlibadr(fd, id->lib, psys->clmd->coll_parms->group);
|
|
|
|
|
psys->clmd->modifier.error = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* particle modifier must be removed before particle system */
|
|
|
|
|
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
|
|
|
|
|
BLI_remlink(&ob->modifiers, psmd);
|
|
|
|
|
modifier_free((ModifierData *)psmd);
|
|
|
|
|
|
|
|
|
|
BLI_remlink(particles, psys);
|
|
|
|
|
MEM_freeN(psys);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
}
|
|
|
|
|
static void direct_link_particlesystems(FileData *fd, ListBase *particles)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ParticleSystem *psys;
|
|
|
|
|
ParticleData *pa;
|
|
|
|
|
int a;
|
|
|
|
|
|
|
|
|
|
for (psys = particles->first; psys; psys = psys->next) {
|
|
|
|
|
psys->particles = newdataadr(fd, psys->particles);
|
|
|
|
|
|
|
|
|
|
if (psys->particles && psys->particles->hair) {
|
2019-04-22 09:13:00 +10:00
|
|
|
for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
pa->hair = newdataadr(fd, pa->hair);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (psys->particles && psys->particles->keys) {
|
|
|
|
|
for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
|
|
|
|
|
pa->keys = NULL;
|
|
|
|
|
pa->totkey = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
psys->flag &= ~PSYS_KEYED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (psys->particles && psys->particles->boid) {
|
|
|
|
|
pa = psys->particles;
|
|
|
|
|
pa->boid = newdataadr(fd, pa->boid);
|
2019-07-02 22:17:22 +10:00
|
|
|
|
|
|
|
|
/* This is purely runtime data, but still can be an issue if left dangling. */
|
|
|
|
|
pa->boid->ground = NULL;
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (a = 1, pa++; a < psys->totpart; a++, pa++) {
|
|
|
|
|
pa->boid = (pa - 1)->boid + 1;
|
|
|
|
|
pa->boid->ground = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (psys->particles) {
|
2019-04-22 09:13:00 +10:00
|
|
|
for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
pa->boid = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
psys->fluid_springs = newdataadr(fd, psys->fluid_springs);
|
|
|
|
|
|
|
|
|
|
psys->child = newdataadr(fd, psys->child);
|
|
|
|
|
psys->effectors = NULL;
|
|
|
|
|
|
|
|
|
|
link_list(fd, &psys->targets);
|
|
|
|
|
|
|
|
|
|
psys->edit = NULL;
|
|
|
|
|
psys->free_edit = NULL;
|
|
|
|
|
psys->pathcache = NULL;
|
|
|
|
|
psys->childcache = NULL;
|
|
|
|
|
BLI_listbase_clear(&psys->pathcachebufs);
|
|
|
|
|
BLI_listbase_clear(&psys->childcachebufs);
|
|
|
|
|
psys->pdd = NULL;
|
|
|
|
|
|
|
|
|
|
if (psys->clmd) {
|
|
|
|
|
psys->clmd = newdataadr(fd, psys->clmd);
|
|
|
|
|
psys->clmd->clothObject = NULL;
|
|
|
|
|
psys->clmd->hairdata = NULL;
|
|
|
|
|
|
|
|
|
|
psys->clmd->sim_parms = newdataadr(fd, psys->clmd->sim_parms);
|
|
|
|
|
psys->clmd->coll_parms = newdataadr(fd, psys->clmd->coll_parms);
|
|
|
|
|
|
|
|
|
|
if (psys->clmd->sim_parms) {
|
|
|
|
|
psys->clmd->sim_parms->effector_weights = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
if (psys->clmd->sim_parms->presets > 10) {
|
2019-04-17 06:17:24 +02:00
|
|
|
psys->clmd->sim_parms->presets = 0;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
psys->hair_in_mesh = psys->hair_out_mesh = NULL;
|
|
|
|
|
psys->clmd->solver_result = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache, 0);
|
|
|
|
|
if (psys->clmd) {
|
|
|
|
|
psys->clmd->point_cache = psys->pointcache;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
psys->tree = NULL;
|
|
|
|
|
psys->bvhtree = NULL;
|
|
|
|
|
|
|
|
|
|
psys->orig_psys = NULL;
|
|
|
|
|
psys->batch_cache = NULL;
|
|
|
|
|
}
|
|
|
|
|
return;
|
2016-12-28 17:30:58 +01:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Mesh
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void lib_link_mesh(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Mesh *me;
|
|
|
|
|
|
|
|
|
|
for (me = main->meshes.first; me; me = me->id.next) {
|
|
|
|
|
if (me->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
|
|
|
|
|
* of library blocks that implement this.*/
|
|
|
|
|
IDP_LibLinkProperty(me->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &me->id, me->adt);
|
|
|
|
|
|
|
|
|
|
/* this check added for python created meshes */
|
|
|
|
|
if (me->mat) {
|
|
|
|
|
for (i = 0; i < me->totcol; i++) {
|
|
|
|
|
me->mat[i] = newlibadr_us(fd, me->id.lib, me->mat[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
me->totcol = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me->ipo = newlibadr_us(fd, me->id.lib, me->ipo); // XXX: deprecated: old anim sys
|
|
|
|
|
me->key = newlibadr_us(fd, me->id.lib, me->key);
|
|
|
|
|
me->texcomesh = newlibadr_us(fd, me->id.lib, me->texcomesh);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (me = main->meshes.first; me; me = me->id.next) {
|
|
|
|
|
if (me->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
/*check if we need to convert mfaces to mpolys*/
|
|
|
|
|
if (me->totface && !me->totpoly) {
|
|
|
|
|
/* temporarily switch main so that reading from
|
|
|
|
|
* external CustomData works */
|
|
|
|
|
Main *gmain = G_MAIN;
|
|
|
|
|
G_MAIN = main;
|
|
|
|
|
|
|
|
|
|
BKE_mesh_do_versions_convert_mfaces_to_mpolys(me);
|
|
|
|
|
|
|
|
|
|
G_MAIN = gmain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Re-tessellate, even if the polys were just created from tessfaces, this
|
|
|
|
|
* is important because it:
|
|
|
|
|
* - fill the CD_ORIGINDEX layer
|
|
|
|
|
* - gives consistency of tessface between loading from a file and
|
|
|
|
|
* converting an edited BMesh back into a mesh (i.e. it replaces
|
|
|
|
|
* quad tessfaces in a loaded mesh immediately, instead of lazily
|
|
|
|
|
* waiting until edit mode has been entered/exited, making it easier
|
|
|
|
|
* to recognize problems that would otherwise only show up after edits).
|
|
|
|
|
*/
|
2012-02-20 00:18:35 +00:00
|
|
|
#ifdef USE_TESSFACE_DEFAULT
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_mesh_tessface_calc(me);
|
2012-02-20 00:18:35 +00:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_mesh_tessface_clear(me);
|
2012-02-20 00:18:35 +00:00
|
|
|
#endif
|
2012-07-12 15:36:22 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
me->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (mdverts == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = count; i > 0; i--, mdverts++) {
|
|
|
|
|
/*convert to vgroup allocation system*/
|
|
|
|
|
MDeformWeight *dw;
|
|
|
|
|
if (mdverts->dw && (dw = newdataadr(fd, mdverts->dw))) {
|
|
|
|
|
const ssize_t dw_len = mdverts->totweight * sizeof(MDeformWeight);
|
|
|
|
|
void *dw_tmp = MEM_mallocN(dw_len, "direct_link_dverts");
|
|
|
|
|
memcpy(dw_tmp, dw, dw_len);
|
|
|
|
|
mdverts->dw = dw_tmp;
|
|
|
|
|
MEM_freeN(dw);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mdverts->dw = NULL;
|
|
|
|
|
mdverts->totweight = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2009-11-25 14:27:50 +00:00
|
|
|
static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps, int external)
|
2009-01-06 18:59:03 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (mdisps) {
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; ++i) {
|
|
|
|
|
mdisps[i].disps = newdataadr(fd, mdisps[i].disps);
|
|
|
|
|
mdisps[i].hidden = newdataadr(fd, mdisps[i].hidden);
|
|
|
|
|
|
|
|
|
|
if (mdisps[i].totdisp && !mdisps[i].level) {
|
|
|
|
|
/* this calculation is only correct for loop mdisps;
|
|
|
|
|
* if loading pre-BMesh face mdisps this will be
|
|
|
|
|
* overwritten with the correct value in
|
|
|
|
|
* bm_corners_to_loops() */
|
|
|
|
|
float gridsize = sqrtf(mdisps[i].totdisp);
|
|
|
|
|
mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && (mdisps[i].disps)) {
|
|
|
|
|
/* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */
|
|
|
|
|
/* this does swap for data written at write_mdisps() - readfile.c */
|
|
|
|
|
BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3);
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!external && !mdisps[i].disps) {
|
2019-04-17 06:17:24 +02:00
|
|
|
mdisps[i].totdisp = 0;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2009-01-06 18:59:03 +00:00
|
|
|
}
|
|
|
|
|
|
2012-05-10 20:33:24 +00:00
|
|
|
static void direct_link_grid_paint_mask(FileData *fd, int count, GridPaintMask *grid_paint_mask)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (grid_paint_mask) {
|
|
|
|
|
int i;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (i = 0; i < count; ++i) {
|
|
|
|
|
GridPaintMask *gpm = &grid_paint_mask[i];
|
2019-04-22 09:13:00 +10:00
|
|
|
if (gpm->data) {
|
2019-04-17 06:17:24 +02:00
|
|
|
gpm->data = newdataadr(fd, gpm->data);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2012-05-10 20:33:24 +00:00
|
|
|
}
|
|
|
|
|
|
2011-12-28 09:11:11 +00:00
|
|
|
/*this isn't really a public api function, so prototyped here*/
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
static void direct_link_customdata(FileData *fd, CustomData *data, int count)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int i = 0;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
data->layers = newdataadr(fd, data->layers);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* annoying workaround for bug [#31079] loading legacy files with
|
|
|
|
|
* no polygons _but_ have stale customdata */
|
|
|
|
|
if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) {
|
|
|
|
|
CustomData_reset(data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
data->external = newdataadr(fd, data->external);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
while (i < data->totlayer) {
|
|
|
|
|
CustomDataLayer *layer = &data->layers[i];
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (layer->flag & CD_FLAG_EXTERNAL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
layer->flag &= ~CD_FLAG_IN_MEMORY;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2013-09-13 13:34:10 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
layer->flag &= ~CD_FLAG_NOFREE;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (CustomData_verify_versions(data, i)) {
|
|
|
|
|
layer->data = newdataadr(fd, layer->data);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (layer->type == CD_MDISPS) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_mdisps(fd, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else if (layer->type == CD_GRID_PAINT_MASK) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_grid_paint_mask(fd, count, layer->data);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
CustomData_update_typemap(data);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void direct_link_mesh(FileData *fd, Mesh *mesh)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
mesh->mat = newdataadr(fd, mesh->mat);
|
|
|
|
|
test_pointer_array(fd, (void **)&mesh->mat);
|
|
|
|
|
|
|
|
|
|
mesh->mvert = newdataadr(fd, mesh->mvert);
|
|
|
|
|
mesh->medge = newdataadr(fd, mesh->medge);
|
|
|
|
|
mesh->mface = newdataadr(fd, mesh->mface);
|
|
|
|
|
mesh->mloop = newdataadr(fd, mesh->mloop);
|
|
|
|
|
mesh->mpoly = newdataadr(fd, mesh->mpoly);
|
|
|
|
|
mesh->tface = newdataadr(fd, mesh->tface);
|
|
|
|
|
mesh->mtface = newdataadr(fd, mesh->mtface);
|
|
|
|
|
mesh->mcol = newdataadr(fd, mesh->mcol);
|
|
|
|
|
mesh->dvert = newdataadr(fd, mesh->dvert);
|
|
|
|
|
mesh->mloopcol = newdataadr(fd, mesh->mloopcol);
|
|
|
|
|
mesh->mloopuv = newdataadr(fd, mesh->mloopuv);
|
|
|
|
|
mesh->mselect = newdataadr(fd, mesh->mselect);
|
|
|
|
|
|
|
|
|
|
/* animdata */
|
|
|
|
|
mesh->adt = newdataadr(fd, mesh->adt);
|
|
|
|
|
direct_link_animdata(fd, mesh->adt);
|
|
|
|
|
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Normally direct_link_dverts should be called in direct_link_customdata,
|
|
|
|
|
* but for backwards compatibility in do_versions to work we do it here. */
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_dverts(fd, mesh->totvert, mesh->dvert);
|
|
|
|
|
|
|
|
|
|
direct_link_customdata(fd, &mesh->vdata, mesh->totvert);
|
|
|
|
|
direct_link_customdata(fd, &mesh->edata, mesh->totedge);
|
|
|
|
|
direct_link_customdata(fd, &mesh->fdata, mesh->totface);
|
|
|
|
|
direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
|
|
|
|
|
direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
|
|
|
|
|
|
|
|
|
|
mesh->bb = NULL;
|
|
|
|
|
mesh->edit_mesh = NULL;
|
|
|
|
|
BKE_mesh_runtime_reset(mesh);
|
|
|
|
|
|
|
|
|
|
/* happens with old files */
|
|
|
|
|
if (mesh->mselect == NULL) {
|
|
|
|
|
mesh->totselect = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Multires data */
|
|
|
|
|
mesh->mr = newdataadr(fd, mesh->mr);
|
|
|
|
|
if (mesh->mr) {
|
|
|
|
|
MultiresLevel *lvl;
|
|
|
|
|
|
|
|
|
|
link_list(fd, &mesh->mr->levels);
|
|
|
|
|
lvl = mesh->mr->levels.first;
|
|
|
|
|
|
|
|
|
|
direct_link_customdata(fd, &mesh->mr->vdata, lvl->totvert);
|
|
|
|
|
direct_link_dverts(fd, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
|
|
|
|
|
direct_link_customdata(fd, &mesh->mr->fdata, lvl->totface);
|
|
|
|
|
|
|
|
|
|
mesh->mr->edge_flags = newdataadr(fd, mesh->mr->edge_flags);
|
|
|
|
|
mesh->mr->edge_creases = newdataadr(fd, mesh->mr->edge_creases);
|
|
|
|
|
|
|
|
|
|
mesh->mr->verts = newdataadr(fd, mesh->mr->verts);
|
|
|
|
|
|
|
|
|
|
/* If mesh has the same number of vertices as the
|
|
|
|
|
* highest multires level, load the current mesh verts
|
|
|
|
|
* into multires and discard the old data. Needed
|
|
|
|
|
* because some saved files either do not have a verts
|
|
|
|
|
* array, or the verts array contains out-of-date
|
|
|
|
|
* data. */
|
|
|
|
|
if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mesh->mr->verts) {
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(mesh->mr->verts);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
mesh->mr->verts = MEM_dupallocN(mesh->mvert);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (; lvl; lvl = lvl->next) {
|
|
|
|
|
lvl->verts = newdataadr(fd, lvl->verts);
|
|
|
|
|
lvl->faces = newdataadr(fd, lvl->faces);
|
|
|
|
|
lvl->edges = newdataadr(fd, lvl->edges);
|
|
|
|
|
lvl->colfaces = newdataadr(fd, lvl->colfaces);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if multires is present but has no valid vertex data,
|
|
|
|
|
* there's no way to recover it; silently remove multires */
|
|
|
|
|
if (mesh->mr && !mesh->mr->verts) {
|
|
|
|
|
multires_free(mesh->mr);
|
|
|
|
|
mesh->mr = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && mesh->tface) {
|
|
|
|
|
TFace *tf = mesh->tface;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < mesh->totface; i++, tf++) {
|
|
|
|
|
BLI_endian_switch_uint32_array(tf->col, 4);
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Lattice
|
|
|
|
|
* \{ */
|
2006-09-03 12:16:14 +00:00
|
|
|
|
|
|
|
|
static void lib_link_latt(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Lattice *lt = main->lattices.first; lt; lt = lt->id.next) {
|
|
|
|
|
if (lt->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(lt->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, <->id, lt->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lt->ipo = newlibadr_us(fd, lt->id.lib, lt->ipo); // XXX deprecated - old animation system
|
|
|
|
|
lt->key = newlibadr_us(fd, lt->id.lib, lt->key);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lt->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-09-03 12:16:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_latt(FileData *fd, Lattice *lt)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
lt->def = newdataadr(fd, lt->def);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lt->dvert = newdataadr(fd, lt->dvert);
|
|
|
|
|
direct_link_dverts(fd, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lt->editlatt = NULL;
|
|
|
|
|
lt->batch_cache = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lt->adt = newdataadr(fd, lt->adt);
|
|
|
|
|
direct_link_animdata(fd, lt->adt);
|
2006-09-03 12:16:14 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
2006-09-03 12:16:14 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Object
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void lib_link_modifiers_common(void *userData, Object *ob, ID **idpoin, int cb_flag)
|
2005-07-19 20:14:17 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = userData;
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
*idpoin = newlibadr(fd, ob->id.lib, *idpoin);
|
|
|
|
|
if (*idpoin != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
|
|
|
|
|
id_us_plus_no_lib(*idpoin);
|
|
|
|
|
}
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
static void lib_link_modifiers(FileData *fd, Object *ob)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
modifiers_foreachIDLink(ob, lib_link_modifiers_common, fd);
|
2018-05-02 18:13:15 +02:00
|
|
|
|
2019-06-14 23:16:04 +02:00
|
|
|
/* If linking from a library, clear 'local' library override flag. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ob->id.lib != NULL) {
|
|
|
|
|
for (ModifierData *mod = ob->modifiers.first; mod != NULL; mod = mod->next) {
|
2019-06-14 23:16:04 +02:00
|
|
|
mod->flag &= ~eModifierFlag_OverrideLibrary_Local;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2005-07-19 20:14:17 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
static void lib_link_gpencil_modifiers(FileData *fd, Object *ob)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_gpencil_modifiers_foreachIDLink(ob, lib_link_modifiers_common, fd);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-06-14 23:16:04 +02:00
|
|
|
/* If linking from a library, clear 'local' library override flag. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ob->id.lib != NULL) {
|
|
|
|
|
for (GpencilModifierData *mod = ob->greasepencil_modifiers.first; mod != NULL;
|
|
|
|
|
mod = mod->next) {
|
2019-06-14 23:16:04 +02:00
|
|
|
mod->flag &= ~eGpencilModifierFlag_OverrideLibrary_Local;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_shaderfxs(FileData *fd, Object *ob)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_shaderfx_foreachIDLink(ob, lib_link_modifiers_common, fd);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-06-14 23:16:04 +02:00
|
|
|
/* If linking from a library, clear 'local' library override flag. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ob->id.lib != NULL) {
|
|
|
|
|
for (ShaderFxData *fx = ob->shader_fx.first; fx != NULL; fx = fx->next) {
|
2019-06-14 23:16:04 +02:00
|
|
|
fx->flag &= ~eShaderFxFlag_OverrideLibrary_Local;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_object(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bool warn = false;
|
|
|
|
|
|
|
|
|
|
for (Object *ob = main->objects.first; ob; ob = ob->id.next) {
|
|
|
|
|
if (ob->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
int a;
|
|
|
|
|
|
|
|
|
|
IDP_LibLinkProperty(ob->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &ob->id, ob->adt);
|
|
|
|
|
|
|
|
|
|
// XXX deprecated - old animation system <<<
|
|
|
|
|
ob->ipo = newlibadr_us(fd, ob->id.lib, ob->ipo);
|
|
|
|
|
ob->action = newlibadr_us(fd, ob->id.lib, ob->action);
|
|
|
|
|
// >>> XXX deprecated - old animation system
|
|
|
|
|
|
|
|
|
|
ob->parent = newlibadr(fd, ob->id.lib, ob->parent);
|
|
|
|
|
ob->track = newlibadr(fd, ob->id.lib, ob->track);
|
|
|
|
|
ob->poselib = newlibadr_us(fd, ob->id.lib, ob->poselib);
|
|
|
|
|
|
|
|
|
|
/* 2.8x drops support for non-empty dupli instances. */
|
|
|
|
|
if (ob->type == OB_EMPTY) {
|
|
|
|
|
ob->instance_collection = newlibadr_us(fd, ob->id.lib, ob->instance_collection);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-06-04 15:18:37 +02:00
|
|
|
if (ob->instance_collection != NULL) {
|
|
|
|
|
ID *id = newlibadr(fd, ob->id.lib, ob->instance_collection);
|
|
|
|
|
blo_reportf_wrap(fd->reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
TIP_("Non-Empty object '%s' cannot duplicate collection '%s' "
|
|
|
|
|
"anymore in Blender 2.80, removed instancing"),
|
|
|
|
|
ob->id.name + 2,
|
|
|
|
|
id->name + 2);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
ob->instance_collection = NULL;
|
|
|
|
|
ob->transflag &= ~OB_DUPLICOLLECTION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ob->proxy = newlibadr_us(fd, ob->id.lib, ob->proxy);
|
|
|
|
|
if (ob->proxy) {
|
|
|
|
|
/* paranoia check, actually a proxy_from pointer should never be written... */
|
|
|
|
|
if (ob->proxy->id.lib == NULL) {
|
|
|
|
|
ob->proxy->proxy_from = NULL;
|
|
|
|
|
ob->proxy = NULL;
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ob->id.lib) {
|
2019-04-17 06:17:24 +02:00
|
|
|
printf("Proxy lost from object %s lib %s\n", ob->id.name + 2, ob->id.lib->name);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
printf("Proxy lost from object %s lib <NONE>\n", ob->id.name + 2);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* this triggers object_update to always use a copy */
|
|
|
|
|
ob->proxy->proxy_from = ob;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ob->proxy_group = newlibadr(fd, ob->id.lib, ob->proxy_group);
|
|
|
|
|
|
|
|
|
|
void *poin = ob->data;
|
|
|
|
|
ob->data = newlibadr_us(fd, ob->id.lib, ob->data);
|
|
|
|
|
|
|
|
|
|
if (ob->data == NULL && poin != NULL) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ob->id.lib) {
|
2019-04-17 06:17:24 +02:00
|
|
|
printf("Can't find obdata of %s lib %s\n", ob->id.name + 2, ob->id.lib->name);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
printf("Object %s lost data.\n", ob->id.name + 2);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
ob->type = OB_EMPTY;
|
|
|
|
|
warn = true;
|
|
|
|
|
|
|
|
|
|
if (ob->pose) {
|
|
|
|
|
/* we can't call #BKE_pose_free() here because of library linking
|
|
|
|
|
* freeing will recurse down into every pose constraints ID pointers
|
|
|
|
|
* which are not always valid, so for now free directly and suffer
|
|
|
|
|
* some leaked memory rather then crashing immediately
|
|
|
|
|
* while bad this _is_ an exceptional case - campbell */
|
2012-05-30 09:27:16 +00:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_pose_free(ob->pose);
|
2012-05-30 09:27:16 +00:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(ob->pose);
|
2012-05-30 09:27:16 +00:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
ob->pose = NULL;
|
|
|
|
|
ob->mode &= ~OB_MODE_POSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
for (a = 0; a < ob->totcol; a++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ob->mat[a] = newlibadr_us(fd, ob->id.lib, ob->mat[a]);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* When the object is local and the data is library its possible
|
|
|
|
|
* the material list size gets out of sync. [#22663] */
|
|
|
|
|
if (ob->data && ob->id.lib != ((ID *)ob->data)->lib) {
|
|
|
|
|
const short *totcol_data = give_totcolp(ob);
|
|
|
|
|
/* Only expand so as not to loose any object materials that might be set. */
|
|
|
|
|
if (totcol_data && (*totcol_data > ob->totcol)) {
|
|
|
|
|
/* printf("'%s' %d -> %d\n", ob->id.name, ob->totcol, *totcol_data); */
|
|
|
|
|
BKE_material_resize_object(main, ob, *totcol_data, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ob->gpd = newlibadr_us(fd, ob->id.lib, ob->gpd);
|
|
|
|
|
|
|
|
|
|
ob->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
/* if id.us==0 a new base will be created later on */
|
|
|
|
|
|
|
|
|
|
/* WARNING! Also check expand_object(), should reflect the stuff below. */
|
|
|
|
|
lib_link_pose(fd, main, ob, ob->pose);
|
|
|
|
|
lib_link_constraints(fd, &ob->id, &ob->constraints);
|
|
|
|
|
|
|
|
|
|
// XXX deprecated - old animation system <<<
|
|
|
|
|
lib_link_constraint_channels(fd, &ob->id, &ob->constraintChannels);
|
|
|
|
|
lib_link_nlastrips(fd, &ob->id, &ob->nlastrips);
|
|
|
|
|
// >>> XXX deprecated - old animation system
|
|
|
|
|
|
|
|
|
|
for (PartEff *paf = ob->effect.first; paf; paf = paf->next) {
|
|
|
|
|
if (paf->type == EFF_PARTICLE) {
|
|
|
|
|
paf->group = newlibadr_us(fd, ob->id.lib, paf->group);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(
|
|
|
|
|
ob, eModifierType_Fluidsim);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fluidmd && fluidmd->fss) {
|
2019-04-17 06:17:24 +02:00
|
|
|
fluidmd->fss->ipo = newlibadr_us(
|
|
|
|
|
fd, ob->id.lib, fluidmd->fss->ipo); // XXX deprecated - old animation system
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
SmokeModifierData *smd = (SmokeModifierData *)modifiers_findByType(ob,
|
|
|
|
|
eModifierType_Smoke);
|
|
|
|
|
|
|
|
|
|
if (smd && (smd->type == MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
|
|
|
|
|
smd->domain->flags |=
|
|
|
|
|
MOD_SMOKE_FILE_LOAD; /* flag for refreshing the simulation after loading */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* texture field */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ob->pd) {
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_partdeflect(fd, &ob->id, ob->pd);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (ob->soft) {
|
|
|
|
|
ob->soft->collision_group = newlibadr(fd, ob->id.lib, ob->soft->collision_group);
|
|
|
|
|
|
|
|
|
|
ob->soft->effector_weights->group = newlibadr(
|
|
|
|
|
fd, ob->id.lib, ob->soft->effector_weights->group);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem);
|
|
|
|
|
lib_link_modifiers(fd, ob);
|
|
|
|
|
lib_link_gpencil_modifiers(fd, ob);
|
|
|
|
|
lib_link_shaderfxs(fd, ob);
|
|
|
|
|
|
|
|
|
|
if (ob->rigidbody_constraint) {
|
|
|
|
|
ob->rigidbody_constraint->ob1 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob1);
|
|
|
|
|
ob->rigidbody_constraint->ob2 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
LodLevel *level;
|
|
|
|
|
for (level = ob->lodlevels.first; level; level = level->next) {
|
|
|
|
|
level->source = newlibadr(fd, ob->id.lib, level->source);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!level->source && level == ob->lodlevels.first) {
|
2019-04-17 06:17:24 +02:00
|
|
|
level->source = ob;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (warn) {
|
|
|
|
|
BKE_report(fd->reports, RPT_WARNING, "Warning in console");
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/* direct data for cache */
|
|
|
|
|
static void direct_link_motionpath(FileData *fd, bMotionPath *mpath)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* sanity check */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mpath == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-02-22 18:15:56 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink points cache */
|
|
|
|
|
mpath->points = newdataadr(fd, mpath->points);
|
2019-02-22 18:15:56 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
mpath->points_vbo = NULL;
|
|
|
|
|
mpath->batch_line = NULL;
|
|
|
|
|
mpath->batch_points = NULL;
|
2019-02-22 18:15:56 +11:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
Point Cache Refactoring
=======================
Caching and Baking:
- The point cache is now cleared on DAG_object_flush_update(), and not cleared for time dependency graph updates.
- There is now a Bake button instead of Protect. Also cache start and end frames were added to softbody and particles.
- The cloth autoprotect feature was removed.
- The Ctrl+B menu now also bakes cloth and particles next to softbody and fluids. Additionally there are now frree bake and free cache menu entries.
- The point cache api has been changed. There is now a PTCacheID struct for each point cache type that can be filled and then used to call the point cache functions.
- PointCache struct was added to DNA and is automatically allocated for each physics type.
- Soft body now supports Bake Editing just like cloth.
- Tried to make the systems deal consistently with time ipo's and offsets. Still not sure it all works correct, but too complicated to solve completely now.
Library Linking:
- Added some more warnings to prevent editing settings on library linked objects.
- Linked objects now read from the cache located next to the original library file, and never write to it. This restores old behavior for softbodies. For local simulation the mesh and not the object should be linked.
- Dupligroups and proxies can't create local point caches at the moment, how to implement that I'm not sure. We probably need a proxy point cache for that to work (ugh).
Physics UI:
- Renamed deflection panel to collision for consistency and reorganized the buttons. Also removed some softbody collision buttons from the softbody panel that were duplicated in this panel for cloth.
- Tweaked field panel buttons to not jump around when changing options.
- Tabbing e.g. Soft Body Collision into the Soft Body panel, it now only shows Collision to make the panel names readable.
- I tried to make enabled/disabling physics more consistent, since all three system did things different. Now the two modifier buttons to enable the modifier for the viewport and rendering are also duplicated in the physics panels. Toggling the Soft Body and Cloth buttons now both remove their modifiers.
- Fixed modifier error drawing glitch.
Particles:
- Particles are now recalculated more often than before. Previously it did partial updates based on the changes, but that doesn't work well with DAG_object_flush_update() ..
- Fixed memory leak loading keyed particle system. Now keys are not written to file anymore but always created after loading.
- Make particle threads work with autothreads.
Continue Physics:
- The timeline play now has a Continue Physics option in the playback menu, which keeps the simulations going without writing them to the cache.
- This doesn't always work that well, some changes are not immediately updated, but this can be improved later. Still it's fun to get a feel for the physics.
Todo:
- Point cache can get out of sync with and undo and changing a file without saving it.
- Change the point cache file format to store a version (so old point cache files can be either converted or at least ignored), and to do correct endian conversion.
- Menu item and/or buttons for Ctrl+B.
- A system("rm ..") was changed to remove() since the former is very slow for clearing point caches. These system() calls were already giving trouble in a bug in the tracker, but really most use of this system("") should be changed and tested.
- The Soft Body Collision and Clot Collision panel titles don't mention there's point cache settings there too, doing that makes them unreadable with the default panel setup.. but may need to make the names longer anyway.
2008-04-10 11:39:20 +00:00
|
|
|
static void direct_link_pose(FileData *fd, bPose *pose)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bPoseChannel *pchan;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!pose) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &pose->chanbase);
|
|
|
|
|
link_list(fd, &pose->agroups);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
pose->chanhash = NULL;
|
|
|
|
|
pose->chan_array = NULL;
|
2010-03-26 10:33:53 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
|
pchan->bone = NULL;
|
|
|
|
|
pchan->parent = newdataadr(fd, pchan->parent);
|
|
|
|
|
pchan->child = newdataadr(fd, pchan->child);
|
|
|
|
|
pchan->custom_tx = newdataadr(fd, pchan->custom_tx);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
pchan->bbone_prev = newdataadr(fd, pchan->bbone_prev);
|
|
|
|
|
pchan->bbone_next = newdataadr(fd, pchan->bbone_next);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_constraints(fd, &pchan->constraints);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
pchan->prop = newdataadr(fd, pchan->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&pchan->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
pchan->mpath = newdataadr(fd, pchan->mpath);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (pchan->mpath) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_motionpath(fd, pchan->mpath);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&pchan->iktree);
|
|
|
|
|
BLI_listbase_clear(&pchan->siktree);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* in case this value changes in future, clamp else we get undefined behavior */
|
|
|
|
|
CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
|
2017-05-03 08:34:24 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
pchan->draw_data = NULL;
|
2019-04-18 21:19:57 +03:00
|
|
|
BKE_pose_channel_runtime_reset(&pchan->runtime);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
pose->ikdata = NULL;
|
|
|
|
|
if (pose->ikparam != NULL) {
|
|
|
|
|
pose->ikparam = newdataadr(fd, pose->ikparam);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ModifierData *md;
|
|
|
|
|
|
|
|
|
|
link_list(fd, lb);
|
|
|
|
|
|
|
|
|
|
for (md = lb->first; md; md = md->next) {
|
|
|
|
|
md->error = NULL;
|
|
|
|
|
md->runtime = NULL;
|
|
|
|
|
|
|
|
|
|
/* if modifiers disappear, or for upward compatibility */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (NULL == modifierType_getInfo(md->type)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
md->type = eModifierType_None;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (md->type == eModifierType_Subsurf) {
|
|
|
|
|
SubsurfModifierData *smd = (SubsurfModifierData *)md;
|
|
|
|
|
|
|
|
|
|
smd->emCache = smd->mCache = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Armature) {
|
|
|
|
|
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
|
|
|
|
|
|
|
|
|
amd->prevCos = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Cloth) {
|
|
|
|
|
ClothModifierData *clmd = (ClothModifierData *)md;
|
|
|
|
|
|
|
|
|
|
clmd->clothObject = NULL;
|
|
|
|
|
clmd->hairdata = NULL;
|
|
|
|
|
|
|
|
|
|
clmd->sim_parms = newdataadr(fd, clmd->sim_parms);
|
|
|
|
|
clmd->coll_parms = newdataadr(fd, clmd->coll_parms);
|
|
|
|
|
|
|
|
|
|
direct_link_pointcache_list(fd, &clmd->ptcaches, &clmd->point_cache, 0);
|
|
|
|
|
|
|
|
|
|
if (clmd->sim_parms) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (clmd->sim_parms->presets > 10) {
|
2019-04-17 06:17:24 +02:00
|
|
|
clmd->sim_parms->presets = 0;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
clmd->sim_parms->reset = 0;
|
|
|
|
|
|
|
|
|
|
clmd->sim_parms->effector_weights = newdataadr(fd, clmd->sim_parms->effector_weights);
|
|
|
|
|
|
|
|
|
|
if (!clmd->sim_parms->effector_weights) {
|
|
|
|
|
clmd->sim_parms->effector_weights = BKE_effector_add_weights(NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clmd->solver_result = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Fluidsim) {
|
|
|
|
|
FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
|
|
|
|
|
|
|
|
|
|
fluidmd->fss = newdataadr(fd, fluidmd->fss);
|
|
|
|
|
if (fluidmd->fss) {
|
|
|
|
|
fluidmd->fss->fmd = fluidmd;
|
|
|
|
|
fluidmd->fss->meshVelocities = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Smoke) {
|
|
|
|
|
SmokeModifierData *smd = (SmokeModifierData *)md;
|
|
|
|
|
|
|
|
|
|
if (smd->type == MOD_SMOKE_TYPE_DOMAIN) {
|
|
|
|
|
smd->flow = NULL;
|
|
|
|
|
smd->coll = NULL;
|
|
|
|
|
smd->domain = newdataadr(fd, smd->domain);
|
|
|
|
|
smd->domain->smd = smd;
|
|
|
|
|
|
|
|
|
|
smd->domain->fluid = NULL;
|
|
|
|
|
smd->domain->fluid_mutex = BLI_rw_mutex_alloc();
|
|
|
|
|
smd->domain->wt = NULL;
|
|
|
|
|
smd->domain->shadow = NULL;
|
|
|
|
|
smd->domain->tex = NULL;
|
|
|
|
|
smd->domain->tex_shadow = NULL;
|
|
|
|
|
smd->domain->tex_flame = NULL;
|
|
|
|
|
smd->domain->tex_flame_coba = NULL;
|
|
|
|
|
smd->domain->tex_coba = NULL;
|
|
|
|
|
smd->domain->tex_field = NULL;
|
|
|
|
|
smd->domain->tex_velocity_x = NULL;
|
|
|
|
|
smd->domain->tex_velocity_y = NULL;
|
|
|
|
|
smd->domain->tex_velocity_z = NULL;
|
|
|
|
|
smd->domain->tex_wt = NULL;
|
|
|
|
|
smd->domain->coba = newdataadr(fd, smd->domain->coba);
|
|
|
|
|
|
|
|
|
|
smd->domain->effector_weights = newdataadr(fd, smd->domain->effector_weights);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!smd->domain->effector_weights) {
|
2019-04-17 06:17:24 +02:00
|
|
|
smd->domain->effector_weights = BKE_effector_add_weights(NULL);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
direct_link_pointcache_list(
|
|
|
|
|
fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0]), 1);
|
|
|
|
|
|
|
|
|
|
/* Smoke uses only one cache from now on, so store pointer convert */
|
|
|
|
|
if (smd->domain->ptcaches[1].first || smd->domain->point_cache[1]) {
|
|
|
|
|
if (smd->domain->point_cache[1]) {
|
|
|
|
|
PointCache *cache = newdataadr(fd, smd->domain->point_cache[1]);
|
|
|
|
|
if (cache->flag & PTCACHE_FAKE_SMOKE) {
|
|
|
|
|
/* Smoke was already saved in "new format" and this cache is a fake one. */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
printf(
|
|
|
|
|
"High resolution smoke cache not available due to pointcache update. Please "
|
|
|
|
|
"reset the simulation.\n");
|
|
|
|
|
}
|
|
|
|
|
BKE_ptcache_free(cache);
|
|
|
|
|
}
|
|
|
|
|
BLI_listbase_clear(&smd->domain->ptcaches[1]);
|
|
|
|
|
smd->domain->point_cache[1] = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (smd->type == MOD_SMOKE_TYPE_FLOW) {
|
|
|
|
|
smd->domain = NULL;
|
|
|
|
|
smd->coll = NULL;
|
|
|
|
|
smd->flow = newdataadr(fd, smd->flow);
|
|
|
|
|
smd->flow->smd = smd;
|
|
|
|
|
smd->flow->mesh = NULL;
|
|
|
|
|
smd->flow->verts_old = NULL;
|
|
|
|
|
smd->flow->numverts = 0;
|
|
|
|
|
smd->flow->psys = newdataadr(fd, smd->flow->psys);
|
|
|
|
|
}
|
|
|
|
|
else if (smd->type == MOD_SMOKE_TYPE_COLL) {
|
|
|
|
|
smd->flow = NULL;
|
|
|
|
|
smd->domain = NULL;
|
|
|
|
|
smd->coll = newdataadr(fd, smd->coll);
|
|
|
|
|
if (smd->coll) {
|
|
|
|
|
smd->coll->smd = smd;
|
|
|
|
|
smd->coll->verts_old = NULL;
|
|
|
|
|
smd->coll->numverts = 0;
|
|
|
|
|
smd->coll->mesh = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
smd->type = 0;
|
|
|
|
|
smd->flow = NULL;
|
|
|
|
|
smd->domain = NULL;
|
|
|
|
|
smd->coll = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_DynamicPaint) {
|
|
|
|
|
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
|
|
|
|
|
|
|
|
|
|
if (pmd->canvas) {
|
|
|
|
|
pmd->canvas = newdataadr(fd, pmd->canvas);
|
|
|
|
|
pmd->canvas->pmd = pmd;
|
|
|
|
|
pmd->canvas->flags &= ~MOD_DPAINT_BAKING; /* just in case */
|
|
|
|
|
|
|
|
|
|
if (pmd->canvas->surfaces.first) {
|
|
|
|
|
DynamicPaintSurface *surface;
|
|
|
|
|
link_list(fd, &pmd->canvas->surfaces);
|
|
|
|
|
|
|
|
|
|
for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
|
|
|
|
|
surface->canvas = pmd->canvas;
|
|
|
|
|
surface->data = NULL;
|
|
|
|
|
direct_link_pointcache_list(fd, &(surface->ptcaches), &(surface->pointcache), 1);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!(surface->effector_weights = newdataadr(fd, surface->effector_weights))) {
|
2019-04-17 06:17:24 +02:00
|
|
|
surface->effector_weights = BKE_effector_add_weights(NULL);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pmd->brush) {
|
|
|
|
|
pmd->brush = newdataadr(fd, pmd->brush);
|
|
|
|
|
pmd->brush->pmd = pmd;
|
|
|
|
|
pmd->brush->psys = newdataadr(fd, pmd->brush->psys);
|
|
|
|
|
pmd->brush->paint_ramp = newdataadr(fd, pmd->brush->paint_ramp);
|
|
|
|
|
pmd->brush->vel_ramp = newdataadr(fd, pmd->brush->vel_ramp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Collision) {
|
|
|
|
|
CollisionModifierData *collmd = (CollisionModifierData *)md;
|
2012-06-30 22:49:33 +00:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
// TODO: CollisionModifier should use pointcache
|
|
|
|
|
// + have proper reset events before enabling this
|
|
|
|
|
collmd->x = newdataadr(fd, collmd->x);
|
|
|
|
|
collmd->xnew = newdataadr(fd, collmd->xnew);
|
|
|
|
|
collmd->mfaces = newdataadr(fd, collmd->mfaces);
|
|
|
|
|
|
|
|
|
|
collmd->current_x = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_x");
|
|
|
|
|
collmd->current_xnew = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_xnew");
|
|
|
|
|
collmd->current_v = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_v");
|
2012-06-30 22:49:33 +00:00
|
|
|
#endif
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
collmd->x = NULL;
|
|
|
|
|
collmd->xnew = NULL;
|
|
|
|
|
collmd->current_x = NULL;
|
|
|
|
|
collmd->current_xnew = NULL;
|
|
|
|
|
collmd->current_v = NULL;
|
|
|
|
|
collmd->time_x = collmd->time_xnew = -1000;
|
|
|
|
|
collmd->mvert_num = 0;
|
|
|
|
|
collmd->tri_num = 0;
|
|
|
|
|
collmd->is_static = false;
|
|
|
|
|
collmd->bvhtree = NULL;
|
|
|
|
|
collmd->tri = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Surface) {
|
|
|
|
|
SurfaceModifierData *surmd = (SurfaceModifierData *)md;
|
|
|
|
|
|
|
|
|
|
surmd->mesh = NULL;
|
|
|
|
|
surmd->bvhtree = NULL;
|
|
|
|
|
surmd->x = NULL;
|
|
|
|
|
surmd->v = NULL;
|
|
|
|
|
surmd->numverts = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Hook) {
|
|
|
|
|
HookModifierData *hmd = (HookModifierData *)md;
|
|
|
|
|
|
|
|
|
|
hmd->indexar = newdataadr(fd, hmd->indexar);
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
BLI_endian_switch_int32_array(hmd->indexar, hmd->totindex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hmd->curfalloff = newdataadr(fd, hmd->curfalloff);
|
|
|
|
|
if (hmd->curfalloff) {
|
|
|
|
|
direct_link_curvemapping(fd, hmd->curfalloff);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_ParticleSystem) {
|
|
|
|
|
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
|
|
|
|
|
|
2019-06-21 11:49:43 +02:00
|
|
|
psmd->mesh_final = NULL;
|
|
|
|
|
psmd->mesh_original = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
psmd->psys = newdataadr(fd, psmd->psys);
|
|
|
|
|
psmd->flag &= ~eParticleSystemFlag_psys_updated;
|
|
|
|
|
psmd->flag |= eParticleSystemFlag_file_loaded;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Explode) {
|
|
|
|
|
ExplodeModifierData *psmd = (ExplodeModifierData *)md;
|
|
|
|
|
|
|
|
|
|
psmd->facepa = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_MeshDeform) {
|
|
|
|
|
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
|
|
|
|
|
|
|
|
|
|
mmd->bindinfluences = newdataadr(fd, mmd->bindinfluences);
|
|
|
|
|
mmd->bindoffsets = newdataadr(fd, mmd->bindoffsets);
|
|
|
|
|
mmd->bindcagecos = newdataadr(fd, mmd->bindcagecos);
|
|
|
|
|
mmd->dyngrid = newdataadr(fd, mmd->dyngrid);
|
|
|
|
|
mmd->dyninfluences = newdataadr(fd, mmd->dyninfluences);
|
|
|
|
|
mmd->dynverts = newdataadr(fd, mmd->dynverts);
|
|
|
|
|
|
|
|
|
|
mmd->bindweights = newdataadr(fd, mmd->bindweights);
|
|
|
|
|
mmd->bindcos = newdataadr(fd, mmd->bindcos);
|
|
|
|
|
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mmd->bindoffsets) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_endian_switch_int32_array(mmd->bindoffsets, mmd->totvert + 1);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (mmd->bindcagecos) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_endian_switch_float_array(mmd->bindcagecos, mmd->totcagevert * 3);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (mmd->dynverts) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_endian_switch_int32_array(mmd->dynverts, mmd->totvert);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (mmd->bindweights) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_endian_switch_float_array(mmd->bindweights, mmd->totvert);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (mmd->bindcos) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_endian_switch_float_array(mmd->bindcos, mmd->totcagevert * 3);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Ocean) {
|
|
|
|
|
OceanModifierData *omd = (OceanModifierData *)md;
|
|
|
|
|
omd->oceancache = NULL;
|
|
|
|
|
omd->ocean = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_Warp) {
|
|
|
|
|
WarpModifierData *tmd = (WarpModifierData *)md;
|
|
|
|
|
|
|
|
|
|
tmd->curfalloff = newdataadr(fd, tmd->curfalloff);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (tmd->curfalloff) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, tmd->curfalloff);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_WeightVGEdit) {
|
|
|
|
|
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
|
|
|
|
|
|
|
|
|
|
wmd->cmap_curve = newdataadr(fd, wmd->cmap_curve);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (wmd->cmap_curve) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, wmd->cmap_curve);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_LaplacianDeform) {
|
|
|
|
|
LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
|
|
|
|
|
|
|
|
|
|
lmd->vertexco = newdataadr(fd, lmd->vertexco);
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
BLI_endian_switch_float_array(lmd->vertexco, lmd->total_verts * 3);
|
|
|
|
|
}
|
|
|
|
|
lmd->cache_system = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_CorrectiveSmooth) {
|
|
|
|
|
CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
|
|
|
|
|
|
|
|
|
|
if (csmd->bind_coords) {
|
|
|
|
|
csmd->bind_coords = newdataadr(fd, csmd->bind_coords);
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
BLI_endian_switch_float_array((float *)csmd->bind_coords, csmd->bind_coords_num * 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* runtime only */
|
|
|
|
|
csmd->delta_cache = NULL;
|
|
|
|
|
csmd->delta_cache_num = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_MeshSequenceCache) {
|
|
|
|
|
MeshSeqCacheModifierData *msmcd = (MeshSeqCacheModifierData *)md;
|
|
|
|
|
msmcd->reader = NULL;
|
2019-04-04 15:07:37 +02:00
|
|
|
msmcd->reader_object_path[0] = '\0';
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else if (md->type == eModifierType_SurfaceDeform) {
|
|
|
|
|
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
|
|
|
|
|
|
|
|
|
smd->verts = newdataadr(fd, smd->verts);
|
|
|
|
|
|
|
|
|
|
if (smd->verts) {
|
|
|
|
|
for (int i = 0; i < smd->numverts; i++) {
|
|
|
|
|
smd->verts[i].binds = newdataadr(fd, smd->verts[i].binds);
|
|
|
|
|
|
|
|
|
|
if (smd->verts[i].binds) {
|
|
|
|
|
for (int j = 0; j < smd->verts[i].numbinds; j++) {
|
|
|
|
|
smd->verts[i].binds[j].vert_inds = newdataadr(fd, smd->verts[i].binds[j].vert_inds);
|
|
|
|
|
smd->verts[i].binds[j].vert_weights = newdataadr(
|
|
|
|
|
fd, smd->verts[i].binds[j].vert_weights);
|
|
|
|
|
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (smd->verts[i].binds[j].vert_inds) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_endian_switch_uint32_array(smd->verts[i].binds[j].vert_inds,
|
|
|
|
|
smd->verts[i].binds[j].numverts);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (smd->verts[i].binds[j].vert_weights) {
|
|
|
|
|
if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID ||
|
|
|
|
|
smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI) {
|
|
|
|
|
BLI_endian_switch_float_array(smd->verts[i].binds[j].vert_weights, 3);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_endian_switch_float_array(smd->verts[i].binds[j].vert_weights,
|
|
|
|
|
smd->verts[i].binds[j].numverts);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
static void direct_link_gpencil_modifiers(FileData *fd, ListBase *lb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
GpencilModifierData *md;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, lb);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (md = lb->first; md; md = md->next) {
|
|
|
|
|
md->error = NULL;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* if modifiers disappear, or for upward compatibility */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (NULL == BKE_gpencil_modifierType_getInfo(md->type)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
md->type = eModifierType_None;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (md->type == eGpencilModifierType_Lattice) {
|
|
|
|
|
LatticeGpencilModifierData *gpmd = (LatticeGpencilModifierData *)md;
|
|
|
|
|
gpmd->cache_data = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eGpencilModifierType_Hook) {
|
|
|
|
|
HookGpencilModifierData *hmd = (HookGpencilModifierData *)md;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
hmd->curfalloff = newdataadr(fd, hmd->curfalloff);
|
|
|
|
|
if (hmd->curfalloff) {
|
|
|
|
|
direct_link_curvemapping(fd, hmd->curfalloff);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (md->type == eGpencilModifierType_Thick) {
|
|
|
|
|
ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
gpmd->curve_thickness = newdataadr(fd, gpmd->curve_thickness);
|
|
|
|
|
if (gpmd->curve_thickness) {
|
|
|
|
|
direct_link_curvemapping(fd, gpmd->curve_thickness);
|
|
|
|
|
/* initialize the curve. Maybe this could be moved to modififer logic */
|
2019-08-07 03:21:55 +10:00
|
|
|
BKE_curvemapping_initialize(gpmd->curve_thickness);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_shaderfxs(FileData *fd, ListBase *lb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ShaderFxData *fx;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, lb);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (fx = lb->first; fx; fx = fx->next) {
|
|
|
|
|
fx->error = NULL;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* if shader disappear, or for upward compatibility */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (NULL == BKE_shaderfxType_getInfo(fx->type)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
fx->type = eShaderFxType_None;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void direct_link_object(FileData *fd, Object *ob)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
PartEff *paf;
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* XXX This should not be needed - but seems like it can happen in some cases,
|
|
|
|
|
* so for now play safe. */
|
2019-04-17 06:17:24 +02:00
|
|
|
ob->proxy_from = NULL;
|
|
|
|
|
|
|
|
|
|
/* loading saved files with editmode enabled works, but for undo we like
|
|
|
|
|
* to stay in object mode during undo presses so keep editmode disabled.
|
|
|
|
|
*
|
|
|
|
|
* Also when linking in a file don't allow edit and pose modes.
|
|
|
|
|
* See [#34776, #42780] for more information.
|
|
|
|
|
*/
|
|
|
|
|
if (fd->memfile || (ob->id.tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT))) {
|
|
|
|
|
ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT);
|
|
|
|
|
if (!fd->memfile) {
|
|
|
|
|
ob->mode &= ~OB_MODE_POSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ob->adt = newdataadr(fd, ob->adt);
|
|
|
|
|
direct_link_animdata(fd, ob->adt);
|
|
|
|
|
|
|
|
|
|
ob->pose = newdataadr(fd, ob->pose);
|
|
|
|
|
direct_link_pose(fd, ob->pose);
|
|
|
|
|
|
|
|
|
|
ob->mpath = newdataadr(fd, ob->mpath);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ob->mpath) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_motionpath(fd, ob->mpath);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
link_list(fd, &ob->defbase);
|
|
|
|
|
link_list(fd, &ob->fmaps);
|
|
|
|
|
// XXX deprecated - old animation system <<<
|
|
|
|
|
direct_link_nlastrips(fd, &ob->nlastrips);
|
|
|
|
|
link_list(fd, &ob->constraintChannels);
|
|
|
|
|
// >>> XXX deprecated - old animation system
|
|
|
|
|
|
|
|
|
|
ob->mat = newdataadr(fd, ob->mat);
|
|
|
|
|
test_pointer_array(fd, (void **)&ob->mat);
|
|
|
|
|
ob->matbits = newdataadr(fd, ob->matbits);
|
|
|
|
|
|
|
|
|
|
/* do it here, below old data gets converted */
|
|
|
|
|
direct_link_modifiers(fd, &ob->modifiers);
|
|
|
|
|
direct_link_gpencil_modifiers(fd, &ob->greasepencil_modifiers);
|
|
|
|
|
direct_link_shaderfxs(fd, &ob->shader_fx);
|
|
|
|
|
|
|
|
|
|
link_list(fd, &ob->effect);
|
|
|
|
|
paf = ob->effect.first;
|
|
|
|
|
while (paf) {
|
|
|
|
|
if (paf->type == EFF_PARTICLE) {
|
|
|
|
|
paf->keys = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (paf->type == EFF_WAVE) {
|
|
|
|
|
WaveEff *wav = (WaveEff *)paf;
|
|
|
|
|
PartEff *next = paf->next;
|
|
|
|
|
WaveModifierData *wmd = (WaveModifierData *)modifier_new(eModifierType_Wave);
|
|
|
|
|
|
|
|
|
|
wmd->damp = wav->damp;
|
|
|
|
|
wmd->flag = wav->flag;
|
|
|
|
|
wmd->height = wav->height;
|
|
|
|
|
wmd->lifetime = wav->lifetime;
|
|
|
|
|
wmd->narrow = wav->narrow;
|
|
|
|
|
wmd->speed = wav->speed;
|
|
|
|
|
wmd->startx = wav->startx;
|
|
|
|
|
wmd->starty = wav->startx;
|
|
|
|
|
wmd->timeoffs = wav->timeoffs;
|
|
|
|
|
wmd->width = wav->width;
|
|
|
|
|
|
|
|
|
|
BLI_addtail(&ob->modifiers, wmd);
|
|
|
|
|
|
|
|
|
|
BLI_remlink(&ob->effect, paf);
|
|
|
|
|
MEM_freeN(paf);
|
|
|
|
|
|
|
|
|
|
paf = next;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (paf->type == EFF_BUILD) {
|
|
|
|
|
BuildEff *baf = (BuildEff *)paf;
|
|
|
|
|
PartEff *next = paf->next;
|
|
|
|
|
BuildModifierData *bmd = (BuildModifierData *)modifier_new(eModifierType_Build);
|
|
|
|
|
|
|
|
|
|
bmd->start = baf->sfra;
|
|
|
|
|
bmd->length = baf->len;
|
|
|
|
|
bmd->randomize = 0;
|
|
|
|
|
bmd->seed = 1;
|
|
|
|
|
|
|
|
|
|
BLI_addtail(&ob->modifiers, bmd);
|
|
|
|
|
|
|
|
|
|
BLI_remlink(&ob->effect, paf);
|
|
|
|
|
MEM_freeN(paf);
|
|
|
|
|
|
|
|
|
|
paf = next;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
paf = paf->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ob->pd = newdataadr(fd, ob->pd);
|
|
|
|
|
direct_link_partdeflect(ob->pd);
|
|
|
|
|
ob->soft = newdataadr(fd, ob->soft);
|
|
|
|
|
if (ob->soft) {
|
|
|
|
|
SoftBody *sb = ob->soft;
|
|
|
|
|
|
|
|
|
|
sb->bpoint = NULL; // init pointers so it gets rebuilt nicely
|
|
|
|
|
sb->bspring = NULL;
|
|
|
|
|
sb->scratch = NULL;
|
|
|
|
|
/* although not used anymore */
|
|
|
|
|
/* still have to be loaded to be compatible with old files */
|
|
|
|
|
sb->keys = newdataadr(fd, sb->keys);
|
|
|
|
|
test_pointer_array(fd, (void **)&sb->keys);
|
|
|
|
|
if (sb->keys) {
|
|
|
|
|
int a;
|
|
|
|
|
for (a = 0; a < sb->totkey; a++) {
|
|
|
|
|
sb->keys[a] = newdataadr(fd, sb->keys[a]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sb->effector_weights = newdataadr(fd, sb->effector_weights);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!sb->effector_weights) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sb->effector_weights = BKE_effector_add_weights(NULL);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
sb->shared = newdataadr(fd, sb->shared);
|
|
|
|
|
if (sb->shared == NULL) {
|
|
|
|
|
/* Link deprecated caches if they exist, so we can use them for versioning.
|
|
|
|
|
* We should only do this when sb->shared == NULL, because those pointers
|
|
|
|
|
* are always set (for compatibility with older Blenders). We mustn't link
|
|
|
|
|
* the same pointcache twice. */
|
|
|
|
|
direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache, false);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* link caches */
|
|
|
|
|
direct_link_pointcache_list(fd, &sb->shared->ptcaches, &sb->shared->pointcache, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ob->fluidsimSettings = newdataadr(fd, ob->fluidsimSettings); /* NT */
|
|
|
|
|
|
|
|
|
|
ob->rigidbody_object = newdataadr(fd, ob->rigidbody_object);
|
|
|
|
|
if (ob->rigidbody_object) {
|
|
|
|
|
RigidBodyOb *rbo = ob->rigidbody_object;
|
|
|
|
|
/* Allocate runtime-only struct */
|
|
|
|
|
rbo->shared = MEM_callocN(sizeof(*rbo->shared), "RigidBodyObShared");
|
|
|
|
|
}
|
|
|
|
|
ob->rigidbody_constraint = newdataadr(fd, ob->rigidbody_constraint);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ob->rigidbody_constraint) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ob->rigidbody_constraint->physics_constraint = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
link_list(fd, &ob->particlesystem);
|
|
|
|
|
direct_link_particlesystems(fd, &ob->particlesystem);
|
|
|
|
|
|
|
|
|
|
direct_link_constraints(fd, &ob->constraints);
|
|
|
|
|
|
|
|
|
|
link_list(fd, &ob->hooks);
|
|
|
|
|
while (ob->hooks.first) {
|
|
|
|
|
ObHook *hook = ob->hooks.first;
|
|
|
|
|
HookModifierData *hmd = (HookModifierData *)modifier_new(eModifierType_Hook);
|
|
|
|
|
|
|
|
|
|
hook->indexar = newdataadr(fd, hook->indexar);
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
BLI_endian_switch_int32_array(hook->indexar, hook->totindex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Do conversion here because if we have loaded
|
|
|
|
|
* a hook we need to make sure it gets converted
|
|
|
|
|
* and freed, regardless of version.
|
|
|
|
|
*/
|
|
|
|
|
copy_v3_v3(hmd->cent, hook->cent);
|
|
|
|
|
hmd->falloff = hook->falloff;
|
|
|
|
|
hmd->force = hook->force;
|
|
|
|
|
hmd->indexar = hook->indexar;
|
|
|
|
|
hmd->object = hook->parent;
|
|
|
|
|
memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv));
|
|
|
|
|
hmd->totindex = hook->totindex;
|
|
|
|
|
|
|
|
|
|
BLI_addhead(&ob->modifiers, hmd);
|
|
|
|
|
BLI_remlink(&ob->hooks, hook);
|
|
|
|
|
|
|
|
|
|
modifier_unique_name(&ob->modifiers, (ModifierData *)hmd);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(hook);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ob->iuser = newdataadr(fd, ob->iuser);
|
|
|
|
|
if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE && !ob->iuser) {
|
|
|
|
|
BKE_object_empty_draw_type_set(ob, ob->empty_drawtype);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ob->derivedDeform = NULL;
|
|
|
|
|
ob->derivedFinal = NULL;
|
|
|
|
|
BKE_object_runtime_reset(ob);
|
|
|
|
|
link_list(fd, &ob->pc_ids);
|
|
|
|
|
|
|
|
|
|
/* in case this value changes in future, clamp else we get undefined behavior */
|
|
|
|
|
CLAMP(ob->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
|
|
|
|
|
|
|
|
|
|
if (ob->sculpt) {
|
|
|
|
|
ob->sculpt = NULL;
|
|
|
|
|
/* Only create data on undo, otherwise rely on editor mode switching. */
|
|
|
|
|
if (fd->memfile && (ob->mode & OB_MODE_ALL_SCULPT)) {
|
|
|
|
|
BKE_object_sculpt_data_create(ob);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
link_list(fd, &ob->lodlevels);
|
|
|
|
|
ob->currentlod = ob->lodlevels.first;
|
|
|
|
|
|
|
|
|
|
ob->preview = direct_link_preview_image(fd, ob->preview);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *view_settings)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
view_settings->curve_mapping = newdataadr(fd, view_settings->curve_mapping);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (view_settings->curve_mapping) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, view_settings->curve_mapping);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read View Layer (Collection Data)
|
|
|
|
|
* \{ */
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
|
|
|
|
static void direct_link_layer_collections(FileData *fd, ListBase *lb, bool master)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, lb);
|
|
|
|
|
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
2019-04-17 06:17:24 +02:00
|
|
|
lc->scene_collection = newdataadr(fd, lc->scene_collection);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
|
|
|
|
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Master collection is not a real data-lock. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (master) {
|
|
|
|
|
lc->collection = newdataadr(fd, lc->collection);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_layer_collections(fd, &lc->layer_collections, false);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
view_layer->stats = NULL;
|
|
|
|
|
link_list(fd, &view_layer->object_bases);
|
|
|
|
|
view_layer->basact = newdataadr(fd, view_layer->basact);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_layer_collections(fd, &view_layer->layer_collections, true);
|
|
|
|
|
view_layer->active_collection = newdataadr(fd, view_layer->active_collection);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
view_layer->id_properties = newdataadr(fd, view_layer->id_properties);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&view_layer->id_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &(view_layer->freestyle_config.modules));
|
|
|
|
|
link_list(fd, &(view_layer->freestyle_config.linesets));
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&view_layer->drawdata);
|
|
|
|
|
view_layer->object_bases_array = NULL;
|
|
|
|
|
view_layer->object_bases_hash = NULL;
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void lib_link_layer_collection(FileData *fd,
|
|
|
|
|
Library *lib,
|
|
|
|
|
LayerCollection *layer_collection,
|
|
|
|
|
bool master)
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
{
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Master collection is not a real data-lock. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (!master) {
|
|
|
|
|
layer_collection->collection = newlibadr(fd, lib, layer_collection->collection);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (LayerCollection *layer_collection_nested = layer_collection->layer_collections.first;
|
|
|
|
|
layer_collection_nested != NULL;
|
|
|
|
|
layer_collection_nested = layer_collection_nested->next) {
|
|
|
|
|
lib_link_layer_collection(fd, lib, layer_collection_nested, false);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_view_layer(FileData *fd, Library *lib, ViewLayer *view_layer)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc;
|
|
|
|
|
fmc = fmc->next) {
|
|
|
|
|
fmc->script = newlibadr(fd, lib, fmc->script);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
|
|
|
|
|
fls->linestyle = newlibadr_us(fd, lib, fls->linestyle);
|
|
|
|
|
fls->group = newlibadr_us(fd, lib, fls->group);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Base *base = view_layer->object_bases.first, *base_next = NULL; base; base = base_next) {
|
|
|
|
|
base_next = base->next;
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* we only bump the use count for the collection objects */
|
|
|
|
|
base->object = newlibadr(fd, lib, base->object);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (base->object == NULL) {
|
|
|
|
|
/* Free in case linked object got lost. */
|
|
|
|
|
BLI_freelinkN(&view_layer->object_bases, base);
|
|
|
|
|
if (view_layer->basact == base) {
|
|
|
|
|
view_layer->basact = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (LayerCollection *layer_collection = view_layer->layer_collections.first;
|
|
|
|
|
layer_collection != NULL;
|
|
|
|
|
layer_collection = layer_collection->next) {
|
|
|
|
|
lib_link_layer_collection(fd, lib, layer_collection, true);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
view_layer->mat_override = newlibadr_us(fd, lib, view_layer->mat_override);
|
2019-01-06 15:22:47 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(view_layer->id_properties, fd);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Collection
|
|
|
|
|
* \{ */
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
|
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
|
|
|
|
static void direct_link_scene_collection(FileData *fd, SceneCollection *sc)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &sc->objects);
|
|
|
|
|
link_list(fd, &sc->scene_collections);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
|
|
|
|
|
direct_link_scene_collection(fd, nsc);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_scene_collection(FileData *fd, Library *lib, SceneCollection *sc)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (LinkData *link = sc->objects.first; link; link = link->next) {
|
|
|
|
|
link->data = newlibadr_us(fd, lib, link->data);
|
|
|
|
|
BLI_assert(link->data);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
|
|
|
|
|
lib_link_scene_collection(fd, lib, nsc);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static void direct_link_collection(FileData *fd, Collection *collection)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &collection->gobject);
|
|
|
|
|
link_list(fd, &collection->children);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
collection->preview = direct_link_preview_image(fd, collection->preview);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
2019-07-30 13:04:00 +02:00
|
|
|
collection->tag = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&collection->object_cache);
|
|
|
|
|
BLI_listbase_clear(&collection->parents);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
|
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
2019-04-17 06:17:24 +02:00
|
|
|
/* This runs before the very first doversion. */
|
|
|
|
|
collection->collection = newdataadr(fd, collection->collection);
|
|
|
|
|
if (collection->collection != NULL) {
|
|
|
|
|
direct_link_scene_collection(fd, collection->collection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
collection->view_layer = newdataadr(fd, collection->view_layer);
|
|
|
|
|
if (collection->view_layer != NULL) {
|
|
|
|
|
direct_link_view_layer(fd, collection->view_layer);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_collection_data(FileData *fd, Library *lib, Collection *collection)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (CollectionObject *cob = collection->gobject.first, *cob_next = NULL; cob; cob = cob_next) {
|
|
|
|
|
cob_next = cob->next;
|
|
|
|
|
cob->ob = newlibadr_us(fd, lib, cob->ob);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (cob->ob == NULL) {
|
|
|
|
|
BLI_freelinkN(&collection->gobject, cob);
|
|
|
|
|
}
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-05-22 22:51:36 +02:00
|
|
|
for (CollectionChild *child = collection->children.first; child != NULL; child = child->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
child->collection = newlibadr_us(fd, lib, child->collection);
|
|
|
|
|
}
|
2019-05-22 22:51:36 +02:00
|
|
|
|
|
|
|
|
BKE_collection_parent_relations_rebuild(collection);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_collection(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Collection *collection = main->collections.first; collection;
|
|
|
|
|
collection = collection->id.next) {
|
|
|
|
|
if (collection->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
collection->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
IDP_LibLinkProperty(collection->id.properties, fd);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
|
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
2019-04-17 06:17:24 +02:00
|
|
|
if (collection->collection) {
|
|
|
|
|
lib_link_scene_collection(fd, collection->id.lib, collection->collection);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (collection->view_layer) {
|
|
|
|
|
lib_link_view_layer(fd, collection->id.lib, collection->view_layer);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_collection_data(fd, collection->id.lib, collection);
|
|
|
|
|
}
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Scene
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2009-02-04 17:40:50 +00:00
|
|
|
/* patch for missing scene IDs, can't be in do-versions */
|
|
|
|
|
static void composite_patch(bNodeTree *ntree, Scene *scene)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bNode *node;
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (node = ntree->nodes.first; node; node = node->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (node->id == NULL && node->type == CMP_NODE_R_LAYERS) {
|
2019-04-17 06:17:24 +02:00
|
|
|
node->id = &scene->id;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-02-04 17:40:50 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-17 00:39:00 +00:00
|
|
|
static void link_paint(FileData *fd, Scene *sce, Paint *p)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (p) {
|
|
|
|
|
p->brush = newlibadr_us(fd, sce->id.lib, p->brush);
|
|
|
|
|
for (int i = 0; i < p->tool_slots_len; i++) {
|
|
|
|
|
if (p->tool_slots[i].brush != NULL) {
|
|
|
|
|
p->tool_slots[i].brush = newlibadr_us(fd, sce->id.lib, p->tool_slots[i].brush);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
p->palette = newlibadr_us(fd, sce->id.lib, p->palette);
|
|
|
|
|
p->paint_cursor = NULL;
|
2018-11-05 16:18:43 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_paint_runtime_init(sce->toolsettings, p);
|
|
|
|
|
}
|
2009-08-17 00:39:00 +00:00
|
|
|
}
|
2009-02-04 17:40:50 +00:00
|
|
|
|
2012-08-19 15:41:56 +00:00
|
|
|
static void lib_link_sequence_modifiers(FileData *fd, Scene *scene, ListBase *lb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SequenceModifierData *smd;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (smd = lb->first; smd; smd = smd->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (smd->mask_id) {
|
2019-04-17 06:17:24 +02:00
|
|
|
smd->mask_id = newlibadr_us(fd, scene->id.lib, smd->mask_id);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-10 15:02:25 +02:00
|
|
|
static void direct_link_lightcache_texture(FileData *fd, LightCacheTexture *lctex)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
lctex->tex = NULL;
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (lctex->data) {
|
|
|
|
|
lctex->data = newdataadr(fd, lctex->data);
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] *
|
|
|
|
|
lctex->tex_size[2];
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
|
|
|
|
|
BLI_endian_switch_float_array((float *)lctex->data, data_size * sizeof(float));
|
|
|
|
|
}
|
|
|
|
|
else if (lctex->data_type == LIGHTCACHETEX_UINT) {
|
|
|
|
|
BLI_endian_switch_uint32_array((uint *)lctex->data, data_size * sizeof(uint));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-10 15:02:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_lightcache(FileData *fd, LightCache *cache)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_lightcache_texture(fd, &cache->cube_tx);
|
|
|
|
|
direct_link_lightcache_texture(fd, &cache->grid_tx);
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (cache->cube_mips) {
|
|
|
|
|
cache->cube_mips = newdataadr(fd, cache->cube_mips);
|
|
|
|
|
for (int i = 0; i < cache->mips_len; ++i) {
|
|
|
|
|
direct_link_lightcache_texture(fd, &cache->cube_mips[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-10 15:02:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
cache->cube_data = newdataadr(fd, cache->cube_data);
|
|
|
|
|
cache->grid_data = newdataadr(fd, cache->grid_data);
|
2018-07-10 15:02:25 +02:00
|
|
|
}
|
|
|
|
|
|
2014-11-11 19:39:20 +01:00
|
|
|
/* check for cyclic set-scene,
|
|
|
|
|
* libs can cause this case which is normally prevented, see (T#####) */
|
|
|
|
|
#define USE_SETSCENE_CHECK
|
|
|
|
|
|
|
|
|
|
#ifdef USE_SETSCENE_CHECK
|
|
|
|
|
/**
|
|
|
|
|
* A version of #BKE_scene_validate_setscene with special checks for linked libs.
|
|
|
|
|
*/
|
|
|
|
|
static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Scene *sce_iter;
|
|
|
|
|
int a;
|
2014-11-11 19:39:20 +01:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->set == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return 1;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2014-11-11 19:39:20 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
|
|
|
|
|
if (sce_iter->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2014-11-11 19:39:20 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (a > totscene) {
|
|
|
|
|
sce->set = NULL;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-11-11 19:39:20 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return 1;
|
2014-11-11 19:39:20 +01:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_scene(FileData *fd, Main *main)
|
|
|
|
|
{
|
2014-11-11 19:39:20 +01:00
|
|
|
#ifdef USE_SETSCENE_CHECK
|
2019-04-17 06:17:24 +02:00
|
|
|
bool need_check_set = false;
|
|
|
|
|
int totscene = 0;
|
2014-11-11 19:39:20 +01:00
|
|
|
#endif
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Scene *sce = main->scenes.first; sce; sce = sce->id.next) {
|
|
|
|
|
if (sce->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
|
|
|
|
|
* of library blocks that implement this.*/
|
|
|
|
|
IDP_LibLinkProperty(sce->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &sce->id, sce->adt);
|
|
|
|
|
|
|
|
|
|
lib_link_keyingsets(fd, &sce->id, &sce->keyingsets);
|
|
|
|
|
|
|
|
|
|
sce->camera = newlibadr(fd, sce->id.lib, sce->camera);
|
|
|
|
|
sce->world = newlibadr_us(fd, sce->id.lib, sce->world);
|
|
|
|
|
sce->set = newlibadr(fd, sce->id.lib, sce->set);
|
|
|
|
|
sce->gpd = newlibadr_us(fd, sce->id.lib, sce->gpd);
|
|
|
|
|
|
|
|
|
|
link_paint(fd, sce, &sce->toolsettings->imapaint.paint);
|
2019-08-01 09:03:50 +10:00
|
|
|
if (sce->toolsettings->sculpt) {
|
2019-07-31 12:13:29 -07:00
|
|
|
link_paint(fd, sce, &sce->toolsettings->sculpt->paint);
|
2019-08-01 09:03:50 +10:00
|
|
|
}
|
|
|
|
|
if (sce->toolsettings->vpaint) {
|
2019-07-31 12:13:29 -07:00
|
|
|
link_paint(fd, sce, &sce->toolsettings->vpaint->paint);
|
2019-08-01 09:03:50 +10:00
|
|
|
}
|
|
|
|
|
if (sce->toolsettings->wpaint) {
|
2019-07-31 12:13:29 -07:00
|
|
|
link_paint(fd, sce, &sce->toolsettings->wpaint->paint);
|
2019-08-01 09:03:50 +10:00
|
|
|
}
|
|
|
|
|
if (sce->toolsettings->uvsculpt) {
|
2019-07-31 12:13:29 -07:00
|
|
|
link_paint(fd, sce, &sce->toolsettings->uvsculpt->paint);
|
2019-08-01 09:03:50 +10:00
|
|
|
}
|
|
|
|
|
if (sce->toolsettings->gp_paint) {
|
2019-07-31 12:13:29 -07:00
|
|
|
link_paint(fd, sce, &sce->toolsettings->gp_paint->paint);
|
2019-08-01 09:03:50 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->toolsettings->sculpt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->toolsettings->sculpt->gravity_object = newlibadr(
|
|
|
|
|
fd, sce->id.lib, sce->toolsettings->sculpt->gravity_object);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->toolsettings->imapaint.stencil) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->toolsettings->imapaint.stencil = newlibadr_us(
|
|
|
|
|
fd, sce->id.lib, sce->toolsettings->imapaint.stencil);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->toolsettings->imapaint.clone) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->toolsettings->imapaint.clone = newlibadr_us(
|
|
|
|
|
fd, sce->id.lib, sce->toolsettings->imapaint.clone);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->toolsettings->imapaint.canvas) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->toolsettings->imapaint.canvas = newlibadr_us(
|
|
|
|
|
fd, sce->id.lib, sce->toolsettings->imapaint.canvas);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
sce->toolsettings->particle.shape_object = newlibadr(
|
|
|
|
|
fd, sce->id.lib, sce->toolsettings->particle.shape_object);
|
|
|
|
|
|
|
|
|
|
sce->toolsettings->gp_sculpt.guide.reference_object = newlibadr(
|
|
|
|
|
fd, sce->id.lib, sce->toolsettings->gp_sculpt.guide.reference_object);
|
|
|
|
|
|
|
|
|
|
for (Base *base_legacy_next, *base_legacy = sce->base.first; base_legacy;
|
|
|
|
|
base_legacy = base_legacy_next) {
|
|
|
|
|
base_legacy_next = base_legacy->next;
|
|
|
|
|
|
|
|
|
|
base_legacy->object = newlibadr_us(fd, sce->id.lib, base_legacy->object);
|
|
|
|
|
|
|
|
|
|
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_legacy);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (base_legacy == sce->basact) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->basact = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(base_legacy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Sequence *seq;
|
|
|
|
|
SEQ_BEGIN (sce->ed, seq) {
|
|
|
|
|
IDP_LibLinkProperty(seq->prop, fd);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (seq->ipo) {
|
2019-04-17 06:17:24 +02:00
|
|
|
seq->ipo = newlibadr_us(
|
|
|
|
|
fd, sce->id.lib, seq->ipo); // XXX deprecated - old animation system
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
seq->scene_sound = NULL;
|
|
|
|
|
if (seq->scene) {
|
|
|
|
|
seq->scene = newlibadr(fd, sce->id.lib, seq->scene);
|
2019-06-04 16:52:48 +02:00
|
|
|
seq->scene_sound = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
if (seq->clip) {
|
|
|
|
|
seq->clip = newlibadr_us(fd, sce->id.lib, seq->clip);
|
|
|
|
|
}
|
|
|
|
|
if (seq->mask) {
|
|
|
|
|
seq->mask = newlibadr_us(fd, sce->id.lib, seq->mask);
|
|
|
|
|
}
|
|
|
|
|
if (seq->scene_camera) {
|
|
|
|
|
seq->scene_camera = newlibadr(fd, sce->id.lib, seq->scene_camera);
|
|
|
|
|
}
|
|
|
|
|
if (seq->sound) {
|
|
|
|
|
seq->scene_sound = NULL;
|
|
|
|
|
if (seq->type == SEQ_TYPE_SOUND_HD) {
|
|
|
|
|
seq->type = SEQ_TYPE_SOUND_RAM;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
seq->sound = newlibadr(fd, sce->id.lib, seq->sound);
|
|
|
|
|
}
|
|
|
|
|
if (seq->sound) {
|
|
|
|
|
id_us_plus_no_lib((ID *)seq->sound);
|
2019-06-04 16:52:48 +02:00
|
|
|
seq->scene_sound = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (seq->type == SEQ_TYPE_TEXT) {
|
|
|
|
|
TextVars *t = seq->effectdata;
|
|
|
|
|
t->text_font = newlibadr_us(fd, sce->id.lib, t->text_font);
|
|
|
|
|
}
|
|
|
|
|
BLI_listbase_clear(&seq->anims);
|
|
|
|
|
|
|
|
|
|
lib_link_sequence_modifiers(fd, sce, &seq->modifiers);
|
|
|
|
|
}
|
|
|
|
|
SEQ_END;
|
|
|
|
|
|
|
|
|
|
for (TimeMarker *marker = sce->markers.first; marker; marker = marker->next) {
|
|
|
|
|
if (marker->camera) {
|
|
|
|
|
marker->camera = newlibadr(fd, sce->id.lib, marker->camera);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* rigidbody world relies on it's linked collections */
|
|
|
|
|
if (sce->rigidbody_world) {
|
|
|
|
|
RigidBodyWorld *rbw = sce->rigidbody_world;
|
2019-04-22 09:13:00 +10:00
|
|
|
if (rbw->group) {
|
2019-04-17 06:17:24 +02:00
|
|
|
rbw->group = newlibadr(fd, sce->id.lib, rbw->group);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (rbw->constraints) {
|
2019-04-17 06:17:24 +02:00
|
|
|
rbw->constraints = newlibadr(fd, sce->id.lib, rbw->constraints);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (rbw->effector_weights) {
|
2019-04-17 06:17:24 +02:00
|
|
|
rbw->effector_weights->group = newlibadr(fd, sce->id.lib, rbw->effector_weights->group);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sce->nodetree) {
|
|
|
|
|
lib_link_ntree(fd, &sce->id, sce->nodetree);
|
|
|
|
|
sce->nodetree->id.lib = sce->id.lib;
|
|
|
|
|
composite_patch(sce->nodetree, sce);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) {
|
|
|
|
|
srl->mat_override = newlibadr_us(fd, sce->id.lib, srl->mat_override);
|
|
|
|
|
for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc;
|
|
|
|
|
fmc = fmc->next) {
|
|
|
|
|
fmc->script = newlibadr(fd, sce->id.lib, fmc->script);
|
|
|
|
|
}
|
|
|
|
|
for (FreestyleLineSet *fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
|
|
|
|
|
fls->linestyle = newlibadr_us(fd, sce->id.lib, fls->linestyle);
|
|
|
|
|
fls->group = newlibadr_us(fd, sce->id.lib, fls->group);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Motion Tracking */
|
|
|
|
|
sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip);
|
2014-11-11 19:39:20 +01:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sce->collection) {
|
|
|
|
|
lib_link_scene_collection(fd, sce->id.lib, sce->collection);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sce->master_collection) {
|
|
|
|
|
lib_link_collection_data(fd, sce->id.lib, sce->master_collection);
|
|
|
|
|
}
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ViewLayer *view_layer = sce->view_layers.first; view_layer;
|
|
|
|
|
view_layer = view_layer->next) {
|
|
|
|
|
lib_link_view_layer(fd, sce->id.lib, view_layer);
|
|
|
|
|
}
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sce->r.bake.cage_object) {
|
|
|
|
|
sce->r.bake.cage_object = newlibadr(fd, sce->id.lib, sce->r.bake.cage_object);
|
|
|
|
|
}
|
2018-12-07 10:41:57 -02:00
|
|
|
|
2014-11-11 19:39:20 +01:00
|
|
|
#ifdef USE_SETSCENE_CHECK
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sce->set != NULL) {
|
|
|
|
|
/* link flag for scenes with set would be reset later,
|
|
|
|
|
* so this way we only check cyclic for newly linked scenes.
|
|
|
|
|
*/
|
|
|
|
|
need_check_set = true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* postpone un-setting the flag until we've checked the set-scene */
|
|
|
|
|
sce->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
2014-11-11 19:39:20 +01:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->id.tag &= ~LIB_TAG_NEED_LINK;
|
2014-11-11 19:39:20 +01:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-11-11 19:39:20 +01:00
|
|
|
|
|
|
|
|
#ifdef USE_SETSCENE_CHECK
|
2019-04-17 06:17:24 +02:00
|
|
|
totscene++;
|
2014-11-11 19:39:20 +01:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-11-11 19:39:20 +01:00
|
|
|
|
|
|
|
|
#ifdef USE_SETSCENE_CHECK
|
2019-04-17 06:17:24 +02:00
|
|
|
if (need_check_set) {
|
|
|
|
|
for (Scene *sce = main->scenes.first; sce; sce = sce->id.next) {
|
|
|
|
|
if (sce->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
sce->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
if (!scene_validate_setscene__liblink(sce, totscene)) {
|
|
|
|
|
printf("Found cyclic background scene when linking %s\n", sce->id.name + 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-11-11 19:39:20 +01:00
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2014-11-11 19:39:20 +01:00
|
|
|
#undef USE_SETSCENE_CHECK
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void link_recurs_seq(FileData *fd, ListBase *lb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Sequence *seq;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, lb);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (seq = lb->first; seq; seq = seq->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (seq->seqbase.first) {
|
2019-04-17 06:17:24 +02:00
|
|
|
link_recurs_seq(fd, &seq->seqbase);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2018-11-05 16:18:43 +11:00
|
|
|
static void direct_link_paint(FileData *fd, const Scene *scene, Paint *p)
|
2015-02-11 15:07:04 +01:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (p->num_input_samples < 1) {
|
2019-04-17 06:17:24 +02:00
|
|
|
p->num_input_samples = 1;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2015-02-11 15:07:04 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
p->cavity_curve = newdataadr(fd, p->cavity_curve);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (p->cavity_curve) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, p->cavity_curve);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_paint_cavity_curve_preset(p, CURVE_PRESET_LINE);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-11-02 09:10:23 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
p->tool_slots = newdataadr(fd, p->tool_slots);
|
2018-11-05 16:18:43 +11:00
|
|
|
|
2019-05-06 18:02:22 +02:00
|
|
|
/* Workaround for invalid data written in older versions. */
|
|
|
|
|
const size_t expected_size = sizeof(PaintToolSlot) * p->tool_slots_len;
|
|
|
|
|
if (p->tool_slots && MEM_allocN_len(p->tool_slots) < expected_size) {
|
|
|
|
|
MEM_freeN(p->tool_slots);
|
|
|
|
|
p->tool_slots = MEM_callocN(expected_size, "PaintToolSlot");
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_paint_runtime_init(scene->toolsettings, p);
|
2015-02-11 15:07:04 +01:00
|
|
|
}
|
|
|
|
|
|
2018-11-05 16:18:43 +11:00
|
|
|
static void direct_link_paint_helper(FileData *fd, const Scene *scene, Paint **paint)
|
2009-08-17 00:39:00 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* TODO. is this needed */
|
|
|
|
|
(*paint) = newdataadr(fd, (*paint));
|
2015-02-11 15:07:04 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (*paint) {
|
|
|
|
|
direct_link_paint(fd, scene, *paint);
|
|
|
|
|
}
|
2009-08-17 00:39:00 +00:00
|
|
|
}
|
|
|
|
|
|
2012-08-19 15:41:56 +00:00
|
|
|
static void direct_link_sequence_modifiers(FileData *fd, ListBase *lb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SequenceModifierData *smd;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, lb);
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (smd = lb->first; smd; smd = smd->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (smd->mask_sequence) {
|
2019-04-17 06:17:24 +02:00
|
|
|
smd->mask_sequence = newdataadr(fd, smd->mask_sequence);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (smd->type == seqModifierType_Curves) {
|
|
|
|
|
CurvesModifierData *cmd = (CurvesModifierData *)smd;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, &cmd->curve_mapping);
|
|
|
|
|
}
|
|
|
|
|
else if (smd->type == seqModifierType_HueCorrect) {
|
|
|
|
|
HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_curvemapping(fd, &hcmd->curve_mapping);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
}
|
|
|
|
|
|
2018-05-24 17:28:35 +02:00
|
|
|
static void direct_link_scene(FileData *fd, Scene *sce)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Editing *ed;
|
|
|
|
|
Sequence *seq;
|
|
|
|
|
MetaStack *ms;
|
|
|
|
|
RigidBodyWorld *rbw;
|
|
|
|
|
ViewLayer *view_layer;
|
|
|
|
|
SceneRenderLayer *srl;
|
|
|
|
|
|
|
|
|
|
sce->depsgraph_hash = NULL;
|
|
|
|
|
sce->fps_info = NULL;
|
|
|
|
|
|
|
|
|
|
memset(&sce->customdata_mask, 0, sizeof(sce->customdata_mask));
|
|
|
|
|
memset(&sce->customdata_mask_modal, 0, sizeof(sce->customdata_mask_modal));
|
|
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
BKE_sound_reset_scene_runtime(sce);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* set users to one by default, not in lib-link, this will increase it for compo nodes */
|
|
|
|
|
id_us_ensure_real(&sce->id);
|
|
|
|
|
|
|
|
|
|
link_list(fd, &(sce->base));
|
|
|
|
|
|
|
|
|
|
sce->adt = newdataadr(fd, sce->adt);
|
|
|
|
|
direct_link_animdata(fd, sce->adt);
|
|
|
|
|
|
|
|
|
|
link_list(fd, &sce->keyingsets);
|
|
|
|
|
direct_link_keyingsets(fd, &sce->keyingsets);
|
|
|
|
|
|
|
|
|
|
sce->basact = newdataadr(fd, sce->basact);
|
|
|
|
|
|
|
|
|
|
sce->toolsettings = newdataadr(fd, sce->toolsettings);
|
|
|
|
|
if (sce->toolsettings) {
|
|
|
|
|
direct_link_paint_helper(fd, sce, (Paint **)&sce->toolsettings->sculpt);
|
|
|
|
|
direct_link_paint_helper(fd, sce, (Paint **)&sce->toolsettings->vpaint);
|
|
|
|
|
direct_link_paint_helper(fd, sce, (Paint **)&sce->toolsettings->wpaint);
|
|
|
|
|
direct_link_paint_helper(fd, sce, (Paint **)&sce->toolsettings->uvsculpt);
|
|
|
|
|
direct_link_paint_helper(fd, sce, (Paint **)&sce->toolsettings->gp_paint);
|
|
|
|
|
|
|
|
|
|
direct_link_paint(fd, sce, &sce->toolsettings->imapaint.paint);
|
|
|
|
|
|
|
|
|
|
sce->toolsettings->imapaint.paintcursor = NULL;
|
|
|
|
|
sce->toolsettings->particle.paintcursor = NULL;
|
|
|
|
|
sce->toolsettings->particle.scene = NULL;
|
|
|
|
|
sce->toolsettings->particle.object = NULL;
|
|
|
|
|
sce->toolsettings->gp_sculpt.paintcursor = NULL;
|
|
|
|
|
|
|
|
|
|
/* relink grease pencil interpolation curves */
|
|
|
|
|
sce->toolsettings->gp_interpolate.custom_ipo = newdataadr(
|
|
|
|
|
fd, sce->toolsettings->gp_interpolate.custom_ipo);
|
|
|
|
|
if (sce->toolsettings->gp_interpolate.custom_ipo) {
|
|
|
|
|
direct_link_curvemapping(fd, sce->toolsettings->gp_interpolate.custom_ipo);
|
|
|
|
|
}
|
|
|
|
|
/* relink grease pencil multiframe falloff curve */
|
|
|
|
|
sce->toolsettings->gp_sculpt.cur_falloff = newdataadr(
|
|
|
|
|
fd, sce->toolsettings->gp_sculpt.cur_falloff);
|
|
|
|
|
if (sce->toolsettings->gp_sculpt.cur_falloff) {
|
|
|
|
|
direct_link_curvemapping(fd, sce->toolsettings->gp_sculpt.cur_falloff);
|
|
|
|
|
}
|
|
|
|
|
/* relink grease pencil primitive curve */
|
|
|
|
|
sce->toolsettings->gp_sculpt.cur_primitive = newdataadr(
|
|
|
|
|
fd, sce->toolsettings->gp_sculpt.cur_primitive);
|
|
|
|
|
if (sce->toolsettings->gp_sculpt.cur_primitive) {
|
|
|
|
|
direct_link_curvemapping(fd, sce->toolsettings->gp_sculpt.cur_primitive);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sce->ed) {
|
|
|
|
|
ListBase *old_seqbasep = &sce->ed->seqbase;
|
|
|
|
|
|
|
|
|
|
ed = sce->ed = newdataadr(fd, sce->ed);
|
|
|
|
|
|
|
|
|
|
ed->act_seq = newdataadr(fd, ed->act_seq);
|
2019-04-28 14:13:41 -07:00
|
|
|
ed->cache = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* recursive link sequences, lb will be correctly initialized */
|
|
|
|
|
link_recurs_seq(fd, &ed->seqbase);
|
|
|
|
|
|
|
|
|
|
SEQ_BEGIN (ed, seq) {
|
|
|
|
|
seq->seq1 = newdataadr(fd, seq->seq1);
|
|
|
|
|
seq->seq2 = newdataadr(fd, seq->seq2);
|
|
|
|
|
seq->seq3 = newdataadr(fd, seq->seq3);
|
|
|
|
|
|
|
|
|
|
/* a patch: after introduction of effects with 3 input strips */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (seq->seq3 == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
seq->seq3 = seq->seq2;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
seq->effectdata = newdataadr(fd, seq->effectdata);
|
|
|
|
|
seq->stereo3d_format = newdataadr(fd, seq->stereo3d_format);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (seq->type & SEQ_TYPE_EFFECT) {
|
2019-04-17 06:17:24 +02:00
|
|
|
seq->flag |= SEQ_EFFECT_NOT_LOADED;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (seq->type == SEQ_TYPE_SPEED) {
|
|
|
|
|
SpeedControlVars *s = seq->effectdata;
|
|
|
|
|
s->frameMap = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (seq->type == SEQ_TYPE_TEXT) {
|
|
|
|
|
TextVars *t = seq->effectdata;
|
|
|
|
|
t->text_blf_id = SEQ_FONT_NOT_LOADED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seq->prop = newdataadr(fd, seq->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&seq->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
|
|
|
|
|
seq->strip = newdataadr(fd, seq->strip);
|
|
|
|
|
if (seq->strip && seq->strip->done == 0) {
|
|
|
|
|
seq->strip->done = true;
|
|
|
|
|
|
|
|
|
|
if (ELEM(seq->type,
|
|
|
|
|
SEQ_TYPE_IMAGE,
|
|
|
|
|
SEQ_TYPE_MOVIE,
|
|
|
|
|
SEQ_TYPE_SOUND_RAM,
|
|
|
|
|
SEQ_TYPE_SOUND_HD)) {
|
|
|
|
|
seq->strip->stripdata = newdataadr(fd, seq->strip->stripdata);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
seq->strip->stripdata = NULL;
|
|
|
|
|
}
|
2019-05-31 14:40:41 +02:00
|
|
|
seq->strip->crop = newdataadr(fd, seq->strip->crop);
|
|
|
|
|
seq->strip->transform = newdataadr(fd, seq->strip->transform);
|
|
|
|
|
seq->strip->proxy = newdataadr(fd, seq->strip->proxy);
|
|
|
|
|
if (seq->strip->proxy) {
|
|
|
|
|
seq->strip->proxy->anim = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-05-31 14:40:41 +02:00
|
|
|
else if (seq->flag & SEQ_USE_PROXY) {
|
|
|
|
|
BKE_sequencer_proxy_set(seq, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* need to load color balance to it could be converted to modifier */
|
|
|
|
|
seq->strip->color_balance = newdataadr(fd, seq->strip->color_balance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
direct_link_sequence_modifiers(fd, &seq->modifiers);
|
|
|
|
|
}
|
|
|
|
|
SEQ_END;
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* link metastack, slight abuse of structs here,
|
|
|
|
|
* have to restore pointer to internal part in struct */
|
2019-04-17 06:17:24 +02:00
|
|
|
{
|
|
|
|
|
Sequence temp;
|
|
|
|
|
void *poin;
|
|
|
|
|
intptr_t offset;
|
|
|
|
|
|
|
|
|
|
offset = ((intptr_t) & (temp.seqbase)) - ((intptr_t)&temp);
|
|
|
|
|
|
|
|
|
|
/* root pointer */
|
|
|
|
|
if (ed->seqbasep == old_seqbasep) {
|
|
|
|
|
ed->seqbasep = &ed->seqbase;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
poin = POINTER_OFFSET(ed->seqbasep, -offset);
|
|
|
|
|
|
|
|
|
|
poin = newdataadr(fd, poin);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (poin) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ed->seqbasep = (ListBase *)POINTER_OFFSET(poin, offset);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
ed->seqbasep = &ed->seqbase;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
/* stack */
|
|
|
|
|
link_list(fd, &(ed->metastack));
|
|
|
|
|
|
|
|
|
|
for (ms = ed->metastack.first; ms; ms = ms->next) {
|
|
|
|
|
ms->parseq = newdataadr(fd, ms->parseq);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ms->oldbasep == old_seqbasep) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ms->oldbasep = &ed->seqbase;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
else {
|
|
|
|
|
poin = POINTER_OFFSET(ms->oldbasep, -offset);
|
|
|
|
|
poin = newdataadr(fd, poin);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (poin) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ms->oldbasep = (ListBase *)POINTER_OFFSET(poin, offset);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
ms->oldbasep = &ed->seqbase;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-02 16:01:00 +03:00
|
|
|
#ifdef DURIAN_CAMERA_SWITCH
|
|
|
|
|
/* Runtime */
|
|
|
|
|
sce->r.mode &= ~R_NO_CAMERA_SWITCH;
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->r.avicodecdata = newdataadr(fd, sce->r.avicodecdata);
|
|
|
|
|
if (sce->r.avicodecdata) {
|
|
|
|
|
sce->r.avicodecdata->lpFormat = newdataadr(fd, sce->r.avicodecdata->lpFormat);
|
|
|
|
|
sce->r.avicodecdata->lpParms = newdataadr(fd, sce->r.avicodecdata->lpParms);
|
|
|
|
|
}
|
|
|
|
|
if (sce->r.ffcodecdata.properties) {
|
|
|
|
|
sce->r.ffcodecdata.properties = newdataadr(fd, sce->r.ffcodecdata.properties);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(
|
|
|
|
|
&sce->r.ffcodecdata.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
link_list(fd, &(sce->markers));
|
|
|
|
|
link_list(fd, &(sce->transform_spaces));
|
|
|
|
|
link_list(fd, &(sce->r.layers));
|
|
|
|
|
link_list(fd, &(sce->r.views));
|
|
|
|
|
|
|
|
|
|
for (srl = sce->r.layers.first; srl; srl = srl->next) {
|
|
|
|
|
srl->prop = newdataadr(fd, srl->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&srl->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
link_list(fd, &(srl->freestyleConfig.modules));
|
|
|
|
|
link_list(fd, &(srl->freestyleConfig.linesets));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sce->nodetree = newdataadr(fd, sce->nodetree);
|
|
|
|
|
if (sce->nodetree) {
|
|
|
|
|
direct_link_id(fd, &sce->nodetree->id);
|
|
|
|
|
direct_link_nodetree(fd, sce->nodetree);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
direct_link_view_settings(fd, &sce->view_settings);
|
|
|
|
|
|
|
|
|
|
sce->rigidbody_world = newdataadr(fd, sce->rigidbody_world);
|
|
|
|
|
rbw = sce->rigidbody_world;
|
|
|
|
|
if (rbw) {
|
|
|
|
|
rbw->shared = newdataadr(fd, rbw->shared);
|
|
|
|
|
|
|
|
|
|
if (rbw->shared == NULL) {
|
|
|
|
|
/* Link deprecated caches if they exist, so we can use them for versioning.
|
|
|
|
|
* We should only do this when rbw->shared == NULL, because those pointers
|
|
|
|
|
* are always set (for compatibility with older Blenders). We mustn't link
|
|
|
|
|
* the same pointcache twice. */
|
|
|
|
|
direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, false);
|
|
|
|
|
|
|
|
|
|
/* make sure simulation starts from the beginning after loading file */
|
|
|
|
|
if (rbw->pointcache) {
|
|
|
|
|
rbw->ltime = (float)rbw->pointcache->startframe;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* must nullify the reference to physics sim object, since it no-longer exist
|
|
|
|
|
* (and will need to be recalculated)
|
|
|
|
|
*/
|
|
|
|
|
rbw->shared->physics_world = NULL;
|
|
|
|
|
|
|
|
|
|
/* link caches */
|
|
|
|
|
direct_link_pointcache_list(fd, &rbw->shared->ptcaches, &rbw->shared->pointcache, false);
|
|
|
|
|
|
|
|
|
|
/* make sure simulation starts from the beginning after loading file */
|
|
|
|
|
if (rbw->shared->pointcache) {
|
|
|
|
|
rbw->ltime = (float)rbw->shared->pointcache->startframe;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rbw->objects = NULL;
|
|
|
|
|
rbw->numbodies = 0;
|
|
|
|
|
|
|
|
|
|
/* set effector weights */
|
|
|
|
|
rbw->effector_weights = newdataadr(fd, rbw->effector_weights);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!rbw->effector_weights) {
|
2019-04-17 06:17:24 +02:00
|
|
|
rbw->effector_weights = BKE_effector_add_weights(NULL);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sce->preview = direct_link_preview_image(fd, sce->preview);
|
|
|
|
|
|
|
|
|
|
direct_link_curvemapping(fd, &sce->r.mblur_shutter_curve);
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
2019-04-17 06:17:24 +02:00
|
|
|
/* this runs before the very first doversion */
|
|
|
|
|
if (sce->collection) {
|
|
|
|
|
sce->collection = newdataadr(fd, sce->collection);
|
|
|
|
|
direct_link_scene_collection(fd, sce->collection);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sce->master_collection) {
|
|
|
|
|
sce->master_collection = newdataadr(fd, sce->master_collection);
|
|
|
|
|
/* Needed because this is an ID outside of Main. */
|
|
|
|
|
direct_link_id(fd, &sce->master_collection->id);
|
|
|
|
|
direct_link_collection(fd, sce->master_collection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* insert into global old-new map for reading without UI (link_global accesses it again) */
|
|
|
|
|
link_glob_list(fd, &sce->view_layers);
|
|
|
|
|
for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
|
|
|
|
|
direct_link_view_layer(fd, view_layer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fd->memfile) {
|
|
|
|
|
/* If it's undo try to recover the cache. */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->scenemap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
sce->eevee.light_cache = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* else try to read the cache from file. */
|
|
|
|
|
sce->eevee.light_cache = newdataadr(fd, sce->eevee.light_cache);
|
|
|
|
|
if (sce->eevee.light_cache) {
|
|
|
|
|
direct_link_lightcache(fd, sce->eevee.light_cache);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sce->layer_properties = newdataadr(fd, sce->layer_properties);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Grease Pencil
|
|
|
|
|
* \{ */
|
2018-04-13 20:29:16 +02:00
|
|
|
|
|
|
|
|
/* relink's grease pencil data's refs */
|
|
|
|
|
static void lib_link_gpencil(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Relink all data-lock linked by GP data-lock */
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bGPdata *gpd = main->gpencils.first; gpd; gpd = gpd->id.next) {
|
|
|
|
|
if (gpd->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
/* Layers */
|
|
|
|
|
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
|
|
|
|
/* Layer -> Parent References */
|
|
|
|
|
gpl->parent = newlibadr(fd, gpd->id.lib, gpl->parent);
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Data-block Stuff */
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(gpd->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &gpd->id, gpd->adt);
|
2018-04-13 20:29:16 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* materials */
|
|
|
|
|
for (int a = 0; a < gpd->totcol; a++) {
|
|
|
|
|
gpd->mat[a] = newlibadr_us(fd, gpd->id.lib, gpd->mat[a]);
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
gpd->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-04-13 20:29:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* relinks grease-pencil data - used for direct_link and old file linkage */
|
|
|
|
|
static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bGPDlayer *gpl;
|
|
|
|
|
bGPDframe *gpf;
|
|
|
|
|
bGPDstroke *gps;
|
|
|
|
|
bGPDpalette *palette;
|
2018-04-13 20:29:16 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* we must firstly have some grease-pencil data to link! */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (gpd == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink animdata */
|
|
|
|
|
gpd->adt = newdataadr(fd, gpd->adt);
|
|
|
|
|
direct_link_animdata(fd, gpd->adt);
|
2018-04-13 20:29:16 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* init stroke buffer */
|
|
|
|
|
gpd->runtime.sbuffer = NULL;
|
2019-07-20 23:01:19 +02:00
|
|
|
gpd->runtime.sbuffer_used = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
gpd->runtime.sbuffer_size = 0;
|
|
|
|
|
gpd->runtime.tot_cp_points = 0;
|
2019-02-09 10:59:25 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink palettes (old palettes deprecated, only to convert old files) */
|
|
|
|
|
link_list(fd, &gpd->palettes);
|
|
|
|
|
if (gpd->palettes.first != NULL) {
|
|
|
|
|
for (palette = gpd->palettes.first; palette; palette = palette->next) {
|
|
|
|
|
link_list(fd, &palette->colors);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-04-13 20:29:16 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* materials */
|
|
|
|
|
gpd->mat = newdataadr(fd, gpd->mat);
|
|
|
|
|
test_pointer_array(fd, (void **)&gpd->mat);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink layers */
|
|
|
|
|
link_list(fd, &gpd->layers);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
|
|
|
|
/* relink frames */
|
|
|
|
|
link_list(fd, &gpl->frames);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
gpl->actframe = newdataadr(fd, gpl->actframe);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
gpl->runtime.icon_id = 0;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
|
|
|
|
/* relink strokes (and their points) */
|
|
|
|
|
link_list(fd, &gpf->strokes);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
|
|
|
|
/* relink stroke points array */
|
|
|
|
|
gps->points = newdataadr(fd, gps->points);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink weight data */
|
|
|
|
|
if (gps->dvert) {
|
|
|
|
|
gps->dvert = newdataadr(fd, gps->dvert);
|
|
|
|
|
direct_link_dverts(fd, gps->totpoints, gps->dvert);
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* the triangulation is not saved, so need to be recalculated */
|
|
|
|
|
gps->triangles = NULL;
|
|
|
|
|
gps->tot_triangles = 0;
|
|
|
|
|
gps->flag |= GP_STROKE_RECALC_GEOMETRY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-04-13 20:29:16 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read Screen Area/Region (Screen Data)
|
|
|
|
|
* \{ */
|
2018-04-13 20:29:16 +02:00
|
|
|
|
2018-06-03 13:32:36 +02:00
|
|
|
static void direct_link_panel_list(FileData *fd, ListBase *lb)
|
2018-04-13 20:29:16 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, lb);
|
2018-04-13 20:29:16 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Panel *pa = lb->first; pa; pa = pa->next) {
|
|
|
|
|
pa->runtime_flag = 0;
|
|
|
|
|
pa->activedata = NULL;
|
|
|
|
|
pa->type = NULL;
|
|
|
|
|
direct_link_panel_list(fd, &pa->children);
|
|
|
|
|
}
|
2018-06-03 13:32:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
uiList *ui_list;
|
|
|
|
|
|
|
|
|
|
direct_link_panel_list(fd, &ar->panels);
|
|
|
|
|
|
|
|
|
|
link_list(fd, &ar->panels_category_active);
|
|
|
|
|
|
|
|
|
|
link_list(fd, &ar->ui_lists);
|
|
|
|
|
|
|
|
|
|
for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) {
|
|
|
|
|
ui_list->type = NULL;
|
|
|
|
|
ui_list->dyn_data = NULL;
|
|
|
|
|
ui_list->properties = newdataadr(fd, ui_list->properties);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&ui_list->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
link_list(fd, &ar->ui_previews);
|
|
|
|
|
|
|
|
|
|
if (spacetype == SPACE_EMPTY) {
|
2019-08-01 13:53:25 +10:00
|
|
|
/* unknown space type, don't leak regiondata */
|
2019-04-17 06:17:24 +02:00
|
|
|
ar->regiondata = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (ar->flag & RGN_FLAG_TEMP_REGIONDATA) {
|
|
|
|
|
/* Runtime data, don't use. */
|
|
|
|
|
ar->regiondata = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ar->regiondata = newdataadr(fd, ar->regiondata);
|
|
|
|
|
if (ar->regiondata) {
|
|
|
|
|
if (spacetype == SPACE_VIEW3D) {
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
|
|
rv3d->localvd = newdataadr(fd, rv3d->localvd);
|
|
|
|
|
rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
|
|
|
|
|
|
|
|
|
|
rv3d->depths = NULL;
|
|
|
|
|
rv3d->render_engine = NULL;
|
|
|
|
|
rv3d->sms = NULL;
|
|
|
|
|
rv3d->smooth_timer = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ar->v2d.tab_offset = NULL;
|
|
|
|
|
ar->v2d.tab_num = 0;
|
|
|
|
|
ar->v2d.tab_cur = 0;
|
|
|
|
|
ar->v2d.sms = NULL;
|
|
|
|
|
ar->v2d.alpha_hor = ar->v2d.alpha_vert = 255; /* visible by default */
|
|
|
|
|
BLI_listbase_clear(&ar->panels_category);
|
|
|
|
|
BLI_listbase_clear(&ar->handlers);
|
|
|
|
|
BLI_listbase_clear(&ar->uiblocks);
|
|
|
|
|
ar->headerstr = NULL;
|
|
|
|
|
ar->visible = 0;
|
|
|
|
|
ar->type = NULL;
|
|
|
|
|
ar->do_draw = 0;
|
|
|
|
|
ar->gizmo_map = NULL;
|
|
|
|
|
ar->regiontimer = NULL;
|
|
|
|
|
ar->draw_buffer = NULL;
|
|
|
|
|
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
|
2018-04-13 20:29:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_area(FileData *fd, ScrArea *area)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SpaceLink *sl;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
|
|
|
|
|
link_list(fd, &(area->spacedata));
|
|
|
|
|
link_list(fd, &(area->regionbase));
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&area->handlers);
|
|
|
|
|
area->type = NULL; /* spacetype callbacks */
|
2019-07-02 22:17:22 +10:00
|
|
|
|
|
|
|
|
/* Should always be unset so that rna_Area_type_get works correctly. */
|
|
|
|
|
area->butspacetype = SPACE_EMPTY;
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
area->region_active_win = -1;
|
|
|
|
|
|
|
|
|
|
area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE;
|
|
|
|
|
|
|
|
|
|
area->global = newdataadr(fd, area->global);
|
|
|
|
|
|
|
|
|
|
/* if we do not have the spacetype registered we cannot
|
|
|
|
|
* free it, so don't allocate any new memory for such spacetypes. */
|
|
|
|
|
if (!BKE_spacetype_exists(area->spacetype)) {
|
2019-07-02 22:17:22 +10:00
|
|
|
/* Hint for versioning code to replace deprecated space types. */
|
|
|
|
|
area->butspacetype = area->spacetype;
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
area->spacetype = SPACE_EMPTY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ar = area->regionbase.first; ar; ar = ar->next) {
|
|
|
|
|
direct_link_region(fd, ar, area->spacetype);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* accident can happen when read/save new file with older version */
|
|
|
|
|
/* 2.50: we now always add spacedata for info */
|
|
|
|
|
if (area->spacedata.first == NULL) {
|
|
|
|
|
SpaceInfo *sinfo = MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
|
|
|
|
|
area->spacetype = sinfo->spacetype = SPACE_INFO;
|
|
|
|
|
BLI_addtail(&area->spacedata, sinfo);
|
|
|
|
|
}
|
|
|
|
|
/* add local view3d too */
|
|
|
|
|
else if (area->spacetype == SPACE_VIEW3D) {
|
|
|
|
|
blo_do_versions_view3d_split_250(area->spacedata.first, &area->regionbase);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (sl = area->spacedata.first; sl; sl = sl->next) {
|
|
|
|
|
link_list(fd, &(sl->regionbase));
|
|
|
|
|
|
|
|
|
|
/* if we do not have the spacetype registered we cannot
|
|
|
|
|
* free it, so don't allocate any new memory for such spacetypes. */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!BKE_spacetype_exists(sl->spacetype)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sl->spacetype = SPACE_EMPTY;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (ar = sl->regionbase.first; ar; ar = ar->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_region(fd, ar, sl->spacetype);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (sl->spacetype == SPACE_VIEW3D) {
|
|
|
|
|
View3D *v3d = (View3D *)sl;
|
|
|
|
|
|
|
|
|
|
v3d->flag |= V3D_INVALID_BACKBUF;
|
|
|
|
|
|
|
|
|
|
if (v3d->gpd) {
|
|
|
|
|
v3d->gpd = newdataadr(fd, v3d->gpd);
|
|
|
|
|
direct_link_gpencil(fd, v3d->gpd);
|
|
|
|
|
}
|
|
|
|
|
v3d->localvd = newdataadr(fd, v3d->localvd);
|
|
|
|
|
v3d->runtime.properties_storage = NULL;
|
|
|
|
|
|
|
|
|
|
/* render can be quite heavy, set to solid on load */
|
|
|
|
|
if (v3d->shading.type == OB_RENDER) {
|
|
|
|
|
v3d->shading.type = OB_SOLID;
|
|
|
|
|
}
|
|
|
|
|
v3d->shading.prev_type = OB_SOLID;
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (v3d->fx_settings.dof) {
|
2019-04-17 06:17:24 +02:00
|
|
|
v3d->fx_settings.dof = newdataadr(fd, v3d->fx_settings.dof);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (v3d->fx_settings.ssao) {
|
2019-04-17 06:17:24 +02:00
|
|
|
v3d->fx_settings.ssao = newdataadr(fd, v3d->fx_settings.ssao);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_GRAPH) {
|
|
|
|
|
SpaceGraph *sipo = (SpaceGraph *)sl;
|
|
|
|
|
|
|
|
|
|
sipo->ads = newdataadr(fd, sipo->ads);
|
|
|
|
|
BLI_listbase_clear(&sipo->runtime.ghost_curves);
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_NLA) {
|
|
|
|
|
SpaceNla *snla = (SpaceNla *)sl;
|
|
|
|
|
|
|
|
|
|
snla->ads = newdataadr(fd, snla->ads);
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_OUTLINER) {
|
|
|
|
|
SpaceOutliner *soops = (SpaceOutliner *)sl;
|
|
|
|
|
|
|
|
|
|
/* use newdataadr_no_us and do not free old memory avoiding double
|
|
|
|
|
* frees and use of freed memory. this could happen because of a
|
|
|
|
|
* bug fixed in revision 58959 where the treestore memory address
|
|
|
|
|
* was not unique */
|
|
|
|
|
TreeStore *ts = newdataadr_no_us(fd, soops->treestore);
|
|
|
|
|
soops->treestore = NULL;
|
|
|
|
|
if (ts) {
|
|
|
|
|
TreeStoreElem *elems = newdataadr_no_us(fd, ts->data);
|
|
|
|
|
|
|
|
|
|
soops->treestore = BLI_mempool_create(
|
|
|
|
|
sizeof(TreeStoreElem), ts->usedelem, 512, BLI_MEMPOOL_ALLOW_ITER);
|
|
|
|
|
if (ts->usedelem && elems) {
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < ts->usedelem; i++) {
|
|
|
|
|
TreeStoreElem *new_elem = BLI_mempool_alloc(soops->treestore);
|
|
|
|
|
*new_elem = elems[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* we only saved what was used */
|
|
|
|
|
soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
|
|
|
|
|
}
|
|
|
|
|
soops->treehash = NULL;
|
|
|
|
|
soops->tree.first = soops->tree.last = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_IMAGE) {
|
|
|
|
|
SpaceImage *sima = (SpaceImage *)sl;
|
|
|
|
|
|
|
|
|
|
sima->iuser.scene = NULL;
|
|
|
|
|
sima->iuser.ok = 1;
|
|
|
|
|
sima->scopes.waveform_1 = NULL;
|
|
|
|
|
sima->scopes.waveform_2 = NULL;
|
|
|
|
|
sima->scopes.waveform_3 = NULL;
|
|
|
|
|
sima->scopes.vecscope = NULL;
|
|
|
|
|
sima->scopes.ok = 0;
|
|
|
|
|
|
|
|
|
|
/* WARNING: gpencil data is no longer stored directly in sima after 2.5
|
|
|
|
|
* so sacrifice a few old files for now to avoid crashes with new files!
|
|
|
|
|
* committed: r28002 */
|
2018-04-13 20:29:16 +02:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
sima->gpd = newdataadr(fd, sima->gpd);
|
2019-05-31 23:21:16 +10:00
|
|
|
if (sima->gpd) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_gpencil(fd, sima->gpd);
|
2019-05-31 23:21:16 +10:00
|
|
|
}
|
2018-04-13 20:29:16 +02:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_NODE) {
|
|
|
|
|
SpaceNode *snode = (SpaceNode *)sl;
|
|
|
|
|
|
|
|
|
|
if (snode->gpd) {
|
|
|
|
|
snode->gpd = newdataadr(fd, snode->gpd);
|
|
|
|
|
direct_link_gpencil(fd, snode->gpd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
link_list(fd, &snode->treepath);
|
|
|
|
|
snode->edittree = NULL;
|
|
|
|
|
snode->iofsd = NULL;
|
|
|
|
|
BLI_listbase_clear(&snode->linkdrag);
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_TEXT) {
|
|
|
|
|
SpaceText *st = (SpaceText *)sl;
|
|
|
|
|
|
|
|
|
|
st->drawcache = NULL;
|
|
|
|
|
st->scroll_accum[0] = 0.0f;
|
|
|
|
|
st->scroll_accum[1] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_SEQ) {
|
|
|
|
|
SpaceSeq *sseq = (SpaceSeq *)sl;
|
|
|
|
|
|
|
|
|
|
/* grease pencil data is not a direct data and can't be linked from direct_link*
|
|
|
|
|
* functions, it should be linked from lib_link* functions instead
|
|
|
|
|
*
|
|
|
|
|
* otherwise it'll lead to lost grease data on open because it'll likely be
|
|
|
|
|
* read from file after all other users of grease pencil and newdataadr would
|
|
|
|
|
* simple return NULL here (sergey)
|
|
|
|
|
*/
|
2018-04-13 20:29:16 +02:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sseq->gpd) {
|
|
|
|
|
sseq->gpd = newdataadr(fd, sseq->gpd);
|
|
|
|
|
direct_link_gpencil(fd, sseq->gpd);
|
|
|
|
|
}
|
2018-04-13 20:29:16 +02:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
sseq->scopes.reference_ibuf = NULL;
|
|
|
|
|
sseq->scopes.zebra_ibuf = NULL;
|
|
|
|
|
sseq->scopes.waveform_ibuf = NULL;
|
|
|
|
|
sseq->scopes.sep_waveform_ibuf = NULL;
|
|
|
|
|
sseq->scopes.vector_ibuf = NULL;
|
|
|
|
|
sseq->scopes.histogram_ibuf = NULL;
|
|
|
|
|
sseq->compositor = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_PROPERTIES) {
|
|
|
|
|
SpaceProperties *sbuts = (SpaceProperties *)sl;
|
|
|
|
|
|
|
|
|
|
sbuts->path = NULL;
|
|
|
|
|
sbuts->texuser = NULL;
|
|
|
|
|
sbuts->mainbo = sbuts->mainb;
|
|
|
|
|
sbuts->mainbuser = sbuts->mainb;
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_CONSOLE) {
|
|
|
|
|
SpaceConsole *sconsole = (SpaceConsole *)sl;
|
|
|
|
|
ConsoleLine *cl, *cl_next;
|
|
|
|
|
|
|
|
|
|
link_list(fd, &sconsole->scrollback);
|
|
|
|
|
link_list(fd, &sconsole->history);
|
|
|
|
|
|
2019-05-01 11:09:22 +10:00
|
|
|
// for (cl= sconsole->scrollback.first; cl; cl= cl->next)
|
2019-04-17 06:17:24 +02:00
|
|
|
// cl->line= newdataadr(fd, cl->line);
|
|
|
|
|
|
|
|
|
|
/* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
|
|
|
|
|
* from left to right. the right-most expression sets the result of the comma
|
|
|
|
|
* expression as a whole*/
|
|
|
|
|
for (cl = sconsole->history.first; cl; cl = cl_next) {
|
|
|
|
|
cl_next = cl->next;
|
|
|
|
|
cl->line = newdataadr(fd, cl->line);
|
|
|
|
|
if (cl->line) {
|
|
|
|
|
/* the allocted length is not written, so reset here */
|
|
|
|
|
cl->len_alloc = cl->len + 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_remlink(&sconsole->history, cl);
|
|
|
|
|
MEM_freeN(cl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_FILE) {
|
|
|
|
|
SpaceFile *sfile = (SpaceFile *)sl;
|
|
|
|
|
|
|
|
|
|
/* this sort of info is probably irrelevant for reloading...
|
|
|
|
|
* plus, it isn't saved to files yet!
|
|
|
|
|
*/
|
|
|
|
|
sfile->folders_prev = sfile->folders_next = NULL;
|
|
|
|
|
sfile->files = NULL;
|
|
|
|
|
sfile->layout = NULL;
|
|
|
|
|
sfile->op = NULL;
|
|
|
|
|
sfile->previews_timer = NULL;
|
|
|
|
|
sfile->params = newdataadr(fd, sfile->params);
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_CLIP) {
|
|
|
|
|
SpaceClip *sclip = (SpaceClip *)sl;
|
|
|
|
|
|
|
|
|
|
sclip->scopes.track_search = NULL;
|
|
|
|
|
sclip->scopes.track_preview = NULL;
|
|
|
|
|
sclip->scopes.ok = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&area->actionzones);
|
|
|
|
|
|
|
|
|
|
area->v1 = newdataadr(fd, area->v1);
|
|
|
|
|
area->v2 = newdataadr(fd, area->v2);
|
|
|
|
|
area->v3 = newdataadr(fd, area->v3);
|
|
|
|
|
area->v4 = newdataadr(fd, area->v4);
|
2018-04-13 20:29:16 +02:00
|
|
|
}
|
|
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
static void lib_link_area(FileData *fd, ID *parent_id, ScrArea *area)
|
2018-04-13 20:29:16 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
area->full = newlibadr(fd, parent_id->lib, area->full);
|
|
|
|
|
|
|
|
|
|
memset(&area->runtime, 0x0, sizeof(area->runtime));
|
|
|
|
|
|
|
|
|
|
for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
|
|
|
|
|
switch (sl->spacetype) {
|
|
|
|
|
case SPACE_VIEW3D: {
|
|
|
|
|
View3D *v3d = (View3D *)sl;
|
|
|
|
|
|
|
|
|
|
v3d->camera = newlibadr(fd, parent_id->lib, v3d->camera);
|
|
|
|
|
v3d->ob_centre = newlibadr(fd, parent_id->lib, v3d->ob_centre);
|
|
|
|
|
|
|
|
|
|
if (v3d->localvd) {
|
|
|
|
|
v3d->localvd->camera = newlibadr(fd, parent_id->lib, v3d->localvd->camera);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_GRAPH: {
|
|
|
|
|
SpaceGraph *sipo = (SpaceGraph *)sl;
|
|
|
|
|
bDopeSheet *ads = sipo->ads;
|
|
|
|
|
|
|
|
|
|
if (ads) {
|
|
|
|
|
ads->source = newlibadr(fd, parent_id->lib, ads->source);
|
|
|
|
|
ads->filter_grp = newlibadr(fd, parent_id->lib, ads->filter_grp);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_PROPERTIES: {
|
|
|
|
|
SpaceProperties *sbuts = (SpaceProperties *)sl;
|
|
|
|
|
sbuts->pinid = newlibadr(fd, parent_id->lib, sbuts->pinid);
|
|
|
|
|
if (sbuts->pinid == NULL) {
|
|
|
|
|
sbuts->flag &= ~SB_PIN_CONTEXT;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_FILE:
|
|
|
|
|
break;
|
|
|
|
|
case SPACE_ACTION: {
|
|
|
|
|
SpaceAction *saction = (SpaceAction *)sl;
|
|
|
|
|
bDopeSheet *ads = &saction->ads;
|
|
|
|
|
|
|
|
|
|
if (ads) {
|
|
|
|
|
ads->source = newlibadr(fd, parent_id->lib, ads->source);
|
|
|
|
|
ads->filter_grp = newlibadr(fd, parent_id->lib, ads->filter_grp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
saction->action = newlibadr(fd, parent_id->lib, saction->action);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_IMAGE: {
|
|
|
|
|
SpaceImage *sima = (SpaceImage *)sl;
|
|
|
|
|
|
|
|
|
|
sima->image = newlibadr_real_us(fd, parent_id->lib, sima->image);
|
|
|
|
|
sima->mask_info.mask = newlibadr_real_us(fd, parent_id->lib, sima->mask_info.mask);
|
|
|
|
|
|
|
|
|
|
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
|
|
|
|
|
* so fingers crossed this works fine!
|
|
|
|
|
*/
|
|
|
|
|
sima->gpd = newlibadr_us(fd, parent_id->lib, sima->gpd);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_SEQ: {
|
|
|
|
|
SpaceSeq *sseq = (SpaceSeq *)sl;
|
|
|
|
|
|
|
|
|
|
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
|
|
|
|
|
* so fingers crossed this works fine!
|
|
|
|
|
*/
|
|
|
|
|
sseq->gpd = newlibadr_us(fd, parent_id->lib, sseq->gpd);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_NLA: {
|
|
|
|
|
SpaceNla *snla = (SpaceNla *)sl;
|
|
|
|
|
bDopeSheet *ads = snla->ads;
|
|
|
|
|
|
|
|
|
|
if (ads) {
|
|
|
|
|
ads->source = newlibadr(fd, parent_id->lib, ads->source);
|
|
|
|
|
ads->filter_grp = newlibadr(fd, parent_id->lib, ads->filter_grp);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_TEXT: {
|
|
|
|
|
SpaceText *st = (SpaceText *)sl;
|
|
|
|
|
|
|
|
|
|
st->text = newlibadr(fd, parent_id->lib, st->text);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_SCRIPT: {
|
|
|
|
|
SpaceScript *scpt = (SpaceScript *)sl;
|
|
|
|
|
/*scpt->script = NULL; - 2.45 set to null, better re-run the script */
|
|
|
|
|
if (scpt->script) {
|
|
|
|
|
scpt->script = newlibadr(fd, parent_id->lib, scpt->script);
|
|
|
|
|
if (scpt->script) {
|
|
|
|
|
SCRIPT_SET_NULL(scpt->script);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_OUTLINER: {
|
|
|
|
|
SpaceOutliner *so = (SpaceOutliner *)sl;
|
|
|
|
|
so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id);
|
|
|
|
|
|
|
|
|
|
if (so->treestore) {
|
|
|
|
|
TreeStoreElem *tselem;
|
|
|
|
|
BLI_mempool_iter iter;
|
|
|
|
|
|
|
|
|
|
BLI_mempool_iternew(so->treestore, &iter);
|
|
|
|
|
while ((tselem = BLI_mempool_iterstep(&iter))) {
|
|
|
|
|
tselem->id = newlibadr(fd, NULL, tselem->id);
|
|
|
|
|
}
|
|
|
|
|
if (so->treehash) {
|
|
|
|
|
/* rebuild hash table, because it depends on ids too */
|
|
|
|
|
so->storeflag |= SO_TREESTORE_REBUILD;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_NODE: {
|
|
|
|
|
SpaceNode *snode = (SpaceNode *)sl;
|
|
|
|
|
bNodeTreePath *path, *path_next;
|
|
|
|
|
bNodeTree *ntree;
|
|
|
|
|
|
|
|
|
|
/* node tree can be stored locally in id too, link this first */
|
|
|
|
|
snode->id = newlibadr(fd, parent_id->lib, snode->id);
|
|
|
|
|
snode->from = newlibadr(fd, parent_id->lib, snode->from);
|
|
|
|
|
|
|
|
|
|
ntree = snode->id ? ntreeFromID(snode->id) : NULL;
|
|
|
|
|
snode->nodetree = ntree ? ntree : newlibadr_us(fd, parent_id->lib, snode->nodetree);
|
|
|
|
|
|
|
|
|
|
for (path = snode->treepath.first; path; path = path->next) {
|
|
|
|
|
if (path == snode->treepath.first) {
|
|
|
|
|
/* first nodetree in path is same as snode->nodetree */
|
|
|
|
|
path->nodetree = snode->nodetree;
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
path->nodetree = newlibadr_us(fd, parent_id->lib, path->nodetree);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!path->nodetree) {
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* remaining path entries are invalid, remove */
|
|
|
|
|
for (; path; path = path_next) {
|
|
|
|
|
path_next = path->next;
|
|
|
|
|
|
|
|
|
|
BLI_remlink(&snode->treepath, path);
|
|
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* edittree is just the last in the path,
|
|
|
|
|
* set this directly since the path may have been shortened above */
|
|
|
|
|
if (snode->treepath.last) {
|
|
|
|
|
path = snode->treepath.last;
|
|
|
|
|
snode->edittree = path->nodetree;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
snode->edittree = NULL;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_CLIP: {
|
|
|
|
|
SpaceClip *sclip = (SpaceClip *)sl;
|
|
|
|
|
sclip->clip = newlibadr_real_us(fd, parent_id->lib, sclip->clip);
|
|
|
|
|
sclip->mask_info.mask = newlibadr_real_us(fd, parent_id->lib, sclip->mask_info.mask);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-04-13 20:29:16 +02:00
|
|
|
}
|
|
|
|
|
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
/**
|
|
|
|
|
* \return false on error.
|
|
|
|
|
*/
|
|
|
|
|
static bool direct_link_area_map(FileData *fd, ScrAreaMap *area_map)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &area_map->vertbase);
|
|
|
|
|
link_list(fd, &area_map->edgebase);
|
|
|
|
|
link_list(fd, &area_map->areabase);
|
|
|
|
|
for (ScrArea *area = area_map->areabase.first; area; area = area->next) {
|
|
|
|
|
direct_link_area(fd, area);
|
|
|
|
|
}
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* edges */
|
|
|
|
|
for (ScrEdge *se = area_map->edgebase.first; se; se = se->next) {
|
|
|
|
|
se->v1 = newdataadr(fd, se->v1);
|
|
|
|
|
se->v2 = newdataadr(fd, se->v2);
|
|
|
|
|
BKE_screen_sort_scrvert(&se->v1, &se->v2);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (se->v1 == NULL) {
|
|
|
|
|
BLI_remlink(&area_map->edgebase, se);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return true;
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Window Manager
|
|
|
|
|
* \{ */
|
2007-12-24 18:53:37 +00:00
|
|
|
|
|
|
|
|
static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
wmWindow *win;
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
id_us_ensure_real(&wm->id);
|
|
|
|
|
link_list(fd, &wm->windows);
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (win = wm->windows.first; win; win = win->next) {
|
|
|
|
|
win->parent = newdataadr(fd, win->parent);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
WorkSpaceInstanceHook *hook = win->workspace_hook;
|
|
|
|
|
win->workspace_hook = newdataadr(fd, hook);
|
2018-07-03 15:34:26 +02:00
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* we need to restore a pointer to this later when reading workspaces,
|
|
|
|
|
* so store in global oldnew-map. */
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(fd->globmap, hook, win->workspace_hook, 0);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_area_map(fd, &win->global_areas);
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
win->ghostwin = NULL;
|
|
|
|
|
win->gpuctx = NULL;
|
|
|
|
|
win->eventstate = NULL;
|
|
|
|
|
win->cursor_keymap_status = NULL;
|
|
|
|
|
win->tweak = NULL;
|
2014-12-07 00:58:17 +01:00
|
|
|
#ifdef WIN32
|
2019-04-17 06:17:24 +02:00
|
|
|
win->ime_data = NULL;
|
2014-12-07 00:58:17 +01:00
|
|
|
#endif
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&win->queue);
|
|
|
|
|
BLI_listbase_clear(&win->handlers);
|
|
|
|
|
BLI_listbase_clear(&win->modalhandlers);
|
|
|
|
|
BLI_listbase_clear(&win->gesture);
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
win->active = 0;
|
2013-11-27 20:48:07 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
win->cursor = 0;
|
|
|
|
|
win->lastcursor = 0;
|
|
|
|
|
win->modalcursor = 0;
|
|
|
|
|
win->grabcursor = 0;
|
|
|
|
|
win->addmousemove = true;
|
|
|
|
|
win->stereo3d_format = newdataadr(fd, win->stereo3d_format);
|
2015-04-24 11:58:03 -03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* multiview always fallback to anaglyph at file opening
|
|
|
|
|
* otherwise quadbuffer saved files can break Blender */
|
|
|
|
|
if (win->stereo3d_format) {
|
|
|
|
|
win->stereo3d_format->display_mode = S3D_DISPLAY_ANAGLYPH;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&wm->timers);
|
|
|
|
|
BLI_listbase_clear(&wm->operators);
|
|
|
|
|
BLI_listbase_clear(&wm->paintcursors);
|
|
|
|
|
BLI_listbase_clear(&wm->queue);
|
|
|
|
|
BKE_reports_init(&wm->reports, RPT_STORE);
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&wm->keyconfigs);
|
|
|
|
|
wm->defaultconf = NULL;
|
|
|
|
|
wm->addonconf = NULL;
|
|
|
|
|
wm->userconf = NULL;
|
|
|
|
|
wm->undo_stack = NULL;
|
2016-08-03 23:31:48 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
wm->message_bus = NULL;
|
2016-08-03 23:31:48 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&wm->jobs);
|
|
|
|
|
BLI_listbase_clear(&wm->drags);
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
wm->windrawable = NULL;
|
|
|
|
|
wm->winactive = NULL;
|
|
|
|
|
wm->initialized = 0;
|
|
|
|
|
wm->op_undo_depth = 0;
|
|
|
|
|
wm->is_interface_locked = 0;
|
2018-04-13 20:29:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_windowmanager(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
wmWindowManager *wm;
|
|
|
|
|
wmWindow *win;
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (wm = main->wm.first; wm; wm = wm->id.next) {
|
|
|
|
|
if (wm->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
/* Note: WM IDProperties are never written to file, hence no need to read/link them here. */
|
|
|
|
|
for (win = wm->windows.first; win; win = win->next) {
|
|
|
|
|
if (win->workspace_hook) { /* NULL for old files */
|
|
|
|
|
lib_link_workspace_instance_hook(fd, win->workspace_hook, &wm->id);
|
|
|
|
|
}
|
|
|
|
|
win->scene = newlibadr(fd, wm->id.lib, win->scene);
|
|
|
|
|
/* deprecated, but needed for versioning (will be NULL'ed then) */
|
|
|
|
|
win->screen = newlibadr(fd, NULL, win->screen);
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
|
|
|
|
|
lib_link_area(fd, &wm->id, area);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-04-13 20:29:16 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
wm->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-07-22 09:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Screen
|
|
|
|
|
* \{ */
|
2008-12-29 13:38:08 +00:00
|
|
|
|
2018-06-17 17:10:19 +02:00
|
|
|
/* note: file read without screens option G_FILE_NO_UI;
|
2012-04-22 11:54:53 +00:00
|
|
|
* check lib pointers in call below */
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_screen(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bScreen *sc = main->screens.first; sc; sc = sc->id.next) {
|
|
|
|
|
if (sc->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(sc->id.properties, fd);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* deprecated, but needed for versioning (will be NULL'ed then) */
|
|
|
|
|
sc->scene = newlibadr(fd, sc->id.lib, sc->scene);
|
2015-03-06 14:22:00 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sc->animtimer = NULL; /* saved in rare cases */
|
|
|
|
|
sc->tool_tip = NULL;
|
|
|
|
|
sc->scrubbing = false;
|
2018-06-17 17:10:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ScrArea *area = sc->areabase.first; area; area = area->next) {
|
|
|
|
|
lib_link_area(fd, &sc->id, area);
|
|
|
|
|
}
|
|
|
|
|
sc->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-21 10:29:08 +01:00
|
|
|
/* how to handle user count on pointer restore */
|
|
|
|
|
typedef enum ePointerUserMode {
|
2019-04-17 06:17:24 +02:00
|
|
|
USER_IGNORE = 0, /* ignore user count */
|
|
|
|
|
USER_REAL = 1, /* ensure at least one real user (fake user ignored) */
|
2014-02-21 10:29:08 +01:00
|
|
|
} ePointerUserMode;
|
|
|
|
|
|
2016-06-07 16:07:13 +10:00
|
|
|
static void restore_pointer_user(ID *id, ID *newid, ePointerUserMode user)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_assert(STREQ(newid->name + 2, id->name + 2));
|
|
|
|
|
BLI_assert(newid->lib == id->lib);
|
|
|
|
|
UNUSED_VARS_NDEBUG(id);
|
2016-06-07 16:07:13 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (user == USER_REAL) {
|
|
|
|
|
id_us_ensure_real(newid);
|
|
|
|
|
}
|
2016-06-07 16:07:13 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef USE_GHASH_RESTORE_POINTER
|
|
|
|
|
/**
|
|
|
|
|
* A version of #restore_pointer_by_name that performs a full search (slow!).
|
|
|
|
|
* Use only for limited lookups, when the overhead of
|
|
|
|
|
* creating a #IDNameLib_Map for a single lookup isn't worthwhile.
|
|
|
|
|
*/
|
|
|
|
|
static void *restore_pointer_by_name_main(Main *mainp, ID *id, ePointerUserMode user)
|
2013-03-18 16:34:57 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (id) {
|
|
|
|
|
ListBase *lb = which_libbase(mainp, GS(id->name));
|
|
|
|
|
if (lb) { /* there's still risk of checking corrupt mem (freed Ids in oops) */
|
|
|
|
|
ID *idn = lb->first;
|
|
|
|
|
for (; idn; idn = idn->next) {
|
|
|
|
|
if (STREQ(idn->name + 2, id->name + 2)) {
|
|
|
|
|
if (idn->lib == id->lib) {
|
|
|
|
|
restore_pointer_user(id, idn, user);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return idn;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2016-06-07 16:07:13 +10:00
|
|
|
#endif
|
2013-03-18 16:34:57 +00:00
|
|
|
|
2013-01-14 12:02:10 +00:00
|
|
|
/**
|
|
|
|
|
* Only for undo files, or to restore a screen after reading without UI...
|
|
|
|
|
*
|
2016-06-07 16:07:13 +10:00
|
|
|
* \param user:
|
2014-08-12 16:03:17 +02:00
|
|
|
* - USER_IGNORE: no usercount change
|
|
|
|
|
* - USER_REAL: ensure a real user (even if a fake one is set)
|
2016-06-07 16:07:13 +10:00
|
|
|
* \param id_map: lookup table, use when performing many lookups.
|
2016-06-29 20:37:54 +10:00
|
|
|
* this could be made an optional argument (falling back to a full lookup),
|
2016-06-07 16:07:13 +10:00
|
|
|
* however at the moment it's always available.
|
2013-01-14 12:02:10 +00:00
|
|
|
*/
|
2016-06-07 16:07:13 +10:00
|
|
|
static void *restore_pointer_by_name(struct IDNameLib_Map *id_map, ID *id, ePointerUserMode user)
|
2004-09-05 13:43:51 +00:00
|
|
|
{
|
2016-06-07 16:07:13 +10:00
|
|
|
#ifdef USE_GHASH_RESTORE_POINTER
|
2019-04-17 06:17:24 +02:00
|
|
|
if (id) {
|
|
|
|
|
/* use fast lookup when available */
|
|
|
|
|
ID *idn = BKE_main_idmap_lookup_id(id_map, id);
|
|
|
|
|
if (idn) {
|
|
|
|
|
restore_pointer_user(id, idn, user);
|
|
|
|
|
}
|
|
|
|
|
return idn;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
2016-06-07 16:07:13 +10:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *mainp = BKE_main_idmap_main_get(id_map);
|
|
|
|
|
return restore_pointer_by_name_main(mainp, id, user);
|
2016-06-07 16:07:13 +10:00
|
|
|
#endif
|
2004-09-05 13:43:51 +00:00
|
|
|
}
|
|
|
|
|
|
2016-06-07 16:07:13 +10:00
|
|
|
static void lib_link_seq_clipboard_pt_restore(ID *id, struct IDNameLib_Map *id_map)
|
2013-07-24 06:51:04 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (id) {
|
|
|
|
|
/* clipboard must ensure this */
|
|
|
|
|
BLI_assert(id->newid != NULL);
|
|
|
|
|
id->newid = restore_pointer_by_name(id_map, id->newid, USER_REAL);
|
|
|
|
|
}
|
2013-07-24 06:51:04 +00:00
|
|
|
}
|
2012-02-03 13:08:44 +00:00
|
|
|
static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
struct IDNameLib_Map *id_map = arg_pt;
|
2013-07-24 06:51:04 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_seq_clipboard_pt_restore((ID *)seq->scene, id_map);
|
|
|
|
|
lib_link_seq_clipboard_pt_restore((ID *)seq->scene_camera, id_map);
|
|
|
|
|
lib_link_seq_clipboard_pt_restore((ID *)seq->clip, id_map);
|
|
|
|
|
lib_link_seq_clipboard_pt_restore((ID *)seq->mask, id_map);
|
|
|
|
|
lib_link_seq_clipboard_pt_restore((ID *)seq->sound, id_map);
|
|
|
|
|
return 1;
|
2012-02-03 13:08:44 +00:00
|
|
|
}
|
|
|
|
|
|
2016-06-07 16:07:13 +10:00
|
|
|
static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map)
|
2012-02-03 13:08:44 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* update IDs stored in sequencer clipboard */
|
|
|
|
|
BKE_sequencer_base_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map);
|
2012-02-03 13:08:44 +00:00
|
|
|
}
|
|
|
|
|
|
2018-11-27 16:42:56 -02:00
|
|
|
static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, ViewLayer *view_layer)
|
2004-09-05 13:43:51 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
|
|
|
|
|
|
|
|
|
|
for (ScrArea *area = screen->areabase.first; area; area = area->next) {
|
|
|
|
|
for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
|
|
|
|
|
if (sl->spacetype == SPACE_VIEW3D) {
|
|
|
|
|
View3D *v3d = (View3D *)sl;
|
|
|
|
|
|
|
|
|
|
if (v3d->camera == NULL || v3d->scenelock) {
|
|
|
|
|
v3d->camera = scene->camera;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v3d->localvd) {
|
|
|
|
|
Base *base = NULL;
|
|
|
|
|
|
|
|
|
|
v3d->localvd->camera = scene->camera;
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Localview can become invalid during undo/redo steps,
|
|
|
|
|
* so we exit it when no could be found. */
|
2019-04-17 06:17:24 +02:00
|
|
|
for (base = view_layer->object_bases.first; base; base = base->next) {
|
|
|
|
|
if (base->local_view_bits & v3d->local_view_uuid) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (base == NULL) {
|
|
|
|
|
MEM_freeN(v3d->localvd);
|
|
|
|
|
v3d->localvd = NULL;
|
|
|
|
|
v3d->local_view_uuid = 0;
|
|
|
|
|
|
|
|
|
|
/* Regionbase storage is different depending if the space is active. */
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
|
|
|
|
&sl->regionbase;
|
|
|
|
|
for (ARegion *ar = regionbase->first; ar; ar = ar->next) {
|
|
|
|
|
if (ar->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
if (rv3d->localvd) {
|
|
|
|
|
MEM_freeN(rv3d->localvd);
|
|
|
|
|
rv3d->localvd = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
|
|
|
|
|
Main *newmain,
|
|
|
|
|
WorkSpaceLayout *layout)
|
|
|
|
|
{
|
|
|
|
|
bScreen *screen = BKE_workspace_layout_screen_get(layout);
|
|
|
|
|
|
|
|
|
|
/* avoid conflicts with 2.8x branch */
|
|
|
|
|
{
|
|
|
|
|
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
|
|
|
|
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
|
|
|
|
|
if (sl->spacetype == SPACE_VIEW3D) {
|
|
|
|
|
View3D *v3d = (View3D *)sl;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
|
|
|
|
|
v3d->camera = restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL);
|
|
|
|
|
v3d->ob_centre = restore_pointer_by_name(id_map, (ID *)v3d->ob_centre, USER_REAL);
|
|
|
|
|
|
|
|
|
|
/* Free render engines for now. */
|
|
|
|
|
ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
|
|
|
|
|
for (ar = regionbase->first; ar; ar = ar->next) {
|
|
|
|
|
if (ar->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
if (rv3d && rv3d->render_engine) {
|
|
|
|
|
RE_engine_free(rv3d->render_engine);
|
|
|
|
|
rv3d->render_engine = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_GRAPH) {
|
|
|
|
|
SpaceGraph *sipo = (SpaceGraph *)sl;
|
|
|
|
|
bDopeSheet *ads = sipo->ads;
|
|
|
|
|
|
|
|
|
|
if (ads) {
|
|
|
|
|
ads->source = restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ads->filter_grp) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ads->filter_grp = restore_pointer_by_name(
|
|
|
|
|
id_map, (ID *)ads->filter_grp, USER_IGNORE);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* force recalc of list of channels (i.e. includes calculating F-Curve colors)
|
|
|
|
|
* thus preventing the "black curves" problem post-undo
|
|
|
|
|
*/
|
|
|
|
|
sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR;
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_PROPERTIES) {
|
|
|
|
|
SpaceProperties *sbuts = (SpaceProperties *)sl;
|
|
|
|
|
sbuts->pinid = restore_pointer_by_name(id_map, sbuts->pinid, USER_IGNORE);
|
|
|
|
|
if (sbuts->pinid == NULL) {
|
|
|
|
|
sbuts->flag &= ~SB_PIN_CONTEXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO: restore path pointers: T40046
|
|
|
|
|
* (complicated because this contains data pointers too, not just ID)*/
|
|
|
|
|
MEM_SAFE_FREE(sbuts->path);
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_FILE) {
|
|
|
|
|
SpaceFile *sfile = (SpaceFile *)sl;
|
|
|
|
|
sfile->op = NULL;
|
|
|
|
|
sfile->previews_timer = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_ACTION) {
|
|
|
|
|
SpaceAction *saction = (SpaceAction *)sl;
|
|
|
|
|
|
|
|
|
|
saction->action = restore_pointer_by_name(id_map, (ID *)saction->action, USER_REAL);
|
|
|
|
|
saction->ads.source = restore_pointer_by_name(
|
|
|
|
|
id_map, (ID *)saction->ads.source, USER_REAL);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (saction->ads.filter_grp) {
|
2019-04-17 06:17:24 +02:00
|
|
|
saction->ads.filter_grp = restore_pointer_by_name(
|
|
|
|
|
id_map, (ID *)saction->ads.filter_grp, USER_IGNORE);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* force recalc of list of channels, potentially updating the active action
|
|
|
|
|
* while we're at it (as it can only be updated that way) [#28962]
|
|
|
|
|
*/
|
|
|
|
|
saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_IMAGE) {
|
|
|
|
|
SpaceImage *sima = (SpaceImage *)sl;
|
|
|
|
|
|
|
|
|
|
sima->image = restore_pointer_by_name(id_map, (ID *)sima->image, USER_REAL);
|
|
|
|
|
|
|
|
|
|
/* this will be freed, not worth attempting to find same scene,
|
|
|
|
|
* since it gets initialized later */
|
|
|
|
|
sima->iuser.scene = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2016-08-26 12:54:49 +02:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Those are allocated and freed by space code, no need to handle them here. */
|
|
|
|
|
MEM_SAFE_FREE(sima->scopes.waveform_1);
|
|
|
|
|
MEM_SAFE_FREE(sima->scopes.waveform_2);
|
|
|
|
|
MEM_SAFE_FREE(sima->scopes.waveform_3);
|
|
|
|
|
MEM_SAFE_FREE(sima->scopes.vecscope);
|
2016-08-26 12:54:49 +02:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
sima->scopes.ok = 0;
|
|
|
|
|
|
|
|
|
|
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
|
|
|
|
|
* so assume that here we're doing for undo only...
|
|
|
|
|
*/
|
|
|
|
|
sima->gpd = restore_pointer_by_name(id_map, (ID *)sima->gpd, USER_REAL);
|
|
|
|
|
sima->mask_info.mask = restore_pointer_by_name(
|
|
|
|
|
id_map, (ID *)sima->mask_info.mask, USER_REAL);
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_SEQ) {
|
|
|
|
|
SpaceSeq *sseq = (SpaceSeq *)sl;
|
|
|
|
|
|
|
|
|
|
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
|
|
|
|
|
* so assume that here we're doing for undo only...
|
|
|
|
|
*/
|
|
|
|
|
sseq->gpd = restore_pointer_by_name(id_map, (ID *)sseq->gpd, USER_REAL);
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_NLA) {
|
|
|
|
|
SpaceNla *snla = (SpaceNla *)sl;
|
|
|
|
|
bDopeSheet *ads = snla->ads;
|
|
|
|
|
|
|
|
|
|
if (ads) {
|
|
|
|
|
ads->source = restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ads->filter_grp) {
|
2019-04-17 06:17:24 +02:00
|
|
|
ads->filter_grp = restore_pointer_by_name(
|
|
|
|
|
id_map, (ID *)ads->filter_grp, USER_IGNORE);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_TEXT) {
|
|
|
|
|
SpaceText *st = (SpaceText *)sl;
|
|
|
|
|
|
|
|
|
|
st->text = restore_pointer_by_name(id_map, (ID *)st->text, USER_REAL);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (st->text == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
st->text = newmain->texts.first;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_SCRIPT) {
|
|
|
|
|
SpaceScript *scpt = (SpaceScript *)sl;
|
|
|
|
|
|
|
|
|
|
scpt->script = restore_pointer_by_name(id_map, (ID *)scpt->script, USER_REAL);
|
|
|
|
|
|
|
|
|
|
/*sc->script = NULL; - 2.45 set to null, better re-run the script */
|
|
|
|
|
if (scpt->script) {
|
|
|
|
|
SCRIPT_SET_NULL(scpt->script);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_OUTLINER) {
|
|
|
|
|
SpaceOutliner *so = (SpaceOutliner *)sl;
|
|
|
|
|
|
|
|
|
|
so->search_tse.id = restore_pointer_by_name(id_map, so->search_tse.id, USER_IGNORE);
|
|
|
|
|
|
|
|
|
|
if (so->treestore) {
|
|
|
|
|
TreeStoreElem *tselem;
|
|
|
|
|
BLI_mempool_iter iter;
|
|
|
|
|
|
|
|
|
|
BLI_mempool_iternew(so->treestore, &iter);
|
|
|
|
|
while ((tselem = BLI_mempool_iterstep(&iter))) {
|
2019-04-29 22:05:11 +10:00
|
|
|
/* Do not try to restore pointers to drivers/sequence/etc.,
|
|
|
|
|
* can crash in undo case! */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (TSE_IS_REAL_ID(tselem)) {
|
|
|
|
|
tselem->id = restore_pointer_by_name(id_map, tselem->id, USER_IGNORE);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tselem->id = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (so->treehash) {
|
|
|
|
|
/* rebuild hash table, because it depends on ids too */
|
|
|
|
|
so->storeflag |= SO_TREESTORE_REBUILD;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_NODE) {
|
|
|
|
|
SpaceNode *snode = (SpaceNode *)sl;
|
|
|
|
|
bNodeTreePath *path, *path_next;
|
|
|
|
|
bNodeTree *ntree;
|
|
|
|
|
|
|
|
|
|
/* node tree can be stored locally in id too, link this first */
|
|
|
|
|
snode->id = restore_pointer_by_name(id_map, snode->id, USER_REAL);
|
|
|
|
|
snode->from = restore_pointer_by_name(id_map, snode->from, USER_IGNORE);
|
|
|
|
|
|
|
|
|
|
ntree = snode->id ? ntreeFromID(snode->id) : NULL;
|
|
|
|
|
snode->nodetree = ntree ?
|
|
|
|
|
ntree :
|
|
|
|
|
restore_pointer_by_name(id_map, (ID *)snode->nodetree, USER_REAL);
|
|
|
|
|
|
|
|
|
|
for (path = snode->treepath.first; path; path = path->next) {
|
|
|
|
|
if (path == snode->treepath.first) {
|
|
|
|
|
/* first nodetree in path is same as snode->nodetree */
|
|
|
|
|
path->nodetree = snode->nodetree;
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
path->nodetree = restore_pointer_by_name(id_map, (ID *)path->nodetree, USER_REAL);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!path->nodetree) {
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* remaining path entries are invalid, remove */
|
|
|
|
|
for (; path; path = path_next) {
|
|
|
|
|
path_next = path->next;
|
|
|
|
|
|
|
|
|
|
BLI_remlink(&snode->treepath, path);
|
|
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* edittree is just the last in the path,
|
|
|
|
|
* set this directly since the path may have been shortened above */
|
|
|
|
|
if (snode->treepath.last) {
|
|
|
|
|
path = snode->treepath.last;
|
|
|
|
|
snode->edittree = path->nodetree;
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
snode->edittree = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else if (sl->spacetype == SPACE_CLIP) {
|
|
|
|
|
SpaceClip *sclip = (SpaceClip *)sl;
|
|
|
|
|
|
|
|
|
|
sclip->clip = restore_pointer_by_name(id_map, (ID *)sclip->clip, USER_REAL);
|
|
|
|
|
sclip->mask_info.mask = restore_pointer_by_name(
|
|
|
|
|
id_map, (ID *)sclip->mask_info.mask, USER_REAL);
|
|
|
|
|
|
|
|
|
|
sclip->scopes.ok = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Used to link a file (without UI) to the current UI.
|
|
|
|
|
* Note that it assumes the old pointers in UI are still valid, so old Main is not freed.
|
|
|
|
|
*/
|
2019-04-17 06:17:24 +02:00
|
|
|
void blo_lib_link_restore(Main *oldmain,
|
|
|
|
|
Main *newmain,
|
|
|
|
|
wmWindowManager *curwm,
|
|
|
|
|
Scene *curscene,
|
|
|
|
|
ViewLayer *cur_view_layer)
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain, true, oldmain);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (WorkSpace *workspace = newmain->workspaces.first; workspace;
|
|
|
|
|
workspace = workspace->id.next) {
|
|
|
|
|
ListBase *layouts = BKE_workspace_layouts_get(workspace);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) {
|
|
|
|
|
lib_link_workspace_layout_restore(id_map, newmain, layout);
|
|
|
|
|
}
|
|
|
|
|
}
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (wmWindow *win = curwm->windows.first; win; win = win->next) {
|
|
|
|
|
WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
|
|
|
|
|
ID *workspace_id = (ID *)workspace;
|
|
|
|
|
Scene *oldscene = win->scene;
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
workspace = restore_pointer_by_name(id_map, workspace_id, USER_REAL);
|
|
|
|
|
BKE_workspace_active_set(win->workspace_hook, workspace);
|
|
|
|
|
win->scene = restore_pointer_by_name(id_map, (ID *)win->scene, USER_REAL);
|
|
|
|
|
if (win->scene == NULL) {
|
|
|
|
|
win->scene = curscene;
|
|
|
|
|
}
|
|
|
|
|
if (BKE_view_layer_find(win->scene, win->view_layer_name) == NULL) {
|
|
|
|
|
STRNCPY(win->view_layer_name, cur_view_layer->name);
|
|
|
|
|
}
|
|
|
|
|
BKE_workspace_active_set(win->workspace_hook, workspace);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* keep cursor location through undo */
|
|
|
|
|
memcpy(&win->scene->cursor, &oldscene->cursor, sizeof(win->scene->cursor));
|
2019-02-26 00:58:35 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_window_scene_data_restore(win, win->scene, cur_view_layer);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_assert(win->screen == NULL);
|
|
|
|
|
}
|
2012-02-03 13:08:44 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* update IDs stored in all possible clipboards */
|
|
|
|
|
lib_link_clipboard_restore(id_map);
|
2016-06-07 16:07:13 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_main_idmap_destroy(id_map);
|
2004-09-05 13:43:51 +00:00
|
|
|
}
|
|
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
/* for the saved 2.50 files without regiondata */
|
|
|
|
|
/* and as patch for 2.48 and older */
|
2012-05-04 15:42:49 +00:00
|
|
|
void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions)
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ARegion *ar;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ar = regions->first; ar; ar = ar->next) {
|
|
|
|
|
if (ar->regiontype == RGN_TYPE_WINDOW && ar->regiondata == NULL) {
|
|
|
|
|
RegionView3D *rv3d;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
rv3d = ar->regiondata = MEM_callocN(sizeof(RegionView3D), "region v3d patch");
|
|
|
|
|
rv3d->persp = (char)v3d->persp;
|
|
|
|
|
rv3d->view = (char)v3d->view;
|
|
|
|
|
rv3d->dist = v3d->dist;
|
|
|
|
|
copy_v3_v3(rv3d->ofs, v3d->ofs);
|
|
|
|
|
copy_qt_qt(rv3d->viewquat, v3d->viewquat);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* this was not initialized correct always */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (v3d->gridsubdiv == 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
v3d->gridsubdiv = 10;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
}
|
|
|
|
|
|
2013-05-06 11:23:13 +00:00
|
|
|
static bool direct_link_screen(FileData *fd, bScreen *sc)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bool wrong_id = false;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sc->regionbase.first = sc->regionbase.last = NULL;
|
|
|
|
|
sc->context = NULL;
|
|
|
|
|
sc->active_region = NULL;
|
2012-09-06 00:33:59 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sc->preview = direct_link_preview_image(fd, sc->preview);
|
2016-12-01 16:43:57 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (!direct_link_area_map(fd, AREAMAP_FROM_SCREEN(sc))) {
|
|
|
|
|
printf("Error reading Screen %s... removing it.\n", sc->id.name + 2);
|
|
|
|
|
wrong_id = true;
|
|
|
|
|
}
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return wrong_id;
|
2004-06-23 18:22:51 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Library
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-12-14 09:59:22 +00:00
|
|
|
static void direct_link_library(FileData *fd, Library *lib, Main *main)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *newmain;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* check if the library was already read */
|
|
|
|
|
for (newmain = fd->mainlist->first; newmain; newmain = newmain->next) {
|
|
|
|
|
if (newmain->curlib) {
|
|
|
|
|
if (BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) {
|
|
|
|
|
blo_reportf_wrap(fd->reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
TIP_("Library '%s', '%s' had multiple instances, save and reload!"),
|
|
|
|
|
lib->name,
|
|
|
|
|
lib->filepath);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
change_link_placeholder_to_real_ID_pointer(fd->mainlist, fd, lib, newmain->curlib);
|
|
|
|
|
/* change_link_placeholder_to_real_ID_pointer_fd(fd, lib, newmain->curlib); */
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_remlink(&main->libraries, lib);
|
|
|
|
|
MEM_freeN(lib);
|
2018-02-13 20:58:40 +01:00
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Now, since Blender always expect **latest** Main pointer from fd->mainlist
|
|
|
|
|
* to be the active library Main pointer,
|
|
|
|
|
* where to add all non-library data-blocks found in file next, we have to switch that
|
2019-04-17 06:17:24 +02:00
|
|
|
* 'dupli' found Main to latest position in the list!
|
|
|
|
|
* Otherwise, you get weird disappearing linked data on a rather inconsistent basis.
|
|
|
|
|
* See also T53977 for reproducible case. */
|
|
|
|
|
BLI_remlink(fd->mainlist, newmain);
|
|
|
|
|
BLI_addtail(fd->mainlist, newmain);
|
2018-02-13 20:58:40 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-02-13 20:58:40 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* make sure we have full path in lib->filepath */
|
|
|
|
|
BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name));
|
|
|
|
|
BLI_cleanup_path(fd->relabase, lib->filepath);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
// printf("direct_link_library: name %s\n", lib->name);
|
|
|
|
|
// printf("direct_link_library: filepath %s\n", lib->filepath);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib->packedfile = direct_link_packedfile(fd, lib->packedfile);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* new main */
|
|
|
|
|
newmain = BKE_main_new();
|
|
|
|
|
BLI_addtail(fd->mainlist, newmain);
|
|
|
|
|
newmain->curlib = lib;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib->parent = NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void lib_link_library(FileData *UNUSED(fd), Main *main)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Library *lib;
|
|
|
|
|
for (lib = main->libraries.first; lib; lib = lib->id.next) {
|
|
|
|
|
id_us_ensure_real(&lib->id);
|
|
|
|
|
}
|
2008-02-02 11:19:34 +00:00
|
|
|
}
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Always call this once you have loaded new library data to set the relative paths correctly
|
|
|
|
|
* in relation to the blend file. */
|
2008-02-02 11:19:34 +00:00
|
|
|
static void fix_relpaths_library(const char *basepath, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Library *lib;
|
|
|
|
|
/* BLO_read_from_memory uses a blank filename */
|
|
|
|
|
if (basepath == NULL || basepath[0] == '\0') {
|
|
|
|
|
for (lib = main->libraries.first; lib; lib = lib->id.next) {
|
|
|
|
|
/* when loading a linked lib into a file which has not been saved,
|
|
|
|
|
* there is nothing we can be relative to, so instead we need to make
|
|
|
|
|
* it absolute. This can happen when appending an object with a relative
|
|
|
|
|
* link into an unsaved blend file. See [#27405].
|
|
|
|
|
* The remap relative option will make it relative again on save - campbell */
|
|
|
|
|
if (BLI_path_is_rel(lib->name)) {
|
|
|
|
|
BLI_strncpy(lib->name, lib->filepath, sizeof(lib->name));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for (lib = main->libraries.first; lib; lib = lib->id.next) {
|
|
|
|
|
/* Libraries store both relative and abs paths, recreate relative paths,
|
2019-04-22 01:10:29 +10:00
|
|
|
* relative to the blend file since indirectly linked libs will be
|
|
|
|
|
* relative to their direct linked library. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (BLI_path_is_rel(lib->name)) { /* if this is relative to begin with? */
|
|
|
|
|
BLI_strncpy(lib->name, lib->filepath, sizeof(lib->name));
|
|
|
|
|
BLI_path_rel(lib->name, basepath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Light Probe
|
|
|
|
|
* \{ */
|
2017-06-06 22:47:41 +02:00
|
|
|
|
2017-06-12 20:59:54 +10:00
|
|
|
static void lib_link_lightprobe(FileData *fd, Main *main)
|
2017-06-06 22:47:41 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (LightProbe *prb = main->lightprobes.first; prb; prb = prb->id.next) {
|
|
|
|
|
if (prb->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(prb->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &prb->id, prb->adt);
|
2017-06-06 22:47:41 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
prb->visibility_grp = newlibadr(fd, prb->id.lib, prb->visibility_grp);
|
2018-04-24 12:15:25 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
prb->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-06 22:47:41 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-12 20:59:54 +10:00
|
|
|
static void direct_link_lightprobe(FileData *fd, LightProbe *prb)
|
2017-06-06 22:47:41 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
prb->adt = newdataadr(fd, prb->adt);
|
|
|
|
|
direct_link_animdata(fd, prb->adt);
|
2017-06-06 22:47:41 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Speaker
|
|
|
|
|
* \{ */
|
2011-08-01 11:44:20 +00:00
|
|
|
|
|
|
|
|
static void lib_link_speaker(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Speaker *spk = main->speakers.first; spk; spk = spk->id.next) {
|
|
|
|
|
if (spk->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(spk->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &spk->id, spk->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
spk->sound = newlibadr_us(fd, spk->id.lib, spk->sound);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
spk->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-08-01 11:44:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_speaker(FileData *fd, Speaker *spk)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
spk->adt = newdataadr(fd, spk->adt);
|
|
|
|
|
direct_link_animdata(fd, spk->adt);
|
2011-08-01 11:44:20 +00:00
|
|
|
|
2012-04-22 11:54:53 +00:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
spk->sound = newdataadr(fd, spk->sound);
|
|
|
|
|
direct_link_sound(fd, spk->sound);
|
2012-04-22 11:54:53 +00:00
|
|
|
#endif
|
2011-08-01 11:44:20 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Sound
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void direct_link_sound(FileData *fd, bSound *sound)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
sound->tags = 0;
|
|
|
|
|
sound->handle = NULL;
|
|
|
|
|
sound->playback_handle = NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* versioning stuff, if there was a cache, then we enable caching: */
|
|
|
|
|
if (sound->cache) {
|
|
|
|
|
sound->flags |= SOUND_FLAGS_CACHING;
|
|
|
|
|
sound->cache = NULL;
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->soundmap) {
|
|
|
|
|
sound->waveform = newsoundadr(fd, sound->waveform);
|
|
|
|
|
sound->tags |= SOUND_TAGS_WAVEFORM_NO_RELOAD;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sound->waveform = NULL;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
|
|
|
|
|
BLI_spin_init(sound->spinlock);
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* clear waveform loading flag */
|
|
|
|
|
sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
|
2014-11-24 18:18:35 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sound->packedfile = direct_link_packedfile(fd, sound->packedfile);
|
|
|
|
|
sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_sound(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bSound *sound = main->sounds.first; sound; sound = sound->id.next) {
|
|
|
|
|
if (sound->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(sound->id.properties, fd);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sound->ipo = newlibadr_us(
|
|
|
|
|
fd, sound->id.lib, sound->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
BKE_sound_reset_runtime(sound);
|
2017-03-28 10:03:59 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sound->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Movie Clip
|
|
|
|
|
* \{ */
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void direct_link_movieReconstruction(FileData *fd,
|
|
|
|
|
MovieTrackingReconstruction *reconstruction)
|
2011-12-05 18:57:17 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
reconstruction->cameras = newdataadr(fd, reconstruction->cameras);
|
2011-12-05 18:57:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_movieTracks(FileData *fd, ListBase *tracksbase)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MovieTrackingTrack *track;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, tracksbase);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (track = tracksbase->first; track; track = track->next) {
|
|
|
|
|
track->markers = newdataadr(fd, track->markers);
|
|
|
|
|
}
|
2011-12-05 18:57:17 +00:00
|
|
|
}
|
|
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
static void direct_link_moviePlaneTracks(FileData *fd, ListBase *plane_tracks_base)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MovieTrackingPlaneTrack *plane_track;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, plane_tracks_base);
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
|
|
|
|
|
int i;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
plane_track->point_tracks = newdataadr(fd, plane_track->point_tracks);
|
|
|
|
|
test_pointer_array(fd, (void **)&plane_track->point_tracks);
|
|
|
|
|
for (i = 0; i < plane_track->point_tracksnr; i++) {
|
|
|
|
|
plane_track->point_tracks[i] = newdataadr(fd, plane_track->point_tracks[i]);
|
|
|
|
|
}
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
plane_track->markers = newdataadr(fd, plane_track->markers);
|
|
|
|
|
}
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
static void direct_link_movieclip(FileData *fd, MovieClip *clip)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MovieTracking *tracking = &clip->tracking;
|
|
|
|
|
MovieTrackingObject *object;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->adt = newdataadr(fd, clip->adt);
|
2012-02-17 08:13:45 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->movieclipmap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->cache = newmclipadr(fd, clip->cache);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->cache = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->movieclipmap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->tracking.camera.intrinsics = newmclipadr(fd, clip->tracking.camera.intrinsics);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->tracking.camera.intrinsics = NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_movieTracks(fd, &tracking->tracks);
|
|
|
|
|
direct_link_moviePlaneTracks(fd, &tracking->plane_tracks);
|
|
|
|
|
direct_link_movieReconstruction(fd, &tracking->reconstruction);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->tracking.act_track = newdataadr(fd, clip->tracking.act_track);
|
|
|
|
|
clip->tracking.act_plane_track = newdataadr(fd, clip->tracking.act_plane_track);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->anim = NULL;
|
|
|
|
|
clip->tracking_context = NULL;
|
|
|
|
|
clip->tracking.stats = NULL;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Needed for proper versioning, will be NULL for all newer files anyway. */
|
|
|
|
|
clip->tracking.stabilization.rot_track = newdataadr(fd, clip->tracking.stabilization.rot_track);
|
2011-12-05 18:57:17 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->tracking.dopesheet.ok = 0;
|
|
|
|
|
BLI_listbase_clear(&clip->tracking.dopesheet.channels);
|
|
|
|
|
BLI_listbase_clear(&clip->tracking.dopesheet.coverage_segments);
|
2012-05-03 23:15:01 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &tracking->objects);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (object = tracking->objects.first; object; object = object->next) {
|
|
|
|
|
direct_link_movieTracks(fd, &object->tracks);
|
|
|
|
|
direct_link_moviePlaneTracks(fd, &object->plane_tracks);
|
|
|
|
|
direct_link_movieReconstruction(fd, &object->reconstruction);
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-10 15:26:50 +00:00
|
|
|
static void lib_link_movieTracks(FileData *fd, MovieClip *clip, ListBase *tracksbase)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MovieTrackingTrack *track;
|
2012-06-10 15:26:50 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (track = tracksbase->first; track; track = track->next) {
|
|
|
|
|
track->gpd = newlibadr_us(fd, clip->id.lib, track->gpd);
|
|
|
|
|
}
|
2012-06-10 15:26:50 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-29 23:26:57 +06:00
|
|
|
static void lib_link_moviePlaneTracks(FileData *fd, MovieClip *clip, ListBase *tracksbase)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MovieTrackingPlaneTrack *plane_track;
|
2013-11-29 23:26:57 +06:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (plane_track = tracksbase->first; plane_track; plane_track = plane_track->next) {
|
|
|
|
|
plane_track->image = newlibadr_us(fd, clip->id.lib, plane_track->image);
|
|
|
|
|
}
|
2013-11-29 23:26:57 +06:00
|
|
|
}
|
|
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
static void lib_link_movieclip(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (MovieClip *clip = main->movieclips.first; clip; clip = clip->id.next) {
|
|
|
|
|
if (clip->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
MovieTracking *tracking = &clip->tracking;
|
2012-06-10 15:26:50 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
IDP_LibLinkProperty(clip->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &clip->id, clip->adt);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->gpd = newlibadr_us(fd, clip->id.lib, clip->gpd);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_movieTracks(fd, clip, &tracking->tracks);
|
|
|
|
|
lib_link_moviePlaneTracks(fd, clip, &tracking->plane_tracks);
|
2012-06-10 15:26:50 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (MovieTrackingObject *object = tracking->objects.first; object; object = object->next) {
|
|
|
|
|
lib_link_movieTracks(fd, clip, &object->tracks);
|
|
|
|
|
lib_link_moviePlaneTracks(fd, clip, &object->plane_tracks);
|
|
|
|
|
}
|
2012-06-10 15:26:50 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
clip->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Masks
|
|
|
|
|
* \{ */
|
2012-06-04 16:42:58 +00:00
|
|
|
|
|
|
|
|
static void direct_link_mask(FileData *fd, Mask *mask)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MaskLayer *masklay;
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
mask->adt = newdataadr(fd, mask->adt);
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &mask->masklayers);
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
|
|
|
|
|
MaskSpline *spline;
|
|
|
|
|
MaskLayerShape *masklay_shape;
|
2016-04-27 14:33:51 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* can't use newdataadr since it's a pointer within an array */
|
|
|
|
|
MaskSplinePoint *act_point_search = NULL;
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &masklay->splines);
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (spline = masklay->splines.first; spline; spline = spline->next) {
|
|
|
|
|
MaskSplinePoint *points_old = spline->points;
|
|
|
|
|
int i;
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
spline->points = newdataadr(fd, spline->points);
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (i = 0; i < spline->tot_point; i++) {
|
|
|
|
|
MaskSplinePoint *point = &spline->points[i];
|
2016-04-27 14:33:51 +10:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (point->tot_uw) {
|
2019-04-17 06:17:24 +02:00
|
|
|
point->uw = newdataadr(fd, point->uw);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* detect active point */
|
|
|
|
|
if ((act_point_search == NULL) && (masklay->act_point >= points_old) &&
|
|
|
|
|
(masklay->act_point < points_old + spline->tot_point)) {
|
|
|
|
|
act_point_search = &spline->points[masklay->act_point - points_old];
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &masklay->splines_shapes);
|
2012-09-23 18:50:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
|
|
|
|
|
masklay_shape = masklay_shape->next) {
|
|
|
|
|
masklay_shape->data = newdataadr(fd, masklay_shape->data);
|
2012-09-23 18:50:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (masklay_shape->tot_vert) {
|
|
|
|
|
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
BLI_endian_switch_float_array(masklay_shape->data,
|
|
|
|
|
masklay_shape->tot_vert * sizeof(float) *
|
|
|
|
|
MASK_OBJECT_SHAPE_ELEM_SIZE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
masklay->act_spline = newdataadr(fd, masklay->act_spline);
|
|
|
|
|
masklay->act_point = act_point_search;
|
|
|
|
|
}
|
2012-06-04 16:42:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_mask_parent(FileData *fd, Mask *mask, MaskParent *parent)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
parent->id = newlibadr_us(fd, mask->id.lib, parent->id);
|
2012-06-04 16:42:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_mask(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Mask *mask = main->masks.first; mask; mask = mask->id.next) {
|
|
|
|
|
if (mask->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
IDP_LibLinkProperty(mask->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &mask->id, mask->adt);
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (MaskLayer *masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
|
|
|
|
|
MaskSpline *spline;
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
spline = masklay->splines.first;
|
|
|
|
|
while (spline) {
|
|
|
|
|
int i;
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (i = 0; i < spline->tot_point; i++) {
|
|
|
|
|
MaskSplinePoint *point = &spline->points[i];
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_mask_parent(fd, mask, &point->parent);
|
|
|
|
|
}
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_mask_parent(fd, mask, &spline->parent);
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
spline = spline->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
mask->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-06-04 16:42:58 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read ID: Line Style
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2010-07-24 20:37:54 +00:00
|
|
|
static void lib_link_linestyle(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (FreestyleLineStyle *linestyle = main->linestyles.first; linestyle;
|
|
|
|
|
linestyle = linestyle->id.next) {
|
|
|
|
|
if (linestyle->id.tag & LIB_TAG_NEED_LINK) {
|
|
|
|
|
LineStyleModifier *m;
|
|
|
|
|
|
|
|
|
|
IDP_LibLinkProperty(linestyle->id.properties, fd);
|
|
|
|
|
lib_link_animdata(fd, &linestyle->id, linestyle->adt);
|
|
|
|
|
|
|
|
|
|
for (m = linestyle->color_modifiers.first; m; m = m->next) {
|
|
|
|
|
switch (m->type) {
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
|
|
|
|
LineStyleColorModifier_DistanceFromObject *cm =
|
|
|
|
|
(LineStyleColorModifier_DistanceFromObject *)m;
|
|
|
|
|
cm->target = newlibadr(fd, linestyle->id.lib, cm->target);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (m = linestyle->alpha_modifiers.first; m; m = m->next) {
|
|
|
|
|
switch (m->type) {
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
|
|
|
|
LineStyleAlphaModifier_DistanceFromObject *am =
|
|
|
|
|
(LineStyleAlphaModifier_DistanceFromObject *)m;
|
|
|
|
|
am->target = newlibadr(fd, linestyle->id.lib, am->target);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (m = linestyle->thickness_modifiers.first; m; m = m->next) {
|
|
|
|
|
switch (m->type) {
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
|
|
|
|
LineStyleThicknessModifier_DistanceFromObject *tm =
|
|
|
|
|
(LineStyleThicknessModifier_DistanceFromObject *)m;
|
|
|
|
|
tm->target = newlibadr(fd, linestyle->id.lib, tm->target);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int a = 0; a < MAX_MTEX; a++) {
|
|
|
|
|
MTex *mtex = linestyle->mtex[a];
|
|
|
|
|
if (mtex) {
|
|
|
|
|
mtex->tex = newlibadr_us(fd, linestyle->id.lib, mtex->tex);
|
|
|
|
|
mtex->object = newlibadr(fd, linestyle->id.lib, mtex->object);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (linestyle->nodetree) {
|
|
|
|
|
lib_link_ntree(fd, &linestyle->id, linestyle->nodetree);
|
|
|
|
|
linestyle->nodetree->id.lib = linestyle->id.lib;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
linestyle->id.tag &= ~LIB_TAG_NEED_LINK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-07-24 20:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_linestyle_color_modifier(FileData *fd, LineStyleModifier *modifier)
|
2010-06-25 22:45:42 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
switch (modifier->type) {
|
|
|
|
|
case LS_MODIFIER_ALONG_STROKE: {
|
|
|
|
|
LineStyleColorModifier_AlongStroke *m = (LineStyleColorModifier_AlongStroke *)modifier;
|
|
|
|
|
m->color_ramp = newdataadr(fd, m->color_ramp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_CAMERA: {
|
|
|
|
|
LineStyleColorModifier_DistanceFromCamera *m = (LineStyleColorModifier_DistanceFromCamera *)
|
|
|
|
|
modifier;
|
|
|
|
|
m->color_ramp = newdataadr(fd, m->color_ramp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
|
|
|
|
LineStyleColorModifier_DistanceFromObject *m = (LineStyleColorModifier_DistanceFromObject *)
|
|
|
|
|
modifier;
|
|
|
|
|
m->color_ramp = newdataadr(fd, m->color_ramp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_MATERIAL: {
|
|
|
|
|
LineStyleColorModifier_Material *m = (LineStyleColorModifier_Material *)modifier;
|
|
|
|
|
m->color_ramp = newdataadr(fd, m->color_ramp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_TANGENT: {
|
|
|
|
|
LineStyleColorModifier_Tangent *m = (LineStyleColorModifier_Tangent *)modifier;
|
|
|
|
|
m->color_ramp = newdataadr(fd, m->color_ramp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_NOISE: {
|
|
|
|
|
LineStyleColorModifier_Noise *m = (LineStyleColorModifier_Noise *)modifier;
|
|
|
|
|
m->color_ramp = newdataadr(fd, m->color_ramp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_CREASE_ANGLE: {
|
|
|
|
|
LineStyleColorModifier_CreaseAngle *m = (LineStyleColorModifier_CreaseAngle *)modifier;
|
|
|
|
|
m->color_ramp = newdataadr(fd, m->color_ramp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_CURVATURE_3D: {
|
|
|
|
|
LineStyleColorModifier_Curvature_3D *m = (LineStyleColorModifier_Curvature_3D *)modifier;
|
|
|
|
|
m->color_ramp = newdataadr(fd, m->color_ramp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-07-24 20:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_linestyle_alpha_modifier(FileData *fd, LineStyleModifier *modifier)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
switch (modifier->type) {
|
|
|
|
|
case LS_MODIFIER_ALONG_STROKE: {
|
|
|
|
|
LineStyleAlphaModifier_AlongStroke *m = (LineStyleAlphaModifier_AlongStroke *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_CAMERA: {
|
|
|
|
|
LineStyleAlphaModifier_DistanceFromCamera *m = (LineStyleAlphaModifier_DistanceFromCamera *)
|
|
|
|
|
modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
|
|
|
|
LineStyleAlphaModifier_DistanceFromObject *m = (LineStyleAlphaModifier_DistanceFromObject *)
|
|
|
|
|
modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_MATERIAL: {
|
|
|
|
|
LineStyleAlphaModifier_Material *m = (LineStyleAlphaModifier_Material *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_TANGENT: {
|
|
|
|
|
LineStyleAlphaModifier_Tangent *m = (LineStyleAlphaModifier_Tangent *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_NOISE: {
|
|
|
|
|
LineStyleAlphaModifier_Noise *m = (LineStyleAlphaModifier_Noise *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_CREASE_ANGLE: {
|
|
|
|
|
LineStyleAlphaModifier_CreaseAngle *m = (LineStyleAlphaModifier_CreaseAngle *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_CURVATURE_3D: {
|
|
|
|
|
LineStyleAlphaModifier_Curvature_3D *m = (LineStyleAlphaModifier_Curvature_3D *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-07-24 20:37:54 +00:00
|
|
|
}
|
2010-06-25 22:45:42 +00:00
|
|
|
|
2010-07-24 20:37:54 +00:00
|
|
|
static void direct_link_linestyle_thickness_modifier(FileData *fd, LineStyleModifier *modifier)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
switch (modifier->type) {
|
|
|
|
|
case LS_MODIFIER_ALONG_STROKE: {
|
|
|
|
|
LineStyleThicknessModifier_AlongStroke *m = (LineStyleThicknessModifier_AlongStroke *)
|
|
|
|
|
modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_CAMERA: {
|
|
|
|
|
LineStyleThicknessModifier_DistanceFromCamera *m =
|
|
|
|
|
(LineStyleThicknessModifier_DistanceFromCamera *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
|
|
|
|
LineStyleThicknessModifier_DistanceFromObject *m =
|
|
|
|
|
(LineStyleThicknessModifier_DistanceFromObject *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_MATERIAL: {
|
|
|
|
|
LineStyleThicknessModifier_Material *m = (LineStyleThicknessModifier_Material *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_TANGENT: {
|
|
|
|
|
LineStyleThicknessModifier_Tangent *m = (LineStyleThicknessModifier_Tangent *)modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_CREASE_ANGLE: {
|
|
|
|
|
LineStyleThicknessModifier_CreaseAngle *m = (LineStyleThicknessModifier_CreaseAngle *)
|
|
|
|
|
modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LS_MODIFIER_CURVATURE_3D: {
|
|
|
|
|
LineStyleThicknessModifier_Curvature_3D *m = (LineStyleThicknessModifier_Curvature_3D *)
|
|
|
|
|
modifier;
|
|
|
|
|
m->curve = newdataadr(fd, m->curve);
|
|
|
|
|
direct_link_curvemapping(fd, m->curve);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_linestyle_geometry_modifier(FileData *UNUSED(fd),
|
|
|
|
|
LineStyleModifier *UNUSED(modifier))
|
2011-08-19 14:05:11 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-24 20:37:54 +00:00
|
|
|
static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int a;
|
|
|
|
|
LineStyleModifier *modifier;
|
|
|
|
|
|
|
|
|
|
linestyle->adt = newdataadr(fd, linestyle->adt);
|
|
|
|
|
direct_link_animdata(fd, linestyle->adt);
|
|
|
|
|
link_list(fd, &linestyle->color_modifiers);
|
2019-04-22 09:13:00 +10:00
|
|
|
for (modifier = linestyle->color_modifiers.first; modifier; modifier = modifier->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_linestyle_color_modifier(fd, modifier);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &linestyle->alpha_modifiers);
|
2019-04-22 09:13:00 +10:00
|
|
|
for (modifier = linestyle->alpha_modifiers.first; modifier; modifier = modifier->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_linestyle_alpha_modifier(fd, modifier);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &linestyle->thickness_modifiers);
|
2019-04-22 09:13:00 +10:00
|
|
|
for (modifier = linestyle->thickness_modifiers.first; modifier; modifier = modifier->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_linestyle_thickness_modifier(fd, modifier);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &linestyle->geometry_modifiers);
|
2019-04-22 09:13:00 +10:00
|
|
|
for (modifier = linestyle->geometry_modifiers.first; modifier; modifier = modifier->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_linestyle_geometry_modifier(fd, modifier);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
for (a = 0; a < MAX_MTEX; a++) {
|
|
|
|
|
linestyle->mtex[a] = newdataadr(fd, linestyle->mtex[a]);
|
|
|
|
|
}
|
|
|
|
|
linestyle->nodetree = newdataadr(fd, linestyle->nodetree);
|
|
|
|
|
if (linestyle->nodetree) {
|
|
|
|
|
direct_link_id(fd, &linestyle->nodetree->id);
|
|
|
|
|
direct_link_nodetree(fd, linestyle->nodetree);
|
|
|
|
|
}
|
2010-07-24 20:37:54 +00:00
|
|
|
}
|
2010-06-25 22:45:42 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read Library Data Block
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2019-08-12 11:54:37 +02:00
|
|
|
static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const int tag)
|
|
|
|
|
{
|
|
|
|
|
ListBase *lb = which_libbase(mainvar, idcode);
|
|
|
|
|
ID *ph_id = BKE_libblock_alloc_notest(idcode);
|
|
|
|
|
|
|
|
|
|
*((short *)ph_id->name) = idcode;
|
|
|
|
|
BLI_strncpy(ph_id->name + 2, idname, sizeof(ph_id->name) - 2);
|
|
|
|
|
BKE_libblock_init_empty(ph_id);
|
|
|
|
|
ph_id->lib = mainvar->curlib;
|
|
|
|
|
ph_id->tag = tag | LIB_TAG_MISSING;
|
|
|
|
|
ph_id->us = ID_FAKE_USERS(ph_id);
|
|
|
|
|
ph_id->icon_id = 0;
|
|
|
|
|
|
|
|
|
|
BLI_addtail(lb, ph_id);
|
|
|
|
|
id_sort_by_name(lb, ph_id);
|
|
|
|
|
|
|
|
|
|
return ph_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void placeholders_ensure_valid(Main *bmain)
|
|
|
|
|
{
|
|
|
|
|
/* Placeholder ObData IDs won't have any material, we have to update their objects for that,
|
|
|
|
|
* otherwise the inconsistency between both will lead to crashes (especially in Eevee?). */
|
|
|
|
|
for (Object *ob = bmain->objects.first; ob != NULL; ob = ob->id.next) {
|
|
|
|
|
ID *obdata = ob->data;
|
|
|
|
|
if (obdata != NULL && obdata->tag & LIB_TAG_MISSING) {
|
|
|
|
|
test_object_materials(bmain, ob, obdata);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-03 17:05:21 +00:00
|
|
|
static const char *dataname(short id_code)
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
switch (id_code) {
|
|
|
|
|
case ID_OB:
|
|
|
|
|
return "Data from OB";
|
|
|
|
|
case ID_ME:
|
|
|
|
|
return "Data from ME";
|
|
|
|
|
case ID_IP:
|
|
|
|
|
return "Data from IP";
|
|
|
|
|
case ID_SCE:
|
|
|
|
|
return "Data from SCE";
|
|
|
|
|
case ID_MA:
|
|
|
|
|
return "Data from MA";
|
|
|
|
|
case ID_TE:
|
|
|
|
|
return "Data from TE";
|
|
|
|
|
case ID_CU:
|
|
|
|
|
return "Data from CU";
|
|
|
|
|
case ID_GR:
|
|
|
|
|
return "Data from GR";
|
|
|
|
|
case ID_AR:
|
|
|
|
|
return "Data from AR";
|
|
|
|
|
case ID_AC:
|
|
|
|
|
return "Data from AC";
|
|
|
|
|
case ID_LI:
|
|
|
|
|
return "Data from LI";
|
|
|
|
|
case ID_MB:
|
|
|
|
|
return "Data from MB";
|
|
|
|
|
case ID_IM:
|
|
|
|
|
return "Data from IM";
|
|
|
|
|
case ID_LT:
|
|
|
|
|
return "Data from LT";
|
|
|
|
|
case ID_LA:
|
|
|
|
|
return "Data from LA";
|
|
|
|
|
case ID_CA:
|
|
|
|
|
return "Data from CA";
|
|
|
|
|
case ID_KE:
|
|
|
|
|
return "Data from KE";
|
|
|
|
|
case ID_WO:
|
|
|
|
|
return "Data from WO";
|
|
|
|
|
case ID_SCR:
|
|
|
|
|
return "Data from SCR";
|
|
|
|
|
case ID_VF:
|
|
|
|
|
return "Data from VF";
|
|
|
|
|
case ID_TXT:
|
|
|
|
|
return "Data from TXT";
|
|
|
|
|
case ID_SPK:
|
|
|
|
|
return "Data from SPK";
|
|
|
|
|
case ID_LP:
|
|
|
|
|
return "Data from LP";
|
|
|
|
|
case ID_SO:
|
|
|
|
|
return "Data from SO";
|
|
|
|
|
case ID_NT:
|
|
|
|
|
return "Data from NT";
|
|
|
|
|
case ID_BR:
|
|
|
|
|
return "Data from BR";
|
|
|
|
|
case ID_PA:
|
|
|
|
|
return "Data from PA";
|
|
|
|
|
case ID_PAL:
|
|
|
|
|
return "Data from PAL";
|
|
|
|
|
case ID_PC:
|
|
|
|
|
return "Data from PCRV";
|
|
|
|
|
case ID_GD:
|
|
|
|
|
return "Data from GD";
|
|
|
|
|
case ID_WM:
|
|
|
|
|
return "Data from WM";
|
|
|
|
|
case ID_MC:
|
|
|
|
|
return "Data from MC";
|
|
|
|
|
case ID_MSK:
|
|
|
|
|
return "Data from MSK";
|
|
|
|
|
case ID_LS:
|
|
|
|
|
return "Data from LS";
|
|
|
|
|
case ID_CF:
|
|
|
|
|
return "Data from CF";
|
|
|
|
|
case ID_WS:
|
|
|
|
|
return "Data from WS";
|
|
|
|
|
}
|
|
|
|
|
return "Data from Lib Block";
|
Orange: more noodle updates!
**** NEW: Group Nodes
Node trees usually become messy and confusing quickly, so we need
not only a way to collapse Nodes into single 'groups', but also a
way to re-use that data to create libraries of effects.
This has been done by making a new Library data type, the NodeTree.
Everything that has been grouped is stored here, and available for
re-use, appending or linking. These NodeTrees are fully generic,
i.e. can store shader trees, composit trees, and so on. The 'type'
value as stored in the NodeTree will keep track of internal type
definitions and execute/drawing callbacks. Needless to say, re-using
shader trees in a composit tree is a bit useless, and will be
prevented in the browsing code. :)
So; any NodeTree can become a "Goup Node" inside in a NodeTree. This
Group Node then works just like any Node.
To prevent the current code to become too complex, I've disabled
the possibility to insert Groups inside of Groups. That might be
enabled later, but is a real nasty piece of code to get OK.
Since Group Nodes are a dynamic Node type, a lot of work has been
done to ensure Node definitions can be dynamic too, but still allow
to be stored in files, and allow to be verified for type-definition
changes on reloading. This system needs a little bit maturing still,
so the Python gurus should better wait a little bit! (Also for me to
write the definite API docs for it).
What works now:
- Press CTRL+G to create a new Group. The grouping code checks for
impossible selections (like an unselected node between selected nodes).
Everthing that's selected then gets removed from the current tree, and
inserted in a new NodeTree library data block. A Group Node then is
added which links to this new NodeTree.
- Press ALT+G to ungroup. This will not delete the NodeTree library
data, but just duplicate the Group into the current tree.
- Press TAB, or click on the NodeTree icon to edit Groups. Note that
NodeTrees are instances, so editing one Group will also change the
other users.
This also means that when removing nodes in a Group (or hiding sockets
or changing internal links) this is immediately corrected for all users
of this Group, also in other Materials.
- While editing Groups, only the internal Nodes can be edited. A single
click outside of the Group boundary will close this 'edit mode'.
What needs to be done:
- SHIFT+A menu in toolbox style, also including a list of Groups
- Enable the single-user button in the Group Node
- Displaying all (visible) internal group UI elements in the Node Panel
- Enable Library linking and prevent editing of Groups then.
**** NEW: Socket Visibility control
Node types will be generated with a lot of possible inputs or outputs,
and drawing all sockets all the time isn't very useful then.
A new option in the Node header ('plus' icon) allows to either hide all
unused sockets (first keypress) or to reveil them (when there are hidden
sockets, the icon displays black, otherwise it's blended).
Hidden sockets in Nodes also are not exported to a Group, so this way
you can control what options (in/outputs) exactly are available.
To be done:
- a way to hide individual sockets, like with a RMB click on it.
**** NEW: Nodes now render!
This is still quite primitive, more on a level to replace the (now
obsolete and disabled) Material Layers.
What needs to be done:
- make the "Geometry" node work properly, also for AA textures
- make the Texture Node work (does very little at the moment)
- give Material Nodes all inputs as needed (like Map-to Panel)
- find a way to export more data from a Material Node, like the
shadow value, or light intensity only, etc
Very important also to separate from the Material Buttons the
"global" options, like "Ztransp" or "Wire" or "Halo". These can not
be set for each Material-Node individually.
Also note that the Preview Render (Buttons window) now renders a bit
differently. This was a horrid piece of antique code, using a totally
incompatible way of rendering. Target is to fully re-use internal
render code for previews.
OK... that's it mostly. Now test!
2006-01-02 13:06:05 +00:00
|
|
|
}
|
|
|
|
|
|
2010-12-03 17:05:21 +00:00
|
|
|
static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *allocname)
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bhead = blo_bhead_next(fd, bhead);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
while (bhead && bhead->code == DATA) {
|
|
|
|
|
void *data;
|
2010-02-13 13:38:10 +00:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
/* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */
|
|
|
|
|
short *sp = fd->filesdna->structs[bhead->SDNAnr];
|
|
|
|
|
char *tmp = malloc(100);
|
|
|
|
|
allocname = fd->filesdna->types[sp[0]];
|
|
|
|
|
strcpy(tmp, allocname);
|
|
|
|
|
data = read_struct(fd, bhead, tmp);
|
2010-02-13 13:38:10 +00:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
data = read_struct(fd, bhead, allocname);
|
2010-02-13 13:38:10 +00:00
|
|
|
#endif
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (data) {
|
|
|
|
|
oldnewmap_insert(fd->datamap, bhead->old, data, 0);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bhead = blo_bhead_next(fd, bhead);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return bhead;
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-26 14:14:56 +01:00
|
|
|
static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int tag, ID **r_id)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* this routine reads a libblock and its direct data. Use link functions to connect it all
|
|
|
|
|
*/
|
|
|
|
|
ID *id;
|
|
|
|
|
ListBase *lb;
|
|
|
|
|
const char *allocname;
|
|
|
|
|
bool wrong_id = false;
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* In undo case, most libs and linked data should be kept as is from previous state
|
|
|
|
|
* (see BLO_read_from_memfile).
|
|
|
|
|
* However, some needed by the snapshot being read may have been removed in previous one,
|
|
|
|
|
* and would go missing.
|
2019-04-17 06:17:24 +02:00
|
|
|
* This leads e.g. to disappearing objects in some undo/redo case, see T34446.
|
2019-04-22 01:10:29 +10:00
|
|
|
* That means we have to carefully check whether current lib or
|
|
|
|
|
* libdata already exits in old main, if it does we merely copy it over into new main area,
|
|
|
|
|
* otherwise we have to do a full read of that bhead... */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd->memfile && ELEM(bhead->code, ID_LI, ID_LINK_PLACEHOLDER)) {
|
|
|
|
|
const char *idname = blo_bhead_id_name(fd, bhead);
|
|
|
|
|
|
|
|
|
|
DEBUG_PRINTF("Checking %s...\n", idname);
|
|
|
|
|
|
|
|
|
|
if (bhead->code == ID_LI) {
|
|
|
|
|
Main *libmain = fd->old_mainlist->first;
|
|
|
|
|
/* Skip oldmain itself... */
|
|
|
|
|
for (libmain = libmain->next; libmain; libmain = libmain->next) {
|
|
|
|
|
DEBUG_PRINTF("... against %s: ", libmain->curlib ? libmain->curlib->id.name : "<NULL>");
|
|
|
|
|
if (libmain->curlib && STREQ(idname, libmain->curlib->id.name)) {
|
|
|
|
|
Main *oldmain = fd->old_mainlist->first;
|
|
|
|
|
DEBUG_PRINTF("FOUND!\n");
|
2019-04-22 01:10:29 +10:00
|
|
|
/* In case of a library, we need to re-add its main to fd->mainlist,
|
|
|
|
|
* because if we have later a missing ID_LINK_PLACEHOLDER,
|
|
|
|
|
* we need to get the correct lib it is linked to!
|
|
|
|
|
* Order is crucial, we cannot bulk-add it in BLO_read_from_memfile()
|
|
|
|
|
* like it used to be. */
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_remlink(fd->old_mainlist, libmain);
|
|
|
|
|
BLI_remlink_safe(&oldmain->libraries, libmain->curlib);
|
|
|
|
|
BLI_addtail(fd->mainlist, libmain);
|
|
|
|
|
BLI_addtail(&main->libraries, libmain->curlib);
|
|
|
|
|
|
|
|
|
|
if (r_id) {
|
|
|
|
|
*r_id = NULL; /* Just in case... */
|
|
|
|
|
}
|
|
|
|
|
return blo_bhead_next(fd, bhead);
|
|
|
|
|
}
|
|
|
|
|
DEBUG_PRINTF("nothing...\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
DEBUG_PRINTF("... in %s (%s): ",
|
|
|
|
|
main->curlib ? main->curlib->id.name : "<NULL>",
|
|
|
|
|
main->curlib ? main->curlib->name : "<NULL>");
|
|
|
|
|
if ((id = BKE_libblock_find_name(main, GS(idname), idname + 2))) {
|
|
|
|
|
DEBUG_PRINTF("FOUND!\n");
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Even though we found our linked ID,
|
|
|
|
|
* there is no guarantee its address is still the same. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (id != bhead->old) {
|
|
|
|
|
oldnewmap_insert(fd->libmap, bhead->old, id, GS(id->name));
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* No need to do anything else for ID_LINK_PLACEHOLDER,
|
|
|
|
|
* it's assumed already present in its lib's main. */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (r_id) {
|
|
|
|
|
*r_id = NULL; /* Just in case... */
|
|
|
|
|
}
|
|
|
|
|
return blo_bhead_next(fd, bhead);
|
|
|
|
|
}
|
|
|
|
|
DEBUG_PRINTF("nothing...\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* read libblock */
|
|
|
|
|
id = read_struct(fd, bhead, "lib block");
|
|
|
|
|
|
|
|
|
|
if (id) {
|
|
|
|
|
const short idcode = GS(id->name);
|
|
|
|
|
/* do after read_struct, for dna reconstruct */
|
|
|
|
|
lb = which_libbase(main, idcode);
|
|
|
|
|
if (lb) {
|
|
|
|
|
oldnewmap_insert(
|
|
|
|
|
fd->libmap, bhead->old, id, bhead->code); /* for ID_LINK_PLACEHOLDER check */
|
|
|
|
|
BLI_addtail(lb, id);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* unknown ID type */
|
|
|
|
|
printf("%s: unknown id code '%c%c'\n", __func__, (idcode & 0xff), (idcode >> 8));
|
|
|
|
|
MEM_freeN(id);
|
|
|
|
|
id = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (r_id) {
|
2019-04-17 06:17:24 +02:00
|
|
|
*r_id = id;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (!id) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return blo_bhead_next(fd, bhead);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
id->lib = main->curlib;
|
|
|
|
|
id->us = ID_FAKE_USERS(id);
|
|
|
|
|
id->icon_id = 0;
|
|
|
|
|
id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
|
|
|
|
|
id->orig_id = NULL;
|
2019-07-22 17:07:46 +02:00
|
|
|
|
|
|
|
|
/* NOTE: It is important to not clear the recalc flags for undo/redo.
|
|
|
|
|
* Preserving recalc flags on redo/undo is the only way to make dependency graph detect
|
|
|
|
|
* that animation is to be evaluated on undo/redo. If this is not enforced by the recalc
|
|
|
|
|
* flags dependency graph does not do animation update to avoid loss of unkeyed changes.,
|
|
|
|
|
* which conflicts with undo/redo of changes to animation data itself.
|
|
|
|
|
*
|
|
|
|
|
* But for regular file load we clear the flag, since the flags might have been changed sinde
|
|
|
|
|
* the version the file has been saved with. */
|
|
|
|
|
if (!fd->memfile) {
|
|
|
|
|
id->recalc = 0;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* this case cannot be direct_linked: it's just the ID part */
|
|
|
|
|
if (bhead->code == ID_LINK_PLACEHOLDER) {
|
2019-06-17 12:51:53 +10:00
|
|
|
/* That way, we know which data-lock needs do_versions (required currently for linking). */
|
2019-04-17 06:17:24 +02:00
|
|
|
id->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW;
|
|
|
|
|
|
|
|
|
|
return blo_bhead_next(fd, bhead);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* need a name for the mallocN, just for debugging and sane prints on leaks */
|
|
|
|
|
allocname = dataname(GS(id->name));
|
|
|
|
|
|
|
|
|
|
/* read all data into fd->datamap */
|
|
|
|
|
bhead = read_data_into_oldnewmap(fd, bhead, allocname);
|
|
|
|
|
|
|
|
|
|
/* init pointers direct data */
|
|
|
|
|
direct_link_id(fd, id);
|
|
|
|
|
|
2019-06-17 12:51:53 +10:00
|
|
|
/* That way, we know which data-lock needs do_versions (required currently for linking). */
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Note: doing this after driect_link_id(), which resets that field. */
|
|
|
|
|
id->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW;
|
|
|
|
|
|
|
|
|
|
switch (GS(id->name)) {
|
|
|
|
|
case ID_WM:
|
|
|
|
|
direct_link_windowmanager(fd, (wmWindowManager *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_SCR:
|
|
|
|
|
wrong_id = direct_link_screen(fd, (bScreen *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_SCE:
|
|
|
|
|
direct_link_scene(fd, (Scene *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_OB:
|
|
|
|
|
direct_link_object(fd, (Object *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_ME:
|
|
|
|
|
direct_link_mesh(fd, (Mesh *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_CU:
|
|
|
|
|
direct_link_curve(fd, (Curve *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_MB:
|
|
|
|
|
direct_link_mball(fd, (MetaBall *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_MA:
|
|
|
|
|
direct_link_material(fd, (Material *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_TE:
|
|
|
|
|
direct_link_texture(fd, (Tex *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_IM:
|
|
|
|
|
direct_link_image(fd, (Image *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LA:
|
|
|
|
|
direct_link_light(fd, (Light *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_VF:
|
|
|
|
|
direct_link_vfont(fd, (VFont *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_TXT:
|
|
|
|
|
direct_link_text(fd, (Text *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_IP:
|
|
|
|
|
direct_link_ipo(fd, (Ipo *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_KE:
|
|
|
|
|
direct_link_key(fd, (Key *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LT:
|
|
|
|
|
direct_link_latt(fd, (Lattice *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_WO:
|
|
|
|
|
direct_link_world(fd, (World *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LI:
|
|
|
|
|
direct_link_library(fd, (Library *)id, main);
|
|
|
|
|
break;
|
|
|
|
|
case ID_CA:
|
|
|
|
|
direct_link_camera(fd, (Camera *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_SPK:
|
|
|
|
|
direct_link_speaker(fd, (Speaker *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_SO:
|
|
|
|
|
direct_link_sound(fd, (bSound *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LP:
|
|
|
|
|
direct_link_lightprobe(fd, (LightProbe *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_GR:
|
|
|
|
|
direct_link_collection(fd, (Collection *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_AR:
|
|
|
|
|
direct_link_armature(fd, (bArmature *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_AC:
|
|
|
|
|
direct_link_action(fd, (bAction *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_NT:
|
|
|
|
|
direct_link_nodetree(fd, (bNodeTree *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_BR:
|
|
|
|
|
direct_link_brush(fd, (Brush *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_PA:
|
|
|
|
|
direct_link_particlesettings(fd, (ParticleSettings *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_GD:
|
|
|
|
|
direct_link_gpencil(fd, (bGPdata *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_MC:
|
|
|
|
|
direct_link_movieclip(fd, (MovieClip *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_MSK:
|
|
|
|
|
direct_link_mask(fd, (Mask *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LS:
|
|
|
|
|
direct_link_linestyle(fd, (FreestyleLineStyle *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_PAL:
|
|
|
|
|
direct_link_palette(fd, (Palette *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_PC:
|
|
|
|
|
direct_link_paint_curve(fd, (PaintCurve *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_CF:
|
|
|
|
|
direct_link_cachefile(fd, (CacheFile *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_WS:
|
|
|
|
|
direct_link_workspace(fd, (WorkSpace *)id, main);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oldnewmap_free_unused(fd->datamap);
|
|
|
|
|
oldnewmap_clear(fd->datamap);
|
|
|
|
|
|
|
|
|
|
if (wrong_id) {
|
|
|
|
|
BKE_id_free(main, id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (bhead);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read Global Data
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2007-12-24 18:53:37 +00:00
|
|
|
/* note, this has to be kept for reading older files... */
|
|
|
|
|
/* also version info is written here */
|
|
|
|
|
static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileGlobal *fg = read_struct(fd, bhead, "Global");
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* copy to bfd handle */
|
|
|
|
|
bfd->main->subversionfile = fg->subversion;
|
|
|
|
|
bfd->main->minversionfile = fg->minversion;
|
|
|
|
|
bfd->main->minsubversionfile = fg->minsubversion;
|
|
|
|
|
bfd->main->build_commit_timestamp = fg->build_commit_timestamp;
|
|
|
|
|
BLI_strncpy(bfd->main->build_hash, fg->build_hash, sizeof(bfd->main->build_hash));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bfd->fileflags = fg->fileflags;
|
|
|
|
|
bfd->globalf = fg->globalf;
|
|
|
|
|
BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Error in 2.65 and older: main->name was not set if you save from startup
|
|
|
|
|
* (not after loading file). */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bfd->filename[0] == 0) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->fileversion < 265 || (fd->fileversion == 265 && fg->subversion < 1)) {
|
|
|
|
|
if ((G.fileflags & G_FILE_RECOVER) == 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_strncpy(bfd->filename, BKE_main_blendfile_path(bfd->main), sizeof(bfd->filename));
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* early 2.50 version patch - filename not in FileGlobal struct at all */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->fileversion <= 250) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_strncpy(bfd->filename, BKE_main_blendfile_path(bfd->main), sizeof(bfd->filename));
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (G.fileflags & G_FILE_RECOVER) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase));
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bfd->curscreen = fg->curscreen;
|
|
|
|
|
bfd->curscene = fg->curscene;
|
|
|
|
|
bfd->cur_view_layer = fg->cur_view_layer;
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(fg);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->globalf = bfd->globalf;
|
|
|
|
|
fd->fileflags = bfd->fileflags;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return blo_bhead_next(fd, bhead);
|
2007-12-24 18:53:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* note, this has to be kept for reading older files... */
|
|
|
|
|
static void link_global(FileData *fd, BlendFileData *bfd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bfd->cur_view_layer = newglobadr(fd, bfd->cur_view_layer);
|
|
|
|
|
bfd->curscreen = newlibadr(fd, NULL, bfd->curscreen);
|
|
|
|
|
bfd->curscene = newlibadr(fd, NULL, bfd->curscene);
|
|
|
|
|
// this happens in files older than 2.35
|
|
|
|
|
if (bfd->curscene == NULL) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (bfd->curscreen) {
|
2019-04-17 06:17:24 +02:00
|
|
|
bfd->curscene = bfd->curscreen->scene;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Versioning
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2013-03-17 14:38:58 +00:00
|
|
|
/* initialize userdef with non-UI dependency stuff */
|
|
|
|
|
/* other initializers (such as theme color defaults) go to resources.c */
|
2013-12-03 03:14:09 -02:00
|
|
|
static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
|
2013-03-17 14:38:58 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *bmain = bfd->main;
|
|
|
|
|
UserDef *user = bfd->user;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (user == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (MAIN_VERSION_OLDER(bmain, 266, 4)) {
|
|
|
|
|
bTheme *btheme;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Themes for Node and Sequence editor were not using grid color,
|
|
|
|
|
* but back. we copy this over then. */
|
2019-04-17 06:17:24 +02:00
|
|
|
for (btheme = user->themes.first; btheme; btheme = btheme->next) {
|
2019-08-06 04:20:17 +10:00
|
|
|
copy_v4_v4_uchar(btheme->space_node.grid, btheme->space_node.back);
|
|
|
|
|
copy_v4_v4_uchar(btheme->space_sequencer.grid, btheme->space_sequencer.back);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2013-12-03 03:14:09 -02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "WalkNavigation", "walk_navigation")) {
|
|
|
|
|
user->walk_navigation.mouse_speed = 1.0f;
|
|
|
|
|
user->walk_navigation.walk_speed = 2.5f; /* m/s */
|
|
|
|
|
user->walk_navigation.walk_speed_factor = 5.0f;
|
|
|
|
|
user->walk_navigation.view_height = 1.6f; /* m */
|
|
|
|
|
user->walk_navigation.jump_height = 0.4f; /* m */
|
|
|
|
|
user->walk_navigation.teleport_time = 0.2f; /* s */
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* grease pencil multisamples */
|
|
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "gpencil_multisamples")) {
|
|
|
|
|
user->gpencil_multisamples = 4;
|
|
|
|
|
}
|
2018-11-20 15:35:59 +03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* tablet pressure threshold */
|
|
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "float", "pressure_threshold_max")) {
|
|
|
|
|
user->pressure_threshold_max = 1.0f;
|
|
|
|
|
}
|
2013-03-17 14:38:58 +00:00
|
|
|
}
|
2013-04-12 10:52:47 +00:00
|
|
|
|
2012-05-04 15:42:49 +00:00
|
|
|
static void do_versions(FileData *fd, Library *lib, Main *main)
|
2010-05-01 12:39:06 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* WATCH IT!!!: pointers from libdata have not been converted */
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (G.debug & G_DEBUG) {
|
|
|
|
|
char build_commit_datetime[32];
|
|
|
|
|
time_t temp_time = main->build_commit_timestamp;
|
|
|
|
|
struct tm *tm = (temp_time) ? gmtime(&temp_time) : NULL;
|
|
|
|
|
if (LIKELY(tm)) {
|
|
|
|
|
strftime(build_commit_datetime, sizeof(build_commit_datetime), "%Y-%m-%d %H:%M", tm);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_strncpy(build_commit_datetime, "unknown", sizeof(build_commit_datetime));
|
|
|
|
|
}
|
2013-11-15 17:11:59 +06:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
printf("read file %s\n Version %d sub %d date %s hash %s\n",
|
|
|
|
|
fd->relabase,
|
|
|
|
|
main->versionfile,
|
|
|
|
|
main->subversionfile,
|
|
|
|
|
build_commit_datetime,
|
|
|
|
|
main->build_hash);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
blo_do_versions_pre250(fd, lib, 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);
|
2019-04-20 20:25:23 +02:00
|
|
|
blo_do_versions_cycles(fd, lib, main);
|
2013-11-04 19:21:50 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
|
|
|
|
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
|
2012-06-04 16:42:58 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* don't forget to set version number in BKE_blender_version.h! */
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2016-12-23 12:54:51 +01:00
|
|
|
static void do_versions_after_linking(Main *main)
|
2010-06-19 10:50:23 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
// printf("%s for %s (%s), %d.%d\n", __func__, main->curlib ? main->curlib->name : main->name,
|
|
|
|
|
// main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile);
|
2016-12-07 13:52:12 +01:00
|
|
|
|
2019-04-20 20:25:20 +02:00
|
|
|
do_versions_after_linking_250(main);
|
|
|
|
|
do_versions_after_linking_260(main);
|
2019-04-17 06:17:24 +02:00
|
|
|
do_versions_after_linking_270(main);
|
|
|
|
|
do_versions_after_linking_280(main);
|
2019-04-20 20:25:23 +02:00
|
|
|
do_versions_after_linking_cycles(main);
|
2010-06-19 10:50:23 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read Library Data Block (all)
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void lib_link_all(FileData *fd, Main *main)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_id(fd, main);
|
|
|
|
|
|
|
|
|
|
/* No load UI for undo memfiles */
|
|
|
|
|
if (fd->memfile == NULL) {
|
|
|
|
|
lib_link_windowmanager(fd, main);
|
|
|
|
|
}
|
2019-04-22 01:10:29 +10:00
|
|
|
/* DO NOT skip screens here,
|
|
|
|
|
* 3D viewport may contains pointers to other ID data (like bgpic)! See T41411. */
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_screen(fd, main);
|
|
|
|
|
lib_link_scene(fd, main);
|
|
|
|
|
lib_link_object(fd, main);
|
|
|
|
|
lib_link_mesh(fd, main);
|
|
|
|
|
lib_link_curve(fd, main);
|
|
|
|
|
lib_link_mball(fd, main);
|
|
|
|
|
lib_link_material(fd, main);
|
|
|
|
|
lib_link_texture(fd, main);
|
|
|
|
|
lib_link_image(fd, main);
|
|
|
|
|
lib_link_ipo(
|
|
|
|
|
fd, main); /* XXX deprecated... still needs to be maintained for version patches still */
|
|
|
|
|
lib_link_key(fd, main);
|
|
|
|
|
lib_link_world(fd, main);
|
|
|
|
|
lib_link_light(fd, main);
|
|
|
|
|
lib_link_latt(fd, main);
|
|
|
|
|
lib_link_text(fd, main);
|
|
|
|
|
lib_link_camera(fd, main);
|
|
|
|
|
lib_link_speaker(fd, main);
|
|
|
|
|
lib_link_lightprobe(fd, main);
|
|
|
|
|
lib_link_sound(fd, main);
|
|
|
|
|
lib_link_collection(fd, main);
|
|
|
|
|
lib_link_armature(fd, main);
|
|
|
|
|
lib_link_action(fd, main);
|
|
|
|
|
lib_link_vfont(fd, main);
|
|
|
|
|
lib_link_nodetree(fd,
|
|
|
|
|
main); /* has to be done after scene/materials, this will verify group nodes */
|
|
|
|
|
lib_link_palette(fd, main);
|
|
|
|
|
lib_link_brush(fd, main);
|
|
|
|
|
lib_link_paint_curve(fd, main);
|
|
|
|
|
lib_link_particlesettings(fd, main);
|
|
|
|
|
lib_link_movieclip(fd, main);
|
|
|
|
|
lib_link_mask(fd, main);
|
|
|
|
|
lib_link_linestyle(fd, main);
|
|
|
|
|
lib_link_gpencil(fd, main);
|
|
|
|
|
lib_link_cachefiles(fd, main);
|
|
|
|
|
lib_link_workspaces(fd, main);
|
|
|
|
|
|
|
|
|
|
lib_link_library(fd, main); /* only init users */
|
|
|
|
|
|
|
|
|
|
/* We could integrate that to mesh/curve/lattice lib_link, but this is really cheap process,
|
|
|
|
|
* so simpler to just use it directly in this single call. */
|
|
|
|
|
BLO_main_validate_shapekeys(main, NULL);
|
2019-05-22 22:57:16 +02:00
|
|
|
|
|
|
|
|
if (fd->memfile != NULL) {
|
2019-06-12 09:04:10 +10:00
|
|
|
/* When doing redo, we perform a tremendous amount of esoteric magic tricks to avoid having to
|
|
|
|
|
* re-read all library data-blocks.
|
2019-05-22 22:57:16 +02:00
|
|
|
* Unfortunately, that means that we do not clear Collections' parents lists, which then get
|
|
|
|
|
* improperly extended in some cases by lib_link_scene() and lib_link_collection() calls above
|
2019-07-07 15:38:41 +10:00
|
|
|
* (when one local collection is parent of linked ones).
|
2019-05-22 22:57:16 +02:00
|
|
|
* I do not really see a way to address that issue, besides brute force call below which
|
|
|
|
|
* invalidates and re-creates all parenting relationships between collections. Yet another
|
|
|
|
|
* example of why it is such a bad idea to keep that kind of double-linked relationships info
|
|
|
|
|
* 'permanently' in our data structures... */
|
|
|
|
|
BKE_main_collections_parent_relations_rebuild(main);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read User Preferences
|
|
|
|
|
* \{ */
|
|
|
|
|
|
KEYMAP REFACTORING
Diff Keymaps
User edited keymaps now no longer override the builtin keymaps entirely, but
rather save only the difference and reapply those changes. This means they can
stay better in sync when the builtin keymaps change. The diff/patch algorithm
is not perfect, but better for the common case where only a few items are changed
rather than entire keymaps The main weakness is that if a builtin keymap item
changes, user modification of that item may need to be redone in some cases.
Keymap Editor
The most noticeable change here is that there is no longer an "Edit" button for
keymaps, all are editable immediately, but a "Restore" buttons shows for keymaps
and items that have been edited. Shortcuts for addons can also be edited in the
keymap editor.
Addons
Addons now should only modify the new addon keyconfiguration, the keymap items
there will be added to the builtin ones for handling events, and not get lost
when starting new files. Example code of register/unregister:
km = wm.keyconfigs.addon.keymaps.new("3D View", space_type="VIEW_3D")
km.keymap_items.new('my.operator', 'ESC', 'PRESS')
km = wm.keyconfigs.addon.keymaps["3D View"]
km.keymap_items.remove(km.keymap_items["my.operator"])
Compatibility
The changes made are not forward compatible, i.e. if you save user preferences
with newer versions, older versions will not have key configuration changes that
were made.
2011-08-05 20:45:26 +00:00
|
|
|
static void direct_link_keymapitem(FileData *fd, wmKeyMapItem *kmi)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
kmi->properties = newdataadr(fd, kmi->properties);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
kmi->ptr = NULL;
|
|
|
|
|
kmi->flag &= ~KMI_UPDATE;
|
KEYMAP REFACTORING
Diff Keymaps
User edited keymaps now no longer override the builtin keymaps entirely, but
rather save only the difference and reapply those changes. This means they can
stay better in sync when the builtin keymaps change. The diff/patch algorithm
is not perfect, but better for the common case where only a few items are changed
rather than entire keymaps The main weakness is that if a builtin keymap item
changes, user modification of that item may need to be redone in some cases.
Keymap Editor
The most noticeable change here is that there is no longer an "Edit" button for
keymaps, all are editable immediately, but a "Restore" buttons shows for keymaps
and items that have been edited. Shortcuts for addons can also be edited in the
keymap editor.
Addons
Addons now should only modify the new addon keyconfiguration, the keymap items
there will be added to the builtin ones for handling events, and not get lost
when starting new files. Example code of register/unregister:
km = wm.keyconfigs.addon.keymaps.new("3D View", space_type="VIEW_3D")
km.keymap_items.new('my.operator', 'ESC', 'PRESS')
km = wm.keyconfigs.addon.keymaps["3D View"]
km.keymap_items.remove(km.keymap_items["my.operator"])
Compatibility
The changes made are not forward compatible, i.e. if you save user preferences
with newer versions, older versions will not have key configuration changes that
were made.
2011-08-05 20:45:26 +00:00
|
|
|
}
|
2007-12-24 18:53:37 +00:00
|
|
|
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
UserDef *user;
|
|
|
|
|
wmKeyMap *keymap;
|
|
|
|
|
wmKeyMapItem *kmi;
|
|
|
|
|
wmKeyMapDiffItem *kmdi;
|
|
|
|
|
bAddon *addon;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bfd->user = user = read_struct(fd, bhead, "user def");
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* User struct has separate do-version handling */
|
|
|
|
|
user->versionfile = bfd->main->versionfile;
|
|
|
|
|
user->subversionfile = bfd->main->subversionfile;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* read all data into fd->datamap */
|
|
|
|
|
bhead = read_data_into_oldnewmap(fd, bhead, "user def");
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &user->themes);
|
|
|
|
|
link_list(fd, &user->user_keymaps);
|
|
|
|
|
link_list(fd, &user->user_keyconfig_prefs);
|
|
|
|
|
link_list(fd, &user->user_menus);
|
|
|
|
|
link_list(fd, &user->addons);
|
|
|
|
|
link_list(fd, &user->autoexec_paths);
|
2015-04-06 10:40:12 -03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (keymap = user->user_keymaps.first; keymap; keymap = keymap->next) {
|
|
|
|
|
keymap->modal_items = NULL;
|
|
|
|
|
keymap->poll = NULL;
|
|
|
|
|
keymap->flag &= ~KEYMAP_UPDATE;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &keymap->diff_items);
|
|
|
|
|
link_list(fd, &keymap->items);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) {
|
|
|
|
|
kmdi->remove_item = newdataadr(fd, kmdi->remove_item);
|
|
|
|
|
kmdi->add_item = newdataadr(fd, kmdi->add_item);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (kmdi->remove_item) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_keymapitem(fd, kmdi->remove_item);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (kmdi->add_item) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_keymapitem(fd, kmdi->add_item);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
direct_link_keymapitem(fd, kmi);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2013-03-26 09:59:43 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (wmKeyConfigPref *kpt = user->user_keyconfig_prefs.first; kpt; kpt = kpt->next) {
|
|
|
|
|
kpt->prop = newdataadr(fd, kpt->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&kpt->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
}
|
2018-11-16 11:24:49 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bUserMenu *um = user->user_menus.first; um; um = um->next) {
|
|
|
|
|
link_list(fd, &um->items);
|
|
|
|
|
for (bUserMenuItem *umi = um->items.first; umi; umi = umi->next) {
|
|
|
|
|
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
|
|
|
|
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
|
|
|
|
umi_op->prop = newdataadr(fd, umi_op->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&umi_op->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-24 16:07:34 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (addon = user->addons.first; addon; addon = addon->next) {
|
|
|
|
|
addon->prop = newdataadr(fd, addon->prop);
|
|
|
|
|
IDP_DirectLinkGroup_OrFree(&addon->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
|
|
|
|
}
|
2012-12-29 10:24:42 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
// XXX
|
|
|
|
|
user->uifonts.first = user->uifonts.last = NULL;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
link_list(fd, &user->uistyles);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Don't read the active app template, use the default one. */
|
|
|
|
|
user->app_template[0] = '\0';
|
2018-08-28 15:12:14 +02:00
|
|
|
|
2019-05-13 10:52:14 +02:00
|
|
|
/* Clear runtime data. */
|
|
|
|
|
user->runtime.is_dirty = false;
|
2019-05-31 18:09:38 +02:00
|
|
|
user->edit_studio_light = 0;
|
2019-05-13 10:52:14 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* free fd->datamap again */
|
|
|
|
|
oldnewmap_free_unused(fd->datamap);
|
|
|
|
|
oldnewmap_clear(fd->datamap);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return bhead;
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Read File (Internal)
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2011-05-18 06:27:32 +00:00
|
|
|
BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead = blo_bhead_first(fd);
|
|
|
|
|
BlendFileData *bfd;
|
|
|
|
|
ListBase mainlist = {NULL, NULL};
|
|
|
|
|
|
|
|
|
|
bfd = MEM_callocN(sizeof(BlendFileData), "blendfiledata");
|
|
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
bfd->main = BKE_main_new();
|
2019-04-17 06:17:24 +02:00
|
|
|
bfd->main->versionfile = fd->fileversion;
|
|
|
|
|
|
|
|
|
|
bfd->type = BLENFILETYPE_BLEND;
|
2019-05-13 12:36:14 +10:00
|
|
|
|
|
|
|
|
if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
|
|
|
|
|
BLI_addtail(&mainlist, bfd->main);
|
|
|
|
|
fd->mainlist = &mainlist;
|
|
|
|
|
BLI_strncpy(bfd->main->name, filepath, sizeof(bfd->main->name));
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (G.background) {
|
|
|
|
|
/* We only read & store .blend thumbnail in background mode
|
|
|
|
|
* (because we cannot re-generate it, no OpenGL available).
|
|
|
|
|
*/
|
|
|
|
|
const int *data = read_file_thumbnail(fd);
|
|
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
|
const int width = data[0];
|
|
|
|
|
const int height = data[1];
|
|
|
|
|
if (BLEN_THUMB_MEMSIZE_IS_VALID(width, height)) {
|
|
|
|
|
const size_t sz = BLEN_THUMB_MEMSIZE(width, height);
|
|
|
|
|
bfd->main->blen_thumb = MEM_mallocN(sz, __func__);
|
|
|
|
|
|
|
|
|
|
BLI_assert((sz - sizeof(*bfd->main->blen_thumb)) ==
|
|
|
|
|
(BLEN_THUMB_MEMSIZE_FILE(width, height) - (sizeof(*data) * 2)));
|
|
|
|
|
bfd->main->blen_thumb->width = width;
|
|
|
|
|
bfd->main->blen_thumb->height = height;
|
|
|
|
|
memcpy(bfd->main->blen_thumb->rect, &data[2], sz - sizeof(*bfd->main->blen_thumb));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (bhead) {
|
|
|
|
|
switch (bhead->code) {
|
|
|
|
|
case DATA:
|
|
|
|
|
case DNA1:
|
|
|
|
|
case TEST: /* used as preview since 2.5x */
|
|
|
|
|
case REND:
|
|
|
|
|
bhead = blo_bhead_next(fd, bhead);
|
|
|
|
|
break;
|
|
|
|
|
case GLOB:
|
|
|
|
|
bhead = read_global(bfd, fd, bhead);
|
|
|
|
|
break;
|
|
|
|
|
case USER:
|
|
|
|
|
if (fd->skip_flags & BLO_READ_SKIP_USERDEF) {
|
|
|
|
|
bhead = blo_bhead_next(fd, bhead);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
bhead = read_userdef(bfd, fd, bhead);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ENDB:
|
|
|
|
|
bhead = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ID_LINK_PLACEHOLDER:
|
|
|
|
|
if (fd->skip_flags & BLO_READ_SKIP_DATA) {
|
|
|
|
|
bhead = blo_bhead_next(fd, bhead);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Add link placeholder to the main of the library it belongs to.
|
|
|
|
|
* The library is the most recently loaded ID_LI block, according
|
|
|
|
|
* to the file format definition. So we can use the entry at the
|
|
|
|
|
* end of mainlist, added in direct_link_library. */
|
|
|
|
|
Main *libmain = mainlist.last;
|
|
|
|
|
bhead = read_libblock(
|
|
|
|
|
fd, libmain, bhead, LIB_TAG_ID_LINK_PLACEHOLDER | LIB_TAG_EXTERN, NULL);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
|
|
|
|
|
case ID_SCRN:
|
|
|
|
|
bhead->code = ID_SCR;
|
|
|
|
|
/* pass on to default */
|
|
|
|
|
ATTR_FALLTHROUGH;
|
|
|
|
|
default:
|
|
|
|
|
if (fd->skip_flags & BLO_READ_SKIP_DATA) {
|
|
|
|
|
bhead = blo_bhead_next(fd, bhead);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* do before read_libraries, but skip undo case */
|
|
|
|
|
if (fd->memfile == NULL) {
|
2019-05-13 12:36:14 +10:00
|
|
|
if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
|
|
|
|
|
do_versions(fd, NULL, bfd->main);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((fd->skip_flags & BLO_READ_SKIP_USERDEF) == 0) {
|
|
|
|
|
do_versions_userdef(fd, bfd);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
|
|
|
|
|
read_libraries(fd, &mainlist);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
blo_join_main(&mainlist);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
lib_link_all(fd, bfd->main);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
/* Skip in undo case. */
|
|
|
|
|
if (fd->memfile == NULL) {
|
|
|
|
|
/* Yep, second splitting... but this is a very cheap operation, so no big deal. */
|
|
|
|
|
blo_split_main(&mainlist, bfd->main);
|
|
|
|
|
for (Main *mainvar = mainlist.first; mainvar; mainvar = mainvar->next) {
|
|
|
|
|
BLI_assert(mainvar->versionfile != 0);
|
|
|
|
|
do_versions_after_linking(mainvar);
|
|
|
|
|
}
|
|
|
|
|
blo_join_main(&mainlist);
|
2019-04-20 20:25:22 +02:00
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
/* After all data has been read and versioned, uses LIB_TAG_NEW. */
|
|
|
|
|
ntreeUpdateAllNew(bfd->main);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-12 11:54:37 +02:00
|
|
|
placeholders_ensure_valid(bfd->main);
|
|
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
/* Now that all our data-blocks are loaded,
|
|
|
|
|
* we can re-generate overrides from their references. */
|
|
|
|
|
if (fd->memfile == NULL) {
|
|
|
|
|
/* Do not apply in undo case! */
|
2019-06-14 23:16:04 +02:00
|
|
|
BKE_main_override_library_update(bfd->main);
|
2019-05-13 12:36:14 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
BKE_collections_after_lib_link(bfd->main);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
/* Make all relative paths, relative to the open blend file. */
|
|
|
|
|
fix_relpaths_library(fd->relabase, bfd->main);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 12:36:14 +10:00
|
|
|
link_global(fd, bfd); /* as last */
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
fd->mainlist = NULL; /* Safety, this is local variable, shall not be used afterward. */
|
|
|
|
|
|
|
|
|
|
return bfd;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Library Linking
|
|
|
|
|
*
|
|
|
|
|
* Also used for append.
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2012-08-04 19:34:38 +00:00
|
|
|
struct BHeadSort {
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead;
|
|
|
|
|
const void *old;
|
2008-01-30 18:18:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int verg_bheadsort(const void *v1, const void *v2)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const struct BHeadSort *x1 = v1, *x2 = v2;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (x1->old > x2->old) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return 1;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else if (x1->old < x2->old) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return -1;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
return 0;
|
2008-01-30 18:18:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void sort_bhead_old_map(FileData *fd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead;
|
|
|
|
|
struct BHeadSort *bhs;
|
|
|
|
|
int tot = 0;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
tot++;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
fd->tot_bheadmap = tot;
|
2019-04-22 09:13:00 +10:00
|
|
|
if (tot == 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bhs = fd->bheadmap = MEM_malloc_arrayN(tot, sizeof(struct BHeadSort), "BHeadSort");
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead), bhs++) {
|
|
|
|
|
bhs->bhead = bhead;
|
|
|
|
|
bhs->old = bhead->old;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
qsort(fd->bheadmap, tot, sizeof(struct BHeadSort), verg_bheadsort);
|
2008-01-30 18:18:33 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static BHead *find_previous_lib(FileData *fd, BHead *bhead)
|
|
|
|
|
{
|
2019-06-12 09:04:10 +10:00
|
|
|
/* Skip library data-blocks in undo, see comment in read_libblock. */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->memfile) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2009-10-20 16:43:25 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (; bhead; bhead = blo_bhead_prev(fd, bhead)) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (bhead->code == ID_LI) {
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return bhead;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static BHead *find_bhead(FileData *fd, void *old)
|
|
|
|
|
{
|
2008-02-03 18:50:03 +00:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead;
|
2008-02-03 18:50:03 +00:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
struct BHeadSort *bhs, bhs_s;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!old) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->bheadmap == NULL) {
|
2019-04-17 06:17:24 +02:00
|
|
|
sort_bhead_old_map(fd);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
bhs_s.old = old;
|
|
|
|
|
bhs = bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct BHeadSort), verg_bheadsort);
|
2008-01-30 18:18:33 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (bhs) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return bhs->bhead;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2008-02-03 18:50:03 +00:00
|
|
|
#if 0
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
2019-05-31 23:21:16 +10:00
|
|
|
if (bhead->old == old) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return bhead;
|
2019-05-31 23:21:16 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2008-02-03 18:50:03 +00:00
|
|
|
#endif
|
2004-06-23 18:22:51 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-11 00:05:14 +11:00
|
|
|
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name)
|
|
|
|
|
{
|
2015-03-11 00:33:44 +11:00
|
|
|
#ifdef USE_GHASH_BHEAD
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
char idname_full[MAX_ID_NAME];
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
*((short *)idname_full) = idcode;
|
|
|
|
|
BLI_strncpy(idname_full + 2, name, sizeof(idname_full) - 2);
|
2015-03-11 00:33:44 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return BLI_ghash_lookup(fd->bhead_idname_hash, idname_full);
|
2015-03-11 00:33:44 +11:00
|
|
|
|
|
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bhead;
|
|
|
|
|
|
|
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
|
|
|
|
if (bhead->code == idcode) {
|
|
|
|
|
const char *idname_test = blo_bhead_id_name(fd, bhead);
|
|
|
|
|
if (STREQ(idname_test + 2, name)) {
|
|
|
|
|
return bhead;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (bhead->code == ENDB) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
2015-03-11 00:33:44 +11:00
|
|
|
#endif
|
2015-03-11 00:05:14 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static BHead *find_bhead_from_idname(FileData *fd, const char *idname)
|
|
|
|
|
{
|
2015-03-11 00:33:44 +11:00
|
|
|
#ifdef USE_GHASH_BHEAD
|
2019-04-17 06:17:24 +02:00
|
|
|
return BLI_ghash_lookup(fd->bhead_idname_hash, idname);
|
2015-03-11 00:33:44 +11:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
return find_bhead_from_code_name(fd, GS(idname), idname + 2);
|
2015-03-11 00:33:44 +11:00
|
|
|
#endif
|
2015-03-11 00:05:14 +11:00
|
|
|
}
|
|
|
|
|
|
2007-04-28 16:15:00 +00:00
|
|
|
static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const char *idname = blo_bhead_id_name(fd, bhead);
|
|
|
|
|
/* which_libbase can be NULL, intentionally not using idname+2 */
|
|
|
|
|
return BLI_findstring(which_libbase(mainvar, GS(idname)), idname, offsetof(ID, name));
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Library Linking (expand pointers)
|
|
|
|
|
* \{ */
|
|
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = fdhandle;
|
|
|
|
|
|
|
|
|
|
BHead *bhead = find_bhead(fd, old);
|
|
|
|
|
if (bhead == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bhead->code == ID_LINK_PLACEHOLDER) {
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Placeholder link to data-lock in another library. */
|
2019-04-17 06:17:24 +02:00
|
|
|
BHead *bheadlib = find_previous_lib(fd, bhead);
|
|
|
|
|
if (bheadlib == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Library *lib = read_struct(fd, bheadlib, "Library");
|
|
|
|
|
Main *libmain = blo_find_main(fd, lib->name, fd->relabase);
|
|
|
|
|
|
|
|
|
|
if (libmain->curlib == NULL) {
|
|
|
|
|
const char *idname = blo_bhead_id_name(fd, bhead);
|
|
|
|
|
|
|
|
|
|
blo_reportf_wrap(fd->reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
TIP_("LIB: Data refers to main .blend file: '%s' from %s"),
|
|
|
|
|
idname,
|
|
|
|
|
mainvar->curlib->filepath);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID *id = is_yet_read(fd, libmain, bhead);
|
|
|
|
|
|
|
|
|
|
if (id == NULL) {
|
|
|
|
|
/* ID has not been read yet, add placeholder to the main of the
|
|
|
|
|
* library it belongs to, so that it will be read later. */
|
|
|
|
|
read_libblock(fd, libmain, bhead, LIB_TAG_ID_LINK_PLACEHOLDER | LIB_TAG_INDIRECT, NULL);
|
|
|
|
|
// commented because this can print way too much
|
|
|
|
|
// if (G.debug & G_DEBUG) printf("expand_doit: other lib %s\n", lib->name);
|
|
|
|
|
|
|
|
|
|
/* for outliner dependency only */
|
|
|
|
|
libmain->curlib->parent = mainvar->curlib;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* "id" is either a placeholder or real ID that is already in the
|
|
|
|
|
* main of the library (A) it belongs to. However it might have been
|
|
|
|
|
* put there by another library (C) which only updated its own
|
|
|
|
|
* fd->libmap. In that case we also need to update the fd->libmap
|
|
|
|
|
* of the current library (B) so we can find it for lookups.
|
|
|
|
|
*
|
|
|
|
|
* An example of such a setup is:
|
|
|
|
|
* (A) tree.blend: contains Tree object.
|
|
|
|
|
* (B) forest.blend: contains Forest collection linking in Tree from tree.blend.
|
|
|
|
|
* (C) shot.blend: links in both Tree from tree.blend and Forest from forest.blend.
|
|
|
|
|
*/
|
|
|
|
|
oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
|
|
|
|
|
|
2019-06-17 12:51:53 +10:00
|
|
|
/* If "id" is a real data-lock and not a placeholder, we need to
|
2019-04-17 06:17:24 +02:00
|
|
|
* update fd->libmap to replace ID_LINK_PLACEHOLDER with the real
|
|
|
|
|
* ID_* code.
|
|
|
|
|
*
|
|
|
|
|
* When the real ID is read this replacement happens for all
|
|
|
|
|
* libraries read so far, but not for libraries that have not been
|
|
|
|
|
* read yet at that point. */
|
|
|
|
|
change_link_placeholder_to_real_ID_pointer_fd(fd, bhead->old, id);
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Commented because this can print way too much. */
|
|
|
|
|
#if 0
|
|
|
|
|
if (G.debug & G_DEBUG) {
|
|
|
|
|
printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(lib);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Data-block in same library. */
|
2019-04-17 06:17:24 +02:00
|
|
|
/* In 2.50+ file identifier for screens is patched, forward compatibility. */
|
|
|
|
|
if (bhead->code == ID_SCRN) {
|
|
|
|
|
bhead->code = ID_SCR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID *id = is_yet_read(fd, mainvar, bhead);
|
|
|
|
|
if (id == NULL) {
|
|
|
|
|
read_libblock(fd, mainvar, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, NULL);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-04-22 01:10:29 +10:00
|
|
|
/* this is actually only needed on UI call? when ID was already read before,
|
|
|
|
|
* and another append happens which invokes same ID...
|
|
|
|
|
* in that case the lookup table needs this entry */
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
|
|
|
|
|
// commented because this can print way too much
|
|
|
|
|
// if (G.debug & G_DEBUG) printf("expand: already read %s\n", id->name);
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:31:47 +02:00
|
|
|
static BLOExpandDoitCallback expand_doit;
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2012-09-26 20:05:38 +00:00
|
|
|
// XXX deprecated - old animation system
|
2006-06-08 19:26:08 +00:00
|
|
|
static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
IpoCurve *icu;
|
|
|
|
|
for (icu = ipo->curve.first; icu; icu = icu->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (icu->driver) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, icu->driver->ob);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2006-06-08 19:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-26 20:05:38 +00:00
|
|
|
// XXX deprecated - old animation system
|
2009-01-19 02:26:46 +00:00
|
|
|
static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *chanbase)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bConstraintChannel *chan;
|
|
|
|
|
for (chan = chanbase->first; chan; chan = chan->next) {
|
|
|
|
|
expand_doit(fd, mainvar, chan->ipo);
|
|
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2018-05-24 14:55:05 +02:00
|
|
|
static void expand_id(FileData *fd, Main *mainvar, ID *id)
|
|
|
|
|
{
|
2019-06-14 23:16:04 +02:00
|
|
|
if (id->override_library) {
|
|
|
|
|
expand_doit(fd, mainvar, id->override_library->reference);
|
|
|
|
|
expand_doit(fd, mainvar, id->override_library->storage);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-05-24 14:55:05 +02:00
|
|
|
}
|
|
|
|
|
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
static void expand_idprops(FileData *fd, Main *mainvar, IDProperty *prop)
|
|
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!prop) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
switch (prop->type) {
|
|
|
|
|
case IDP_ID:
|
|
|
|
|
expand_doit(fd, mainvar, IDP_Id(prop));
|
|
|
|
|
break;
|
|
|
|
|
case IDP_IDPARRAY: {
|
|
|
|
|
IDProperty *idp_array = IDP_IDPArray(prop);
|
|
|
|
|
for (int i = 0; i < prop->len; i++) {
|
|
|
|
|
expand_idprops(fd, mainvar, &idp_array[i]);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case IDP_GROUP:
|
|
|
|
|
for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) {
|
|
|
|
|
expand_idprops(fd, mainvar, loop);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
}
|
|
|
|
|
|
2009-11-22 11:15:38 +00:00
|
|
|
static void expand_fmodifiers(FileData *fd, Main *mainvar, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FModifier *fcm;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (fcm = list->first; fcm; fcm = fcm->next) {
|
|
|
|
|
/* library data for specific F-Modifier types */
|
|
|
|
|
switch (fcm->type) {
|
|
|
|
|
case FMODIFIER_TYPE_PYTHON: {
|
|
|
|
|
FMod_Python *data = (FMod_Python *)fcm->data;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, data->script);
|
2015-07-18 19:02:39 +10:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-11-22 11:15:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_fcurves(FileData *fd, Main *mainvar, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FCurve *fcu;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (fcu = list->first; fcu; fcu = fcu->next) {
|
|
|
|
|
/* Driver targets if there is a driver */
|
|
|
|
|
if (fcu->driver) {
|
|
|
|
|
ChannelDriver *driver = fcu->driver;
|
|
|
|
|
DriverVar *dvar;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
|
|
|
|
|
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
|
|
|
|
|
// TODO: only expand those that are going to get used?
|
|
|
|
|
expand_doit(fd, mainvar, dtar->id);
|
|
|
|
|
}
|
|
|
|
|
DRIVER_TARGETS_LOOPER_END;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* F-Curve Modifiers */
|
|
|
|
|
expand_fmodifiers(fd, mainvar, &fcu->modifiers);
|
|
|
|
|
}
|
2009-11-22 11:15:38 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-19 02:26:46 +00:00
|
|
|
static void expand_action(FileData *fd, Main *mainvar, bAction *act)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bActionChannel *chan;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
// XXX deprecated - old animation system --------------
|
|
|
|
|
for (chan = act->chanbase.first; chan; chan = chan->next) {
|
|
|
|
|
expand_doit(fd, mainvar, chan->ipo);
|
|
|
|
|
expand_constraint_channels(fd, mainvar, &chan->constraintChannels);
|
|
|
|
|
}
|
|
|
|
|
// ---------------------------------------------------
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* F-Curves in Action */
|
|
|
|
|
expand_fcurves(fd, mainvar, &act->curves);
|
2016-09-30 10:11:29 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) {
|
|
|
|
|
if (marker->camera) {
|
|
|
|
|
expand_doit(fd, mainvar, marker->camera);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-11 12:19:42 +00:00
|
|
|
static void expand_keyingsets(FileData *fd, Main *mainvar, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
KeyingSet *ks;
|
|
|
|
|
KS_Path *ksp;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* expand the ID-pointers in KeyingSets's paths */
|
|
|
|
|
for (ks = list->first; ks; ks = ks->next) {
|
|
|
|
|
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
|
|
|
|
|
expand_doit(fd, mainvar, ksp->id);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-11 12:19:42 +00:00
|
|
|
}
|
|
|
|
|
|
2009-07-06 03:44:44 +00:00
|
|
|
static void expand_animdata_nlastrips(FileData *fd, Main *mainvar, ListBase *list)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
NlaStrip *strip;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (strip = list->first; strip; strip = strip->next) {
|
|
|
|
|
/* check child strips */
|
|
|
|
|
expand_animdata_nlastrips(fd, mainvar, &strip->strips);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* check F-Curves */
|
|
|
|
|
expand_fcurves(fd, mainvar, &strip->fcurves);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* check F-Modifiers */
|
|
|
|
|
expand_fmodifiers(fd, mainvar, &strip->modifiers);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink referenced action */
|
|
|
|
|
expand_doit(fd, mainvar, strip->act);
|
|
|
|
|
}
|
2009-07-06 03:44:44 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-19 02:26:46 +00:00
|
|
|
static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
NlaTrack *nlt;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* own action */
|
|
|
|
|
expand_doit(fd, mainvar, adt->action);
|
|
|
|
|
expand_doit(fd, mainvar, adt->tmpact);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* drivers - assume that these F-Curves have driver data to be in this list... */
|
|
|
|
|
expand_fcurves(fd, mainvar, &adt->drivers);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* nla-data - referenced actions */
|
2019-04-22 09:13:00 +10:00
|
|
|
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata_nlastrips(fd, mainvar, &nlt->strips);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
}
|
2009-01-19 02:26:46 +00:00
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int a;
|
|
|
|
|
|
|
|
|
|
expand_doit(fd, mainvar, part->instance_object);
|
|
|
|
|
expand_doit(fd, mainvar, part->instance_collection);
|
|
|
|
|
expand_doit(fd, mainvar, part->eff_group);
|
|
|
|
|
expand_doit(fd, mainvar, part->bb_ob);
|
|
|
|
|
expand_doit(fd, mainvar, part->collision_group);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (part->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, part->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
for (a = 0; a < MAX_MTEX; a++) {
|
|
|
|
|
if (part->mtex[a]) {
|
|
|
|
|
expand_doit(fd, mainvar, part->mtex[a]->tex);
|
|
|
|
|
expand_doit(fd, mainvar, part->mtex[a]->object);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (part->effector_weights) {
|
|
|
|
|
expand_doit(fd, mainvar, part->effector_weights->group);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (part->pd) {
|
|
|
|
|
expand_doit(fd, mainvar, part->pd->tex);
|
|
|
|
|
expand_doit(fd, mainvar, part->pd->f_source);
|
|
|
|
|
}
|
|
|
|
|
if (part->pd2) {
|
|
|
|
|
expand_doit(fd, mainvar, part->pd2->tex);
|
|
|
|
|
expand_doit(fd, mainvar, part->pd2->f_source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (part->boids) {
|
|
|
|
|
BoidState *state;
|
|
|
|
|
BoidRule *rule;
|
|
|
|
|
|
|
|
|
|
for (state = part->boids->states.first; state; state = state->next) {
|
|
|
|
|
for (rule = state->rules.first; rule; rule = rule->next) {
|
|
|
|
|
if (rule->type == eBoidRuleType_Avoid) {
|
|
|
|
|
BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
|
|
|
|
|
expand_doit(fd, mainvar, gabr->ob);
|
|
|
|
|
}
|
|
|
|
|
else if (rule->type == eBoidRuleType_FollowLeader) {
|
|
|
|
|
BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
|
|
|
|
|
expand_doit(fd, mainvar, flbr->ob);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ParticleDupliWeight *dw = part->instance_weights.first; dw; dw = dw->next) {
|
|
|
|
|
expand_doit(fd, mainvar, dw->ob);
|
|
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
}
|
|
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
static void expand_collection(FileData *fd, Main *mainvar, Collection *collection)
|
Orange branch: Revived hidden treasure, the Groups!
Previous experiment (in 2000) didn't satisfy, it had even some primitive
NLA option in groups... so, cleaned up the old code (removed most) and
integrated it back in a more useful way.
Usage:
- CTRL+G gives menu to add group, add to existing group, or remove from
groups.
- In Object buttons, a new (should become first) Panel was added, showing
not only Object "ID button" and Parent, but also the Groups the Object
Belongs to. These buttons also allow rename, assigning or removing.
- To indicate Objects are grouped, they're drawn in a (not theme yet, so
temporal?) green wire color.
- Use ALT+SHIFT mouse-select to (de)select an entire group
But, the real power of groups is in the following features:
-> Particle Force field and Guide control
In the "Particle Motion" Panel, you can indicate a Group name, this then
limits force fields or guides to members of that Group. (Note that layers
still work on top of that... not sure about that).
-> Light Groups
In the Material "Shaders" Panel, you can indicate a Group name to limit
lighting for the Material to lamps in this group. The Lights in a Group do
need to be 'visible' for the Scene to be rendered (as usual).
-> Group Duplicator
In the Object "Anim" Panel, you can set any Object (use Empty!) to
duplicate an entire Group. It will make copies of all Objects in that Group.
Also works for animated Objects, but it will copy the current positions or
deforms. Control over 'local timing' (so we can do Massive anims!) will be
added later.
(Note; this commit won't render Group duplicators yet, a fix in bf-blender
will enable that, next commit will sync)
-> Library Appending
In the SHIFT-F1 or SHIFT+F4 browsers, you can also find the Groups listed.
By appending or linking the Group itself, and use the Group Duplicator, you
now can animate and position linked Objects. The nice thing is that the
local saved file itself will only store the Group name that was linked, so
on a next file read, the Group Objects will be re-read as stored (changed)
in the Library file.
(Note; current implementation also "gives a base" to linked Group Objects,
to show them as Objects in the current Scene. Need that now for testing
purposes, but probably will be removed later).
-> Outliner
Outliner now shows Groups as optio too, nice to organize your data a bit too!
In General, Groups have a very good potential... for example, it could
become default for MetaBall Objects too (jiri, I can help you later on how
this works). All current 'layer relationships' in Blender should be dropped
in time, I guess...
2005-12-06 10:55:30 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
|
|
|
|
|
expand_doit(fd, mainvar, cob->ob);
|
|
|
|
|
}
|
2017-12-01 11:24:21 -02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (CollectionChild *child = collection->children.first; child; child = child->next) {
|
|
|
|
|
expand_doit(fd, mainvar, child->collection);
|
|
|
|
|
}
|
2017-12-01 11:24:21 -02:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
2019-04-17 06:17:24 +02:00
|
|
|
if (collection->collection != NULL) {
|
|
|
|
|
expand_scene_collection(fd, mainvar, collection->collection);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
Orange branch: Revived hidden treasure, the Groups!
Previous experiment (in 2000) didn't satisfy, it had even some primitive
NLA option in groups... so, cleaned up the old code (removed most) and
integrated it back in a more useful way.
Usage:
- CTRL+G gives menu to add group, add to existing group, or remove from
groups.
- In Object buttons, a new (should become first) Panel was added, showing
not only Object "ID button" and Parent, but also the Groups the Object
Belongs to. These buttons also allow rename, assigning or removing.
- To indicate Objects are grouped, they're drawn in a (not theme yet, so
temporal?) green wire color.
- Use ALT+SHIFT mouse-select to (de)select an entire group
But, the real power of groups is in the following features:
-> Particle Force field and Guide control
In the "Particle Motion" Panel, you can indicate a Group name, this then
limits force fields or guides to members of that Group. (Note that layers
still work on top of that... not sure about that).
-> Light Groups
In the Material "Shaders" Panel, you can indicate a Group name to limit
lighting for the Material to lamps in this group. The Lights in a Group do
need to be 'visible' for the Scene to be rendered (as usual).
-> Group Duplicator
In the Object "Anim" Panel, you can set any Object (use Empty!) to
duplicate an entire Group. It will make copies of all Objects in that Group.
Also works for animated Objects, but it will copy the current positions or
deforms. Control over 'local timing' (so we can do Massive anims!) will be
added later.
(Note; this commit won't render Group duplicators yet, a fix in bf-blender
will enable that, next commit will sync)
-> Library Appending
In the SHIFT-F1 or SHIFT+F4 browsers, you can also find the Groups listed.
By appending or linking the Group itself, and use the Group Duplicator, you
now can animate and position linked Objects. The nice thing is that the
local saved file itself will only store the Group name that was linked, so
on a next file read, the Group Objects will be re-read as stored (changed)
in the Library file.
(Note; current implementation also "gives a base" to linked Group Objects,
to show them as Objects in the current Scene. Need that now for testing
purposes, but probably will be removed later).
-> Outliner
Outliner now shows Groups as optio too, nice to organize your data a bit too!
In General, Groups have a very good potential... for example, it could
become default for MetaBall Objects too (jiri, I can help you later on how
this works). All current 'layer relationships' in Blender should be dropped
in time, I guess...
2005-12-06 10:55:30 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void expand_key(FileData *fd, Main *mainvar, Key *key)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, key->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (key->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, key->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2008-11-12 22:03:11 +00:00
|
|
|
static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bNode *node;
|
|
|
|
|
bNodeSocket *sock;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ntree->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, ntree->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ntree->gpd) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ntree->gpd);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (node = ntree->nodes.first; node; node = node->next) {
|
|
|
|
|
if (node->id && node->type != CMP_NODE_R_LAYERS) {
|
|
|
|
|
expand_doit(fd, mainvar, node->id);
|
|
|
|
|
}
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_idprops(fd, mainvar, node->prop);
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (sock = node->inputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_idprops(fd, mainvar, sock->prop);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
for (sock = node->outputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_idprops(fd, mainvar, sock->prop);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2008-11-12 22:03:11 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (sock = ntree->inputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_idprops(fd, mainvar, sock->prop);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
for (sock = ntree->outputs.first; sock; sock = sock->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_idprops(fd, mainvar, sock->prop);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2008-11-12 22:03:11 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, tex->ima);
|
|
|
|
|
expand_doit(fd, mainvar, tex->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (tex->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, tex->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (tex->nodetree) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_nodetree(fd, mainvar, tex->nodetree);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, brush->mtex.tex);
|
|
|
|
|
expand_doit(fd, mainvar, brush->mask_mtex.tex);
|
|
|
|
|
expand_doit(fd, mainvar, brush->clone.image);
|
|
|
|
|
expand_doit(fd, mainvar, brush->paint_curve);
|
|
|
|
|
if (brush->gpencil_settings != NULL) {
|
|
|
|
|
expand_doit(fd, mainvar, brush->gpencil_settings->material);
|
|
|
|
|
}
|
Brush Datablock:
- Added a new Brush datablock, only used by image paint, but intended
to be used in texture paint, vertex paint, weight paint and sculpt
mode also.
- Being a datablock, these brushes can be saved, appended and linked.
They have a fake user by default, to make sure they are saved even if
not selected.
Image Painting:
- Replaced the img module with C code in imagepaint.c
- Airbrush is no longer a separate tool, but rather an option that can
be used for soften, smear and clone also.
- Blend modes mix, add, subtract, multiply, darken and lighten have been
added, code taken directly from vertex paint.
Note to project files maintainers:
- The img module was removed from SCons and Makefiles, and this should
be done in other build systems also. I'll wait to remove the module
from cvs, to not break compilation.
2006-07-26 22:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void expand_material(FileData *fd, Main *mainvar, Material *ma)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ma->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ma->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, ma->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ma->nodetree) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_nodetree(fd, mainvar, ma->nodetree);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ma->gp_style) {
|
|
|
|
|
MaterialGPencilStyle *gp_style = ma->gp_style;
|
|
|
|
|
expand_doit(fd, mainvar, gp_style->sima);
|
|
|
|
|
expand_doit(fd, mainvar, gp_style->ima);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-27 12:02:02 +11:00
|
|
|
static void expand_light(FileData *fd, Main *mainvar, Light *la)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, la->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (la->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, la->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (la->nodetree) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_nodetree(fd, mainvar, la->nodetree);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, lt->ipo); // XXX deprecated - old animation system
|
|
|
|
|
expand_doit(fd, mainvar, lt->key);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (lt->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, lt->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_world(FileData *fd, Main *mainvar, World *wrld)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, wrld->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (wrld->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, wrld->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (wrld->nodetree) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_nodetree(fd, mainvar, wrld->nodetree);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_mball(FileData *fd, Main *mainvar, MetaBall *mb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int a;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (a = 0; a < mb->totcol; a++) {
|
|
|
|
|
expand_doit(fd, mainvar, mb->mat[a]);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mb->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, mb->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int a;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (a = 0; a < cu->totcol; a++) {
|
|
|
|
|
expand_doit(fd, mainvar, cu->mat[a]);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, cu->vfont);
|
|
|
|
|
expand_doit(fd, mainvar, cu->vfontb);
|
|
|
|
|
expand_doit(fd, mainvar, cu->vfonti);
|
|
|
|
|
expand_doit(fd, mainvar, cu->vfontbi);
|
|
|
|
|
expand_doit(fd, mainvar, cu->key);
|
|
|
|
|
expand_doit(fd, mainvar, cu->ipo); // XXX deprecated - old animation system
|
|
|
|
|
expand_doit(fd, mainvar, cu->bevobj);
|
|
|
|
|
expand_doit(fd, mainvar, cu->taperobj);
|
|
|
|
|
expand_doit(fd, mainvar, cu->textoncurve);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (cu->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, cu->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int a;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (me->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, me->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (a = 0; a < me->totcol; a++) {
|
|
|
|
|
expand_doit(fd, mainvar, me->mat[a]);
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, me->key);
|
|
|
|
|
expand_doit(fd, mainvar, me->texcomesh);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2010-02-06 11:50:39 +00:00
|
|
|
/* temp struct used to transport needed info to expand_constraint_cb() */
|
|
|
|
|
typedef struct tConstraintExpandData {
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd;
|
|
|
|
|
Main *mainvar;
|
2010-02-06 11:50:39 +00:00
|
|
|
} tConstraintExpandData;
|
|
|
|
|
/* callback function used to expand constraint ID-links */
|
2019-04-17 06:17:24 +02:00
|
|
|
static void expand_constraint_cb(bConstraint *UNUSED(con),
|
|
|
|
|
ID **idpoin,
|
|
|
|
|
bool UNUSED(is_reference),
|
|
|
|
|
void *userdata)
|
2010-02-06 11:50:39 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
tConstraintExpandData *ced = (tConstraintExpandData *)userdata;
|
|
|
|
|
expand_doit(ced->fd, ced->mainvar, *idpoin);
|
2010-02-06 11:50:39 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
tConstraintExpandData ced;
|
|
|
|
|
bConstraint *curcon;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* relink all ID-blocks used by the constraints */
|
|
|
|
|
ced.fd = fd;
|
|
|
|
|
ced.mainvar = mainvar;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_constraints_id_loop(lb, expand_constraint_cb, &ced);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* deprecated manual expansion stuff */
|
|
|
|
|
for (curcon = lb->first; curcon; curcon = curcon->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (curcon->ipo) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, curcon->ipo); // XXX deprecated - old animation system
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_pose(FileData *fd, Main *mainvar, bPose *pose)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
bPoseChannel *chan;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (!pose) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (chan = pose->chanbase.first; chan; chan = chan->next) {
|
|
|
|
|
expand_constraints(fd, mainvar, &chan->constraints);
|
|
|
|
|
expand_idprops(fd, mainvar, chan->prop);
|
|
|
|
|
expand_doit(fd, mainvar, chan->custom);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
static void expand_bones(FileData *fd, Main *mainvar, Bone *bone)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_idprops(fd, mainvar, bone->prop);
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Bone *curBone = bone->childbase.first; curBone; curBone = curBone->next) {
|
|
|
|
|
expand_bones(fd, mainvar, curBone);
|
|
|
|
|
}
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (arm->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, arm->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
2017-04-13 12:30:03 +03:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Bone *curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
|
|
|
|
|
expand_bones(fd, mainvar, curBone);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void expand_object_expandModifiers(void *userData,
|
|
|
|
|
Object *UNUSED(ob),
|
|
|
|
|
ID **idpoin,
|
|
|
|
|
int UNUSED(cb_flag))
|
2005-07-20 18:04:50 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
struct {
|
|
|
|
|
FileData *fd;
|
|
|
|
|
Main *mainvar;
|
|
|
|
|
} *data = userData;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = data->fd;
|
|
|
|
|
Main *mainvar = data->mainvar;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, *idpoin);
|
2005-07-20 18:04:50 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void expand_object(FileData *fd, Main *mainvar, Object *ob)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ParticleSystem *psys;
|
|
|
|
|
bActionStrip *strip;
|
|
|
|
|
PartEff *paf;
|
|
|
|
|
int a;
|
|
|
|
|
|
|
|
|
|
expand_doit(fd, mainvar, ob->data);
|
|
|
|
|
|
|
|
|
|
/* expand_object_expandModifier() */
|
|
|
|
|
if (ob->modifiers.first) {
|
|
|
|
|
struct {
|
|
|
|
|
FileData *fd;
|
|
|
|
|
Main *mainvar;
|
|
|
|
|
} data;
|
|
|
|
|
data.fd = fd;
|
|
|
|
|
data.mainvar = mainvar;
|
|
|
|
|
|
|
|
|
|
modifiers_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* expand_object_expandModifier() */
|
|
|
|
|
if (ob->greasepencil_modifiers.first) {
|
|
|
|
|
struct {
|
|
|
|
|
FileData *fd;
|
|
|
|
|
Main *mainvar;
|
|
|
|
|
} data;
|
|
|
|
|
data.fd = fd;
|
|
|
|
|
data.mainvar = mainvar;
|
|
|
|
|
|
|
|
|
|
BKE_gpencil_modifiers_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* expand_object_expandShaderFx() */
|
|
|
|
|
if (ob->shader_fx.first) {
|
|
|
|
|
struct {
|
|
|
|
|
FileData *fd;
|
|
|
|
|
Main *mainvar;
|
|
|
|
|
} data;
|
|
|
|
|
data.fd = fd;
|
|
|
|
|
data.mainvar = mainvar;
|
|
|
|
|
|
|
|
|
|
BKE_shaderfx_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expand_pose(fd, mainvar, ob->pose);
|
|
|
|
|
expand_doit(fd, mainvar, ob->poselib);
|
|
|
|
|
expand_constraints(fd, mainvar, &ob->constraints);
|
|
|
|
|
|
|
|
|
|
expand_doit(fd, mainvar, ob->gpd);
|
|
|
|
|
|
|
|
|
|
// XXX deprecated - old animation system (for version patching only)
|
|
|
|
|
expand_doit(fd, mainvar, ob->ipo);
|
|
|
|
|
expand_doit(fd, mainvar, ob->action);
|
|
|
|
|
|
|
|
|
|
expand_constraint_channels(fd, mainvar, &ob->constraintChannels);
|
|
|
|
|
|
|
|
|
|
for (strip = ob->nlastrips.first; strip; strip = strip->next) {
|
|
|
|
|
expand_doit(fd, mainvar, strip->object);
|
|
|
|
|
expand_doit(fd, mainvar, strip->act);
|
|
|
|
|
expand_doit(fd, mainvar, strip->ipo);
|
|
|
|
|
}
|
|
|
|
|
// XXX deprecated - old animation system (for version patching only)
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ob->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, ob->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
for (a = 0; a < ob->totcol; a++) {
|
|
|
|
|
expand_doit(fd, mainvar, ob->mat[a]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
paf = blo_do_version_give_parteff_245(ob);
|
2019-04-22 09:13:00 +10:00
|
|
|
if (paf && paf->group) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, paf->group);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ob->instance_collection) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ob->instance_collection);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ob->proxy) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ob->proxy);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (ob->proxy_group) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ob->proxy_group);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, psys->part);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (ob->pd) {
|
|
|
|
|
expand_doit(fd, mainvar, ob->pd->tex);
|
|
|
|
|
expand_doit(fd, mainvar, ob->pd->f_source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ob->soft) {
|
|
|
|
|
expand_doit(fd, mainvar, ob->soft->collision_group);
|
|
|
|
|
|
|
|
|
|
if (ob->soft->effector_weights) {
|
|
|
|
|
expand_doit(fd, mainvar, ob->soft->effector_weights->group);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ob->rigidbody_constraint) {
|
|
|
|
|
expand_doit(fd, mainvar, ob->rigidbody_constraint->ob1);
|
|
|
|
|
expand_doit(fd, mainvar, ob->rigidbody_constraint->ob2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ob->currentlod) {
|
|
|
|
|
LodLevel *level;
|
|
|
|
|
for (level = ob->lodlevels.first; level; level = level->next) {
|
|
|
|
|
expand_doit(fd, mainvar, level->source);
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (LinkData *link = sc->objects.first; link; link = link->next) {
|
|
|
|
|
expand_doit(fd, mainvar, link->data);
|
|
|
|
|
}
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
|
|
|
|
|
expand_scene_collection(fd, mainvar, nsc);
|
|
|
|
|
}
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SceneRenderLayer *srl;
|
|
|
|
|
FreestyleModuleConfig *module;
|
|
|
|
|
FreestyleLineSet *lineset;
|
|
|
|
|
|
|
|
|
|
for (Base *base_legacy = sce->base.first; base_legacy; base_legacy = base_legacy->next) {
|
|
|
|
|
expand_doit(fd, mainvar, base_legacy->object);
|
|
|
|
|
}
|
|
|
|
|
expand_doit(fd, mainvar, sce->camera);
|
|
|
|
|
expand_doit(fd, mainvar, sce->world);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, sce->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_keyingsets(fd, mainvar, &sce->keyingsets);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->set) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, sce->set);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->nodetree) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_nodetree(fd, mainvar, sce->nodetree);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
for (srl = sce->r.layers.first; srl; srl = srl->next) {
|
|
|
|
|
expand_doit(fd, mainvar, srl->mat_override);
|
|
|
|
|
for (module = srl->freestyleConfig.modules.first; module; module = module->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (module->script) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, module->script);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (lineset->group) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, lineset->group);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, lineset->linestyle);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
|
|
|
|
|
expand_idprops(fd, mainvar, view_layer->id_properties);
|
|
|
|
|
|
|
|
|
|
for (module = view_layer->freestyle_config.modules.first; module; module = module->next) {
|
|
|
|
|
if (module->script) {
|
|
|
|
|
expand_doit(fd, mainvar, module->script);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
|
|
|
|
|
if (lineset->group) {
|
|
|
|
|
expand_doit(fd, mainvar, lineset->group);
|
|
|
|
|
}
|
|
|
|
|
expand_doit(fd, mainvar, lineset->linestyle);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (sce->gpd) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, sce->gpd);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (sce->ed) {
|
|
|
|
|
Sequence *seq;
|
|
|
|
|
|
|
|
|
|
SEQ_BEGIN (sce->ed, seq) {
|
|
|
|
|
expand_idprops(fd, mainvar, seq->prop);
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (seq->scene) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, seq->scene);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (seq->scene_camera) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, seq->scene_camera);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (seq->clip) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, seq->clip);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (seq->mask) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, seq->mask);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
if (seq->sound) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, seq->sound);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
|
|
|
|
|
TextVars *data = seq->effectdata;
|
|
|
|
|
expand_doit(fd, mainvar, data->text_font);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
SEQ_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sce->rigidbody_world) {
|
|
|
|
|
expand_doit(fd, mainvar, sce->rigidbody_world->group);
|
|
|
|
|
expand_doit(fd, mainvar, sce->rigidbody_world->constraints);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (TimeMarker *marker = sce->markers.first; marker; marker = marker->next) {
|
|
|
|
|
if (marker->camera) {
|
|
|
|
|
expand_doit(fd, mainvar, marker->camera);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expand_doit(fd, mainvar, sce->clip);
|
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
```
2017-02-07 10:18:38 +01:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#ifdef USE_COLLECTION_COMPAT_28
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sce->collection) {
|
|
|
|
|
expand_scene_collection(fd, mainvar, sce->collection);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#endif
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sce->master_collection) {
|
|
|
|
|
expand_collection(fd, mainvar, sce->master_collection);
|
|
|
|
|
}
|
2018-12-07 10:41:57 -02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (sce->r.bake.cage_object) {
|
|
|
|
|
expand_doit(fd, mainvar, sce->r.bake.cage_object);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ca->ipo); // XXX deprecated - old animation system
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-05-22 10:44:02 +02:00
|
|
|
for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) {
|
|
|
|
|
if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) {
|
|
|
|
|
expand_doit(fd, mainvar, bgpic->ima);
|
|
|
|
|
}
|
|
|
|
|
else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) {
|
|
|
|
|
expand_doit(fd, mainvar, bgpic->ima);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (ca->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, ca->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
static void expand_cachefile(FileData *fd, Main *mainvar, CacheFile *cache_file)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (cache_file->adt) {
|
|
|
|
|
expand_animdata(fd, mainvar, cache_file->adt);
|
|
|
|
|
}
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
}
|
|
|
|
|
|
2011-08-01 11:44:20 +00:00
|
|
|
static void expand_speaker(FileData *fd, Main *mainvar, Speaker *spk)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, spk->sound);
|
2011-08-01 11:44:20 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (spk->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, spk->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2011-08-01 11:44:20 +00:00
|
|
|
}
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void expand_sound(FileData *fd, Main *mainvar, bSound *snd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, snd->ipo); // XXX deprecated - old animation system
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-12 20:59:54 +10:00
|
|
|
static void expand_lightprobe(FileData *fd, Main *mainvar, LightProbe *prb)
|
2017-06-06 22:47:41 +02:00
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (prb->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, prb->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2017-06-06 22:47:41 +02:00
|
|
|
}
|
|
|
|
|
|
2012-02-17 10:54:21 +00:00
|
|
|
static void expand_movieclip(FileData *fd, Main *mainvar, MovieClip *clip)
|
|
|
|
|
{
|
2019-04-22 09:13:00 +10:00
|
|
|
if (clip->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, clip->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2012-02-17 10:54:21 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2012-07-31 20:54:27 +00:00
|
|
|
static void expand_mask_parent(FileData *fd, Main *mainvar, MaskParent *parent)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (parent->id) {
|
|
|
|
|
expand_doit(fd, mainvar, parent->id);
|
|
|
|
|
}
|
2012-07-31 20:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void expand_mask(FileData *fd, Main *mainvar, Mask *mask)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MaskLayer *mask_layer;
|
2012-07-31 20:54:27 +00:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mask->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, mask->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2012-07-31 20:54:27 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (mask_layer = mask->masklayers.first; mask_layer; mask_layer = mask_layer->next) {
|
|
|
|
|
MaskSpline *spline;
|
2012-07-31 20:54:27 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (spline = mask_layer->splines.first; spline; spline = spline->next) {
|
|
|
|
|
int i;
|
2012-07-31 20:54:27 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (i = 0; i < spline->tot_point; i++) {
|
|
|
|
|
MaskSplinePoint *point = &spline->points[i];
|
2012-07-31 20:54:27 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_mask_parent(fd, mainvar, &point->parent);
|
|
|
|
|
}
|
2012-07-31 20:54:27 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_mask_parent(fd, mainvar, &spline->parent);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-07-31 20:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
2010-06-25 22:45:42 +00:00
|
|
|
static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *linestyle)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
int a;
|
|
|
|
|
LineStyleModifier *m;
|
|
|
|
|
|
|
|
|
|
for (a = 0; a < MAX_MTEX; a++) {
|
|
|
|
|
if (linestyle->mtex[a]) {
|
|
|
|
|
expand_doit(fd, mainvar, linestyle->mtex[a]->tex);
|
|
|
|
|
expand_doit(fd, mainvar, linestyle->mtex[a]->object);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-22 09:13:00 +10:00
|
|
|
if (linestyle->nodetree) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_nodetree(fd, mainvar, linestyle->nodetree);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (linestyle->adt) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_animdata(fd, mainvar, linestyle->adt);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
for (m = linestyle->color_modifiers.first; m; m = m->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ((LineStyleColorModifier_DistanceFromObject *)m)->target);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
for (m = linestyle->alpha_modifiers.first; m; m = m->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ((LineStyleAlphaModifier_DistanceFromObject *)m)->target);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
for (m = linestyle->thickness_modifiers.first; m; m = m->next) {
|
2019-04-22 09:13:00 +10:00
|
|
|
if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit(fd, mainvar, ((LineStyleThicknessModifier_DistanceFromObject *)m)->target);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2010-06-25 22:45:42 +00:00
|
|
|
}
|
|
|
|
|
|
Grease Pencil - Storyboarding Features (merge from GPencil_EditStrokes branch)
This merge-commit brings in a number of new features and workflow/UI improvements for
working with Grease Pencil. While these were originally targetted at improving
the workflow for creating 3D storyboards in Blender using the Grease Pencil,
many of these changes should also prove useful in other workflows too.
The main highlights here are:
1) It is now possible to edit Grease Pencil strokes
- Use D Tab, or toggle the "Enable Editing" toggles in the Toolbar/Properties regions
to enter "Stroke Edit Mode". In this mode, many common editing tools will
operate on Grease Pencil stroke points instead.
- Tools implemented include Select, Select All/Border/Circle/Linked/More/Less,
Grab, Rotate, Scale, Bend, Shear, To Sphere, Mirror, Duplicate, Delete.
- Proportional Editing works when using the transform tools
2) Grease Pencil stroke settings can now be animated
NOTE: Currently drivers don't work, but if time allows, this may still be
added before the release.
3) Strokes can be drawn with "filled" interiors, using a separate set of
colour/opacity settings to the ones used for the lines themselves.
This makes use of OpenGL filled polys, which has the limitation of only
being able to fill convex shapes. Some artifacts may be visible on concave
shapes (e.g. pacman's mouth will be overdrawn)
4) "Volumetric Strokes" - An alternative drawing technique for stroke drawing
has been added which draws strokes as a series of screen-aligned discs.
While this was originally a partial experimental technique at getting better
quality 3D lines, the effects possible using this technique were interesting
enough to warrant making this a dedicated feature. Best results when partial
opacity and large stroke widths are used.
5) Improved Onion Skinning Support
- Different colours can be selected for the before/after ghosts. To do so,
enable the "colour wheel" toggle beside the Onion Skinning toggle, and set
the colours accordingly.
- Different numbers of ghosts can be shown before/after the current frame
6) Grease Pencil datablocks are now attached to the scene by default instead of
the active object.
- For a long time, the object-attachment has proved to be quite problematic
for users to keep track of. Now that this is done at scene level, it is
easier for most users to use.
- An exception for old files (and for any addons which may benefit from object
attachment instead), is that if the active object has a Grease Pencil datablock,
that will be used instead.
- It is not currently possible to choose object-attachment from the UI, but
it is simple to do this from the console instead, by doing:
context.active_object.grease_pencil = bpy.data.grease_pencil["blah"]
7) Various UI Cleanups
- The layers UI has been cleaned up to use a list instead of the nested-panels
design. Apart from saving space, this is also much nicer to look at now.
- The UI code is now all defined in Python. To support this, it has been necessary
to add some new context properties to make it easier to access these settings.
e.g. "gpencil_data" for the datablock
"active_gpencil_layer" and "active_gpencil_frame" for active data,
"editable_gpencil_strokes" for the strokes that can be edited
- The "stroke placement/alignment" settings (previously "Drawing Settings" at the
bottom of the Grease Pencil panel in the Properties Region) is now located in
the toolbar. These were more toolsettings than properties for how GPencil got drawn.
- "Use Sketching Sessions" has been renamed "Continuous Drawing", as per a
suggestion for an earlier discussion on developer.blender.org
- By default, the painting operator will wait for a mouse button to be pressed
before it starts creating the stroke. This is to make it easier to include
this operator in various toolbars/menus/etc. To get it immediately starting
(as when you hold down DKEy to draw), set "wait_for_input" to False.
- GPencil Layers can be rearranged in the "Grease Pencil" mode of the Action Editor
- Toolbar panels have been added to all the other editors which support these.
8) Pie menus for quick-access to tools
A set of experimental pie menus has been included for quick access to many
tools and settings. It is not necessary to use these to get things done,
but they have been designed to help make certain common tasks easier.
- Ctrl-D = The main pie menu. Reveals tools in a context sensitive and
spatially stable manner.
- D Q = "Quick Settings" pie. This allows quick access to the active
layer's settings. Notably, colours, thickness, and turning
onion skinning on/off.
2014-12-01 01:52:06 +13:00
|
|
|
static void expand_gpencil(FileData *fd, Main *mainvar, bGPdata *gpd)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (gpd->adt) {
|
|
|
|
|
expand_animdata(fd, mainvar, gpd->adt);
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
|
|
|
|
expand_doit(fd, mainvar, gpl->parent);
|
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int a = 0; a < gpd->totcol; a++) {
|
|
|
|
|
expand_doit(fd, mainvar, gpd->mat[a]);
|
|
|
|
|
}
|
Grease Pencil - Storyboarding Features (merge from GPencil_EditStrokes branch)
This merge-commit brings in a number of new features and workflow/UI improvements for
working with Grease Pencil. While these were originally targetted at improving
the workflow for creating 3D storyboards in Blender using the Grease Pencil,
many of these changes should also prove useful in other workflows too.
The main highlights here are:
1) It is now possible to edit Grease Pencil strokes
- Use D Tab, or toggle the "Enable Editing" toggles in the Toolbar/Properties regions
to enter "Stroke Edit Mode". In this mode, many common editing tools will
operate on Grease Pencil stroke points instead.
- Tools implemented include Select, Select All/Border/Circle/Linked/More/Less,
Grab, Rotate, Scale, Bend, Shear, To Sphere, Mirror, Duplicate, Delete.
- Proportional Editing works when using the transform tools
2) Grease Pencil stroke settings can now be animated
NOTE: Currently drivers don't work, but if time allows, this may still be
added before the release.
3) Strokes can be drawn with "filled" interiors, using a separate set of
colour/opacity settings to the ones used for the lines themselves.
This makes use of OpenGL filled polys, which has the limitation of only
being able to fill convex shapes. Some artifacts may be visible on concave
shapes (e.g. pacman's mouth will be overdrawn)
4) "Volumetric Strokes" - An alternative drawing technique for stroke drawing
has been added which draws strokes as a series of screen-aligned discs.
While this was originally a partial experimental technique at getting better
quality 3D lines, the effects possible using this technique were interesting
enough to warrant making this a dedicated feature. Best results when partial
opacity and large stroke widths are used.
5) Improved Onion Skinning Support
- Different colours can be selected for the before/after ghosts. To do so,
enable the "colour wheel" toggle beside the Onion Skinning toggle, and set
the colours accordingly.
- Different numbers of ghosts can be shown before/after the current frame
6) Grease Pencil datablocks are now attached to the scene by default instead of
the active object.
- For a long time, the object-attachment has proved to be quite problematic
for users to keep track of. Now that this is done at scene level, it is
easier for most users to use.
- An exception for old files (and for any addons which may benefit from object
attachment instead), is that if the active object has a Grease Pencil datablock,
that will be used instead.
- It is not currently possible to choose object-attachment from the UI, but
it is simple to do this from the console instead, by doing:
context.active_object.grease_pencil = bpy.data.grease_pencil["blah"]
7) Various UI Cleanups
- The layers UI has been cleaned up to use a list instead of the nested-panels
design. Apart from saving space, this is also much nicer to look at now.
- The UI code is now all defined in Python. To support this, it has been necessary
to add some new context properties to make it easier to access these settings.
e.g. "gpencil_data" for the datablock
"active_gpencil_layer" and "active_gpencil_frame" for active data,
"editable_gpencil_strokes" for the strokes that can be edited
- The "stroke placement/alignment" settings (previously "Drawing Settings" at the
bottom of the Grease Pencil panel in the Properties Region) is now located in
the toolbar. These were more toolsettings than properties for how GPencil got drawn.
- "Use Sketching Sessions" has been renamed "Continuous Drawing", as per a
suggestion for an earlier discussion on developer.blender.org
- By default, the painting operator will wait for a mouse button to be pressed
before it starts creating the stroke. This is to make it easier to include
this operator in various toolbars/menus/etc. To get it immediately starting
(as when you hold down DKEy to draw), set "wait_for_input" to False.
- GPencil Layers can be rearranged in the "Grease Pencil" mode of the Action Editor
- Toolbar panels have been added to all the other editors which support these.
8) Pie menus for quick-access to tools
A set of experimental pie menus has been included for quick access to many
tools and settings. It is not necessary to use these to get things done,
but they have been designed to help make certain common tasks easier.
- Ctrl-D = The main pie menu. Reveals tools in a context sensitive and
spatially stable manner.
- D Q = "Quick Settings" pie. This allows quick access to the active
layer's settings. Notably, colours, thickness, and turning
onion skinning on/off.
2014-12-01 01:52:06 +13:00
|
|
|
}
|
|
|
|
|
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
static void expand_workspace(FileData *fd, Main *mainvar, WorkSpace *workspace)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *layouts = BKE_workspace_layouts_get(workspace);
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) {
|
|
|
|
|
expand_doit(fd, mainvar, BKE_workspace_layout_screen_get(layout));
|
|
|
|
|
}
|
Main Workspace Integration
This commit does the main integration of workspaces, which is a design we agreed on during the 2.8 UI workshop (see https://wiki.blender.org/index.php/Dev:2.8/UI/Workshop_Writeup)
Workspaces should generally be stable, I'm not aware of any remaining bugs (or I've forgotten them :) ). If you find any, let me know!
(Exception: mode switching button might get out of sync with actual mode in some cases, would consider that a limitation/ToDo. Needs to be resolved at some point.)
== Main Changes/Features
* Introduces the new Workspaces as data-blocks.
* Allow storing a number of custom workspaces as part of the user configuration. Needs further work to allow adding and deleting individual workspaces.
* Bundle a default workspace configuration with Blender (current screen-layouts converted to workspaces).
* Pressing button to add a workspace spawns a menu to select between "Duplicate Current" and the workspaces from the user configuration. If no workspaces are stored in the user configuration, the default workspaces are listed instead.
* Store screen-layouts (`bScreen`) per workspace.
* Store an active screen-layout per workspace. Changing the workspace will enable this layout.
* Store active mode in workspace. Changing the workspace will also enter the mode of the new workspace. (Note that we still store the active mode in the object, moving this completely to workspaces is a separate project.)
* Store an active render layer per workspace.
* Moved mode switch from 3D View header to Info Editor header.
* Store active scene in window (not directly workspace related, but overlaps quite a bit).
* Removed 'Use Global Scene' User Preference option.
* Compatibility with old files - a new workspace is created for every screen-layout of old files. Old Blender versions should be able to read files saved with workspace support as well.
* Default .blend only contains one workspace ("General").
* Support appending workspaces.
Opening files without UI and commandline rendering should work fine.
Note that the UI is temporary! We plan to introduce a new global topbar
that contains the workspace options and tabs for switching workspaces.
== Technical Notes
* Workspaces are data-blocks.
* Adding and removing `bScreen`s should be done through `ED_workspace_layout` API now.
* A workspace can be active in multiple windows at the same time.
* The mode menu (which is now in the Info Editor header) doesn't display "Grease Pencil Edit" mode anymore since its availability depends on the active editor. Will be fixed by making Grease Pencil an own object type (as planned).
* The button to change the active workspace object mode may get out of sync with the mode of the active object. Will either be resolved by moving mode out of object data, or we'll disable workspace modes again (there's a `#define USE_WORKSPACE_MODE` for that).
* Screen-layouts (`bScreen`) are IDs and thus stored in a main list-base. Had to add a wrapper `WorkSpaceLayout` so we can store them in a list-base within workspaces, too. On the long run we could completely replace `bScreen` by workspace structs.
* `WorkSpace` types use some special compiler trickery to allow marking structs and struct members as private. BKE_workspace API should be used for accessing those.
* Added scene operators `SCENE_OT_`. Was previously done through screen operators.
== BPY API Changes
* Removed `Screen.scene`, added `Window.scene`
* Removed `UserPreferencesView.use_global_scene`
* Added `Context.workspace`, `Window.workspace` and `BlendData.workspaces`
* Added `bpy.types.WorkSpace` containing `screens`, `object_mode` and `render_layer`
* Added Screen.layout_name for the layout name that'll be displayed in the UI (may differ from internal name)
== What's left?
* There are a few open design questions (T50521). We should find the needed answers and implement them.
* Allow adding and removing individual workspaces from workspace configuration (needs UI design).
* Get the override system ready and support overrides per workspace.
* Support custom UI setups as part of workspaces (hidden panels, hidden buttons, customizable toolbars, etc).
* Allow enabling add-ons per workspace.
* Support custom workspace keymaps.
* Remove special exception for workspaces in linking code (so they're always appended, never linked). Depends on a few things, so best to solve later.
* Get the topbar done.
* Workspaces need a proper icon, current one is just a placeholder :)
Reviewed By: campbellbarton, mont29
Tags: #user_interface, #bf_blender_2.8
Maniphest Tasks: T50521
Differential Revision: https://developer.blender.org/D2451
2017-06-01 19:56:58 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
|
|
|
|
* Set the callback func used over all ID data found by \a BLO_expand_main func.
|
|
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param expand_doit_func: Called for each ID block it finds.
|
2015-10-12 14:21:34 +02:00
|
|
|
*/
|
2015-10-12 14:31:47 +02:00
|
|
|
void BLO_main_expander(BLOExpandDoitCallback expand_doit_func)
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
expand_doit = expand_doit_func;
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
|
|
|
|
* Loop over all ID data in Main to mark relations.
|
Split id->flag in two, persistent flags and runtime tags.
This is purely internal sanitizing/cleanup, no change in behavior is expected at all.
This change was also needed because we were getting short on ID flags, and
future enhancement of 'user_one' ID behavior requires two new ones.
id->flag remains for persistent data (fakeuser only, so far!), this also allows us
100% backward & forward compatibility.
New id->tag is used for most flags. Though written in .blend files, its content
is cleared at read time.
Note that .blend file version was bumped, so that we can clear runtimeflags from
old .blends, important in case we add new persistent flags in future.
Also, behavior of tags (either status ones, or whether they need to be cleared before/after use)
has been added as comments to their declaration.
Reviewers: sergey, campbellbarton
Differential Revision: https://developer.blender.org/D1683
2015-12-27 11:53:50 +01:00
|
|
|
* Set (id->tag & LIB_TAG_NEED_EXPAND) to mark expanding. Flags get cleared after expanding.
|
2015-10-12 14:21:34 +02:00
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param fdhandle: usually filedata, or own handle.
|
|
|
|
|
* \param mainvar: the Main database to expand.
|
2015-10-12 14:21:34 +02:00
|
|
|
*/
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
void BLO_expand_main(void *fdhandle, Main *mainvar)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *lbarray[MAX_LIBARRAY];
|
|
|
|
|
FileData *fd = fdhandle;
|
|
|
|
|
ID *id;
|
|
|
|
|
int a;
|
|
|
|
|
bool do_it = true;
|
|
|
|
|
|
|
|
|
|
while (do_it) {
|
|
|
|
|
do_it = false;
|
|
|
|
|
|
|
|
|
|
a = set_listbasepointers(mainvar, lbarray);
|
|
|
|
|
while (a--) {
|
|
|
|
|
id = lbarray[a]->first;
|
|
|
|
|
while (id) {
|
|
|
|
|
if (id->tag & LIB_TAG_NEED_EXPAND) {
|
|
|
|
|
expand_id(fd, mainvar, id);
|
|
|
|
|
expand_idprops(fd, mainvar, id->properties);
|
|
|
|
|
|
|
|
|
|
switch (GS(id->name)) {
|
|
|
|
|
case ID_OB:
|
|
|
|
|
expand_object(fd, mainvar, (Object *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_ME:
|
|
|
|
|
expand_mesh(fd, mainvar, (Mesh *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_CU:
|
|
|
|
|
expand_curve(fd, mainvar, (Curve *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_MB:
|
|
|
|
|
expand_mball(fd, mainvar, (MetaBall *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_SCE:
|
|
|
|
|
expand_scene(fd, mainvar, (Scene *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_MA:
|
|
|
|
|
expand_material(fd, mainvar, (Material *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_TE:
|
|
|
|
|
expand_texture(fd, mainvar, (Tex *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_WO:
|
|
|
|
|
expand_world(fd, mainvar, (World *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LT:
|
|
|
|
|
expand_lattice(fd, mainvar, (Lattice *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LA:
|
|
|
|
|
expand_light(fd, mainvar, (Light *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_KE:
|
|
|
|
|
expand_key(fd, mainvar, (Key *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_CA:
|
|
|
|
|
expand_camera(fd, mainvar, (Camera *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_SPK:
|
|
|
|
|
expand_speaker(fd, mainvar, (Speaker *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_SO:
|
|
|
|
|
expand_sound(fd, mainvar, (bSound *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LP:
|
|
|
|
|
expand_lightprobe(fd, mainvar, (LightProbe *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_AR:
|
|
|
|
|
expand_armature(fd, mainvar, (bArmature *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_AC:
|
|
|
|
|
expand_action(fd, mainvar, (bAction *)id); // XXX deprecated - old animation system
|
|
|
|
|
break;
|
|
|
|
|
case ID_GR:
|
|
|
|
|
expand_collection(fd, mainvar, (Collection *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_NT:
|
|
|
|
|
expand_nodetree(fd, mainvar, (bNodeTree *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_BR:
|
|
|
|
|
expand_brush(fd, mainvar, (Brush *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_IP:
|
|
|
|
|
expand_ipo(fd, mainvar, (Ipo *)id); // XXX deprecated - old animation system
|
|
|
|
|
break;
|
|
|
|
|
case ID_PA:
|
|
|
|
|
expand_particlesettings(fd, mainvar, (ParticleSettings *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_MC:
|
|
|
|
|
expand_movieclip(fd, mainvar, (MovieClip *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_MSK:
|
|
|
|
|
expand_mask(fd, mainvar, (Mask *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_LS:
|
|
|
|
|
expand_linestyle(fd, mainvar, (FreestyleLineStyle *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_GD:
|
|
|
|
|
expand_gpencil(fd, mainvar, (bGPdata *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_CF:
|
|
|
|
|
expand_cachefile(fd, mainvar, (CacheFile *)id);
|
|
|
|
|
break;
|
|
|
|
|
case ID_WS:
|
|
|
|
|
expand_workspace(fd, mainvar, (WorkSpace *)id);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
do_it = true;
|
|
|
|
|
id->tag &= ~LIB_TAG_NEED_EXPAND;
|
|
|
|
|
}
|
|
|
|
|
id = id->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Library Linking (helper functions)
|
|
|
|
|
* \{ */
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
static bool object_in_any_scene(Main *bmain, Object *ob)
|
2006-06-02 20:48:22 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Scene *sce;
|
|
|
|
|
|
|
|
|
|
for (sce = bmain->scenes.first; sce; sce = sce->id.next) {
|
|
|
|
|
if (BKE_scene_object_find(sce, ob)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-12 15:37:58 +02:00
|
|
|
static bool object_in_any_collection(Main *bmain, Object *ob)
|
|
|
|
|
{
|
|
|
|
|
Collection *collection;
|
|
|
|
|
|
|
|
|
|
for (collection = bmain->collections.first; collection; collection = collection->id.next) {
|
|
|
|
|
if (BKE_collection_has_object(collection, ob)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void add_loose_objects_to_scene(Main *mainvar,
|
|
|
|
|
Main *bmain,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
const View3D *v3d,
|
|
|
|
|
Library *lib,
|
|
|
|
|
const short flag)
|
|
|
|
|
{
|
|
|
|
|
Collection *active_collection = NULL;
|
2019-08-12 15:37:58 +02:00
|
|
|
const bool do_append = (flag & FILE_LINK) == 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
BLI_assert(scene);
|
|
|
|
|
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Give all objects which are LIB_TAG_INDIRECT a base,
|
|
|
|
|
* or for a collection when *lib has been set. */
|
2019-04-17 06:17:24 +02:00
|
|
|
for (Object *ob = mainvar->objects.first; ob; ob = ob->id.next) {
|
|
|
|
|
bool do_it = (ob->id.tag & LIB_TAG_DOIT) != 0;
|
|
|
|
|
if (do_it || ((ob->id.tag & LIB_TAG_INDIRECT) && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0)) {
|
2019-08-12 15:37:58 +02:00
|
|
|
if (do_append) {
|
2019-04-17 06:17:24 +02:00
|
|
|
if (ob->id.us == 0) {
|
|
|
|
|
do_it = true;
|
|
|
|
|
}
|
2019-08-12 15:37:58 +02:00
|
|
|
else if ((ob->id.lib == lib) && (object_in_any_collection(bmain, ob) == 0)) {
|
|
|
|
|
/* When appending, make sure any indirectly loaded object gets a base,
|
|
|
|
|
* when they are not part of any collection yet. */
|
2019-04-17 06:17:24 +02:00
|
|
|
do_it = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (do_it) {
|
|
|
|
|
/* Find or add collection as needed. */
|
|
|
|
|
if (active_collection == NULL) {
|
|
|
|
|
if (flag & FILE_ACTIVE_COLLECTION) {
|
|
|
|
|
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
|
|
|
|
|
active_collection = lc->collection;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
active_collection = BKE_collection_add(bmain, scene->master_collection, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CLAMP_MIN(ob->id.us, 0);
|
|
|
|
|
ob->mode = OB_MODE_OBJECT;
|
|
|
|
|
|
|
|
|
|
BKE_collection_object_add(bmain, active_collection, ob);
|
|
|
|
|
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
|
|
|
|
|
|
|
|
|
if (v3d != NULL) {
|
|
|
|
|
base->local_view_bits |= v3d->local_view_uuid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flag & FILE_AUTOSELECT) {
|
|
|
|
|
base->flag |= BASE_SELECTED;
|
2019-04-22 01:10:29 +10:00
|
|
|
/* Do NOT make base active here! screws up GUI stuff,
|
|
|
|
|
* if you want it do it on src/ level. */
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BKE_scene_object_base_flag_sync_from_base(base);
|
|
|
|
|
|
|
|
|
|
ob->id.tag &= ~LIB_TAG_INDIRECT;
|
|
|
|
|
ob->id.tag |= LIB_TAG_EXTERN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void add_collections_to_scene(Main *mainvar,
|
|
|
|
|
Main *bmain,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
const View3D *v3d,
|
|
|
|
|
Library *lib,
|
|
|
|
|
const short flag)
|
|
|
|
|
{
|
|
|
|
|
Collection *active_collection = scene->master_collection;
|
|
|
|
|
if (flag & FILE_ACTIVE_COLLECTION) {
|
|
|
|
|
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
|
|
|
|
|
active_collection = lc->collection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Give all objects which are tagged a base. */
|
|
|
|
|
for (Collection *collection = mainvar->collections.first; collection;
|
|
|
|
|
collection = collection->id.next) {
|
|
|
|
|
if ((flag & FILE_GROUP_INSTANCE) && (collection->id.tag & LIB_TAG_DOIT)) {
|
|
|
|
|
/* Any indirect collection should not have been tagged. */
|
|
|
|
|
BLI_assert((collection->id.tag & LIB_TAG_INDIRECT) == 0);
|
|
|
|
|
|
|
|
|
|
/* BKE_object_add(...) messes with the selection. */
|
|
|
|
|
Object *ob = BKE_object_add_only_object(bmain, OB_EMPTY, collection->id.name + 2);
|
|
|
|
|
ob->type = OB_EMPTY;
|
|
|
|
|
|
|
|
|
|
BKE_collection_object_add(bmain, active_collection, ob);
|
|
|
|
|
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
|
|
|
|
|
|
|
|
|
if (v3d != NULL) {
|
|
|
|
|
base->local_view_bits |= v3d->local_view_uuid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (base->flag & BASE_SELECTABLE) {
|
|
|
|
|
base->flag |= BASE_SELECTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BKE_scene_object_base_flag_sync_from_base(base);
|
|
|
|
|
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
|
|
|
|
|
view_layer->basact = base;
|
|
|
|
|
|
|
|
|
|
/* Assign the collection. */
|
|
|
|
|
ob->instance_collection = collection;
|
|
|
|
|
id_us_plus(&collection->id);
|
|
|
|
|
ob->transflag |= OB_DUPLICOLLECTION;
|
|
|
|
|
copy_v3_v3(ob->loc, scene->cursor.location);
|
|
|
|
|
}
|
2019-08-12 15:37:58 +02:00
|
|
|
/* We do not want to force instantiation of indirectly linked collections,
|
|
|
|
|
* not even when appending. Users can now easily instantiate collections (and their objects)
|
|
|
|
|
* as needed by themsleves. See T67032. */
|
|
|
|
|
else if ((collection->id.tag & LIB_TAG_INDIRECT) == 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
bool do_add_collection = (collection->id.tag & LIB_TAG_DOIT) != 0;
|
|
|
|
|
if (!do_add_collection) {
|
|
|
|
|
/* We need to check that objects in that collections are already instantiated in a scene.
|
|
|
|
|
* Otherwise, it's better to add the collection to the scene's active collection, than to
|
|
|
|
|
* instantiate its objects in active scene's collection directly. See T61141.
|
2019-04-22 01:10:29 +10:00
|
|
|
* Note that we only check object directly into that collection,
|
|
|
|
|
* not recursively into its children.
|
2019-04-17 06:17:24 +02:00
|
|
|
*/
|
|
|
|
|
for (CollectionObject *coll_ob = collection->gobject.first; coll_ob != NULL;
|
|
|
|
|
coll_ob = coll_ob->next) {
|
|
|
|
|
Object *ob = coll_ob->ob;
|
2019-08-12 15:37:58 +02:00
|
|
|
if ((ob->id.tag & (LIB_TAG_PRE_EXISTING | LIB_TAG_DOIT | LIB_TAG_INDIRECT)) == 0 &&
|
|
|
|
|
(ob->id.lib == lib) && (object_in_any_scene(bmain, ob) == 0)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
do_add_collection = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (do_add_collection) {
|
|
|
|
|
/* Add collection as child of active collection. */
|
|
|
|
|
BKE_collection_child_add(bmain, active_collection, collection);
|
|
|
|
|
|
|
|
|
|
if (flag & FILE_AUTOSELECT) {
|
|
|
|
|
for (CollectionObject *coll_ob = collection->gobject.first; coll_ob != NULL;
|
|
|
|
|
coll_ob = coll_ob->next) {
|
|
|
|
|
Object *ob = coll_ob->ob;
|
|
|
|
|
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
|
|
|
|
if (base) {
|
|
|
|
|
base->flag |= BASE_SELECTED;
|
|
|
|
|
BKE_scene_object_base_flag_sync_from_base(base);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-12 15:37:58 +02:00
|
|
|
/* Those are kept for safety and consistency, but should not be needed anymore? */
|
2019-04-17 06:17:24 +02:00
|
|
|
collection->id.tag &= ~LIB_TAG_INDIRECT;
|
|
|
|
|
collection->id.tag |= LIB_TAG_EXTERN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-01-07 14:28:00 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2011-03-13 01:15:14 +00:00
|
|
|
/* returns true if the item was found
|
2012-04-22 11:54:53 +00:00
|
|
|
* but it may already have already been appended/linked */
|
2016-06-22 18:05:55 +02:00
|
|
|
static ID *link_named_part(
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *mainl, FileData *fd, const short idcode, const char *name, const int flag)
|
|
|
|
|
{
|
|
|
|
|
BHead *bhead = find_bhead_from_code_name(fd, idcode, name);
|
|
|
|
|
ID *id;
|
|
|
|
|
|
|
|
|
|
const bool use_placeholders = (flag & BLO_LIBLINK_USE_PLACEHOLDERS) != 0;
|
|
|
|
|
const bool force_indirect = (flag & BLO_LIBLINK_FORCE_INDIRECT) != 0;
|
|
|
|
|
|
|
|
|
|
BLI_assert(BKE_idcode_is_linkable(idcode) && BKE_idcode_is_valid(idcode));
|
|
|
|
|
|
|
|
|
|
if (bhead) {
|
|
|
|
|
id = is_yet_read(fd, mainl, bhead);
|
|
|
|
|
if (id == NULL) {
|
|
|
|
|
/* not read yet */
|
|
|
|
|
const int tag = force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_EXTERN;
|
|
|
|
|
read_libblock(fd, mainl, bhead, tag | LIB_TAG_NEED_EXPAND, &id);
|
|
|
|
|
|
|
|
|
|
if (id) {
|
|
|
|
|
/* sort by name in list */
|
|
|
|
|
ListBase *lb = which_libbase(mainl, idcode);
|
|
|
|
|
id_sort_by_name(lb, id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* already linked */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (G.debug) {
|
2019-04-17 06:17:24 +02:00
|
|
|
printf("append: already linked\n");
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
|
|
|
|
|
if (!force_indirect && (id->tag & LIB_TAG_INDIRECT)) {
|
|
|
|
|
id->tag &= ~LIB_TAG_INDIRECT;
|
|
|
|
|
id->tag |= LIB_TAG_EXTERN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (use_placeholders) {
|
|
|
|
|
/* XXX flag part is weak! */
|
|
|
|
|
id = create_placeholder(
|
|
|
|
|
mainl, idcode, name, force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_EXTERN);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
id = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if we found the id but the id is NULL, this is really bad */
|
|
|
|
|
BLI_assert(!((bhead != NULL) && (id == NULL)));
|
|
|
|
|
|
|
|
|
|
return id;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
|
|
|
|
* Simple reader for copy/paste buffers.
|
|
|
|
|
*/
|
2019-03-25 09:55:36 +01:00
|
|
|
int BLO_library_link_copypaste(Main *mainl, BlendHandle *bh, const unsigned int id_types_mask)
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = (FileData *)(bh);
|
|
|
|
|
BHead *bhead;
|
|
|
|
|
int num_directly_linked = 0;
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
|
|
|
|
ID *id = NULL;
|
2016-01-08 11:05:39 +01:00
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (bhead->code == ENDB) {
|
2019-04-17 06:17:24 +02:00
|
|
|
break;
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-03-25 09:55:36 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (BKE_idcode_is_valid(bhead->code) && BKE_idcode_is_linkable(bhead->code) &&
|
|
|
|
|
(id_types_mask == 0 ||
|
|
|
|
|
(BKE_idcode_to_idfilter((short)bhead->code) & id_types_mask) != 0)) {
|
|
|
|
|
read_libblock(fd, mainl, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, &id);
|
|
|
|
|
num_directly_linked++;
|
|
|
|
|
}
|
2016-01-12 06:31:50 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (id) {
|
|
|
|
|
/* sort by name in list */
|
|
|
|
|
ListBase *lb = which_libbase(mainl, GS(id->name));
|
|
|
|
|
id_sort_by_name(lb, id);
|
2016-01-08 11:05:39 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (bhead->code == ID_OB) {
|
|
|
|
|
/* Instead of instancing Base's directly, postpone until after collections are loaded
|
|
|
|
|
* otherwise the base's flag is set incorrectly when collections are used */
|
|
|
|
|
Object *ob = (Object *)id;
|
|
|
|
|
ob->mode = OB_MODE_OBJECT;
|
|
|
|
|
/* ensure add_loose_objects_to_scene runs on this object */
|
|
|
|
|
BLI_assert(id->us == 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-03-25 09:55:36 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return num_directly_linked;
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:07:07 +02:00
|
|
|
static ID *link_named_part_ex(
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *mainl, FileData *fd, const short idcode, const char *name, const int flag)
|
2011-05-26 20:45:19 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ID *id = link_named_part(mainl, fd, idcode, name, flag);
|
2011-05-26 20:45:19 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (id && (GS(id->name) == ID_OB)) {
|
|
|
|
|
/* Tag as loose object needing to be instantiated somewhere... */
|
|
|
|
|
id->tag |= LIB_TAG_DOIT;
|
|
|
|
|
}
|
|
|
|
|
else if (id && (GS(id->name) == ID_GR)) {
|
|
|
|
|
/* tag as needing to be instantiated or linked */
|
|
|
|
|
id->tag |= LIB_TAG_DOIT;
|
|
|
|
|
}
|
2015-10-12 15:07:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return id;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
2019-02-22 18:35:07 +11:00
|
|
|
* Link a named data-block from an external blend file.
|
2015-10-12 14:21:34 +02:00
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param mainl: The main database to link from (not the active one).
|
|
|
|
|
* \param bh: The blender file handle.
|
2019-02-22 18:35:07 +11:00
|
|
|
* \param idcode: The kind of data-block to link.
|
|
|
|
|
* \param name: The name of the data-block (without the 2 char ID prefix).
|
2015-10-15 16:04:04 +02:00
|
|
|
* \return the linked ID when found.
|
2015-10-12 14:21:34 +02:00
|
|
|
*/
|
2019-04-17 06:17:24 +02:00
|
|
|
ID *BLO_library_link_named_part(Main *mainl,
|
|
|
|
|
BlendHandle **bh,
|
|
|
|
|
const short idcode,
|
|
|
|
|
const char *name)
|
2009-09-12 19:54:39 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = (FileData *)(*bh);
|
|
|
|
|
return link_named_part(mainl, fd, idcode, name, 0);
|
2011-05-26 20:45:19 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
2019-02-22 18:35:07 +11:00
|
|
|
* Link a named data-block from an external blend file.
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
* Optionally instantiate the object/collection in the scene when the flags are set.
|
2015-10-12 14:21:34 +02:00
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param mainl: The main database to link from (not the active one).
|
|
|
|
|
* \param bh: The blender file handle.
|
2019-02-22 18:35:07 +11:00
|
|
|
* \param idcode: The kind of data-block to link.
|
|
|
|
|
* \param name: The name of the data-block (without the 2 char ID prefix).
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param flag: Options for linking, used for instantiating.
|
2019-04-22 01:10:29 +10:00
|
|
|
* \param scene: The scene in which to instantiate objects/collections
|
|
|
|
|
* (if NULL, no instantiation is done).
|
|
|
|
|
* \param v3d: The active 3D viewport.
|
|
|
|
|
* (only to define active layers for instantiated objects & collections, can be NULL).
|
2015-10-15 16:04:04 +02:00
|
|
|
* \return the linked ID when found.
|
2015-10-12 14:21:34 +02:00
|
|
|
*/
|
|
|
|
|
ID *BLO_library_link_named_part_ex(
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *mainl, BlendHandle **bh, const short idcode, const char *name, const int flag)
|
2009-09-12 19:54:39 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = (FileData *)(*bh);
|
|
|
|
|
return link_named_part_ex(mainl, fd, idcode, name, flag);
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
2007-03-16 05:39:30 +00:00
|
|
|
/* common routine to append/link something from a library */
|
2006-01-04 19:05:24 +00:00
|
|
|
|
2015-10-12 13:46:58 +02:00
|
|
|
static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *mainl;
|
2012-05-25 17:13:30 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
(*fd)->mainlist = MEM_callocN(sizeof(ListBase), "FileData.mainlist");
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* clear for objects and collections instantiating tag */
|
|
|
|
|
BKE_main_id_tag_listbase(&(mainvar->objects), LIB_TAG_DOIT, false);
|
|
|
|
|
BKE_main_id_tag_listbase(&(mainvar->collections), LIB_TAG_DOIT, false);
|
2013-09-03 17:24:07 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* make mains */
|
|
|
|
|
blo_split_main((*fd)->mainlist, mainvar);
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* which one do we need? */
|
|
|
|
|
mainl = blo_find_main(*fd, filepath, BKE_main_blendfile_path(mainvar));
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* needed for do_version */
|
|
|
|
|
mainl->versionfile = (*fd)->fileversion;
|
|
|
|
|
read_file_version(*fd, mainl);
|
2015-03-11 00:33:44 +11:00
|
|
|
#ifdef USE_GHASH_BHEAD
|
2019-04-17 06:17:24 +02:00
|
|
|
read_file_bhead_idname_map_create(*fd);
|
2015-03-11 00:33:44 +11:00
|
|
|
#endif
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return mainl;
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
|
|
|
|
* Initialize the BlendHandle for linking library data.
|
|
|
|
|
*
|
2019-04-22 01:10:29 +10:00
|
|
|
* \param mainvar: The current main database, e.g. #G_MAIN or #CTX_data_main(C).
|
|
|
|
|
* \param bh: A blender file handle as returned by
|
|
|
|
|
* #BLO_blendhandle_from_file or #BLO_blendhandle_from_memory.
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param filepath: Used for relative linking, copied to the \a lib->name.
|
2019-04-22 01:10:29 +10:00
|
|
|
* \return the library Main, to be passed to #BLO_library_append_named_part as \a mainl.
|
2015-10-12 14:21:34 +02:00
|
|
|
*/
|
2015-10-12 13:46:58 +02:00
|
|
|
Main *BLO_library_link_begin(Main *mainvar, BlendHandle **bh, const char *filepath)
|
2009-09-12 19:54:39 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = (FileData *)(*bh);
|
|
|
|
|
return library_link_begin(mainvar, &fd, filepath);
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
2016-12-23 12:54:51 +01:00
|
|
|
static void split_main_newid(Main *mainptr, Main *main_newid)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* We only copy the necessary subset of data in this temp main. */
|
|
|
|
|
main_newid->versionfile = mainptr->versionfile;
|
|
|
|
|
main_newid->subversionfile = mainptr->subversionfile;
|
|
|
|
|
BLI_strncpy(main_newid->name, mainptr->name, sizeof(main_newid->name));
|
|
|
|
|
main_newid->curlib = mainptr->curlib;
|
2016-12-23 12:54:51 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *lbarray[MAX_LIBARRAY];
|
|
|
|
|
ListBase *lbarray_newid[MAX_LIBARRAY];
|
|
|
|
|
int i = set_listbasepointers(mainptr, lbarray);
|
|
|
|
|
set_listbasepointers(main_newid, lbarray_newid);
|
|
|
|
|
while (i--) {
|
|
|
|
|
BLI_listbase_clear(lbarray_newid[i]);
|
2016-12-23 12:54:51 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (ID *id = lbarray[i]->first, *idnext; id; id = idnext) {
|
|
|
|
|
idnext = id->next;
|
2016-12-23 12:54:51 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (id->tag & LIB_TAG_NEW) {
|
|
|
|
|
BLI_remlink(lbarray[i], id);
|
|
|
|
|
BLI_addtail(lbarray_newid[i], id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-12-23 12:54:51 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:07:07 +02:00
|
|
|
/* scene and v3d may be NULL. */
|
2019-04-17 06:17:24 +02:00
|
|
|
static void library_link_end(Main *mainl,
|
|
|
|
|
FileData **fd,
|
|
|
|
|
const short flag,
|
|
|
|
|
Main *bmain,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
const View3D *v3d)
|
|
|
|
|
{
|
|
|
|
|
Main *mainvar;
|
|
|
|
|
Library *curlib;
|
|
|
|
|
|
|
|
|
|
/* expander now is callback function */
|
|
|
|
|
BLO_main_expander(expand_doit_library);
|
|
|
|
|
|
|
|
|
|
/* make main consistent */
|
|
|
|
|
BLO_expand_main(*fd, mainl);
|
|
|
|
|
|
|
|
|
|
/* do this when expand found other libs */
|
|
|
|
|
read_libraries(*fd, (*fd)->mainlist);
|
|
|
|
|
|
|
|
|
|
curlib = mainl->curlib;
|
|
|
|
|
|
|
|
|
|
/* make the lib path relative if required */
|
|
|
|
|
if (flag & FILE_RELPATH) {
|
|
|
|
|
/* use the full path, this could have been read by other library even */
|
|
|
|
|
BLI_strncpy(curlib->name, curlib->filepath, sizeof(curlib->name));
|
|
|
|
|
|
|
|
|
|
/* uses current .blend file as reference */
|
|
|
|
|
BLI_path_rel(curlib->name, BKE_main_blendfile_path_from_global());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
blo_join_main((*fd)->mainlist);
|
|
|
|
|
mainvar = (*fd)->mainlist->first;
|
|
|
|
|
mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
|
|
|
|
|
|
|
|
|
|
lib_link_all(*fd, mainvar);
|
|
|
|
|
BKE_collections_after_lib_link(mainvar);
|
|
|
|
|
|
|
|
|
|
/* Yep, second splitting... but this is a very cheap operation, so no big deal. */
|
|
|
|
|
blo_split_main((*fd)->mainlist, mainvar);
|
|
|
|
|
Main *main_newid = BKE_main_new();
|
|
|
|
|
for (mainvar = ((Main *)(*fd)->mainlist->first)->next; mainvar; mainvar = mainvar->next) {
|
|
|
|
|
BLI_assert(mainvar->versionfile != 0);
|
2019-04-22 01:10:29 +10:00
|
|
|
/* We need to split out IDs already existing,
|
|
|
|
|
* or they will go again through do_versions - bad, very bad! */
|
2019-04-17 06:17:24 +02:00
|
|
|
split_main_newid(mainvar, main_newid);
|
|
|
|
|
|
|
|
|
|
do_versions_after_linking(main_newid);
|
|
|
|
|
|
|
|
|
|
add_main_to_main(mainvar, main_newid);
|
|
|
|
|
}
|
|
|
|
|
BKE_main_free(main_newid);
|
|
|
|
|
blo_join_main((*fd)->mainlist);
|
|
|
|
|
mainvar = (*fd)->mainlist->first;
|
|
|
|
|
MEM_freeN((*fd)->mainlist);
|
|
|
|
|
|
2019-04-20 20:25:22 +02:00
|
|
|
/* After all data has been read and versioned, uses LIB_TAG_NEW. */
|
|
|
|
|
ntreeUpdateAllNew(mainvar);
|
|
|
|
|
|
2019-08-12 11:54:37 +02:00
|
|
|
placeholders_ensure_valid(mainvar);
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_main_id_tag_all(mainvar, LIB_TAG_NEW, false);
|
|
|
|
|
|
|
|
|
|
fix_relpaths_library(BKE_main_blendfile_path(mainvar),
|
|
|
|
|
mainvar); /* make all relative paths, relative to the open blend file */
|
|
|
|
|
|
|
|
|
|
/* Give a base to loose objects and collections.
|
2019-04-22 01:10:29 +10:00
|
|
|
* Only directly linked objects & collections are instantiated by
|
|
|
|
|
* `BLO_library_link_named_part_ex()` & co,
|
2019-04-17 06:17:24 +02:00
|
|
|
* here we handle indirect ones and other possible edge-cases. */
|
|
|
|
|
if (scene) {
|
|
|
|
|
add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
|
|
|
|
|
add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clear objects and collections instantiating tag. */
|
|
|
|
|
BKE_main_id_tag_listbase(&(mainvar->objects), LIB_TAG_DOIT, false);
|
|
|
|
|
BKE_main_id_tag_listbase(&(mainvar->collections), LIB_TAG_DOIT, false);
|
|
|
|
|
|
|
|
|
|
/* patch to prevent switch_endian happens twice */
|
|
|
|
|
if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
|
|
|
|
blo_filedata_free(*fd);
|
|
|
|
|
*fd = NULL;
|
|
|
|
|
}
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 14:21:34 +02:00
|
|
|
/**
|
2015-10-12 15:07:07 +02:00
|
|
|
* Finalize linking from a given .blend file (library).
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
* Optionally instance the indirect object/collection in the scene when the flags are set.
|
2015-10-12 14:21:34 +02:00
|
|
|
* \note Do not use \a bh after calling this function, it may frees it.
|
|
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param mainl: The main database to link from (not the active one).
|
|
|
|
|
* \param bh: The blender file handle (WARNING! may be freed by this function!).
|
|
|
|
|
* \param flag: Options for linking, used for instantiating.
|
2018-12-12 12:55:20 +11:00
|
|
|
* \param bmain: The main database in which to instantiate objects/collections
|
2019-04-22 01:10:29 +10:00
|
|
|
* \param scene: The scene in which to instantiate objects/collections
|
|
|
|
|
* (if NULL, no instantiation is done).
|
|
|
|
|
* \param view_layer: The scene layer in which to instantiate objects/collections
|
|
|
|
|
* (if NULL, no instantiation is done).
|
|
|
|
|
* \param v3d: The active 3D viewport
|
|
|
|
|
* (only to define local-view for instantiated objects & groups, can be NULL).
|
2015-10-12 14:21:34 +02:00
|
|
|
*/
|
2019-04-17 06:17:24 +02:00
|
|
|
void BLO_library_link_end(Main *mainl,
|
|
|
|
|
BlendHandle **bh,
|
|
|
|
|
int flag,
|
|
|
|
|
Main *bmain,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
const View3D *v3d)
|
2009-09-12 19:54:39 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
FileData *fd = (FileData *)(*bh);
|
|
|
|
|
library_link_end(mainl, &fd, flag, bmain, scene, view_layer, v3d);
|
|
|
|
|
*bh = (BlendHandle *)fd;
|
2007-03-16 05:39:30 +00:00
|
|
|
}
|
|
|
|
|
|
2011-05-18 19:42:30 +00:00
|
|
|
void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)
|
2007-03-16 05:39:30 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return read_struct(fd, bh, blockname);
|
2007-03-16 05:39:30 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-22 18:15:56 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Library Reading
|
|
|
|
|
* \{ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-27 19:25:21 +01:00
|
|
|
static int has_linked_ids_to_read(Main *mainvar)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
ListBase *lbarray[MAX_LIBARRAY];
|
|
|
|
|
int a = set_listbasepointers(mainvar, lbarray);
|
|
|
|
|
|
|
|
|
|
while (a--) {
|
|
|
|
|
for (ID *id = lbarray[a]->first; id; id = id->next) {
|
|
|
|
|
if (id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void read_library_linked_id(
|
|
|
|
|
ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id)
|
|
|
|
|
{
|
|
|
|
|
BHead *bhead = NULL;
|
|
|
|
|
const bool is_valid = BKE_idcode_is_linkable(GS(id->name)) || ((id->tag & LIB_TAG_EXTERN) == 0);
|
|
|
|
|
|
|
|
|
|
if (fd) {
|
|
|
|
|
bhead = find_bhead_from_idname(fd, id->name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!is_valid) {
|
|
|
|
|
blo_reportf_wrap(reports,
|
|
|
|
|
RPT_ERROR,
|
|
|
|
|
TIP_("LIB: %s: '%s' is directly linked from '%s' (parent '%s'), but is a "
|
|
|
|
|
"non-linkable data type"),
|
|
|
|
|
BKE_idcode_to_name(GS(id->name)),
|
|
|
|
|
id->name + 2,
|
|
|
|
|
mainvar->curlib->filepath,
|
|
|
|
|
library_parent_filepath(mainvar->curlib));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
id->tag &= ~LIB_TAG_ID_LINK_PLACEHOLDER;
|
|
|
|
|
|
|
|
|
|
if (bhead) {
|
|
|
|
|
id->tag |= LIB_TAG_NEED_EXPAND;
|
|
|
|
|
// printf("read lib block %s\n", id->name);
|
|
|
|
|
read_libblock(fd, mainvar, bhead, id->tag, r_id);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
blo_reportf_wrap(reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
TIP_("LIB: %s: '%s' missing from '%s', parent '%s'"),
|
|
|
|
|
BKE_idcode_to_name(GS(id->name)),
|
|
|
|
|
id->name + 2,
|
|
|
|
|
mainvar->curlib->filepath,
|
|
|
|
|
library_parent_filepath(mainvar->curlib));
|
|
|
|
|
|
|
|
|
|
/* Generate a placeholder for this ID (simplified version of read_libblock actually...). */
|
|
|
|
|
if (r_id) {
|
|
|
|
|
*r_id = is_valid ? create_placeholder(mainvar, GS(id->name), id->name + 2, id->tag) : NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void read_library_linked_ids(FileData *basefd,
|
|
|
|
|
FileData *fd,
|
|
|
|
|
ListBase *mainlist,
|
|
|
|
|
Main *mainvar)
|
|
|
|
|
{
|
|
|
|
|
GHash *loaded_ids = BLI_ghash_str_new(__func__);
|
|
|
|
|
|
|
|
|
|
ListBase *lbarray[MAX_LIBARRAY];
|
|
|
|
|
int a = set_listbasepointers(mainvar, lbarray);
|
|
|
|
|
|
|
|
|
|
while (a--) {
|
|
|
|
|
ID *id = lbarray[a]->first;
|
|
|
|
|
ListBase pending_free_ids = {NULL};
|
|
|
|
|
|
|
|
|
|
while (id) {
|
|
|
|
|
ID *id_next = id->next;
|
|
|
|
|
if (id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
|
|
|
|
|
BLI_remlink(lbarray[a], id);
|
|
|
|
|
|
|
|
|
|
/* When playing with lib renaming and such, you may end with cases where
|
|
|
|
|
* you have more than one linked ID of the same data-block from same
|
|
|
|
|
* library. This is absolutely horrible, hence we use a ghash to ensure
|
|
|
|
|
* we go back to a single linked data when loading the file. */
|
|
|
|
|
ID **realid = NULL;
|
|
|
|
|
if (!BLI_ghash_ensure_p(loaded_ids, id->name, (void ***)&realid)) {
|
|
|
|
|
read_library_linked_id(basefd->reports, fd, mainvar, id, realid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* realid shall never be NULL - unless some source file/lib is broken
|
|
|
|
|
* (known case: some directly linked shapekey from a missing lib...). */
|
|
|
|
|
/* BLI_assert(*realid != NULL); */
|
|
|
|
|
|
|
|
|
|
/* Now that we have a real ID, replace all pointers to placeholders in
|
2019-06-12 09:04:10 +10:00
|
|
|
* fd->libmap with pointers to the real data-blocks. We do this for all
|
2019-04-17 06:17:24 +02:00
|
|
|
* libraries since multiple might be referencing this ID. */
|
|
|
|
|
change_link_placeholder_to_real_ID_pointer(mainlist, basefd, id, *realid);
|
|
|
|
|
|
|
|
|
|
/* We cannot free old lib-ref placeholder ID here anymore, since we use
|
|
|
|
|
* its name as key in loaded_ids hash. */
|
|
|
|
|
BLI_addtail(&pending_free_ids, id);
|
|
|
|
|
}
|
|
|
|
|
id = id_next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clear GHash and free link placeholder IDs of the current type. */
|
|
|
|
|
BLI_ghash_clear(loaded_ids, NULL, NULL);
|
|
|
|
|
BLI_freelistN(&pending_free_ids);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_ghash_free(loaded_ids, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static FileData *read_library_file_data(FileData *basefd,
|
|
|
|
|
ListBase *mainlist,
|
|
|
|
|
Main *mainl,
|
|
|
|
|
Main *mainptr)
|
|
|
|
|
{
|
|
|
|
|
FileData *fd = mainptr->curlib->filedata;
|
|
|
|
|
|
|
|
|
|
if (fd != NULL) {
|
|
|
|
|
/* File already open. */
|
|
|
|
|
return fd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mainptr->curlib->packedfile) {
|
|
|
|
|
/* Read packed file. */
|
|
|
|
|
PackedFile *pf = mainptr->curlib->packedfile;
|
|
|
|
|
|
|
|
|
|
blo_reportf_wrap(basefd->reports,
|
|
|
|
|
RPT_INFO,
|
|
|
|
|
TIP_("Read packed library: '%s', parent '%s'"),
|
|
|
|
|
mainptr->curlib->name,
|
|
|
|
|
library_parent_filepath(mainptr->curlib));
|
|
|
|
|
fd = blo_filedata_from_memory(pf->data, pf->size, basefd->reports);
|
|
|
|
|
|
|
|
|
|
/* Needed for library_append and read_libraries. */
|
|
|
|
|
BLI_strncpy(fd->relabase, mainptr->curlib->filepath, sizeof(fd->relabase));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Read file on disk. */
|
|
|
|
|
blo_reportf_wrap(basefd->reports,
|
|
|
|
|
RPT_INFO,
|
|
|
|
|
TIP_("Read library: '%s', '%s', parent '%s'"),
|
|
|
|
|
mainptr->curlib->filepath,
|
|
|
|
|
mainptr->curlib->name,
|
|
|
|
|
library_parent_filepath(mainptr->curlib));
|
|
|
|
|
fd = blo_filedata_from_file(mainptr->curlib->filepath, basefd->reports);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fd) {
|
|
|
|
|
/* Share the mainlist, so all libraries are added immediately in a
|
|
|
|
|
* single list. It used to be that all FileData's had their own list,
|
|
|
|
|
* but with indirectly linking this meant we didn't catch duplicate
|
|
|
|
|
* libraries properly. */
|
|
|
|
|
fd->mainlist = mainlist;
|
|
|
|
|
|
|
|
|
|
fd->reports = basefd->reports;
|
|
|
|
|
|
2019-04-22 09:13:00 +10:00
|
|
|
if (fd->libmap) {
|
2019-04-17 06:17:24 +02:00
|
|
|
oldnewmap_free(fd->libmap);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
fd->libmap = oldnewmap_new();
|
|
|
|
|
|
|
|
|
|
mainptr->curlib->filedata = fd;
|
|
|
|
|
mainptr->versionfile = fd->fileversion;
|
|
|
|
|
|
|
|
|
|
/* subversion */
|
|
|
|
|
read_file_version(fd, mainptr);
|
2015-03-11 00:33:44 +11:00
|
|
|
#ifdef USE_GHASH_BHEAD
|
2019-04-17 06:17:24 +02:00
|
|
|
read_file_bhead_idname_map_create(fd);
|
2015-03-11 00:33:44 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mainptr->curlib->filedata = NULL;
|
|
|
|
|
mainptr->curlib->id.tag |= LIB_TAG_MISSING;
|
|
|
|
|
/* Set lib version to current main one... Makes assert later happy. */
|
|
|
|
|
mainptr->versionfile = mainptr->curlib->versionfile = mainl->versionfile;
|
|
|
|
|
mainptr->subversionfile = mainptr->curlib->subversionfile = mainl->subversionfile;
|
|
|
|
|
}
|
2018-06-17 17:06:07 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (fd == NULL) {
|
|
|
|
|
blo_reportf_wrap(
|
|
|
|
|
basefd->reports, RPT_WARNING, TIP_("Cannot find lib '%s'"), mainptr->curlib->filepath);
|
|
|
|
|
}
|
2019-02-27 19:25:21 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return fd;
|
2019-02-27 19:25:21 +01:00
|
|
|
}
|
First step to handle missing libs/datablocks when reading a file.
Idea is, instead of ignoring completely missing linked datablocks, to
create void placeholders for them.
That way, you can work on your file, save it, and find again your missing data once
lib becomes available again. Or you can edit missing lib's path (in Outliner),
save and reload the file, and you are done.
Also, Outliner now shows broken libraries (and placeholders) with a 'broken lib' icon.
Future plans are also to be able to relocate missing libs and reload them at runtime.
Code notes:
- Placeholder ID is just a regular datablock of same type as expected linked one,
with 'default' data, and a LIB_MISSING bitflag set.
- To allow creation of such datablocks, creation of datablocks in BKE was split in two step:
+ Allocation of memory itself.
+ Setting of all internal data to default values.
See also the design task (T43351).
Reviewed by @campbellbarton, thanks a bunch!
Differential Revision: https://developer.blender.org/D1394
2015-10-20 14:44:57 +02:00
|
|
|
|
2019-02-27 19:25:21 +01:00
|
|
|
static void read_libraries(FileData *basefd, ListBase *mainlist)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
Main *mainl = mainlist->first;
|
|
|
|
|
bool do_it = true;
|
|
|
|
|
|
|
|
|
|
/* Expander is now callback function. */
|
|
|
|
|
BLO_main_expander(expand_doit_library);
|
|
|
|
|
|
|
|
|
|
/* At this point the base blend file has been read, and each library blend
|
2019-06-12 09:04:10 +10:00
|
|
|
* encountered so far has a main with placeholders for linked data-blocks.
|
2019-04-17 06:17:24 +02:00
|
|
|
*
|
|
|
|
|
* Now we will read the library blend files and replace the placeholders
|
2019-06-12 09:04:10 +10:00
|
|
|
* with actual data-blocks. We loop over library mains multiple times in
|
|
|
|
|
* case a library needs to link additional data-blocks from another library
|
2019-04-17 06:17:24 +02:00
|
|
|
* that had been read previously. */
|
|
|
|
|
while (do_it) {
|
|
|
|
|
do_it = false;
|
|
|
|
|
|
|
|
|
|
/* Loop over mains of all library blend files encountered so far. Note
|
|
|
|
|
* this list gets longer as more indirectly library blends are found. */
|
|
|
|
|
for (Main *mainptr = mainl->next; mainptr; mainptr = mainptr->next) {
|
2019-06-12 09:04:10 +10:00
|
|
|
/* Does this library have any more linked data-blocks we need to read? */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (has_linked_ids_to_read(mainptr)) {
|
2019-04-22 01:10:29 +10:00
|
|
|
#if 0
|
2019-06-12 09:04:10 +10:00
|
|
|
printf("Reading linked data-blocks from %s (%s)\n",
|
2019-04-22 01:10:29 +10:00
|
|
|
mainptr->curlib->id.name,
|
|
|
|
|
mainptr->curlib->name);
|
|
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* Open file if it has not been done yet. */
|
|
|
|
|
FileData *fd = read_library_file_data(basefd, mainlist, mainl, mainptr);
|
|
|
|
|
|
|
|
|
|
if (fd) {
|
|
|
|
|
do_it = true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Read linked data-locks for each link placeholder, and replace
|
|
|
|
|
* the placeholder with the real data-lock. */
|
2019-04-17 06:17:24 +02:00
|
|
|
read_library_linked_ids(basefd, fd, mainlist, mainptr);
|
|
|
|
|
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Test if linked data-locks need to read further linked data-locks
|
2019-04-17 06:17:24 +02:00
|
|
|
* and create link placeholders for them. */
|
|
|
|
|
BLO_expand_main(fd, mainptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Main *main_newid = BKE_main_new();
|
|
|
|
|
for (Main *mainptr = mainl->next; mainptr; mainptr = mainptr->next) {
|
2019-06-17 12:51:53 +10:00
|
|
|
/* Do versioning for newly added linked data-locks. If no data-locks
|
2019-04-17 06:17:24 +02:00
|
|
|
* were read from a library versionfile will still be zero and we can
|
|
|
|
|
* skip it. */
|
|
|
|
|
if (mainptr->versionfile) {
|
|
|
|
|
/* Split out already existing IDs to avoid them going through
|
|
|
|
|
* do_versions multiple times, which would have bad consequences. */
|
|
|
|
|
split_main_newid(mainptr, main_newid);
|
|
|
|
|
|
|
|
|
|
/* File data can be zero with link/append. */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mainptr->curlib->filedata) {
|
2019-04-17 06:17:24 +02:00
|
|
|
do_versions(mainptr->curlib->filedata, mainptr->curlib, main_newid);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-17 06:17:24 +02:00
|
|
|
do_versions(basefd, NULL, main_newid);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
add_main_to_main(mainptr, main_newid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Lib linking. */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mainptr->curlib->filedata) {
|
2019-04-17 06:17:24 +02:00
|
|
|
lib_link_all(mainptr->curlib->filedata, mainptr);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* Free file data we no longer need. */
|
2019-04-22 09:13:00 +10:00
|
|
|
if (mainptr->curlib->filedata) {
|
2019-04-17 06:17:24 +02:00
|
|
|
blo_filedata_free(mainptr->curlib->filedata);
|
2019-04-22 09:13:00 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
mainptr->curlib->filedata = NULL;
|
|
|
|
|
}
|
|
|
|
|
BKE_main_free(main_newid);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-02-22 18:15:56 +11:00
|
|
|
|
|
|
|
|
/** \} */
|