diff options
Diffstat (limited to 'source/blender')
85 files changed, 991 insertions, 609 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index f5f6cab60a2..b4550584b4d 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -651,7 +651,7 @@ DerivedMesh *getEditDerivedBMesh(struct BMEditMesh *em, struct Object *ob, DerivedMesh *mesh_create_derived_index_render(struct Scene *scene, struct Object *ob, CustomDataMask dataMask, int index); /* same as above but wont use render settings */ -DerivedMesh *mesh_create_derived(struct Mesh *me, struct Object *ob, float (*vertCos)[3]); +DerivedMesh *mesh_create_derived(struct Mesh *me, float (*vertCos)[3]); DerivedMesh *mesh_create_derived_view(struct Scene *scene, struct Object *ob, CustomDataMask dataMask); DerivedMesh *mesh_create_derived_no_deform(struct Scene *scene, struct Object *ob, diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 3ac5c8c9a76..9068be970b5 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -134,13 +134,16 @@ void action_groups_clear_tempflags(struct bAction *act); /* Pose API ----------------- */ void BKE_pose_channel_free(struct bPoseChannel *pchan); +void BKE_pose_channel_free_ex(struct bPoseChannel *pchan, bool do_id_user); void BKE_pose_channels_free(struct bPose *pose); +void BKE_pose_channels_free_ex(struct bPose *pose, bool do_id_user); void BKE_pose_channels_hash_make(struct bPose *pose); void BKE_pose_channels_hash_free(struct bPose *pose); void BKE_pose_free(struct bPose *pose); +void BKE_pose_free_ex(struct bPose *pose, bool do_id_user); void BKE_pose_copy_data(struct bPose **dst, struct bPose *src, const bool copy_constraints); void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from); struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name); diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index 560617db474..7006b2904ac 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -53,7 +53,7 @@ int CDDM_Check(struct DerivedMesh *dm); * original data in Mesh, but it is safe to apply vertex coordinates or * calculate normals as those functions will automatically create new * data to not overwrite the original */ -struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh, struct Object *ob); +struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh); struct DerivedMesh *CDDM_from_bmesh(struct BMesh *bm, int use_mdisps); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index bdfa0973838..cad3f264fb8 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -74,6 +74,7 @@ struct ListBase *which_libbase(struct Main *mainlib, short type); int set_listbasepointers(struct Main *main, struct ListBase **lb); void BKE_libblock_free(struct ListBase *lb, void *idv); +void BKE_libblock_free_ex(struct ListBase *lb, void *idv, bool do_id_user); void BKE_libblock_free_us(struct ListBase *lb, void *idv); void BKE_libblock_free_data(struct ID *id); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index b5e75729659..6ed8406d9a4 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -66,6 +66,7 @@ void BKE_object_free_curve_cache(struct Object *ob); void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob); void BKE_object_free(struct Object *ob); +void BKE_object_free_ex(struct Object *ob, bool do_id_user); void BKE_object_free_derived_caches(struct Object *ob); void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *hmd); diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index 34ed4f2c8b1..86be3bfe770 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -67,10 +67,7 @@ struct RigidBodyWorld *BKE_rigidbody_world_copy(struct RigidBodyWorld *rbw); void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw); /* 'validate' (i.e. make new or replace old) Physics-Engine objects */ -void BKE_rigidbody_validate_sim_world(struct Scene *scene, struct RigidBodyWorld *rbw, short rebuild); -void BKE_rigidbody_validate_sim_object(struct RigidBodyWorld *rbw, struct Object *ob, short rebuild); -void BKE_rigidbody_validate_sim_shape(struct Object *ob, short rebuild); -void BKE_rigidbody_validate_sim_constraint(struct RigidBodyWorld *rbw, struct Object *ob, short rebuild); +void BKE_rigidbody_validate_sim_world(struct Scene *scene, struct RigidBodyWorld *rbw, bool rebuild); /* -------------- */ /* Utilities */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index fa0f6e3af28..b48b7629d41 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -838,9 +838,9 @@ void DM_interp_poly_data(DerivedMesh *source, DerivedMesh *dest, } /// -DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3]) +DerivedMesh *mesh_create_derived(Mesh *me, float (*vertCos)[3]) { - DerivedMesh *dm = CDDM_from_mesh(me, ob); + DerivedMesh *dm = CDDM_from_mesh(me); if (!dm) return NULL; @@ -874,7 +874,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, float (*deformedVerts)[3] = BKE_mesh_vertexCos_get(me, &numVerts); modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, 0); - dm = mesh_create_derived(me, ob, deformedVerts); + dm = mesh_create_derived(me, deformedVerts); if (build_shapekey_layers) add_shapekey_layers(dm, me, ob); @@ -882,7 +882,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, MEM_freeN(deformedVerts); } else { - DerivedMesh *tdm = mesh_create_derived(me, ob, NULL); + DerivedMesh *tdm = mesh_create_derived(me, NULL); if (build_shapekey_layers) add_shapekey_layers(tdm, me, ob); @@ -953,7 +953,7 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int lay int free; if (em) dm = CDDM_from_editbmesh(em, FALSE, FALSE); - else dm = CDDM_from_mesh(me, ob); + else dm = CDDM_from_mesh(me); orco = get_orco_coords_dm(ob, em, layer, &free); @@ -1533,7 +1533,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos * coordinates (vpaint, etc.) */ if (deform_r) { - *deform_r = CDDM_from_mesh(me, ob); + *deform_r = CDDM_from_mesh(me); if (build_shapekey_layers) add_shapekey_layers(dm, me, ob); @@ -1659,7 +1659,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } } else { - dm = CDDM_from_mesh(me, ob); + dm = CDDM_from_mesh(me); ASSERT_IS_VALID_DM(dm); if (build_shapekey_layers) @@ -1823,7 +1823,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos #endif } else { - finaldm = CDDM_from_mesh(me, ob); + finaldm = CDDM_from_mesh(me); if (build_shapekey_layers) { add_shapekey_layers(finaldm, me, ob); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index c91fae2adbc..4991f1ce225 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -714,10 +714,12 @@ void BKE_pose_channels_hash_free(bPose *pose) * Deallocates a pose channel. * Does not free the pose channel itself. */ -void BKE_pose_channel_free(bPoseChannel *pchan) +void BKE_pose_channel_free_ex(bPoseChannel *pchan, bool do_id_user) { if (pchan->custom) { - id_us_min(&pchan->custom->id); + if (do_id_user) { + id_us_min(&pchan->custom->id); + } pchan->custom = NULL; } @@ -734,17 +736,22 @@ void BKE_pose_channel_free(bPoseChannel *pchan) } } +void BKE_pose_channel_free(bPoseChannel *pchan) +{ + BKE_pose_channel_free_ex(pchan, true); +} + /** * Removes and deallocates all channels from a pose. * Does not free the pose itself. */ -void BKE_pose_channels_free(bPose *pose) +void BKE_pose_channels_free_ex(bPose *pose, bool do_id_user) { bPoseChannel *pchan; if (pose->chanbase.first) { for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) - BKE_pose_channel_free(pchan); + BKE_pose_channel_free_ex(pchan, do_id_user); BLI_freelistN(&pose->chanbase); } @@ -752,14 +759,19 @@ void BKE_pose_channels_free(bPose *pose) BKE_pose_channels_hash_free(pose); } +void BKE_pose_channels_free(bPose *pose) +{ + BKE_pose_channels_free_ex(pose, true); +} + /** * Removes and deallocates all data from a pose, and also frees the pose. */ -void BKE_pose_free(bPose *pose) +void BKE_pose_free_ex(bPose *pose, bool do_id_user) { if (pose) { /* free pose-channels */ - BKE_pose_channels_free(pose); + BKE_pose_channels_free_ex(pose, do_id_user); /* free pose-groups */ if (pose->agroups.first) @@ -777,6 +789,11 @@ void BKE_pose_free(bPose *pose) } } +void BKE_pose_free(bPose *pose) +{ + BKE_pose_free_ex(pose, true); +} + static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan) { bConstraint *pcon, *con; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index d9447e51aa3..32914dedde1 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1802,9 +1802,9 @@ DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops return dm; } -DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) +DerivedMesh *CDDM_from_mesh(Mesh *mesh) { - CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm"); + CDDerivedMesh *cddm = cdDM_create(__func__); DerivedMesh *dm = &cddm->dm; CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS); int alloctype; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 8074d6bceec..6376878c664 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2735,7 +2735,7 @@ void DAG_threaded_update_begin(Scene *scene, void (*func)(void *node, void *user_data), void *user_data) { - DagNode *node, *root_node; + DagNode *node; /* We reset num_pending_parents to zero first and tag node as not scheduled yet... */ for (node = scene->theDag->DagNode.first; node; node = node->next) { @@ -2756,10 +2756,15 @@ void DAG_threaded_update_begin(Scene *scene, } } - /* Add root node to the queue. */ - root_node = scene->theDag->DagNode.first; - root_node->scheduled = true; - func(root_node, user_data); + /* Add root nodes to the queue. */ + BLI_spin_lock(&threaded_update_lock); + for (node = scene->theDag->DagNode.first; node; node = node->next) { + if (node->num_pending_parents == 0) { + node->scheduled = true; + func(node, user_data); + } + } + BLI_spin_unlock(&threaded_update_lock); } /* This function is called when handling node is done. diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 00dee2611c1..43bd6a0b36c 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -868,7 +868,7 @@ void BKE_libblock_free_data(ID *id) } /* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */ -void BKE_libblock_free(ListBase *lb, void *idv) +void BKE_libblock_free_ex(ListBase *lb, void *idv, bool do_id_user) { Main *bmain = G.main; /* should eventually be an arg */ ID *id = idv; @@ -885,7 +885,7 @@ void BKE_libblock_free(ListBase *lb, void *idv) BKE_library_free((Library *)id); break; case ID_OB: - BKE_object_free((Object *)id); + BKE_object_free_ex((Object *)id, do_id_user); break; case ID_ME: BKE_mesh_free((Mesh *)id, 1); @@ -951,7 +951,7 @@ void BKE_libblock_free(ListBase *lb, void *idv) BKE_action_free((bAction *)id); break; case ID_NT: - ntreeFreeTree((bNodeTree *)id); + ntreeFreeTree_ex((bNodeTree *)id, do_id_user); break; case ID_BR: BKE_brush_free((Brush *)id); @@ -988,6 +988,11 @@ void BKE_libblock_free(ListBase *lb, void *idv) MEM_freeN(id); } +void BKE_libblock_free(ListBase *lb, void *idv) +{ + BKE_libblock_free_ex(lb, idv, true); +} + void BKE_libblock_free_us(ListBase *lb, void *idv) /* test users */ { ID *id = idv; @@ -1025,44 +1030,44 @@ void free_main(Main *mainvar) while ( (id = lb->first) ) { #if 1 - BKE_libblock_free(lb, id); + BKE_libblock_free_ex(lb, id, false); #else /* errors freeing ID's can be hard to track down, * enable this so valgrind will give the line number in its error log */ switch (a) { - case 0: BKE_libblock_free(lb, id); break; - case 1: BKE_libblock_free(lb, id); break; - case 2: BKE_libblock_free(lb, id); break; - case 3: BKE_libblock_free(lb, id); break; - case 4: BKE_libblock_free(lb, id); break; - case 5: BKE_libblock_free(lb, id); break; - case 6: BKE_libblock_free(lb, id); break; - case 7: BKE_libblock_free(lb, id); break; - case 8: BKE_libblock_free(lb, id); break; - case 9: BKE_libblock_free(lb, id); break; - case 10: BKE_libblock_free(lb, id); break; - case 11: BKE_libblock_free(lb, id); break; - case 12: BKE_libblock_free(lb, id); break; - case 13: BKE_libblock_free(lb, id); break; - case 14: BKE_libblock_free(lb, id); break; - case 15: BKE_libblock_free(lb, id); break; - case 16: BKE_libblock_free(lb, id); break; - case 17: BKE_libblock_free(lb, id); break; - case 18: BKE_libblock_free(lb, id); break; - case 19: BKE_libblock_free(lb, id); break; - case 20: BKE_libblock_free(lb, id); break; - case 21: BKE_libblock_free(lb, id); break; - case 22: BKE_libblock_free(lb, id); break; - case 23: BKE_libblock_free(lb, id); break; - case 24: BKE_libblock_free(lb, id); break; - case 25: BKE_libblock_free(lb, id); break; - case 26: BKE_libblock_free(lb, id); break; - case 27: BKE_libblock_free(lb, id); break; - case 28: BKE_libblock_free(lb, id); break; - case 29: BKE_libblock_free(lb, id); break; - case 30: BKE_libblock_free(lb, id); break; - case 31: BKE_libblock_free(lb, id); break; - case 32: BKE_libblock_free(lb, id); break; + case 0: BKE_libblock_free_ex(lb, id, false); break; + case 1: BKE_libblock_free_ex(lb, id, false); break; + case 2: BKE_libblock_free_ex(lb, id, false); break; + case 3: BKE_libblock_free_ex(lb, id, false); break; + case 4: BKE_libblock_free_ex(lb, id, false); break; + case 5: BKE_libblock_free_ex(lb, id, false); break; + case 6: BKE_libblock_free_ex(lb, id, false); break; + case 7: BKE_libblock_free_ex(lb, id, false); break; + case 8: BKE_libblock_free_ex(lb, id, false); break; + case 9: BKE_libblock_free_ex(lb, id, false); break; + case 10: BKE_libblock_free_ex(lb, id, false); break; + case 11: BKE_libblock_free_ex(lb, id, false); break; + case 12: BKE_libblock_free_ex(lb, id, false); break; + case 13: BKE_libblock_free_ex(lb, id, false); break; + case 14: BKE_libblock_free_ex(lb, id, false); break; + case 15: BKE_libblock_free_ex(lb, id, false); break; + case 16: BKE_libblock_free_ex(lb, id, false); break; + case 17: BKE_libblock_free_ex(lb, id, false); break; + case 18: BKE_libblock_free_ex(lb, id, false); break; + case 19: BKE_libblock_free_ex(lb, id, false); break; + case 20: BKE_libblock_free_ex(lb, id, false); break; + case 21: BKE_libblock_free_ex(lb, id, false); break; + case 22: BKE_libblock_free_ex(lb, id, false); break; + case 23: BKE_libblock_free_ex(lb, id, false); break; + case 24: BKE_libblock_free_ex(lb, id, false); break; + case 25: BKE_libblock_free_ex(lb, id, false); break; + case 26: BKE_libblock_free_ex(lb, id, false); break; + case 27: BKE_libblock_free_ex(lb, id, false); break; + case 28: BKE_libblock_free_ex(lb, id, false); break; + case 29: BKE_libblock_free_ex(lb, id, false); break; + case 30: BKE_libblock_free_ex(lb, id, false); break; + case 31: BKE_libblock_free_ex(lb, id, false); break; + case 32: BKE_libblock_free_ex(lb, id, false); break; default: BLI_assert(0); break; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 722ea536ed2..2189fbd2f55 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -769,7 +769,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob) /* XXX - probably not necessary to regenerate the cddm so much? */ /* generate highest level with displacements */ - cddm = CDDM_from_mesh(me, NULL); + cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0, 0); cddm->release(cddm); @@ -782,7 +782,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob) /* heuristic to produce a better-fitting base mesh */ - cddm = CDDM_from_mesh(me, NULL); + cddm = CDDM_from_mesh(me); pmap = cddm->getPolyMap(ob, cddm); origco = MEM_callocN(sizeof(float) * 3 * me->totvert, "multires apply base origco"); for (i = 0; i < me->totvert; ++i) @@ -865,7 +865,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob) BKE_mesh_calc_normals(me); /* subdivide the mesh to highest level without displacements */ - cddm = CDDM_from_mesh(me, NULL); + cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0); cddm->release(cddm); @@ -902,7 +902,7 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); /* create subsurf DM from original mesh at high level */ - cddm = CDDM_from_mesh(me, NULL); + cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); ss = ((CCGDerivedMesh *)highdm)->ss; @@ -1174,7 +1174,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) /* create subsurf DM from original mesh at high level */ if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform); - else cddm = CDDM_from_mesh(me, NULL); + else cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); @@ -1236,7 +1236,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform); - else cddm = CDDM_from_mesh(me, NULL); + else cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); @@ -2114,7 +2114,7 @@ void multires_load_old(Object *ob, Mesh *me) multiresModifier_subdivide(mmd, ob, 1, 0); mmd->lvl = mmd->totlvl; - orig = CDDM_from_mesh(me, NULL); + orig = CDDM_from_mesh(me); /* XXX We *must* alloc paint mask here, else we have some kind of mismatch in * multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the * reference subsurfed dm with this option, before calling multiresModifier_disp_run(), diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index d0ce56332a7..977aa016d2e 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1714,8 +1714,11 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) } } - /* XXX not nice, but needed to free localized node groups properly */ - free_localized_node_groups(ntree); + /* when freeing main, this would check other ntree's which may have been freed, see [#37939] */ + if (do_id_user) { + /* XXX not nice, but needed to free localized node groups properly */ + free_localized_node_groups(ntree); + } /* unregister associated RNA types */ ntreeInterfaceTypeFree(ntree); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 26684d19507..711065b0e8b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -321,7 +321,7 @@ void BKE_object_free_derived_caches(Object *ob) } /* do not free object itself */ -void BKE_object_free(Object *ob) +void BKE_object_free_ex(Object *ob, bool do_id_user) { int a; @@ -364,7 +364,7 @@ void BKE_object_free(Object *ob) if (ob->defbase.first) BLI_freelistN(&ob->defbase); if (ob->pose) - BKE_pose_free(ob->pose); + BKE_pose_free_ex(ob->pose, do_id_user); if (ob->mpath) animviz_free_motionpath(ob->mpath); BKE_bproperty_free_list(&ob->prop); @@ -399,6 +399,11 @@ void BKE_object_free(Object *ob) } } +void BKE_object_free(Object *ob) +{ + BKE_object_free_ex(ob, true); +} + static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin) { Object *unlinkOb = userData; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 0f5707f9a60..37ca502970d 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1106,7 +1106,7 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D /* Grid distribution */ if (part->distr==PART_DISTR_GRID && from != PART_FROM_VERT) { BLI_srandom(31415926 + psys->seed); - dm= CDDM_from_mesh((Mesh*)ob->data, ob); + dm= CDDM_from_mesh((Mesh*)ob->data); DM_ensure_tessface(dm); distribute_grid(dm,psys); dm->release(dm); @@ -1145,7 +1145,7 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D if (psys->part->use_modifier_stack) dm = finaldm; else - dm= CDDM_from_mesh((Mesh*)ob->data, ob); + dm= CDDM_from_mesh((Mesh*)ob->data); /* BMESH ONLY, for verts we don't care about tessfaces */ if (from != PART_FROM_VERT) { diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 600805e71ce..271a9a91f95 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -225,26 +225,47 @@ void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc) /* ************************************** */ /* Setup Utilities - Validate Sim Instances */ +/* get the appropriate DerivedMesh based on rigid body mesh source */ +static DerivedMesh *rigidbody_get_mesh(Object *ob) +{ + if (ob->rigidbody_object->mesh_source == RBO_MESH_DEFORM) { + return ob->derivedDeform; + } + else if (ob->rigidbody_object->mesh_source == RBO_MESH_FINAL) { + return ob->derivedFinal; + } + else { + return CDDM_from_mesh(ob->data); + } +} + /* create collision shape of mesh - convex hull */ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, float margin, bool *can_embed) { rbCollisionShape *shape = NULL; - Mesh *me = NULL; + DerivedMesh *dm = NULL; + MVert *mvert = NULL; + int totvert = 0; if (ob->type == OB_MESH && ob->data) { - me = ob->data; + dm = rigidbody_get_mesh(ob); + mvert = (dm) ? dm->getVertArray(dm) : NULL; + totvert = (dm) ? dm->getNumVerts(dm) : 0; } else { printf("ERROR: cannot make Convex Hull collision shape for non-Mesh object\n"); } - if (me && me->totvert) { - shape = RB_shape_new_convex_hull((float *)me->mvert, sizeof(MVert), me->totvert, margin, can_embed); + if (totvert) { + shape = RB_shape_new_convex_hull((float *)mvert, sizeof(MVert), totvert, margin, can_embed); } else { printf("ERROR: no vertices to define Convex Hull collision shape with\n"); } + if (dm && ob->rigidbody_object->mesh_source == RBO_MESH_BASE) + dm->release(dm); + return shape; } @@ -256,14 +277,20 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) rbCollisionShape *shape = NULL; if (ob->type == OB_MESH) { - DerivedMesh *dm = CDDM_from_mesh(ob->data, ob); - + DerivedMesh *dm = NULL; MVert *mvert; MFace *mface; int totvert; int totface; + int tottris = 0; + int triangle_index = 0; + + dm = rigidbody_get_mesh(ob); /* ensure mesh validity, then grab data */ + if (dm == NULL) + return NULL; + DM_ensure_tessface(dm); mvert = (dm) ? dm->getVertArray(dm) : NULL; @@ -278,32 +305,32 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) else { rbMeshData *mdata; int i; + + /* count triangles */ + for (i = 0; i < totface; i++) { + (mface[i].v4) ? (tottris += 2) : (tottris += 1); + } /* init mesh data for collision shape */ - mdata = RB_trimesh_data_new(); + mdata = RB_trimesh_data_new(tottris, totvert); + + RB_trimesh_add_vertices(mdata, (float*)mvert, totvert, sizeof(MVert)); /* loop over all faces, adding them as triangles to the collision shape * (so for some faces, more than triangle will get added) */ for (i = 0; (i < totface) && (mface) && (mvert); i++, mface++) { /* add first triangle - verts 1,2,3 */ - { - MVert *va = (mface->v1 < totvert) ? (mvert + mface->v1) : (mvert); - MVert *vb = (mface->v2 < totvert) ? (mvert + mface->v2) : (mvert); - MVert *vc = (mface->v3 < totvert) ? (mvert + mface->v3) : (mvert); - - RB_trimesh_add_triangle(mdata, va->co, vb->co, vc->co); - } + RB_trimesh_add_triangle_indices(mdata, triangle_index, mface->v1, mface->v2, mface->v3); + triangle_index++; /* add second triangle if needed - verts 1,3,4 */ if (mface->v4) { - MVert *va = (mface->v1 < totvert) ? (mvert + mface->v1) : (mvert); - MVert *vb = (mface->v3 < totvert) ? (mvert + mface->v3) : (mvert); - MVert *vc = (mface->v4 < totvert) ? (mvert + mface->v4) : (mvert); - - RB_trimesh_add_triangle(mdata, va->co, vb->co, vc->co); + RB_trimesh_add_triangle_indices(mdata, triangle_index, mface->v1, mface->v3, mface->v4); + triangle_index++; } } + RB_trimesh_finish(mdata); /* construct collision shape * @@ -323,7 +350,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) } /* cleanup temp data */ - if (dm) { + if (dm && ob->rigidbody_object->mesh_source == RBO_MESH_BASE) { dm->release(dm); } } @@ -337,7 +364,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) /* Create new physics sim collision shape for object and store it, * or remove the existing one first and replace... */ -void BKE_rigidbody_validate_sim_shape(Object *ob, short rebuild) +static void rigidbody_validate_sim_shape(Object *ob, bool rebuild) { RigidBodyOb *rbo = ob->rigidbody_object; rbCollisionShape *new_shape = NULL; @@ -425,9 +452,10 @@ void BKE_rigidbody_validate_sim_shape(Object *ob, short rebuild) rbo->physics_shape = new_shape; RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo)); } - else { /* otherwise fall back to box shape */ + /* use box shape if we can't fall back to old shape */ + else if (rbo->physics_shape == NULL) { rbo->shape = RB_SHAPE_BOX; - BKE_rigidbody_validate_sim_shape(ob, true); + rigidbody_validate_sim_shape(ob, true); } } @@ -436,7 +464,7 @@ void BKE_rigidbody_validate_sim_shape(Object *ob, short rebuild) /* Create physics sim representation of object given RigidBody settings * < rebuild: even if an instance already exists, replace it */ -void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short rebuild) +static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool rebuild) { RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL; float loc[3]; @@ -451,10 +479,9 @@ void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short re /* make sure collision shape exists */ /* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects, but it's needed for constraints to update correctly */ if (rbo->physics_shape == NULL || rebuild) - BKE_rigidbody_validate_sim_shape(ob, true); + rigidbody_validate_sim_shape(ob, true); - if (rbo->physics_object) { - if (rebuild == false) + if (rbo->physics_object && rebuild == false) { RB_dworld_remove_body(rbw->physics_world, rbo->physics_object); } if (!rbo->physics_object || rebuild) { @@ -500,7 +527,7 @@ void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short re /* Create physics sim representation of constraint given rigid body constraint settings * < rebuild: even if an instance already exists, replace it */ -void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, short rebuild) +static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, bool rebuild) { RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL; float loc[3]; @@ -527,8 +554,7 @@ void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, shor return; } - if (rbc->physics_constraint) { - if (rebuild == false) + if (rbc->physics_constraint && rebuild == false) { RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint); } if (rbc->physics_constraint == NULL || rebuild) { @@ -672,7 +698,7 @@ void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, shor /* Create physics sim world given RigidBody world settings */ // NOTE: this does NOT update object references that the scene uses, in case those aren't ready yet! -void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, short rebuild) +void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) { /* sanity checks */ if (rbw == NULL) @@ -798,6 +824,8 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) else rbo->shape = RB_SHAPE_TRIMESH; + rbo->mesh_source = RBO_MESH_DEFORM; + /* set initial transform */ mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat); @@ -1000,6 +1028,17 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o if (rbo->physics_object == NULL) return; + if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) { + DerivedMesh *dm = ob->derivedDeform; + if (dm) { + MVert *mvert = dm->getVertArray(dm); + int totvert = dm->getNumVerts(dm); + BoundBox *bb = BKE_object_boundbox_get(ob); + + RB_shape_trimesh_update(rbo->physics_shape, (float*)mvert, totvert, sizeof(MVert), bb->vec[0], bb->vec[6]); + } + } + mat4_decompose(loc, rot, scale, ob->obmat); /* update scale for all objects */ @@ -1091,7 +1130,7 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, int r * - assume object to be active? That is the default for newly added settings... */ ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, RBO_TYPE_ACTIVE); - BKE_rigidbody_validate_sim_object(rbw, ob, true); + rigidbody_validate_sim_object(rbw, ob, true); rbo = ob->rigidbody_object; } @@ -1100,15 +1139,15 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, int r /* refresh object... */ if (rebuild) { /* World has been rebuilt so rebuild object */ - BKE_rigidbody_validate_sim_object(rbw, ob, true); + rigidbody_validate_sim_object(rbw, ob, true); } else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) { - BKE_rigidbody_validate_sim_object(rbw, ob, false); + rigidbody_validate_sim_object(rbw, ob, false); } /* refresh shape... */ if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) { /* mesh/shape data changed, so force shape refresh */ - BKE_rigidbody_validate_sim_shape(ob, true); + rigidbody_validate_sim_shape(ob, true); /* now tell RB sim about it */ // XXX: we assume that this can only get applied for active/passive shapes that will be included as rigidbodies RB_body_set_collision_shape(rbo->physics_object, rbo->physics_shape); @@ -1137,7 +1176,7 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, int r * constraint settings (perhaps it was added manually), add! */ ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED); - BKE_rigidbody_validate_sim_constraint(rbw, ob, true); + rigidbody_validate_sim_constraint(rbw, ob, true); rbc = ob->rigidbody_constraint; } @@ -1145,10 +1184,10 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, int r /* perform simulation data updates as tagged */ if (rebuild) { /* World has been rebuilt so rebuild constraint */ - BKE_rigidbody_validate_sim_constraint(rbw, ob, true); + rigidbody_validate_sim_constraint(rbw, ob, true); } else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) { - BKE_rigidbody_validate_sim_constraint(rbw, ob, false); + rigidbody_validate_sim_constraint(rbw, ob, false); } rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE; } @@ -1355,10 +1394,7 @@ void BKE_rigidbody_free_constraint(Object *ob) {} struct RigidBodyOb *BKE_rigidbody_copy_object(Object *ob) { return NULL; } struct RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob) { return NULL; } void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc) {} -void BKE_rigidbody_validate_sim_shape(Object *ob, short rebuild) {} -void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short rebuild) {} -void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, short rebuild) {} -void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, short rebuild) {} +void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {} struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; } struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw) { return NULL; } void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {} diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 84b9b0aadf4..3ca702e0068 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1293,7 +1293,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi } /* Update will decrease child's valency and schedule child with zero valency. */ - DAG_threaded_update_handle_node_updated(node,scene_update_object_add_task, pool); + DAG_threaded_update_handle_node_updated(node, scene_update_object_add_task, pool); #undef PRINT } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index e94db6f637c..188c80e7cc8 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -3693,7 +3693,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA); float edge_sum[3], face_sum[3]; CCGVertIterator *vi; - DerivedMesh *dm = CDDM_from_mesh(me, NULL); + DerivedMesh *dm = CDDM_from_mesh(me); ss_sync_from_derivedmesh(ss, dm, NULL, 0); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 11875722d27..1d03bf42f83 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -721,24 +721,16 @@ bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsign /* first vector */ fp1[0] = (float)(p1[0] - pt[0]); fp1[1] = (float)(p1[1] - pt[1]); - normalize_v2(fp1); for (i = 0; i < nr; i++) { - float dot, ang, cross; p2 = verts[i]; /* second vector */ fp2[0] = (float)(p2[0] - pt[0]); fp2[1] = (float)(p2[1] - pt[1]); - normalize_v2(fp2); /* dot and angle and cross */ - dot = dot_v2v2(fp1, fp2); - ang = fabsf(saacos(dot)); - cross = (float)((p1[1] - p2[1]) * (p1[0] - pt[0]) + (p2[0] - p1[0]) * (p1[1] - pt[1])); - - if (cross < 0.0f) angletot -= ang; - else angletot += ang; + angletot += angle_signed_v2v2(fp1, fp2); /* circulate */ copy_v2_v2(fp1, fp2); @@ -769,24 +761,16 @@ bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsign /* first vector */ fp1[0] = (float)(p1[0] - pt[0]); fp1[1] = (float)(p1[1] - pt[1]); - normalize_v2(fp1); for (i = 0; i < nr; i++) { - float dot, ang, cross; p2 = verts[i]; /* second vector */ fp2[0] = (float)(p2[0] - pt[0]); fp2[1] = (float)(p2[1] - pt[1]); - normalize_v2(fp2); /* dot and angle and cross */ - dot = dot_v2v2(fp1, fp2); - ang = fabsf(saacos(dot)); - cross = (float)((p1[1] - p2[1]) * (p1[0] - pt[0]) + (p2[0] - p1[0]) * (p1[1] - pt[1])); - - if (cross < 0.0f) angletot -= ang; - else angletot += ang; + angletot += angle_signed_v2v2(fp1, fp2); /* circulate */ copy_v2_v2(fp1, fp2); diff --git a/source/blender/blenlib/intern/polyfill2d.c b/source/blender/blenlib/intern/polyfill2d.c index 287a0909870..f5a226cebb6 100644 --- a/source/blender/blenlib/intern/polyfill2d.c +++ b/source/blender/blenlib/intern/polyfill2d.c @@ -50,8 +50,6 @@ #include "BLI_strict_flags.h" -#define SIGN_EPS 0.000001f - /* avoid fan-fill topology */ #define USE_CLIP_EVEN #define USE_CONVEX_SKIP @@ -97,7 +95,7 @@ static void pf_ear_tip_cut(PolyFill *pf, unsigned int index_ear_tip); BLI_INLINE eSign signum_i(float a) { - if (UNLIKELY(fabsf(a) < SIGN_EPS)) + if (UNLIKELY(a == 0.0f)) return 0; else if (a > 0.0f) return 1; @@ -105,9 +103,23 @@ BLI_INLINE eSign signum_i(float a) return -1; } +/** + * alternative version of #area_tri_signed_v2 + * needed because of float precision issues + * + * \note removes / 2 since its not needed since we only need ths sign. + */ +BLI_INLINE float area_tri_signed_v2_alt_2x(const float v1[2], const float v2[2], const float v3[2]) +{ + return ((v1[0] * (v2[1] - v3[1])) + + (v2[0] * (v3[1] - v1[1])) + + (v3[0] * (v1[1] - v2[1]))); +} + + static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float v3[2]) { - return signum_i(area_tri_signed_v2(v3, v2, v1)); + return signum_i(area_tri_signed_v2_alt_2x(v3, v2, v1)); } static unsigned int *pf_tri_add(PolyFill *pf) @@ -316,9 +328,9 @@ static bool pf_ear_tip_check(PolyFill *pf, const unsigned int index_ear_tip) /* Because the polygon has clockwise winding order, * the area sign will be positive if the point is strictly inside. * It will be 0 on the edge, which we want to include as well. */ - if ((span_tri_v2_sign(v1, v2, v) == CONVEX) && - (span_tri_v2_sign(v2, v3, v) == CONVEX) && - (span_tri_v2_sign(v3, v1, v) == CONVEX)) + if ((span_tri_v2_sign(v1, v2, v) != CONCAVE) && + (span_tri_v2_sign(v2, v3, v) != CONCAVE) && + (span_tri_v2_sign(v3, v1, v) != CONCAVE)) { return false; } diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 572b142d044..0ce40f717d4 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -582,7 +582,7 @@ void BLI_ascii_strtolower(char *str, const size_t len) { size_t i; - for (i = 0; i < len; i++) + for (i = 0; (i < len) && str[i]; i++) if (str[i] >= 'A' && str[i] <= 'Z') str[i] += 'a' - 'A'; } @@ -591,7 +591,7 @@ void BLI_ascii_strtoupper(char *str, const size_t len) { size_t i; - for (i = 0; i < len; i++) + for (i = 0; (i < len) && str[i]; i++) if (str[i] >= 'a' && str[i] <= 'z') str[i] -= 'a' - 'A'; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4d9234e18bc..8cb9853aa47 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1354,7 +1354,13 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain) } for (; ima; ima = ima->id.next) { - ima->cache = newmclipadr(fd, ima->cache); + ima->cache = newimaadr(fd, ima->cache); + if (ima->cache == NULL) { + ima->bindcode = 0; + ima->tpageflag &= ~IMA_GLBIND_IS_DATA; + ima->gputexture = NULL; + ima->rr = NULL; + } for (i = 0; i < IMA_MAX_RENDER_SLOT; i++) ima->renders[i] = newimaadr(fd, ima->renders[i]); @@ -3277,7 +3283,7 @@ static void direct_link_image(FileData *fd, Image *ima) ima->cache = NULL; /* if not restored, we keep the binded opengl index */ - if (!fd->imamap) { + if (!ima->cache) { ima->bindcode = 0; ima->tpageflag &= ~IMA_GLBIND_IS_DATA; ima->gputexture = NULL; diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index cbaffe2da1a..7b3ca898718 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1258,7 +1258,7 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example)) * * \return A BMFace pointer */ -BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, +BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMLoop *l_v1, BMLoop *l_v2, BMLoop **r_l, #ifdef USE_BMESH_HOLES ListBase *holes, @@ -1275,21 +1275,12 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMFace *f2; BMLoop *l_iter, *l_first; - BMLoop *l_v1 = NULL, *l_v2 = NULL, *l_f1 = NULL, *l_f2 = NULL; + BMLoop *l_f1 = NULL, *l_f2 = NULL; BMEdge *e; - int i, len, f1len, f2len; + BMVert *v1 = l_v1->v, *v2 = l_v2->v; + int f1len, f2len; - /* verify that v1 and v2 are in face */ - len = f->len; - for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < len; i++, l_iter = l_iter->next) { - if (l_iter->v == v1) l_v1 = l_iter; - else if (l_iter->v == v2) l_v2 = l_iter; - } - - if (!l_v1 || !l_v2) { - BLI_assert(0); - return NULL; - } + BLI_assert(f == l_v1->f && f == l_v2->f); /* allocate new edge between v1 and v2 */ e = BM_edge_create(bm, v1, v2, example, no_double ? BM_CREATE_NO_DOUBLE : BM_CREATE_NOP); diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index e9fd4e650cb..654698da3c6 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -72,14 +72,15 @@ void BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len BMEdge **e_in, int e_in_len); /* EULER API - For modifying structure */ -BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, - BMVert *v2, BMLoop **r_l, +BMFace *bmesh_sfme(BMesh *bm, BMFace *f, + BMLoop *l1, BMLoop *l2, + BMLoop **r_l, #ifdef USE_BMESH_HOLES - ListBase *holes, + ListBase *holes, #endif - BMEdge *example, - const bool no_double - ); + BMEdge *example, + const bool no_double + ); BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e); BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_splice); diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 49c8c987956..6d8dc531a32 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -252,48 +252,6 @@ BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f_a, BMFace *f_b, BMEdge *e, const } /** - * \brief Connect Verts, Split Face - * - * connects two verts together, automatically (if very naively) finding the - * face they both share (if there is one) and splitting it. Use this at your - * own risk, as it doesn't handle the many complex cases it should (like zero-area faces, - * multiple faces, etc). - * - * this is really only meant for cases where you don't know before hand the face - * the two verts belong to for splitting (e.g. the subdivision operator). - * - * \return The newly created edge. - */ -BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f) -{ - BMIter fiter; - BMIter viter; - BMVert *v_iter; - BMFace *f_iter; - - /* be warned: this can do weird things in some ngon situation, see BM_face_legal_splits */ - BM_ITER_ELEM (f_iter, &fiter, v1, BM_FACES_OF_VERT) { - BM_ITER_ELEM (v_iter, &viter, f_iter, BM_FACES_OF_VERT) { - if (v_iter == v2) { - BMLoop *l_new; - - f_iter = BM_face_split(bm, f_iter, v1, v2, &l_new, NULL, false); - - if (r_f) { - *r_f = f_iter; - } - return l_new->e; - } - } - } - - if (r_f) { - *r_f = NULL; - } - return NULL; -} - -/** * \brief Face Split * * Split a face along two vertices. returns the newly made face, and sets @@ -310,13 +268,26 @@ BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f) * if the split is successful (and the original original face will be the * other side). NULL if the split fails. */ -BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l, - BMEdge *example, const bool no_double) +BMFace *BM_face_split(BMesh *bm, BMFace *f, + BMLoop *l_a, BMLoop *l_b, + BMLoop **r_l, BMEdge *example, + const bool no_double) { const bool has_mdisp = CustomData_has_layer(&bm->ldata, CD_MDISPS); BMFace *f_new, *f_tmp; - BLI_assert(v1 != v2); + BLI_assert(l_a != l_b); + BLI_assert(f == l_a->f && f == l_b->f); + BLI_assert(!BM_loop_is_adjacent(l_a, l_b)); + + /* could be an assert */ + if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b))) { + return NULL; + } + + if (f != l_a->f || f != l_b->f) { + return NULL; + } /* do we have a multires layer? */ if (has_mdisp) { @@ -324,9 +295,9 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l } #ifdef USE_BMESH_HOLES - f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double); + f_new = bmesh_sfme(bm, f, l_a, l_b, r_l, NULL, example, no_double); #else - f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double); + f_new = bmesh_sfme(bm, f, l_a, l_b, r_l, example, no_double); #endif if (f_new) { @@ -369,7 +340,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l * * \param bm The bmesh * \param f the original face - * \param v1, v2 vertices which define the split edge, must be different + * \param l_a, l_b vertices which define the split edge, must be different * \param cos Array of coordinates for intermediate points * \param n Length of \a cos (must be > 0) * \param r_l pointer which will receive the BMLoop for the first split edge (from \a v1) in the new face @@ -379,16 +350,31 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l * if the split is successful (and the original original face will be the * other side). NULL if the split fails. */ -BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[][3], int n, +BMFace *BM_face_split_n(BMesh *bm, BMFace *f, + BMLoop *l_a, BMLoop *l_b, + float cos[][3], int n, BMLoop **r_l, BMEdge *example) { BMFace *f_new, *f_tmp; BMLoop *l_dummy; BMEdge *e, *e_new; BMVert *v_new; + // BMVert *v_a = l_a->v; /* UNUSED */ + BMVert *v_b = l_b->v; int i, j; - BLI_assert(v1 != v2); + BLI_assert(l_a != l_b); + BLI_assert(f == l_a->f && f == l_b->f); + BLI_assert(!BM_loop_is_adjacent(l_a, l_b)); + + /* could be an assert */ + if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b))) { + return NULL; + } + + if (l_a->f != l_b->f) { + return NULL; + } f_tmp = BM_face_copy(bm, bm, f, true, true); @@ -396,12 +382,12 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[ r_l = &l_dummy; #ifdef USE_BMESH_HOLES - f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false); + f_new = bmesh_sfme(bm, f, l_a, l_b, r_l, NULL, example, false); #else - f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, false); + f_new = bmesh_sfme(bm, f, l_a, l_b, r_l, example, false); #endif - /* bmesh_sfme returns in r_l a Loop for f_new going from v1 to v2. - * The radial_next is for f and goes from v2 to v1 */ + /* bmesh_sfme returns in r_l a Loop for f_new going from v_a to v_b. + * The radial_next is for f and goes from v_b to v_a */ if (f_new) { BM_elem_attrs_copy(bm, bm, f, f_new); @@ -409,7 +395,7 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[ e = (*r_l)->e; for (i = 0; i < n; i++) { - v_new = bmesh_semv(bm, v2, e, &e_new); + v_new = bmesh_semv(bm, v_b, e, &e_new); BLI_assert(v_new != NULL); /* bmesh_semv returns in e_new the edge going from v_new to tv */ copy_v3_v3(v_new->co, cos[i]); @@ -510,8 +496,14 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true); if (f2) { BMLoop *l_new = NULL; - if (BM_face_split(bm, f2, tv, tv2, &l_new, NULL, false)) { - e_new = l_new->e; + BMLoop *l_a, *l_b; + + if ((l_a = BM_face_vert_share_loop(f2, tv)) && + (l_b = BM_face_vert_share_loop(f2, tv2))) + { + if (BM_face_split(bm, f2, l_a, l_b, &l_new, NULL, false)) { + e_new = l_new->e; + } } } } @@ -1058,10 +1050,10 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f /* note, this assumes joining the faces _didnt_ also remove the verts. * the #BM_edge_rotate_check will ensure this, but its possibly corrupt state or future edits * break this */ - if (!BM_face_split(bm, f, v1, v2, NULL, NULL, true)) { - return NULL; - } - else { + if ((l1 = BM_face_vert_share_loop(f, v1)) && + (l2 = BM_face_vert_share_loop(f, v2)) && + BM_face_split(bm, f, l1, l2, NULL, NULL, true)) + { /* we should really be able to know the faces some other way, * rather then fetching them back from the edge, but this is predictable * where using the return values from face split isn't. - campbell */ @@ -1071,6 +1063,9 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f fb->head.hflag = f_hflag_prev_2; } } + else { + return NULL; + } return e_new; } diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h index ca281c13f21..f3ed99230d7 100644 --- a/source/blender/bmesh/intern/bmesh_mods.h +++ b/source/blender/bmesh/intern/bmesh_mods.h @@ -35,15 +35,13 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v); BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const bool do_del); -BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f); - BMFace *BM_face_split(BMesh *bm, BMFace *f, - BMVert *v1, BMVert *v2, + BMLoop *l_a, BMLoop *l_b, BMLoop **r_l, BMEdge *example, const bool no_double); BMFace *BM_face_split_n(BMesh *bm, BMFace *f, - BMVert *v1, BMVert *v2, + BMLoop *l_a, BMLoop *l_b, float cos[][3], int n, BMLoop **r_l, BMEdge *example); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 7a625840891..a3aaea9e257 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -800,67 +800,67 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, BLI_assert((r_faces_new == NULL) == (r_faces_new_tot == NULL)); if (f->len == 4) { - BMVert *v1, *v2; + BMLoop *l_v1, *l_v2; l_first = BM_FACE_FIRST_LOOP(f); switch (quad_method) { case MOD_TRIANGULATE_QUAD_FIXED: { - v1 = l_first->v; - v2 = l_first->next->next->v; + l_v1 = l_first; + l_v2 = l_first->next->next; break; } case MOD_TRIANGULATE_QUAD_ALTERNATE: { - v1 = l_first->next->v; - v2 = l_first->prev->v; + l_v1 = l_first->next; + l_v2 = l_first->prev; break; } case MOD_TRIANGULATE_QUAD_SHORTEDGE: { - BMVert *v3, *v4; + BMLoop *l_v3, *l_v4; float d1, d2; - v1 = l_first->v; - v2 = l_first->next->next->v; - v3 = l_first->next->v; - v4 = l_first->prev->v; + l_v1 = l_first; + l_v2 = l_first->next->next; + l_v3 = l_first->next; + l_v4 = l_first->prev; - d1 = len_squared_v3v3(v1->co, v2->co); - d2 = len_squared_v3v3(v3->co, v4->co); + d1 = len_squared_v3v3(l_v1->v->co, l_v2->v->co); + d2 = len_squared_v3v3(l_v3->v->co, l_v4->v->co); if (d2 < d1) { - v1 = v3; - v2 = v4; + l_v1 = l_v3; + l_v2 = l_v4; } break; } case MOD_TRIANGULATE_QUAD_BEAUTY: default: { - BMVert *v3, *v4; + BMLoop *l_v3, *l_v4; float cost; - v1 = l_first->next->v; - v2 = l_first->next->next->v; - v3 = l_first->prev->v; - v4 = l_first->v; + l_v1 = l_first->next; + l_v2 = l_first->next->next; + l_v3 = l_first->prev; + l_v4 = l_first; - cost = BM_verts_calc_rotate_beauty(v1, v2, v3, v4, 0, 0); + cost = BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0); if (cost < 0.0f) { - v1 = v4; - //v2 = v2; + l_v1 = l_v4; + //l_v2 = l_v2; } else { - //v1 = v1; - v2 = v3; + //l_v1 = l_v1; + l_v2 = l_v3; } break; } } - f_new = BM_face_split(bm, f, v1, v2, &l_new, NULL, false); + f_new = BM_face_split(bm, f, l_v1, l_v2, &l_new, NULL, false); copy_v3_v3(f_new->no, f->no); if (use_tag) { diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 16785778883..968ca5f3102 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -182,6 +182,37 @@ BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v) } /** + * Given 2 verts, find the smallest face they share and give back both loops. + */ +BMFace *BM_vert_pair_share_face(BMVert *v_a, BMVert *v_b, + BMLoop **r_l_a, BMLoop **r_l_b) +{ + BMLoop *l_cur_a = NULL, *l_cur_b = NULL; + BMFace *f_cur = NULL; + + if (v_a->e && v_b->e) { + BMIter iter; + BMLoop *l_a, *l_b; + + BM_ITER_ELEM (l_a, &iter, v_a, BM_LOOPS_OF_VERT) { + if ((f_cur == NULL) || (l_a->f->len < f_cur->len)) { + l_b = BM_face_vert_share_loop(l_a->f, v_b); + if (l_b) { + f_cur = l_a->f; + l_cur_a = l_a; + l_cur_b = l_b; + } + } + } + } + + if (r_l_a) *r_l_a = l_cur_a; + if (r_l_b) *r_l_b = l_cur_b; + + return f_cur; +} + +/** * Get the first loop of a vert. Uses the same initialization code for the first loop of the * iterator API */ diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 17c14310191..d4b6cd0e061 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -49,6 +49,8 @@ BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v); BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v); BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step); BMLoop *BM_vert_find_first_loop(BMVert *v); +BMFace *BM_vert_pair_share_face(BMVert *v_a, BMVert *v_b, + BMLoop **r_l_a, BMLoop **r_l_b); int BM_vert_edge_count_nonwire(BMVert *v); int BM_vert_edge_count(BMVert *v); @@ -67,6 +69,7 @@ BLI_INLINE bool BM_edge_is_contiguous(const BMEdge *e); bool BM_edge_is_convex(const BMEdge *e); bool BM_loop_is_convex(const BMLoop *l); +BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b); float BM_loop_calc_face_angle(BMLoop *l); void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3]); diff --git a/source/blender/bmesh/intern/bmesh_queries_inline.h b/source/blender/bmesh/intern/bmesh_queries_inline.h index c3ee363f247..a2a0a15faad 100644 --- a/source/blender/bmesh/intern/bmesh_queries_inline.h +++ b/source/blender/bmesh/intern/bmesh_queries_inline.h @@ -127,5 +127,14 @@ BLI_INLINE int BM_edge_is_boundary(BMEdge *e) } #endif +/** + * Tests whether one loop is next to another within the same face. + */ +BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) +{ + BLI_assert(l_a->f == l_b->f); + BLI_assert(l_a != l_b); + return (ELEM(l_b, l_a->next, l_a->prev)); +} #endif /* __BMESH_QUERIES_INLINE_H__ */ diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index d0f64eb2892..3d2c8c3d020 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -63,7 +63,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f) continue; } - if (l_last != l->prev && l_last != l->next) { + if (!BM_loop_is_adjacent(l_last, l)) { BMLoop **l_pair = STACK_PUSH_RET(loops_split); l_pair[0] = l_last; l_pair[1] = l; @@ -96,7 +96,17 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f) } for (i = 0; i < STACK_SIZE(verts_pair); i++) { - f_new = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &l_new, NULL, false); + BMLoop *l_a, *l_b; + + if ((l_a = BM_face_vert_share_loop(f, verts_pair[i][0])) && + (l_b = BM_face_vert_share_loop(f, verts_pair[i][1]))) + { + f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false); + } + else { + f_new = NULL; + } + f = f_new; if (!l_new || !f_new) { diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c index bd7a625406c..334647fc68c 100644 --- a/source/blender/bmesh/operators/bmo_connect_nonplanar.c +++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c @@ -86,7 +86,7 @@ static float bm_face_subset_calc_planar(BMLoop *l_first, BMLoop *l_last, const f return delta_z; } -static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) +static bool bm_face_split_find(BMFace *f, BMLoop *l_pair[2], float *r_angle) { BMLoop *l_iter, *l_first; BMLoop **l_arr = BLI_array_alloca(l_arr, f->len); @@ -111,9 +111,7 @@ static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) BMLoop *l_b = l_arr[i_b]; /* check these are not touching * (we could be smarter here) */ - if ((l_a->next != l_b) && - (l_a->prev != l_b)) - { + if (!BM_loop_is_adjacent(l_a, l_b)) { /* first calculate normals */ float no_a[3], no_b[3]; @@ -130,8 +128,8 @@ static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) BM_face_legal_splits(f, &l_split, 1); if (l_split[0]) { err_best = err_test; - v_pair[0] = l_a->v; - v_pair[1] = l_b->v; + l_pair[0] = l_a; + l_pair[1] = l_b; angle_best = angle_normalized_v3v3(no_a, no_b); found = true; @@ -151,13 +149,14 @@ static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) static bool bm_face_split_by_angle(BMesh *bm, BMFace *f, BMFace *r_f_pair[2], const float angle_limit) { - BMVert *v_pair[2]; + BMLoop *l_pair[2]; float angle; - if (bm_face_split_find(f, v_pair, &angle) && (angle > angle_limit)) { + if (bm_face_split_find(f, l_pair, &angle) && (angle > angle_limit)) { BMFace *f_new; BMLoop *l_new; - f_new = BM_face_split(bm, f, v_pair[0], v_pair[1], &l_new, NULL, false); + + f_new = BM_face_split(bm, f, l_pair[0], l_pair[1], &l_new, NULL, false); if (f_new) { r_f_pair[0] = f; r_f_pair[1] = f_new; diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index ae645b97874..60b96e35057 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -99,7 +99,7 @@ static void bm_face_split(BMesh *bm, const short oflag) if (BMO_elem_flag_test(bm, l->next->v, oflag) == 0 && BMO_elem_flag_test(bm, l->prev->v, oflag) == 0) { - BM_face_split(bm, l->f, l->next->v, l->prev->v, NULL, NULL, true); + BM_face_split(bm, l->f, l->next, l->prev, NULL, NULL, true); } } } diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index cc5a635092a..a771e05acfc 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -40,30 +40,32 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot *slot_targetmap) { BMIter liter; - BMLoop *l; - BMVert *v2, *v_double; + BMLoop *l, *l_tar, *l_double; bool split = false; BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - v2 = BMO_slot_map_elem_get(slot_targetmap, l->v); - /* ok: if v2 is NULL (e.g. not in the map) then it's + BMVert *v_tar = BMO_slot_map_elem_get(slot_targetmap, l->v); + /* ok: if v_tar is NULL (e.g. not in the map) then it's * a target vert, otherwise it's a double */ - if ((v2 && BM_vert_in_face(f, v2)) && - (v2 != l->prev->v) && - (v2 != l->next->v)) - { - v_double = l->v; - split = true; - break; + if (v_tar) { + l_tar = BM_face_vert_share_loop(f, v_tar); + + if (l_tar && (l_tar != l) && !BM_loop_is_adjacent(l_tar, l)) { + l_double = l; + split = true; + break; + } } } - if (split && v_double != v2) { + if (split) { BMLoop *l_new; - BMFace *f2 = BM_face_split(bm, f, v_double, v2, &l_new, NULL, false); + BMFace *f_new; - remdoubles_splitface(f, bm, op, slot_targetmap); - remdoubles_splitface(f2, bm, op, slot_targetmap); + f_new = BM_face_split(bm, f, l_double, l_tar, &l_new, NULL, false); + + remdoubles_splitface(f, bm, op, slot_targetmap); + remdoubles_splitface(f_new, bm, op, slot_targetmap); } } diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index b3b9cecf389..723595771a1 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -133,28 +133,23 @@ typedef struct SubDPattern { /* connects face with smallest len, which I think should always be correct for * edge subdivision */ -static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f_new) +static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace **r_f_new) { - BMIter iter, iter2; - BMVert *v; BMLoop *l_new; - BMFace *f, *f_cur = NULL; + BMLoop *l_a, *l_b; + BMFace *f; /* this isn't the best thing in the world. it doesn't handle cases where there's * multiple faces yet. that might require a convexity test to figure out which * face is "best" and who knows what for non-manifold conditions. */ - for (f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); f; f = BM_iter_step(&iter)) { - for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, f); v; v = BM_iter_step(&iter2)) { - if (v == v2) { - if (!f_cur || f->len < f_cur->len) f_cur = f; - } - } - } + f = BM_vert_pair_share_face(v_a, v_b, &l_a, &l_b); + + if (f) { + BMFace *f_new; - if (f_cur) { - f = BM_face_split(bm, f_cur, v1, v2, &l_new, NULL, false); + f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false); - if (r_f_new) *r_f_new = f; + if (r_f_new) *r_f_new = f_new; return l_new ? l_new->e : NULL; } @@ -1118,7 +1113,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) if (loops_split[j][0]) { BMFace *f_new; BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == NULL); - f_new = BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &l_new, NULL, false); + f_new = BM_face_split(bm, face, loops_split[j][0], loops_split[j][1], &l_new, NULL, false); if (f_new) { BMO_elem_flag_enable(bm, l_new->e, ELE_INNER); } diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index d1ec06c5486..182bf0518ef 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -828,7 +828,7 @@ static void bm_face_slice(BMesh *bm, BMLoop *l, const int cuts) for (i = 0; i < cuts; i++) { /* no chance of double */ - BM_face_split(bm, l_new->f, l_new->prev->v, l_new->next->next->v, &l_new, NULL, false); + BM_face_split(bm, l_new->f, l_new->prev, l_new->next->next, &l_new, NULL, false); if (l_new->f->len < l_new->radial_next->f->len) { l_new = l_new->radial_next; } diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 7f39cbee2c5..b10f162f2b0 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -2095,7 +2095,7 @@ static void bevel_build_trifan(BMesh *bm, BevVert *bv) BMLoop *l_new; BMFace *f_new; BLI_assert(v_fan == l_fan->v); - f_new = BM_face_split(bm, f, l_fan->v, l_fan->next->next->v, &l_new, NULL, FALSE); + f_new = BM_face_split(bm, f, l_fan, l_fan->next->next, &l_new, NULL, FALSE); if (f_new->len > f->len) { f = f_new; @@ -2140,7 +2140,7 @@ static void bevel_build_quadstrip(BMesh *bm, BevVert *bv) l_b = l_b->next; } else { - BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, FALSE); + BM_face_split(bm, f, l_a, l_b, &l_new, NULL, FALSE); f = l_new->f; /* walk around the new face to get the next verts to split */ diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c index 6aeb26435ac..7001cfa4061 100644 --- a/source/blender/bmesh/tools/bmesh_bisect_plane.c +++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c @@ -139,9 +139,14 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con BMLoop *l_new; if (LIKELY(STACK_SIZE(vert_split_arr) == 2)) { + BMLoop *l_a, *l_b; + + l_a = BM_face_vert_share_loop(f, vert_split_arr[0]); + l_b = BM_face_vert_share_loop(f, vert_split_arr[1]); + /* common case, just cut the face once */ l_new = NULL; - BM_face_split(bm, f, vert_split_arr[0], vert_split_arr[1], &l_new, NULL, true); + BM_face_split(bm, f, l_a, l_b, &l_new, NULL, true); if (l_new) { if (oflag_center) { BMO_elem_flag_enable(bm, l_new->e, oflag_center); @@ -254,9 +259,9 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con /* in fact this simple test is good enough, * test if the loops are adjacent */ - if (found && (l_a->next != l_b && l_a->prev != l_b)) { + if (found && !BM_loop_is_adjacent(l_a, l_b)) { BMFace *f_tmp; - f_tmp = BM_face_split(bm, face_split_arr[j], l_a->v, l_b->v, NULL, NULL, true); + f_tmp = BM_face_split(bm, face_split_arr[j], l_a, l_b, NULL, NULL, true); if (f_tmp) { if (f_tmp != face_split_arr[j]) { STACK_PUSH(face_split_arr, f_tmp); diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 3ee238ad54f..292978cd247 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -358,7 +358,7 @@ static bool bm_decim_triangulate_begin(BMesh *bm) * - if there is a quad that has a free standing edge joining it along * where we want to split the face, there isnt a good way we can handle this. * currently that edge will get removed when joining the tris back into a quad. */ - f_new = BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, false); + f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false); if (f_new) { /* the value of this doesn't matter, only that the 2 loops match and have unique values */ diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c index 868caa49ec7..092a004aece 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c +++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c @@ -144,7 +144,7 @@ static bool bm_vert_dissolve_fan(BMesh *bm, BMVert *v) if (l->f->len > 3) { BMLoop *l_new; BLI_assert(l->prev->v != l->next->v); - BM_face_split(bm, l->f, l->prev->v, l->next->v, &l_new, NULL, true); + BM_face_split(bm, l->f, l->prev, l->next, &l_new, NULL, true); BM_elem_flag_merge_into(l_new->e, l->e, l->prev->e); } } diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index f230adce28c..559b180189f 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -942,7 +942,7 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj float ctime = BKE_scene_frame_get_from_ctime(scene, *it); CFRA = BKE_scene_frame_get_from_ctime(scene, *it); - //BKE_scene_update_for_newframe_viewport(G.main,scene,scene->lay); + //BKE_scene_update_for_newframe(G.main->eval_ctx, G.main,scene,scene->lay); BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL); if (bone) { diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 2e805ce18f1..f5b81c6f6b0 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -160,7 +160,7 @@ Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh } } else { - dm = mesh_create_derived((Mesh *)ob->data, ob, NULL); + dm = mesh_create_derived((Mesh *)ob->data, NULL); } tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index ad745155286..5e93fda0cd4 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1042,9 +1042,11 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGro * - this will also affect things like Drivers, and also works for Bone Constraints */ if (ads && owner_id) { - if ((ads->filterflag & ADS_FILTER_ONLYSEL) || (ads->filterflag & ADS_FILTER_INCL_HIDDEN) == 0) { - if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode)) - continue; + if ((filter_mode & ANIMFILTER_TMP_IGNORE_ONLYSEL) == 0) { + if ((ads->filterflag & ADS_FILTER_ONLYSEL) || (ads->filterflag & ADS_FILTER_INCL_HIDDEN) == 0) { + if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode)) + continue; + } } } @@ -1541,21 +1543,17 @@ static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, { bNode *node; size_t items = 0; - int group_filter_mode = filter_mode & ~ADS_FILTER_ONLYSEL; items += animdata_filter_ds_nodetree_group(ac, anim_data, ads, owner_id, ntree, filter_mode); for (node = ntree->nodes.first; node; node = node->next) { if (node->type == NODE_GROUP) { if (node->id) { - int filterflag = ads->filterflag; - if ((filter_mode & ADS_FILTER_ONLYSEL) && (node->flag & NODE_SELECT) == 0) { + if ((ads->filterflag & ADS_FILTER_ONLYSEL) && (node->flag & NODE_SELECT) == 0) { continue; } - /* TODO(sergey): A bit creepy, but this flag is not used from threads anyway. */ - ads->filterflag &= ~ADS_FILTER_ONLYSEL; - items += animdata_filter_ds_nodetree_group(ac, anim_data, ads, owner_id, (bNodeTree *) node->id, group_filter_mode); - ads->filterflag = filterflag; + items += animdata_filter_ds_nodetree_group(ac, anim_data, ads, owner_id, (bNodeTree *) node->id, + filter_mode | ANIMFILTER_TMP_IGNORE_ONLYSEL); } } } diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index dd1995a5428..48440d10ae3 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -59,6 +59,7 @@ extern const unsigned char stipple_halftone[128]; extern const unsigned char stipple_quarttone[128]; extern const unsigned char stipple_diag_stripes_pos[128]; extern const unsigned char stipple_diag_stripes_neg[128]; +extern const unsigned char stipple_checker_8px[128]; /** * Draw a lined (non-looping) arc with the given diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 8b9bb0a4ab0..dff5069d991 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -225,7 +225,10 @@ typedef enum eAnimFilter_Flags { ANIMFILTER_NODUPLIS = (1 << 11), /* for checking if we should keep some collapsed channel around (internal use only!) */ - ANIMFILTER_TMP_PEEK = (1 << 30) + ANIMFILTER_TMP_PEEK = (1 << 30), + + /* ignore ONLYSEL flag from filterflag, (internal use only!) */ + ANIMFILTER_TMP_IGNORE_ONLYSEL = (1 << 31) } eAnimFilter_Flags; /* ---------- Flag Checking Macros ------------ */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index cfd6d74dcef..735e7f35d61 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -726,8 +726,8 @@ void UI_exit(void); #define UI_LAYOUT_MENU 2 #define UI_LAYOUT_TOOLBAR 3 -#define UI_UNIT_X U.widget_unit -#define UI_UNIT_Y U.widget_unit +#define UI_UNIT_X ((void)0, U.widget_unit) +#define UI_UNIT_Y ((void)0, U.widget_unit) #define UI_LAYOUT_ALIGN_EXPAND 0 #define UI_LAYOUT_ALIGN_LEFT 1 @@ -748,6 +748,10 @@ void UI_exit(void); #define UI_LAYOUT_OP_SHOW_TITLE 1 #define UI_LAYOUT_OP_SHOW_EMPTY 2 +/* used for transp checkers */ +#define UI_ALPHA_CHECKER_DARK 100 +#define UI_ALPHA_CHECKER_LIGHT 160 + /* flags to set which corners will become rounded: * * 1------2 diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index b6f93726bfc..3301f1f1e5a 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -935,11 +935,11 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti /* first background, to show tranparency */ - glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255); + glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255); glRectf(x1, y1, x1 + sizex, y1 + sizey); glEnable(GL_POLYGON_STIPPLE); - glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255); - glPolygonStipple(checker_stipple_sml); + glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255); + glPolygonStipple(stipple_checker_8px); glRectf(x1, y1, x1 + sizex, y1 + sizey); glDisable(GL_POLYGON_STIPPLE); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index e11b93ca69b..5500df624cf 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -544,11 +544,6 @@ void ui_widget_color_init(struct ThemeUI *tui); void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state, bool use_sep); void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state); -extern const unsigned char checker_stipple_sml[32 * 32 / 8]; -/* used for transp checkers */ -#define UI_TRANSP_DARK 100 -#define UI_TRANSP_LIGHT 160 - #define UI_TEXT_MARGIN_X 0.4f /* interface_style.c */ diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 5c2ce7ad635..477b7c4e8f3 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -181,18 +181,6 @@ static const unsigned int check_tria_face[4][3] = { {3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3} }; -GLubyte const checker_stipple_sml[32 * 32 / 8] = -{ - 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, - 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, -}; - /* ************************************************* */ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3) @@ -681,15 +669,15 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) float x_mid = 0.0f; /* used for dumb clamping of values */ /* dark checkers */ - glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255); + glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); glDrawArrays(GL_POLYGON, 0, wtb->totvert); /* light checkers */ glEnable(GL_POLYGON_STIPPLE); - glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255); - glPolygonStipple(checker_stipple_sml); + glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255); + glPolygonStipple(stipple_checker_8px); glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); glDrawArrays(GL_POLYGON, 0, wtb->totvert); diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 6b60e5ed390..4cf4cd1ddba 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -590,8 +590,6 @@ static float *threaded_mask_rasterize(Mask *mask, const int width, const int hei task_pool = BLI_task_pool_create(task_scheduler, &state); - BLI_begin_threaded_malloc(); - scanlines_per_thread = height / num_threads; for (i = 0; i < num_threads; i++) { ThreadedMaskRasterizeData *data = MEM_mallocN(sizeof(ThreadedMaskRasterizeData), @@ -614,7 +612,6 @@ static float *threaded_mask_rasterize(Mask *mask, const int width, const int hei /* Free memory. */ BLI_task_pool_free(task_pool); - BLI_end_threaded_malloc(); BKE_maskrasterize_handle_free(handle); return buffer; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 64175c133ea..0d1e43a709b 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2237,6 +2237,7 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha BMesh *bm = kcd->em->bm; KnifeEdge *kfe, *kfelast; BMVert *v1, *v2; + BMLoop *l_v1, *l_v2; BMFace *f_new; Ref *ref; KnifeVert *kfv, *kfvprev; @@ -2262,28 +2263,36 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha } BLI_assert(i == nco); l_new = NULL; - if (nco == 0) { - /* Want to prevent creating two-sided polygons */ - if (v1 == v2 || BM_edge_exists(v1, v2)) { - f_new = NULL; + + if ((l_v1 = BM_face_vert_share_loop(f, v1)) && + (l_v2 = BM_face_vert_share_loop(f, v2))) + { + if (nco == 0) { + /* Want to prevent creating two-sided polygons */ + if (v1 == v2 || BM_edge_exists(v1, v2)) { + f_new = NULL; + } + else { + f_new = BM_face_split(bm, f, l_v1, l_v2, &l_new, NULL, true); + } } else { - f_new = BM_face_split(bm, f, v1, v2, &l_new, NULL, true); - } - } - else { - f_new = BM_face_split_n(bm, f, v1, v2, cos, nco, &l_new, NULL); - if (f_new) { - /* Now go through lnew chain matching up chain kv's and assign real v's to them */ - for (l_iter = l_new->next, i = 0; i < nco; l_iter = l_iter->next, i++) { - BLI_assert(equals_v3v3(cos[i], l_iter->v->co)); - if (kcd->select_result) { - BM_edge_select_set(bm, l_iter->e, true); + f_new = BM_face_split_n(bm, f, l_v1, l_v2, cos, nco, &l_new, NULL); + if (f_new) { + /* Now go through lnew chain matching up chain kv's and assign real v's to them */ + for (l_iter = l_new->next, i = 0; i < nco; l_iter = l_iter->next, i++) { + BLI_assert(equals_v3v3(cos[i], l_iter->v->co)); + if (kcd->select_result) { + BM_edge_select_set(bm, l_iter->e, true); + } + kverts[i]->v = l_iter->v; } - kverts[i]->v = l_iter->v; } } } + else { + f_new = NULL; + } /* the select chain above doesnt account for the first loop */ if (kcd->select_result) { diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 55564703a87..b8a96bba874 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -209,7 +209,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); Mesh *me = (Mesh *)ob->data; MultiresModifierData tmp_mmd = *mmd; - DerivedMesh *cddm = CDDM_from_mesh(me, ob); + DerivedMesh *cddm = CDDM_from_mesh(me); if (mmd->lvl > 0) { *lvl = mmd->lvl; @@ -234,7 +234,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l Mesh *me = (Mesh *)ob->data; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); MultiresModifierData tmp_mmd = *mmd; - DerivedMesh *cddm = CDDM_from_mesh(me, ob); + DerivedMesh *cddm = CDDM_from_mesh(me); DerivedMesh *dm; DM_set_only_copy(cddm, CD_MASK_BAREMESH); diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 230c3a11108..9cdb6de99b0 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -137,6 +137,16 @@ const GLubyte stipple_diag_stripes_neg[128] = { 0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0, 0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80}; +const GLubyte stipple_checker_8px[128] = { + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255}; + void fdrawbezier(float vec[4][3]) { @@ -204,22 +214,12 @@ void fdrawcheckerboard(float x1, float y1, float x2, float y2) { unsigned char col1[4] = {40, 40, 40}, col2[4] = {50, 50, 50}; - GLubyte checker_stipple[32 * 32 / 8] = { - 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, - 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255}; - glColor3ubv(col1); glRectf(x1, y1, x2, y2); glColor3ubv(col2); glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(checker_stipple); + glPolygonStipple(stipple_checker_8px); glRectf(x1, y1, x2, y2); glDisable(GL_POLYGON_STIPPLE); } diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 80b844464db..16845bb10fb 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -116,7 +116,7 @@ static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, glBegin(GL_LINE_STRIP); } -static void tracking_segment_end_cb(void *UNUSED(userdata)) +static void tracking_segment_end_cb(void *UNUSED(userdata), int UNUSED(coord)) { glEnd(); @@ -151,7 +151,7 @@ static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, } } -static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) +static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc) { MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; @@ -191,6 +191,108 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) &userdata, tracking_segment_knot_cb, NULL, NULL); } +typedef struct TrackErrorCurveUserData { + MovieTracking *tracking; + MovieTrackingObject *tracking_object; + MovieTrackingTrack *active_track; + bool matrix_initialized; + int matrix_frame; + float projection_matrix[4][4]; + int width, height; + float aspy; +} TrackErrorCurveUserData; + +static void tracking_error_segment_point_cb(void *userdata, + MovieTrackingTrack *track, MovieTrackingMarker *marker, + int coord, int scene_framenr, float UNUSED(value)) +{ + if (coord == 1) { + TrackErrorCurveUserData *data = (TrackErrorCurveUserData *) userdata; + float reprojected_position[4], bundle_position[4], marker_position[2], delta[2]; + float reprojection_error; + + if (!data->matrix_initialized || data->matrix_frame != scene_framenr) { + BKE_tracking_get_projection_matrix(data->tracking, data->tracking_object, + scene_framenr, data->width, data->height, + data->projection_matrix); + } + + copy_v3_v3(bundle_position, track->bundle_pos); + bundle_position[3] = 1; + + mul_v4_m4v4(reprojected_position, data->projection_matrix, bundle_position); + reprojected_position[0] = (reprojected_position[0] / + (reprojected_position[3] * 2.0f) + 0.5f) * data->width; + reprojected_position[1] = (reprojected_position[1] / + (reprojected_position[3] * 2.0f) + 0.5f) * data->height * data->aspy; + + BKE_tracking_distort_v2(data->tracking, reprojected_position, reprojected_position); + + marker_position[0] = (marker->pos[0] + track->offset[0]) * data->width; + marker_position[1] = (marker->pos[1] + track->offset[1]) * data->height * data->aspy; + + sub_v2_v2v2(delta, reprojected_position, marker_position); + reprojection_error = len_v2(delta); + + glVertex2f(scene_framenr, reprojection_error); + } +} + +static void tracking_error_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord) +{ + if (coord == 1) { + TrackErrorCurveUserData *data = (TrackErrorCurveUserData *) userdata; + float col[4] = {0.0f, 0.0f, 1.0f, 1.0f}; + + if (track == data->active_track) { + col[3] = 1.0f; + glLineWidth(2.0f); + } + else { + col[3] = 0.5f; + glLineWidth(1.0f); + } + + glColor4fv(col); + + glBegin(GL_LINE_STRIP); + } +} + +static void tracking_error_segment_end_cb(void *UNUSED(userdata), int coord) +{ + if (coord == 1) { + glEnd(); + glLineWidth(1.0f); + } +} + +static void draw_tracks_error_curves(SpaceClip *sc) +{ + MovieClip *clip = ED_space_clip_get_clip(sc); + MovieTracking *tracking = &clip->tracking; + TrackErrorCurveUserData data; + + data.tracking = tracking; + data.tracking_object = BKE_tracking_object_get_active(tracking); + data.active_track = BKE_tracking_track_get_active(tracking); + data.matrix_initialized = false; + BKE_movieclip_get_size(clip, &sc->user, &data.width, &data.height); + data.aspy = 1.0f / tracking->camera.pixel_aspect; + + if (!data.width || !data.height) { + return; + } + + clip_graph_tracking_values_iterate(sc, + (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, + (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, + &data, + tracking_error_segment_point_cb, + tracking_error_segment_start_cb, + tracking_error_segment_end_cb); +} + static void draw_frame_curves(SpaceClip *sc) { MovieClip *clip = ED_space_clip_get_clip(sc); @@ -237,8 +339,11 @@ void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene) UI_view2d_grid_free(grid); if (clip) { - if (sc->flag & SC_SHOW_GRAPH_TRACKS) - draw_tracks_curves(v2d, sc); + if (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) + draw_tracks_motion_curves(v2d, sc); + + if (sc->flag & SC_SHOW_GRAPH_TRACKS_ERROR) + draw_tracks_error_curves(sc); if (sc->flag & SC_SHOW_GRAPH_FRAMES) draw_frame_curves(sc); diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index e0062ecd243..44261b8b500 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -72,6 +72,16 @@ static int ED_space_clip_graph_poll(bContext *C) return FALSE; } +static int clip_graph_knots_poll(bContext *C) +{ + if (ED_space_clip_graph_poll(C)) { + SpaceClip *sc = CTX_wm_space_clip(C); + + return (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) != 0; + } + return FALSE; +} + typedef struct { int action; } SelectUserData; @@ -130,7 +140,7 @@ static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack copy_v2_v2(data->prev_co, co); } -static void find_nearest_tracking_segment_end_cb(void *userdata) +static void find_nearest_tracking_segment_end_cb(void *userdata, int UNUSED(coord)) { MouseSelectUserData *data = userdata; @@ -302,7 +312,7 @@ void CLIP_OT_graph_select(wmOperatorType *ot) /* api callbacks */ ot->exec = select_exec; ot->invoke = select_invoke; - ot->poll = ED_space_clip_graph_poll; + ot->poll = clip_graph_knots_poll; /* flags */ ot->flag = OPTYPE_UNDO; @@ -394,7 +404,7 @@ void CLIP_OT_graph_select_border(wmOperatorType *ot) ot->invoke = WM_border_select_invoke; ot->exec = border_select_graph_exec; ot->modal = WM_border_select_modal; - ot->poll = ED_space_clip_graph_poll; + ot->poll = clip_graph_knots_poll; /* flags */ ot->flag = OPTYPE_UNDO; @@ -461,7 +471,7 @@ void CLIP_OT_graph_select_all_markers(wmOperatorType *ot) /* api callbacks */ ot->exec = graph_select_all_markers_exec; - ot->poll = ED_space_clip_graph_poll; + ot->poll = clip_graph_knots_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -496,7 +506,7 @@ void CLIP_OT_graph_delete_curve(wmOperatorType *ot) /* api callbacks */ ot->invoke = WM_operator_confirm; ot->exec = delete_curve_exec; - ot->poll = ED_space_clip_tracking_poll; + ot->poll = clip_graph_knots_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -536,7 +546,7 @@ void CLIP_OT_graph_delete_knot(wmOperatorType *ot) /* api callbacks */ ot->exec = delete_knot_exec; - ot->poll = ED_space_clip_graph_poll; + ot->poll = clip_graph_knots_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index af9d8f97138..811f8e2eaab 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -125,12 +125,12 @@ void ED_clip_tool_props_register(struct ARegionType *art); void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata, void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord), - void (*segment_end)(void *userdata)); + void (*segment_end)(void *userdata, int coord)); void clip_graph_tracking_values_iterate(struct SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata, void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord), - void (*segment_end)(void *userdata)); + void (*segment_end)(void *userdata, int coord)); void clip_graph_tracking_iterate(struct SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata, void (*func)(void *userdata, struct MovieTrackingMarker *marker)); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 060531ae82c..4b90fa5839f 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -70,7 +70,7 @@ void clip_graph_tracking_values_iterate_track( void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), - void (*segment_end)(void *userdata)) + void (*segment_end)(void *userdata, int coord)) { MovieClip *clip = ED_space_clip_get_clip(sc); int width, height, coord; @@ -89,7 +89,7 @@ void clip_graph_tracking_values_iterate_track( if (marker->flag & MARKER_DISABLED) { if (open) { if (segment_end) - segment_end(userdata); + segment_end(userdata, coord); open = false; } @@ -121,7 +121,7 @@ void clip_graph_tracking_values_iterate_track( if (open) { if (segment_end) - segment_end(userdata); + segment_end(userdata, coord); } } } @@ -131,7 +131,7 @@ void clip_graph_tracking_values_iterate( void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), - void (*segment_end)(void *userdata)) + void (*segment_end)(void *userdata, int coord)) { MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 2cabb595fb7..e1262d0d7b8 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -247,7 +247,7 @@ static SpaceLink *clip_new(const bContext *C) sc = MEM_callocN(sizeof(SpaceClip), "initclip"); sc->spacetype = SPACE_CLIP; sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH | SC_MANUAL_CALIBRATION | - SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL; + SC_SHOW_GRAPH_TRACKS_MOTION | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL; sc->zoom = 1.0f; sc->path_length = 20; sc->scopes.track_preview_height = 120; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 76305aaabaa..672549f0402 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -165,8 +165,10 @@ static void draw_render_info(Scene *scene, Image *ima, ARegion *ar, float zoomx, void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_default_view, int channels, int x, int y, const unsigned char cp[4], const float fp[4], const float linearcol[4], int *zp, float *zpf) { + rcti color_rect; char str[256]; - float dx = 6; + int dx = 6; + const int dy = 0.3f * UI_UNIT_Y; /* text colors */ /* XXX colored text not allowed in Blender UI */ #if 0 @@ -193,21 +195,21 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def glColor3ub(255, 255, 255); BLI_snprintf(str, sizeof(str), "X:%-4d Y:%-4d |", x, y); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_Y, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); if (zp) { glColor3ub(255, 255, 255); BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff)); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } if (zpf) { glColor3ub(255, 255, 255); BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } @@ -220,7 +222,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), " R:%-3d", cp[0]); else BLI_snprintf(str, sizeof(str), " R:-"); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); @@ -231,7 +233,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), " G:%-3d", cp[1]); else BLI_snprintf(str, sizeof(str), " G:-"); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); @@ -242,7 +244,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), " B:%-3d", cp[2]); else BLI_snprintf(str, sizeof(str), " B:-"); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); @@ -254,7 +256,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), " A:%-3d", cp[3]); else BLI_snprintf(str, sizeof(str), "- "); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } @@ -274,7 +276,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, &scene->view_settings, &scene->display_settings); BLI_snprintf(str, sizeof(str), " | CM R:%-.4f G:%-.4f B:%-.4f", rgba[0], rgba[1], rgba[2]); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } @@ -316,23 +318,47 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def } glDisable(GL_BLEND); - glColor3fv(finalcol); dx += 0.25f * UI_UNIT_X; - glBegin(GL_QUADS); - glVertex2f(dx, 0.15f * UI_UNIT_Y); - glVertex2f(dx, 0.85f * UI_UNIT_Y); - glVertex2f(dx + 1.5f * UI_UNIT_X, 0.85 * UI_UNIT_Y); - glVertex2f(dx + 1.5f * UI_UNIT_X, 0.15f * UI_UNIT_Y); - glEnd(); + + BLI_rcti_init(&color_rect, dx, dx + (1.5f * UI_UNIT_X), 0.15f * UI_UNIT_Y, 0.85f * UI_UNIT_Y); + + if (channels == 4) { + rcti color_rect_half; + int color_quater_x, color_quater_y; + + color_rect_half = color_rect; + color_rect_half.xmax = BLI_rcti_cent_x(&color_rect); + glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax); + + color_rect_half = color_rect; + color_rect_half.xmin = BLI_rcti_cent_x(&color_rect); + + color_quater_x = BLI_rcti_cent_x(&color_rect_half); + color_quater_y = BLI_rcti_cent_y(&color_rect_half); + + glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255); + glRecti(color_rect_half.xmin, color_rect_half.ymin, color_rect_half.xmax, color_rect_half.ymax); + + glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255); + glRecti(color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax); + glRecti(color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(UNPACK3(finalcol), fp ? fp[3] : (cp[3] / 255.0f)); + glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax); + glDisable(GL_BLEND); + } + else { + glColor3fv(finalcol); + glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax); + } /* draw outline */ glColor3ub(128, 128, 128); - glBegin(GL_LINE_LOOP); - glVertex2f(dx, 0.15f * UI_UNIT_Y); - glVertex2f(dx, 0.85f * UI_UNIT_Y); - glVertex2f(dx + 1.5f * UI_UNIT_X, 0.85f * UI_UNIT_Y); - glVertex2f(dx + 1.5f * UI_UNIT_X, 0.15f * UI_UNIT_Y); - glEnd(); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); dx += 1.75f * UI_UNIT_X; @@ -348,12 +374,12 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def } BLI_snprintf(str, sizeof(str), "V:%-.4f", val); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); BLI_snprintf(str, sizeof(str), " L:%-.4f", lum); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } @@ -362,22 +388,22 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def rgb_to_yuv(finalcol[0], finalcol[1], finalcol[2], &lum, &u, &v); BLI_snprintf(str, sizeof(str), "H:%-.4f", hue); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); BLI_snprintf(str, sizeof(str), " S:%-.4f", sat); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); BLI_snprintf(str, sizeof(str), " V:%-.4f", val); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); BLI_snprintf(str, sizeof(str), " L:%-.4f", lum); - BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); + BLF_position(blf_mono_font, dx, dy, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } diff --git a/source/blender/editors/space_info/info_intern.h b/source/blender/editors/space_info/info_intern.h index b5426fe15e1..967bcec57c5 100644 --- a/source/blender/editors/space_info/info_intern.h +++ b/source/blender/editors/space_info/info_intern.h @@ -37,6 +37,7 @@ struct SpaceInfo; struct wmOperatorType; struct ReportList; +void FILE_OT_autopack_toggle(struct wmOperatorType *ot); void FILE_OT_pack_all(struct wmOperatorType *ot); void FILE_OT_unpack_all(struct wmOperatorType *ot); void FILE_OT_unpack_item(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 6c76ba64893..ace3b8d5393 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -70,7 +70,7 @@ #include "info_intern.h" -/********************* pack blend file libararies operator *********************/ +/********************* pack blend file libaries operator *********************/ static int pack_libraries_exec(bContext *C, wmOperator *op) { @@ -124,6 +124,36 @@ void FILE_OT_unpack_libraries(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/********************* toogle auto-pack operator *********************/ + +static int autopack_toggle_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + + if (G.fileflags & G_AUTOPACK) { + G.fileflags &= ~G_AUTOPACK; + } + else { + packAll(bmain, op->reports); + G.fileflags |= G_AUTOPACK; + } + + return OPERATOR_FINISHED; +} + +void FILE_OT_autopack_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Automatically Pack Into .blend"; + ot->idname = "FILE_OT_autopack_toggle"; + ot->description = "Automatically pack all external files into the .blend file"; + + /* api callbacks */ + ot->exec = autopack_toggle_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} /********************* pack all operator *********************/ @@ -168,7 +198,7 @@ static int pack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev void FILE_OT_pack_all(wmOperatorType *ot) { /* identifiers */ - ot->name = "Pack All"; + ot->name = "Pack All Into .blend"; ot->idname = "FILE_OT_pack_all"; ot->description = "Pack all used external files into the .blend"; @@ -214,7 +244,7 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( count = countPackedFiles(bmain); if (!count) { - BKE_report(op->reports, RPT_WARNING, "No packed files (auto-pack disabled)"); + BKE_report(op->reports, RPT_WARNING, "No packed files to unpack"); G.fileflags &= ~G_AUTOPACK; return OPERATOR_CANCELLED; } @@ -238,7 +268,7 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( void FILE_OT_unpack_all(wmOperatorType *ot) { /* identifiers */ - ot->name = "Unpack All"; + ot->name = "Unpack All Into Files"; ot->idname = "FILE_OT_unpack_all"; ot->description = "Unpack all files packed into this .blend to external ones"; diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index 96e0de17918..c029a4bf0bc 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -179,6 +179,7 @@ static void info_main_area_draw(const bContext *C, ARegion *ar) static void info_operatortypes(void) { + WM_operatortype_append(FILE_OT_autopack_toggle); WM_operatortype_append(FILE_OT_pack_all); WM_operatortype_append(FILE_OT_pack_libraries); WM_operatortype_append(FILE_OT_unpack_all); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 5b8c4a92555..02e981f2ffd 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -6201,7 +6201,7 @@ static void get_local_bounds(Object *ob, float center[3], float size[3]) } #endif -static void draw_bb_quadric(BoundBox *bb, char type) +static void draw_bb_quadric(BoundBox *bb, char type, bool around_origin) { float size[3], cent[3]; GLUquadricObj *qobj = gluNewQuadric(); @@ -6212,9 +6212,14 @@ static void draw_bb_quadric(BoundBox *bb, char type) size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]); size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]); - cent[0] = 0.5f * (bb->vec[0][0] + bb->vec[4][0]); - cent[1] = 0.5f * (bb->vec[0][1] + bb->vec[2][1]); - cent[2] = 0.5f * (bb->vec[0][2] + bb->vec[1][2]); + if (around_origin) { + zero_v3(cent); + } + else { + cent[0] = 0.5f * (bb->vec[0][0] + bb->vec[4][0]); + cent[1] = 0.5f * (bb->vec[0][1] + bb->vec[2][1]); + cent[2] = 0.5f * (bb->vec[0][2] + bb->vec[1][2]); + } glPushMatrix(); if (type == OB_BOUND_SPHERE) { @@ -6278,11 +6283,37 @@ static void draw_bounding_volume(Scene *scene, Object *ob, char type) BKE_boundbox_init_from_minmax(bb, min, max); } - if (bb == NULL) return; - - if (type == OB_BOUND_BOX) draw_box(bb->vec); - else draw_bb_quadric(bb, type); + if (bb == NULL) + return; + if (ob->gameflag & OB_BOUNDS) { /* bounds need to be drawn around origin for game engine */ + + if (type == OB_BOUND_BOX) { + float vec[8][3], size[3]; + + size[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]); + size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]); + size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]); + + vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0]; + vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = +size[0]; + vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = -size[1]; + vec[2][1] = vec[3][1] = vec[6][1] = vec[7][1] = +size[1]; + vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2]; + vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2]; + + draw_box(vec); + } + else { + draw_bb_quadric(bb, type, true); + } + } + else { + if (type == OB_BOUND_BOX) + draw_box(bb->vec); + else + draw_bb_quadric(bb, type, false); + } } static void drawtexspace(Object *ob) @@ -6565,6 +6596,48 @@ static void draw_object_matcap_check(Scene *scene, View3D *v3d, Object *ob) } +static void draw_rigidbody_shape(Object *ob) +{ + BoundBox *bb = NULL; + float size[3], vec[8][3]; + + if (ob->type == OB_MESH) { + bb = BKE_mesh_boundbox_get(ob); + } + + if (bb == NULL) + return; + + switch (ob->rigidbody_object->shape) { + case RB_SHAPE_BOX: + size[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]); + size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]); + size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]); + + vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0]; + vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = +size[0]; + vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = -size[1]; + vec[2][1] = vec[3][1] = vec[6][1] = vec[7][1] = +size[1]; + vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2]; + vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2]; + + draw_box(vec); + break; + case RB_SHAPE_SPHERE: + draw_bb_quadric(bb, OB_BOUND_SPHERE, true); + break; + case RB_SHAPE_CONE: + draw_bb_quadric(bb, OB_BOUND_CONE, true); + break; + case RB_SHAPE_CYLINDER: + draw_bb_quadric(bb, OB_BOUND_CYLINDER, true); + break; + case RB_SHAPE_CAPSULE: + draw_bb_quadric(bb, OB_BOUND_CAPSULE, true); + break; + } +} + /** * main object drawing function, draws in selection * \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET @@ -7129,6 +7202,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short setlinestyle(0); } } + if (ob->rigidbody_object) { + draw_rigidbody_shape(ob); + } /* draw extra: after normal draw because of makeDispList */ if (dtx && (G.f & G_RENDER_OGL) == 0) { diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 2e98058639b..dcbcb127f5c 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1543,7 +1543,7 @@ static int game_engine_exec(bContext *C, wmOperator *op) //XXX restore_all_scene_cfra(scene_cfra_store); BKE_scene_set_background(CTX_data_main(C), startscene); - //XXX BKE_scene_update_for_newframe_viewport(bmain, scene, scene->lay); + //XXX BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay); BLI_callback_exec(bmain, &startscene->id, BLI_CB_EVT_GAME_POST); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index e6e46c569e9..4bd4db9849b 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -6382,6 +6382,10 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t) /* count */ t->total = 0; + if ((sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) == 0) { + return; + } + track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c index ff65e11f53e..e8146c34f5e 100644 --- a/source/blender/editors/util/crazyspace.c +++ b/source/blender/editors/util/crazyspace.c @@ -344,7 +344,7 @@ int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformma if (mti->type == eModifierTypeType_OnlyDeform) { if (!defmats) { Mesh *me = (Mesh *)ob->data; - dm = mesh_create_derived(me, ob, NULL); + dm = mesh_create_derived(me, NULL); deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); defmats = MEM_callocN(sizeof(*defmats) * numVerts, "defmats"); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index cc8a453c169..6ca3e1ae2a9 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -1318,13 +1318,11 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l handle->float_colorspace = init_data->float_colorspace; } -static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle, int start_scanline, int num_scanlines, +static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle, int height, float *linear_buffer, bool *is_straight_alpha) { int channels = handle->channels; int width = handle->width; - int height = num_scanlines; - int scanline_offset = channels * start_scanline * width; int buffer_size = channels * width * height; @@ -1342,7 +1340,7 @@ static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle, int i; /* first convert byte buffer to float, keep in image space */ - for (i = 0, fp = linear_buffer, cp = byte_buffer + scanline_offset; + for (i = 0, fp = linear_buffer, cp = byte_buffer; i < width * height; i++, fp += channels, cp += channels) { @@ -1375,7 +1373,7 @@ static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle, const char *from_colorspace = handle->float_colorspace; const char *to_colorspace = global_role_scene_linear; - memcpy(linear_buffer, handle->buffer + scanline_offset, buffer_size * sizeof(float)); + memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float)); if (!is_data && !is_data_display) { IMB_colormanagement_transform(linear_buffer, width, height, channels, @@ -1391,7 +1389,7 @@ static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle, * using duplicated buffer here */ - memcpy(linear_buffer, handle->buffer + scanline_offset, buffer_size * sizeof(float)); + memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float)); *is_straight_alpha = false; } @@ -1421,69 +1419,50 @@ static void *do_display_buffer_apply_thread(void *handle_v) } } else { -#define SCANLINE_BLOCK_SIZE 64 - /* TODO(sergey): Instead of nasty scanline-blocking in per-scanline-block thread we might - * better to use generic task scheduler, but that would need extra testing - * before deploying into production. - */ - - int scanlines = (height + SCANLINE_BLOCK_SIZE - 1) / SCANLINE_BLOCK_SIZE; - int i; - float *linear_buffer = MEM_mallocN(channels * width * SCANLINE_BLOCK_SIZE * sizeof(float), + bool is_straight_alpha, predivide; + float *linear_buffer = MEM_mallocN(channels * width * height * sizeof(float), "color conversion linear buffer"); - for (i = 0; i < scanlines; i ++) { - int start_scanline = i * SCANLINE_BLOCK_SIZE; - int num_scanlines = (i == scanlines - 1) ? - (height - SCANLINE_BLOCK_SIZE * i) : - SCANLINE_BLOCK_SIZE; - int scanline_offset = channels * start_scanline * width; - int scanline_offset4 = 4 * start_scanline * width; - bool is_straight_alpha, predivide; - - display_buffer_apply_get_linear_buffer(handle, start_scanline, num_scanlines, - linear_buffer, &is_straight_alpha); - predivide = is_straight_alpha == false; - - if (is_data) { - /* special case for data buffers - no color space conversions, - * only generate byte buffers - */ - } - else { - /* apply processor */ - IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, num_scanlines, channels, - predivide); - } + display_buffer_apply_get_linear_buffer(handle, height, linear_buffer, &is_straight_alpha); - /* copy result to output buffers */ - if (display_buffer_byte) { - /* do conversion */ - IMB_buffer_byte_from_float(display_buffer_byte + scanline_offset4, linear_buffer, - channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, - predivide, width, num_scanlines, width, width); - } + predivide = is_straight_alpha == false; + + if (is_data) { + /* special case for data buffers - no color space conversions, + * only generate byte buffers + */ + } + else { + /* apply processor */ + IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, + predivide); + } - if (display_buffer) { - memcpy(display_buffer + scanline_offset, linear_buffer, width * num_scanlines * channels * sizeof(float)); + /* copy result to output buffers */ + if (display_buffer_byte) { + /* do conversion */ + IMB_buffer_byte_from_float(display_buffer_byte, linear_buffer, + channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, + predivide, width, height, width, width); + } - if (is_straight_alpha && channels == 4) { - int i; - float *fp; + if (display_buffer) { + memcpy(display_buffer, linear_buffer, width * height * channels * sizeof(float)); - for (i = 0, fp = display_buffer; - i < width * num_scanlines; - i++, fp += channels) - { - straight_to_premul_v4(fp); - } + if (is_straight_alpha && channels == 4) { + int i; + float *fp; + + for (i = 0, fp = display_buffer; + i < width * height; + i++, fp += channels) + { + straight_to_premul_v4(fp); } } } MEM_freeN(linear_buffer); - -#undef SCANLINE_BLOCK_SIZE } return NULL; diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 71d5f5150ad..e0a6e034f94 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -41,7 +41,7 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -#include "BLI_threads.h" +#include "BLI_task.h" #include "BLI_listbase.h" #include "BLI_math.h" @@ -288,48 +288,54 @@ void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in /*********************** Threaded image processing *************************/ +static void processor_apply_func(TaskPool *pool, void *taskdata, int UNUSED(threadid)) +{ + void (*do_thread) (void *) = (void (*) (void *)) BLI_task_pool_userdata(pool); + do_thread(taskdata); +} + void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata, void (init_handle) (void *handle, int start_line, int tot_line, void *customdata), void *(do_thread) (void *)) { - void *handles; - ListBase threads; + const int lines_per_task = 64; + + TaskScheduler *task_scheduler = BLI_task_scheduler_get(); + TaskPool *task_pool; - int i, tot_thread = BLI_system_thread_count(); - int start_line, tot_line; + void *handles; + int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task; + int i, start_line; - handles = MEM_callocN(handle_size * tot_thread, "processor apply threaded handles"); + task_pool = BLI_task_pool_create(task_scheduler, do_thread); - if (tot_thread > 1) - BLI_init_threads(&threads, do_thread, tot_thread); + handles = MEM_callocN(handle_size * total_tasks, "processor apply threaded handles"); start_line = 0; - tot_line = ((float)(buffer_lines / tot_thread)) + 0.5f; - for (i = 0; i < tot_thread; i++) { - int cur_tot_line; + for (i = 0; i < total_tasks; i++) { + int lines_per_current_task; void *handle = ((char *) handles) + handle_size * i; - if (i < tot_thread - 1) - cur_tot_line = tot_line; + if (i < total_tasks - 1) + lines_per_current_task = lines_per_task; else - cur_tot_line = buffer_lines - start_line; + lines_per_current_task = buffer_lines - start_line; - init_handle(handle, start_line, cur_tot_line, init_customdata); + init_handle(handle, start_line, lines_per_current_task, init_customdata); - if (tot_thread > 1) - BLI_insert_thread(&threads, handle); + BLI_task_pool_push(task_pool, processor_apply_func, handle, false, TASK_PRIORITY_LOW); - start_line += tot_line; + start_line += lines_per_task; } - if (tot_thread > 1) - BLI_end_threads(&threads); - else - do_thread(handles); + /* work and wait until tasks are done */ + BLI_task_pool_work_and_wait(task_pool); + /* Free memory. */ MEM_freeN(handles); + BLI_task_pool_free(task_pool); } /* Alpha-under */ diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h index 4a96c324f04..5d76ffe57b5 100644 --- a/source/blender/makesdna/DNA_rigidbody_types.h +++ b/source/blender/makesdna/DNA_rigidbody_types.h @@ -103,7 +103,8 @@ typedef struct RigidBodyOb { int flag; /* (eRigidBodyOb_Flag) */ int col_groups; /* Collision groups that determines wich rigid bodies can collide with each other */ - int pad; + short mesh_source; /* (eRigidBody_MeshSource) mesh source for mesh based collision shapes */ + short pad; /* Physics Parameters */ float mass; /* how much object 'weighs' (i.e. absolute 'amount of stuff' it holds) */ @@ -148,7 +149,9 @@ typedef enum eRigidBodyOb_Flag { /* rigidbody is not dynamically simulated */ RBO_FLAG_DISABLED = (1 << 5), /* collision margin is not embedded (only used by convex hull shapes for now) */ - RBO_FLAG_USE_MARGIN = (1 << 6) + RBO_FLAG_USE_MARGIN = (1 << 6), + /* collision shape deforms during simulation (only for passive triangle mesh shapes) */ + RBO_FLAG_USE_DEFORM = (1 << 7) } eRigidBodyOb_Flag; /* RigidBody Collision Shape */ @@ -173,6 +176,15 @@ typedef enum eRigidBody_Shape { //RB_SHAPE_COMPOUND, } eRigidBody_Shape; +typedef enum eRigidBody_MeshSource { + /* base mesh */ + RBO_MESH_BASE = 0, + /* only deformations */ + RBO_MESH_DEFORM, + /* final derived mesh */ + RBO_MESH_FINAL +} eRigidBody_MeshSource; + /* ******************************** */ /* RigidBody Constraint */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 9038885f6af..f2dc4dce11f 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1107,27 +1107,28 @@ typedef struct SpaceClip { /* SpaceClip->flag */ typedef enum eSpaceClip_Flag { - SC_SHOW_MARKER_PATTERN = (1 << 0), - SC_SHOW_MARKER_SEARCH = (1 << 1), - SC_LOCK_SELECTION = (1 << 2), - SC_SHOW_TINY_MARKER = (1 << 3), - SC_SHOW_TRACK_PATH = (1 << 4), - SC_SHOW_BUNDLES = (1 << 5), - SC_MUTE_FOOTAGE = (1 << 6), - SC_HIDE_DISABLED = (1 << 7), - SC_SHOW_NAMES = (1 << 8), - SC_SHOW_GRID = (1 << 9), - SC_SHOW_STABLE = (1 << 10), - SC_MANUAL_CALIBRATION = (1 << 11), - SC_SHOW_GPENCIL = (1 << 12), - SC_SHOW_FILTERS = (1 << 13), - SC_SHOW_GRAPH_FRAMES = (1 << 14), - SC_SHOW_GRAPH_TRACKS = (1 << 15), -/* SC_SHOW_PYRAMID_LEVELS = (1 << 16), */ /* UNUSED */ - SC_LOCK_TIMECURSOR = (1 << 17), - SC_SHOW_SECONDS = (1 << 18), - SC_SHOW_GRAPH_SEL_ONLY = (1 << 19), - SC_SHOW_GRAPH_HIDDEN = (1 << 20), + SC_SHOW_MARKER_PATTERN = (1 << 0), + SC_SHOW_MARKER_SEARCH = (1 << 1), + SC_LOCK_SELECTION = (1 << 2), + SC_SHOW_TINY_MARKER = (1 << 3), + SC_SHOW_TRACK_PATH = (1 << 4), + SC_SHOW_BUNDLES = (1 << 5), + SC_MUTE_FOOTAGE = (1 << 6), + SC_HIDE_DISABLED = (1 << 7), + SC_SHOW_NAMES = (1 << 8), + SC_SHOW_GRID = (1 << 9), + SC_SHOW_STABLE = (1 << 10), + SC_MANUAL_CALIBRATION = (1 << 11), + SC_SHOW_GPENCIL = (1 << 12), + SC_SHOW_FILTERS = (1 << 13), + SC_SHOW_GRAPH_FRAMES = (1 << 14), + SC_SHOW_GRAPH_TRACKS_MOTION = (1 << 15), +/* SC_SHOW_PYRAMID_LEVELS = (1 << 16), */ /* UNUSED */ + SC_LOCK_TIMECURSOR = (1 << 17), + SC_SHOW_SECONDS = (1 << 18), + SC_SHOW_GRAPH_SEL_ONLY = (1 << 19), + SC_SHOW_GRAPH_HIDDEN = (1 << 20), + SC_SHOW_GRAPH_TRACKS_ERROR = (1 << 21), } eSpaceClip_Flag; /* SpaceClip->mode */ diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 35be44c4090..1710f9e81af 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -969,7 +969,7 @@ static int make_structDNA(const char *baseDirectory, FILE *file) names = MEM_callocN(sizeof(char *) * maxnr, "names"); types = MEM_callocN(sizeof(char *) * maxnr, "types"); typelens_native = MEM_callocN(sizeof(short) * maxnr, "typelens_native"); - typelens_32 = MEM_callocN(sizeof(short) * maxnr, "typelens_64"); + typelens_32 = MEM_callocN(sizeof(short) * maxnr, "typelens_32"); typelens_64 = MEM_callocN(sizeof(short) * maxnr, "typelens_64"); structs = MEM_callocN(sizeof(short *) * maxnr, "structs"); @@ -981,7 +981,7 @@ static int make_structDNA(const char *baseDirectory, FILE *file) add_type("short", 2); /* SDNA_TYPE_SHORT */ add_type("ushort", 2); /* SDNA_TYPE_USHORT */ add_type("int", 4); /* SDNA_TYPE_INT */ - add_type("long", 4); /* SDNA_TYPE_LONG */ /* should it be 8 on 64 bits? */ + add_type("long", 4); /* SDNA_TYPE_LONG */ /* maybe 4 or 8 bytes depending on platform, disallowed for now */ add_type("ulong", 4); /* SDNA_TYPE_ULONG */ add_type("float", 4); /* SDNA_TYPE_FLOAT */ add_type("double", 8); /* SDNA_TYPE_DOUBLE */ diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 6a43fed3ac6..b7b793ebeaf 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -42,6 +42,22 @@ /* all the list begin functions are added manually here, Main is not in SDNA */ +static int rna_Main_use_autopack_get(PointerRNA *UNUSED(ptr)) +{ + if (G.fileflags & G_AUTOPACK) + return 1; + + return 0; +} + +static void rna_Main_use_autopack_set(PointerRNA *UNUSED(ptr), int value) +{ + if (value) + G.fileflags |= G_AUTOPACK; + else + G.fileflags &= ~G_AUTOPACK; +} + static int rna_Main_is_saved_get(PointerRNA *UNUSED(ptr)) { return G.relbase_valid; @@ -356,6 +372,10 @@ void RNA_def_main(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_Main_is_saved_get", NULL); RNA_def_property_ui_text(prop, "File is Saved", "Has the current session been saved to disk as a .blend file"); + prop = RNA_def_property(srna, "use_autopack", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_Main_use_autopack_get", "rna_Main_use_autopack_set"); + RNA_def_property_ui_text(prop, "Use Autopack", "Automatically pack all external data into .blend file"); + for (i = 0; lists[i].name; i++) { prop = RNA_def_property(srna, lists[i].identifier, PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, lists[i].type); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 84ee2b1402e..de002bdfd2c 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -80,7 +80,7 @@ EnumPropertyItem modifier_type_items[] = { {eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""}, {eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""}, {eModifierType_Triangulate, "TRIANGULATE", ICON_MOD_TRIANGULATE, "Triangulate", ""}, - {eModifierType_Wireframe, "WIREFRAME", ICON_MOD_WIREFRAME, "Wireframe", "Generates a wireframe on the edges of a mesh"}, + {eModifierType_Wireframe, "WIREFRAME", ICON_MOD_WIREFRAME, "Wireframe", "Generate a wireframe on the edges of a mesh"}, {0, "", 0, N_("Deform"), ""}, {eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""}, {eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""}, diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 8cd3252fe10..85e0d91fc71 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -386,7 +386,7 @@ void rna_Object_dm_info(struct Object *ob, int type, char *result) switch (type) { case 0: if (ob->type == OB_MESH) { - dm = CDDM_from_mesh(ob->data, ob); + dm = CDDM_from_mesh(ob->data); ret = DM_debug_info(dm); dm_release = TRUE; } diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index cc14e60f45a..58fc9ab25d4 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -76,6 +76,13 @@ EnumPropertyItem rigidbody_constraint_type_items[] = { {RBC_TYPE_MOTOR, "MOTOR", ICON_NONE, "Motor", "Drive rigid body around or along an axis"}, {0, NULL, 0, NULL, NULL}}; +/* mesh source for collision shape creation */ +EnumPropertyItem rigidbody_mesh_source_items[] = { + {RBO_MESH_BASE, "BASE", 0, "Base", "Base mesh"}, + {RBO_MESH_DEFORM, "DEFORM", 0, "Deform", "Deformations (shaps keys, deform modifiers"}, + {RBO_MESH_FINAL, "FINAL", 0, "Final", "All modifiers"}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME @@ -769,6 +776,13 @@ static void rna_def_rigidbody_object(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "mesh_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mesh_source"); + RNA_def_property_enum_items(prop, rigidbody_mesh_source_items); + RNA_def_property_ui_text(prop, "Mesh Source", "Source of the mesh used to create collision shape"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset"); + /* booleans */ prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", RBO_FLAG_DISABLED); @@ -790,6 +804,11 @@ static void rna_def_rigidbody_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Kinematic", "Allow rigid body to be controlled by the animation system"); RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "use_deform", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_USE_DEFORM); + RNA_def_property_ui_text(prop, "Deforming", "Rigid body deforms during simulation"); + RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset"); + /* Physics Parameters */ prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_UNIT_MASS); RNA_def_property_float_sdna(prop, NULL, "mass"); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index fdaf204be23..ae6b2e75658 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3745,14 +3745,21 @@ static void rna_def_space_clip(BlenderRNA *brna) "Show curve for per-frame average error (camera motion should be solved first)"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); - /* show graph_tracks */ - prop = RNA_def_property(srna, "show_graph_tracks", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS); - RNA_def_property_ui_text(prop, "Show Tracks", + /* show graph tracks motion */ + prop = RNA_def_property(srna, "show_graph_tracks_motion", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS_MOTION); + RNA_def_property_ui_text(prop, "Show Tracks Motion", "Display the speed curves (in \"x\" direction red, in \"y\" direction green) " "for the selected tracks"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* show graph tracks motion */ + prop = RNA_def_property(srna, "show_graph_tracks_error", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS_ERROR); + RNA_def_property_ui_text(prop, "Show Tracks Error", + "Display the reprojection error curve for selected tracks"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* show_only_selected */ prop = RNA_def_property(srna, "show_graph_only_selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_SEL_ONLY); diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 3ab7bff0e63..e81fc44f238 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -179,7 +179,7 @@ static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedDat ArmatureModifierData *amd = (ArmatureModifierData *) md; DerivedMesh *dm = derivedData; - if (!derivedData) dm = CDDM_from_mesh((Mesh *)ob->data, ob); + if (!derivedData) dm = CDDM_from_mesh((Mesh *)ob->data); armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts, amd->deformflag, NULL, amd->defgrp_name); diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 9335d7577c7..1f24662960a 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -116,7 +116,7 @@ static void deformVerts(ModifierData *md, Object *ob, /* if possible use/create DerivedMesh */ if (derivedData) dm = CDDM_copy(derivedData); - else if (ob->type == OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + else if (ob->type == OB_MESH) dm = CDDM_from_mesh(ob->data); if (!ob->pd) { printf("CollisionModifier deformVerts: Should not happen!\n"); diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index e754ac8f766..1d5dc29c119 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -96,14 +96,15 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, + DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { MaskModifierData *mmd = (MaskModifierData *)md; - DerivedMesh *dm = derivedData, *result = NULL; + const bool found_test = (mmd->flag & MOD_MASK_INV) == 0; + DerivedMesh *result = NULL; GHash *vertHash = NULL, *edgeHash, *polyHash; GHashIterator *hashIter; - MDeformVert *dvert = NULL, *dv; + MDeformVert *dvert, *dv; int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0; int maxVerts, maxEdges, maxPolys; int i; @@ -119,6 +120,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int *loop_mapping; + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + if (dvert == NULL) { + return found_test ? CDDM_from_template(dm, 0, 0, 0, 0, 0) : dm; + } + /* Overview of Method: * 1. Get the vertices that are in the vertexgroup of interest * 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices @@ -136,7 +142,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (maxVerts == 0) || (ob->defbase.first == NULL) ) { - return derivedData; + return dm; } /* if mode is to use selected armature bones, aggregate the bone groups */ @@ -150,7 +156,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* check that there is armature object with bones to use, otherwise return original mesh */ if (ELEM3(NULL, oba, oba->pose, ob->defbase.first)) - return derivedData; + return dm; /* determine whether each vertexgroup is associated with a selected bone or not * - each cell is a boolean saying whether bone corresponding to the ith group is selected @@ -168,16 +174,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, bone_select_array[i] = FALSE; } } - - /* if no dverts (i.e. no data for vertex groups exists), we've got an - * inconsistent situation, so free hashes and return original mesh - */ - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - if (dvert == NULL) { - MEM_freeN(bone_select_array); - return derivedData; - } - + /* verthash gives mapping from original vertex indices to the new indices (including selected matches only) * key = oldindex, value = newindex */ @@ -189,7 +186,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, */ for (i = 0, dv = dvert; i < maxVerts; i++, dv++) { MDeformWeight *dw = dv->dw; - short found = 0; + bool found = false; int j; /* check the groups that vertex is assigned to, and see if it was any use */ @@ -204,14 +201,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } } - /* check if include vert in vertHash */ - if (mmd->flag & MOD_MASK_INV) { - /* if this vert is in the vgroup, don't include it in vertHash */ - if (found) continue; - } - else { - /* if this vert isn't in the vgroup, don't include it in vertHash */ - if (!found) continue; + if (found_test != found) { + continue; } /* add to ghash for verts (numVerts acts as counter for mapping) */ @@ -224,13 +215,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } else { /* --- Using Nominated VertexGroup only --- */ int defgrp_index = defgroup_name_index(ob, mmd->vgroup); - - /* get dverts */ - if (defgrp_index != -1) - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - + /* if no vgroup (i.e. dverts) found, return the initial mesh */ - if ((defgrp_index == -1) || (dvert == NULL)) + if (defgrp_index == -1) return dm; /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ @@ -238,18 +225,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* add vertices which exist in vertexgroup into ghash for filtering */ for (i = 0, dv = dvert; i < maxVerts; i++, dv++) { - const int weight_set = defvert_find_weight(dv, defgrp_index) != 0.0f; - - /* check if include vert in vertHash */ - if (mmd->flag & MOD_MASK_INV) { - /* if this vert is in the vgroup, don't include it in vertHash */ - if (weight_set) continue; + const bool found = defvert_find_weight(dv, defgrp_index) != 0.0f; + if (found_test != found) { + continue; } - else { - /* if this vert isn't in the vgroup, don't include it in vertHash */ - if (!weight_set) continue; - } - + /* add to ghash for verts (numVerts acts as counter for mapping) */ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts)); numVerts++; diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 0c3746fc570..c087a7870c0 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -183,7 +183,7 @@ DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, } else if (ob->type == OB_MESH) { if (em) dm = CDDM_from_editbmesh(em, FALSE, FALSE); - else dm = CDDM_from_mesh((struct Mesh *)(ob->data), ob); + else dm = CDDM_from_mesh((struct Mesh *)(ob->data)); if (vertexCos) { CDDM_apply_vert_coords(dm, vertexCos); diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 06f4664c11b..ecb99974472 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -473,7 +473,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der if (me->edit_btmesh) target_dm = CDDM_from_editbmesh(me->edit_btmesh, FALSE, FALSE); else - target_dm = CDDM_from_mesh(me, obr); + target_dm = CDDM_from_mesh(me); } free_target_dm = TRUE; } diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c index af228ca5f57..3ebd9bd38fd 100644 --- a/source/blender/modifiers/intern/MOD_wireframe.c +++ b/source/blender/modifiers/intern/MOD_wireframe.c @@ -75,7 +75,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) } -static DerivedMesh* WireframeModifier_do( WireframeModifierData *wmd, Object *ob, DerivedMesh *dm) +static DerivedMesh *WireframeModifier_do( WireframeModifierData *wmd, Object *ob, DerivedMesh *dm) { DerivedMesh *result; BMesh *bm; diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c index d228e1a0646..236d6badd55 100644 --- a/source/blender/python/bmesh/bmesh_py_utils.c +++ b/source/blender/python/bmesh/bmesh_py_utils.c @@ -401,6 +401,7 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args, BMesh *bm; BMFace *f_new = NULL; BMLoop *l_new = NULL; + BMLoop *l_a, *l_b; if (!PyArg_ParseTupleAndKeywords(args, kw, "O!O!O!|OiO!:face_split", (char **)kwlist, &BPy_BMFace_Type, &py_face, @@ -422,9 +423,12 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args, } /* this doubles for checking that the verts are in the same mesh */ - if (BM_vert_in_face(py_face->f, py_vert_a->v) == false || - BM_vert_in_face(py_face->f, py_vert_b->v) == false) + if ((l_a = BM_face_vert_share_loop(py_face->f, py_vert_a->v)) && + (l_b = BM_face_vert_share_loop(py_face->f, py_vert_b->v))) { + /* pass */ + } + else { PyErr_SetString(PyExc_ValueError, "face_split(...): one of the verts passed is not found in the face"); return NULL; @@ -448,14 +452,14 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args, if (ncoords) { f_new = BM_face_split_n(bm, py_face->f, - py_vert_a->v, py_vert_b->v, + l_a, l_b, (float (*)[3])coords, ncoords, &l_new, py_edge_example ? py_edge_example->e : NULL); PyMem_Free(coords); } else { f_new = BM_face_split(bm, py_face->f, - py_vert_a->v, py_vert_b->v, + l_a, l_b, &l_new, py_edge_example ? py_edge_example->e : NULL, edge_exists); } diff --git a/source/blender/python/generic/bpy_threads.c b/source/blender/python/generic/bpy_threads.c index 610c1846f56..63a47ff0b20 100644 --- a/source/blender/python/generic/bpy_threads.c +++ b/source/blender/python/generic/bpy_threads.c @@ -27,14 +27,6 @@ * these functions are slightly different from the original Python API, * don't throw SIGABRT even if the thread state is NULL. */ -/** \file blender/python/intern/bpy_interface.c - * \ingroup pythonintern - * - * This file deals with embedding the python interpreter within blender, - * starting and stopping python and exposing blender/python modules so they can - * be accesses from scripts. - */ - /* grr, python redefines */ #ifdef _POSIX_C_SOURCE # undef _POSIX_C_SOURCE diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index afff90feb49..78434427b18 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1612,6 +1612,7 @@ static bool rlayer_node_uses_alpha(bNodeTree *ntree, bNode *node) */ #define DEPSGRAPH_WORKAROUND_HACK +#ifdef DEPSGRAPH_WORKAROUND_HACK static bool allow_render_mesh_object(Object *ob) { /* override not showing object when duplis are used with particles */ @@ -1625,7 +1626,6 @@ static bool allow_render_mesh_object(Object *ob) return true; } -#ifdef DEPSGRAPH_WORKAROUND_HACK static void tag_dependend_objects_for_render(Scene *scene, int renderlay) { Scene *sce_iter; |