Merge branch 'master' into blender2.8

This commit is contained in:
2018-01-16 12:07:43 +01:00
5 changed files with 128 additions and 40 deletions

View File

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

View File

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

View File

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

View File

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

View File

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