diff options
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 19 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 18 |
4 files changed, 41 insertions, 6 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index fd1b7e1351d..7b1022d1a3f 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -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 */ diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 52744c81b7e..8234d0ab6dc 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -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; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 3d51449e28f..3e9b2e5751b 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -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) { diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index e1bd48e002f..d017e11e783 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -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 ***************** */ |