Merged Google Summer of Code sculptmode/multires/retopo tools.

From the tracker:
https://projects.blender.org/tracker/index.php?func=detail&aid=5018&group_id=9&atid=127
This commit is contained in:
Nicholas Bishop 2006-11-06 01:08:26 +00:00
parent 6feb2cc4f6
commit 8e97a2955b
49 changed files with 5485 additions and 166 deletions

@ -199,5 +199,14 @@ void post_layer_create(struct VLayer *vlayer);
void post_layer_destroy(struct VLayer *vlayer);
void post_server_add(void);
/* multires.c */
struct MultiresLevel;
void multires_free(struct Mesh *me);
void multires_set_level(void *ob, void *me_v);
void multires_calc_level_maps(struct MultiresLevel *lvl);
/* sculptmode.c */
void sculptmode_free_vertexusers(struct Scene *sce);
void sculptmode_init(struct Scene *sce);
#endif

@ -63,7 +63,6 @@ struct bSoundListener;
struct BMF_Font;
struct EditMesh;
typedef struct Global {
/* active pointers */
@ -190,6 +189,8 @@ typedef struct Global {
#define G_DRAW_VERSE_DEBUG (1 << 27)
/*#endif*/
#define G_SCULPTMODE (1 << 28)
/* G.fileflags */
#define G_AUTOPACK (1 << 0)

@ -285,4 +285,9 @@ void post_geometry_free_constraint(struct VNode *vnode) {}
void post_layer_create(struct VLayer *vlayer) {}
void post_layer_destroy(struct VLayer *vlayer) {}
void post_server_add(void) {}
/* Multires/sculpt stubs */
void multires_free(struct Mesh *me) {}
void multires_set_level(void *ob, void *me_v) {}
void multires_calc_level_maps(struct MultiresLevel *lvl) {}
void sculptmode_init(struct Scene *sce) {}
void sculptmode_free_all(struct Scene *sce) {}

@ -78,6 +78,8 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "multires.h"
// headers for fluidsim bobj meshes
#include <stdlib.h>
#include "LBM_fluidsim.h"
@ -3370,9 +3372,32 @@ DerivedMesh *mesh_get_derived_deform(Object *ob, int *needsFree_r)
DerivedMesh *mesh_create_derived_render(Object *ob)
{
DerivedMesh *final;
Mesh *m= get_mesh(ob);
unsigned i;
/* Goto the pin level for multires */
if(m->mr) {
m->mr->newlvl= m->mr->pinlvl;
multires_set_level(ob,m);
}
mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0);
/* Propagate the changes to render level - fails if mesh topology changed */
if(m->mr) {
if(final->getNumVerts(final) == m->totvert &&
final->getNumFaces(final) == m->totface) {
for(i=0; i<m->totvert; ++i)
memcpy(&m->mvert[i], CustomData_get(&final->vertData, i, LAYERTYPE_MVERT), sizeof(MVert));
final->release(final);
m->mr->newlvl= m->mr->renderlvl;
multires_set_level(ob,m);
final= getMeshDerivedMesh(m,ob,NULL);
}
}
return final;
}

@ -55,6 +55,8 @@
#include "DNA_meshdata_types.h"
#include "DNA_ipo_types.h"
#include "BDR_sculptmode.h"
#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_DerivedMesh.h"
@ -80,6 +82,8 @@
#include "BLI_editVert.h"
#include "BLI_arithb.h"
#include "multires.h"
int update_realtime_texture(TFace *tface, double time)
@ -153,6 +157,14 @@ void free_mesh(Mesh *me)
{
unlink_mesh(me);
if(me->pv) {
if(me->pv->vert_map) MEM_freeN(me->pv->vert_map);
if(me->pv->edge_map) MEM_freeN(me->pv->edge_map);
if(me->pv->old_faces) MEM_freeN(me->pv->old_faces);
if(me->pv->old_edges) MEM_freeN(me->pv->old_edges);
MEM_freeN(me->pv);
}
if(me->mvert) MEM_freeN(me->mvert);
if(me->medge) MEM_freeN(me->medge);
if(me->mface) MEM_freeN(me->mface);
@ -166,6 +178,8 @@ void free_mesh(Mesh *me)
if(me->bb) MEM_freeN(me->bb);
if(me->mselect) MEM_freeN(me->mselect);
if(me->mr) multires_free(me);
}
void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)

@ -56,6 +56,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_scriptlink_types.h"
#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
#include "BKE_action.h"
@ -76,6 +77,9 @@
#include "BKE_world.h"
#include "BKE_utildefines.h"
#include "BIF_previewrender.h"
#include "BDR_sculptmode.h"
#include "BPY_extern.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@ -162,6 +166,8 @@ void free_scene(Scene *sce)
ntreeFreeTree(sce->nodetree);
MEM_freeN(sce->nodetree);
}
sculptmode_free_all(sce);
}
Scene *add_scene(char *name)
@ -232,9 +238,11 @@ Scene *add_scene(char *name)
strcpy(sce->r.backbuf, "//backbuf");
strcpy(sce->r.pic, U.renderdir);
strcpy(sce->r.ftype, "//ftype");
BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f);
sce->r.osa= 8;
sculptmode_init(sce);
/* note; in header_info.c the scene copy happens..., if you add more to renderdata it has to be checked there */
scene_add_render_layer(sce);

@ -41,6 +41,7 @@
#include "DNA_mesh_types.h"
struct DerivedMesh;
struct RetopoPaintData;
/* note; changing this also might affect the undo copy in editmesh.c */
typedef struct EditVert
@ -163,6 +164,9 @@ typedef struct EditMesh
*/
struct DerivedMesh *derivedCage, *derivedFinal;
char retopo_mode; /* 0=OFF, 1=ON, 2=PAINT */
struct RetopoPaintData *retopo_paint_data;
#ifdef WITH_VERSE
void *vnode;
#endif

@ -105,6 +105,8 @@
#include "BLI_arithb.h"
#include "BLI_storage_types.h" // for relname flags
#include "BDR_sculptmode.h"
#include "BKE_bad_level_calls.h" // for reopen_text build_seqar (from WHILE_SEQ) set_rects_butspace check_imasel_copy
#include "BKE_action.h"
@ -136,6 +138,8 @@
#include "BLO_undofile.h"
#include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory
#include "multires.h"
#include "readfile.h"
#include "genfile.h"
@ -2249,6 +2253,31 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->oc= 0;
mesh->dface= NULL;
mesh->mselect= NULL;
/* Multires data */
mesh->mr= newdataadr(fd, mesh->mr);
if(mesh->mr) {
MultiresLevel *lvl;
link_list(fd, &mesh->mr->levels);
for(lvl= mesh->mr->levels.first; lvl; lvl= lvl->next) {
lvl->verts= newdataadr(fd, lvl->verts);
lvl->faces= newdataadr(fd, lvl->faces);
lvl->edges= newdataadr(fd, lvl->edges);
lvl->texcolfaces= newdataadr(fd, lvl->texcolfaces);
/* Recalculating the maps is faster than reading them from the file */
multires_calc_level_maps(lvl);
}
}
/* PMV */
mesh->pv= newdataadr(fd, mesh->pv);
if(mesh->pv) {
mesh->pv->vert_map= newdataadr(fd, mesh->pv->vert_map);
mesh->pv->edge_map= newdataadr(fd, mesh->pv->edge_map);
mesh->pv->old_faces= newdataadr(fd, mesh->pv->old_faces);
mesh->pv->old_edges= newdataadr(fd, mesh->pv->old_edges);
}
if (mesh->tface) {
TFace *tfaces= mesh->tface;
@ -2699,7 +2728,8 @@ static void lib_link_scene(FileData *fd, Main *main)
Base *base, *next;
Editing *ed;
Sequence *seq;
int a;
sce= main->scene.first;
while(sce) {
if(sce->id.flag & LIB_NEEDLINK) {
@ -2711,6 +2741,13 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->imapaint.brush=
newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.brush);
/* Sculptdata textures */
for(a=0; a<MAX_MTEX; ++a) {
MTex *mtex= sce->sculptdata.mtex[a];
if(mtex)
mtex->tex= newlibadr_us(fd, sce->id.lib, mtex->tex);
}
base= sce->base.first;
while(base) {
next= base->next;
@ -2792,7 +2829,18 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->radio= newdataadr(fd, sce->radio);
sce->toolsettings= newdataadr(fd, sce->toolsettings);
/* SculptData */
sce->sculptdata.active_ob= NULL;
sce->sculptdata.vertex_users= NULL;
sce->sculptdata.texrndr= NULL;
sce->sculptdata.propset= 0;
sce->sculptdata.undo_cur= NULL;
sce->sculptdata.undo.first= sce->sculptdata.undo.last= NULL;
/* SculptData textures */
for(a=0; a<MAX_MTEX; ++a)
sce->sculptdata.mtex[a]= newdataadr(fd,sce->sculptdata.mtex[a]);
if(sce->ed) {
ed= sce->ed= newdataadr(fd, sce->ed);
@ -3030,6 +3078,7 @@ static void lib_link_screen(FileData *fd, Main *main)
if(v3d->localvd) {
v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
}
v3d->depths= NULL;
v3d->ri= NULL;
}
else if(sl->spacetype==SPACE_IPO) {
@ -3352,6 +3401,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
v3d->localvd= newdataadr(fd, v3d->localvd);
v3d->afterdraw.first= v3d->afterdraw.last= NULL;
v3d->clipbb= newdataadr(fd, v3d->clipbb);
v3d->retopo_view_data= NULL;
}
else if (sl->spacetype==SPACE_OOPS) {
SpaceOops *soops= (SpaceOops*) sl;

@ -1007,6 +1007,7 @@ static void write_dverts(WriteData *wd, int count, MDeformVert *dvlist)
static void write_meshs(WriteData *wd, ListBase *idbase)
{
Mesh *mesh;
MultiresLevel *lvl;
mesh= idbase->first;
while(mesh) {
@ -1029,7 +1030,7 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
/* direct data */
writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat);
writestruct(wd, DATA, "MVert", mesh->totvert, mesh->mvert);
writestruct(wd, DATA, "MVert", mesh->pv?mesh->pv->totvert:mesh->totvert, mesh->mvert);
writestruct(wd, DATA, "MEdge", mesh->totedge, mesh->medge);
writestruct(wd, DATA, "MFace", mesh->totface, mesh->mface);
writestruct(wd, DATA, "TFace", mesh->totface, mesh->tface);
@ -1038,6 +1039,26 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
write_dverts(wd, mesh->totvert, mesh->dvert);
/* Multires data */
writestruct(wd, DATA, "Multires", 1, mesh->mr);
if(mesh->mr) {
for(lvl= mesh->mr->levels.first; lvl; lvl= lvl->next) {
writestruct(wd, DATA, "MultiresLevel", 1, lvl);
writestruct(wd, DATA, "MVert", lvl->totvert, lvl->verts);
writestruct(wd, DATA, "MultiresFace", lvl->totface, lvl->faces);
writestruct(wd, DATA, "MultiresEdge", lvl->totedge, lvl->edges);
writestruct(wd, DATA, "MultiresTexColFace", lvl->totface, lvl->texcolfaces);
}
}
/* PMV data */
if(mesh->pv) {
writestruct(wd, DATA, "PartialVisibility", 1, mesh->pv);
writedata(wd, DATA, sizeof(unsigned int)*mesh->pv->totvert, mesh->pv->vert_map);
writedata(wd, DATA, sizeof(int)*mesh->pv->totedge, mesh->pv->edge_map);
writestruct(wd, DATA, "MFace", mesh->pv->totface, mesh->pv->old_faces);
writestruct(wd, DATA, "MEdge", mesh->pv->totedge, mesh->pv->old_edges);
}
}
mesh= mesh->id.next;
}
@ -1199,6 +1220,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
Strip *strip;
TimeMarker *marker;
SceneRenderLayer *srl;
int a;
sce= scebase->first;
while(sce) {
@ -1214,7 +1236,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
writestruct(wd, DATA, "Radio", 1, sce->radio);
writestruct(wd, DATA, "ToolSettings", 1, sce->toolsettings);
for(a=0; a<MAX_MTEX; ++a)
writestruct(wd, DATA, "MTex", 1, sce->sculptdata.mtex[a]);
ed= sce->ed;
if(ed) {
writestruct(wd, DATA, "Editing", 1, ed);

@ -50,6 +50,9 @@ struct EditVert;
struct EditFace;
struct EditEdge;
int set_gl_material(int nr);
int init_gl_materials(struct Object *ob, int check_alpha);
void mesh_foreachScreenVert(void (*func)(void *userData, struct EditVert *eve, int x, int y, int index), void *userData, int clipVerts);
void mesh_foreachScreenEdge(void (*func)(void *userData, struct EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts);
void mesh_foreachScreenFace(void (*func)(void *userData, struct EditFace *efa, int x, int y, int index), void *userData);

@ -0,0 +1,77 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BDR_SCULPTMODE_H
#define BDR_SCULPTMODE_H
struct uiBlock;
struct BrushData;
struct Mesh;
struct Object;
struct Scene;
struct ScrArea;
typedef struct PropsetData {
short origloc[2];
short origsize;
char origstrength;
unsigned int tex;
} PropsetData;
/* Memory */
void sculptmode_init(struct Scene *);
void sculptmode_free_all(struct Scene *);
/* Undo */
void sculptmode_undo_push(char *str);
void sculptmode_undo();
void sculptmode_redo();
void sculptmode_undo_menu();
/* Interface */
void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, unsigned short cy);
void sculptmode_draw_interface_textures(struct uiBlock *block,unsigned short cx, unsigned short cy);
void sculptmode_rem_tex(void*,void*);
void sculptmode_propset(const unsigned short event);
void sculptmode_selectbrush_menu();
void sculptmode_draw_mesh();
struct BrushData *sculptmode_brush();
void sculptmode_update_tex();
void sculpt();
void set_sculpt_object(struct Object *ob);
void set_sculptmode();
/* Partial Mesh Visibility */
void sculptmode_revert_pmv(struct Mesh *me);
void sculptmode_pmv_off(struct Mesh *me);
void sculptmode_pmv(int mode);
#endif

@ -72,6 +72,7 @@ extern void add_primitiveMesh(int type);
extern void adduplicate_mesh(void);
extern void add_click_mesh(void);
extern void addedgeface_mesh(void);
void addfaces_from_edgenet();
/* ******************* editmesh_lib.c */

@ -43,6 +43,7 @@ struct rctf;
void sdrawXORline(int x0, int y0, int x1, int y1);
void sdrawXORline4(int nr, int x0, int y0, int x1, int y1);
void fdrawXORellipse(float xofs, float yofs, float hw, float hh);
void fdrawXORcirc(float xofs, float yofs, float rad);
/**

@ -30,6 +30,9 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef BIF_PREVIEWRENDER_H
#define BIF_PREVIEWRENDER_H
#include "DNA_vec_types.h"
struct View3D;
@ -87,3 +90,5 @@ void BIF_view3d_previewdraw (struct ScrArea *sa, struct uiBlock *block);
void BIF_view3d_previewrender_free(struct View3D *v3d);
void BIF_view3d_previewrender_clear(struct ScrArea *sa);
void BIF_view3d_previewrender_signal(struct ScrArea *sa, short signal);
#endif

@ -161,7 +161,7 @@ typedef enum {
ICON_UGLY_GREEN_RING,
ICON_GHOST,
ICON_SORTBYEXT,
ICON_BLANK33,
ICON_SCULPTMODE_HLT,
ICON_VERTEXSEL,
ICON_EDGESEL,
ICON_FACESEL,

@ -0,0 +1,115 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BIF_RETOPO_H
#define BIF_RETOPO_H
#include "DNA_vec_types.h"
struct EditVert;
struct Mesh;
struct View3D;
typedef struct RetopoViewData {
/* OpenGL matrices */
double modelviewmat[16], projectionmat[16];
int viewport[4];
char queue_matrix_update;
} RetopoViewData;
typedef struct RetopoPaintPoint {
struct RetopoPaintPoint *next, *prev;
vec2s loc;
short index;
float co[3];
struct EditVert *eve;
} RetopoPaintPoint;
typedef struct RetopoPaintLine {
struct RetopoPaintLine *next, *prev;
ListBase points;
ListBase hitlist; /* RetopoPaintHit */
RetopoPaintPoint *cyclic;
} RetopoPaintLine;
typedef struct RetopoPaintSel {
struct RetopoPaintSel *next, *prev;
RetopoPaintLine *line;
char first;
} RetopoPaintSel;
typedef struct RetopoPaintData {
char mode;
char in_drag;
short sloc[2];
ListBase lines;
ListBase intersections; /* RetopoPaintPoint */
short seldist;
RetopoPaintSel nearest;
/* Interface controls */
char line_div;
char ellipse_div;
} RetopoPaintData;
/* RetopoPaintData.mode */
#define RETOPO_PEN 1
#define RETOPO_LINE 2
#define RETOPO_ELLIPSE 4
RetopoPaintData *get_retopo_paint_data();
char retopo_mesh_check();
char retopo_curve_check();
void retopo_end_okee();
void retopo_free_paint_data(RetopoPaintData *rpd);
void retopo_free_paint();
char retopo_mesh_paint_check();
void retopo_paint_view_update(struct View3D *v3d);
void retopo_paint_toggle(void*,void*);
char retopo_paint(const unsigned short event);
void retopo_draw_paint_lines();
RetopoPaintData *retopo_paint_data_copy(RetopoPaintData *rpd);
void retopo_toggle(void*,void*);
void retopo_do_vert(struct View3D *v3d, float *v);
void retopo_do_all(void*,void*);
void retopo_queue_updates(struct View3D *v3d);
void retopo_matrix_update(struct View3D *v3d);
void retopo_free_view_data(struct View3D *v3d);
#endif

@ -54,6 +54,7 @@ struct SpaceOops;
#define VIEW3D_HANDLER_PROPERTIES 2
#define VIEW3D_HANDLER_OBJECT 3
#define VIEW3D_HANDLER_PREVIEW 4
#define VIEW3D_HANDLER_MULTIRES 5
/* ipo handler codes */
#define IPO_HANDLER_PROPERTIES 20

@ -39,6 +39,14 @@ struct BoundBox;
struct View3D;
struct ScrArea;
typedef struct ViewDepths {
unsigned short w, h;
float *depths;
double depth_range[2];
char damaged;
} ViewDepths;
#define PERSP_WIN 0
#define PERSP_VIEW 1
#define PERSP_STORE 2

@ -554,6 +554,9 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_BTEXDELETE 2856
#define B_BRUSHKEEPDATA 2857
/* Sculptmode */
#define B_SCULPT_TEXBROWSE 2860
/* *********************** */
#define B_RADIOBUTS 3000

@ -0,0 +1,54 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef MULTIRES_H
#define MULTIRES_H
struct uiBlock;
struct Object;
struct Mesh;
struct MultiresLevel;
void multires_draw_interface(struct uiBlock *block, unsigned short cx, unsigned short cy);
void multires_disp_map(void *, void*);
void multires_make(void *ob, void *me);
void multires_delete(void *ob, void *me);
void multires_free(Mesh *me);
void multires_free_level(MultiresLevel *lvl);
void multires_del_lower(void *ob, void *me);
void multires_del_higher(void *ob, void *me);
void multires_add_level(void *ob, void *me);
void multires_set_level(void *ob, void *me);
void multires_update_levels(Mesh *me);
void multires_level_to_mesh(Object *ob, Mesh *me);
void multires_calc_level_maps(MultiresLevel *lvl);
void multires_edge_level_update(void *ob, void *me);
#endif

@ -229,6 +229,7 @@ typedef struct IpoCurve {
#define CU_STRETCH 128
#define CU_OFFS_PATHDIST 256
#define CU_FAST 512 /* Font: no filling inside editmode */
#define CU_RETOPO 1024
/* spacemode */
#define CU_LEFT 0

@ -47,6 +47,8 @@ struct MCol;
struct MSticky;
struct Mesh;
struct OcInfo;
struct Multires;
struct PartialVisibility;
typedef struct TFace {
@ -99,6 +101,8 @@ typedef struct Mesh {
short totcol;
short subsurftype;
struct Multires *mr; /* Multiresolution modeling data */
struct PartialVisibility *pv;
/*ifdef WITH_VERSE*/
/* not written in file, pointer at geometry VerseNode */
void *vnode;

@ -75,6 +75,66 @@ typedef struct MSelect {
int index;
int type;
} MSelect;
/* Multiresolution modeling */
typedef struct MultiresCol {
float a, r, g, b, u, v;
} MultiresCol;
typedef struct MultiresFace {
unsigned int v[4];
unsigned int mid;
unsigned int childrenstart;
char flag, pad[3];
} MultiresFace;
typedef struct MultiresEdge {
unsigned int v[2];
unsigned int mid;
} MultiresEdge;
typedef struct MultiresTexColFace {
/* vertex colors and texfaces */
void *tex_page;
MultiresCol col[4];
short tex_mode, tex_tile, tex_unwrap;
char tex_flag, tex_transp;
} MultiresTexColFace;
typedef struct MultiresMapNode {
struct MultiresMapNode *next, *prev;
int Index, pad;
} MultiresMapNode;
typedef struct MultiresLevel {
struct MultiresLevel *next, *prev;
MVert *verts;
MultiresFace *faces;
MultiresTexColFace *texcolfaces;
MultiresEdge *edges;
ListBase *vert_edge_map;
ListBase *vert_face_map;
unsigned int totvert, totface, totedge, pad;
} MultiresLevel;
typedef struct Multires {
ListBase levels;
unsigned char level_count, current, newlvl, edgelvl, pinlvl, renderlvl;
unsigned char use_col, use_tex;
/* Vertex groups are stored only for the level 1 mesh, for all other
* levels it's calculated when multires_level_to_mesh() is called */
MDeformVert *dverts;
} Multires;
typedef struct PartialVisibility {
unsigned int *vert_map; /* vert_map[Old Index]= New Index */
int *edge_map; /* edge_map[Old Index]= New Index, -1= hidden */
MFace *old_faces;
MEdge *old_edges;
unsigned int totface, totedge, totvert, pad;
} PartialVisibility;
/* mvert->flag (1=SELECT) */
#define ME_SPHERETEST 2
#define ME_SPHERETEMP 4

@ -49,6 +49,7 @@ struct Scene;
struct Image;
struct Group;
struct bNodeTree;
struct PropsetData;
typedef struct Base {
struct Base *next, *prev;
@ -357,6 +358,74 @@ typedef struct ToolSettings {
} ToolSettings;
/* Used by all brushes to store their properties, which can be directly set
by the interface code. Note that not all properties are actually used by
all the brushes. */
typedef struct BrushData
{
short size;
char strength, dir; /* Not used for smooth brush */
char airbrush;
char pad[7];
} BrushData;
struct RenderInfo;
struct SculptUndo;
typedef struct SculptData
{
/* Cache of the OpenGL matrices */
double modelviewmat[16];
double projectionmat[16];
int viewport[4];
/* Pointers to all of sculptmodes's textures */
struct MTex *mtex[10];
struct Object *active_ob;
/* An array of lists; array is sized as
large as the number of verts in the mesh,
the list for each vert contains the index
for all the faces that use that vertex */
struct ListBase *vertex_users;
/* Used to cache the render of the active texture */
struct RenderInfo *texrndr;
struct PropsetData *propset_data;
struct ListBase undo;
struct SculptUndo *undo_cur;
/* For rotating around a pivot point */
vec3f pivot;
/* Settings for each brush */
BrushData drawbrush, smoothbrush, pinchbrush, inflatebrush, grabbrush, layerbrush;
/* Number of nodes in vertex_users */
int vertex_users_size;
short brush_type;
/* Symmetry is separate from the other BrushData because the same
settings are always used for all brush types */
short symm_x, symm_y, symm_z;
/* For the Brush Shape */
float texsize[3];
short texact, texnr;
short spacing;
char texrept;
char texfade;
char averaging, propset, pad[2];
} SculptData;
#define SCULPTREPT_DRAG 1
#define SCULPTREPT_TILE 2
#define SCULPTREPT_3D 3
typedef struct Scene {
ID id;
struct Object *camera;
@ -405,6 +474,9 @@ typedef struct Scene {
struct DagForest *theDag;
short dagisvalid, dagflags;
short pad4, recalc; /* recalc = counterpart of ob->recalc */
/* Sculptmode data */
struct SculptData sculptdata;
} Scene;
@ -549,6 +621,14 @@ typedef struct Scene {
#define FFMPEG_MULTIPLEX_AUDIO 1
#define FFMPEG_AUTOSPLIT_OUTPUT 2
/* SculptData brushtype */
#define DRAW_BRUSH 1
#define SMOOTH_BRUSH 2
#define PINCH_BRUSH 3
#define INFLATE_BRUSH 4
#define GRAB_BRUSH 5
#define LAYER_BRUSH 6
/* toolsettings->imagepaint_flag */
#define IMAGEPAINT_DRAWING 1
#define IMAGEPAINT_DRAW_TOOL 2

@ -258,7 +258,6 @@ extern UserDef U; /* from usiblender.c !!!! */
#define USER_DISABLE_SOUND 2
#define USER_DISABLE_MIPMAP 4
/* vrml flag */
#define USER_VRML_LAYERS 1

@ -34,6 +34,7 @@
#ifndef DNA_VIEW3D_TYPES_H
#define DNA_VIEW3D_TYPES_H
struct ViewDepths;
struct Object;
struct Image;
struct Tex;
@ -41,6 +42,7 @@ struct SpaceLink;
struct Base;
struct BoundBox;
struct RenderInfo;
struct RetopoViewData;
/* This is needed to not let VC choke on near and far... old
* proprietary MS extensions... */
@ -95,6 +97,8 @@ typedef struct View3D {
struct BGpic *bgpic;
struct View3D *localvd;
struct RenderInfo *ri;
struct RetopoViewData *retopo_view_data;
struct ViewDepths *depths;
/**
* The drawing mode for the 3d display. Set to OB_WIRE, OB_SOLID,
@ -104,7 +108,7 @@ typedef struct View3D {
int lay, layact;
short scenelock, around, camzoom;
short pad1;
char pivot_last, pad1; /* pivot_last is for rotating around the last edited element */
float lens, grid, gridview, pixsize, near, far;
float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */

@ -92,6 +92,7 @@
#include "IMB_imbuf_types.h"
#include "envmap.h"
#include "multires.h"
#include "render_types.h"
#include "rendercore.h"
#include "renderdatabase.h"
@ -1784,7 +1785,7 @@ static void use_mesh_edge_lookup(Render *re, Mesh *me, DispListMesh *dlm, MEdge
static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts)
{
Mesh *me;
Mesh *me, *me_store= NULL;
MVert *mvert = NULL;
MFace *mface;
VlakRen *vlr; //, *vlr1;
@ -1801,7 +1802,7 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
int end, do_autosmooth=0, totvert = 0, dm_needsfree;
int useFluidmeshNormals= 0; // NT fluidsim, use smoothed normals?
int use_original_normals= 0;
me= ob->data;
paf = give_parteff(ob);
@ -1853,9 +1854,49 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
if(!only_verts)
if(need_orco) orco = get_object_orco(re, ob);
/* If multires is enabled, a copy is made of the mesh
to allow multires to be applied with modifiers. */
if(me->mr) {
me_store= me;
{
Mesh *men= MEM_callocN(sizeof(Mesh),"mrm render mesh");
men->totvert= me->totvert;
men->totedge= me->totedge;
men->totface= me->totface;
men->mvert= MEM_dupallocN(me->mvert);
men->medge= MEM_dupallocN(me->medge);
men->mface= MEM_dupallocN(me->mface);
if(me->mr) {
MultiresLevel *lvl, *nlvl;
men->mr= MEM_dupallocN(me->mr);
men->mr->levels.first= men->mr->levels.last= NULL;
for(lvl= me->mr->levels.first; lvl; lvl= lvl->next) {
nlvl= MEM_dupallocN(lvl);
BLI_addtail(&men->mr->levels,nlvl);
nlvl->verts= MEM_dupallocN(lvl->verts);
nlvl->faces= MEM_dupallocN(lvl->faces);
nlvl->edges= MEM_dupallocN(lvl->edges);
multires_calc_level_maps(nlvl);
}
}
me= men;
}
ob->data= me;
}
dm = mesh_create_derived_render(ob);
dm_needsfree= 1;
/* (Multires) Now switch the meshes back around */
if(me->mr) {
ob->data= me_store;
me_store= me;
me= ob->data;
}
if(dm==NULL) return; /* in case duplicated object fails? */
@ -1864,7 +1905,7 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
(ob->fluidsimSettings->meshSurface) ) {
useFluidmeshNormals = 1;
}
dlm = dm->convertToDispListMesh(dm, 1);
mvert= dlm->mvert;
@ -2111,9 +2152,13 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
if(need_stress)
calc_edge_stress(re, me, totverto, totvlako);
}
if(dlm) displistmesh_free(dlm);
if(dm_needsfree) dm->release(dm);
if(me_store) {
free_mesh(me_store);
MEM_freeN(me_store);
}
}
/* ------------------------------------------------------------------------- */

@ -109,6 +109,7 @@
#include "BIF_poseobject.h"
#include "BIF_renderwin.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_scrarea.h"
#include "BIF_space.h"
@ -147,6 +148,7 @@
#include "BDR_editcurve.h"
#include "BDR_editface.h"
#include "BDR_editobject.h"
#include "BDR_sculptmode.h"
#include "BDR_vpaint.h"
#include "BDR_unwrapper.h"
@ -162,6 +164,7 @@
#include "RE_render_ext.h" // make_sticky
#include "butspace.h" // own module
#include "multires.h"
static float editbutweight=1.0;
float editbutvweight=1;
@ -669,6 +672,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
static void editing_panel_mesh_type(Object *ob, Mesh *me)
{
uiBlock *block;
uiBut *but;
float val;
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
@ -678,9 +682,33 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
uiDefButBitS(block, TOG, ME_AUTOSMOOTH, REDRAWVIEW3D, "Auto Smooth",10,180,154,19, &me->flag, 0, 0, 0, 0, "Treats all set-smoothed faces with angles less than Degr: as 'smooth' during render");
uiDefButS(block, NUM, B_DIFF, "Degr:", 10,160,154,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on");
/* Retopo */
if(G.obedit) {
uiBlockBeginAlign(block);
but= uiDefButBitC(block,TOG,1,B_NOP, "Retopo", 10,130,154,19, &G.editMesh->retopo_mode, 0,0,0,0, "Turn on the re-topology tool");
uiButSetFunc(but,retopo_toggle,ob,me);
if(G.editMesh->retopo_mode) {
but= uiDefButBitC(block,TOG,2,B_NOP,"Paint", 10,110,50,19, &G.editMesh->retopo_mode,0,0,0,0, "");
uiButSetFunc(but,retopo_paint_toggle,ob,me);
but= uiDefBut(block,BUT,B_NOP,"Retopo All", 60,110,104,19, 0,0,0,0,0, "Apply the re-topology tool to all selected vertices");
uiButSetFunc(but,retopo_do_all,ob,me);
}
}
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_AUTO);
val= me->mr ? 1.0 : 0.0;
uiDefBut(block, LABEL, 0, "Multires",10,70,70,20,0,val,0,0,0,"");
if(me->mr) {
but= uiDefBut(block,BUT,B_NOP,"Delete", 80,70,84,19,0,0,0,0,0,"");
uiButSetFunc(but,multires_delete,ob,me);
}
else {
but= uiDefBut(block,BUT,B_NOP,"Make", 80,70,84,19,0,0,0,0,0,"");
uiButSetFunc(but,multires_make,ob,me);
}
if(me->mcol) val= 1.0; else val= 0.0;
uiDefBut(block, LABEL, 0, "VertCol", 10,50,70,20, 0, val, 0, 0, 0, "");
if(me->mcol==NULL) {
@ -1111,6 +1139,9 @@ static void modifiers_applyModifier(void *obv, void *mdv)
BIF_undo_push("Apply modifier");
}
if (G.f & G_SCULPTMODE)
set_sculpt_object(OBACT);
}
static void modifiers_copyModifier(void *ob_v, void *md_v)
@ -2525,6 +2556,17 @@ static void editing_panel_curve_tools1(Object *ob, Curve *cu)
uiBlockEndAlign(block);
uiDefButF(block, NUM, REDRAWVIEW3D, "NSize:", 400, 40, 150, 19, &G.scene->editbutsize, 0.001, 1.0, 10, 0, "Normal size for drawing");
if(G.obedit) {
uiBut *but;
uiBlockBeginAlign(block);
but= uiDefButBitS(block,TOG,CU_RETOPO,B_NOP, "Retopo", 560,180,100,19, &cu->flag, 0,0,0,0, "Turn on the re-topology tool");
uiButSetFunc(but,retopo_toggle,0,0);
if(cu->flag & CU_RETOPO) {
but= uiDefBut(block,BUT,B_NOP,"Retopo All", 560,160,100,19, 0,0,0,0,0, "Apply the re-topology tool to all selected vertices");
uiButSetFunc(but,retopo_do_all,0,0);
}
}
}
/* only for bevel or taper */
@ -3921,13 +3963,168 @@ static void editing_panel_links(Object *ob)
uiDefBut(block, BUT,B_MATASS, "Assign", 292,47,162,26, 0, 0, 0, 0, 0, "In EditMode, assigns the active index to selected faces");
uiBlockBeginAlign(block);
uiDefBut(block, BUT,B_SETSMOOTH,"Set Smooth", 291,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'smooth' rendering of selected faces");
uiDefBut(block, BUT,B_SETSOLID, "Set Solid", 373,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'solid' rendering of selected faces");
if(!(G.f & G_SCULPTMODE) || ((G.f & G_SCULPTMODE) && G.obedit))
{
uiDefBut(block, BUT,B_SETSMOOTH,"Set Smooth", 291,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'smooth' rendering of selected faces");
uiDefBut(block, BUT,B_SETSOLID, "Set Solid", 373,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'solid' rendering of selected faces");
}
uiBlockEndAlign(block);
}
void editing_panel_sculpting_tools()
{
uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_tools", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Sculpting Tools", "Editing", 300, 0, 318, 204)==0) return;
sculptmode_draw_interface_tools(block,0,200);
}
void editing_panel_sculpting_textures()
{
uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_textures", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Brush Textures", "Editing", 300, 0, 318, 204)==0) return;
sculptmode_draw_interface_textures(block,0,200);
}
void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned short cy)
{
SculptData *sd;
uiBut *but;
if(!G.scene) return;
sd= &G.scene->sculptdata;
uiBlockBeginAlign(block);
uiDefBut(block,LABEL,B_NOP,"Brush",cx,cy,90,19,NULL,0,0,0,0,"");
cy-= 20;
uiBlockBeginAlign(block);
uiDefButS(block,ROW,REDRAWBUTSEDIT,"Draw",cx,cy,67,19,&sd->brush_type,14.0,DRAW_BRUSH,0,0,"Draw lines on the model");
uiDefButS(block,ROW,REDRAWBUTSEDIT,"Smooth",cx+67,cy,67,19,&sd->brush_type,14.0,SMOOTH_BRUSH,0,0,"Interactively smooth areas of the model");
uiDefButS(block,ROW,REDRAWBUTSEDIT,"Pinch",cx+134,cy,66,19,&sd->brush_type,14.0,PINCH_BRUSH,0,0,"Interactively pinch areas of the model");
cy-= 20;
uiDefButS(block,ROW,REDRAWBUTSEDIT,"Inflate",cx,cy,67,19,&sd->brush_type,14,INFLATE_BRUSH,0,0,"Push vertices along the direction of their normals");
uiDefButS(block,ROW,REDRAWBUTSEDIT,"Grab", cx+67,cy,67,19,&sd->brush_type,14,GRAB_BRUSH,0,0,"Grabs a group of vertices and moves them with the mouse");
uiDefButS(block,ROW,REDRAWBUTSEDIT,"Layer", cx+134,cy,66,19,&sd->brush_type,14, LAYER_BRUSH,0,0,"Adds a layer of depth");
cy-= 25;
uiBlockBeginAlign(block);
uiDefBut(block,LABEL,B_NOP,"Shape",cx,cy,90,19,NULL,0,0,0,0,"");
cy-= 20;
uiBlockBeginAlign(block);
if(sd->brush_type!=SMOOTH_BRUSH && sd->brush_type!=GRAB_BRUSH) {
uiDefButC(block,ROW,B_NOP,"Add",cx,cy,67,19,&sculptmode_brush()->dir,15.0,1.0,0, 0,"Add depth to model [Shift]");
uiDefButC(block,ROW,B_NOP,"Sub",cx+67,cy,67,19,&sculptmode_brush()->dir,15.0,2.0,0, 0,"Subtract depth from model [Shift]");
}
if(sd->brush_type!=GRAB_BRUSH)
uiDefButC(block,TOG,B_NOP,"Airbrush",cx+134,cy,66,19,&sculptmode_brush()->airbrush,0,0,0,0,"Brush makes changes without waiting for the mouse to move");
cy-= 20;
but= uiDefButS(block,NUMSLI,B_NOP,"Size: ",cx,cy,200,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels");
cy-= 20;
uiDefButC(block,NUMSLI,B_NOP,"Strength: ",cx,cy,200,19,&sculptmode_brush()->strength,1.0,100.0,0,0,"Set brush strength");
cy-= 25;
uiBlockBeginAlign(block);
uiDefBut( block,LABEL,B_NOP,"Symmetry",cx,cy,90,19,NULL,0,0,0,0,"");
cy-= 20;
uiBlockBeginAlign(block);
uiDefButS(block,TOG,B_NOP,"X",cx,cy,67,19,&sd->symm_x,0,0,0,0,"Mirror brush across X axis");
uiDefButS(block,TOG,B_NOP,"Y",cx+67,cy,67,19,&sd->symm_y,0,0,0,0,"Mirror brush across Y axis");
uiDefButS(block,TOG,B_NOP,"Z",cx+134,cy,66,19,&sd->symm_z,0,0,0,0,"Mirror brush across Z axis");
uiBlockEndAlign(block);
cx+= 210;
}
void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsigned short cy)
{
SculptData *sd= &G.scene->sculptdata;
MTex *mtex;
int i;
int orig_y= cy;
char *strp;
uiBut *but;
uiBlockBeginAlign(block);
uiDefBut(block,LABEL,B_NOP,"Texture",cx,cy,200,20,0,0,0,0,0,"");
cy-= 20;
/* TEX CHANNELS */
uiBlockSetCol(block, TH_BUT_NEUTRAL);
for(i=-1; i<8; i++) {
char str[64];
int loos;
mtex= sd->mtex[i];
if(i==-1)
strcpy(str, "Default");
else {
if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos);
else strcpy(str, "");
}
str[10]= 0;
uiDefButS(block, ROW, REDRAWBUTSEDIT, str,cx, cy, 80, 20, &sd->texact, 3.0, (float)i, 0, 0, "Texture channel");
cy-= 18;
}
cy= orig_y-20;
cx+= 85;
mtex= sd->mtex[sd->texact];
if(sd->texact != -1) {
ID *id= NULL;
uiBlockBeginAlign(block);
if(mtex && mtex->tex) id= &mtex->tex->id;
IDnames_to_pupstring(&strp, NULL, "ADD NEW %x 32767", &G.main->tex, id, &G.buts->texnr);
if(mtex && mtex->tex) {
uiDefBut(block, TEX, B_IDNAME, "TE:",cx,cy,115,19, mtex->tex->id.name+2, 0.0, 18.0, 0, 0, "Texture name");
cy-= 20;
uiDefButS(block,MENU,B_SCULPT_TEXBROWSE, strp, cx,cy,20,19, &G.buts->texnr, 0,0,0,0, "Selects an existing texture or creates new");
uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, cx+21,cy,21,20, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
but= uiDefBut(block, BUT, B_NOP, "Clear",cx+43, cy, 72, 20, 0, 0, 0, 0, 0, "Erases link to texture");
uiButSetFunc(but,sculptmode_rem_tex,0,0);
cy-= 20;
uiDefButC(block,ROW,B_NOP, "Drag", cx, cy,39,19, &sd->texrept, 18,SCULPTREPT_DRAG,0,0,"Move the texture with the brush");
uiDefButC(block,ROW,B_NOP, "Tile", cx+39,cy,39,19, &sd->texrept, 18,SCULPTREPT_TILE,0,0,"Treat the texture as a tiled image extending across the screen");
uiDefButC(block,ROW,B_NOP, "3D", cx+78,cy,37,19, &sd->texrept, 18,SCULPTREPT_3D, 0,0,"Use vertex coords as texture coordinates");
cy-= 20;
uiDefButF(block,NUM,B_NOP, "X", cx, cy,39,19, &sd->texsize[0],-20,20,10,0,"Scaling factor for texture's X axis");
uiDefButF(block,NUM,B_NOP, "Y", cx+39,cy,38,19, &sd->texsize[1],-20,20,10,0,"Scaling factor for texture's Y axis");
uiDefButF(block,NUM,B_NOP, "Z", cx+78,cy,38,19, &sd->texsize[2],-20,20,10,0,"Scaling factor for texture's Z axis");
cy-= 20;
uiDefButC(block,TOG,B_NOP, "Fade", cx,cy,50,19, &sd->texfade, 0,0,0,0,"Smooth the edges of the texture");
uiDefButS(block,NUM,B_NOP, "Space", cx+50,cy,65,19, &sd->spacing, 0,500,20,0,"Non-zero inserts N pixels between dots");
cy+= 40;
}
else {
uiDefButS(block,TOG,B_SCULPT_TEXBROWSE, "Add New" ,cx, cy, 115, 19, &G.buts->texnr,-1,32767,0,0, "Adds a new texture");
uiDefButS(block,MENU,B_SCULPT_TEXBROWSE, strp, cx,cy-20,20,19, &G.buts->texnr, 0,0,0,0, "Selects an existing texture or creates new");
}
MEM_freeN(strp);
}
else {
uiBlockBeginAlign(block);
uiDefButS(block,NUM,B_NOP, "Space", cx+50,cy,65,19, &sd->spacing, 0,500,20,0,"Non-zero inserts N pixels between dots");
}
uiBlockEndAlign(block);
}
/* *************************** FACE/PAINT *************************** */
void do_fpaintbuts(unsigned short event)
@ -3937,8 +4134,12 @@ void do_fpaintbuts(unsigned short event)
bDeformGroup *defGroup;
TFace *activetf, *tf;
int a;
SculptData *sd= &G.scene->sculptdata;
ID *id, *idtest;
extern VPaint Gwp; /* from vpaint */
ToolSettings *settings= G.scene->toolsettings;
int nr= 1;
MTex *mtex;
ob= OBACT;
if(ob==NULL) return;
@ -4073,6 +4274,68 @@ void do_fpaintbuts(unsigned short event)
allqueue(REDRAWVIEW3D, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
break;
case B_SCULPT_TEXBROWSE:
sd= &G.scene->sculptdata;
if(G.buts->texnr== -2) {
id= NULL;
if(sd) {
mtex= sd->mtex[sd->texact];
if(mtex) id= &mtex->tex->id;
}
activate_databrowse((ID *)id, ID_TE, 0, B_SCULPT_TEXBROWSE, &G.buts->texnr, do_global_buttons);
return;
}
if(G.buts->texnr < 0) break;
if(G.buts->pin) {
}
else if(sd && sd->texact == -1) {
error("No texture channel selected");
allqueue(REDRAWBUTSSHADING, 0);
}
else if(sd && sd->texact != -1) {
id= NULL;
mtex= sd->mtex[sd->texact];
if(mtex) id= &mtex->tex->id;
idtest= G.main->tex.first;
while(idtest) {
if(nr==G.buts->texnr) {
break;
}
nr++;
idtest= idtest->next;
}
if(idtest==0) { /* new tex */
if(id) idtest= (ID *)copy_texture((Tex *)id);
else idtest= (ID *)add_texture("Tex");
idtest->us--;
}
if(idtest!=id && sd) {
if(sd->mtex[sd->texact]==0) {
sd->mtex[sd->texact]= add_mtex();
sd->mtex[sd->texact]->texco= TEXCO_VIEW;
}
sd->mtex[sd->texact]->tex= (Tex *)idtest;
id_us_plus(idtest);
if(id) id->us--;
BIF_undo_push("Texture browse");
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWBUTSSHADING, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWOOPS, 0);
BIF_preview_changed(ID_TE);
}
}
break;
case B_BRUSHBROWSE:
if(G.buts->menunr==-2) {
activate_databrowse((ID*)settings->imapaint.brush, ID_BR, 0, B_BRUSHBROWSE, &G.buts->menunr, do_global_buttons);
@ -4413,6 +4676,64 @@ static void editing_panel_mesh_uvautocalculation(void)
uiBlockEndAlign(block);
}
void editing_panel_mesh_multires()
{
uiBlock *block;
Object *ob= OBACT;
Mesh *me= get_mesh(ob);
if(!me->mr) return;
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_multires", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Multires", "Editing", 500, 0, 220, 204)==0) return;
multires_draw_interface(block,100,0);
}
void multires_draw_interface(uiBlock *block, unsigned short cx, unsigned short cy)
{
uiBut *but;
Object *ob= OBACT;
Mesh *me= get_mesh(ob);
uiBlockBeginAlign(block);
but= uiDefBut(block,BUT,B_NOP,"Add Level", cx,cy,200,19,0,0,0,0,0,"Add a new level of subdivision at the end of the chain");
uiButSetFunc(but,multires_add_level,ob,me);
cy-= 20;
if(me->mr->level_count>1) {
but= uiDefButC(block,NUM,B_NOP,"Level: ",cx,cy,200,19,&me->mr->newlvl,1.0,me->mr->level_count,0,0,"");
uiButSetFunc(but,multires_set_level,ob,me);
cy-= 20;
but= uiDefBut(block,BUT,B_NOP,"Del Lower", cx,cy,100,19,0,0,0,0,0,"Remove all levels of subdivision below the current one");
uiButSetFunc(but,multires_del_lower,ob,me);
but= uiDefBut(block,BUT,B_NOP,"Del Higher", cx+100,cy,100,19,0,0,0,0,0,"Remove all levels of subdivision above the current one");
uiButSetFunc(but,multires_del_higher,ob,me);
cy-= 20;
but= uiDefButC(block,NUM,B_NOP,"Edges: ",cx,cy,200,19,&me->mr->edgelvl,1.0,me->mr->level_count,0,0,"Set level of edges to display");
uiButSetFunc(but,multires_edge_level_update,ob,me);
cy-= 20;
uiBlockBeginAlign(block);
cy-= 5;
uiDefBut(block,LABEL,B_NOP,"Rendering",cx,cy,100,19,0,0,0,0,0,"");
cy-= 20;
uiDefButC(block,NUM,B_NOP,"Pin: ",cx,cy,200,19,&me->mr->pinlvl,1.0,me->mr->level_count,0,0,"Set level to apply modifiers to during render");
cy-= 20;
uiDefButC(block,NUM,B_NOP,"Render: ",cx,cy,200,19,&me->mr->renderlvl,1.0,me->mr->level_count,0,0,"Set level to render");
cy-= 20;
//but= uiDefBut(block,BUT,B_NOP,"Displacement Map", cx,cy,200,19,0,0,0,0,0,"");
//uiButSetFunc(but,multires_disp_map,me,0);
}
uiBlockEndAlign(block);
}
/* this is a mode context sensitive system */
void editing_panels()
@ -4435,11 +4756,17 @@ void editing_panels()
editing_panel_modifiers(ob);
editing_panel_shapes(ob);
/* modes */
if(get_mesh(ob)->mr)
editing_panel_mesh_multires();
if(G.obedit) {
editing_panel_mesh_tools(ob, ob->data);
editing_panel_mesh_tools1(ob, ob->data);
}
else {
else if(G.f & G_SCULPTMODE) {
editing_panel_sculpting_tools();
uiNewPanelTabbed("Sculpting Tools", "Editing");
editing_panel_sculpting_textures();
} else {
if(G.f & G_FACESELECT) {
editing_panel_mesh_texface();
editing_panel_mesh_uvautocalculation();

@ -1218,7 +1218,7 @@ static void texture_panel_colors(Tex *tex)
}
static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *la, bNode *node, Brush *br)
static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *la, bNode *node, Brush *br, SculptData *sd)
{
MTex *mt=NULL;
uiBlock *block;
@ -1240,6 +1240,7 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l
else if(wrld) idfrom= &wrld->id;
else if(la) idfrom= &la->id;
else if(br) idfrom= &br->id;
else if(sd) idfrom= NULL; /* Not sure what this does */
else idfrom= NULL;
uiBlockSetCol(block, TH_BUT_SETTING2);
@ -1255,6 +1256,9 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l
else if(br) {
std_libbuttons(block, 10, 180, 0, NULL, B_BTEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->menunr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA);
}
else if(sd) {
std_libbuttons(block, 10, 180, 0, NULL, B_SCULPT_TEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA);
}
else if(node) {
}
@ -1272,6 +1276,7 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l
else if(wrld) mt= wrld->mtex[a];
else if(la) mt= la->mtex[a];
else if(br) mt= br->mtex[a];
else if(sd) mt= sd->mtex[a];
if(mt && mt->tex) splitIDname(mt->tex->id.name+2, str, &loos);
else strcpy(str, "");
@ -1293,6 +1298,10 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l
uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(br->texact), 0.0, (float)a, 0, 0, "");
yco-= 20;
}
else if(sd) {
uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(sd->texact), 0.0, (float)a, 0, 0, "");
yco-= 20;
}
}
uiBlockEndAlign(block);
}
@ -1335,7 +1344,7 @@ static void texture_panel_preview(MTex *mtex, int preview)
uiDefButC(block, ROW, B_TEXREDR_PRV, "Mat", 200,175,80,25, &G.buts->texfrom, 3.0, 0.0, 0, 0, "Displays the textures of the active material");
uiDefButC(block, ROW, B_TEXREDR_PRV, "World", 200,150,80,25, &G.buts->texfrom, 3.0, 1.0, 0, 0, "Displays the textures of the world block");
uiDefButC(block, ROW, B_TEXREDR_PRV, "Lamp", 200,125,80,25, &G.buts->texfrom, 3.0, 2.0, 0, 0, "Displays the textures of the selected lamp");
uiDefButC(block, ROW, B_TEXREDR_PRV, "Brush", 200,100,80,25, &G.buts->texfrom, 3.0, 3.0, 0, 0, "Displays the textures of the selected lamp");
uiDefButC(block, ROW, B_TEXREDR_PRV, "Brush", 200,100,80,25, &G.buts->texfrom, 3.0, 3.0, 0, 0, "Displays the textures of the selected brush");
uiBlockEndAlign(block);
if(mtex && mtex->tex)
@ -3459,6 +3468,7 @@ void texture_panels()
{
Material *ma=NULL;
Brush *br=NULL;
SculptData *sd=NULL;
Lamp *la=NULL;
World *wrld=NULL;
bNode *node=NULL;
@ -3492,16 +3502,23 @@ void texture_panels()
}
}
else if(G.buts->texfrom==3) {
br= G.scene->toolsettings->imapaint.brush;
if(br) mtex= br->mtex[br->texact];
if(G.f & G_SCULPTMODE) {
sd= &G.scene->sculptdata;
if(sd->texact != -1)
mtex= sd->mtex[sd->texact];
}
else {
br= G.scene->toolsettings->imapaint.brush;
if(br) mtex= br->mtex[br->texact];
}
}
texture_panel_preview(mtex, ma || wrld || la || br || node); // for 'from' buttons
texture_panel_preview(mtex, ma || wrld || la || br || node || sd); // for 'from' buttons
if(ma || wrld || la || br || node) {
if(ma || wrld || la || br || node || sd) {
Tex *tex= NULL;
texture_panel_texture(mtex, ma, wrld, la, node, br);
texture_panel_texture(mtex, ma, wrld, la, node, br, sd);
if(mtex) tex= mtex->tex;
else if(node) tex= (Tex *)node->id;

@ -104,12 +104,14 @@
#include "BIF_glutil.h"
#include "BIF_mywindow.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BDR_drawmesh.h"
#include "BDR_drawobject.h"
#include "BDR_editobject.h"
#include "BDR_sculptmode.h"
#include "BDR_vpaint.h"
#include "BSE_drawview.h"
@ -139,7 +141,7 @@ static void draw_bounding_volume(Object *ob);
static float matbuf[MAXMATBUF][2][4];
static int totmat_gl= 0;
static int set_gl_material(int nr)
int set_gl_material(int nr)
{
static int last_gl_matnr= -1;
static int last_ret_val= 1;
@ -170,7 +172,7 @@ static int set_gl_material(int nr)
}
/* returns 1: when there's alpha needed to be drawn in a 2nd pass */
static int init_gl_materials(Object *ob, int check_alpha)
int init_gl_materials(Object *ob, int check_alpha)
{
extern Material defmaterial; // render module abuse...
Material *ma;
@ -1900,6 +1902,8 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived
draw_em_fancy_edges(cageDM);
if(ob==G.obedit) {
retopo_matrix_update(G.vd);
draw_em_fancy_verts(em, cageDM);
if(G.f & G_DRAWNORMALS) {
@ -2171,6 +2175,9 @@ static int draw_mesh_object(Base *base, int dt, int flag)
if (cageNeedsFree) cageDM->release(cageDM);
if (finalNeedsFree) finalDM->release(finalDM);
}
else if(!G.obedit && G.scene->sculptdata.active_ob == ob) {
sculptmode_draw_mesh(NULL);
}
else {
/* don't create boundbox here with mesh_get_bb(), the derived system will make it, puts deformed bb's OK */
@ -3069,6 +3076,8 @@ static void drawnurb(Base *base, Nurb *nurb, int dt)
Nurb *nu;
BevList *bl;
retopo_matrix_update(G.vd);
/* DispList */
BIF_ThemeColor(TH_WIRE);
drawDispList(base, dt);
@ -3956,6 +3965,7 @@ void draw_object(Base *base, int flag)
}
}
}
/* draw-extra supported for boundbox drawmode too */
if(dt>=OB_BOUNDBOX ) {

@ -110,6 +110,7 @@
#include "BIF_poseobject.h"
#include "BIF_previewrender.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
@ -121,6 +122,7 @@
#include "BDR_drawobject.h"
#include "BDR_editobject.h"
#include "BDR_vpaint.h"
#include "BDR_sculptmode.h"
#include "BSE_drawview.h"
#include "BSE_filesel.h"
@ -142,6 +144,8 @@
#include "RE_pipeline.h" // make_stars
#include "multires.h"
/* Modules used */
#include "radio.h"
@ -1192,6 +1196,9 @@ ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax)
dr++;
}
ibuf->ftype= PNG;
IMB_saveiff(ibuf, "/tmp/rt.png", IB_rect);
/* put clipped result back, if needed */
if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax)
return ibuf;
@ -2217,8 +2224,12 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
/* (ton) can't use the rename trick for paint... panel names and settings are stored in the files and
used to find previous locations when re-open. This causes flipping */
if(uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 204)==0) return;
if((G.f & G_SCULPTMODE) && !G.obedit) {
if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 425, 234)) return;
} else {
if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 204)) return;
}
if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
@ -2260,7 +2271,10 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
/* 'f' is for floating panel */
uiBlockPickerButtons(block, rgb, hsv, old, hexcol, 'f', REDRAWBUTSEDIT);
}
else {
else if(G.f & G_SCULPTMODE) {
sculptmode_draw_interface_tools(block,10,150);
sculptmode_draw_interface_textures(block,220,150);
} else {
BoundBox *bb = NULL;
uiBlockBeginAlign(block);
@ -2319,6 +2333,32 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
uiClearButLock();
}
static void view3d_panel_multires(short cntrl) // VIEW3D_HANDLER_MULTIRES
{
uiBlock *block;
uiBut *but;
Object *ob= OBACT;
if(!ob || ob->type!=OB_MESH) return;
block= uiNewBlock(&curarea->uiblocks, "view3d_panel_multires", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(VIEW3D_HANDLER_MULTIRES); // for close and esc
if(!uiNewPanel(curarea, block, "Multires Properties", "View3d", 10, 230, 220, 200)) return;
if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
if(get_mesh(ob)->mr)
multires_draw_interface(block, 5,100);
else {
but= uiDefBut(block,BUT,B_NOP,"Make Multires", 5,100,120,19,0,0,0,0,0,"Adds multires data to mesh");
uiButSetFunc(but,multires_make,ob,get_mesh(ob));
}
uiClearButLock();
}
static void view3d_panel_background(short cntrl) // VIEW3D_HANDLER_BACKGROUND
{
uiBlock *block;
@ -2516,6 +2556,9 @@ static void view3d_blockhandlers(ScrArea *sa)
case VIEW3D_HANDLER_PREVIEW:
view3d_panel_preview(sa, v3d->blockhandler[a+1]);
break;
case VIEW3D_HANDLER_MULTIRES:
view3d_panel_multires(v3d->blockhandler[a+1]);
break;
}
/* clear action value for event */
@ -2636,6 +2679,35 @@ static void draw_dupli_objects(View3D *v3d, Base *base)
}
void view3d_update_depths(View3D *v3d)
{
/* Create storage for, and, if necessary, copy depth buffer */
if(!v3d->depths) v3d->depths= MEM_callocN(sizeof(ViewDepths),"ViewDepths");
if(v3d->depths) {
ViewDepths *d= v3d->depths;
if(d->w != v3d->area->winx ||
d->h != v3d->area->winy) {
d->w= v3d->area->winx;
d->h= v3d->area->winy;
if(d->depths)
MEM_freeN(d->depths);
d->depths= MEM_mallocN(sizeof(float)*d->w*d->h,"View depths");
d->damaged= 1;
}
if(d->damaged) {
glReadBuffer(GL_FRONT);
glReadPixels(v3d->area->winrct.xmin,v3d->area->winrct.ymin,d->w,d->h,
GL_DEPTH_COMPONENT,GL_FLOAT, d->depths);
glReadBuffer(GL_BACK);
glGetDoublev(GL_DEPTH_RANGE,d->depth_range);
d->damaged= 0;
}
}
}
void drawview3dspace(ScrArea *sa, void *spacedata)
{
View3D *v3d= spacedata;
@ -2764,6 +2836,10 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
}
}
}
if(retopo_mesh_check() || retopo_curve_check())
view3d_update_depths(v3d);
/* draw selected and editmode */
for(base= G.scene->base.first; base; base= base->next) {
if(v3d->lay & base->lay) {
@ -2772,6 +2848,9 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
}
}
if(!(retopo_mesh_check() || retopo_curve_check()) && (G.f & G_SCULPTMODE))
view3d_update_depths(v3d);
if(G.moving) {
BIF_drawConstraint();
if(G.obedit) BIF_drawPropCircle(); // only editmode has proportional edit
@ -2794,7 +2873,47 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
}
persp(PERSP_WIN); // set ortho
/* Draw Sculpt Mode brush */
if(!G.obedit && (G.f & G_SCULPTMODE)) {
PropsetData *pd = G.scene->sculptdata.propset_data;
const short r= sculptmode_brush()->size;
if(pd) {
/* Draw brush with texture */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, pd->tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glColor4f(0,0,0,1);
glTexCoord2f(0,0);
glVertex2f(pd->origloc[0]-r, pd->origloc[1]-r);
glTexCoord2f(1,0);
glVertex2f(pd->origloc[0]+r, pd->origloc[1]-r);
glTexCoord2f(1,1);
glVertex2f(pd->origloc[0]+r, pd->origloc[1]+r);
glTexCoord2f(0,1);
glVertex2f(pd->origloc[0]-r, pd->origloc[1]+r);
glEnd();
glDisable(GL_TEXTURE_2D);
if(pd->origsize != r)
fdrawXORcirc(pd->origloc[0], pd->origloc[1], pd->origsize);
fdrawXORcirc(pd->origloc[0], pd->origloc[1], r);
} else {
short c[2];
getmouseco_areawin(c);
fdrawXORcirc((float)c[0], (float)c[1], r);
}
}
retopo_draw_paint_lines();
if(v3d->persp>1) drawviewborder();
if(v3d->flag2 & V3D_FLYMODE) drawviewborder_flymode();
if(!(G.f & G_PLAYANIM)) drawcursor(v3d);
@ -2841,7 +2960,6 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
!during_script()) {
BPY_do_pyscript((ID *)G.scene, SCRIPT_REDRAW);
}
}

@ -81,6 +81,7 @@
#include "BIF_mywindow.h"
#include "BIF_interface.h"
#include "BIF_transform.h"
#include "BIF_retopo.h"
#include "BSE_view.h" /* For persp... */
#include "BSE_edit.h"
@ -2710,6 +2711,8 @@ void addvert_Nurb(int mode)
}
}
retopo_do_all(0,0);
test2DNurb(nu);
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
countall();

@ -84,6 +84,7 @@
#include "BIF_interface.h"
#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
#include "BIF_retopo.h"
#include "BIF_space.h"
#include "BIF_screen.h"
#include "BIF_toolbox.h"
@ -605,6 +606,8 @@ void free_editMesh(EditMesh *em)
mesh_octree_table(NULL, NULL, 'e');
G.totvert= G.totface= 0;
if(em->retopo_paint_data) retopo_free_paint_data(em->retopo_paint_data);
}
/* on G.editMesh */
@ -1806,6 +1809,8 @@ typedef struct UndoMesh {
TFace *tfaces;
int totvert, totedge, totface,totsel;
short selectmode;
RetopoPaintData *retopo_paint_data;
char retopo_mode;
} UndoMesh;
@ -1826,6 +1831,7 @@ static void free_undoMesh(void *umv)
if(um->faces) MEM_freeN(um->faces);
if(um->tfaces) MEM_freeN(um->tfaces);
if(um->selected) MEM_freeN(um->selected);
if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
MEM_freeN(um);
}
@ -1922,6 +1928,9 @@ static void *editMesh_to_undoMesh(void)
else if(ese->type == EDITEDGE) a = esec->index = ((EditEdge*)ese->data)->tmp.l;
else if(ese->type == EDITFACE) a = esec->index = ((EditFace*)ese->data)->tmp.l;
}
um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
um->retopo_mode= em->retopo_mode;
return um;
}
@ -2028,6 +2037,9 @@ static void undoMesh_to_editMesh(void *umv)
EM_free_index_arrays();
}
retopo_free_paint();
em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
em->retopo_mode= um->retopo_mode;
}

@ -590,6 +590,53 @@ static void fix_new_face(EditFace *eface)
}
}
void addfaces_from_edgenet()
{
EditVert *eve1, *eve2, *eve3, *eve4;
EditMesh *em= G.editMesh;
for(eve1= em->verts.first; eve1; eve1= eve1->next) {
for(eve2= em->verts.first; (eve1->f & 1) && eve2; eve2= eve2->next) {
if(findedgelist(eve1,eve2)) {
for(eve3= em->verts.first; eve3; eve3= eve3->next) {
if((eve2!=eve3 && findedgelist(eve1,eve3))) {
EditEdge *sh_edge= NULL;
EditVert *sh_vert= NULL;
sh_edge= findedgelist(eve2,eve3);
if(sh_edge) { /* Add a triangle */
if(!exist_face_overlaps(eve1,eve2,eve3,NULL))
fix_new_face(addfacelist(eve1,eve2,eve3,NULL,NULL,NULL));
}
else { /* Check for a shared vertex */
for(eve4= em->verts.first; eve4; eve4= eve4->next) {
if(eve4!=eve1 && eve4!=eve2 && eve4!=eve3 &&
!findedgelist(eve1,eve4) && findedgelist(eve2,eve4) &&
findedgelist(eve3,eve4)) {
sh_vert= eve4;
break;
}
}
if(sh_vert) {
if(sh_vert) {
if(!exist_face_overlaps(eve1,eve2,eve4,eve3))
fix_new_face(addfacelist(eve1,eve2,eve4,eve3,NULL,NULL));
}
}
}
}
}
}
}
}
countall();
EM_select_flush();
}
void addedgeface_mesh(void)
{
EditMesh *em = G.editMesh;

@ -138,6 +138,7 @@
#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
@ -156,6 +157,7 @@
#include "BSE_editipo_types.h"
#include "BDR_vpaint.h"
#include "BDR_sculptmode.h"
#include "BDR_editface.h"
#include "BDR_editmball.h"
#include "BDR_editobject.h"
@ -262,6 +264,8 @@ void delete_obj(int ok)
if(G.obedit) return;
if(G.scene->id.lib) return;
if(G.f & G_SCULPTMODE) set_sculptmode();
base= FIRSTBASE;
while(base) {
@ -1507,12 +1511,15 @@ void enter_editmode(int wc)
if(wc) waitcursor(1);
if(ob->type==OB_MESH) {
if(G.f & G_SCULPTMODE) set_sculpt_object(NULL);
me= get_mesh(ob);
if( me==0 ) return;
if(me->id.lib) {
error("Can't edit library data");
return;
}
if(me->pv) sculptmode_pmv_off(me);
ok= 1;
G.obedit= ob;
make_editMesh();
@ -1585,6 +1592,8 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b
/* temporal */
countall();
retopo_end_okee();
if(G.totvert>MESH_MAX_VERTS) {
error("Too many vertices");
return;
@ -1636,6 +1645,9 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b
/* also flush ob recalc, doesn't take much overhead, but used for particles */
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
if(G.f & G_SCULPTMODE)
set_sculpt_object(ob);
if(freedata) {
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
}

@ -176,6 +176,7 @@ static int choose_cursor(ScrArea *sa)
else if(G.f & G_VERTEXPAINT) return CURSOR_VPAINT;
else if(G.f & G_WEIGHTPAINT) return CURSOR_VPAINT;
else if(G.f & G_FACESELECT) return CURSOR_FACESEL;
else if(G.f & G_SCULPTMODE) return CURSOR_EDIT;
else return CURSOR_STD;
}
else if (sa->spacetype==SPACE_TEXT) {

@ -90,6 +90,7 @@
#include "BIF_toolbox.h"
#include "BDR_editobject.h" /* For headerprint */
#include "BDR_sculptmode.h"
#include "BDR_vpaint.h"
#include "BDR_editface.h"
#include "BDR_drawobject.h"
@ -1073,6 +1074,10 @@ void set_active_base(Base *base)
DAG_object_flush_update(G.scene, tbase->object, OB_RECALC_DATA);
}
}
if(base->object->type==OB_MESH && G.f & G_SCULPTMODE) {
set_sculpt_object(base->object);
}
}
}
@ -1416,6 +1421,9 @@ void mouse_select(void)
/* selecting a non-mesh, should end a couple of modes... */
if(basact->object->type!=OB_MESH) {
if(G.f & G_SCULPTMODE) {
set_sculptmode();
}
if(G.f & G_WEIGHTPAINT) {
set_wpaint(); /* toggle */
}

@ -137,6 +137,20 @@ void sdrawXORline4(int nr, int x0, int y0, int x1, int y1)
set_inverted_drawing(0);
}
void fdrawXORellipse(float xofs, float yofs, float hw, float hh)
{
if(hw==0) return;
set_inverted_drawing(1);
glPushMatrix();
glTranslatef(xofs, yofs, 0.0);
glScalef(1,hh/hw,1);
glutil_draw_lined_arc(0.0, M_PI*2.0, hw, 20);
glPopMatrix();
set_inverted_drawing(0);
}
void fdrawXORcirc(float xofs, float yofs, float rad)
{
set_inverted_drawing(1);

@ -323,10 +323,17 @@ void buttons_active_id(ID **id, ID **idfrom)
}
}
else if(G.buts->texfrom==3) {
Brush *brush= G.scene->toolsettings->imapaint.brush;
if (brush) {
mtex= brush->mtex[brush->texact];
if(mtex) *id= (ID*)mtex->tex;
if(G.f & G_SCULPTMODE) {
if(G.scene->sculptdata.texact != -1) {
mtex= G.scene->sculptdata.mtex[G.scene->sculptdata.texact];
if(mtex) *id= (ID*)mtex->tex;
}
} else {
Brush *brush= G.scene->toolsettings->imapaint.brush;
if (brush) {
mtex= brush->mtex[brush->texact];
if(mtex) *id= (ID*)mtex->tex;
}
}
}
}

@ -75,6 +75,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BSE_edit.h"
#include "BSE_editipo.h"
@ -86,6 +87,7 @@
#include "BDR_editface.h"
#include "BDR_editmball.h"
#include "BDR_editobject.h"
#include "BDR_sculptmode.h"
#include "BDR_imagepaint.h"
#include "BDR_vpaint.h"
@ -105,6 +107,7 @@
#include "BIF_poseobject.h"
#include "BIF_renderwin.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toets.h"
@ -135,6 +138,7 @@
#define V3D_OBJECTMODE_SEL ICON_OBJECT
#define V3D_EDITMODE_SEL ICON_EDITMODE_HLT
#define V3D_SCULPTMODE_SEL ICON_SCULPTMODE_HLT
#define V3D_FACESELECTMODE_SEL ICON_FACESEL_HLT
#define V3D_VERTEXPAINTMODE_SEL ICON_VPAINT_HLT
#define V3D_TEXTUREPAINTMODE_SEL ICON_TPAINT_HLT
@ -2165,6 +2169,9 @@ static void do_view3d_edit_objectmenu(void *arg, int event)
case 17: /* Transform snap to grid */
G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
break;
case 18:
add_blockhandler(curarea, VIEW3D_HANDLER_MULTIRES, 0);
break;
}
allqueue(REDRAWVIEW3D, 0);
}
@ -2197,6 +2204,7 @@ static uiBlock *view3d_edit_objectmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 15, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Multires Properties", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 18, "");
uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_object_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, menuwidth, 19, "");
@ -2731,6 +2739,9 @@ static void do_view3d_edit_meshmenu(void *arg, int event)
if(session) b_verse_push_object(session, G.obedit);
break;
#endif
case 14:
add_blockhandler(curarea, VIEW3D_HANDLER_MULTIRES, 0);
break;
case 17: /* Transform snap to grid */
G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
break;
@ -2767,6 +2778,7 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Transform Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Multires Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
@ -3764,7 +3776,6 @@ static void do_view3d_vpaintmenu(void *arg, int event)
allqueue(REDRAWVIEW3D, 0);
}
static uiBlock *view3d_vpaintmenu(void *arg_unused)
{
uiBlock *block;
@ -3889,6 +3900,41 @@ static uiBlock *view3d_wpaintmenu(void *arg_unused)
return block;
}
void do_view3d_sculptmenu(void *arg, int event)
{
short avg= G.scene->sculptdata.averaging;
switch(event) {
case 0: /* Set sculptdata.averaging */
if(button(&avg,1,10,"Averaging:")==0) return;
G.scene->sculptdata.averaging= avg;
break;
}
allqueue(REDRAWVIEW3D, 0);
}
uiBlock *view3d_sculptmenu(void *arg_unused_so_why_have_it/*?*/)
{
uiBlock *block;
short yco= 0, menuwidth= 120;
block= uiNewBlock(&curarea->uiblocks, "view3d_sculptmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_view3d_sculptmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mouse averaging", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
if(curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
}
else {
uiBlockSetDirection(block, UI_TOP);
uiBlockFlipOrder(block);
}
uiTextBoundsBlock(block, 50);
return block;
}
static void do_view3d_facesel_propertiesmenu(void *arg, int event)
{
@ -4172,7 +4218,8 @@ static char *view3d_modeselect_pup(void)
}
if (ob->type == OB_MESH) {
str += sprintf(str, formatstr, "Sculpt Mode", V3D_SCULPTMODE_SEL, ICON_SCULPTMODE_HLT);
str += sprintf(str, formatstr, "UV Face Select", V3D_FACESELECTMODE_SEL, ICON_FACESEL_HLT);
str += sprintf(str, formatstr, "Vertex Paint", V3D_VERTEXPAINTMODE_SEL, ICON_VPAINT_HLT);
str += sprintf(str, formatstr, "Texture Paint", V3D_TEXTUREPAINTMODE_SEL, ICON_TPAINT_HLT);
@ -4316,6 +4363,7 @@ void do_view3d_buttons(short event)
if (G.vd->modeselect == V3D_OBJECTMODE_SEL) {
G.vd->flag &= ~V3D_MODE;
if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
@ -4326,6 +4374,7 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_EDITMODE_SEL) {
if(!G.obedit) {
G.vd->flag &= ~V3D_MODE;
if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
@ -4334,6 +4383,18 @@ void do_view3d_buttons(short event)
BIF_undo_push("Original"); /* here, because all over code enter_editmode is abused */
}
}
else if (G.vd->modeselect == V3D_SCULPTMODE_SEL) {
if (!(G.f & G_SCULPTMODE)) {
G.vd->flag &= ~V3D_MODE;
if(G.f & G_FACESELECT) set_faceselect(); /* Switch off face select */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
set_sculptmode();
}
}
else if (G.vd->modeselect == V3D_FACESELECTMODE_SEL) {
if ((G.obedit) && (G.f & G_FACESELECT)) {
exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
@ -4343,6 +4404,7 @@ void do_view3d_buttons(short event)
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
} else {
G.vd->flag &= ~V3D_MODE;
if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
@ -4354,6 +4416,7 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_VERTEXPAINTMODE_SEL) {
if (!(G.f & G_VERTEXPAINT)) {
G.vd->flag &= ~V3D_MODE;
if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
if(G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
@ -4364,6 +4427,7 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_TEXTUREPAINTMODE_SEL) {
if (!(G.f & G_TEXTUREPAINT)) {
G.vd->flag &= ~V3D_MODE;
if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
if(G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
@ -4374,6 +4438,7 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_WEIGHTPAINTMODE_SEL) {
if (!(G.f & G_WEIGHTPAINT) && (ob && ob->type == OB_MESH) ) {
G.vd->flag &= ~V3D_MODE;
if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
@ -4590,6 +4655,11 @@ static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
uiDefPulldownBut(block, view3d_tpaintmenu, NULL, "Paint", xco,-2, xmax-3, 24, "");
xco+= xmax;
}
else if( G.f & G_SCULPTMODE) {
xmax= GetButStringLength("Sculpt");
uiDefPulldownBut(block, view3d_sculptmenu, NULL, "Sculpt", xco, -2, xmax-3, 24, "");
xco+= xmax;
}
else if (G.f & G_FACESELECT) {
if (ob && ob->type == OB_MESH) {
xmax= GetButStringLength("Face");
@ -4654,6 +4724,7 @@ void view3d_buttons(void)
if (G.obedit) G.vd->modeselect = V3D_EDITMODE_SEL;
else if(ob && (ob->flag & OB_POSEMODE)) G.vd->modeselect = V3D_POSEMODE_SEL;
else if (G.f & G_SCULPTMODE) G.vd->modeselect = V3D_SCULPTMODE_SEL;
else if (G.f & G_WEIGHTPAINT) G.vd->modeselect = V3D_WEIGHTPAINTMODE_SEL;
else if (G.f & G_VERTEXPAINT) G.vd->modeselect = V3D_VERTEXPAINTMODE_SEL;
else if (G.f & G_TEXTUREPAINT) G.vd->modeselect = V3D_TEXTUREPAINTMODE_SEL;
@ -4679,123 +4750,152 @@ void view3d_buttons(void)
/* around */
xco+= XIC+18;
/* Show wireframe for sculptmode */
if(!G.obedit && G.f & G_SCULPTMODE && ob) {
uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", xco,0,30,20, &ob->dtx, 0,0,0,0, "Adds the active object's wireframe over solid drawing");
xco+= 35;
uiDefButC(block, TOG, B_NOP, "PvRot", xco,0,40,20,&G.vd->pivot_last, 0,0,0,0, "Rotate around the center of the last brush action");
xco+= 40;
}
uiBlockBeginAlign(block);
uiDefIconTextButS(block, ICONTEXTROW,B_AROUND, ICON_ROTATE, around_pup(), xco,0,XIC+10,YIC, &(G.vd->around), 0, 3.0, 0, 0, "Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period) ");
xco+= XIC+10;
uiDefIconButBitS(block, TOG, V3D_ALIGN, B_AROUND, ICON_ALIGN,
xco,0,XIC,YIC,
&G.vd->flag, 0, 0, 0, 0, "Move object centers only");
uiBlockEndAlign(block);
xco+= XIC+8;
if(retopo_mesh_paint_check()) {
RetopoPaintData *rpd= get_retopo_paint_data();
if(rpd) {
uiDefButC(block,ROW,B_NOP,"Pen",xco,0,40,20,&rpd->mode,6.0,RETOPO_PEN,0,0,"");
xco+=40;
uiDefButC(block,ROW,B_NOP,"Line",xco,0,40,20,&rpd->mode,6.0,RETOPO_LINE,0,0,"");
xco+=40;
uiDefButC(block,ROW,B_NOP,"Ellipse",xco,0,60,20,&rpd->mode,6.0,RETOPO_ELLIPSE,0,0,"");
xco+=65;
uiBlockBeginAlign(block);
uiDefButC(block,NUM,B_NOP,"LineDiv",xco,0,80,20,&rpd->line_div,1,50,0,0,"How much to subdivide each line made with the Line tool");
xco+=80;
uiDefButC(block,NUM,B_NOP,"EllDiv",xco,0,80,20,&rpd->ellipse_div,3,50,0,0,"How much to subdivide each ellipse made with the Ellipse tool");
xco+=85;
uiBlockEndAlign(block);
}
} else {
uiDefIconTextButS(block, ICONTEXTROW,B_AROUND, ICON_ROTATE, around_pup(), xco,0,XIC+10,YIC, &(G.vd->around), 0, 3.0, 0, 0, "Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period) ");
/* Transform widget / manipulators */
uiBlockBeginAlign(block);
uiDefIconButBitS(block, TOG, V3D_USE_MANIPULATOR, B_REDR, ICON_MANIPUL,xco,0,XIC,YIC, &G.vd->twflag, 0, 0, 0, 0, "Use 3d transform manipulator (Ctrl Space)");
xco+= XIC;
if(G.vd->twflag & V3D_USE_MANIPULATOR) {
uiDefIconButBitS(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode (Ctrl Alt G)");
xco+= XIC;
uiDefIconButBitS(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode (Ctrl Alt R)");
xco+= XIC;
uiDefIconButBitS(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode (Ctrl Alt S)");
xco+= XIC;
}
uiDefButS(block, MENU, B_NOP, "Orientation%t|Global%x0|Local%x1|Normal%x2|View%x3",xco,0,70,YIC, &G.vd->twmode, 0, 0, 0, 0, "Transform Orientation (Alt Space)");
xco+= 70;
uiBlockEndAlign(block);
xco+= 8;
/* LAYERS */
if(G.obedit==NULL && G.vd->localview==0) {
uiBlockBeginAlign(block);
for(a=0; a<5; a++)
uiDefButBitI(block, TOG, 1<<a, B_LAY+a, "", (short)(xco+a*(XIC/2)), (short)(YIC/2),(short)(XIC/2),(short)(YIC/2), &(G.vd->lay), 0, 0, 0, 0, "Toggles Layer visibility (Num, Shift Num)");
for(a=0; a<5; a++)
uiDefButBitI(block, TOG, 1<<(a+10), B_LAY+10+a, "",(short)(xco+a*(XIC/2)), 0, XIC/2, (YIC)/2, &(G.vd->lay), 0, 0, 0, 0, "Toggles Layer visibility (Alt Num, Alt Shift Num)");
xco+= 5;
uiBlockBeginAlign(block);
for(a=5; a<10; a++)
uiDefButBitI(block, TOG, 1<<a, B_LAY+a, "", (short)(xco+a*(XIC/2)), (short)(YIC/2),(short)(XIC/2),(short)(YIC/2), &(G.vd->lay), 0, 0, 0, 0, "Toggles Layer visibility (Num, Shift Num)");
for(a=5; a<10; a++)
uiDefButBitI(block, TOG, 1<<(a+10), B_LAY+10+a, "",(short)(xco+a*(XIC/2)), 0, XIC/2, (YIC)/2, &(G.vd->lay), 0, 0, 0, 0, "Toggles Layer visibility (Alt Num, Alt Shift Num)");
uiBlockEndAlign(block);
xco+= (a-2)*(XIC/2)+3;
/* LOCK */
uiDefIconButS(block, ICONTOG, B_SCENELOCK, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.vd->scenelock), 0, 0, 0, 0, "Locks layers and used Camera to Scene (Ctrl `)");
xco+= XIC+10;
}
/* proportional falloff */
if(G.obedit && (G.obedit->type == OB_MESH || G.obedit->type == OB_CURVE || G.obedit->type == OB_SURF || G.obedit->type == OB_LATTICE)) {
uiBlockBeginAlign(block);
uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF, "Proportional %t|Off %x0|On %x1|Connected %x2", xco,0,XIC+10,YIC, &(G.scene->proportional), 0, 1.0, 0, 0, "Proportional Edit Falloff (Hotkeys: O, Alt O) ");
xco+= XIC+10;
if(G.scene->proportional) {
uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SMOOTHCURVE, propfalloff_pup(), xco,0,XIC+10,YIC, &(G.scene->prop_mode), 0.0, 0.0, 0, 0, "Proportional Edit Falloff (Hotkey: Shift O) ");
xco+= XIC+10;
}
xco+= 10;
}
/* selection modus */
if(G.obedit && (G.obedit->type == OB_MESH)) {
uiBlockBeginAlign(block);
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode (Ctrl Tab 1)");
xco+= XIC;
uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode (Ctrl Tab 2)");
xco+= XIC;
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)");
xco+= XIC;
uiDefIconButBitS(block, TOG, V3D_ALIGN, B_AROUND, ICON_ALIGN,
xco,0,XIC,YIC,
&G.vd->flag, 0, 0, 0, 0, "Move object centers only");
uiBlockEndAlign(block);
if(G.vd->drawtype > OB_WIRE) {
uiDefIconButBitS(block, TOG, V3D_ZBUF_SELECT, B_REDR, ICON_ORTHO, xco,0,XIC,YIC, &G.vd->flag, 1.0, 0.0, 0, 0, "Limit selection to visible (clipped with depth buffer)");
xco+= XIC+8;
/* Transform widget / manipulators */
uiBlockBeginAlign(block);
uiDefIconButBitS(block, TOG, V3D_USE_MANIPULATOR, B_REDR, ICON_MANIPUL,xco,0,XIC,YIC, &G.vd->twflag, 0, 0, 0, 0, "Use 3d transform manipulator (Ctrl Space)");
xco+= XIC;
if(G.vd->twflag & V3D_USE_MANIPULATOR) {
uiDefIconButBitS(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode (Ctrl Alt G)");
xco+= XIC;
uiDefIconButBitS(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode (Ctrl Alt R)");
xco+= XIC;
uiDefIconButBitS(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode (Ctrl Alt S)");
xco+= XIC;
}
xco+= 20;
}
uiDefIconBut(block, BUT, B_VIEWRENDER, ICON_SCENE_DEHLT, xco,0,XIC,YIC, NULL, 0, 1.0, 0, 0, "Render this window (hold CTRL for anim)");
if (ob && (ob->flag & OB_POSEMODE)) {
xco+= XIC/2;
uiBlockBeginAlign(block);
if(curarea->headertype==HEADERTOP) {
uiDefIconBut(block, BUT, B_ACTCOPY, ICON_COPYUP,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Copies the current pose to the buffer");
uiSetButLock(ob->id.lib!=0, "Can't edit library data");
uiDefIconBut(block, BUT, B_ACTPASTE, ICON_PASTEUP,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Pastes the pose from the buffer");
uiDefIconBut(block, BUT, B_ACTPASTEFLIP, ICON_PASTEFLIPUP,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Pastes the mirrored pose from the buffer");
}
else {
uiDefIconBut(block, BUT, B_ACTCOPY, ICON_COPYDOWN,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Copies the current pose to the buffer");
uiSetButLock(ob->id.lib!=0, "Can't edit library data");
uiDefIconBut(block, BUT, B_ACTPASTE, ICON_PASTEDOWN,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Pastes the pose from the buffer");
uiDefIconBut(block, BUT, B_ACTPASTEFLIP, ICON_PASTEFLIPDOWN,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Pastes the mirrored pose from the buffer");
}
uiDefButS(block, MENU, B_NOP, "Orientation%t|Global%x0|Local%x1|Normal%x2|View%x3",xco,0,70,YIC, &G.vd->twmode, 0, 0, 0, 0, "Transform Orientation (Alt Space)");
xco+= 70;
uiBlockEndAlign(block);
xco+= 8;
/* LAYERS */
if(G.obedit==NULL && G.vd->localview==0) {
uiBlockBeginAlign(block);
for(a=0; a<5; a++)
uiDefButBitI(block, TOG, 1<<a, B_LAY+a, "", (short)(xco+a*(XIC/2)), (short)(YIC/2),(short)(XIC/2),(short)(YIC/2), &(G.vd->lay), 0, 0, 0, 0, "Toggles Layer visibility (Num, Shift Num)");
for(a=0; a<5; a++)
uiDefButBitI(block, TOG, 1<<(a+10), B_LAY+10+a, "",(short)(xco+a*(XIC/2)), 0, XIC/2, (YIC)/2, &(G.vd->lay), 0, 0, 0, 0, "Toggles Layer visibility (Alt Num, Alt Shift Num)");
xco+= 5;
uiBlockBeginAlign(block);
for(a=5; a<10; a++)
uiDefButBitI(block, TOG, 1<<a, B_LAY+a, "", (short)(xco+a*(XIC/2)), (short)(YIC/2),(short)(XIC/2),(short)(YIC/2), &(G.vd->lay), 0, 0, 0, 0, "Toggles Layer visibility (Num, Shift Num)");
for(a=5; a<10; a++)
uiDefButBitI(block, TOG, 1<<(a+10), B_LAY+10+a, "",(short)(xco+a*(XIC/2)), 0, XIC/2, (YIC)/2, &(G.vd->lay), 0, 0, 0, 0, "Toggles Layer visibility (Alt Num, Alt Shift Num)");
uiBlockEndAlign(block);
xco+= (a-2)*(XIC/2)+3;
/* LOCK */
uiDefIconButS(block, ICONTOG, B_SCENELOCK, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.vd->scenelock), 0, 0, 0, 0, "Locks layers and used Camera to Scene (Ctrl `)");
xco+= XIC+10;
}
/* proportional falloff */
if(G.obedit && (G.obedit->type == OB_MESH || G.obedit->type == OB_CURVE || G.obedit->type == OB_SURF || G.obedit->type == OB_LATTICE)) {
uiBlockBeginAlign(block);
uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF, "Proportional %t|Off %x0|On %x1|Connected %x2", xco,0,XIC+10,YIC, &(G.scene->proportional), 0, 1.0, 0, 0, "Proportional Edit Falloff (Hotkeys: O, Alt O) ");
xco+= XIC+10;
if(G.scene->proportional) {
uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SMOOTHCURVE, propfalloff_pup(), xco,0,XIC+10,YIC, &(G.scene->prop_mode), 0.0, 0.0, 0, 0, "Proportional Edit Falloff (Hotkey: Shift O) ");
xco+= XIC+10;
}
xco+= 10;
}
/* selection modus */
if(G.obedit && (G.obedit->type == OB_MESH)) {
uiBlockBeginAlign(block);
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode (Ctrl Tab 1)");
xco+= XIC;
uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode (Ctrl Tab 2)");
xco+= XIC;
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)");
xco+= XIC;
uiBlockEndAlign(block);
if(G.vd->drawtype > OB_WIRE) {
uiDefIconButBitS(block, TOG, V3D_ZBUF_SELECT, B_REDR, ICON_ORTHO, xco,0,XIC,YIC, &G.vd->flag, 1.0, 0.0, 0, 0, "Limit selection to visible (clipped with depth buffer)");
xco+= XIC;
}
xco+= 20;
}
uiDefIconBut(block, BUT, B_VIEWRENDER, ICON_SCENE_DEHLT, xco,0,XIC,YIC, NULL, 0, 1.0, 0, 0, "Render this window (hold CTRL for anim)");
if (ob && (ob->flag & OB_POSEMODE)) {
xco+= XIC/2;
uiBlockBeginAlign(block);
if(curarea->headertype==HEADERTOP) {
uiDefIconBut(block, BUT, B_ACTCOPY, ICON_COPYUP,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Copies the current pose to the buffer");
uiSetButLock(ob->id.lib!=0, "Can't edit library data");
uiDefIconBut(block, BUT, B_ACTPASTE, ICON_PASTEUP,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Pastes the pose from the buffer");
uiDefIconBut(block, BUT, B_ACTPASTEFLIP, ICON_PASTEFLIPUP,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Pastes the mirrored pose from the buffer");
}
else {
uiDefIconBut(block, BUT, B_ACTCOPY, ICON_COPYDOWN,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Copies the current pose to the buffer");
uiSetButLock(ob->id.lib!=0, "Can't edit library data");
uiDefIconBut(block, BUT, B_ACTPASTE, ICON_PASTEDOWN,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Pastes the pose from the buffer");
uiDefIconBut(block, BUT, B_ACTPASTEFLIP, ICON_PASTEFLIPDOWN,
xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0,
"Pastes the mirrored pose from the buffer");
}
uiBlockEndAlign(block);
}
}
/* Always do this last */

@ -1291,6 +1291,16 @@ void do_global_buttons(unsigned short event)
allqueue(REDRAWOOPS, 0);
allqueue(REDRAWIMAGE, 0);
}
else if(G.buts->mainb==CONTEXT_EDITING) {
SculptData *sd= &G.scene->sculptdata;
if(sd && sd->texact != -1) {
if(sd->mtex[sd->texact]) autotexname(sd->mtex[sd->texact]);
BIF_undo_push("Auto name");
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWOOPS, 0);
}
}
break;
case B_RESETAUTOSAVE:

File diff suppressed because it is too large Load Diff

@ -88,6 +88,7 @@
#include "BIF_toolbox.h"
#include "BIF_writeimage.h"
#include "BDR_sculptmode.h"
#include "BDR_editobject.h"
#include "BPY_extern.h" /* for BPY_do_all_scripts */
@ -1058,6 +1059,7 @@ static void do_render(int anim)
Render *re= RE_NewRender(G.scene->id.name);
unsigned int lay= G.scene->lay;
int scemode= G.scene->r.scemode;
int sculptmode= G.f & G_SCULPTMODE;
/* UGLY! we set this flag to prevent renderwindow queue to execute another render */
/* is reset in RE_BlenderFrame */
@ -1073,6 +1075,8 @@ static void do_render(int anim)
if(G.obedit)
exit_editmode(0); /* 0 = no free data */
if(sculptmode) set_sculptmode();
/* allow localview render for objects with lights in normal layers */
if(curarea->spacetype==SPACE_VIEW3D) {
if(G.vd->lay & 0xFF000000) {
@ -1104,6 +1108,8 @@ static void do_render(int anim)
// }
scene_update_for_newframe(G.scene, G.scene->lay); // no redraw needed, this restores to view as we left it
if(sculptmode) set_sculptmode();
waitcursor(0);
}

831
source/blender/src/retopo.c Normal file

@ -0,0 +1,831 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*
* Implements the Retopo tools
*
* BIF_retopo.h
*
*/
#include "MEM_guardedalloc.h"
#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "BDR_editobject.h"
#include "BIF_editmesh.h"
#include "BIF_editmode_undo.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_mywindow.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BSE_edit.h"
#include "BSE_view.h"
#include "editmesh.h"
#include "mydevice.h"
#ifdef WIN32
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
typedef struct RetopoPaintHit {
struct RetopoPaintHit *next, *prev;
RetopoPaintPoint *intersection;
short index;
float where;
} RetopoPaintHit;
void retopo_do_2d(View3D *v3d, short proj[2], float *v, char adj);
void retopo_paint_debug_print(RetopoPaintData *rpd);
/* Painting */
RetopoPaintData *get_retopo_paint_data()
{
if(!retopo_mesh_paint_check()) return NULL;
if(!G.editMesh) return NULL;
return G.editMesh->retopo_paint_data;
}
char retopo_mesh_paint_check()
{
return retopo_mesh_check() && G.editMesh->retopo_mode==3;
}
void retopo_free_paint_data(RetopoPaintData *rpd)
{
if(rpd) {
RetopoPaintLine *l;
for(l= rpd->lines.first; l; l= l->next) {
BLI_freelistN(&l->points);
BLI_freelistN(&l->hitlist);
}
BLI_freelistN(&rpd->lines);
BLI_freelistN(&rpd->intersections);
MEM_freeN(rpd);
}
}
void retopo_free_paint()
{
retopo_free_paint_data(G.editMesh->retopo_paint_data);
G.editMesh->retopo_paint_data= NULL;
}
char line_intersection_2d(const vec2s *a, const vec2s *b, const vec2s *c, const vec2s *d, vec2s *out,
float *r, float *s)
{
float den;
*r= (a->y - c->y) * (d->x - c->x) - (a->x - c->x) * (d->y - c->y);
*s= (a->y - c->y) * (b->x - a->x) - (a->x - c->x) * (b->y - a->y);
den= (b->x - a->x) * (d->y - c->y) - (b->y - a->y) * (d->x - c->x);
if((a->x==b->x && a->y==b->y) || (c->x==d->x && c->y==d->y)) return 0;
if(!den) return 0;
*r/= den;
*s/= den;
if(*s<0 || *s>=1 || *r<0 || *r>=1) return 0;
out->x= a->x + *r*(b->x - a->x);
out->y= a->y + *r*(b->y - a->y);
return 1;
}
void retopo_paint_add_line_hit(RetopoPaintLine *l, RetopoPaintPoint *p, RetopoPaintPoint *intersection, float w)
{
RetopoPaintHit *prev, *hit= MEM_callocN(sizeof(RetopoPaintHit),"RetopoPaintHit");
hit->intersection= intersection;
hit->index= p->index;
hit->where= w;
prev= l->hitlist.first;
if(!prev) {
BLI_addtail(&l->hitlist,hit);
}
else if(prev->index>hit->index) {
BLI_addhead(&l->hitlist,hit);
}
else {
/* Move forward until we hit the next highest index */
while(prev->next) {
if(prev->next->index > hit->index) break;
prev= prev->next;
}
/* Move backward until we hit the next lowest where */
while(prev->prev && prev->prev->index==prev->index &&
prev->where > hit->where)
prev=prev->prev;
BLI_insertlink(&l->hitlist,prev,hit);
}
/* Removed duplicate intersections */
if(hit->prev && hit->prev->intersection==hit->intersection) {
BLI_freelinkN(&l->hitlist,hit);
}
}
char retopo_paint_add_intersection(RetopoPaintData *rpd, RetopoPaintLine *l1, RetopoPaintPoint *p1,
RetopoPaintLine *l2, RetopoPaintPoint *p2, vec2s *out, float r, float s)
{
RetopoPaintPoint *p, *hit;
char found= 0;
for(p=rpd->intersections.first; p; p= p->next) {
if(sqrt(pow(p->loc.x-out->x,2)+pow(p->loc.y-out->y,2))<7) {
found= 1;
break;
}
}
if(!found) {
hit= MEM_callocN(sizeof(RetopoPaintPoint),"Retopo paint intersection");
hit->loc.x= out->x;
hit->loc.y= out->y;
BLI_addtail(&rpd->intersections,hit);
} else {
hit= p;
}
retopo_paint_add_line_hit(l1,p1,hit,r);
retopo_paint_add_line_hit(l2,p2,hit,s);
return !found;
}
/* Returns 1 if a new intersection was added */
char do_line_intersection(RetopoPaintData *rpd, RetopoPaintLine *l1, RetopoPaintPoint *p1,
RetopoPaintLine *l2, RetopoPaintPoint *p2)
{
vec2s out;
float r,s;
if(line_intersection_2d(&p1->loc, &p1->next->loc,
&p2->loc, &p2->next->loc,
&out,&r,&s)) {
if(retopo_paint_add_intersection(rpd,l1,p1,l2,p2,&out,r,s))
return 1;
}
return 0;
}
typedef struct FaceNode {
struct FaceNode *next, *prev;
MFace f;
} FaceNode;
char faces_equal(EditFace *f1, EditFace *f2)
{
return editface_containsVert(f2,f1->v1) &&
editface_containsVert(f2,f1->v2) &&
editface_containsVert(f2,f1->v3) &&
(f1->v4 ? editface_containsVert(f2,f1->v4) : 1);
}
EditFace *addfaceif(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4)
{
EditFace *efa;
for(efa= em->faces.first; efa; efa= efa->next) {
if(editface_containsVert(efa,v1) &&
editface_containsVert(efa,v2) &&
editface_containsVert(efa,v3) &&
(v4 ? editface_containsVert(efa,v4) : 1))
return NULL;
}
return addfacelist(v1,v2,v3,v4,NULL,NULL);
}
void retopo_paint_apply()
{
RetopoPaintData *rpd= G.editMesh->retopo_paint_data;
EditVert *eve;
if(rpd) {
RetopoPaintLine *l1, *l2;
RetopoPaintPoint *p1, *p2;
unsigned hitcount= 0;
unsigned i;
RetopoPaintHit *h;
float hitco[3];
/* Find intersections */
BLI_freelistN(&rpd->intersections);
for(l1= rpd->lines.first; l1; l1= l1->next) {
for(l2= rpd->lines.first; l2; l2= l2->next) {
if(l1!=l2) {
for(p1= l1->points.first; p1 && p1!=l1->points.last; p1= p1->next) {
for(p2= l2->points.first; p2 && p2!=l2->points.last; p2= p2->next) {
if(p1!=p2) {
if(do_line_intersection(rpd,l1,p1,l2,p2))
++hitcount;
}
}
}
}
}
}
/*topoPaintHit *hit;
l1= rpd->lines.first;
for(hit= l1->hitlist.first; hit; hit= hit->next) {
printf("\nhit(%p,%d) ",hit->intersection,hit->index);
}
fflush(stdout);*/
/* Deselect */
for(eve= G.editMesh->verts.first; eve; eve= eve->next)
eve->f &= ~SELECT;
EM_deselect_flush();
for(i=0; i<hitcount; ++i) {
RetopoPaintPoint *intersection= BLI_findlink(&rpd->intersections,i);
retopo_do_2d(G.vd,&intersection->loc.x, hitco, 1);
intersection->eve= addvertlist(hitco);
intersection->eve->f= SELECT;
}
for(l1= rpd->lines.first; l1; l1= l1->next) {
unsigned etcount= BLI_countlist(&l1->hitlist);
if(etcount>=2) {
for(h= l1->hitlist.first; (h && h->next); h= h->next)
addedgelist(h->intersection->eve,h->next->intersection->eve,NULL);
if(etcount>=3 && l1->cyclic)
addedgelist(((RetopoPaintHit*)l1->hitlist.first)->intersection->eve,
((RetopoPaintHit*)l1->hitlist.last)->intersection->eve, NULL);
}
}
addfaces_from_edgenet();
}
retopo_free_paint();
}
void add_rppoint(RetopoPaintLine *l, short x, short y)
{
RetopoPaintPoint *p= MEM_callocN(sizeof(RetopoPaintPoint),"RetopoPaintPoint");
p->loc.x= x;
p->loc.y= y;
BLI_addtail(&l->points,p);
p->index= p->prev?p->prev->index+1:0;
retopo_do_2d(G.vd, &p->loc.x, p->co, 1);
}
RetopoPaintLine *add_rpline(RetopoPaintData *rpd)
{
RetopoPaintLine *l= MEM_callocN(sizeof(RetopoPaintLine),"RetopoPaintLine");
BLI_addtail(&rpd->lines,l);
return l;
}
void retopo_paint_toggle_cyclic(RetopoPaintLine *l)
{
if(!l->cyclic) {
RetopoPaintPoint *pf= l->points.first;
if(pf) {
add_rppoint(l, pf->loc.x, pf->loc.y);
l->cyclic= l->points.last;
}
} else {
BLI_freelinkN(&l->points,l->cyclic);
l->cyclic= NULL;
}
}
void retopo_paint_add_line(RetopoPaintData *rpd, short mouse[2])
{
RetopoPaintLine *l= add_rpline(rpd);
float range[2]= {mouse[0]-rpd->sloc[0],mouse[1]-rpd->sloc[1]};
int i;
/* Add initial point */
add_rppoint(l,rpd->sloc[0],rpd->sloc[1]);
for(i=0; i<rpd->line_div; ++i) {
const float mul= (i+1.0f)/rpd->line_div;
add_rppoint(l,rpd->sloc[0] + range[0]*mul,rpd->sloc[1] + range[1]*mul);
}
allqueue(REDRAWVIEW3D,0);
}
void retopo_paint_add_ellipse(RetopoPaintData *rpd, short mouse[2])
{
int i;
add_rpline(rpd);
for (i=0; i<rpd->ellipse_div; i++) {
float t= (float) i/rpd->ellipse_div;
float cur= t*(M_PI*2);
float w= abs(mouse[0]-rpd->sloc[0]);
float h= abs(mouse[1]-rpd->sloc[1]);
add_rppoint(rpd->lines.last,cos(cur)*w+rpd->sloc[0],sin(cur)*h+rpd->sloc[1]);
}
retopo_paint_toggle_cyclic(rpd->lines.last);
allqueue(REDRAWVIEW3D,0);
}
void retopo_end_okee()
{
if(G.editMesh->retopo_mode==3) {
if(okee("Apply retopo paint?"))
retopo_paint_apply();
else
retopo_free_paint();
G.editMesh->retopo_mode= 1;
}
}
void retopo_paint_toggle(void *a, void *b)
{
if(retopo_mesh_paint_check()) { /* Activate retopo paint */
RetopoPaintData *rpd= MEM_callocN(sizeof(RetopoPaintData),"RetopoPaintData");
G.editMesh->retopo_paint_data= rpd;
rpd->mode= RETOPO_PEN;
rpd->seldist= 15;
rpd->nearest.line= NULL;
rpd->line_div= 25;
rpd->ellipse_div= 25;
} else retopo_end_okee();
BIF_undo_push("Retopo toggle");
allqueue(REDRAWVIEW3D, 1);
}
void retopo_paint_view_update(struct View3D *v3d)
{
RetopoPaintData *rpd= get_retopo_paint_data();
if(rpd) {
RetopoPaintLine *l;
RetopoPaintPoint *p;
double ux, uy, uz;
for(l= rpd->lines.first; l; l= l->next) {
for(p= l->points.first; p; p= p->next) {
gluProject(p->co[0],p->co[1],p->co[2], v3d->retopo_view_data->modelviewmat,
v3d->retopo_view_data->projectionmat,
v3d->retopo_view_data->viewport, &ux, &uy, &uz);
p->loc.x= ux;
p->loc.y= uy;
}
}
}
}
/* Returns 1 if event should be processed by caller, 0 otherwise */
char retopo_paint(const unsigned short event)
{
RetopoPaintData *rpd= get_retopo_paint_data();
if(!event) return 1;
if(rpd) {
RetopoPaintLine *l;
short mouse[2];
char lbut= get_mbut() & L_MOUSE;
getmouseco_areawin(mouse);
if(rpd->in_drag && !lbut) { /* End drag */
rpd->in_drag= 0;
switch(rpd->mode) {
case RETOPO_PEN:
break;
case RETOPO_LINE:
retopo_paint_add_line(rpd, mouse);
break;
case RETOPO_ELLIPSE:
retopo_paint_add_ellipse(rpd, mouse);
break;
}
BIF_undo_push("Retopo paint");
}
switch(event) {
case MOUSEX:
case MOUSEY:
switch(rpd->mode) {
case RETOPO_PEN:
if(rpd->in_drag && rpd->lines.last) {
l= rpd->lines.last;
if(((RetopoPaintPoint*)l->points.last)->loc.x != mouse[0] ||
((RetopoPaintPoint*)l->points.last)->loc.y != mouse[1]) {
add_rppoint(l,mouse[0],mouse[1]);
}
rpd->nearest.line= NULL;
break;
} else { /* Find nearest endpoint */
float sdist;
RetopoPaintLine *l= rpd->lines.first;
RetopoPaintSel n= {NULL,NULL,l,1};
sdist= rpd->seldist + 10;
for(l= rpd->lines.first; l; l= l->next) {
float tdist;
RetopoPaintPoint *p1= l->points.first, *p2= l->points.last;
tdist= sqrt(pow(mouse[0] - p1->loc.x,2)+pow(mouse[1] - p1->loc.y,2));
if(tdist < sdist && tdist < rpd->seldist) {
sdist= tdist;
n.line= l;
n.first= 1;
} else {
tdist= sqrt(pow(mouse[0] - p2->loc.x,2)+pow(mouse[1] - p2->loc.y,2));
if(tdist < sdist && tdist < rpd->seldist) {
sdist= tdist;
n.line= l;
n.first= 0;
}
}
}
if(sdist < rpd->seldist)
rpd->nearest= n;
else rpd->nearest.line= NULL;
}
break;
case RETOPO_LINE:
break;
case RETOPO_ELLIPSE:
break;
}
allqueue(REDRAWVIEW3D,0);
break;
case RETKEY:
case PADENTER:
retopo_paint_apply();
case ESCKEY:
G.editMesh->retopo_mode= 1;
retopo_free_paint();
BIF_undo_push("Retopo toggle");
allqueue(REDRAWVIEW3D, 1);
allqueue(REDRAWBUTSEDIT,0);
break;
case CKEY:
retopo_paint_toggle_cyclic(rpd->lines.last);
allqueue(REDRAWVIEW3D, 0);
break;
case EKEY:
rpd->mode= RETOPO_ELLIPSE;
allqueue(REDRAWBUTSEDIT, 0);
break;
case PKEY:
rpd->mode= RETOPO_PEN;
allqueue(REDRAWBUTSEDIT, 0);
break;
case LEFTMOUSE:
if(!rpd->in_drag) { /* Start new drag */
rpd->in_drag= 1;
/* Location of mouse down */
rpd->sloc[0]= mouse[0];
rpd->sloc[1]= mouse[1];
switch(rpd->mode) {
case RETOPO_PEN:
if(rpd->nearest.line) {
RetopoPaintPoint *p, *pt;
int i;
BLI_remlink(&rpd->lines,rpd->nearest.line);
BLI_addtail(&rpd->lines,rpd->nearest.line);
/* Check if we need to reverse the line */
if(rpd->nearest.first) {
for(p= rpd->nearest.line->points.first; p; p= p->prev) {
pt= p->prev;
p->prev= p->next;
p->next= pt;
}
pt= rpd->nearest.line->points.first;
rpd->nearest.line->points.first= rpd->nearest.line->points.last;
rpd->nearest.line->points.last= pt;
/* Reverse indices */
i= 0;
for(p= rpd->nearest.line->points.first; p; p= p->next)
p->index= i++;
}
} else {
add_rpline(rpd);
add_rppoint(rpd->lines.last,mouse[0],mouse[1]);
}
break;
case RETOPO_LINE:
break;
case RETOPO_ELLIPSE:
break;
}
}
break;
case MIDDLEMOUSE:
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
return 1;
}
return 0;
} else return 1;
}
void retopo_draw_paint_lines()
{
RetopoPaintData *rpd= get_retopo_paint_data();
if(rpd) {
RetopoPaintLine *l;
RetopoPaintPoint *p;
glColor3f(0,0,0);
glLineWidth(2);
/* Draw existing lines */
for(l= rpd->lines.first; l; l= l->next) {
if(l==rpd->lines.last)
glColor3f(0.3,0,0);
glBegin(l->cyclic?GL_LINE_LOOP:GL_LINE_STRIP);
for(p= l->points.first; p; p= p->next) {
glVertex2s(p->loc.x,p->loc.y);
}
glEnd();
}
/* Draw ellipse */
if(rpd->mode==RETOPO_ELLIPSE && rpd->in_drag) {
short mouse[2];
getmouseco_areawin(mouse);
setlinestyle(3);
fdrawXORellipse(rpd->sloc[0],rpd->sloc[1],abs(mouse[0]-rpd->sloc[0]),abs(mouse[1]-rpd->sloc[1]));
setlinestyle(0);
}
else if(rpd->mode==RETOPO_LINE && rpd->in_drag) {
short mouse[2];
getmouseco_areawin(mouse);
setlinestyle(3);
sdrawXORline(rpd->sloc[0],rpd->sloc[1],mouse[0],mouse[1]);
setlinestyle(0);
}
else if(rpd->nearest.line) { /* Draw selection */
RetopoPaintPoint *p= rpd->nearest.first ? rpd->nearest.line->points.first :
rpd->nearest.line->points.last;
if(p)
fdrawXORcirc(p->loc.x, p->loc.y, rpd->seldist);
}
glLineWidth(1);
}
}
RetopoPaintData *retopo_paint_data_copy(RetopoPaintData *rpd)
{
RetopoPaintData *copy;
RetopoPaintLine *l, *lcp;
RetopoPaintPoint *p, *pcp;
if(!rpd) return NULL;
copy= MEM_mallocN(sizeof(RetopoPaintData),"RetopoPaintDataCopy");
memcpy(copy,rpd,sizeof(RetopoPaintData));
copy->lines.first= copy->lines.last= NULL;
for(l= rpd->lines.first; l; l= l->next) {
lcp= MEM_mallocN(sizeof(RetopoPaintLine),"RetopoPaintLineCopy");
memcpy(lcp,l,sizeof(RetopoPaintLine));
BLI_addtail(&copy->lines,lcp);
lcp->hitlist.first= lcp->hitlist.last= NULL;
lcp->points.first= lcp->points.last= NULL;
for(p= l->points.first; p; p= p->next) {
pcp= MEM_mallocN(sizeof(RetopoPaintPoint),"RetopoPaintPointCopy");
memcpy(pcp,p,sizeof(RetopoPaintPoint));
BLI_addtail(&lcp->points,pcp);
}
}
copy->intersections.first= copy->intersections.last= NULL;
return copy;
}
char retopo_mesh_check()
{
return G.obedit && G.obedit->type==OB_MESH && G.editMesh->retopo_mode;
}
char retopo_curve_check()
{
return G.obedit && (G.obedit->type==OB_CURVE ||
G.obedit->type==OB_SURF) && (((Curve*)G.obedit->data)->flag & CU_RETOPO);
}
void retopo_toggle(void *j1,void *j2)
{
if(retopo_mesh_check() || retopo_curve_check()) {
if(G.vd->depths) G.vd->depths->damaged= 1;
retopo_queue_updates(G.vd);
}
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWVIEW3D, 0);
}
void retopo_do_2d(View3D *v3d, short proj[2], float *v, char adj)
{
/* Check to make sure vert is visible in window */
if(proj[0]>0 && proj[1]>0 && proj[0] < v3d->depths->w && proj[1] < v3d->depths->h) {
float depth= v3d->depths->depths[(int)(proj[1]*v3d->depths->w+proj[0])];
double px, py, pz;
/* Don't modify the point if it'll be mapped to the background */
if(depth==v3d->depths->depth_range[1]) {
if(adj) {
/* Find the depth of (0,0,0); */
gluProject(0,0,0,v3d->retopo_view_data->modelviewmat,
v3d->retopo_view_data->projectionmat,
v3d->retopo_view_data->viewport,&px,&py,&pz);
depth= pz;
}
else return;
}
/* Find 3D location with new depth (unproject) */
gluUnProject(proj[0],proj[1],depth,v3d->retopo_view_data->modelviewmat,
v3d->retopo_view_data->projectionmat,
v3d->retopo_view_data->viewport,&px,&py,&pz);
v[0]= px;
v[1]= py;
v[2]= pz;
}
}
void retopo_do_vert(View3D *v3d, float *v)
{
short proj[2];
double px, py, pz;
/* Find 2D location (project) */
gluProject(v[0],v[1],v[2],v3d->retopo_view_data->modelviewmat,v3d->retopo_view_data->projectionmat,
v3d->retopo_view_data->viewport,&px,&py,&pz);
proj[0]= px;
proj[1]= py;
retopo_do_2d(v3d,proj,v,0);
}
void retopo_do_all(void *j1,void *j2)
{
RetopoViewData *rvd= G.vd->retopo_view_data;
if(retopo_mesh_check()) {
if(rvd) {
EditMesh *em= G.editMesh;
EditVert *eve;
/* Apply retopo to all selected vertices */
eve= em->verts.first;
while(eve) {
if(eve->f & SELECT)
retopo_do_vert(G.vd,eve->co);
eve= eve->next;
}
allqueue(REDRAWVIEW3D, 0);
}
}
else if(retopo_curve_check()) {
if(rvd) {
extern ListBase editNurb;
Nurb *nu;
BPoint *bp;
int i, j;
for(nu= editNurb.first; nu; nu= nu->next)
{
if((nu->type & 7)!=CU_BEZIER) {
bp= nu->bp;
for(i=0; i<nu->pntsv; ++i) {
for(j=0; j<nu->pntsu; ++j, ++bp) {
if(bp->f1 & 1)
retopo_do_vert(G.vd,bp->vec);
}
}
}
}
allqueue(REDRAWVIEW3D, 0);
}
}
}
void retopo_queue_updates(View3D *v3d)
{
if(retopo_mesh_check() || retopo_curve_check()) {
if(!v3d->retopo_view_data)
v3d->retopo_view_data= MEM_callocN(sizeof(RetopoViewData),"RetopoViewData");
v3d->retopo_view_data->queue_matrix_update= 1;
allqueue(REDRAWVIEW3D, 0);
}
}
void retopo_matrix_update(View3D *v3d)
{
if(retopo_mesh_check() || retopo_curve_check()) {
RetopoViewData *rvd= v3d->retopo_view_data;
if(!rvd) {
rvd= MEM_callocN(sizeof(RetopoViewData),"RetopoViewData");
v3d->retopo_view_data= rvd;
}
if(rvd && rvd->queue_matrix_update) {
glGetDoublev(GL_MODELVIEW_MATRIX, rvd->modelviewmat);
glGetDoublev(GL_PROJECTION_MATRIX, rvd->projectionmat);
glGetIntegerv(GL_VIEWPORT, rvd->viewport);
rvd->viewport[0]= rvd->viewport[1]= 0;
rvd->queue_matrix_update= 0;
}
}
}
void retopo_free_view_data(View3D *v3d)
{
if(v3d->retopo_view_data) {
MEM_freeN(v3d->retopo_view_data);
v3d->retopo_view_data= NULL;
}
}
void retopo_paint_debug_print(RetopoPaintData *rpd)
{
RetopoPaintLine *l;
RetopoPaintPoint *p;
for(l= rpd->lines.first; l; l= l->next) {
printf("Line:\n");
for(p= l->points.first; p; p= p->next) {
printf(" Point(%d: %d,%d)\n",p->index,p->loc.x,p->loc.y);
}
}
fflush(stdout);
}

File diff suppressed because it is too large Load Diff

@ -52,6 +52,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_gsqueue.h"
#include "BLI_linklist.h"
#include "DNA_action_types.h"
@ -61,6 +62,7 @@
#include "DNA_image_types.h"
#include "DNA_ipo_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h" /* used for select grouped hooks */
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@ -81,6 +83,7 @@
#include "BKE_group.h"
#include "BKE_ipo.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
#include "BKE_scene.h"
#include "BKE_utildefines.h"
@ -115,6 +118,7 @@
#include "BIF_poseobject.h"
#include "BIF_outliner.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toets.h"
@ -140,6 +144,7 @@
#include "BDR_drawmesh.h"
#include "BDR_drawobject.h"
#include "BDR_imagepaint.h"
#include "BDR_sculptmode.h"
#include "BDR_unwrapper.h"
#include "BLO_readfile.h" /* for BLO_blendhandle_close */
@ -152,6 +157,7 @@
#include "mydevice.h"
#include "blendef.h"
#include "datatoc.h"
#include "multires.h"
#include "BIF_transform.h"
@ -776,6 +782,8 @@ void BIF_undo_push(char *str)
else if (G.obedit->type==OB_ARMATURE)
undo_push_armature(str);
}
else if(G.f & G_SCULPTMODE) {
}
else {
if(U.uiflag & USER_GLOBALUNDO)
BKE_write_undo(str);
@ -795,11 +803,16 @@ void BIF_undo(void)
vpaint_undo();
else if(G.f & G_TEXTUREPAINT)
imagepaint_undo();
else if(G.f & G_SCULPTMODE)
sculptmode_undo();
else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
imagepaint_undo();
else {
/* now also in faceselect mode */
if(U.uiflag & USER_GLOBALUNDO) {
if(G.f & G_SCULPTMODE)
set_sculpt_object(NULL);
BKE_undo_step(1);
sound_initialize_sounds();
}
@ -820,6 +833,8 @@ void BIF_redo(void)
vpaint_undo();
else if(G.f & G_TEXTUREPAINT)
imagepaint_undo();
else if(G.f & G_SCULPTMODE)
sculptmode_redo();
else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
imagepaint_undo();
else {
@ -844,6 +859,8 @@ void BIF_undo_menu(void)
;
else if(G.f & G_VERTEXPAINT)
;
else if(G.f & G_SCULPTMODE)
sculptmode_undo_menu();
else {
if(U.uiflag & USER_GLOBALUNDO) {
char *menu= BKE_undo_menu_string();
@ -874,7 +891,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(val) {
if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
if(event==MOUSEY || event==MOUSEX) return;
//if(event==MOUSEY || event==MOUSEX) return;
if(event==UI_BUT_EVENT) do_butspace(val); /* temporal, view3d deserves own queue? */
@ -887,6 +905,23 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if (event==RIGHTMOUSE) event = LEFTMOUSE;
}
if(!G.obedit && (G.f & G_SCULPTMODE)) {
if(G.scene->sculptdata.propset==1) {
sculptmode_propset(event);
return;
}
else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
if(!bwin_qtest(sa->win))
allqueue(REDRAWVIEW3D, 0);
}
}
/* Handle retopo painting */
if(retopo_mesh_paint_check()) {
if(!retopo_paint(event))
return;
}
/* run any view3d event handler script links */
if (event && sa->scriptlink.totscript)
if (BPY_do_spacehandlers(sa, event, SPACEHANDLER_VIEW3D_EVENT))
@ -1031,10 +1066,16 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
* based on user preference USER_LMOUSESELECT
*/
case LEFTMOUSE:
if ((G.obedit) || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT))) {
if ((G.obedit) || !(G.f&(G_SCULPTMODE|G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT))) {
mouse_cursor();
}
else if (G.f & G_WEIGHTPAINT){
else if (G.f & G_SCULPTMODE) {
if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
sculptmode_pmv(0);
else if(!G.scene->sculptdata.propset)
sculpt();
}
else if (G.f & G_WEIGHTPAINT) {
weight_paint();
}
else if (G.f & G_VERTEXPAINT) {
@ -1086,6 +1127,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
face_select();
else if( G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
sample_vpaint();
else if((G.f & G_SCULPTMODE) && G.qual==LR_SHIFTKEY+LR_CTRLKEY)
sculptmode_pmv(1);
else
mouse_select(); /* does poses too */
break;
@ -1149,7 +1192,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
doredraw= 1;
break;
case ONEKEY:
if(G.qual==LR_CTRLKEY) {
if(ob && ob->type == OB_MESH) {
@ -1345,11 +1388,14 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
imagestodisplist();
}
else if((G.qual==0)){
pupval= pupmenu("Draw mode%t|BoundBox %x1|Wire %x2|OpenGL Solid %x3|Shaded Solid %x4|Textured Solid %x5");
if(pupval>0) {
G.vd->drawtype= pupval;
doredraw= 1;
if(G.f & G_SCULPTMODE)
G.scene->sculptdata.propset= 1;
else {
pupval= pupmenu("Draw mode%t|BoundBox %x1|Wire %x2|OpenGL Solid %x3|Shaded Solid %x4|Textured Solid %x5");
if(pupval>0) {
G.vd->drawtype= pupval;
doredraw= 1;
}
}
}
@ -1500,6 +1546,15 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else if(G.f & G_FACESELECT)
hide_tface();
else if(G.f & G_SCULPTMODE) {
if(G.qual==LR_ALTKEY) {
waitcursor(1);
sculptmode_pmv_off(get_mesh(ob));
BIF_undo_push("Partial mesh hide");
allqueue(REDRAWVIEW3D,0);
waitcursor(0);
}
}
else if(ob && (ob->flag & OB_POSEMODE)) {
if (G.qual==0)
hide_selected_pose_bones();
@ -2024,19 +2079,33 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case PAGEUPKEY:
if(G.qual==LR_CTRLKEY)
movekey_obipo(1);
else if((G.qual==0))
nextkey_obipo(1); /* in editipo.c */
if(G.f & G_SCULPTMODE) {
if(ob && ob->type == OB_MESH && ((Mesh*)ob->data)->mr) {
((Mesh*)ob->data)->mr->newlvl= ((Mesh*)ob->data)->mr->current+1;
multires_set_level(ob,ob->data);
}
} else {
if(G.qual==LR_CTRLKEY)
movekey_obipo(1);
else if((G.qual==0))
nextkey_obipo(1); /* in editipo.c */
}
break;
case PAGEDOWNKEY:
if(G.qual==LR_CTRLKEY)
movekey_obipo(-1);
else if((G.qual==0))
nextkey_obipo(-1);
if(G.f & G_SCULPTMODE) {
if(ob && ob->type == OB_MESH && ((Mesh*)ob->data)->mr) {
((Mesh*)ob->data)->mr->newlvl= ((Mesh*)ob->data)->mr->current-1;
multires_set_level(ob,ob->data);
}
} else {
if(G.qual==LR_CTRLKEY)
movekey_obipo(-1);
else if((G.qual==0))
nextkey_obipo(-1);
}
break;
case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
case PADENTER:
@ -2111,6 +2180,8 @@ static void initview3d(ScrArea *sa)
vd->gridflag |= V3D_SHOW_Y;
vd->gridflag |= V3D_SHOW_FLOOR;
vd->gridflag &= ~V3D_SHOW_Z;
vd->depths= NULL;
}
@ -3155,7 +3226,6 @@ void drawinfospace(ScrArea *sa, void *spacedata)
(xpos+edgsp+(4*mpref)+(4*midsp)),y1,mpref,buth,
&(U.uiflag), 0, 0, 0, 0, "Hide files/datablocks that start with a dot(.*)");
uiDefBut(block, LABEL,0,"OpenGL:",
(xpos+edgsp+(5*midsp)+(5*mpref)),y5label,mpref,buth,
0, 0, 0, 0, 0, "");
@ -4947,6 +5017,12 @@ void freespacelist(ScrArea *sa)
}
if(vd->localvd) MEM_freeN(vd->localvd);
if(vd->clipbb) MEM_freeN(vd->clipbb);
if(vd->depths) {
if(vd->depths->depths) MEM_freeN(vd->depths->depths);
MEM_freeN(vd->depths);
vd->depths= NULL;
}
retopo_free_view_data(vd);
if(G.vd==vd) G.vd= NULL;
if(vd->ri) {
BIF_view3d_previewrender_free(vd);
@ -5005,6 +5081,7 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
}
else if(sl->spacetype==SPACE_VIEW3D) {
BIF_view3d_previewrender_free((View3D *)sl);
((View3D*)sl)->depths= NULL;
}
else if(sl->spacetype==SPACE_OOPS) {
SpaceOops *so= (SpaceOops *)sl;

@ -79,6 +79,7 @@
#include "BIF_poseobject.h"
#include "BIF_previewrender.h"
#include "BIF_renderwin.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toets.h"
@ -86,6 +87,7 @@
#include "BIF_usiblender.h"
#include "BIF_writeimage.h"
#include "BDR_sculptmode.h"
#include "BDR_vpaint.h"
#include "BDR_editobject.h"
#include "BDR_editface.h"
@ -334,6 +336,11 @@ void persptoetsen(unsigned short event)
if(G.vd->persp<2) perspo= G.vd->persp;
}
if(G.vd->depths) G.vd->depths->damaged= 1;
retopo_queue_updates(G.vd);
if(retopo_mesh_paint_check() && G.vd->retopo_view_data)
retopo_paint_view_update(G.vd);
if(preview3d_event)
BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
@ -670,6 +677,8 @@ int blenderqread(unsigned short event, short val)
}
else if(ob->type==OB_MESH) {
if(ob==G.obedit) EM_selectmode_menu();
else if(G.f & G_SCULPTMODE)
sculptmode_selectbrush_menu();
else set_wpaint();
}
}

@ -58,6 +58,7 @@
#include "BIF_editmesh.h"
#include "BIF_editsima.h"
#include "BIF_meshtools.h"
#include "BIF_retopo.h"
#ifdef WITH_VERSE
#include "BIF_verse.h"
@ -224,6 +225,8 @@ void recalcData(TransInfo *t)
if(G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR)
editmesh_apply_to_mirror(t);
retopo_do_all(0,G.obedit->data);
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */
@ -238,6 +241,8 @@ void recalcData(TransInfo *t)
testhandlesNurb(nu); /* test for bezier too */
nu= nu->next;
}
retopo_do_all(NULL,NULL);
}
else if(G.obedit->type==OB_ARMATURE){ /* no recalc flag, does pose */
bArmature *arm= G.obedit->data;

@ -71,6 +71,7 @@
#include "BIF_space.h"
#include "BIF_mywindow.h"
#include "BIF_previewrender.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_toolbox.h"
@ -559,7 +560,18 @@ void viewmove(int mode)
/* cumultime(0); */
if (ob && (U.uiflag & USER_ORBIT_SELECTION)) {
if(!G.obedit && (G.f & G_SCULPTMODE) && ob && G.vd->pivot_last) {
use_sel= 1;
VecCopyf(ofs, G.vd->ofs);
VecCopyf(obofs,&G.scene->sculptdata.pivot.x);
Mat4MulVecfl(ob->obmat, obofs);
obofs[0]= -obofs[0];
obofs[1]= -obofs[1];
obofs[2]= -obofs[2];
}
//else if (G.obedit==NULL && ob && !(ob->flag & OB_POSEMODE) && U.uiflag & USER_ORBIT_SELECTION) {
else if (ob && (U.uiflag & USER_ORBIT_SELECTION)) {
use_sel = 1;
VECCOPY(ofs, G.vd->ofs);
@ -761,6 +773,12 @@ void viewmove(int mode)
if(G.f & G_PLAYANIM) inner_play_anim_loop(0, 0);
if(G.f & G_SIMULATION) break;
/* If in retopo paint mode, update lines */
if(retopo_mesh_paint_check() && G.vd->retopo_view_data) {
G.vd->retopo_view_data->queue_matrix_update= 1;
retopo_paint_view_update(G.vd);
}
scrarea_do_windraw(curarea);
screen_swapbuffers();
}
@ -777,6 +795,10 @@ void viewmove(int mode)
if( !(get_mbut() & (L_MOUSE|M_MOUSE))) break;
}
if(G.vd->depths) G.vd->depths->damaged= 1;
retopo_queue_updates(G.vd);
allqueue(REDRAWVIEW3D, 0);
if(preview3d_event)
BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
else