Commit: dd1edb0954b5441255b5a3616841228f466e448e
Author: mano-wii
Date:   Tue Jul 11 13:47:28 2017 -0300
Branches: master
https://developer.blender.org/rBdd1edb0954b5441255b5a3616841228f466e448e

Snap System: Separate raycast functions from nearest2d functions

The only similarity between these functions is that both serve to snap.
However their codes are totally different from one another.
So by separating these functions, it:
- removes the need to put several conditions;
- simplifies and
- optimizes the code

===================================================================

M       source/blender/editors/include/ED_transform_snap_object_context.h
M       source/blender/editors/transform/transform_snap_object.c
M       source/blender/makesrna/intern/rna_scene_api.c
M       source/blenderplayer/bad_level_call_stubs/stubs.c

===================================================================

diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h 
b/source/blender/editors/include/ED_transform_snap_object_context.h
index 6eaae49912c..8066adf55ce 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -84,7 +84,6 @@ void ED_transform_snap_object_context_set_editmesh_callbacks(
 
 bool ED_transform_snap_object_project_ray_ex(
         struct SnapObjectContext *sctx,
-        const unsigned short snap_to,
         const struct SnapObjectParams *params,
         const float ray_start[3], const float ray_normal[3], float *ray_depth,
         /* return args */
@@ -98,7 +97,6 @@ bool ED_transform_snap_object_project_ray(
 
 bool ED_transform_snap_object_project_ray_all(
         SnapObjectContext *sctx,
-        const unsigned short snap_to,
         const struct SnapObjectParams *params,
         const float ray_start[3], const float ray_normal[3],
         float ray_depth, bool sort,
diff --git a/source/blender/editors/transform/transform_snap_object.c 
b/source/blender/editors/transform/transform_snap_object.c
index aecd24d4e40..30cdae416e6 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -130,18 +130,193 @@ struct SnapObjectContext {
 
 };
 
-static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt);
+/** \} */
 
 
 /* -------------------------------------------------------------------- */
 
-/** \name Support for storing all depths, not just the first (raycast 'all')
+/** Common utilities
+* \{ */
+
+struct SnapObject {
+       struct SnapObject *next, *prev;
+
+       bool use_obedit;
+       struct Object *ob;
+       float obmat[4][4];
+};
+
+/**
+ * Walks through all objects in the scene to create the list of objets to snap.
  *
- * This uses a list of #SnapObjectHitDepth structs.
+ * \param sctx: Snap context to store data.
+ * \param snap_select : from enum SnapSelect.
+ * \param use_object_edit_cage : Uses the coordinates of BMesh(if any) to do 
the snapping.
  *
- * \{ */
+ */
+static void create_object_list(
+        SnapObjectContext *sctx,
+        const SnapSelect snap_select, const bool use_object_edit_cage, 
ListBase *r_obj_list)
+{
+       r_obj_list->first = r_obj_list->last = NULL;
+
+       Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL;
+
+       bool ignore_object_selected = false, ignore_object_active = false;
+       switch (snap_select) {
+               case SNAP_ALL:
+                       break;
+               case SNAP_NOT_SELECTED:
+                       ignore_object_selected = true;
+                       break;
+               case SNAP_NOT_ACTIVE:
+                       ignore_object_active = true;
+                       break;
+       }
+
+       /* Need an exception for particle edit because the base is flagged with 
BA_HAS_RECALC_DATA
+        * which makes the loop skip it, even the derived mesh will never change
+        *
+        * To solve that problem, we do it first as an exception.
+        * */
+       Base *base_act = sctx->scene->basact;
+       if (base_act && base_act->object && base_act->object->mode & 
OB_MODE_PARTICLE_EDIT) {
+               struct SnapObject *sobj = MEM_mallocN(sizeof(*sobj), __func__);
+               sobj->use_obedit = false;
+               sobj->ob = base_act->object;
+               copy_m4_m4(sobj->obmat, sobj->ob->obmat);
+               BLI_addtail(r_obj_list, sobj);
+       }
+
+       for (Base *base = sctx->scene->base.first; base != NULL; base = 
base->next) {
+               if ((BASE_VISIBLE_BGMODE(sctx->v3d_data.v3d, sctx->scene, 
base)) &&
+                   (base->flag & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 
&&
+
+                       !((ignore_object_selected && (base->flag & (SELECT | 
BA_WAS_SEL))) ||
+                         (ignore_object_active && base == base_act)))
+               {
+                       Object *ob = base->object;
+
+                       if (ob->transflag & OB_DUPLI) {
+                               DupliObject *dupli_ob;
+                               ListBase *lb = 
object_duplilist(sctx->bmain->eval_ctx, sctx->scene, ob);
+
+                               for (dupli_ob = lb->first; dupli_ob; dupli_ob = 
dupli_ob->next) {
+                                       struct SnapObject *sobj = 
MEM_mallocN(sizeof(*sobj), __func__);
+                                       sobj->use_obedit = obedit && 
dupli_ob->ob->data == obedit->data;
+                                       sobj->ob = sobj->use_obedit ? obedit : 
dupli_ob->ob;;
+                                       copy_m4_m4(sobj->obmat, dupli_ob->mat);
+                                       BLI_addtail(r_obj_list, sobj);
+                               }
+
+                               free_object_duplilist(lb);
+                       }
+
+                       struct SnapObject *sobj = MEM_mallocN(sizeof(*sobj), 
__func__);
+                       sobj->use_obedit = obedit && ob->data == obedit->data;
+                       sobj->ob = sobj->use_obedit ? obedit : ob;
+                       copy_m4_m4(sobj->obmat, sobj->ob->obmat);
+                       BLI_addtail(r_obj_list, sobj);
+               }
+       }
+}
+
+
+/**
+ * Generates a struct with the immutable parameters that will be used on all 
objects.
+ *
+ * \param snap_to: Element to snap, Vertice, Edge or Face.
+ * \param view_proj: ORTHO or PERSP.
+ * Currently only works one at a time, but can eventually operate as flag.
+ *
+ * \param mval: Mouse coords.
+ * (When NULL, ray-casting is handled without any projection matrix 
correction.)
+ * \param ray_origin: ray_start before being moved toward the ray_normal at 
the distance from vew3d clip_min.
+ * \param ray_start: ray_origin moved for the start clipping plane (clip_min).
+ * \param ray_direction: Unit length direction of the ray.
+ * \param depth_range: distances of clipe plane min and clip plane max;
+ */
+static void snap_data_set(
+        SnapData *snapdata,
+        const ARegion *ar, const unsigned short snap_to, const enum eViewProj 
view_proj,
+        const float mval[2], const float ray_origin[3], const float 
ray_start[3],
+        const float ray_direction[3], const float depth_range[2])
+{
+       copy_m4_m4(snapdata->pmat, ((RegionView3D *)ar->regiondata)->persmat);
+       snapdata->win_half[0] = ar->winx / 2;
+       snapdata->win_half[1] = ar->winy / 2;
+       copy_v2_v2(snapdata->mval, mval);
+       snapdata->snap_to = snap_to;
+       copy_v3_v3(snapdata->ray_origin, ray_origin);
+       copy_v3_v3(snapdata->ray_start, ray_start);
+       copy_v3_v3(snapdata->ray_dir, ray_direction);
+       snapdata->view_proj = view_proj;
+       copy_v2_v2(snapdata->depth_range, depth_range);
+}
+
+
+MINLINE float depth_get(const float co[3], const float ray_start[3], const 
float ray_dir[3])
+{
+       float dvec[3];
+       sub_v3_v3v3(dvec, co, ray_start);
+       return dot_v3v3(dvec, ray_dir);
+}
+
+
+static float dist_aabb_to_plane(
+        const float bbmin[3], const float bbmax[3],
+        const float plane_co[3], const float plane_no[3])
+{
+       const float local_bvmin[3] = {
+               (plane_no[0] < 0) ? bbmax[0] : bbmin[0],
+               (plane_no[1] < 0) ? bbmax[1] : bbmin[1],
+               (plane_no[2] < 0) ? bbmax[2] : bbmin[2],
+       };
+       return depth_get(local_bvmin, plane_co, plane_no);
+}
+
+static bool walk_parent_bvhroot_cb(const BVHTreeAxisRange *bounds, void 
*userdata)
+{
+       BVHTreeRay *ray = userdata;
+       const float bbmin[3] = {bounds[0].min, bounds[1].min, bounds[2].min};
+       const float bbmax[3] = {bounds[0].max, bounds[1].max, bounds[2].max};
+       if (!isect_ray_aabb_v3_simple(ray->origin, ray->direction, bbmin, 
bbmax, &ray->radius, NULL)) {
+               ray->radius = -1;
+       }
+       return false;
+}
+
+static bool isect_ray_bvhroot_v3(struct BVHTree *tree, const float 
ray_start[3], const float ray_dir[3], float *depth)
+{
+       BVHTreeRay ray;
+       copy_v3_v3(ray.origin, ray_start);
+       copy_v3_v3(ray.direction, ray_dir);
+
+       BLI_bvhtree_walk_dfs(tree, walk_parent_bvhroot_cb, NULL, NULL, &ray);
+
+       if (ray.radius > 0) {
+               *depth = ray.radius;
+               return true;
+       }
+       else {
+               return false;
+       }
+}
+
+
+static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt);
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Ray Cast Funcs
+* \{ */
+
+/* Store all ray-hits
+ * Support for storing all depths, not just the first (raycast 'all') */
 
-/* Store all ray-hits */
 struct RayCastAll_Data {
        void *bvhdata;
 
@@ -162,6 +337,7 @@ struct RayCastAll_Data {
        bool retval;
 };
 
+
 static struct SnapObjectHitDepth *hit_depth_create(
         const float depth, const float co[3], const float no[3], int index,
         Object *ob, const float obmat[4][4], unsigned int ob_uuid)
@@ -209,77 +385,513 @@ static void raycast_all_cb(void *userdata, int index, 
const BVHTreeRay *ray, BVH
                mul_v3_m4v3(location, (float(*)[4])data->obmat, hit->co);
                depth = (hit->dist + data->len_diff) / data->local_scale;
 
-               /* worldspace normal */
-               copy_v3_v3(normal, hit->no);
-               mul_m3_v3((float(*)[3])data->timat, normal);
-               normalize_v3(normal);
+               /* worldspace normal */
+               copy_v3_v3(normal, hit->no);
+               mul_m3_v3((float(*)[3])data->timat, normal);
+               normalize_v3(normal);
+
+               /* currently unused, and causes issues when looptri's haven't 
been calculated.
+                * since theres some overhead in ensuring this data is valid, 
it may need to be optional. */
+#if 0
+               if (data->dm) {
+                       hit->index = dm_looptri_to_poly_index(data->dm, 
&data->dm_looptri[hit->index]);
+               }
+#endif
+
+               struct SnapObjectHitDepth *hit_item = hit_depth_create(
+                       depth, location, normal, hit->index,
+                       data->ob, data->obmat, data->ob_uuid);
+               BLI_addtail(data->hit_list, hit_item);
+       }
+}
+
+
+static bool raycastDerivedMesh(
+        SnapObjectContext *sctx,
+        const float ray_orig[3], const float ray_start[3], const float 
ray_dir[3], const float depth_range[2],
+        Object *ob, DerivedMesh *dm, float obmat[4][4], const unsigned int 
ob_index,
+        /* read/write args */
+        float *ray_depth,
+        /* return args */
+        float r_loc[3], float r_no[3], int *r_index,
+        ListBase *r_hit_list)
+{
+       bool retval = false;
+
+       if (dm->getNumPolys(dm) == 0) {
+               return retval;
+       }
+
+       float imat[4][4];
+       float timat[3][3]; /* transpose inverse matrix for normals */
+       float ray_start_local[3], ray_normal_local[3];
+       float local_scale, local_depth, len_diff = 0.0f;
+
+       invert_m4_m4(imat, obmat);
+       transpose_m3_m4(timat, imat);
+
+       copy_v3_v3(ray_start_local, ray_start);
+       copy_v3_v3(ray_normal_local, ray_dir);
+
+       mul_m4_v3(imat, ray_start_local);
+       mul_mat3_m4_v3(imat, ray_normal_local);
+
+       /* local scale in normal direction */
+       local_scale = normalize_v3(ray_normal_local);
+       local_depth = *ray_depth;
+       if (local_depth != BVH_RAYCAST_DIST_MAX) {
+               local_depth *= local_scale;
+       }
+
+       /* Test BoundBox */
+       BoundBox *bb = BKE_object_boundbox_get(ob);
+       if (bb) {
+               /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
+               if (!ise

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to