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
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2005-08-20 23:18:35 +0400
committerTon Roosendaal <ton@blender.org>2005-08-20 23:18:35 +0400
commitdd5410162aa3eec61906febfdb0a550122cb2202 (patch)
tree27e702e1fb98fb6cb39e3a454ce052916b65bd5d /source
parentad5ac39ccc9941a77a69266eedb5f4218a779c32 (diff)
New feature; User definable Clipping Planes.
Press ALT+B in 3d window, draw a rect, and it becomes a clipping volume of 4 planes. You then can rotate the view anyway you like. Works for each 3d window individually. Disable it with another ALT+B press. Commit is huge because it had to change all selection code as well. The user-clipping planes are in 'eye space', the other clipping happens in projected 'viewport space'. Nice to notice is that the 'x=3200' convention (to denote a coordinate is clipped) now is a define. Define value is still a number though... but we now can get up to screens of 12000 pixels without issues! Known issue; here it refuses to draw the 'object centers' or Lamp icons within the clipping region. Can't find any reason for it... however, we might move to non-pixmaps for it anyway. Testing might reveil numerous issues, will be standby for it. Curious? Check this http://www.blender.org/bf/rt4.jpg
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/writefile.c1
-rw-r--r--source/blender/include/BIF_editview.h3
-rw-r--r--source/blender/include/BSE_drawview.h4
-rw-r--r--source/blender/include/BSE_view.h7
-rw-r--r--source/blender/makesdna/DNA_object_types.h2
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h8
-rw-r--r--source/blender/src/drawimage.c5
-rw-r--r--source/blender/src/drawipo.c4
-rw-r--r--source/blender/src/drawobject.c65
-rw-r--r--source/blender/src/drawview.c94
-rw-r--r--source/blender/src/editlattice.c2
-rw-r--r--source/blender/src/editmesh_mods.c7
-rw-r--r--source/blender/src/editmesh_tools.c4
-rw-r--r--source/blender/src/editview.c58
-rw-r--r--source/blender/src/space.c26
-rwxr-xr-xsource/blender/src/transform.c2
-rw-r--r--source/blender/src/view.c56
18 files changed, 275 insertions, 74 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 928820f91fd..754b30b4afa 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3018,6 +3018,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
v3d->bgpic= newdataadr(fd, v3d->bgpic);
v3d->localvd= newdataadr(fd, v3d->localvd);
v3d->afterdraw.first= v3d->afterdraw.last= NULL;
+ v3d->clipbb= newdataadr(fd, v3d->clipbb);
}
else if (sl->spacetype==SPACE_OOPS) {
SpaceOops *soops= (SpaceOops*) sl;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 920d4ed634a..fc281a78f63 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1207,6 +1207,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
writestruct(wd, DATA, "View3D", 1, v3d);
if(v3d->bgpic) writestruct(wd, DATA, "BGpic", 1, v3d->bgpic);
if(v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd);
+ if(v3d->clipbb) writestruct(wd, DATA, "BoundBox", 1, v3d->clipbb);
}
else if(sl->spacetype==SPACE_IPO) {
writestruct(wd, DATA, "SpaceIpo", 1, sl);
diff --git a/source/blender/include/BIF_editview.h b/source/blender/include/BIF_editview.h
index 345f21cdb9e..ef4c417188f 100644
--- a/source/blender/include/BIF_editview.h
+++ b/source/blender/include/BIF_editview.h
@@ -36,6 +36,7 @@
struct Base;
struct Object;
struct Camera;
+struct View3D;
void arrows_move_cursor(unsigned short event);
void borderselect(void);
@@ -52,5 +53,7 @@ void set_active_base(struct Base *base);
void set_active_object(struct Object *ob);
void set_render_border(void);
+void view3d_edit_clipping(struct View3D *v3d);
+
#endif
diff --git a/source/blender/include/BSE_drawview.h b/source/blender/include/BSE_drawview.h
index 946018a198e..b0e40699f42 100644
--- a/source/blender/include/BSE_drawview.h
+++ b/source/blender/include/BSE_drawview.h
@@ -57,6 +57,10 @@ void calc_viewborder(struct View3D *v3d, struct rcti *viewborder_r);
void view3d_set_1_to_1_viewborder(struct View3D *v3d);
void timestr(double time, char *str);
+int view3d_test_clipping(struct View3D *v3d, float *vec);
+void view3d_set_clipping(struct View3D *v3d);
+void view3d_clr_clipping(void);
+
void sumo_callback(void *obp);
void init_anim_sumo(void);
void update_anim_sumo(void);
diff --git a/source/blender/include/BSE_view.h b/source/blender/include/BSE_view.h
index 94f5266c4e3..e241f92143b 100644
--- a/source/blender/include/BSE_view.h
+++ b/source/blender/include/BSE_view.h
@@ -46,9 +46,11 @@ struct ScrArea;
void persp_general(int a);
void persp(int a);
-void view3d_get_object_project_mat(struct ScrArea *area, struct Object *ob, float mat[4][4]);
+/* note, the define below is still used for shorts, to calc distances... */
+#define IS_CLIPPED 12000
+void view3d_get_object_project_mat(struct ScrArea *area, struct Object *ob, float pmat[4][4], float vmat[4][4]);
void view3d_project_float(struct ScrArea *area, float *vec, float *adr, float mat[4][4]);
-void view3d_project_short(struct ScrArea *area, float *vec, short *adr, float mat[4][4]);
+void view3d_project_short_clip(struct ScrArea *area, float *vec, short *adr, float projmat[4][4], float viewmat[4][4]);
void view3d_project_short_noclip(struct ScrArea *area, float *vec, short *adr, float mat[4][4]);
void initgrabz(float x, float y, float z);
@@ -57,6 +59,7 @@ void project_short(float *vec, short *adr);
void project_short_noclip(float *vec, short *adr);
void project_int(float *vec, int *adr);
void project_float(float *vec, float *adr);
+
int boundbox_clip(float obmat[][4], struct BoundBox *bb);
void fdrawline(float x1, float y1, float x2, float y2);
void fdrawbox(float x1, float y1, float x2, float y2);
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index c42703b4b17..871d0e3f536 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -60,8 +60,6 @@ typedef struct bDeformGroup {
char name[32];
} bDeformGroup;
-#
-#
typedef struct BoundBox {
float vec[8][3];
} BoundBox;
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 6bd0a91fbdf..f0fe608035a 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -39,6 +39,7 @@ struct Image;
struct Tex;
struct SpaceLink;
struct Base;
+struct BoundBox;
/* This is needed to not let VC choke on near and far... old
* proprietary MS extensions... */
@@ -123,13 +124,17 @@ typedef struct View3D {
short twtype, twmode, twflag, twpad;
float twmat[4][4];
+ /* user defined clipping planes */
+ float clip[4][4];
+ struct BoundBox *clipbb;
+
/* afterdraw, for xray & transparent */
struct ListBase afterdraw;
/* drawflags, denoting state */
short zbuf, transp, xray, pad2;
} View3D;
-/* View3D->flag */
+/* View3D->flag (short) */
#define V3D_MODE (16+32+64+128+256+512)
#define V3D_DISPIMAGE 1
#define V3D_DISPBGPIC 2
@@ -145,6 +150,7 @@ typedef struct View3D {
#define V3D_SELECT_OUTLINE 2048
#define V3D_ZBUF_SELECT 4096
#define V3D_GLOBAL_STATS 8192
+#define V3D_CLIPPING 16384
/* View3D->around */
#define V3D_CENTRE 0
diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c
index 6eed7ac91e0..eb264cf2e17 100644
--- a/source/blender/src/drawimage.c
+++ b/source/blender/src/drawimage.c
@@ -82,6 +82,7 @@
#include "BIF_screen.h"
#include "BSE_trans_types.h"
+#include "BSE_view.h"
/* Modules used */
#include "mydevice.h"
@@ -225,7 +226,7 @@ void uvco_to_areaco(float *vec, short *mval)
{
float x, y;
- mval[0]= 3200;
+ mval[0]= IS_CLIPPED;
x= (vec[0] - G.v2d->cur.xmin)/(G.v2d->cur.xmax-G.v2d->cur.xmin);
y= (vec[1] - G.v2d->cur.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin);
@@ -242,7 +243,7 @@ void uvco_to_areaco_noclip(float *vec, short *mval)
{
float x, y;
- mval[0]= 3200;
+ mval[0]= IS_CLIPPED;
x= (vec[0] - G.v2d->cur.xmin)/(G.v2d->cur.xmax-G.v2d->cur.xmin);
y= (vec[1] - G.v2d->cur.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin);
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index 0310cb477d9..26941b5d71d 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -337,7 +337,7 @@ void ipoco_to_areaco(View2D *v2d, float *vec, short *mval)
{
float x, y;
- mval[0]= 3200;
+ mval[0]= IS_CLIPPED;
x= (vec[0] - v2d->cur.xmin)/(v2d->cur.xmax-v2d->cur.xmin);
y= (vec[1] - v2d->cur.ymin)/(v2d->cur.ymax-v2d->cur.ymin);
@@ -639,7 +639,7 @@ static void draw_solution_line(View2D *v2d, float h)
vec[0]= v2d->cur.xmin;
vec[1]= h;
ipoco_to_areaco(v2d, vec, mval);
- if(mval[0]!=3200) {
+ if(mval[0]!=IS_CLIPPED) {
glBegin(GL_LINES);
glVertex2f(v2d->vert.xmin, mval[1]);
glVertex2f(v2d->vert.xmax, mval[1]);
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 77419925b30..7cc1443ce44 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -279,9 +279,14 @@ void init_draw_rects(void)
static void draw_icon_centered(float *pos, unsigned int *rect, int rectsize)
{
float hsize= (float) rectsize/2.0f;
+// float vals[4];
GLubyte dummy= 0;
glRasterPos3fv(pos);
+// glGetFloatv(GL_CURRENT_RASTER_POSITION_VALID, vals);
+// printf("rasterpos %f\n", vals[0]);
+// glGetFloatv(GL_CURRENT_RASTER_POSITION, vals);
+// printf("pos %f %f %f %f\n", vals[0], vals[1], vals[2], vals[3]);
/* use bitmap to shift rasterpos in pixels */
glBitmap(0, 0, 0.0, 0.0, -hsize, -hsize, &dummy);
@@ -824,14 +829,14 @@ void lattice_foreachScreenVert(void (*func)(void *userData, BPoint *bp, int x, i
DispList *dl = find_displist(&G.obedit->disp, DL_VERTS);
float *co = dl?dl->verts:NULL;
BPoint *bp = editLatt->def;
- float mat[4][4];
+ float pmat[4][4], vmat[4][4];
short s[2];
- view3d_get_object_project_mat(curarea, G.obedit, mat);
+ view3d_get_object_project_mat(curarea, G.obedit, pmat, vmat);
for (i=0; i<N; i++, bp++, co+=3) {
if (bp->hide==0) {
- view3d_project_short(curarea, dl?co:bp->vec, s, mat);
+ view3d_project_short_clip(curarea, dl?co:bp->vec, s, pmat, vmat);
func(userData, bp, s[0], s[1]);
}
}
@@ -898,15 +903,15 @@ static void drawlattice(Object *ob)
static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
- struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float mat[4][4]; } *data = userData;
+ struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
EditVert *eve = EM_get_vert_for_index(index);
short s[2];
if (eve->h==0) {
if (data->clipVerts) {
- view3d_project_short(curarea, co, s, data->mat);
+ view3d_project_short_clip(curarea, co, s, data->pmat, data->vmat);
} else {
- view3d_project_short_noclip(curarea, co, s, data->mat);
+ view3d_project_short_noclip(curarea, co, s, data->pmat);
}
data->func(data->userData, eve, s[0], s[1], index);
@@ -914,7 +919,7 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co
}
void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
{
- struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float mat[4][4]; } data;
+ struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
int dmNeedsFree;
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
@@ -922,7 +927,7 @@ void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, i
data.userData = userData;
data.clipVerts = clipVerts;
- view3d_get_object_project_mat(curarea, G.obedit, data.mat);
+ view3d_get_object_project_mat(curarea, G.obedit, data.pmat, data.vmat);
EM_init_index_arrays(1, 0, 0);
dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
@@ -935,17 +940,17 @@ void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, i
static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
{
- struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float mat[4][4]; } *data = userData;
+ struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
EditEdge *eed = EM_get_edge_for_index(index);
short s[2][2];
if (eed->h==0) {
if (data->clipVerts==1) {
- view3d_project_short(curarea, v0co, s[0], data->mat);
- view3d_project_short(curarea, v1co, s[1], data->mat);
+ view3d_project_short_clip(curarea, v0co, s[0], data->pmat, data->vmat);
+ view3d_project_short_clip(curarea, v1co, s[1], data->pmat, data->vmat);
} else {
- view3d_project_short_noclip(curarea, v0co, s[0], data->mat);
- view3d_project_short_noclip(curarea, v1co, s[1], data->mat);
+ view3d_project_short_noclip(curarea, v0co, s[0], data->pmat);
+ view3d_project_short_noclip(curarea, v1co, s[1], data->pmat);
if (data->clipVerts==2) {
if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<curarea->winx && s[0][1]<curarea->winy))
@@ -959,7 +964,7 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0
}
void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
{
- struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float mat[4][4]; } data;
+ struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
int dmNeedsFree;
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
@@ -967,7 +972,7 @@ void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0,
data.userData = userData;
data.clipVerts = clipVerts;
- view3d_get_object_project_mat(curarea, G.obedit, data.mat);
+ view3d_get_object_project_mat(curarea, G.obedit, data.pmat, data.vmat);
EM_init_index_arrays(0, 1, 0);
dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
@@ -980,26 +985,26 @@ void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0,
static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *no)
{
- struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float mat[4][4]; } *data = userData;
+ struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } *data = userData;
EditFace *efa = EM_get_face_for_index(index);
short s[2];
if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
- view3d_project_short(curarea, cent, s, data->mat);
+ view3d_project_short_clip(curarea, cent, s, data->pmat, data->vmat);
data->func(data->userData, efa, s[0], s[1], index);
}
}
void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData)
{
- struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float mat[4][4]; } data;
+ struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } data;
int dmNeedsFree;
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
data.func = func;
data.userData = userData;
- view3d_get_object_project_mat(curarea, G.obedit, data.mat);
+ view3d_get_object_project_mat(curarea, G.obedit, data.pmat, data.vmat);
EM_init_index_arrays(0, 0, 1);
dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
@@ -1012,12 +1017,12 @@ void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, i
void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), void *userData)
{
- float mat[4][4];
+ float pmat[4][4], vmat[4][4];
short s[2];
Nurb *nu;
int i;
- view3d_get_object_project_mat(curarea, G.obedit, mat);
+ view3d_get_object_project_mat(curarea, G.obedit, pmat, vmat);
for (nu= editNurb.first; nu; nu=nu->next) {
if((nu->type & 7)==CU_BEZIER) {
@@ -1025,11 +1030,11 @@ void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp,
BezTriple *bezt = &nu->bezt[i];
if(bezt->hide==0) {
- view3d_project_short(curarea, bezt->vec[0], s, mat);
+ view3d_project_short_clip(curarea, bezt->vec[0], s, pmat, vmat);
func(userData, nu, NULL, bezt, 0, s[0], s[1]);
- view3d_project_short(curarea, bezt->vec[1], s, mat);
+ view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
func(userData, nu, NULL, bezt, 1, s[0], s[1]);
- view3d_project_short(curarea, bezt->vec[2], s, mat);
+ view3d_project_short_clip(curarea, bezt->vec[2], s, pmat, vmat);
func(userData, nu, NULL, bezt, 2, s[0], s[1]);
}
}
@@ -1039,7 +1044,7 @@ void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp,
BPoint *bp = &nu->bp[i];
if(bp->hide==0) {
- view3d_project_short(curarea, bp->vec, s, mat);
+ view3d_project_short_clip(curarea, bp->vec, s, pmat, vmat);
func(userData, nu, bp, NULL, -1, s[0], s[1]);
}
}
@@ -3646,8 +3651,7 @@ void draw_object(Base *base)
if(zbufoff) glDisable(GL_DEPTH_TEST);
if(warning_recursive) return;
- if(base->flag & OB_FROMDUPLI) return;
- if(base->flag & OB_RADIO) return;
+ if(base->flag & (OB_FROMDUPLI|OB_RADIO)) return;
if(G.f & G_SIMULATION) return;
if((G.f & (G_PICKSEL))==0) {
@@ -3754,8 +3758,14 @@ void draw_object_ext(Base *base)
glDrawBuffer(GL_FRONT);
persp(PERSP_VIEW);
+ if(G.vd->flag & V3D_CLIPPING)
+ view3d_set_clipping(G.vd);
+
draw_object(base);
+ if(G.vd->flag & V3D_CLIPPING)
+ view3d_clr_clipping();
+
G.f &= ~G_DRAW_EXT;
glFlush(); /* reveil frontbuffer drawing */
@@ -3859,7 +3869,6 @@ static int bbs_mesh_solid_EM(DerivedMesh *dm, int facecol)
static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmooth_r)
{
Mesh *me = userData;
- MFace *mf = &me->mface[index];
if (!me->tface || !(me->tface[index].flag&TF_HIDE)) {
set_framebuffer_index_color(index+1);
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 25bd2442880..aee7c588b89 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -765,7 +765,7 @@ static void drawcursor(void)
mx = co[0];
my = co[1];
- if(mx!=3200) {
+ if(mx!=IS_CLIPPED) {
setlinestyle(0);
cpack(0xFF);
circ((float)mx, (float)my, 10.0);
@@ -782,6 +782,66 @@ static void drawcursor(void)
}
}
+/* ********* custom clipping *********** */
+
+static void view3d_draw_clipping(View3D *v3d)
+{
+ BoundBox *bb= v3d->clipbb;
+
+ BIF_ThemeColorShade(TH_BACK, -8);
+
+ glBegin(GL_QUADS);
+
+ glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[3]);
+ glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[1]);
+ glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[5]);
+ glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[3]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[6]);
+ glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[2]);
+ glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[3]);
+
+ glEnd();
+}
+
+void view3d_set_clipping(View3D *v3d)
+{
+ double plane[4];
+ int a;
+
+ for(a=0; a<3; a++) {
+ QUATCOPY(plane, v3d->clip[a]);
+ glClipPlane(GL_CLIP_PLANE0+a, plane);
+ glEnable(GL_CLIP_PLANE0+a);
+ }
+}
+
+void view3d_clr_clipping(void)
+{
+ int a;
+
+ for(a=0; a<4; a++) {
+ glDisable(GL_CLIP_PLANE0+a);
+ }
+}
+
+int view3d_test_clipping(View3D *v3d, float *vec)
+{
+ /* vec in world coordinates, returns 1 if clipped */
+ float view[3];
+
+ VECCOPY(view, vec);
+ Mat4MulVecfl(v3d->viewmat, view);
+
+ if(0.0f < v3d->clip[0][3] + INPR(view, v3d->clip[0]))
+ if(0.0f < v3d->clip[1][3] + INPR(view, v3d->clip[1]))
+ if(0.0f < v3d->clip[2][3] + INPR(view, v3d->clip[2]))
+ if(0.0f < v3d->clip[3][3] + INPR(view, v3d->clip[3]))
+ return 0;
+
+ return 1;
+}
+
+/* ********* end custom clipping *********** */
+
static void view3d_get_viewborder_size(View3D *v3d, float size_r[2])
{
float winmax= MAX2(v3d->area->winx, v3d->area->winy);
@@ -949,6 +1009,9 @@ void backdrawview3d(int test)
glDisable(GL_DEPTH_TEST);
}
+ if(G.vd->flag & V3D_CLIPPING)
+ view3d_set_clipping(G.vd);
+
G.f |= G_BACKBUFSEL;
base= (G.scene->basact);
@@ -967,6 +1030,9 @@ void backdrawview3d(int test)
glDrawBuffer(GL_BACK); /* we were in aux buffers */
#endif
+ if(G.vd->flag & V3D_CLIPPING)
+ view3d_clr_clipping();
+
/* it is important to end a view in a transform compatible with buttons */
persp(PERSP_WIN); // set ortho
bwin_scalematrix(curarea->win, G.vd->blockscale, G.vd->blockscale, G.vd->blockscale);
@@ -1989,11 +2055,8 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
Mat4Invert(v3d->viewinv, v3d->viewmat);
if(v3d->drawtype > OB_WIRE) {
- v3d->zbuf= TRUE;
- glEnable(GL_DEPTH_TEST);
- if(G.f & G_SIMULATION) {
+ if(G.f & G_SIMULATION)
glClearColor(0.0, 0.0, 0.0, 0.0);
- }
else {
float col[3];
BIF_GetThemeColor3fv(TH_BACK, col);
@@ -2013,6 +2076,15 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
myloadmatrix(v3d->viewmat);
persp(PERSP_STORE); // store correct view for persp(PERSP_VIEW) calls
+ if(v3d->flag & V3D_CLIPPING)
+ view3d_draw_clipping(v3d);
+
+ /* set zbuffer after we draw clipping region */
+ if(v3d->drawtype > OB_WIRE) {
+ v3d->zbuf= TRUE;
+ glEnable(GL_DEPTH_TEST);
+ }
+
// needs to be done always, gridview is adjusted in drawgrid() now
v3d->gridview= v3d->grid;
@@ -2036,6 +2108,9 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
}
}
+ if(v3d->flag & V3D_CLIPPING)
+ view3d_set_clipping(v3d);
+
/* draw set first */
if(G.scene->set) {
@@ -2131,6 +2206,9 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
view3d_draw_xray(v3d); // clears zbuffer if it is used!
view3d_draw_transp(v3d);
+ if(v3d->flag & V3D_CLIPPING)
+ view3d_clr_clipping();
+
BIF_draw_manipulator(sa);
if(v3d->zbuf) {
@@ -2212,6 +2290,9 @@ void drawview3d_render(struct View3D *v3d)
glEnable(GL_DEPTH_TEST);
}
+ if(v3d->flag & V3D_CLIPPING)
+ view3d_set_clipping(v3d);
+
if (v3d->drawtype==OB_TEXTURE && G.scene->world) {
glClearColor(G.scene->world->horr, G.scene->world->horg, G.scene->world->horb, 0.0);
} else {
@@ -2325,6 +2406,9 @@ void drawview3d_render(struct View3D *v3d)
view3d_draw_xray(v3d); // clears zbuffer if it is used!
view3d_draw_transp(v3d);
+ if(v3d->flag & V3D_CLIPPING)
+ view3d_clr_clipping();
+
if(v3d->zbuf) {
v3d->zbuf= FALSE;
glDisable(GL_DEPTH_TEST);
diff --git a/source/blender/src/editlattice.c b/source/blender/src/editlattice.c
index 2f7eec5149c..91d56a2ed16 100644
--- a/source/blender/src/editlattice.c
+++ b/source/blender/src/editlattice.c
@@ -214,7 +214,7 @@ void deselectall_Latt(void)
static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y)
{
struct { BPoint *bp; short dist, select, mval[2]; } *data = userData;
- short temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
+ float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
if ((bp->f1&1)==data->select) temp += 5;
if (temp<data->dist) {
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index 11aabb263cd..fb3d8942ee9 100644
--- a/source/blender/src/editmesh_mods.c
+++ b/source/blender/src/editmesh_mods.c
@@ -705,6 +705,10 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
glDrawBuffer(GL_FRONT);
persp(PERSP_VIEW);
+
+ if(G.vd->flag & V3D_CLIPPING)
+ view3d_set_clipping(G.vd);
+
glPushMatrix();
mymultmatrix(G.obedit->obmat);
@@ -778,6 +782,9 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
glFlush();
glDrawBuffer(GL_BACK);
+ if(G.vd->flag & V3D_CLIPPING)
+ view3d_clr_clipping();
+
/* signal that frontbuf differs from back */
curarea->win_swap= WIN_FRONT_OK;
diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c
index d51f2940b9c..80814b2f220 100644
--- a/source/blender/src/editmesh_tools.c
+++ b/source/blender/src/editmesh_tools.c
@@ -4293,13 +4293,13 @@ int EdgeSlide(short immediate, float imperc)
LinkNode *edgelist = NULL, *vertlist=NULL, *look;
GHash *vertgh;
SlideVert *tempsv;
- float perc = 0, percp = 0,vertdist, projectMat[4][4];
+ float perc = 0, percp = 0,vertdist, projectMat[4][4], viewMat[4][4];
int i = 0,j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0;
short event, draw=1;
short mval[2], mvalo[2];
char str[128];
- view3d_get_object_project_mat(curarea, G.obedit, projectMat);
+ view3d_get_object_project_mat(curarea, G.obedit, projectMat, viewMat);
mvalo[0] = -1; mvalo[1] = -1;
numsel =0;
diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c
index c9e2a09c957..89a6e4f4339 100644
--- a/source/blender/src/editview.c
+++ b/source/blender/src/editview.c
@@ -826,7 +826,7 @@ void mouse_cursor(void)
initgrabz(fp[0], fp[1], fp[2]);
- if(mval[0]!=3200) {
+ if(mval[0]!=IS_CLIPPED) {
window_to_3d(dvec, mval[0]-mx, mval[1]-my);
VecSubf(fp, fp, dvec);
@@ -2001,3 +2001,59 @@ void fly(void)
}
+void view3d_edit_clipping(View3D *v3d)
+{
+
+ if(v3d->flag & V3D_CLIPPING) {
+ v3d->flag &= ~V3D_CLIPPING;
+ scrarea_queue_winredraw(curarea);
+ if(v3d->clipbb) MEM_freeN(v3d->clipbb);
+ v3d->clipbb= NULL;
+ }
+ else {
+ rcti rect;
+ double mvmatrix[16];
+ double projmatrix[16];
+ double xs, ys, p[3];
+ GLint viewport[4];
+ short val;
+
+ /* get border in window coords */
+ setlinestyle(2);
+ val= get_border(&rect, 3);
+ setlinestyle(0);
+ if(val==0) return;
+
+ v3d->flag |= V3D_CLIPPING;
+ v3d->clipbb= MEM_mallocN(sizeof(BoundBox), "clipbb");
+
+ /* convert border to 3d coordinates */
+
+ /* Get the matrices needed for gluUnProject */
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
+ glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
+
+ /* Set up viewport so that gluUnProject will give correct values */
+ viewport[0] = 0;
+ viewport[1] = 0;
+
+ /* four clipping planes and bounding volume */
+ for(val=0; val<4; val++) {
+
+ xs= (val==0||val==3)?rect.xmin:rect.xmax;
+ ys= (val==0||val==1)?rect.ymin:rect.ymax;
+ gluUnProject(xs, ys, 0.0, mvmatrix, projmatrix, viewport, &p[0], &p[1], &p[2]);
+ VECCOPY(v3d->clipbb->vec[val], p);
+
+ VECCOPY(v3d->clip[val], G.vd->viewinv[val & 1]);
+ if(val>1) VecMulf(v3d->clip[val], -1.0f);
+ v3d->clip[val][3]= - v3d->clip[val][0]*p[0] - v3d->clip[val][1]*p[1] - v3d->clip[val][2]*p[2];
+
+ gluUnProject(xs, ys, 1.0, mvmatrix, projmatrix, viewport, &p[0], &p[1], &p[2]);
+ VECCOPY(v3d->clipbb->vec[4+val], p);
+ }
+
+ }
+}
+
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index eaa4faf9e62..ac8fd8081fd 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -1128,9 +1128,11 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case BKEY:
- if((G.qual==LR_SHIFTKEY))
+ if(G.qual==LR_ALTKEY)
+ view3d_edit_clipping(v3d);
+ else if(G.qual==LR_SHIFTKEY)
set_render_border();
- else if((G.qual==0))
+ else if(G.qual==0)
borderselect();
break;
case CKEY:
@@ -4494,13 +4496,13 @@ void freespacelist(ListBase *lb)
else if(sl->spacetype==SPACE_BUTS) {
SpaceButs *buts= (SpaceButs*) sl;
if(buts->rect) MEM_freeN(buts->rect);
- if(G.buts==buts) G.buts= 0;
+ if(G.buts==buts) G.buts= NULL;
}
else if(sl->spacetype==SPACE_IPO) {
SpaceIpo *si= (SpaceIpo*) sl;
if(si->editipo) MEM_freeN(si->editipo);
free_ipokey(&si->ipokey);
- if(G.sipo==si) G.sipo= 0;
+ if(G.sipo==si) G.sipo= NULL;
}
else if(sl->spacetype==SPACE_VIEW3D) {
View3D *vd= (View3D*) sl;
@@ -4510,7 +4512,8 @@ void freespacelist(ListBase *lb)
MEM_freeN(vd->bgpic);
}
if(vd->localvd) MEM_freeN(vd->localvd);
- if(G.vd==vd) G.vd= 0;
+ if(vd->clipbb) MEM_freeN(vd->clipbb);
+ if(G.vd==vd) G.vd= NULL;
}
else if(sl->spacetype==SPACE_OOPS) {
free_oopspace((SpaceOops *)sl);
@@ -4544,7 +4547,7 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
duplicatelist(lb1, lb2);
- /* lb1 is kopie from lb2, from lb2 we free the file list */
+ /* lb1 is copy from lb2, from lb2 we free the file list */
sl= lb2->first;
while(sl) {
@@ -4583,20 +4586,21 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
if(sl->spacetype==SPACE_BUTS) {
SpaceButs *buts= (SpaceButs *)sl;
- buts->rect= 0;
+ buts->rect= NULL;
}
else if(sl->spacetype==SPACE_IPO) {
SpaceIpo *si= (SpaceIpo *)sl;
- si->editipo= 0;
- si->ipokey.first= si->ipokey.last= 0;
+ si->editipo= NULL;
+ si->ipokey.first= si->ipokey.last= NULL;
}
else if(sl->spacetype==SPACE_VIEW3D) {
View3D *vd= (View3D *)sl;
if(vd->bgpic) {
vd->bgpic= MEM_dupallocN(vd->bgpic);
- vd->bgpic->rect= 0;
+ vd->bgpic->rect= NULL;
if(vd->bgpic->ima) vd->bgpic->ima->id.us++;
}
+ vd->clipbb= MEM_dupallocN(vd->clipbb);
}
sl= sl->next;
}
@@ -4608,7 +4612,7 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
View3D *v3d= (View3D*) sl;
if(v3d->localvd) {
restore_localviewdata(v3d);
- v3d->localvd= 0;
+ v3d->localvd= NULL;
v3d->localview= 0;
v3d->lay &= 0xFFFFFF;
}
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index ea11b17f26d..53d55c7b772 100755
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -117,7 +117,7 @@ static void helpline(TransInfo *t, float *vec)
getmouseco_areawin(mval);
project_float(vecrot, cent); // no overflow in extreme cases
- if(cent[0]!=3200.0f) {
+ if(cent[0]!=IS_CLIPPED) {
persp(PERSP_WIN);
glDrawBuffer(GL_FRONT);
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index 9b3eab557d0..aef0171bad6 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -173,12 +173,17 @@ void project_short(float *vec, short *adr) /* clips */
{
float fx, fy, vec4[4];
- adr[0]= 3200;
+ adr[0]= IS_CLIPPED;
+
+ if(G.vd->flag & V3D_CLIPPING) {
+ if(view3d_test_clipping(G.vd, vec))
+ return;
+ }
+
VECCOPY(vec4, vec);
vec4[3]= 1.0;
-
Mat4MulVec4fl(G.vd->persmat, vec4);
-
+
if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */
fx= (curarea->winx/2)*(1 + vec4[0]/vec4[3]);
@@ -222,7 +227,7 @@ void project_short_noclip(float *vec, short *adr)
{
float fx, fy, vec4[4];
- adr[0]= 3200;
+ adr[0]= IS_CLIPPED;
VECCOPY(vec4, vec);
vec4[3]= 1.0;
@@ -247,7 +252,7 @@ void project_float(float *vec, float *adr)
{
float vec4[4];
- adr[0]= 3200.0;
+ adr[0]= IS_CLIPPED;
VECCOPY(vec4, vec);
vec4[3]= 1.0;
@@ -259,29 +264,41 @@ void project_float(float *vec, float *adr)
}
}
-void view3d_get_object_project_mat(ScrArea *area, Object *ob, float mat[4][4])
+void view3d_get_object_project_mat(ScrArea *area, Object *ob, float pmat[4][4], float vmat[4][4])
{
if (area->spacetype!=SPACE_VIEW3D || !area->spacedata.first) {
- Mat4One(mat);
+ Mat4One(pmat);
+ Mat4One(vmat);
} else {
View3D *vd = area->spacedata.first;
- float tmp[4][4];
- Mat4MulMat4(tmp, ob->obmat, vd->viewmat);
- Mat4MulMat4(mat, tmp, vd->winmat1);
+ Mat4MulMat4(vmat, ob->obmat, vd->viewmat);
+ Mat4MulMat4(pmat, vmat, vd->winmat1);
}
}
-void view3d_project_short(ScrArea *area, float *vec, short *adr, float mat[4][4])
+/* projectmat brings it to window coords, viewmat to rotated view (eye space) */
+void view3d_project_short_clip(ScrArea *area, float *vec, short *adr, float projmat[4][4], float viewmat[4][4])
{
+ View3D *v3d= area->spacedata.first;
float fx, fy, vec4[4];
- adr[0]= 3200;
+ adr[0]= IS_CLIPPED;
+
+ /* clipplanes in eye space */
+ if(v3d->flag & V3D_CLIPPING) {
+ VECCOPY(vec4, vec);
+ Mat4MulVecfl(viewmat, vec4);
+ if(view3d_test_clipping(v3d, vec4))
+ return;
+ }
+
VECCOPY(vec4, vec);
vec4[3]= 1.0;
- Mat4MulVec4fl(mat, vec4);
-
+ Mat4MulVec4fl(projmat, vec4);
+
+ /* clipplanes in window space */
if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */
fx= (area->winx/2)*(1 + vec4[0]/vec4[3]);
@@ -301,7 +318,8 @@ void view3d_project_short_noclip(ScrArea *area, float *vec, short *adr, float ma
{
float fx, fy, vec4[4];
- adr[0]= 3200;
+ adr[0]= IS_CLIPPED;
+
VECCOPY(vec4, vec);
vec4[3]= 1.0;
@@ -326,7 +344,7 @@ void view3d_project_float(ScrArea *area, float *vec, float *adr, float mat[4][4]
{
float vec4[4];
- adr[0]= 3200.0;
+ adr[0]= IS_CLIPPED;
VECCOPY(vec4, vec);
vec4[3]= 1.0;
@@ -975,6 +993,9 @@ short view3d_opengl_select(unsigned int *buffer, unsigned int bufsize, short x1
glEnable(GL_DEPTH_TEST);
}
+ if(G.vd->flag & V3D_CLIPPING)
+ view3d_set_clipping(G.vd);
+
glSelectBuffer( bufsize, (GLuint *)buffer);
glRenderMode(GL_SELECT);
glInitNames(); /* these two calls whatfor? It doesnt work otherwise */
@@ -1015,6 +1036,9 @@ short view3d_opengl_select(unsigned int *buffer, unsigned int bufsize, short x1
glDisable(GL_DEPTH_TEST);
}
persp(PERSP_WIN);
+
+ if(G.vd->flag & V3D_CLIPPING)
+ view3d_clr_clipping();
return hits;
}