diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 29 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 79 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 120 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 2 |
12 files changed, 186 insertions, 115 deletions
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); |