diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-07-03 15:03:39 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-07-03 15:03:39 +0400 |
commit | 259e78997a50e4be6ed4f2eda7f128c892ad51ca (patch) | |
tree | b6291b39353e3c785bb3c5ce0a01122651e7fcbb /source | |
parent | 1c00740b8155ce2c094189df49ad6ea1ac19b33a (diff) | |
parent | 314a2758505aeba72e2c87f06c5a61c6ceb7773c (diff) |
svn merge ^/trunk/blender -r48489:48527
Diffstat (limited to 'source')
22 files changed, 429 insertions, 97 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 527d85c7cf3..7df491c0fef 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -113,7 +113,7 @@ struct bActionGroup *get_active_actiongroup(struct bAction *act); void set_active_action_group(struct bAction *act, struct bActionGroup *agrp, short select); /* Sync colors used for action/bone group with theme settings */ -void action_group_colors_sync(struct bActionGroup *grp); +void action_group_colors_sync(struct bActionGroup *grp, const struct bActionGroup *ref_grp); /* Add a new action group with the given name to the action */ struct bActionGroup *action_groups_add_new(struct bAction *act, const char name[]); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 8aa25a235a8..2407330a237 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -42,6 +42,7 @@ struct ID; struct Object; struct Mesh; struct MTFace; +struct Scene; /* materials */ @@ -92,6 +93,9 @@ int material_in_material(struct Material *parmat, struct Material *mat); void ramp_blend(int type, float r_col[3], const float fac, const float col[3]); +/* driver update hacks */ +void material_drivers_update(struct Scene *scene, struct Material *mat, float ctime); + /* copy/paste */ void clear_matcopybuf(void); void free_matcopybuf(void); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index b3d2e3371f4..8d1707725b5 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -253,7 +253,7 @@ void set_active_action_group(bAction *act, bActionGroup *agrp, short select) } /* Sync colors used for action/bone group with theme settings */ -void action_group_colors_sync(bActionGroup *grp) +void action_group_colors_sync(bActionGroup *grp, const bActionGroup *ref_grp) { /* only do color copying if using a custom color (i.e. not default color) */ if (grp->customCol) { @@ -265,9 +265,15 @@ void action_group_colors_sync(bActionGroup *grp) memcpy(&grp->cs, col_set, sizeof(ThemeWireColor)); } else { - /* init custom colors with a generic multi-color rgb set, if not initialized already - * (for custom color set) */ - if (grp->cs.solid[0] == 0) { + /* if a reference group is provided, use the custom color from there... */ + if (ref_grp) { + /* assumption: reference group has a color set */ + memcpy(&grp->cs, &ref_grp->cs, sizeof(ThemeWireColor)); + } + /* otherwise, init custom color with a generic/placeholder color set if + * no previous theme color was used that we can just keep using + */ + else if (grp->cs.solid[0] == 0) { /* define for setting colors in theme below */ rgba_char_args_set(grp->cs.solid, 0xff, 0x00, 0x00, 255); rgba_char_args_set(grp->cs.select, 0x81, 0xe6, 0x14, 255); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index a1e67ebd414..692c696803d 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -66,6 +66,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_material.h" #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_object.h" @@ -311,7 +312,7 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node for (fcu = adt->drivers.first; fcu; fcu = fcu->next) { ChannelDriver *driver = fcu->driver; DriverVar *dvar; - int isdata_fcu = isdata || (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")); + int isdata_fcu = (isdata) || (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")); /* loop over variables to get the target relationships */ for (dvar = driver->variables.first; dvar; dvar = dvar->next) { @@ -347,6 +348,48 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node } } +/* XXX: forward def for material driver handling... */ +static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma); + +/* recursive handling for material nodetree drivers */ +static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree) +{ + bNode *n; + + /* nodetree itself */ + if (ntree->adt) { + dag_add_driver_relation(ntree->adt, dag, node, 1); + } + + /* nodetree's nodes... */ + for (n = ntree->nodes.first; n; n = n->next) { + if (n->id && GS(n->id->name) == ID_MA) { + dag_add_material_driver_relations(dag, node, (Material *)n->id); + } + else if (n->type == NODE_GROUP && n->id) { + dag_add_material_nodetree_driver_relations(dag, node, (bNodeTree *)n->id); + } + } +} + +/* recursive handling for material drivers */ +static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma) +{ + /* material itself */ + if (ma->adt) { + dag_add_driver_relation(ma->adt, dag, node, 1); + } + + /* textures */ + // TODO... + //dag_add_texture_driver_relations(DagForest *dag, DagNode *node, ID *id); + + /* material's nodetree */ + if (ma->nodetree) { + dag_add_material_nodetree_driver_relations(dag, node, ma->nodetree); + } +} + static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node) { Base *base; @@ -572,6 +615,20 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O break; } + /* material drivers */ + if (ob->totcol) { + int a; + + for (a = 1; a <= ob->totcol; a++) { + Material *ma = give_current_material(ob, a); + + if (ma) { + /* recursively figure out if there are drivers, and hook these up to this object */ + dag_add_material_driver_relations(dag, node, ma); + } + } + } + /* particles */ psys = ob->particlesystem.first; if (psys) { diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 48d629a2944..ac072832707 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -36,6 +36,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_anim_types.h" #include "DNA_curve_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" @@ -1050,6 +1051,52 @@ int material_in_material(Material *parmat, Material *mat) else return 0; } + + +/* ****************** */ + +/* Update drivers for materials in a nodetree */ +static void material_node_drivers_update(Scene *scene, bNodeTree *ntree, float ctime) +{ + bNode *node; + + /* nodetree itself */ + if (ntree->adt && ntree->adt->drivers.first) { + BKE_animsys_evaluate_animdata(scene, &ntree->id, ntree->adt, ctime, ADT_RECALC_DRIVERS); + } + + /* nodes... */ + for (node = ntree->nodes.first; node; node = node->next) { + if (node->id && GS(node->id->name) == ID_MA) { + /* TODO: prevent infinite recursion here... */ + material_drivers_update(scene, (Material *)node->id, ctime); + } + else if (node->type == NODE_GROUP && node->id) { + material_node_drivers_update(scene, (bNodeTree *)node->id, ctime); + } + } +} + +/* Calculate all drivers for materials + * FIXME: this is really a terrible method which may result in some things being calculated + * multiple times. However, without proper despgraph support for these things, we are forced + * into this sort of thing... + */ +void material_drivers_update(Scene *scene, Material *ma, float ctime) +{ + //if (G.f & G_DEBUG) + // printf("material_drivers_update(%s, %s)\n", scene->id.name, ma->id.name); + + /* material itself */ + if (ma->adt && ma->adt->drivers.first) { + BKE_animsys_evaluate_animdata(scene, &ma->id, ma->adt, ctime, ADT_RECALC_DRIVERS); + } + + /* nodes */ + if (ma->nodetree) { + material_node_drivers_update(scene, ma->nodetree, ctime); + } +} /* ****************** */ #if 0 /* UNUSED */ diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index e3b13ca0f17..6d47575b372 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -3146,19 +3146,17 @@ void BKE_mesh_translate(Mesh *me, float offset[3], int do_keys) } } - void BKE_mesh_ensure_navmesh(Mesh *me) { if (!CustomData_has_layer(&me->pdata, CD_RECAST)) { int i; int numFaces = me->totpoly; int *recastData; - CustomData_add_layer_named(&me->pdata, CD_RECAST, CD_CALLOC, NULL, numFaces, "recastData"); - recastData = (int *)CustomData_get_layer(&me->pdata, CD_RECAST); + recastData = (int *)MEM_mallocN(numFaces * sizeof(int), __func__); for (i = 0; i < numFaces; i++) { recastData[i] = i + 1; } - CustomData_add_layer_named(&me->pdata, CD_RECAST, CD_REFERENCE, recastData, numFaces, "recastData"); + CustomData_add_layer_named(&me->pdata, CD_RECAST, CD_ASSIGN, recastData, numFaces, "recastData"); } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 8fb8d863a8c..b182a7308ac 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2538,7 +2538,7 @@ void BKE_object_handle_update(Scene *scene, Object *ob) printf("recalcdata %s\n", ob->id.name + 2); if (adt) { - /* evaluate drivers */ + /* evaluate drivers - datalevel */ // XXX: for mesh types, should we push this to derivedmesh instead? BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS); } @@ -2595,8 +2595,26 @@ void BKE_object_handle_update(Scene *scene, Object *ob) BKE_lattice_modifiers_calc(scene, ob); break; } - - + + /* related materials */ + /* XXX: without depsgraph tagging, this will always need to be run, which will be slow! + * However, not doing anything (or trying to hack around this lack) is not an option + * anymore, especially due to Cycles [#31834] + */ + if (ob->totcol) { + int a; + + for (a = 1; a <= ob->totcol; a++) { + Material *ma = give_current_material(ob, a); + + if (ma) { + /* recursively update drivers for this material */ + material_drivers_update(scene, ma, ctime); + } + } + } + + /* particles */ if (ob->particlesystem.first) { ParticleSystem *tpsys, *psys; DerivedMesh *dm; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 1d3385eaab6..931937263e4 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -528,8 +528,8 @@ static BMOpDefine bmo_transform_def = { */ static BMOpDefine bmo_object_load_bmesh_def = { "object_load_bmesh", - {{BMO_OP_SLOT_PNT, "scene"}, - {BMO_OP_SLOT_PNT, "object"}, + {{BMO_OP_SLOT_PTR, "scene"}, + {BMO_OP_SLOT_PTR, "object"}, {0, /* null-terminating sentinel */}}, bmo_object_load_bmesh_exec, 0, @@ -543,8 +543,8 @@ static BMOpDefine bmo_object_load_bmesh_def = { */ static BMOpDefine bmo_bmesh_to_mesh_def = { "bmesh_to_mesh", - {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a mesh structure to fill in - {BMO_OP_SLOT_PNT, "object"}, //pointer to an object structure + {{BMO_OP_SLOT_PTR, "mesh"}, //pointer to a mesh structure to fill in + {BMO_OP_SLOT_PTR, "object"}, //pointer to an object structure {BMO_OP_SLOT_BOOL, "notessellation"}, //don't calculate mfaces {0, /* null-terminating sentinel */}}, bmo_bmesh_to_mesh_exec, @@ -559,8 +559,8 @@ static BMOpDefine bmo_bmesh_to_mesh_def = { */ static BMOpDefine bmo_mesh_to_bmesh_def = { "mesh_to_bmesh", - {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a Mesh structure - {BMO_OP_SLOT_PNT, "object"}, //pointer to an Object structure + {{BMO_OP_SLOT_PTR, "mesh"}, //pointer to a Mesh structure + {BMO_OP_SLOT_PTR, "object"}, //pointer to an Object structure {BMO_OP_SLOT_BOOL, "set_shapekey"}, //load active shapekey coordinates into verts {0, /* null-terminating sentinel */}}, bmo_mesh_to_bmesh_exec, @@ -737,7 +737,7 @@ static BMOpDefine bmo_duplicate_def = { {BMO_OP_SLOT_MAPPING, "facemap"}, {BMO_OP_SLOT_MAPPING, "boundarymap"}, {BMO_OP_SLOT_MAPPING, "isovertmap"}, - {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */ + {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */ {0} /* null-terminating sentinel */}, bmo_duplicate_exec, 0 @@ -749,7 +749,7 @@ static BMOpDefine bmo_split_def = { {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, {BMO_OP_SLOT_MAPPING, "boundarymap"}, {BMO_OP_SLOT_MAPPING, "isovertmap"}, - {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */ + {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */ {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */ {0} /* null-terminating sentinel */}, bmo_split_exec, diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 620800cca16..74087c00940 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -99,7 +99,7 @@ enum { /* normally store pointers to object, scene, * _never_ store arrays corresponding to mesh elements with this */ - BMO_OP_SLOT_PNT = 4, + BMO_OP_SLOT_PTR = 4, BMO_OP_SLOT_MAT = 5, BMO_OP_SLOT_VEC = 8, diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index efd02833185..5447e6b5a55 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -378,8 +378,8 @@ void BMO_slot_mat3_set(BMOperator *op, const char *slot_name, float r_mat[3][3]) void BMO_slot_ptr_set(BMOperator *op, const char *slot_name, void *p) { BMOpSlot *slot = BMO_slot_get(op, slot_name); - BLI_assert(slot->slot_type == BMO_OP_SLOT_PNT); - if (!(slot->slot_type == BMO_OP_SLOT_PNT)) + BLI_assert(slot->slot_type == BMO_OP_SLOT_PTR); + if (!(slot->slot_type == BMO_OP_SLOT_PTR)) return; slot->data.p = p; @@ -430,8 +430,8 @@ int BMO_slot_bool_get(BMOperator *op, const char *slot_name) void *BMO_slot_ptr_get(BMOperator *op, const char *slot_name) { BMOpSlot *slot = BMO_slot_get(op, slot_name); - BLI_assert(slot->slot_type == BMO_OP_SLOT_PNT); - if (!(slot->slot_type == BMO_OP_SLOT_PNT)) + BLI_assert(slot->slot_type == BMO_OP_SLOT_PTR); + if (!(slot->slot_type == BMO_OP_SLOT_PTR)) return NULL; return slot->data.p; diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 1a0bd95b7d6..2d3d24b296f 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -485,14 +485,18 @@ bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *area float chunkSizef = this->m_chunkSize; int indexx, indexy; - const int minxchunk = floor(area->xmin / chunkSizef); - const int maxxchunk = ceil((area->xmax - 1) / chunkSizef); - const int minychunk = floor(area->ymin / chunkSizef); - const int maxychunk = ceil((area->ymax - 1) / chunkSizef); + int minxchunk = floor(area->xmin / chunkSizef); + int maxxchunk = ceil((area->xmax - 1) / chunkSizef); + int minychunk = floor(area->ymin / chunkSizef); + int maxychunk = ceil((area->ymax - 1) / chunkSizef); + minxchunk = MAX2(minxchunk, 0); + minychunk = MAX2(minychunk, 0); + maxxchunk = MIN2(maxxchunk, this->m_numberOfXChunks); + maxychunk = MIN2(maxychunk, this->m_numberOfYChunks); bool result = true; - for (indexx = max(minxchunk, 0); indexx < maxxchunk; indexx++) { - for (indexy = max(minychunk, 0); indexy < maxychunk; indexy++) { + for (indexx = minxchunk; indexx < maxxchunk; indexx++) { + for (indexy = minychunk; indexy < maxychunk; indexy++) { if (!scheduleChunkWhenPossible(graph, indexx, indexy)) { result = false; } diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp index 0319e66ee22..bb431f86897 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp @@ -48,13 +48,21 @@ void LensDistortionNode::convertToOperations(ExecutionSystem *graph, CompositorC } else { ScreenLensDistortionOperation *operation = new ScreenLensDistortionOperation(); + operation->setData(data); + if (!(this->getInputSocket(1)->isConnected() || this->getInputSocket(2)->isConnected())) + { + // no nodes connected to the distortion and dispersion. We can precalculate some values + float distortion = ((const bNodeSocketValueFloat *)this->getInputSocket(1)->getbNodeSocket()->default_value)->value; + float dispersion = ((const bNodeSocketValueFloat *)this->getInputSocket(2)->getbNodeSocket()->default_value)->value; + operation->setDistortionAndDispersion(distortion, dispersion); + } this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph); + this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); - operation->setData(data); graph->addOperation(operation); } diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp index 50bac63d6f2..74145c52a5d 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp @@ -36,6 +36,7 @@ ProjectorLensDistortionOperation::ProjectorLensDistortionOperation() : NodeOpera } void ProjectorLensDistortionOperation::initExecution() { + this->initMutex(); this->m_inputProgram = this->getInputSocketReader(0); } @@ -65,6 +66,7 @@ void ProjectorLensDistortionOperation::executePixel(float *color, int x, int y, void ProjectorLensDistortionOperation::deinitExecution() { + this->deinitMutex(); this->m_inputProgram = NULL; } @@ -77,16 +79,18 @@ bool ProjectorLensDistortionOperation::determineDependingAreaOfInterest(rcti *in newInput.xmin = input->xmin - this->m_kr2 - 2; newInput.xmax = input->xmax + this->m_kr2 + 2; } else { - newInput.xmin = 0; + newInput.xmin = input->xmin-7; //(0.25f*20*1)+2 == worse case dispersion newInput.ymin = input->ymin; newInput.ymax = input->ymax; - newInput.xmax = this->m_inputProgram->getWidth(); + newInput.xmax = input->xmax+7; //(0.25f*20*1)+2 == worse case dispersion } return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } void ProjectorLensDistortionOperation::updateDispersion(MemoryBuffer **inputBuffers) { + if (this->m_dispersionAvailable) return; + this->lockMutex(); if (!this->m_dispersionAvailable) { float result[4]; this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST, inputBuffers); @@ -95,4 +99,5 @@ void ProjectorLensDistortionOperation::updateDispersion(MemoryBuffer **inputBuff this->m_kr2 = this->m_kr * 20; this->m_dispersionAvailable = true; } + this->unlockMutex(); } diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index e3abf2aa70b..ea8483734d3 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -42,6 +42,10 @@ ScreenLensDistortionOperation::ScreenLensDistortionOperation() : NodeOperation() void ScreenLensDistortionOperation::initExecution() { this->m_inputProgram = this->getInputSocketReader(0); + this->initMutex(); + this->m_cx = 0.5f * (float)getWidth(); + this->m_cy = 0.5f * (float)getHeight(); + } void *ScreenLensDistortionOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) @@ -139,52 +143,192 @@ void ScreenLensDistortionOperation::executePixel(float *outputColor, int x, int void ScreenLensDistortionOperation::deinitExecution() { + this->deinitMutex(); this->m_inputProgram = NULL; } -void ScreenLensDistortionOperation::determineUV(float result[2], float x, float y) const +void ScreenLensDistortionOperation::determineUV(float result[4], float x, float y, float distortion, float dispersion) +{ + if (!this->m_valuesAvailable) { + updateVariables(distortion, dispersion); + } + determineUV(result, x, y); +} + +void ScreenLensDistortionOperation::determineUV(float result[4], float x, float y) const { + const float height = this->getHeight(); + const float width = this->getWidth(); + + float d, t, ln[6] = {0, 0, 0, 0, 0, 0}; const float v = this->m_sc * ((y + 0.5f) - this->m_cy) / this->m_cy; const float u = this->m_sc * ((x + 0.5f) - this->m_cx) / this->m_cx; - const float t = ABS(MIN3(this->m_kr, this->m_kg, this->m_kb) * 4); - float d = 1.f / (1.f + sqrtf(t)); - result[0] = (u * d + 0.5f) * getWidth() - 0.5f; - result[1] = (v * d + 0.5f) * getHeight() - 0.5f; + const float uv_dot = u * u + v * v; + + if ((t = 1.f - this->m_kr4 * uv_dot) >= 0.f) { + d = 1.f / (1.f + sqrtf(t)); + ln[0] = (u * d + 0.5f) * width - 0.5f, ln[1] = (v * d + 0.5f) * height - 0.5f; + } + if ((t = 1.f - this->m_kg4 * uv_dot) >= 0.f) { + d = 1.f / (1.f + sqrtf(t)); + ln[2] = (u * d + 0.5f) * width - 0.5f, ln[3] = (v * d + 0.5f) * height - 0.5f; + } + if ((t = 1.f - this->m_kb4 * uv_dot) >= 0.f) { + d = 1.f / (1.f + sqrtf(t)); + ln[4] = (u * d + 0.5f) * width - 0.5f, ln[5] = (v * d + 0.5f) * height - 0.5f; + } + + float jit = this->m_data->jit; + float z; + { + // RG + const int dx = ln[2] - ln[0], dy = ln[3] - ln[1]; + const float dsf = sqrtf((float)dx * dx + dy * dy) + 1.f; + const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf); + const float sd = 1.f / (float)ds; + + z = ds; + const float tz = ((float)z + (1.0f)) * sd; + t = 1.0f - (this->m_kr4 + tz * this->m_drg) * uv_dot; + d = 1.0f / (1.f + sqrtf(t)); + const float nx = (u * d + 0.5f) * width - 0.5f; + const float ny = (v * d + 0.5f) * height - 0.5f; + result[0] = nx; + result[1] = ny; + } + { + // GB + const int dx = ln[4] - ln[2], dy = ln[5] - ln[3]; + const float dsf = sqrtf((float)dx * dx + dy * dy) + 1.f; + const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf); + const float sd = 1.f / (float)ds; + + z = ds; + const float tz = ((float)z + (1.0f)) * sd; + t = 1.f - (this->m_kg4 + tz * this->m_dgb) * uv_dot; + d = 1.f / (1.f + sqrtf(t)); + const float nx = (u * d + 0.5f) * width - 0.5f; + const float ny = (v * d + 0.5f) * height - 0.5f; + result[2] = nx; + result[3] = ny; + } } bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInputValue; + newInputValue.xmin = 0; + newInputValue.ymin = 0; + newInputValue.xmax = 2; + newInputValue.ymax = 2; + + NodeOperation *operation = getInputOperation(1); + if (operation->determineDependingAreaOfInterest(&newInputValue, readOperation, output) ) { + return true; + } + + operation = getInputOperation(2); + if (operation->determineDependingAreaOfInterest(&newInputValue, readOperation, output) ) { + return true; + } + +#define MARGIN 64 + +#define UPDATE_INPUT \ + newInput.xmin = MIN3(newInput.xmin, coords[0], coords[2]); \ + newInput.ymin = MIN3(newInput.ymin, coords[1], coords[3]); \ + newInput.xmax = MAX3(newInput.xmax, coords[0], coords[2]); \ + newInput.ymax = MAX3(newInput.ymax, coords[1], coords[3]); + rcti newInput; - newInput.xmin = 0; - newInput.ymin = 0; - newInput.ymax = this->m_inputProgram->getHeight(); - newInput.xmax = this->m_inputProgram->getWidth(); - return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + float margin; + float coords[4]; + if (m_valuesAvailable) { + determineUV(coords, input->xmin, input->ymin); + newInput.xmin = coords[0]; + newInput.ymin = coords[1]; + newInput.xmax = coords[0]; + newInput.ymax = coords[1]; + UPDATE_INPUT; + determineUV(coords, input->xmin, input->ymax); + UPDATE_INPUT; + determineUV(coords, input->xmax, input->ymax); + UPDATE_INPUT; + determineUV(coords, input->xmax, input->ymin); + UPDATE_INPUT; + margin = (ABS(this->m_distortion)+this->m_dispersion)*MARGIN; + } + else + { + determineUV(coords, input->xmin, input->ymin, 1.0f, 1.0f); + newInput.xmin = coords[0]; + newInput.ymin = coords[1]; + newInput.xmax = coords[0]; + newInput.ymax = coords[1]; + UPDATE_INPUT; + determineUV(coords, input->xmin, input->ymin, -1.0f, 1.0f); + UPDATE_INPUT; + + determineUV(coords, input->xmin, input->ymax, -1.0f, 1.0f); + UPDATE_INPUT; + determineUV(coords, input->xmin, input->ymax, 1.0f, 1.0f); + UPDATE_INPUT; + + determineUV(coords, input->xmax, input->ymax, -1.0f, 1.0f); + UPDATE_INPUT; + determineUV(coords, input->xmax, input->ymax, 1.0f, 1.0f); + UPDATE_INPUT; + + determineUV(coords, input->xmax, input->ymin, -1.0f, 1.0f); + UPDATE_INPUT; + determineUV(coords, input->xmax, input->ymin, 1.0f, 1.0f); + UPDATE_INPUT; + margin=MARGIN; + } + +#undef UPDATE_INPUT + newInput.xmin -= margin; + newInput.ymin -= margin; + newInput.xmax += margin; + newInput.ymax += margin; + + operation = getInputOperation(0); + if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) { + return true; + } + return false; +} + +void ScreenLensDistortionOperation::updateVariables(float distortion, float dispersion) +{ + this->m_kg = MAX2(MIN2(distortion, 1.f), -0.999f); + // smaller dispersion range for somewhat more control + const float d = 0.25f * MAX2(MIN2(dispersion, 1.f), 0.f); + this->m_kr = MAX2(MIN2((this->m_kg + d), 1.0f), -0.999f); + this->m_kb = MAX2(MIN2((this->m_kg - d), 1.0f), -0.999f); + this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb); + this->m_sc = (this->m_data->fit && (this->m_maxk > 0.f)) ? (1.f / (1.f + 2.f * this->m_maxk)) : (1.f / (1.f + this->m_maxk)); + this->m_drg = 4.f * (this->m_kg - this->m_kr); + this->m_dgb = 4.f * (this->m_kb - this->m_kg); + + this->m_kr4 = this->m_kr * 4.0f; + this->m_kg4 = this->m_kg * 4.0f; + this->m_kb4 = this->m_kb * 4.0f; } void ScreenLensDistortionOperation::updateDispersionAndDistortion(MemoryBuffer **inputBuffers) { + if (this->m_valuesAvailable) return; + + this->lockMutex(); if (!this->m_valuesAvailable) { float result[4]; this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST, inputBuffers); this->m_distortion = result[0]; this->getInputSocketReader(2)->read(result, 0, 0, COM_PS_NEAREST, inputBuffers); this->m_dispersion = result[0]; - this->m_kg = MAX2(MIN2(this->m_distortion, 1.f), -0.999f); - // smaller dispersion range for somewhat more control - const float d = 0.25f * MAX2(MIN2(this->m_dispersion, 1.f), 0.f); - this->m_kr = MAX2(MIN2((this->m_kg + d), 1.0f), -0.999f); - this->m_kb = MAX2(MIN2((this->m_kg - d), 1.0f), -0.999f); - this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb); - this->m_sc = (this->m_data->fit && (this->m_maxk > 0.f)) ? (1.f / (1.f + 2.f * this->m_maxk)) : (1.f / (1.f + this->m_maxk)); - this->m_drg = 4.f * (this->m_kg - this->m_kr); - this->m_dgb = 4.f * (this->m_kb - this->m_kg); - - this->m_kr4 = this->m_kr * 4.0f; - this->m_kg4 = this->m_kg * 4.0f; - this->m_kb4 = this->m_kb * 4.0f; - this->m_cx = 0.5f * (float)getWidth(); - this->m_cy = 0.5f * (float)getHeight(); + updateVariables(this->m_distortion, this->m_dispersion); this->m_valuesAvailable = true; } + this->unlockMutex(); } diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h index 7e4fda0f755..f80b938818c 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h @@ -66,9 +66,23 @@ public: bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + /** + * @brief Set the distortion and dispersion and precalc some values + * @param distortion + * @param dispersion + */ + void setDistortionAndDispersion(float distortion, float dispersion) { + this->m_distortion = distortion; + this->m_dispersion = dispersion; + updateVariables(distortion, dispersion); + this->m_valuesAvailable = true; + } + private: - void determineUV(float *result, float x, float y) const; + void determineUV(float result[4], float x, float y) const; + void determineUV(float result[4], float x, float y, float distortion, float dispersion); void updateDispersionAndDistortion(MemoryBuffer **inputBuffers); + void updateVariables(float distortion, float dispersion); }; #endif diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 4a5966948ae..672e11ac613 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -416,6 +416,7 @@ static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *pro char *basepath = RNA_path_from_ID_to_property(ptr, prop); char *path = basepath; /* in case no remapping is needed */ + /* Remapping will only be performed in the Properties Editor, as only this * restricts the subspace of options to the 'active' data (a manageable state) */ @@ -426,23 +427,6 @@ static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *pro if (ob && id) { /* only id-types which can be remapped to go through objects should be considered */ switch (GS(id->name)) { - case ID_MA: /* materials */ - { - Material *ma = give_current_material(ob, ob->actcol); - - /* assumes: material will only be shown if it is active objects's active material it's ok */ - if ((ID *)ma == id) { - /* create new path */ - // TODO: use RNA path functions to construct instead? - path = BLI_sprintfN("material_slots[\"%s\"].material.%s", - ma->id.name + 2, basepath); - - /* free old one */ - MEM_freeN(basepath); - } - } - break; - case ID_TE: /* textures */ { Material *ma = give_current_material(ob, ob->actcol); @@ -452,6 +436,7 @@ static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *pro if ((ID *)tex == id) { /* create new path */ // TODO: use RNA path functions to construct step by step instead? + // FIXME: maybe this isn't even needed anymore... path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s", ma->id.name + 2, tex->id.name + 2, basepath); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 6250424d655..267746d5b91 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -201,7 +201,7 @@ FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr, grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1)); if (grp) { agrp->customCol = grp->customCol; - action_group_colors_sync(agrp); + action_group_colors_sync(agrp, grp); } } } diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 48104c9274d..c9851c6a0db 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -237,7 +237,7 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op) /* can be called with C == NULL */ static EnumPropertyItem *group_objects_remove_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { - Object *ob = ED_object_context(C); + Object *ob; EnumPropertyItem *item = NULL, item_tmp = {0}; int totitem = 0; @@ -245,6 +245,8 @@ static EnumPropertyItem *group_objects_remove_itemf(bContext *C, PointerRNA *UNU return DummyRNA_NULL_items; } + ob = ED_object_context(C); + /* check that the action exists */ if (ob) { Group *group = NULL; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 3f77623c928..731304a3b9d 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1312,7 +1312,10 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); - node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr); + /* note: image user properties used directly here, unlike compositor image node, + * which redefines them in the node struct RNA to get proper updates. + */ + node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); } static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index bb8a29f8fe4..35c85f0f40e 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -142,9 +142,9 @@ void rna_ActionGroup_colorset_set(PointerRNA *ptr, int value) /* ensure only valid values get set */ if ((value >= -1) && (value < 21)) { grp->customCol = value; - + /* sync colors stored with theme colors based on the index specified */ - action_group_colors_sync(grp); + action_group_colors_sync(grp, NULL); } } diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index c0ab4abb677..53ddcecd7a8 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -163,6 +163,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" expected an int, not %.200s", self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; } else { slot->data.i = (int)param; @@ -176,12 +177,47 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" expected a float, not %.200s", self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; } else { slot->data.f = param; } break; } + case BMO_OP_SLOT_MAT: + { + /* XXX - BMesh operator design is crappy here, operator slot should define matrix size, + * not the caller! */ + unsigned short size; + if (!MatrixObject_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a Matrix, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + else if (BaseMath_ReadCallback((MatrixObject *)value) == -1) { + return NULL; + } + else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) || + (ELEM(size, 3, 4) == FALSE)) + { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix", + self->opname, slot_name); + return NULL; + } + + BMO_slot_mat_set(&bmop, slot_name, ((MatrixObject *)value)->matrix, size); + break; + } + case BMO_OP_SLOT_VEC: + { + /* passing slot name here is a bit non-descriptive */ + if (mathutils_array_parse(slot->data.vec, 3, 3, value, slot_name) == -1) { + return NULL; + } + break; + } case BMO_OP_SLOT_ELEMENT_BUF: { /* there are many ways we could interpret arguments, for now... @@ -194,12 +230,12 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * * ('VERT', {'TAG'}) */ -#define BPY_BM_GENERIC_MESH_TEST(type_string) \ +#define BPY_BM_GENERIC_MESH_TEST(type_string) \ if (((BPy_BMGeneric *)value)->bm != bm) { \ - PyErr_Format(PyExc_NotImplementedError, \ - "%.200s: keyword \"%.200s\" " type_string " are from another bmesh", \ - self->opname, slot_name, slot->slot_type); \ - return NULL; \ + PyErr_Format(PyExc_NotImplementedError, \ + "%.200s: keyword \"%.200s\" " type_string " are from another bmesh", \ + self->opname, slot_name, slot->slot_type); \ + return NULL; \ } (void)0 if (BPy_BMVertSeq_Check(value)) { @@ -258,6 +294,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * "%.200s: keyword \"%.200s\" expected " "a bmesh sequence, list, (htype, flag) pair, not %.200s", self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; } #undef BPY_BM_GENERIC_MESH_TEST diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 04f9a90f0d2..4bba7ba6838 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -873,7 +873,7 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self) if (path) { if (GS(id->name) == ID_NT) { /* nodetree paths are not accurate */ ret = PyUnicode_FromFormat("bpy.data...%s", - path); + path); } else { ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s", @@ -980,7 +980,7 @@ static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) if (path) { if (GS(id->name) == ID_NT) { /* nodetree paths are not accurate */ ret = PyUnicode_FromFormat("bpy.data...%s", - path); + path); } else { ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s", @@ -2040,12 +2040,12 @@ static int pyrna_prop_collection_bool(BPy_PropertyRNA *self) * This is done for faster lookups. */ #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \ if (keynum < 0) { \ - keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \ - if (keynum_abs < 0) { \ - PyErr_Format(PyExc_IndexError, \ - "bpy_prop_collection[%d]: out of range.", keynum); \ - return ret_err; \ - } \ + keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \ + if (keynum_abs < 0) { \ + PyErr_Format(PyExc_IndexError, \ + "bpy_prop_collection[%d]: out of range.", keynum); \ + return ret_err; \ + } \ } (void)0 @@ -3508,8 +3508,8 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) PyList_Append(ret, linkptr); Py_DECREF(linkptr); } + break; } - break; default: /* should never happen */ BLI_assert(!"Invalid context type"); |