Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-11-21 19:44:05 +0300
committerCampbell Barton <ideasman42@gmail.com>2009-11-21 19:44:05 +0300
commit6f38938a64178f0a3ed6a4b96e4bf459c9076468 (patch)
tree8852c14a73eae4a32b68a78bac1086dd7fc15487
parentbd1f548d8e4a47b81b03af3d50339b2fa33ff5fb (diff)
[#19930] Nurb CV select is failing because of view clipping
- the clipping test function was using the rv3d->viewmatob where it needed to use the object matrix. - added a local clipping member to rv3d, the clipping planes in object-space, avoids many matrix multiplications when testing verts or clipping pixels when projection painting.
-rw-r--r--source/blender/editors/include/ED_view3d.h5
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c13
-rw-r--r--source/blender/editors/space_view3d/drawobject.c41
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c21
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c44
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c2
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h1
9 files changed, 98 insertions, 44 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 2ec9ddf6c52..ecd2d69b7fb 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -104,7 +104,8 @@ void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData,
void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData);
void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData);
-int view3d_test_clipping(struct RegionView3D *rv3d, float *vec);
+void ED_view3d_local_clipping(struct RegionView3D *rv3d, float mat[][4]);
+int view3d_test_clipping(struct RegionView3D *rv3d, float *vec, int local);
void view3d_align_axis_to_vector(struct View3D *v3d, struct RegionView3D *rv3d, int axisidx, float vec[3]);
void drawcircball(int mode, float *cent, float rad, float tmat[][4]);
@@ -143,5 +144,7 @@ int ED_view3d_context_activate(struct bContext *C);
void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
int winx, int winy, float viewmat[][4], float winmat[][4]);
+void view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]);
+
#endif /* ED_VIEW3D_H */
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index a0df4cb1211..e14dedf6002 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -482,14 +482,17 @@ static void findnearestedge__doClosest(void *userData, EditEdge *eed, int x0, in
struct { ViewContext vc; float mval[2]; int dist; EditEdge *closest; } *data = userData;
float v1[2], v2[2];
int distance;
-
+
+ ED_view3d_local_clipping(data->vc.rv3d, data->vc.obedit->obmat); /* for local clipping lookups */
+
v1[0] = x0;
v1[1] = y0;
v2[0] = x1;
v2[1] = y1;
-
+
distance= dist_to_line_segment_v2(data->mval, v1, v2);
-
+
+
if(eed->f & SELECT) distance+=5;
if(distance < data->dist) {
if(data->vc.rv3d->rflag & RV3D_CLIPPING) {
@@ -499,9 +502,8 @@ static void findnearestedge__doClosest(void *userData, EditEdge *eed, int x0, in
vec[0]= eed->v1->co[0] + labda*(eed->v2->co[0] - eed->v1->co[0]);
vec[1]= eed->v1->co[1] + labda*(eed->v2->co[1] - eed->v1->co[1]);
vec[2]= eed->v1->co[2] + labda*(eed->v2->co[2] - eed->v1->co[2]);
- mul_m4_v3(data->vc.obedit->obmat, vec);
- if(view3d_test_clipping(data->vc.rv3d, vec)==0) {
+ if(view3d_test_clipping(data->vc.rv3d, vec, 1)==0) {
data->dist = distance;
data->closest = eed;
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index ef036da6d7b..55f7a6a23b9 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -861,8 +861,7 @@ static int project_paint_occlude_ptv_clip(
if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
- mul_m4_v3(ps->ob->obmat, wco);
- if(!view3d_test_clipping(ps->rv3d, wco)) {
+ if(!view3d_test_clipping(ps->rv3d, wco, 1)) {
return 1;
}
@@ -2446,8 +2445,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
/* a pitty we need to get the worldspace pixel location here */
if(ps->rv3d->rflag & RV3D_CLIPPING) {
interp_v3_v3v3v3(wco, ps->dm_mvert[ (*(&mf->v1 + i1)) ].co, ps->dm_mvert[ (*(&mf->v1 + i2)) ].co, ps->dm_mvert[ (*(&mf->v1 + i3)) ].co, w);
- mul_m4_v3(ps->ob->obmat, wco);
- if(view3d_test_clipping(ps->rv3d, wco)) {
+ if(view3d_test_clipping(ps->rv3d, wco, 1)) {
continue; /* Watch out that no code below this needs to run */
}
}
@@ -2663,9 +2661,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
if(ps->rv3d->rflag & RV3D_CLIPPING) {
if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
-
- mul_m4_v3(ps->ob->obmat, wco);
- if(view3d_test_clipping(ps->rv3d, wco)) {
+
+ if(view3d_test_clipping(ps->rv3d, wco, 1)) {
continue; /* Watch out that no code below this needs to run */
}
}
@@ -2934,6 +2931,8 @@ static void project_paint_begin(ProjPaintState *ps)
/* ---- end defines ---- */
+ ED_view3d_local_clipping(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
+
/* paint onto the derived mesh */
/* Workaround for subsurf selection, try the display mesh first */
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 23cd6f0c7d9..a0c13b6d6ee 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -142,7 +142,7 @@ static void draw_empty_cone(float size);
/* ************* 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)
+static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr, int local)
{
RegionView3D *rv3d= ar->regiondata;
float fx, fy, vec4[4];
@@ -151,9 +151,7 @@ static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr)
/* clipplanes in eye space */
if(rv3d->rflag & RV3D_CLIPPING) {
- VECCOPY(vec4, vec);
- mul_m4_v3(rv3d->viewmatob, vec4);
- if(view3d_test_clipping(rv3d, vec4))
+ if(view3d_test_clipping(rv3d, vec, local))
return;
}
@@ -545,7 +543,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
for(vos= strings->first; vos; vos= vos->next) {
if(mat)
mul_m4_v3(mat, vos->vec);
- view3d_project_short_clip(ar, vos->vec, vos->mval);
+ view3d_project_short_clip(ar, vos->vec, vos->mval, 0);
if(vos->mval[0]!=IS_CLIPPED)
tot++;
}
@@ -1207,9 +1205,11 @@ 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_local_clipping(vc->rv3d, obedit->obmat); /* for local clipping lookups */
+
for (i=0; i<N; i++, bp++, co+=3) {
if (bp->hide==0) {
- view3d_project_short_clip(vc->ar, dl?co:bp->vec, s);
+ view3d_project_short_clip(vc->ar, dl?co:bp->vec, s, 1);
if (s[0] != IS_CLIPPED)
func(userData, bp, s[0], s[1]);
}
@@ -1314,7 +1314,7 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co
short s[2]= {IS_CLIPPED, 0};
if (data->clipVerts) {
- view3d_project_short_clip(data->vc.ar, co, s);
+ view3d_project_short_clip(data->vc.ar, co, s, 1);
} else {
view3d_project_short_noclip(data->vc.ar, co, s);
}
@@ -1334,6 +1334,9 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe
data.userData = userData;
data.clipVerts = clipVerts;
+ if(clipVerts)
+ ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+
EM_init_index_arrays(vc->em, 1, 0, 0);
dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
EM_free_index_arrays();
@@ -1349,8 +1352,8 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0
if (eed->h==0) {
if (data->clipVerts==1) {
- view3d_project_short_clip(data->vc.ar, v0co, s[0]);
- view3d_project_short_clip(data->vc.ar, v1co, s[1]);
+ view3d_project_short_clip(data->vc.ar, v0co, s[0], 1);
+ view3d_project_short_clip(data->vc.ar, v1co, s[1], 1);
} else {
view3d_project_short_noclip(data->vc.ar, v0co, s[0]);
view3d_project_short_noclip(data->vc.ar, v1co, s[1]);
@@ -1376,6 +1379,9 @@ void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEd
data.userData = userData;
data.clipVerts = clipVerts;
+ if(clipVerts)
+ ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+
EM_init_index_arrays(vc->em, 0, 1, 0);
dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
EM_free_index_arrays();
@@ -1390,7 +1396,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *ce
short s[2];
if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
- view3d_project_short_clip(data->vc.ar, cent, s);
+ view3d_project_short_clip(data->vc.ar, cent, s, 1);
data->func(data->userData, efa, s[0], s[1], index);
}
@@ -1405,6 +1411,9 @@ void mesh_foreachScreenFace(ViewContext *vc, void (*func)(void *userData, EditFa
data.func = func;
data.userData = userData;
+ //if(clipVerts)
+ ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+
EM_init_index_arrays(vc->em, 0, 0, 1);
dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
EM_free_index_arrays();
@@ -1419,6 +1428,8 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
Nurb *nu;
int i;
+ ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+
for (nu= cu->editnurb->first; nu; nu=nu->next) {
if(nu->type == CU_BEZIER) {
for (i=0; i<nu->pntsu; i++) {
@@ -1427,17 +1438,17 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
if(bezt->hide==0) {
if(cu->drawflag & CU_HIDE_HANDLES) {
- view3d_project_short_clip(vc->ar, bezt->vec[1], s);
+ view3d_project_short_clip(vc->ar, bezt->vec[1], s, 1);
if (s[0] != IS_CLIPPED)
func(userData, nu, NULL, bezt, 1, s[0], s[1]);
} else {
- view3d_project_short_clip(vc->ar, bezt->vec[0], s);
+ view3d_project_short_clip(vc->ar, bezt->vec[0], s, 1);
if (s[0] != IS_CLIPPED)
func(userData, nu, NULL, bezt, 0, s[0], s[1]);
- view3d_project_short_clip(vc->ar, bezt->vec[1], s);
+ view3d_project_short_clip(vc->ar, bezt->vec[1], s, 1);
if (s[0] != IS_CLIPPED)
func(userData, nu, NULL, bezt, 1, s[0], s[1]);
- view3d_project_short_clip(vc->ar, bezt->vec[2], s);
+ view3d_project_short_clip(vc->ar, bezt->vec[2], s, 1);
if (s[0] != IS_CLIPPED)
func(userData, nu, NULL, bezt, 2, s[0], s[1]);
}
@@ -1449,7 +1460,7 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
BPoint *bp = &nu->bp[i];
if(bp->hide==0) {
- view3d_project_short_clip(vc->ar, bp->vec, s);
+ view3d_project_short_clip(vc->ar, bp->vec, s, 1);
if (s[0] != IS_CLIPPED)
func(userData, nu, bp, NULL, -1, s[0], s[1]);
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index ebd1ab6dbff..d11eee466ed 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -175,6 +175,9 @@ void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
/* local viewmat and persmat, to calculate projections */
wmGetMatrix(rv3d->viewmatob);
wmGetSingleMatrix(rv3d->persmatob);
+
+ /* initializes object space clipping, speeds up clip tests */
+ ED_view3d_local_clipping(rv3d, ob->obmat);
}
/* ******************** default callbacks for view3d space ***************** */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 8aa63518e96..ec8fc869d72 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -193,22 +193,27 @@ void view3d_clr_clipping(void)
}
}
-int view3d_test_clipping(RegionView3D *rv3d, float *vec)
+static test_clipping(float *vec, float clip[][4])
{
- /* vec in world coordinates, returns 1 if clipped */
float view[3];
-
VECCOPY(view, vec);
- if(0.0f < rv3d->clip[0][3] + INPR(view, rv3d->clip[0]))
- if(0.0f < rv3d->clip[1][3] + INPR(view, rv3d->clip[1]))
- if(0.0f < rv3d->clip[2][3] + INPR(view, rv3d->clip[2]))
- if(0.0f < rv3d->clip[3][3] + INPR(view, rv3d->clip[3]))
+ if(0.0f < clip[0][3] + INPR(view, clip[0]))
+ if(0.0f < clip[1][3] + INPR(view, clip[1]))
+ if(0.0f < clip[2][3] + INPR(view, clip[2]))
+ if(0.0f < clip[3][3] + INPR(view, clip[3]))
return 0;
-
+
return 1;
}
+/* for 'local' ED_view3d_local_clipping must run first
+ * then all comparisons can be done in localspace */
+int view3d_test_clipping(RegionView3D *rv3d, float *vec, int local)
+{
+ return test_clipping(vec, local ? rv3d->clip_local : rv3d->clip);
+}
+
/* ********* end custom clipping *********** */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index a545d200e87..8597f0be88d 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -1829,6 +1829,42 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
/* ********************* set clipping operator ****************** */
+static void calc_clipping_plane(float clip[6][4], BoundBox *clipbb)
+{
+ int val;
+
+ for(val=0; val<4; val++) {
+
+ normal_tri_v3( clip[val],clipbb->vec[val], clipbb->vec[val==3?0:val+1], clipbb->vec[val+4]);
+
+ clip[val][3]=
+ - clip[val][0]*clipbb->vec[val][0]
+ - clip[val][1]*clipbb->vec[val][1]
+ - clip[val][2]*clipbb->vec[val][2];
+ }
+}
+
+static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float mat[][4])
+{
+ BoundBox clipbb_local;
+ float imat[4][4];
+ int i;
+
+ invert_m4_m4(imat, mat);
+
+ for(i=0; i<8; i++) {
+ mul_v3_m4v3(clipbb_local.vec[i], imat, clipbb->vec[i]);
+ }
+
+ calc_clipping_plane(clip_local, &clipbb_local);
+}
+
+void ED_view3d_local_clipping(RegionView3D *rv3d, float mat[][4])
+{
+ if(rv3d->rflag & RV3D_CLIPPING)
+ calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat);
+}
+
static int view3d_clipping_exec(bContext *C, wmOperator *op)
{
RegionView3D *rv3d= CTX_wm_region_view3d(C);
@@ -1879,14 +1915,8 @@ static int view3d_clipping_exec(bContext *C, wmOperator *op)
}
/* then plane equations */
- for(val=0; val<4; val++) {
+ calc_clipping_plane(rv3d->clip, rv3d->clipbb);
- normal_tri_v3( rv3d->clip[val],rv3d->clipbb->vec[val], rv3d->clipbb->vec[val==3?0:val+1], rv3d->clipbb->vec[val+4]);
-
- rv3d->clip[val][3]= - rv3d->clip[val][0]*rv3d->clipbb->vec[val][0]
- - rv3d->clip[val][1]*rv3d->clipbb->vec[val][1]
- - rv3d->clip[val][2]*rv3d->clipbb->vec[val][2];
- }
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index ded9b44afd4..82b5730daa2 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -680,7 +680,7 @@ void project_short(ARegion *ar, float *vec, short *adr) /* clips */
adr[0]= IS_CLIPPED;
if(rv3d->rflag & RV3D_CLIPPING) {
- if(view3d_test_clipping(rv3d, vec))
+ if(view3d_test_clipping(rv3d, vec, 0))
return;
}
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 422c56fe4c1..74d9fa59e50 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -97,6 +97,7 @@ typedef struct RegionView3D {
/* user defined clipping planes */
float clip[6][4];
+ float clip_local[6][4]; /* clip in object space, means we can test for clipping in editmode without first going into worldspace */
struct BoundBox *clipbb;
struct bGPdata *gpd; /* Grease-Pencil Data (annotation layers) */