Merge branch 'master' into blender2.8
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include <math.h> // for fabs
|
||||
#include <stdarg.h> /* for va_start/end */
|
||||
#include <time.h> /* for gmtime */
|
||||
#include <ctype.h> /* for isdigit */
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#ifndef WIN32
|
||||
@@ -897,39 +898,42 @@ static void decode_blender_header(FileData *fd)
|
||||
{
|
||||
char header[SIZEOFBLENDERHEADER], num[4];
|
||||
int readsize;
|
||||
|
||||
|
||||
/* read in the header data */
|
||||
readsize = fd->read(fd, header, sizeof(header));
|
||||
|
||||
if (readsize == sizeof(header)) {
|
||||
if (STREQLEN(header, "BLENDER", 7)) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1173,9 +1173,9 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
|
||||
continue;
|
||||
}
|
||||
OperationKey variable_key(dtar->id,
|
||||
DEG_NODE_TYPE_BONE,
|
||||
target_pchan->name,
|
||||
DEG_OPCODE_BONE_DONE);
|
||||
DEG_NODE_TYPE_BONE,
|
||||
target_pchan->name,
|
||||
DEG_OPCODE_BONE_DONE);
|
||||
if (is_same_bone_dependency(variable_key, self_key)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1200,10 +1200,12 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
|
||||
if (RNA_pointer_is_null(&variable_key.ptr)) {
|
||||
continue;
|
||||
}
|
||||
if (is_same_bone_dependency(variable_key, self_key)) {
|
||||
if (is_same_bone_dependency(variable_key, self_key) ||
|
||||
is_nodetree_node_dependency(variable_key, self_key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
add_relation(variable_key, driver_key, "RNA Bone -> Driver");
|
||||
add_relation(variable_key, driver_key, "RNA Target -> Driver");
|
||||
}
|
||||
else {
|
||||
if (dtar->id == id) {
|
||||
|
||||
@@ -297,9 +297,22 @@ protected:
|
||||
DepsNodeHandle create_node_handle(const KeyType& key,
|
||||
const char *default_name = "");
|
||||
|
||||
/* Check whether two keys correponds to the same bone from same armature.
|
||||
*
|
||||
* This is used by drivers relations builder to avoid possible fake
|
||||
* dependency cycle when one bone property drives another property of the
|
||||
* same bone.
|
||||
*/
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
bool is_same_bone_dependency(const KeyFrom& key_from, const KeyTo& key_to);
|
||||
|
||||
/* Similar to above, but used to check whether driver is using node from
|
||||
* the same node tree as a driver variable.
|
||||
*/
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
bool is_nodetree_node_dependency(const KeyFrom& key_from,
|
||||
const KeyTo& key_to);
|
||||
|
||||
private:
|
||||
/* State which never changes, same for the whole builder time. */
|
||||
Main *bmain_;
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
|
||||
extern "C" {
|
||||
#include "DNA_ID.h"
|
||||
}
|
||||
|
||||
namespace DEG {
|
||||
|
||||
template <typename KeyType>
|
||||
@@ -140,9 +146,14 @@ bool DepsgraphRelationBuilder::is_same_bone_dependency(const KeyFrom& key_from,
|
||||
if (op_from == NULL || op_to == NULL) {
|
||||
return false;
|
||||
}
|
||||
/* Different armatures, bone can't be the same. */
|
||||
if (op_from->owner->owner != op_to->owner->owner) {
|
||||
return false;
|
||||
}
|
||||
/* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */
|
||||
if (!(op_from->opcode == DEG_OPCODE_BONE_DONE &&
|
||||
op_to->opcode == DEG_OPCODE_BONE_LOCAL)) {
|
||||
op_to->opcode == DEG_OPCODE_BONE_LOCAL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/* ... BUT, we also need to check if it's same bone. */
|
||||
@@ -152,4 +163,37 @@ bool DepsgraphRelationBuilder::is_same_bone_dependency(const KeyFrom& key_from,
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
bool DepsgraphRelationBuilder::is_nodetree_node_dependency(
|
||||
const KeyFrom& key_from,
|
||||
const KeyTo& key_to)
|
||||
{
|
||||
/* Get operations for requested keys. */
|
||||
DepsNode *node_from = get_node(key_from);
|
||||
DepsNode *node_to = get_node(key_to);
|
||||
if (node_from == NULL || node_to == NULL) {
|
||||
return false;
|
||||
}
|
||||
OperationDepsNode *op_from = node_from->get_exit_operation();
|
||||
OperationDepsNode *op_to = node_to->get_entry_operation();
|
||||
if (op_from == NULL || op_to == NULL) {
|
||||
return false;
|
||||
}
|
||||
/* Check if this is actually a node tree. */
|
||||
if (GS(op_from->owner->owner->id->name) != ID_NT) {
|
||||
return false;
|
||||
}
|
||||
/* Different node trees. */
|
||||
if (op_from->owner->owner != op_to->owner->owner) {
|
||||
return false;
|
||||
}
|
||||
/* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */
|
||||
if (!(op_from->opcode == DEG_OPCODE_PARAMETERS_EVAL &&
|
||||
op_to->opcode == DEG_OPCODE_PARAMETERS_EVAL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
|
||||
@@ -31,12 +31,14 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_easing.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_library.h"
|
||||
@@ -63,6 +65,15 @@
|
||||
|
||||
/* ****************** Relations helpers *********************** */
|
||||
|
||||
static bool ntree_has_drivers(bNodeTree *ntree)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(&ntree->id);
|
||||
if (adt == NULL) {
|
||||
return false;
|
||||
}
|
||||
return !BLI_listbase_is_empty(&adt->drivers);
|
||||
}
|
||||
|
||||
static bool ntree_check_nodes_connected_dfs(bNodeTree *ntree,
|
||||
bNode *from,
|
||||
bNode *to)
|
||||
@@ -134,6 +145,14 @@ static bool node_group_has_output(bNode *node)
|
||||
|
||||
bool node_connected_to_output(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
/* Special case for drivers: if node tree has any drivers we assume it is
|
||||
* always to be tagged for update when node changes. Otherwise we will be
|
||||
* doomed to do some deep and nasty deep search of indirect dependencies,
|
||||
* which will be too complicated without real benefit.
|
||||
*/
|
||||
if (ntree_has_drivers(ntree)) {
|
||||
return true;
|
||||
}
|
||||
for (bNode *current_node = ntree->nodes.first;
|
||||
current_node != NULL;
|
||||
current_node = current_node->next)
|
||||
@@ -144,11 +163,17 @@ bool node_connected_to_output(bNodeTree *ntree, bNode *node)
|
||||
* We could make check more grained here by taking which socket the node
|
||||
* is connected to and so eventually.
|
||||
*/
|
||||
if (current_node->type == NODE_GROUP &&
|
||||
ntree_check_nodes_connected(ntree, node, current_node) &&
|
||||
node_group_has_output(current_node))
|
||||
{
|
||||
return true;
|
||||
if (current_node->type == NODE_GROUP) {
|
||||
if (current_node->id != NULL &&
|
||||
ntree_has_drivers((bNodeTree *)current_node->id))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (ntree_check_nodes_connected(ntree, node, current_node) &&
|
||||
node_group_has_output(current_node))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (current_node->flag & NODE_DO_OUTPUT) {
|
||||
if (ntree_check_nodes_connected(ntree, node, current_node)) {
|
||||
|
||||
Reference in New Issue
Block a user