[Bf-blender-cvs] [dd1edb0954b] master: Snap System: Separate raycast functions from nearest2d functions

mano-wii noreply at git.blender.org
Tue Jul 11 18:52:16 CEST 2017


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. @@




More information about the Bf-blender-cvs mailing list