bugfix for exitmode verts being unselectable. caused by view3d_project_short_clip...
authorCampbell Barton <ideasman42@gmail.com>
Sun, 11 Oct 2009 19:57:56 +0000 (19:57 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 11 Oct 2009 19:57:56 +0000 (19:57 +0000)
Deal with this by adding ED_view3d_init_mats_rv3d(ob, r3d) which initialized the region mat's and is used in mesh_foreachScreenVert, mesh_foreachScreenEdge etc.

source/blender/editors/include/ED_view3d.h
source/blender/editors/mesh/editmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/space_view3d.c

index fd1b7e1351d40a0b690a9c6e156fec5f6c583386..7b1022d1a3f82b8b8c35fbcae9e02b1d4802a262 100644 (file)
@@ -134,5 +134,7 @@ int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, in
 /* get 3d region from context, also if mouse is in header or toolbar */
 struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C);
 
+void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d);
+
 #endif /* ED_VIEW3D_H */
 
index 52744c81b7e2b6315335993a10bf0f010164a49d..8234d0ab6dc871fc2f1efec72878293c5c5f9cce 100644 (file)
@@ -1796,6 +1796,14 @@ void undo_push_mesh(bContext *C, char *name)
 
 /* *************** END UNDO *************/
 
+void EM_init_viewmats(Object *ob, RegionView3D *rv3d)
+{
+       wmMultMatrix(ob->obmat);
+       /* local viewmat and persmat, to calculate projections */
+       wmGetMatrix(rv3d->viewmatob);
+       wmGetSingleMatrix(rv3d->persmatob);
+}
+
 static EditVert **g_em_vert_array = NULL;
 static EditEdge **g_em_edge_array = NULL;
 static EditFace **g_em_face_array = NULL;
index 3d51449e28f7de8c1b18c377d940764138c1b32e..3e9b2e5751ba9b65f3583262c7b169d862831124 100644 (file)
@@ -139,7 +139,9 @@ static void draw_empty_sphere(float size);
 static void draw_empty_cone(float size);
 
 
-/* ************* only use while object drawing ************** */
+/* ************* only use while object drawing **************
+ * or after running ED_view3d_init_mats_rv3d
+ * */
 static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr)
 {
        RegionView3D *rv3d= ar->regiondata;
@@ -1205,6 +1207,8 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo
        int i, N = lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
        short s[2] = {IS_CLIPPED, 0};
 
+       ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */
+
        for (i=0; i<N; i++, bp++, co+=3) {
                if (bp->hide==0) {
                        view3d_project_short_clip(vc->ar, dl?co:bp->vec, s);
@@ -1328,6 +1332,7 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe
        data.userData = userData;
        data.clipVerts = clipVerts;
 
+       ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */
        EM_init_index_arrays(vc->em, 1, 0, 0);
        dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
        EM_free_index_arrays();
@@ -1370,6 +1375,7 @@ void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEd
        data.userData = userData;
        data.clipVerts = clipVerts;
 
+       ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */
        EM_init_index_arrays(vc->em, 0, 1, 0);
        dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
        EM_free_index_arrays();
@@ -1399,6 +1405,7 @@ void mesh_foreachScreenFace(ViewContext *vc, void (*func)(void *userData, EditFa
        data.func = func;
        data.userData = userData;
 
+       ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */
        EM_init_index_arrays(vc->em, 0, 0, 1);
        dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
        EM_free_index_arrays();
@@ -1413,6 +1420,8 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
        Nurb *nu;
        int i;
 
+       ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */
+
        for (nu= cu->editnurb->first; nu; nu=nu->next) {
                if(nu->type == CU_BEZIER) {
                        for (i=0; i<nu->pntsu; i++) {
@@ -5451,11 +5460,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        /* draw paths... */
        // TODO...
 
-       /* multiply view with object matrix */
-       wmMultMatrix(ob->obmat);
-       /* local viewmat and persmat, to calculate projections */
-       wmGetMatrix(rv3d->viewmatob);
-       wmGetSingleMatrix(rv3d->persmatob);
+       /* multiply view with object matrix.
+        * local viewmat and persmat, to calculate projections */
+       ED_view3d_init_mats_rv3d(ob, rv3d);
 
        /* which wire color */
        if((flag & DRAW_CONSTCOLOR) == 0) {
index e1bd48e002f571140531bb0b4184bbe340c78725..d017e11e783e7ca1997f5f5d59bef9908209821b 100644 (file)
@@ -158,6 +158,24 @@ RegionView3D *ED_view3d_context_rv3d(bContext *C)
        return rv3d;
 }
 
+/* Most of the time this isn't needed since you could assume the view matrix was
+ * set while drawing, however when functions like mesh_foreachScreenVert are
+ * called by selection tools, we can't be sure this object was the last.
+ *
+ * for example, transparent objects are drawn after editmode and will cause
+ * the rv3d mat's to change and break selection.
+ *
+ * 'ED_view3d_init_mats_rv3d' should be called before
+ * view3d_project_short_clip and view3d_project_short_noclip in cases where
+ * these functions are not used during draw_object
+ */
+void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
+{
+       wmMultMatrix(ob->obmat);
+       /* local viewmat and persmat, to calculate projections */
+       wmGetMatrix(rv3d->viewmatob);
+       wmGetSingleMatrix(rv3d->persmatob);
+}
 
 /* ******************** default callbacks for view3d space ***************** */