Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/bvhutils.c')
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c101
1 files changed, 77 insertions, 24 deletions
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 1aad0a242f9..5c50c14f1a8 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -41,7 +41,7 @@
#include "BLI_linklist.h"
#include "BKE_DerivedMesh.h"
-
+#include "BKE_tessmesh.h"
#include "BLI_math.h"
#include "MEM_guardedalloc.h"
@@ -555,7 +555,7 @@ BVHTree* bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float
data->mesh = mesh;
data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
- data->face = mesh->getFaceDataArray(mesh, CD_MFACE);
+ data->face = mesh->getTessFaceDataArray(mesh, CD_MFACE);
data->sphere_radius = epsilon;
}
@@ -572,22 +572,87 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float
if(tree == NULL)
{
int i;
- int numFaces= mesh->getNumFaces(mesh);
- MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
- MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE);
+ int numFaces= mesh->getNumTessFaces(mesh);
- if(vert != NULL && face != NULL)
+ /* BMESH spesific check that we have tessfaces,
+ * we _could_ tesselate here but rather not - campbell
+ *
+ * this assert checks we have tessfaces,
+ * if not caller should use DM_ensure_tessface() */
+ BLI_assert(!(numFaces == 0 && mesh->getNumPolys(mesh) != 0));
+
+ if(numFaces != 0)
{
/* Create a bvh-tree of the given target */
tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis);
if(tree != NULL)
{
- /* XXX, for snap only, em & dm are assumed to be aligned, since dm is the em's cage */
- EditMesh *em= data->em_evil;
+ BMEditMesh *em= data->em_evil;
if(em) {
- EditFace *efa= em->faces.first;
- for(i = 0; i < numFaces; i++, efa= efa->next) {
- if(!(efa->f & 1) && efa->h==0 && !((efa->v1->f&1)+(efa->v2->f&1)+(efa->v3->f&1)+(efa->v4?efa->v4->f&1:0))) {
+ /*data->em_evil is only set for snapping, and only for the mesh of the object
+ which is currently open in edit mode. When set, the bvhtree should not contain
+ faces that will interfere with snapping (e.g. faces that are hidden/selected
+ or faces that have selected verts).*/
+
+ /* XXX, for snap only, em & dm are assumed to be aligned, since dm is the em's cage */
+
+ /*Insert BMesh-tesselation triangles into the bvh tree, unless they are hidden
+ and/or selected. Even if the faces themselves are not selected for the snapped
+ transform, having a vertex selected means the face (and thus it's tesselated
+ triangles) will be moving and will not be a good snap targets.*/
+ for (i = 0; i < em->tottri; i++) {
+ BMLoop **tri = em->looptris[i];
+ BMFace *f;
+ BMVert *v;
+ BMIter iter;
+ int insert;
+
+ /*Each loop of the triangle points back to the BMFace it was tesselated from.
+ All three should point to the same face, so just use the face from the first
+ loop.*/
+ f = tri[0]->f;
+
+ /*If the looptris is ordered such that all triangles tesselated from a single
+ faces are consecutive elements in the array, then we could speed up the tests
+ below by using the insert value from the previous iteration.*/
+
+ /*Start with the assumption the triangle should be included for snapping.*/
+ insert = 1;
+
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT) || BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ /*Don't insert triangles tesselated from faces that are hidden
+ or selected*/
+ insert = 0;
+ }
+ else {
+ BM_ITER(v, &iter, em->bm, BM_VERTS_OF_FACE, f) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ /*Don't insert triangles tesselated from faces that have
+ any selected verts.*/
+ insert = 0;
+ }
+ }
+ }
+
+ if (insert)
+ {
+ /*No reason found to block hit-testing the triangle for snap,
+ so insert it now.*/
+ float co[4][3];
+ copy_v3_v3(co[0], tri[0]->v->co);
+ copy_v3_v3(co[1], tri[1]->v->co);
+ copy_v3_v3(co[2], tri[2]->v->co);
+
+ BLI_bvhtree_insert(tree, i, co[0], 3);
+ }
+ }
+ }
+ else {
+ MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
+ MFace *face = mesh->getTessFaceDataArray(mesh, CD_MFACE);
+
+ if (vert != NULL && face != NULL) {
+ for(i = 0; i < numFaces; i++) {
float co[4][3];
copy_v3_v3(co[0], vert[ face[i].v1 ].co);
copy_v3_v3(co[1], vert[ face[i].v2 ].co);
@@ -599,18 +664,6 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float
}
}
}
- else {
- for(i = 0; i < numFaces; i++) {
- float co[4][3];
- copy_v3_v3(co[0], vert[ face[i].v1 ].co);
- copy_v3_v3(co[1], vert[ face[i].v2 ].co);
- copy_v3_v3(co[2], vert[ face[i].v3 ].co);
- if(face[i].v4)
- copy_v3_v3(co[3], vert[ face[i].v4 ].co);
-
- BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
- }
- }
BLI_bvhtree_balance(tree);
//Save on cache for later use
@@ -638,7 +691,7 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float
data->mesh = mesh;
data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
- data->face = mesh->getFaceDataArray(mesh, CD_MFACE);
+ data->face = mesh->getTessFaceDataArray(mesh, CD_MFACE);
data->sphere_radius = epsilon;
}