Revision: 19744 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19744 Author: jaguarandi Date: 2009-04-15 21:33:25 +0200 (Wed, 15 Apr 2009)
Log Message: ----------- Merging Shrinkwrap Constraint! +bvhtree cache (if the derived model doenst gets destroyed then the same BVHtree can be used) this was needed to allow shrinkwrap constraint to be usable. It has been ready for a long time.. but only got merged now, for 2.49. Modified Paths: -------------- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h trunk/blender/source/blender/blenkernel/BKE_bvhutils.h trunk/blender/source/blender/blenkernel/BKE_shrinkwrap.h trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c trunk/blender/source/blender/blenkernel/intern/bvhutils.c trunk/blender/source/blender/blenkernel/intern/constraint.c trunk/blender/source/blender/blenkernel/intern/shrinkwrap.c trunk/blender/source/blender/blenloader/intern/readfile.c trunk/blender/source/blender/include/butspace.h trunk/blender/source/blender/makesdna/DNA_constraint_types.h trunk/blender/source/blender/src/buttons_editing.c trunk/blender/source/blender/src/buttons_object.c trunk/blender/source/blender/src/editconstraint.c Modified: trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h =================================================================== --- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h 2009-04-15 19:20:12 UTC (rev 19743) +++ trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h 2009-04-15 19:33:25 UTC (rev 19744) @@ -44,6 +44,7 @@ #include "DNA_customdata_types.h" #include "BKE_customdata.h" +#include "BKE_bvhutils.h" struct MVert; struct MEdge; @@ -69,6 +70,7 @@ int numVertData, numEdgeData, numFaceData; int needsFree; /* checked on ->release, is set to 0 for cached results */ int deformedOnly; /* set by modifier stack if only deformed from original */ + BVHCache bvhCache; /* Misc. Queries */ Modified: trunk/blender/source/blender/blenkernel/BKE_bvhutils.h =================================================================== --- trunk/blender/source/blender/blenkernel/BKE_bvhutils.h 2009-04-15 19:20:12 UTC (rev 19743) +++ trunk/blender/source/blender/blenkernel/BKE_bvhutils.h 2009-04-15 19:33:25 UTC (rev 19744) @@ -31,6 +31,7 @@ #define BKE_BVHUTILS_H #include "BLI_kdopbvh.h" +#include "BLI_linklist.h" /* * This header encapsulates necessary code to buld a BVH @@ -52,7 +53,7 @@ BVHTree_RayCastCallback raycast_callback; /* Mesh represented on this BVHTree */ - struct DerivedMesh *mesh; + struct DerivedMesh *mesh; /* Vertex array, so that callbacks have instante access to data */ struct MVert *vert; @@ -61,6 +62,9 @@ /* radius for raycast */ float sphere_radius; + /* Private data */ + int cached; + } BVHTreeFromMesh; /* @@ -74,7 +78,7 @@ * * free_bvhtree_from_mesh should be called when the tree is no longer needed. */ -void bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); +BVHTree* bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); /* * Builds a bvh tree where nodes are the faces of the given mesh. @@ -84,15 +88,50 @@ * so that the coordinates and rays are first translated on the mesh local coordinates. * Reason for this is that later bvh_from_mesh_* might use a cache system and so it becames possible to reuse * a BVHTree. + * + * The returned value is the same as in data->tree, its only returned to make it easier to test + * the success * * free_bvhtree_from_mesh should be called when the tree is no longer needed. */ -void bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); +BVHTree* bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); /* * Frees data allocated by a call to bvhtree_from_mesh_*. */ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data); + +/* + * BVHCache + */ + +//Using local coordinates +#define BVHTREE_FROM_FACES 0 +#define BVHTREE_FROM_VERTICES 1 + +typedef LinkNode* BVHCache; + + +/* + * Queries a bvhcache for the chache bvhtree of the request type + */ +BVHTree *bvhcache_find(BVHCache *cache, int type); + +/* + * Inserts a BVHTree of the given type under the cache + * After that the caller no longer needs to worry when to free the BVHTree + * as that will be done when the cache is freed. + * + * A call to this assumes that there was no previous cached tree of the given type + */ +void bvhcache_insert(BVHCache *cache, BVHTree *tree, int type); + +/* + * inits and frees a bvhcache + */ +void bvhcache_init(BVHCache *cache); +void bvhcache_free(BVHCache *cache); + #endif Modified: trunk/blender/source/blender/blenkernel/BKE_shrinkwrap.h =================================================================== --- trunk/blender/source/blender/blenkernel/BKE_shrinkwrap.h 2009-04-15 19:20:12 UTC (rev 19743) +++ trunk/blender/source/blender/blenkernel/BKE_shrinkwrap.h 2009-04-15 19:33:25 UTC (rev 19744) @@ -95,6 +95,8 @@ struct Object; struct DerivedMesh; +struct MVert; +struct MDeformVert; struct ShrinkwrapModifierData; struct MDeformVert; struct BVHTree; @@ -105,8 +107,8 @@ ShrinkwrapModifierData *smd; //shrinkwrap modifier data struct Object *ob; //object we are applying shrinkwrap to - struct DerivedMesh *original; //mesh before shrinkwrap + MVert *vert; //Array of verts being projected (to fetch normals or other data) float (*vertexCos)[3]; //vertexs being shrinkwraped int numVerts; Modified: trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c =================================================================== --- trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c 2009-04-15 19:20:12 UTC (rev 19743) +++ trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c 2009-04-15 19:33:25 UTC (rev 19744) @@ -77,6 +77,7 @@ #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_particle.h" +#include "BKE_bvhutils.h" #include "BLO_sys_types.h" // for intptr_t support @@ -182,6 +183,8 @@ dm->getVertDataArray = DM_get_vert_data_layer; dm->getEdgeDataArray = DM_get_edge_data_layer; dm->getFaceDataArray = DM_get_face_data_layer; + + bvhcache_init(&dm->bvhCache); } void DM_init(DerivedMesh *dm, @@ -218,6 +221,8 @@ int DM_release(DerivedMesh *dm) { if (dm->needsFree) { + bvhcache_free(&dm->bvhCache); + CustomData_free(&dm->vertData, dm->numVertData); CustomData_free(&dm->edgeData, dm->numEdgeData); CustomData_free(&dm->faceData, dm->numFaceData); Modified: trunk/blender/source/blender/blenkernel/intern/bvhutils.c =================================================================== --- trunk/blender/source/blender/blenkernel/intern/bvhutils.c 2009-04-15 19:20:12 UTC (rev 19743) +++ trunk/blender/source/blender/blenkernel/intern/bvhutils.c 2009-04-15 19:33:25 UTC (rev 19744) @@ -30,6 +30,7 @@ #include <stdio.h> #include <string.h> #include <math.h> +#include <assert.h> #include "BKE_bvhutils.h" @@ -45,6 +46,8 @@ #include "BKE_global.h" #include "BLI_arithb.h" +#include "BLI_linklist.h" +#include "MEM_guardedalloc.h" /* Math stuff for ray casting on mesh faces and for nearest surface */ @@ -480,30 +483,47 @@ * BVH builders */ // Builds a bvh tree.. where nodes are the vertexs of the given mesh -void bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) +BVHTree* bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) { - int i; - int numVerts= mesh->getNumVerts(mesh); - MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); - BVHTree *tree = NULL; + BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_VERTICES); - memset(data, 0, sizeof(*data)); + //Not in cache + if(tree == NULL) + { + int i; + int numVerts= mesh->getNumVerts(mesh); + MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); - if(vert == NULL) + if(vert != NULL) + { + tree = BLI_bvhtree_new(numVerts, epsilon, tree_type, axis); + + if(tree != NULL) + { + for(i = 0; i < numVerts; i++) + BLI_bvhtree_insert(tree, i, vert[i].co, 1); + + BLI_bvhtree_balance(tree); + + //Save on cache for later use +// printf("BVHTree built and saved on cache\n"); + bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_VERTICES); + } + } + } + else { - printf("bvhtree cant be build: cant get a vertex array"); - return; +// printf("BVHTree is already build, using cached tree\n"); } - tree = BLI_bvhtree_new(numVerts, epsilon, tree_type, axis); - if(tree != NULL) - { - for(i = 0; i < numVerts; i++) - BLI_bvhtree_insert(tree, i, vert[i].co, 1); - BLI_bvhtree_balance(tree); + //Setup BVHTreeFromMesh + memset(data, 0, sizeof(*data)); + data->tree = tree; - data->tree = tree; + if(data->tree) + { + data->cached = TRUE; //a NULL nearest callback works fine //remeber the min distance to point is the same as the min distance to BV of point @@ -516,43 +536,62 @@ data->sphere_radius = epsilon; } + + return data->tree; } // Builds a bvh tree.. where nodes are the faces of the given mesh. -void bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) +BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) { - int i; - int numFaces= mesh->getNumFaces(mesh); - MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); - MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE); - BVHTree *tree = NULL; + BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_FACES); - memset(data, 0, sizeof(*data)); - - if(vert == NULL && face == NULL) + //Not in cache + if(tree == NULL) { - printf("bvhtree cant be build: cant get a vertex/face array"); - return; - } + int i; + int numFaces= mesh->getNumFaces(mesh); + MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); + MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE); - /* Create a bvh-tree of the given target */ - tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis); - if(tree != NULL) - { - for(i = 0; i < numFaces; i++) + if(vert != NULL && face != NULL) { - float co[4][3]; - VECCOPY(co[0], vert[ face[i].v1 ].co); - VECCOPY(co[1], vert[ face[i].v2 ].co); - VECCOPY(co[2], vert[ face[i].v3 ].co); - if(face[i].v4) - VECCOPY(co[3], vert[ face[i].v4 ].co); + /* Create a bvh-tree of the given target */ + tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis); + if(tree != NULL) + { + for(i = 0; i < numFaces; i++) + { + float co[4][3]; + VECCOPY(co[0], vert[ face[i].v1 ].co); + VECCOPY(co[1], vert[ face[i].v2 ].co); + VECCOPY(co[2], vert[ face[i].v3 ].co); + if(face[i].v4) + VECCOPY(co[3], vert[ face[i].v4 ].co); - BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); + BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); + } + BLI_bvhtree_balance(tree); + + //Save on cache for later use +// printf("BVHTree built and saved on cache\n"); + bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_FACES); + } } - BLI_bvhtree_balance(tree); + } + else + { +// printf("BVHTree is already build, using cached tree\n"); + } - data->tree = tree; + + //Setup BVHTreeFromMesh + memset(data, 0, sizeof(*data)); + data->tree = tree; + + if(data->tree) + { + data->cached = TRUE; + data->nearest_callback = mesh_faces_nearest_point; data->raycast_callback = mesh_faces_spherecast; @@ -562,6 +601,8 @@ data->sphere_radius = epsilon; } @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs