[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [32442] trunk/blender/source/blender/ editors: bugfix [#23150] Creating Vertex with CTRL-LMB not snapping

Campbell Barton ideasman42 at gmail.com
Wed Oct 13 09:43:41 CEST 2010


Revision: 32442
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=32442
Author:   campbellbarton
Date:     2010-10-13 09:43:39 +0200 (Wed, 13 Oct 2010)

Log Message:
-----------
bugfix [#23150] Creating Vertex with CTRL-LMB not snapping
- Added EM_project_snap_verts so other functions can re-use this, similar to old retopo_do_all().
- Changed how the normal for selected geometry is calculated, was accumulating half selected edge's into normals which was OK with even surrounding geometry but could skew too easily if the surroundings were not so even. Now use the 2D screen space selected edge vector to calculate the normals in relation to the target mouse position.
- Option to rotate initial selection, gives better results in some cases. (Ctrl+Shift+Click to disable)
http://wiki.blender.org/index.php/File:ClickExtrudeFix.png

Modified Paths:
--------------
    trunk/blender/source/blender/editors/include/ED_mesh.h
    trunk/blender/source/blender/editors/mesh/editmesh_add.c
    trunk/blender/source/blender/editors/mesh/editmesh_lib.c
    trunk/blender/source/blender/editors/mesh/mesh_ops.c

Modified: trunk/blender/source/blender/editors/include/ED_mesh.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_mesh.h	2010-10-13 06:06:39 UTC (rev 32441)
+++ trunk/blender/source/blender/editors/include/ED_mesh.h	2010-10-13 07:43:39 UTC (rev 32442)
@@ -159,6 +159,8 @@
 
 int			EM_deselect_nth(struct EditMesh *em, int nth);
 
+void EM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct Object *obedit, struct EditMesh *em);
+
 /* editmesh_mods.c */
 extern unsigned int em_vertoffs, em_solidoffs, em_wireoffs;
 

Modified: trunk/blender/source/blender/editors/mesh/editmesh_add.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_add.c	2010-10-13 06:06:39 UTC (rev 32441)
+++ trunk/blender/source/blender/editors/mesh/editmesh_add.c	2010-10-13 07:43:39 UTC (rev 32442)
@@ -110,17 +110,20 @@
 static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
 {
 	ViewContext vc;
-	EditVert *eve, *v1;
+	EditVert *eve;
 	float min[3], max[3];
 	int done= 0;
+	int rot_src= RNA_boolean_get(op->ptr, "rotate_source");
 	
 	em_setup_viewcontext(C, &vc);
 	
+	invert_m4_m4(vc.obedit->imat, vc.obedit->obmat); 
+	
 	INIT_MINMAX(min, max);
 	
-	for(v1= vc.em->verts.first;v1; v1=v1->next) {
-		if(v1->f & SELECT) {
-			DO_MINMAX(v1->co, min, max);
+	for(eve= vc.em->verts.first; eve; eve= eve->next) {
+		if(eve->f & SELECT) {
+			DO_MINMAX(eve->co, min, max);
 			done= 1;
 		}
 	}
@@ -131,25 +134,56 @@
 		float vec[3], cent[3], mat[3][3];
 		float nor[3]= {0.0, 0.0, 0.0};
 		
-		/* check for edges that are half selected, use for rotation */
+		/* 2D normal calc */
+		float mval_f[2]= {(float)event->mval[0], (float)event->mval[1]};
+
+#define SIDE_OF_LINE(pa,pb,pp)	((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
+		
 		done= 0;
+
+		/* calculate the normal for selected edges */
 		for(eed= vc.em->edges.first; eed; eed= eed->next) {
-			if( (eed->v1->f & SELECT)+(eed->v2->f & SELECT) == SELECT ) {
-				if(eed->v1->f & SELECT) sub_v3_v3v3(vec, eed->v1->co, eed->v2->co);
-				else sub_v3_v3v3(vec, eed->v2->co, eed->v1->co);
-				add_v3_v3(nor, vec);
+			if(eed->f & SELECT) {
+				float co1[3], co2[3];
+				mul_v3_m4v3(co1, vc.obedit->obmat, eed->v1->co);
+				mul_v3_m4v3(co2, vc.obedit->obmat, eed->v2->co);
+				project_float_noclip(vc.ar, co1, co1);
+				project_float_noclip(vc.ar, co2, co2);
+				
+				/* 2D rotate by 90d while subtracting
+				 *  (x, y) = (y, -x)
+				 *
+				 * accumulate the screenspace normal in 2D,
+				 * with screenspace edge length weighting the result. */
+				if(SIDE_OF_LINE(co1, co2, mval_f) >= 0.0f) {
+					nor[0] +=  (co1[1] - co2[1]);
+					nor[1] += -(co1[0] - co2[0]);
+				}
+				else {
+					nor[0] +=  (co2[1] - co1[1]);
+					nor[1] += -(co2[0] - co1[0]);
+				}
 				done= 1;
 			}
 		}
+
+#undef SIDE_OF_LINE
+
 		if(done) {
 			float view_vec[3], cross[3];
 
+			/* convert the 2D nomal into 3D */
+			mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* worldspace */
+			mul_mat3_m4_v3(vc.obedit->imat, nor); /* local space */
+			
 			/* correct the normal to be aligned on the view plane */
 			copy_v3_v3(view_vec, vc.rv3d->viewinv[2]);
 			mul_mat3_m4_v3(vc.obedit->imat, view_vec);
 			cross_v3_v3v3(cross, nor, view_vec);
 			cross_v3_v3v3(nor, view_vec, cross);
 			normalize_v3(nor);
+			
+			/* correct for flipping */
 		}
 		
 		/* center */
@@ -159,10 +193,9 @@
 		
 		mul_m4_v3(vc.obedit->obmat, min);	// view space
 		view3d_get_view_aligned_coordinate(&vc, min, event->mval);
-		invert_m4_m4(vc.obedit->imat, vc.obedit->obmat); 
 		mul_m4_v3(vc.obedit->imat, min); // back in object space
 		
-		sub_v3_v3v3(min, min, cent);
+		sub_v3_v3(min, cent);
 		
 		/* calculate rotation */
 		unit_m3(mat);
@@ -179,16 +212,22 @@
 				cross_v3_v3v3(cross, nor, vec);
 				normalize_v3(cross);
 				dot= 0.5f*saacos(dot);
+				
+				/* halve the rotation if its applied twice */
+				if(rot_src) dot *= 0.5f;
+				
 				si= (float)sin(dot);
 				q1[0]= (float)cos(dot);
 				q1[1]= cross[0]*si;
 				q1[2]= cross[1]*si;
-				q1[3]= cross[2]*si;
-				
+				q1[3]= cross[2]*si;				
 				quat_to_mat3( mat,q1);
 			}
 		}
 		
+		if(rot_src)
+			rotateflag(vc.em, SELECT, cent, mat);
+		
 		extrudeflag(vc.obedit, vc.em, SELECT, nor, 0);
 		rotateflag(vc.em, SELECT, cent, mat);
 		translateflag(vc.em, SELECT, min);
@@ -213,8 +252,13 @@
 		
 		eve->f= SELECT;
 	}
-	
-	//retopo_do_all();
+
+	if(	((vc.scene->toolsettings->snap_flag & (SCE_SNAP|SCE_SNAP_PROJECT))==(SCE_SNAP|SCE_SNAP_PROJECT)) &&
+		(vc.scene->toolsettings->snap_mode==SCE_SNAP_MODE_FACE)
+	) {
+		EM_project_snap_verts(C, vc.ar, vc.obedit, vc.em);
+	}
+
 	WM_event_add_notifier(C, NC_GEOM|ND_DATA, vc.obedit->data); 
 	DAG_id_flush_update(vc.obedit->data, OB_RECALC_DATA);
 	
@@ -234,6 +278,8 @@
 	
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_boolean(ot->srna, "rotate_source", 1, "Rotate Source", "Rotate initial selection giving better shape");
 }
 
 

Modified: trunk/blender/source/blender/editors/mesh/editmesh_lib.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_lib.c	2010-10-13 06:06:39 UTC (rev 32441)
+++ trunk/blender/source/blender/editors/mesh/editmesh_lib.c	2010-10-13 07:43:39 UTC (rev 32442)
@@ -58,6 +58,7 @@
 #include "ED_mesh.h"
 #include "ED_screen.h"
 #include "ED_view3d.h"
+#include "ED_transform.h"
 
 #include "mesh_intern.h"
 
@@ -2765,3 +2766,18 @@
 	return 0;
 }
 
+void EM_project_snap_verts(bContext *C, ARegion *ar, Object *obedit, EditMesh *em)
+{
+	EditVert *eve;
+	for(eve= em->verts.first;eve; eve=eve->next) {
+		if(eve->f & SELECT) {
+			float mval[2], vec[3], no_dummy[3];
+			int dist_dummy;
+			mul_v3_m4v3(vec, obedit->obmat, eve->co);
+			project_float_noclip(ar, vec, mval);
+			if(snapObjectsContext(C, mval, &dist_dummy, vec, no_dummy, SNAP_NOT_OBEDIT)) {
+				mul_v3_m4v3(eve->co, obedit->imat, vec);
+			}
+		}
+	}
+}

Modified: trunk/blender/source/blender/editors/mesh/mesh_ops.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/mesh_ops.c	2010-10-13 06:06:39 UTC (rev 32441)
+++ trunk/blender/source/blender/editors/mesh/mesh_ops.c	2010-10-13 07:43:39 UTC (rev 32442)
@@ -292,7 +292,8 @@
 
 	/* use KM_CLICK because same key is used for tweaks */
 	WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", ACTIONMOUSE, KM_CLICK, KM_CTRL, 0);
-	
+	RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", ACTIONMOUSE, KM_CLICK, KM_SHIFT|KM_CTRL, 0)->ptr, "rotate_source", 0);
+
 	WM_keymap_add_item(keymap, "MESH_OT_delete", XKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "MESH_OT_delete", DELKEY, KM_PRESS, 0, 0);
 	





More information about the Bf-blender-cvs mailing list