Seam Cutting in Faceselect Mode:
- Mark Border Seam: mark edges on the border of face selection as seam. - Clear Seam: clears seams in selected faces. Hotkey: Ctrl+E - Alt+RMB Click: mark/clear edge as seam - Alt+Shift+RMB Click: mark/clear seams along the shortest/straightest path from last marked seam. The cost of the path also includes some measure of 'straightness' next to the typical distance to make things work more predicatble and edgeloop friendly. Note that this cuts a path from edge to edge, not vertex to vertex. That gives some nice control over the direction of the seam. Also includes: - Removed old LSCM code. - Fix updates glitches with DerivedMesh/Subsurf drawing in FaceSelect mode. Now there's a drawMappedFacesTex instead of drawFacesTex. - Minimize Stretch menu entry called Limit Stitch. - Removed the lasttface global, was being set before it was used anyway, so might as wel return from a function. - Moved some backbuf sampling code to drawview.c from editmesh, so it can be used by Faceselect and VPaint. - Use BLI_heap in parametrizer.c.
This commit is contained in:
@@ -47,7 +47,6 @@
|
||||
|
||||
struct MVert;
|
||||
struct Object;
|
||||
struct TFace;
|
||||
struct EditMesh;
|
||||
struct DispListMesh;
|
||||
struct ModifierData;
|
||||
@@ -144,7 +143,7 @@ struct DerivedMesh {
|
||||
/* Draw all faces uses TFace
|
||||
* o Drawing options too complicated to enumerate, look at code.
|
||||
*/
|
||||
void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tf, int matnr));
|
||||
void (*drawMappedFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int matnr), void *userData);
|
||||
|
||||
/* Draw mapped faces (no color, or texture)
|
||||
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-face-index, drawSmooth_r) returns true
|
||||
|
||||
@@ -366,7 +366,7 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch
|
||||
glShadeModel(GL_FLAT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr))
|
||||
static void meshDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData)
|
||||
{
|
||||
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
|
||||
Mesh *me = mdm->me;
|
||||
@@ -382,7 +382,7 @@ static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
|
||||
int flag;
|
||||
unsigned char *cp= NULL;
|
||||
|
||||
flag = setDrawParams(tf, mf->mat_nr);
|
||||
flag = setDrawParams(userData, i, mf->mat_nr);
|
||||
|
||||
if (flag==0) {
|
||||
continue;
|
||||
@@ -535,7 +535,7 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]
|
||||
|
||||
mdm->dm.drawFacesSolid = meshDM_drawFacesSolid;
|
||||
mdm->dm.drawFacesColored = meshDM_drawFacesColored;
|
||||
mdm->dm.drawFacesTex = meshDM_drawFacesTex;
|
||||
mdm->dm.drawMappedFacesTex = meshDM_drawMappedFacesTex;
|
||||
mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
|
||||
|
||||
mdm->dm.drawMappedEdges = meshDM_drawMappedEdges;
|
||||
@@ -1202,7 +1202,8 @@ static void ssDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
|
||||
|
||||
#undef PASSVERT
|
||||
}
|
||||
static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr))
|
||||
|
||||
static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData)
|
||||
{
|
||||
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
|
||||
DispListMesh *dlm = ssdm->dlm;
|
||||
@@ -1210,7 +1211,7 @@ static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, i
|
||||
MFace *mface= dlm->mface;
|
||||
TFace *tface = dlm->tface;
|
||||
float *nors = dlm->nors;
|
||||
int a;
|
||||
int a, index=-1;
|
||||
|
||||
for (a=0; a<dlm->totface; a++) {
|
||||
MFace *mf= &mface[a];
|
||||
@@ -1218,7 +1219,9 @@ static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, i
|
||||
int flag;
|
||||
unsigned char *cp= NULL;
|
||||
|
||||
flag = setDrawParams(tf, mf->mat_nr);
|
||||
if (mf->flag&ME_FACE_STEPINDEX) index++;
|
||||
|
||||
flag = setDrawParams(userData, index, mf->mat_nr);
|
||||
|
||||
if (flag==0) {
|
||||
continue;
|
||||
@@ -1401,7 +1404,7 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)
|
||||
|
||||
ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid;
|
||||
ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
|
||||
ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
|
||||
ssdm->dm.drawMappedFacesTex = ssDM_drawMappedFacesTex;
|
||||
ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces;
|
||||
|
||||
/* EM functions */
|
||||
@@ -1624,7 +1627,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
|
||||
ModifierData *md;
|
||||
float (*deformedVerts)[3] = NULL;
|
||||
DerivedMesh *dm;
|
||||
int i, numVerts, cageIndex = modifiers_getCageIndex(ob, NULL);
|
||||
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
|
||||
|
||||
modifiers_clearErrors(ob);
|
||||
|
||||
|
||||
@@ -1376,7 +1376,7 @@ static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned ch
|
||||
|
||||
ccgFaceIterator_free(fi);
|
||||
}
|
||||
static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) {
|
||||
static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData) {
|
||||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
|
||||
@@ -1395,7 +1395,8 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
|
||||
MFace *mf = &mface[index];
|
||||
TFace *tf = tface?&tface[index]:NULL;
|
||||
unsigned char *cp= NULL;
|
||||
int flag = setDrawParams(tf, mf->mat_nr);
|
||||
int findex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
|
||||
int flag = (findex == -1)? 0: setDrawParams(userData, findex, mf->mat_nr);
|
||||
|
||||
if (flag==0) {
|
||||
continue;
|
||||
@@ -1662,7 +1663,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int d
|
||||
ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
|
||||
ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
|
||||
ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
|
||||
ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
|
||||
ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
|
||||
ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
|
||||
|
||||
ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
|
||||
|
||||
@@ -37,6 +37,7 @@ struct Image;
|
||||
struct TFace;
|
||||
struct Object;
|
||||
struct Mesh;
|
||||
struct EdgeHash;
|
||||
|
||||
/**
|
||||
* Enables or disable mipmapping for realtime images (textures).
|
||||
@@ -74,6 +75,7 @@ void free_all_realtime_images(void);
|
||||
void make_repbind(struct Image *ima);
|
||||
int set_tpage(struct TFace *tface);
|
||||
void draw_tface_mesh(struct Object *ob, struct Mesh *me, int dt);
|
||||
struct EdgeHash *get_tface_mesh_marked_edge_info(struct Mesh *me);
|
||||
void init_realtime_GL(void);
|
||||
|
||||
#endif /* BDR_DRAWMESH_H */
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
struct TFace;
|
||||
struct Mesh;
|
||||
|
||||
void set_lasttface(void);
|
||||
struct TFace *get_active_tface(void);
|
||||
void calculate_uv_map(unsigned short mapmode);
|
||||
void default_uv(float uv[][2], float size);
|
||||
void default_tface(struct TFace *tface);
|
||||
@@ -49,13 +49,13 @@ void selectswap_tface(void);
|
||||
void rotate_uv_tface(void);
|
||||
void mirror_uv_tface(void);
|
||||
void minmax_tface(float *min, float *max);
|
||||
int face_pick(struct Mesh *me, short x, short y, unsigned int *index);
|
||||
void face_select(void);
|
||||
void face_borderselect(void);
|
||||
void uv_autocalc_tface(void);
|
||||
void set_faceselect(void);
|
||||
void face_draw(void);
|
||||
void get_same_uv(void);
|
||||
void seam_mark_clear_tface(short mode);
|
||||
|
||||
#endif /* BDR_EDITFACE_H */
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
void set_seamtface(void); /* set TF_SEAM flags in tfaces */
|
||||
void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index);
|
||||
|
||||
void unwrap_lscm(void); /* unwrap faces selected in 3d view */
|
||||
void unwrap_lscm_new(void);
|
||||
void unwrap_lscm(short seamcut); /* unwrap faces selected in 3d view */
|
||||
void minimize_stretch_tface_uv(void); /* optimize faces selected in uv editor */
|
||||
void smooth_area_tface_uv(void);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ struct Object;
|
||||
struct BGpic;
|
||||
struct rcti;
|
||||
struct ScrArea;
|
||||
struct ImBuf;
|
||||
|
||||
void setalpha_bgpic(struct BGpic *bgpic);
|
||||
void default_gl_light(void);
|
||||
@@ -52,6 +53,11 @@ void do_viewbuts(unsigned short event);
|
||||
void add_view3d_after(struct View3D *v3d, struct Base *base, int type);
|
||||
|
||||
void backdrawview3d(int test);
|
||||
void check_backbuf(void);
|
||||
unsigned int sample_backbuf(int x, int y);
|
||||
struct ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax);
|
||||
unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist);;
|
||||
|
||||
void drawview3dspace(struct ScrArea *sa, void *spacedata);
|
||||
void drawview3d_render(struct View3D *v3d, int winx, int winy);
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ extern void do_latticebuts(unsigned short event);
|
||||
extern void do_fpaintbuts(unsigned short event);
|
||||
extern void do_cambuts(unsigned short event);
|
||||
extern void do_armbuts(unsigned short event);
|
||||
extern void do_uvautocalculationbuts(unsigned short event);
|
||||
|
||||
extern char *get_vertexgroup_menustr(struct Object *ob); // used in object buttons
|
||||
|
||||
@@ -113,11 +114,6 @@ extern void do_scriptbuts(unsigned short event);
|
||||
/* ipowindow */
|
||||
extern void do_ipobuts(unsigned short event); // drawipo.c (bad! ton)
|
||||
|
||||
/* uvautocalculation */
|
||||
void do_uvautocalculationbuts(unsigned short event);
|
||||
void get_uvautocalculationsettings(float *radius,float *cubesize, int *mapdir, int *mapalign);
|
||||
|
||||
|
||||
/* butspace.c */
|
||||
void test_meshpoin_but(char *name, struct ID **idpp);
|
||||
void test_obpoin_but(char *name, struct ID **idpp);
|
||||
|
||||
@@ -155,14 +155,14 @@ typedef struct Mesh {
|
||||
#define TF_SUB 3
|
||||
|
||||
/* tface->unwrap */
|
||||
#define TF_SEAM1 1
|
||||
#define TF_SEAM2 2
|
||||
#define TF_SEAM3 4
|
||||
#define TF_SEAM4 8
|
||||
#define TF_PIN1 16
|
||||
#define TF_PIN2 32
|
||||
#define TF_PIN3 64
|
||||
#define TF_PIN4 128
|
||||
#define TF_DEPRECATED1 1
|
||||
#define TF_DEPRECATED2 2
|
||||
#define TF_DEPRECATED3 4
|
||||
#define TF_DEPRECATED4 8
|
||||
#define TF_PIN1 16
|
||||
#define TF_PIN2 32
|
||||
#define TF_PIN3 64
|
||||
#define TF_PIN4 128
|
||||
|
||||
#define MESH_MAX_VERTS 2000000000L
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ typedef struct MSticky {
|
||||
// reserve 16 for ME_HIDE
|
||||
#define ME_EDGERENDER (1<<5)
|
||||
#define ME_LOOSEEDGE (1<<7)
|
||||
#define ME_SEAM_LAST (1<<8)
|
||||
#define ME_EDGE_STEPINDEX (1<<15)
|
||||
|
||||
/* puno = vertexnormal (mface) */
|
||||
|
||||
@@ -580,7 +580,7 @@ void do_butspace(unsigned short event)
|
||||
do_constraintbuts(event);
|
||||
}
|
||||
else if(event<=B_UVAUTOCALCBUTS) {
|
||||
do_uvautocalculationbuts(event);
|
||||
do_uvcalculationbuts(event);
|
||||
}
|
||||
else if(event<=B_EFFECTSBUTS) {
|
||||
do_effects_panels(event);
|
||||
|
||||
@@ -3540,7 +3540,8 @@ void do_fpaintbuts(unsigned short event)
|
||||
Mesh *me;
|
||||
Object *ob;
|
||||
bDeformGroup *defGroup;
|
||||
extern TFace *lasttface; /* caches info on tface bookkeeping ?*/
|
||||
TFace *activetf, *tf;
|
||||
int a;
|
||||
extern VPaint Gwp; /* from vpaint */
|
||||
|
||||
ob= OBACT;
|
||||
@@ -3555,42 +3556,37 @@ void do_fpaintbuts(unsigned short event)
|
||||
case B_COPY_TF_UV:
|
||||
case B_COPY_TF_COL:
|
||||
case B_COPY_TF_TEX:
|
||||
me= get_mesh(ob);
|
||||
if(me && me->tface) {
|
||||
/* extern TFace *lasttface; */
|
||||
TFace *tface= me->tface;
|
||||
int a= me->totface;
|
||||
me = get_mesh(OBACT);
|
||||
activetf = get_active_tface();
|
||||
|
||||
set_lasttface();
|
||||
if(lasttface) {
|
||||
|
||||
while(a--) {
|
||||
if(tface!=lasttface && (tface->flag & TF_SELECT)) {
|
||||
if(event==B_COPY_TF_MODE) {
|
||||
tface->mode= lasttface->mode;
|
||||
tface->transp= lasttface->transp;
|
||||
}
|
||||
else if(event==B_COPY_TF_UV) {
|
||||
memcpy(tface->uv, lasttface->uv, sizeof(tface->uv));
|
||||
tface->tpage= lasttface->tpage;
|
||||
tface->tile= lasttface->tile;
|
||||
|
||||
if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES;
|
||||
else tface->mode &= ~TF_TILES;
|
||||
|
||||
}
|
||||
else if(event==B_COPY_TF_TEX) {
|
||||
tface->tpage= lasttface->tpage;
|
||||
tface->tile= lasttface->tile;
|
||||
|
||||
if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES;
|
||||
else tface->mode &= ~TF_TILES;
|
||||
}
|
||||
else if(event==B_COPY_TF_COL) memcpy(tface->col, lasttface->col, sizeof(tface->col));
|
||||
if(me && activetf) {
|
||||
for (a=0, tf=me->tface; a < me->totface; a++, tf++) {
|
||||
if(tf!=activetf && (tf->flag & TF_SELECT)) {
|
||||
if(event==B_COPY_TF_MODE) {
|
||||
tf->mode= activetf->mode;
|
||||
tf->transp= activetf->transp;
|
||||
}
|
||||
tface++;
|
||||
else if(event==B_COPY_TF_UV) {
|
||||
memcpy(tf->uv, activetf->uv, sizeof(tf->uv));
|
||||
tf->tpage= activetf->tpage;
|
||||
tf->tile= activetf->tile;
|
||||
|
||||
if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
|
||||
else tf->mode &= ~TF_TILES;
|
||||
|
||||
}
|
||||
else if(event==B_COPY_TF_TEX) {
|
||||
tf->tpage= activetf->tpage;
|
||||
tf->tile= activetf->tile;
|
||||
|
||||
if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
|
||||
else tf->mode &= ~TF_TILES;
|
||||
}
|
||||
else if(event==B_COPY_TF_COL)
|
||||
memcpy(tf->col, activetf->col, sizeof(tf->col));
|
||||
}
|
||||
}
|
||||
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
do_shared_vertexcol(me);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
@@ -3616,17 +3612,17 @@ void do_fpaintbuts(unsigned short event)
|
||||
break;
|
||||
|
||||
case B_TFACE_HALO:
|
||||
set_lasttface();
|
||||
if(lasttface) {
|
||||
lasttface->mode &= ~TF_BILLBOARD2;
|
||||
activetf = get_active_tface();
|
||||
if(activetf) {
|
||||
activetf->mode &= ~TF_BILLBOARD2;
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case B_TFACE_BILLB:
|
||||
set_lasttface();
|
||||
if(lasttface) {
|
||||
lasttface->mode &= ~TF_BILLBOARD;
|
||||
activetf = get_active_tface();
|
||||
if(activetf) {
|
||||
activetf->mode &= ~TF_BILLBOARD;
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
}
|
||||
break;
|
||||
@@ -3786,38 +3782,37 @@ static void editing_panel_mesh_texface(void)
|
||||
{
|
||||
extern VPaint Gvp; /* from vpaint */
|
||||
uiBlock *block;
|
||||
extern TFace *lasttface;
|
||||
TFace *tf;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_texface", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
if(uiNewPanel(curarea, block, "Texture face", "Editing", 960, 0, 318, 204)==0) return;
|
||||
|
||||
set_lasttface(); // checks for ob type
|
||||
if(lasttface) {
|
||||
tf = get_active_tface();
|
||||
if(tf) {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, TF_TEX, B_REDR_3D_IMA, "Tex", 600,160,60,19, &tf->mode, 0, 0, 0, 0, "Render face with texture");
|
||||
uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles", 660,160,60,19, &tf->mode, 0, 0, 0, 0, "Use tilemode for face");
|
||||
uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light", 720,160,60,19, &tf->mode, 0, 0, 0, 0, "Use light for face");
|
||||
uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &tf->mode, 0, 0, 0, 0, "Make face invisible");
|
||||
uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision detection");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, TF_TEX, B_REDR_3D_IMA, "Tex", 600,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Render face with texture");
|
||||
uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles", 660,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use tilemode for face");
|
||||
uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light", 720,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use light for face");
|
||||
uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Make face invisible");
|
||||
uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use face for collision detection");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared", 600,135,60,19, &lasttface->mode, 0, 0, 0, 0, "Blend vertex colours across face when vertices are shared");
|
||||
uiDefButBitS(block, TOG, TF_TWOSIDE, REDRAWVIEW3D, "Twoside",660,135,60,19, &lasttface->mode, 0, 0, 0, 0, "Render face twosided");
|
||||
uiDefButBitS(block, TOG, TF_OBCOL, REDRAWVIEW3D, "ObColor",720,135,60,19, &lasttface->mode, 0, 0, 0, 0, "Use ObColor instead of vertex colours");
|
||||
uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared", 600,135,60,19, &tf->mode, 0, 0, 0, 0, "Blend vertex colours across face when vertices are shared");
|
||||
uiDefButBitS(block, TOG, TF_TWOSIDE, REDRAWVIEW3D, "Twoside",660,135,60,19, &tf->mode, 0, 0, 0, 0, "Render face twosided");
|
||||
uiDefButBitS(block, TOG, TF_OBCOL, REDRAWVIEW3D, "ObColor",720,135,60,19, &tf->mode, 0, 0, 0, 0, "Use ObColor instead of vertex colours");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
uiDefButBitS(block, TOG, TF_BILLBOARD, B_TFACE_HALO, "Halo", 600,110,60,19, &lasttface->mode, 0, 0, 0, 0, "Screen aligned billboard");
|
||||
uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &lasttface->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint");
|
||||
uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &lasttface->mode, 0, 0, 0, 0, "Face is used for shadow");
|
||||
uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &lasttface->mode, 0, 0, 0, 0, "Enable bitmap text on face");
|
||||
uiDefButBitS(block, TOG, TF_BILLBOARD, B_TFACE_HALO, "Halo", 600,110,60,19, &tf->mode, 0, 0, 0, 0, "Screen aligned billboard");
|
||||
uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &tf->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint");
|
||||
uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &tf->mode, 0, 0, 0, 0, "Face is used for shadow");
|
||||
uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable bitmap text on face");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiBlockSetCol(block, TH_BUT_SETTING1);
|
||||
uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque", 600,80,60,19, &lasttface->transp, 2.0, 0.0, 0, 0, "Render colour of textured face as colour");
|
||||
uiDefButC(block, ROW, REDRAWVIEW3D, "Add", 660,80,60,19, &lasttface->transp, 2.0, 1.0, 0, 0, "Render face transparent and add colour of face");
|
||||
uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha", 720,80,60,19, &lasttface->transp, 2.0, 2.0, 0, 0, "Render polygon transparent, depending on alpha channel of the texture");
|
||||
uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque", 600,80,60,19, &tf->transp, 2.0, 0.0, 0, 0, "Render colour of textured face as colour");
|
||||
uiDefButC(block, ROW, REDRAWVIEW3D, "Add", 660,80,60,19, &tf->transp, 2.0, 1.0, 0, 0, "Render face transparent and add colour of face");
|
||||
uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha", 720,80,60,19, &tf->transp, 2.0, 2.0, 0, 0, "Render polygon transparent, depending on alpha channel of the texture");
|
||||
|
||||
uiBlockSetCol(block, TH_AUTO);
|
||||
|
||||
@@ -3832,29 +3827,9 @@ static void editing_panel_mesh_texface(void)
|
||||
}
|
||||
}
|
||||
|
||||
void do_uvautocalculationbuts(unsigned short event)
|
||||
void do_uvcalculationbuts(unsigned short event)
|
||||
{
|
||||
switch(event) {
|
||||
case B_UVAUTO_STD1:
|
||||
case B_UVAUTO_STD2:
|
||||
case B_UVAUTO_STD4:
|
||||
case B_UVAUTO_STD8:
|
||||
case B_UVAUTO_CUBE:
|
||||
calculate_uv_map(event);
|
||||
break;
|
||||
case B_UVAUTO_BOUNDS1:
|
||||
case B_UVAUTO_BOUNDS2:
|
||||
case B_UVAUTO_BOUNDS4:
|
||||
case B_UVAUTO_BOUNDS8:
|
||||
case B_UVAUTO_SPHERE:
|
||||
case B_UVAUTO_CYLINDER:
|
||||
case B_UVAUTO_WINDOW:
|
||||
if(select_area(SPACE_VIEW3D)) calculate_uv_map(event);
|
||||
break;
|
||||
case B_UVAUTO_UNWRAP:
|
||||
unwrap_lscm();
|
||||
break;
|
||||
}
|
||||
/* nothing to do here */
|
||||
}
|
||||
|
||||
static void editing_panel_mesh_uvautocalculation(void)
|
||||
@@ -3877,9 +3852,8 @@ static void editing_panel_mesh_uvautocalculation(void)
|
||||
row-= 4*butHB+butS;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, MENU, REDRAWBUTSEDIT, "Unwrapper%t|Conformal%x0|Angle Based%x1|Conformal (Old)%x2",100,row,200,butH, &G.scene->toolsettings->unwrapper, 0, 0, 0, 0, "Unwrap method");
|
||||
if (G.scene->toolsettings->unwrapper != 2)
|
||||
uiDefButBitS(block, TOG, 1, B_NOP, "Fill Holes",100,row-butHB,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0, "Fill holes to prevent internal overlaps");
|
||||
uiDefButS(block, MENU, REDRAWBUTSEDIT, "Unwrapper%t|Conformal%x0|Angle Based%x1",100,row,200,butH, &G.scene->toolsettings->unwrapper, 0, 0, 0, 0, "Unwrap method");
|
||||
uiDefButBitS(block, TOG, 1, B_NOP, "Fill Holes",100,row-butHB,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0, "Fill holes to prevent internal overlaps");
|
||||
uiBlockEndAlign(block);
|
||||
row-= 2*butHB+butS;
|
||||
|
||||
|
||||
@@ -205,24 +205,24 @@ void calc_image_view(SpaceImage *sima, char mode)
|
||||
|
||||
void what_image(SpaceImage *sima)
|
||||
{
|
||||
extern TFace *lasttface; /* editface.c */
|
||||
TFace *activetf;
|
||||
Mesh *me;
|
||||
|
||||
if(sima->mode==SI_TEXTURE) {
|
||||
if(G.f & G_FACESELECT) {
|
||||
|
||||
sima->image= 0;
|
||||
me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0);
|
||||
set_lasttface();
|
||||
me= get_mesh(OBACT);
|
||||
activetf = get_active_tface();
|
||||
|
||||
if(me && me->tface && lasttface && lasttface->mode & TF_TEX) {
|
||||
sima->image= lasttface->tpage;
|
||||
if(me && me->tface && activetf && activetf->mode & TF_TEX) {
|
||||
sima->image= activetf->tpage;
|
||||
|
||||
if(sima->flag & SI_EDITTILE);
|
||||
else sima->curtile= lasttface->tile;
|
||||
else sima->curtile= activetf->tile;
|
||||
|
||||
if(sima->image) {
|
||||
if(lasttface->mode & TF_TILES)
|
||||
if(activetf->mode & TF_TILES)
|
||||
sima->image->tpageflag |= IMA_TILES;
|
||||
else sima->image->tpageflag &= ~IMA_TILES;
|
||||
}
|
||||
|
||||
@@ -515,7 +515,8 @@ static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flag
|
||||
flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
|
||||
*flags_p |= flags;
|
||||
}
|
||||
static EdgeHash *get_marked_edge_info(Mesh *me)
|
||||
|
||||
EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
|
||||
{
|
||||
EdgeHash *eh = BLI_edgehash_new();
|
||||
int i;
|
||||
@@ -618,20 +619,25 @@ static int draw_tfaces3D__setActiveOpts(void *userData, int index)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static int draw_tfaces3D__drawFaceOpts(TFace *tface, int matnr)
|
||||
static int draw_tfaces3D__drawFaceOpts(void *userData, int index, int matnr)
|
||||
{
|
||||
if (tface && !(tface->flag&TF_HIDE) && (tface->flag&TF_SELECT)) {
|
||||
return 2; /* Don't set color */
|
||||
} else {
|
||||
Mesh *me = (Mesh*)userData;
|
||||
|
||||
if (me->tface) {
|
||||
TFace *tface = &me->tface[index];
|
||||
if (!(tface->flag&TF_HIDE) && (tface->flag&TF_SELECT))
|
||||
return 2; /* Don't set color */
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm)
|
||||
{
|
||||
struct { Mesh *me; EdgeHash *eh; } data;
|
||||
|
||||
data.me = me;
|
||||
data.eh = get_marked_edge_info(me);
|
||||
data.eh = get_tface_mesh_marked_edge_info(me);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
@@ -657,7 +663,7 @@ static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
BIF_ThemeColor4(TH_FACE_SELECT);
|
||||
|
||||
dm->drawFacesTex(dm, draw_tfaces3D__drawFaceOpts);
|
||||
dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOpts, (void*)me);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
@@ -838,8 +844,11 @@ static Object *g_draw_tface_mesh_ob = NULL;
|
||||
static int g_draw_tface_mesh_islight = 0;
|
||||
static int g_draw_tface_mesh_istex = 0;
|
||||
static unsigned char g_draw_tface_mesh_obcol[4];
|
||||
static int draw_tface_mesh__set_draw(TFace *tface, int matnr)
|
||||
static int draw_tface_mesh__set_draw(void *userData, int index, int matnr)
|
||||
{
|
||||
Mesh *me = (Mesh*)userData;
|
||||
TFace *tface = (me->tface)? &me->tface[index]: NULL;
|
||||
|
||||
if (tface && ((tface->flag&TF_HIDE) || (tface->mode&TF_INVISIBLE))) return 0;
|
||||
|
||||
if (set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE)) {
|
||||
@@ -901,7 +910,7 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt)
|
||||
int editing= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
|
||||
int start, totface;
|
||||
|
||||
dm->drawFacesTex(dm, draw_tface_mesh__set_draw);
|
||||
dm->drawMappedFacesTex(dm, draw_tface_mesh__set_draw, (void*)me);
|
||||
|
||||
start = 0;
|
||||
totface = me->totface;
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_edgehash.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_curve.h"
|
||||
@@ -4110,17 +4111,47 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int bbs_mesh_wire__setDrawOpts(void *userData, int index)
|
||||
{
|
||||
struct { Mesh *me; EdgeHash *eh; int offset; } *data = userData;
|
||||
MEdge *med = data->me->medge + index;
|
||||
unsigned int flags = (int)BLI_edgehash_lookup(data->eh, med->v1, med->v2);
|
||||
|
||||
if (flags & 1) {
|
||||
set_framebuffer_index_color(data->offset+index);
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bbs_mesh_solid(Object *ob)
|
||||
{
|
||||
int dmNeedsFree;
|
||||
DerivedMesh *dm = mesh_get_derived_final(ob, &dmNeedsFree);
|
||||
Mesh *me = (Mesh*)ob->data;
|
||||
|
||||
glColor3ub(0, 0, 0);
|
||||
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, ob->data, 0);
|
||||
|
||||
if (dmNeedsFree) {
|
||||
dm->release(dm);
|
||||
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0);
|
||||
|
||||
/* draw edges for seam marking in faceselect mode, but not when painting,
|
||||
so that painting doesn't get interrupted on an edge */
|
||||
if ((G.f & G_FACESELECT) && !(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))) {
|
||||
struct { Mesh *me; EdgeHash *eh; int offset; } userData;
|
||||
|
||||
userData.me = me;
|
||||
userData.eh = get_tface_mesh_marked_edge_info(me);
|
||||
userData.offset = userData.me->totface+1;
|
||||
|
||||
bglPolygonOffset(1.0);
|
||||
dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOpts, (void*)&userData);
|
||||
bglPolygonOffset(0.0);
|
||||
|
||||
BLI_edgehash_free(userData.eh, NULL);
|
||||
}
|
||||
|
||||
if (dmNeedsFree)
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
void draw_object_backbufsel(Object *ob)
|
||||
@@ -4145,7 +4176,7 @@ void draw_object_backbufsel(Object *ob)
|
||||
|
||||
// we draw edges always, for loop (select) tools
|
||||
em_wireoffs= bbs_mesh_wire(dm, em_solidoffs);
|
||||
|
||||
|
||||
if(G.scene->selectmode & SCE_SELECT_VERTEX)
|
||||
em_vertoffs= bbs_mesh_verts(dm, em_wireoffs);
|
||||
else em_vertoffs= em_wireoffs;
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "BMF_Api.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
@@ -1054,7 +1055,143 @@ void backdrawview3d(int test)
|
||||
|
||||
}
|
||||
|
||||
void check_backbuf(void)
|
||||
{
|
||||
if(G.vd->flag & V3D_NEEDBACKBUFDRAW)
|
||||
backdrawview3d(0);
|
||||
}
|
||||
|
||||
/* samples a single pixel (copied from vpaint) */
|
||||
unsigned int sample_backbuf(int x, int y)
|
||||
{
|
||||
unsigned int col;
|
||||
|
||||
if(x>=curarea->winx || y>=curarea->winy) return 0;
|
||||
x+= curarea->winrct.xmin;
|
||||
y+= curarea->winrct.ymin;
|
||||
|
||||
check_backbuf(); // actually not needed for apple
|
||||
|
||||
#ifdef __APPLE__
|
||||
glReadBuffer(GL_AUX0);
|
||||
#endif
|
||||
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
if(G.order==B_ENDIAN) SWITCH_INT(col);
|
||||
|
||||
return framebuffer_to_index(col);
|
||||
}
|
||||
|
||||
/* reads full rect, converts indices */
|
||||
ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax)
|
||||
{
|
||||
unsigned int *dr, *rd;
|
||||
struct ImBuf *ibuf, *ibuf1;
|
||||
int a;
|
||||
short xminc, yminc, xmaxc, ymaxc, xs, ys;
|
||||
|
||||
/* clip */
|
||||
if(xmin<0) xminc= 0; else xminc= xmin;
|
||||
if(xmax>=curarea->winx) xmaxc= curarea->winx-1; else xmaxc= xmax;
|
||||
if(xminc > xmaxc) return NULL;
|
||||
|
||||
if(ymin<0) yminc= 0; else yminc= ymin;
|
||||
if(ymax>=curarea->winy) ymaxc= curarea->winy-1; else ymaxc= ymax;
|
||||
if(yminc > ymaxc) return NULL;
|
||||
|
||||
ibuf= IMB_allocImBuf((xmaxc-xminc+1),(ymaxc-yminc+1),32,IB_rect,0);
|
||||
|
||||
check_backbuf(); // actually not needed for apple
|
||||
|
||||
#ifdef __APPLE__
|
||||
glReadBuffer(GL_AUX0);
|
||||
#endif
|
||||
glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
|
||||
|
||||
a= (xmaxc-xminc+1)*(ymaxc-yminc+1);
|
||||
dr= ibuf->rect;
|
||||
while(a--) {
|
||||
if(*dr) *dr= framebuffer_to_index(*dr);
|
||||
dr++;
|
||||
}
|
||||
|
||||
/* put clipped result back, if needed */
|
||||
if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return ibuf;
|
||||
ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0);
|
||||
rd= ibuf->rect;
|
||||
dr= ibuf1->rect;
|
||||
|
||||
for(ys= ymin; ys<=ymax; ys++) {
|
||||
for(xs= xmin; xs<=xmax; xs++, dr++) {
|
||||
if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) {
|
||||
*dr= *rd;
|
||||
rd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
IMB_freeImBuf(ibuf);
|
||||
return ibuf1;
|
||||
}
|
||||
|
||||
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
|
||||
unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist)
|
||||
{
|
||||
struct ImBuf *buf;
|
||||
unsigned int *bufmin, *bufmax, *tbuf;
|
||||
int minx, miny;
|
||||
int a, b, rc, nr, amount, dirvec[4][2];
|
||||
short distance=0;
|
||||
unsigned int index = 0;
|
||||
|
||||
amount= (size-1)/2;
|
||||
|
||||
minx = mval[0]-(amount+1);
|
||||
miny = mval[1]-(amount+1);
|
||||
buf = read_backbuf(minx, miny, minx+size-1, miny+size-1);
|
||||
if (!buf) return 0;
|
||||
|
||||
rc= 0;
|
||||
|
||||
dirvec[0][0]= 1; dirvec[0][1]= 0;
|
||||
dirvec[1][0]= 0; dirvec[1][1]= -size;
|
||||
dirvec[2][0]= -1; dirvec[2][1]= 0;
|
||||
dirvec[3][0]= 0; dirvec[3][1]= size;
|
||||
|
||||
bufmin = buf->rect;
|
||||
tbuf = buf->rect;
|
||||
bufmax = buf->rect + size*size;
|
||||
tbuf+= amount*size+ amount;
|
||||
|
||||
for(nr=1; nr<=size; nr++) {
|
||||
|
||||
for(a=0; a<2; a++) {
|
||||
for(b=0; b<nr; b++, distance++) {
|
||||
if (*tbuf && *tbuf>=min && *tbuf<max) {
|
||||
*dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - zr
|
||||
index = *tbuf - min+1; // messy yah, but indices start at 1
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tbuf+= (dirvec[rc][0]+dirvec[rc][1]);
|
||||
|
||||
if(tbuf<bufmin || tbuf>=bufmax) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
rc++;
|
||||
rc &= 3;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
IMB_freeImBuf(buf);
|
||||
return index;
|
||||
}
|
||||
|
||||
void drawname(Object *ob)
|
||||
{
|
||||
cpack(0x404040);
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_heap.h"
|
||||
#include "BLI_edgehash.h"
|
||||
|
||||
#include "MTC_matrixops.h"
|
||||
|
||||
@@ -91,7 +93,59 @@
|
||||
|
||||
#include "BDR_unwrapper.h"
|
||||
|
||||
TFace *lasttface=NULL;
|
||||
/* returns 0 if not found, otherwise 1 */
|
||||
static int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
|
||||
{
|
||||
if (!me->tface || me->totface==0)
|
||||
return 0;
|
||||
|
||||
if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
|
||||
check_backbuf();
|
||||
persp(PERSP_VIEW);
|
||||
}
|
||||
|
||||
if (rect) {
|
||||
/* sample rect to increase changes of selecting, so that when clicking
|
||||
on an edge in the backbuf, we can still select a face */
|
||||
short dist;
|
||||
*index = sample_backbuf_rect(mval, 3, 1, me->totface+1, &dist);
|
||||
}
|
||||
else
|
||||
/* sample only on the exact position */
|
||||
*index = sample_backbuf(mval[0], mval[1]);
|
||||
|
||||
if ((*index)<=0 || (*index)>(unsigned int)me->totface)
|
||||
return 0;
|
||||
|
||||
(*index)--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns 0 if not found, otherwise 1 */
|
||||
static int facesel_edge_pick(Mesh *me, short *mval, unsigned int *index)
|
||||
{
|
||||
short dist;
|
||||
unsigned int min = me->totface + 1;
|
||||
unsigned int max = me->totface + me->totedge + 1;
|
||||
|
||||
if (me->totedge == 0)
|
||||
return 0;
|
||||
|
||||
if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
|
||||
check_backbuf();
|
||||
persp(PERSP_VIEW);
|
||||
}
|
||||
|
||||
*index = sample_backbuf_rect(mval, 50, min, max, &dist);
|
||||
|
||||
if (*index == 0)
|
||||
return 0;
|
||||
|
||||
(*index)--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void uv_calc_center_vector(float *result, Object *ob, Mesh *me)
|
||||
{
|
||||
@@ -487,47 +541,32 @@ void calculate_uv_map(unsigned short mapmode)
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
|
||||
void set_lasttface()
|
||||
TFace *get_active_tface()
|
||||
{
|
||||
Mesh *me;
|
||||
TFace *tface;
|
||||
TFace *tf;
|
||||
int a;
|
||||
|
||||
lasttface= 0;
|
||||
if(OBACT==NULL || OBACT->type!=OB_MESH) return;
|
||||
if(OBACT==NULL || OBACT->type!=OB_MESH)
|
||||
return NULL;
|
||||
|
||||
me= get_mesh(OBACT);
|
||||
if(me==0 || me->tface==0) return;
|
||||
if(me==0 || me->tface==0)
|
||||
return NULL;
|
||||
|
||||
tface= me->tface;
|
||||
a= me->totface;
|
||||
while(a--) {
|
||||
if(tface->flag & TF_ACTIVE) {
|
||||
lasttface= tface;
|
||||
return;
|
||||
}
|
||||
tface++;
|
||||
}
|
||||
for(a=0, tf=me->tface; a < me->totface; a++, tf++)
|
||||
if(tf->flag & TF_ACTIVE)
|
||||
return tf;
|
||||
|
||||
tface= me->tface;
|
||||
a= me->totface;
|
||||
while(a--) {
|
||||
if(tface->flag & TF_SELECT) {
|
||||
lasttface= tface;
|
||||
return;
|
||||
}
|
||||
tface++;
|
||||
}
|
||||
for(a=0, tf=me->tface; a < me->totface; a++, tf++)
|
||||
if(tf->flag & TF_SELECT)
|
||||
return tf;
|
||||
|
||||
tface= me->tface;
|
||||
a= me->totface;
|
||||
while(a--) {
|
||||
if((tface->flag & TF_HIDE)==0) {
|
||||
lasttface= tface;
|
||||
return;
|
||||
}
|
||||
tface++;
|
||||
}
|
||||
for(a=0, tf=me->tface; a < me->totface; a++, tf++)
|
||||
if((tf->flag & TF_HIDE)==0)
|
||||
return tf;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void default_uv(float uv[][2], float size)
|
||||
@@ -660,7 +699,7 @@ void select_linked_tfaces(int mode)
|
||||
error("The active object is not in this layer");
|
||||
|
||||
getmouseco_areawin(mval);
|
||||
if (!face_pick(me, mval[0], mval[1], &index)) return;
|
||||
if (!facesel_face_pick(me, mval, &index, 1)) return;
|
||||
}
|
||||
|
||||
select_linked_tfaces_with_seams(mode, me, index);
|
||||
@@ -910,55 +949,275 @@ void minmax_tface(float *min, float *max)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the face under the give position in screen coordinates.
|
||||
* Code extracted from face_select routine.
|
||||
* Question: why is all of the backbuffer drawn?
|
||||
* We're only interested in one pixel!
|
||||
* @author Maarten Gribnau
|
||||
* @param me the mesh with the faces to be picked
|
||||
* @param x the x-coordinate to pick at
|
||||
* @param y the y-coordinate to pick at
|
||||
* @param index the index of the face
|
||||
* @return 1 if found, 0 if none found
|
||||
*/
|
||||
int face_pick(Mesh *me, short x, short y, unsigned int *index)
|
||||
#define ME_SEAM_DONE ME_SEAM_LAST /* reuse this flag */
|
||||
|
||||
static float seam_cut_cost(Mesh *me, int e1, int e2, int vert)
|
||||
{
|
||||
unsigned int col;
|
||||
MVert *v = me->mvert + vert;
|
||||
MEdge *med1 = me->medge + e1, *med2 = me->medge + e2;
|
||||
MVert *v1 = me->mvert + ((med1->v1 == vert)? med1->v2: med1->v1);
|
||||
MVert *v2 = me->mvert + ((med2->v1 == vert)? med2->v2: med2->v1);
|
||||
float cost, d1[3], d2[3];
|
||||
|
||||
if (me==0 || me->tface==0)
|
||||
return 0;
|
||||
cost = VecLenf(v1->co, v->co);
|
||||
cost += VecLenf(v->co, v2->co);
|
||||
|
||||
/* Have OpenGL draw in the back buffer with color coded face indices */
|
||||
if (curarea->win_swap==WIN_EQUAL) {
|
||||
G.vd->flag |= V3D_NEEDBACKBUFDRAW;
|
||||
VecSubf(d1, v->co, v1->co);
|
||||
VecSubf(d2, v2->co, v->co);
|
||||
|
||||
cost = cost + 0.5f*cost*(2.0f - fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
static void seam_add_adjacent(Mesh *me, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost)
|
||||
{
|
||||
int startadj, endadj = nedges[vertnum+1];
|
||||
|
||||
for (startadj = nedges[vertnum]; startadj < endadj; startadj++) {
|
||||
int adjnum = edges[startadj];
|
||||
MEdge *medadj = me->medge + adjnum;
|
||||
float newcost;
|
||||
|
||||
if (medadj->flag & ME_SEAM_DONE)
|
||||
continue;
|
||||
|
||||
newcost = cost[mednum] + seam_cut_cost(me, mednum, adjnum, vertnum);
|
||||
|
||||
if (cost[adjnum] > newcost) {
|
||||
cost[adjnum] = newcost;
|
||||
prevedge[adjnum] = mednum;
|
||||
BLI_heap_insert(heap, newcost, (void*)adjnum);
|
||||
}
|
||||
}
|
||||
if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
|
||||
backdrawview3d(0);
|
||||
persp(PERSP_VIEW);
|
||||
}
|
||||
/* Read the pixel under the cursor */
|
||||
#ifdef __APPLE__
|
||||
glReadBuffer(GL_AUX0);
|
||||
#endif
|
||||
glReadPixels(x+curarea->winrct.xmin, y+curarea->winrct.ymin, 1, 1,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, &col);
|
||||
glReadBuffer(GL_BACK);
|
||||
}
|
||||
|
||||
/* Unbelievable! */
|
||||
if (G.order==B_ENDIAN) {
|
||||
SWITCH_INT(col);
|
||||
}
|
||||
/* Convert the color back to a face index */
|
||||
*index = framebuffer_to_index(col);
|
||||
if (col==0 || (*index)<=0 || (*index)>(unsigned) me->totface)
|
||||
return 0;
|
||||
static int seam_shortest_path(Mesh *me, int source, int target)
|
||||
{
|
||||
Heap *heap;
|
||||
EdgeHash *ehash;
|
||||
float *cost;
|
||||
MEdge *med;
|
||||
int a, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0;
|
||||
TFace *tf;
|
||||
MFace *mf;
|
||||
|
||||
(*index)--;
|
||||
/* mark hidden edges as done, so we don't use them */
|
||||
ehash = BLI_edgehash_new();
|
||||
|
||||
for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++) {
|
||||
if (!(tf->flag & TF_HIDE)) {
|
||||
BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
|
||||
BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
|
||||
if (mf->v4) {
|
||||
BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
|
||||
BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
|
||||
}
|
||||
else
|
||||
BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
for (a=0, med=me->medge; a<me->totedge; a++, med++)
|
||||
if (!BLI_edgehash_haskey(ehash, med->v1, med->v2))
|
||||
med->flag |= ME_SEAM_DONE;
|
||||
|
||||
BLI_edgehash_free(ehash, NULL);
|
||||
|
||||
/* alloc */
|
||||
nedges = MEM_callocN(sizeof(*nedges)*me->totvert+1, "SeamPathNEdges");
|
||||
edges = MEM_mallocN(sizeof(*edges)*me->totedge*2, "SeamPathEdges");
|
||||
prevedge = MEM_mallocN(sizeof(*prevedge)*me->totedge, "SeamPathPrevious");
|
||||
cost = MEM_mallocN(sizeof(*cost)*me->totedge, "SeamPathCost");
|
||||
|
||||
/* count edges, compute adjacent edges offsets and fill adjacent edges */
|
||||
for (a=0, med=me->medge; a<me->totedge; a++, med++) {
|
||||
nedges[med->v1+1]++;
|
||||
nedges[med->v2+1]++;
|
||||
}
|
||||
|
||||
for (a=1; a<me->totvert; a++) {
|
||||
int newswap = nedges[a+1];
|
||||
nedges[a+1] = nedgeswap + nedges[a];
|
||||
nedgeswap = newswap;
|
||||
}
|
||||
nedges[0] = nedges[1] = 0;
|
||||
|
||||
for (a=0, med=me->medge; a<me->totedge; a++, med++) {
|
||||
edges[nedges[med->v1+1]++] = a;
|
||||
edges[nedges[med->v2+1]++] = a;
|
||||
|
||||
cost[a] = 1e20f;
|
||||
prevedge[a] = -1;
|
||||
}
|
||||
|
||||
/* regular dijkstra shortest path, but over edges instead of vertices */
|
||||
heap = BLI_heap_new();
|
||||
BLI_heap_insert(heap, 0.0f, (void*)source);
|
||||
cost[source] = 0.0f;
|
||||
|
||||
while (!BLI_heap_empty(heap)) {
|
||||
mednum = (int)BLI_heap_popmin(heap);
|
||||
med = me->medge + mednum;
|
||||
|
||||
if (mednum == target)
|
||||
break;
|
||||
|
||||
if (med->flag & ME_SEAM_DONE)
|
||||
continue;
|
||||
|
||||
med->flag |= ME_SEAM_DONE;
|
||||
|
||||
seam_add_adjacent(me, heap, mednum, med->v1, nedges, edges, prevedge, cost);
|
||||
seam_add_adjacent(me, heap, mednum, med->v2, nedges, edges, prevedge, cost);
|
||||
}
|
||||
|
||||
MEM_freeN(nedges);
|
||||
MEM_freeN(edges);
|
||||
MEM_freeN(cost);
|
||||
BLI_heap_free(heap, NULL);
|
||||
|
||||
for (a=0, med=me->medge; a<me->totedge; a++, med++)
|
||||
med->flag &= ~ME_SEAM_DONE;
|
||||
|
||||
if (mednum != target) {
|
||||
MEM_freeN(prevedge);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* follow path back to source and mark as seam */
|
||||
if (mednum == target) {
|
||||
short allseams = 1;
|
||||
|
||||
mednum = target;
|
||||
do {
|
||||
med = me->medge + mednum;
|
||||
if (!(med->flag & ME_SEAM)) {
|
||||
allseams = 0;
|
||||
break;
|
||||
}
|
||||
mednum = prevedge[mednum];
|
||||
} while (mednum != source);
|
||||
|
||||
mednum = target;
|
||||
do {
|
||||
med = me->medge + mednum;
|
||||
if (allseams)
|
||||
med->flag &= ~ME_SEAM;
|
||||
else
|
||||
med->flag |= ME_SEAM;
|
||||
mednum = prevedge[mednum];
|
||||
} while (mednum != -1);
|
||||
}
|
||||
|
||||
MEM_freeN(prevedge);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void seam_select(Mesh *me, short *mval, short path)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
MEdge *medge, *med;
|
||||
int a, lastindex = -1;
|
||||
|
||||
if (!facesel_edge_pick(me, mval, &index))
|
||||
return;
|
||||
|
||||
for (a=0, med=me->medge; a<me->totedge; a++, med++) {
|
||||
if (med->flag & ME_SEAM_LAST) {
|
||||
lastindex = a;
|
||||
med->flag &= ~ME_SEAM_LAST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
medge = me->medge + index;
|
||||
if (!path || (lastindex == -1) || (index == lastindex) ||
|
||||
!seam_shortest_path(me, lastindex, index))
|
||||
medge->flag ^= ME_SEAM;
|
||||
medge->flag |= ME_SEAM_LAST;
|
||||
|
||||
G.f |= G_DRAWSEAMS;
|
||||
|
||||
if (G.rt == 8)
|
||||
unwrap_lscm(1);
|
||||
|
||||
BIF_undo_push("Mark Seam");
|
||||
|
||||
object_tface_flags_changed(OBACT, 1);
|
||||
}
|
||||
|
||||
void seam_edgehash_insert_face(EdgeHash *ehash, MFace *mf)
|
||||
{
|
||||
BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
|
||||
BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
|
||||
if (mf->v4) {
|
||||
BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
|
||||
BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
|
||||
}
|
||||
else
|
||||
BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
|
||||
}
|
||||
|
||||
void seam_mark_clear_tface(short mode)
|
||||
{
|
||||
Mesh *me;
|
||||
TFace *tf;
|
||||
MFace *mf;
|
||||
MEdge *med;
|
||||
int a;
|
||||
|
||||
me= get_mesh(OBACT);
|
||||
if(me==0 || me->tface==0 || me->totface==0) return;
|
||||
|
||||
if (mode == 0)
|
||||
mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2");
|
||||
|
||||
if (mode != 1 && mode != 2)
|
||||
return;
|
||||
|
||||
if (mode == 2) {
|
||||
EdgeHash *ehash = BLI_edgehash_new();
|
||||
|
||||
for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++)
|
||||
if (!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT))
|
||||
seam_edgehash_insert_face(ehash, mf);
|
||||
|
||||
for (a=0, med=me->medge; a<me->totedge; a++, med++)
|
||||
if (BLI_edgehash_haskey(ehash, med->v1, med->v2))
|
||||
med->flag &= ~ME_SEAM;
|
||||
|
||||
BLI_edgehash_free(ehash, NULL);
|
||||
}
|
||||
else {
|
||||
/* mark edges that are on both selected and deselected faces */
|
||||
EdgeHash *ehash1 = BLI_edgehash_new();
|
||||
EdgeHash *ehash2 = BLI_edgehash_new();
|
||||
|
||||
for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++) {
|
||||
if ((tf->flag & TF_HIDE) || !(tf->flag & TF_SELECT))
|
||||
seam_edgehash_insert_face(ehash1, mf);
|
||||
else
|
||||
seam_edgehash_insert_face(ehash2, mf);
|
||||
}
|
||||
|
||||
for (a=0, med=me->medge; a<me->totedge; a++, med++)
|
||||
if (BLI_edgehash_haskey(ehash1, med->v1, med->v2) &&
|
||||
BLI_edgehash_haskey(ehash2, med->v1, med->v2))
|
||||
med->flag |= ME_SEAM;
|
||||
|
||||
BLI_edgehash_free(ehash1, NULL);
|
||||
BLI_edgehash_free(ehash2, NULL);
|
||||
}
|
||||
|
||||
if (G.rt == 8)
|
||||
unwrap_lscm(1);
|
||||
|
||||
BIF_undo_push("Mark Seam");
|
||||
|
||||
object_tface_flags_changed(OBACT, 1);
|
||||
}
|
||||
|
||||
void face_select()
|
||||
{
|
||||
Object *ob;
|
||||
@@ -975,7 +1234,13 @@ void face_select()
|
||||
}
|
||||
me = get_mesh(ob);
|
||||
getmouseco_areawin(mval);
|
||||
if (!face_pick(me, mval[0], mval[1], &index)) return;
|
||||
|
||||
if (G.qual & LR_ALTKEY) {
|
||||
seam_select(me, mval, (G.qual & LR_SHIFTKEY) != 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!facesel_face_pick(me, mval, &index, 1)) return;
|
||||
|
||||
tsel= (((TFace*)me->tface)+index);
|
||||
msel= (((MFace*)me->mface)+index);
|
||||
@@ -1003,8 +1268,6 @@ void face_select()
|
||||
}
|
||||
else tsel->flag |= TF_SELECT;
|
||||
|
||||
lasttface = tsel;
|
||||
|
||||
/* image window redraw */
|
||||
|
||||
BIF_undo_push("Select UV face");
|
||||
@@ -1149,7 +1412,7 @@ void uv_autocalc_tface()
|
||||
case UV_WINDOW_MAPPING:
|
||||
calculate_uv_map(B_UVAUTO_WINDOW); break;
|
||||
case UV_UNWRAP_MAPPING:
|
||||
unwrap_lscm(); break;
|
||||
unwrap_lscm(0); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1176,10 +1439,6 @@ void set_faceselect() /* toggle */
|
||||
|
||||
if(G.f & G_FACESELECT) {
|
||||
setcursor_space(SPACE_VIEW3D, CURSOR_FACESEL);
|
||||
if(me) {
|
||||
set_lasttface();
|
||||
set_seamtface(); /* set TF_SEAM flags in tface */
|
||||
}
|
||||
BIF_undo_push("Set UV Faceselect");
|
||||
}
|
||||
else if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) {
|
||||
@@ -1497,7 +1756,7 @@ void face_draw()
|
||||
if ((xy[0] != xy_old[0]) || (xy[1] != xy_old[1])) {
|
||||
|
||||
/* Get face to draw on */
|
||||
if (!face_pick(me, xy[0], xy[1], &face_index)) face = NULL;
|
||||
if (!facesel_face_pick(me, xy, &face_index, 0)) face = NULL;
|
||||
else face = (((TFace*)me->tface)+face_index);
|
||||
|
||||
/* Check if this is another face. */
|
||||
|
||||
@@ -123,145 +123,6 @@ void EM_select_mirrored(void)
|
||||
|
||||
unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0; // set in drawobject.c ... for colorindices
|
||||
|
||||
static void check_backbuf(void)
|
||||
{
|
||||
if(G.vd->flag & V3D_NEEDBACKBUFDRAW) {
|
||||
backdrawview3d(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* samples a single pixel (copied from vpaint) */
|
||||
static unsigned int sample_backbuf(int x, int y)
|
||||
{
|
||||
unsigned int col;
|
||||
|
||||
if(x>=curarea->winx || y>=curarea->winy) return 0;
|
||||
x+= curarea->winrct.xmin;
|
||||
y+= curarea->winrct.ymin;
|
||||
|
||||
check_backbuf(); // actually not needed for apple
|
||||
|
||||
#ifdef __APPLE__
|
||||
glReadBuffer(GL_AUX0);
|
||||
#endif
|
||||
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
if(G.order==B_ENDIAN) SWITCH_INT(col);
|
||||
|
||||
return framebuffer_to_index(col);
|
||||
}
|
||||
|
||||
/* reads full rect, converts indices */
|
||||
struct ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax)
|
||||
{
|
||||
unsigned int *dr, *rd;
|
||||
struct ImBuf *ibuf, *ibuf1;
|
||||
int a;
|
||||
short xminc, yminc, xmaxc, ymaxc, xs, ys;
|
||||
|
||||
/* clip */
|
||||
if(xmin<0) xminc= 0; else xminc= xmin;
|
||||
if(xmax>=curarea->winx) xmaxc= curarea->winx-1; else xmaxc= xmax;
|
||||
if(xminc > xmaxc) return NULL;
|
||||
|
||||
if(ymin<0) yminc= 0; else yminc= ymin;
|
||||
if(ymax>=curarea->winy) ymaxc= curarea->winy-1; else ymaxc= ymax;
|
||||
if(yminc > ymaxc) return NULL;
|
||||
|
||||
ibuf= IMB_allocImBuf((xmaxc-xminc+1),(ymaxc-yminc+1),32,IB_rect,0);
|
||||
|
||||
check_backbuf(); // actually not needed for apple
|
||||
|
||||
#ifdef __APPLE__
|
||||
glReadBuffer(GL_AUX0);
|
||||
#endif
|
||||
glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
|
||||
|
||||
a= (xmaxc-xminc+1)*(ymaxc-yminc+1);
|
||||
dr= ibuf->rect;
|
||||
while(a--) {
|
||||
if(*dr) *dr= framebuffer_to_index(*dr);
|
||||
dr++;
|
||||
}
|
||||
|
||||
/* put clipped result back, if needed */
|
||||
if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return ibuf;
|
||||
ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0);
|
||||
rd= ibuf->rect;
|
||||
dr= ibuf1->rect;
|
||||
|
||||
for(ys= ymin; ys<=ymax; ys++) {
|
||||
for(xs= xmin; xs<=xmax; xs++, dr++) {
|
||||
if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) {
|
||||
*dr= *rd;
|
||||
rd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
IMB_freeImBuf(ibuf);
|
||||
return ibuf1;
|
||||
}
|
||||
|
||||
|
||||
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
|
||||
static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist)
|
||||
{
|
||||
struct ImBuf *buf;
|
||||
unsigned int *bufmin, *bufmax, *tbuf;
|
||||
int minx, miny;
|
||||
int a, b, rc, nr, amount, dirvec[4][2];
|
||||
short distance=0;
|
||||
unsigned int index = 0;
|
||||
|
||||
amount= (size-1)/2;
|
||||
|
||||
minx = mval[0]-(amount+1);
|
||||
miny = mval[1]-(amount+1);
|
||||
buf = read_backbuf(minx, miny, minx+size-1, miny+size-1);
|
||||
if (!buf) return 0;
|
||||
|
||||
rc= 0;
|
||||
|
||||
dirvec[0][0]= 1; dirvec[0][1]= 0;
|
||||
dirvec[1][0]= 0; dirvec[1][1]= -size;
|
||||
dirvec[2][0]= -1; dirvec[2][1]= 0;
|
||||
dirvec[3][0]= 0; dirvec[3][1]= size;
|
||||
|
||||
bufmin = buf->rect;
|
||||
tbuf = buf->rect;
|
||||
bufmax = buf->rect + size*size;
|
||||
tbuf+= amount*size+ amount;
|
||||
|
||||
for(nr=1; nr<=size; nr++) {
|
||||
|
||||
for(a=0; a<2; a++) {
|
||||
for(b=0; b<nr; b++, distance++) {
|
||||
if (*tbuf && *tbuf>=min && *tbuf<max) {
|
||||
*dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - zr
|
||||
index = *tbuf - min+1; // messy yah, but indices start at 1
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tbuf+= (dirvec[rc][0]+dirvec[rc][1]);
|
||||
|
||||
if(tbuf<bufmin || tbuf>=bufmax) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
rc++;
|
||||
rc &= 3;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
IMB_freeImBuf(buf);
|
||||
return index;
|
||||
}
|
||||
|
||||
/* facilities for border select and circle select */
|
||||
static char *selbuf= NULL;
|
||||
|
||||
|
||||
@@ -1504,10 +1504,8 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un
|
||||
|
||||
if(freedata) free_editMesh(G.editMesh);
|
||||
|
||||
if(G.f & G_FACESELECT) {
|
||||
set_seamtface();
|
||||
if(G.f & G_FACESELECT)
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
if(G.f & G_WEIGHTPAINT)
|
||||
mesh_octree_table(G.obedit, NULL, 'e');
|
||||
}
|
||||
|
||||
@@ -1029,7 +1029,7 @@ static void do_image_uvsmenu(void *arg, int event)
|
||||
pin_tface_uv(0);
|
||||
break;
|
||||
case 10:
|
||||
unwrap_lscm();
|
||||
unwrap_lscm(0);
|
||||
break;
|
||||
case 11:
|
||||
if(G.sima->flag & SI_LIVE_UNWRAP) G.sima->flag &= ~SI_LIVE_UNWRAP;
|
||||
@@ -1072,7 +1072,7 @@ static uiBlock *image_uvsmenu(void *arg_unused)
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Minimize Stretch|Ctrl V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Minimize Stretch|Ctrl V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Limit Stitch...|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Stitch|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
|
||||
uiDefIconTextBlockBut(block, image_uvs_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
|
||||
|
||||
@@ -3574,55 +3574,56 @@ static uiBlock *view3d_paintmenu(void *arg_unused)
|
||||
|
||||
static void do_view3d_facesel_propertiesmenu(void *arg, int event)
|
||||
{
|
||||
extern TFace *lasttface;
|
||||
set_lasttface();
|
||||
|
||||
switch(event) {
|
||||
case 0: /* textured */
|
||||
lasttface->mode ^= TF_TEX;
|
||||
break;
|
||||
case 1: /* tiled*/
|
||||
lasttface->mode ^= TF_TILES;
|
||||
break;
|
||||
case 2: /* light */
|
||||
lasttface->mode ^= TF_LIGHT;
|
||||
break;
|
||||
case 3: /* invisible */
|
||||
lasttface->mode ^= TF_INVISIBLE;
|
||||
break;
|
||||
case 4: /* collision */
|
||||
lasttface->mode ^= TF_DYNAMIC;
|
||||
break;
|
||||
case 5: /* shared vertex colors */
|
||||
lasttface->mode ^= TF_SHAREDCOL;
|
||||
break;
|
||||
case 6: /* two sided */
|
||||
lasttface->mode ^= TF_TWOSIDE;
|
||||
break;
|
||||
case 7: /* use object color */
|
||||
lasttface->mode ^= TF_OBCOL;
|
||||
break;
|
||||
case 8: /* halo */
|
||||
lasttface->mode ^= TF_BILLBOARD;
|
||||
break;
|
||||
case 9: /* billboard */
|
||||
lasttface->mode ^= TF_BILLBOARD2;
|
||||
break;
|
||||
case 10: /* shadow */
|
||||
lasttface->mode ^= TF_SHADOW;
|
||||
break;
|
||||
case 11: /* text */
|
||||
lasttface->mode ^= TF_BMFONT;
|
||||
break;
|
||||
case 12: /* opaque blend mode */
|
||||
lasttface->transp = TF_SOLID;
|
||||
break;
|
||||
case 13: /* additive blend mode */
|
||||
lasttface->transp |= TF_ADD;
|
||||
break;
|
||||
case 14: /* alpha blend mode */
|
||||
lasttface->transp = TF_ALPHA;
|
||||
break;
|
||||
TFace *tf = get_active_tface();
|
||||
|
||||
if (tf) {
|
||||
switch(event) {
|
||||
case 0: /* textured */
|
||||
tf->mode ^= TF_TEX;
|
||||
break;
|
||||
case 1: /* tiled*/
|
||||
tf->mode ^= TF_TILES;
|
||||
break;
|
||||
case 2: /* light */
|
||||
tf->mode ^= TF_LIGHT;
|
||||
break;
|
||||
case 3: /* invisible */
|
||||
tf->mode ^= TF_INVISIBLE;
|
||||
break;
|
||||
case 4: /* collision */
|
||||
tf->mode ^= TF_DYNAMIC;
|
||||
break;
|
||||
case 5: /* shared vertex colors */
|
||||
tf->mode ^= TF_SHAREDCOL;
|
||||
break;
|
||||
case 6: /* two sided */
|
||||
tf->mode ^= TF_TWOSIDE;
|
||||
break;
|
||||
case 7: /* use object color */
|
||||
tf->mode ^= TF_OBCOL;
|
||||
break;
|
||||
case 8: /* halo */
|
||||
tf->mode ^= TF_BILLBOARD;
|
||||
break;
|
||||
case 9: /* billboard */
|
||||
tf->mode ^= TF_BILLBOARD2;
|
||||
break;
|
||||
case 10: /* shadow */
|
||||
tf->mode ^= TF_SHADOW;
|
||||
break;
|
||||
case 11: /* text */
|
||||
tf->mode ^= TF_BMFONT;
|
||||
break;
|
||||
case 12: /* opaque blend mode */
|
||||
tf->transp = TF_SOLID;
|
||||
break;
|
||||
case 13: /* additive blend mode */
|
||||
tf->transp |= TF_ADD;
|
||||
break;
|
||||
case 14: /* alpha blend mode */
|
||||
tf->transp = TF_ALPHA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
@@ -3630,61 +3631,60 @@ static void do_view3d_facesel_propertiesmenu(void *arg, int event)
|
||||
|
||||
static uiBlock *view3d_facesel_propertiesmenu(void *arg_unused)
|
||||
{
|
||||
extern TFace *lasttface;
|
||||
TFace *tf = get_active_tface();
|
||||
uiBlock *block;
|
||||
short yco = 20, menuwidth = 120;
|
||||
|
||||
/* to display ticks/crosses depending on face properties */
|
||||
set_lasttface();
|
||||
/* display ticks/crosses depending on active tface properties */
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "view3d_facesel_propertiesmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
|
||||
uiBlockSetButmFunc(block, do_view3d_facesel_propertiesmenu, NULL);
|
||||
|
||||
if (lasttface->mode & TF_TEX) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Textured", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
|
||||
if (tf->mode & TF_TEX) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Textured", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Textured", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
if (lasttface->mode & TF_TILES) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Tiled", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
|
||||
if (tf->mode & TF_TILES) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Tiled", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Tiled", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
|
||||
|
||||
if (lasttface->mode & TF_LIGHT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Light", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
|
||||
if (tf->mode & TF_LIGHT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Light", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Light", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
|
||||
|
||||
if (lasttface->mode & TF_INVISIBLE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Invisible", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
|
||||
if (tf->mode & TF_INVISIBLE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Invisible", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Invisible", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
|
||||
|
||||
if (lasttface->mode & TF_DYNAMIC) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Collision", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
|
||||
if (tf->mode & TF_DYNAMIC) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Collision", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Collision", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
|
||||
|
||||
if (lasttface->mode & TF_SHAREDCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shared Vertex Colors", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
|
||||
if (tf->mode & TF_SHAREDCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shared Vertex Colors", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Shared Vertex Colors", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
|
||||
|
||||
if (lasttface->mode & TF_TWOSIDE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Two Sided", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
|
||||
if (tf->mode & TF_TWOSIDE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Two Sided", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Two Sided", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
|
||||
|
||||
if (lasttface->mode & TF_OBCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Use Object Color", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
|
||||
if (tf->mode & TF_OBCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Use Object Color", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Use Object Color", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
|
||||
|
||||
if (lasttface->mode & TF_BILLBOARD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Halo", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
|
||||
if (tf->mode & TF_BILLBOARD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Halo", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Halo", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
|
||||
|
||||
if (lasttface->mode & TF_BILLBOARD2) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Billboard", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
|
||||
if (tf->mode & TF_BILLBOARD2) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Billboard", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Billboard", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
|
||||
|
||||
if (lasttface->mode & TF_SHADOW) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shadow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
|
||||
if (tf->mode & TF_SHADOW) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shadow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Shadow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
|
||||
|
||||
if (lasttface->mode & TF_BMFONT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Text", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
|
||||
if (tf->mode & TF_BMFONT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Text", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Text", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
if (lasttface->transp == TF_SOLID) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Opaque Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
|
||||
if (tf->transp == TF_SOLID) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Opaque Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Opaque Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
|
||||
|
||||
if (lasttface->transp == TF_ADD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Additive Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
|
||||
if (tf->transp == TF_ADD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Additive Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Additive Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
|
||||
|
||||
if (lasttface->transp == TF_ALPHA) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Alpha Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
|
||||
if (tf->transp == TF_ALPHA) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Alpha Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
|
||||
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Alpha Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
@@ -3731,44 +3731,36 @@ static void do_view3d_faceselmenu(void *arg, int event)
|
||||
{
|
||||
/* code copied from buttons.c :(
|
||||
would be nice if it was split up into functions */
|
||||
Mesh *me=NULL;
|
||||
Object *ob=NULL;
|
||||
extern TFace *lasttface; /* caches info on tface bookkeeping ?*/
|
||||
TFace *tface;
|
||||
Mesh *me;
|
||||
TFace *tf, *activetf;
|
||||
int a;
|
||||
|
||||
switch(event) {
|
||||
case 0: /* copy draw mode */
|
||||
case 1: /* copy UVs */
|
||||
case 2: /* copy vertex colors */
|
||||
ob= OBACT;
|
||||
if(ob==0) return;
|
||||
me= get_mesh(ob);
|
||||
if(!(me && me->tface)) return;
|
||||
me= get_mesh(OBACT);
|
||||
activetf = get_active_tface();
|
||||
|
||||
tface= me->tface;
|
||||
a= me->totface;
|
||||
set_lasttface();
|
||||
if(lasttface) {
|
||||
|
||||
while(a--) {
|
||||
if(tface!=lasttface && (tface->flag & TF_SELECT)) {
|
||||
if (me && activetf) {
|
||||
for (a=0, tf=me->tface; a < me->totface; a++, tf++) {
|
||||
if(tf!=activetf && (tf->flag & TF_SELECT)) {
|
||||
if(event==0) {
|
||||
tface->mode= lasttface->mode;
|
||||
tface->transp= lasttface->transp;
|
||||
tf->mode= activetf->mode;
|
||||
tf->transp= activetf->transp;
|
||||
} else if(event==1) {
|
||||
memcpy(tface->uv, lasttface->uv, sizeof(tface->uv));
|
||||
tface->tpage= lasttface->tpage;
|
||||
tface->tile= lasttface->tile;
|
||||
memcpy(tf->uv, activetf->uv, sizeof(tf->uv));
|
||||
tf->tpage= activetf->tpage;
|
||||
tf->tile= activetf->tile;
|
||||
|
||||
if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES;
|
||||
else tface->mode &= ~TF_TILES;
|
||||
if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
|
||||
else tf->mode &= ~TF_TILES;
|
||||
|
||||
} else if(event==2)
|
||||
memcpy(tface->col, lasttface->col, sizeof(tface->col));
|
||||
memcpy(tf->col, activetf->col, sizeof(tf->col));
|
||||
}
|
||||
tface++;
|
||||
}
|
||||
|
||||
do_shared_vertexcol(me);
|
||||
}
|
||||
break;
|
||||
@@ -3784,7 +3776,12 @@ static void do_view3d_faceselmenu(void *arg, int event)
|
||||
case 9: /* mirror UVs */
|
||||
mirror_uv_tface();
|
||||
break;
|
||||
|
||||
case 10: /* mark border seam */
|
||||
seam_mark_clear_tface(1);
|
||||
break;
|
||||
case 11: /* clear seam */
|
||||
seam_mark_clear_tface(2);
|
||||
break;
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
@@ -3795,8 +3792,6 @@ static uiBlock *view3d_faceselmenu(void *arg_unused)
|
||||
uiBlock *block;
|
||||
short yco= 0, menuwidth=120;
|
||||
|
||||
set_lasttface();
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "view3d_faceselmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
|
||||
uiBlockSetButmFunc(block, do_view3d_faceselmenu, NULL);
|
||||
|
||||
@@ -3817,6 +3812,11 @@ static uiBlock *view3d_faceselmenu(void *arg_unused)
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Seam|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mark Border Seam|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBlockBut(block, view3d_facesel_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Faces", 0, yco-=20, 120, 19, "");
|
||||
|
||||
if(curarea->headertype==HEADERTOP) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_heap.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
@@ -129,148 +130,6 @@ static PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link)
|
||||
return link;
|
||||
}
|
||||
|
||||
/* Heap */
|
||||
|
||||
#define PHEAP_PARENT(i) ((i-1)>>1)
|
||||
#define PHEAP_LEFT(i) ((i<<1)+1)
|
||||
#define PHEAP_RIGHT(i) ((i<<1)+2)
|
||||
#define PHEAP_COMPARE(a, b) (a->value < b->value)
|
||||
#define PHEAP_EQUALS(a, b) (a->value == b->value)
|
||||
#define PHEAP_SWAP(heap, i, j) \
|
||||
{ SWAP(int, heap->tree[i]->index, heap->tree[j]->index); \
|
||||
SWAP(PHeapLink*, heap->tree[i], heap->tree[j]); }
|
||||
|
||||
static void pheap_down(PHeap *heap, int i)
|
||||
{
|
||||
while (P_TRUE) {
|
||||
int size = heap->size, smallest;
|
||||
int l = PHEAP_LEFT(i);
|
||||
int r = PHEAP_RIGHT(i);
|
||||
|
||||
smallest = ((l < size) && PHEAP_COMPARE(heap->tree[l], heap->tree[i]))? l: i;
|
||||
|
||||
if ((r < size) && PHEAP_COMPARE(heap->tree[r], heap->tree[smallest]))
|
||||
smallest = r;
|
||||
|
||||
if (smallest == i)
|
||||
break;
|
||||
|
||||
PHEAP_SWAP(heap, i, smallest);
|
||||
i = smallest;
|
||||
}
|
||||
}
|
||||
|
||||
static void pheap_up(PHeap *heap, int i)
|
||||
{
|
||||
while (i > 0) {
|
||||
int p = PHEAP_PARENT(i);
|
||||
|
||||
if (PHEAP_COMPARE(heap->tree[p], heap->tree[i]))
|
||||
break;
|
||||
|
||||
PHEAP_SWAP(heap, p, i);
|
||||
i = p;
|
||||
}
|
||||
}
|
||||
|
||||
static PHeap *pheap_new()
|
||||
{
|
||||
PHeap *heap = (PHeap*)MEM_callocN(sizeof(PHeap), "PHeap");
|
||||
heap->bufsize = 1;
|
||||
heap->tree = (PHeapLink**)MEM_mallocN(sizeof(PHeapLink*), "PHeapTree");
|
||||
heap->arena = BLI_memarena_new(1<<16);
|
||||
|
||||
return heap;
|
||||
}
|
||||
|
||||
static void pheap_delete(PHeap *heap)
|
||||
{
|
||||
MEM_freeN(heap->tree);
|
||||
BLI_memarena_free(heap->arena);
|
||||
MEM_freeN(heap);
|
||||
}
|
||||
|
||||
static PHeapLink *pheap_insert(PHeap *heap, float value, void *ptr)
|
||||
{
|
||||
PHeapLink *link;
|
||||
|
||||
if ((heap->size + 1) > heap->bufsize) {
|
||||
int newsize = heap->bufsize*2;
|
||||
|
||||
PHeapLink **ntree = (PHeapLink**)MEM_mallocN(newsize*sizeof(PHeapLink*), "PHeapTree");
|
||||
memcpy(ntree, heap->tree, sizeof(PHeapLink*)*heap->size);
|
||||
MEM_freeN(heap->tree);
|
||||
|
||||
heap->tree = ntree;
|
||||
heap->bufsize = newsize;
|
||||
}
|
||||
|
||||
param_assert(heap->size < heap->bufsize);
|
||||
|
||||
if (heap->freelinks) {
|
||||
link = heap->freelinks;
|
||||
heap->freelinks = (PHeapLink*)(((PHeapLink*)heap->freelinks)->ptr);
|
||||
}
|
||||
else
|
||||
link = (PHeapLink*)BLI_memarena_alloc(heap->arena, sizeof *link);
|
||||
link->value = value;
|
||||
link->ptr = ptr;
|
||||
link->index = heap->size;
|
||||
|
||||
heap->tree[link->index] = link;
|
||||
|
||||
heap->size++;
|
||||
|
||||
pheap_up(heap, heap->size-1);
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int pheap_empty(PHeap *heap)
|
||||
{
|
||||
return (heap->size == 0);
|
||||
}
|
||||
|
||||
static PHeapLink *pheap_toplink(PHeap *heap)
|
||||
{
|
||||
return heap->tree[0];
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *pheap_popmin(PHeap *heap)
|
||||
{
|
||||
void *ptr = heap->tree[0]->ptr;
|
||||
|
||||
heap->tree[0]->ptr = heap->freelinks;
|
||||
heap->freelinks = heap->tree[0];
|
||||
|
||||
if (heap->size == 1)
|
||||
heap->size--;
|
||||
else {
|
||||
PHEAP_SWAP(heap, 0, heap->size-1);
|
||||
heap->size--;
|
||||
|
||||
pheap_down(heap, 0);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void pheap_remove(PHeap *heap, PHeapLink *link)
|
||||
{
|
||||
int i = link->index;
|
||||
|
||||
while (i > 0) {
|
||||
int p = PHEAP_PARENT(i);
|
||||
|
||||
PHEAP_SWAP(heap, p, i);
|
||||
i = p;
|
||||
}
|
||||
|
||||
pheap_popmin(heap);
|
||||
}
|
||||
|
||||
/* Geometry */
|
||||
|
||||
static float p_vec_angle_cos(float *v1, float *v2, float *v3)
|
||||
@@ -1110,13 +969,13 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
|
||||
PEdge *e, *e1, *e2;
|
||||
PHashKey vkeys[3];
|
||||
PFace *f;
|
||||
struct PHeap *heap = pheap_new(nedges);
|
||||
struct Heap *heap = BLI_heap_new();
|
||||
float angle;
|
||||
|
||||
e = be;
|
||||
do {
|
||||
angle = p_edge_boundary_angle(e);
|
||||
e->u.heaplink = pheap_insert(heap, angle, e);
|
||||
e->u.heaplink = BLI_heap_insert(heap, angle, e);
|
||||
|
||||
e = p_boundary_edge_next(e);
|
||||
} while(e != be);
|
||||
@@ -1127,20 +986,20 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
|
||||
e->pair = be;
|
||||
be->pair = e;
|
||||
|
||||
pheap_remove(heap, e->u.heaplink);
|
||||
pheap_remove(heap, be->u.heaplink);
|
||||
BLI_heap_remove(heap, e->u.heaplink);
|
||||
BLI_heap_remove(heap, be->u.heaplink);
|
||||
}
|
||||
else {
|
||||
while (nedges > 2) {
|
||||
PEdge *ne, *ne1, *ne2;
|
||||
|
||||
e = (PEdge*)pheap_popmin(heap);
|
||||
e = (PEdge*)BLI_heap_popmin(heap);
|
||||
|
||||
e1 = p_boundary_edge_prev(e);
|
||||
e2 = p_boundary_edge_next(e);
|
||||
|
||||
pheap_remove(heap, e1->u.heaplink);
|
||||
pheap_remove(heap, e2->u.heaplink);
|
||||
BLI_heap_remove(heap, e1->u.heaplink);
|
||||
BLI_heap_remove(heap, e2->u.heaplink);
|
||||
e->u.heaplink = e1->u.heaplink = e2->u.heaplink = NULL;
|
||||
|
||||
e->flag |= PEDGE_FILLED;
|
||||
@@ -1175,15 +1034,15 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
|
||||
else {
|
||||
ne2->vert->edge = ne2;
|
||||
|
||||
ne2->u.heaplink = pheap_insert(heap, p_edge_boundary_angle(ne2), ne2);
|
||||
e2->u.heaplink = pheap_insert(heap, p_edge_boundary_angle(e2), e2);
|
||||
ne2->u.heaplink = BLI_heap_insert(heap, p_edge_boundary_angle(ne2), ne2);
|
||||
e2->u.heaplink = BLI_heap_insert(heap, p_edge_boundary_angle(e2), e2);
|
||||
}
|
||||
|
||||
nedges--;
|
||||
}
|
||||
}
|
||||
|
||||
pheap_delete(heap);
|
||||
BLI_heap_free(heap, NULL);
|
||||
}
|
||||
|
||||
static void p_chart_fill_boundaries(PChart *chart, PEdge *outer)
|
||||
@@ -2008,7 +1867,7 @@ static void p_chart_simplify_compute(PChart *chart)
|
||||
collapsed may then be view as stacks, where the next collapse/split
|
||||
is at the top of the respective lists. */
|
||||
|
||||
PHeap *heap = pheap_new();
|
||||
Heap *heap = BLI_heap_new();
|
||||
PVert *v, **wheelverts;
|
||||
PEdge *collapsededges = NULL, *e;
|
||||
int nwheelverts, i, ncollapsed = 0;
|
||||
@@ -2023,7 +1882,7 @@ static void p_chart_simplify_compute(PChart *chart)
|
||||
p_collapse_cost_vertex(v, &cost, &e);
|
||||
|
||||
if (e)
|
||||
v->u.heaplink = pheap_insert(heap, cost, e);
|
||||
v->u.heaplink = BLI_heap_insert(heap, cost, e);
|
||||
else
|
||||
v->u.heaplink = NULL;
|
||||
}
|
||||
@@ -2032,12 +1891,12 @@ static void p_chart_simplify_compute(PChart *chart)
|
||||
e->u.nextcollapse = NULL;
|
||||
|
||||
/* pop edge collapse out of heap one by one */
|
||||
while (!pheap_empty(heap)) {
|
||||
while (!BLI_heap_empty(heap)) {
|
||||
if (ncollapsed == NCOLLAPSE)
|
||||
break;
|
||||
|
||||
PHeapLink *link = pheap_toplink(heap);
|
||||
PEdge *edge = (PEdge*)pheap_popmin(heap), *pair = edge->pair;
|
||||
HeapNode *link = BLI_heap_top(heap);
|
||||
PEdge *edge = (PEdge*)BLI_heap_popmin(heap), *pair = edge->pair;
|
||||
PVert *oldv, *keepv;
|
||||
PEdge *wheele, *nexte;
|
||||
|
||||
@@ -2081,21 +1940,21 @@ static void p_chart_simplify_compute(PChart *chart)
|
||||
v = wheelverts[i];
|
||||
|
||||
if (v->u.heaplink) {
|
||||
pheap_remove(heap, v->u.heaplink);
|
||||
BLI_heap_remove(heap, v->u.heaplink);
|
||||
v->u.heaplink = NULL;
|
||||
}
|
||||
|
||||
p_collapse_cost_vertex(v, &cost, &collapse);
|
||||
|
||||
if (collapse)
|
||||
v->u.heaplink = pheap_insert(heap, cost, collapse);
|
||||
v->u.heaplink = BLI_heap_insert(heap, cost, collapse);
|
||||
}
|
||||
|
||||
ncollapsed++;
|
||||
}
|
||||
|
||||
MEM_freeN(wheelverts);
|
||||
pheap_delete(heap);
|
||||
BLI_heap_free(heap, NULL);
|
||||
|
||||
p_chart_post_collapse_flush(chart, collapsededges);
|
||||
}
|
||||
|
||||
@@ -51,23 +51,6 @@ struct PFace;
|
||||
struct PChart;
|
||||
struct PHandle;
|
||||
|
||||
/* Heap */
|
||||
|
||||
typedef struct PHeapLink {
|
||||
void *ptr;
|
||||
float value;
|
||||
int index;
|
||||
} PHeapLink;
|
||||
|
||||
typedef struct PHeap {
|
||||
unsigned int size;
|
||||
unsigned int bufsize;
|
||||
MemArena *arena;
|
||||
PHeapLink *freelinks;
|
||||
PHeapLink *links;
|
||||
PHeapLink **tree;
|
||||
} PHeap;
|
||||
|
||||
/* Simplices */
|
||||
|
||||
typedef struct PVert {
|
||||
@@ -77,7 +60,7 @@ typedef struct PVert {
|
||||
PHashKey key; /* construct */
|
||||
int id; /* abf/lscm matrix index */
|
||||
float distortion; /* area smoothing */
|
||||
PHeapLink *heaplink; /* edge collapsing */
|
||||
HeapNode *heaplink; /* edge collapsing */
|
||||
} u;
|
||||
|
||||
struct PEdge *edge;
|
||||
@@ -93,7 +76,7 @@ typedef struct PEdge {
|
||||
union PEdgeUnion {
|
||||
PHashKey key; /* construct */
|
||||
int id; /* abf matrix index */
|
||||
PHeapLink *heaplink; /* fill holes */
|
||||
HeapNode *heaplink; /* fill holes */
|
||||
struct PEdge *nextcollapse; /* simplification */
|
||||
} u;
|
||||
|
||||
|
||||
@@ -1265,6 +1265,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
else if (G.qual==LR_CTRLKEY) {
|
||||
if(G.obedit && G.obedit->type==OB_MESH)
|
||||
Edge_Menu();
|
||||
else if (G.f & G_FACESELECT)
|
||||
seam_mark_clear_tface(0);
|
||||
}
|
||||
else if (G.qual==LR_SHIFTKEY) {
|
||||
if (G.obedit && G.obedit->type==OB_MESH) {
|
||||
@@ -3992,7 +3994,7 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
break;
|
||||
case EKEY :
|
||||
if(okee("Unwrap"))
|
||||
unwrap_lscm();
|
||||
unwrap_lscm(0);
|
||||
break;
|
||||
case GKEY:
|
||||
if((G.qual==0) && is_uv_tface_editing_allowed()) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -571,6 +571,8 @@ void viewmove(int mode)
|
||||
VECCOPY(obofs, ofs);
|
||||
}
|
||||
}
|
||||
else
|
||||
ofs[0] = ofs[1] = ofs[2] = 0.0f;
|
||||
|
||||
reverse= 1.0f;
|
||||
if (G.vd->persmat[2][1] < 0.0f)
|
||||
|
||||
@@ -652,26 +652,6 @@ static int sample_backbuf_area(int x, int y, float size)
|
||||
return tot;
|
||||
}
|
||||
|
||||
static unsigned int sample_backbuf(int x, int y)
|
||||
{
|
||||
unsigned int col;
|
||||
|
||||
if(x>=curarea->winx || y>=curarea->winy) return 0;
|
||||
|
||||
x+= curarea->winrct.xmin;
|
||||
y+= curarea->winrct.ymin;
|
||||
|
||||
#ifdef __APPLE__
|
||||
glReadBuffer(GL_AUX0);
|
||||
#endif
|
||||
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
if(G.order==B_ENDIAN) SWITCH_INT(col);
|
||||
|
||||
return framebuffer_to_index(col);
|
||||
}
|
||||
|
||||
static int calc_vp_alpha_dl(VPaint *vp, float *vert_nor, short *mval)
|
||||
{
|
||||
float fac, dx, dy;
|
||||
|
||||
Reference in New Issue
Block a user