2009-01-07 19:23:22 +00:00
|
|
|
/**
|
|
|
|
|
* $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) 2001-2002 by NaN Holding BV.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
|
*
|
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
#include <io.h>
|
|
|
|
|
#else
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "IMB_imbuf.h"
|
|
|
|
|
#include "IMB_imbuf_types.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
|
#include "BLI_arithb.h"
|
|
|
|
|
#include "MTC_matrixops.h"
|
|
|
|
|
|
|
|
|
|
#include "DNA_action_types.h"
|
|
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
|
#include "DNA_brush_types.h"
|
|
|
|
|
#include "DNA_cloth_types.h"
|
|
|
|
|
#include "DNA_mesh_types.h"
|
|
|
|
|
#include "DNA_meshdata_types.h"
|
|
|
|
|
#include "DNA_modifier_types.h"
|
|
|
|
|
#include "DNA_object_types.h"
|
|
|
|
|
#include "DNA_object_force.h"
|
|
|
|
|
#include "DNA_particle_types.h"
|
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
|
#include "DNA_space_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
#include "DNA_view3d_types.h"
|
|
|
|
|
#include "DNA_userdef_types.h"
|
|
|
|
|
|
2009-01-25 21:02:52 +00:00
|
|
|
#include "RNA_access.h"
|
|
|
|
|
|
2009-01-07 19:23:22 +00:00
|
|
|
#include "BKE_armature.h"
|
2009-03-11 00:43:08 +00:00
|
|
|
#include "BKE_brush.h"
|
2009-01-07 19:23:22 +00:00
|
|
|
#include "BKE_DerivedMesh.h"
|
|
|
|
|
#include "BKE_cloth.h"
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
#include "BKE_context.h"
|
2009-01-07 19:23:22 +00:00
|
|
|
#include "BKE_customdata.h"
|
|
|
|
|
#include "BKE_depsgraph.h"
|
|
|
|
|
#include "BKE_deform.h"
|
|
|
|
|
#include "BKE_displist.h"
|
|
|
|
|
#include "BKE_global.h"
|
|
|
|
|
#include "BKE_mesh.h"
|
|
|
|
|
#include "BKE_modifier.h"
|
|
|
|
|
#include "BKE_object.h"
|
2009-08-17 02:49:31 +00:00
|
|
|
#include "BKE_paint.h"
|
2009-01-07 19:23:22 +00:00
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
#include "WM_types.h"
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
#include "BIF_glutil.h"
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
#include "ED_mesh.h"
|
|
|
|
|
#include "ED_object.h"
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
#include "ED_screen.h"
|
|
|
|
|
#include "ED_util.h"
|
2009-01-07 19:23:22 +00:00
|
|
|
#include "ED_view3d.h"
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* vp->mode */
|
2009-01-07 19:23:22 +00:00
|
|
|
#define VP_MIX 0
|
|
|
|
|
#define VP_ADD 1
|
|
|
|
|
#define VP_SUB 2
|
|
|
|
|
#define VP_MUL 3
|
|
|
|
|
#define VP_BLUR 4
|
|
|
|
|
#define VP_LIGHTEN 5
|
|
|
|
|
#define VP_DARKEN 6
|
|
|
|
|
|
|
|
|
|
#define MAXINDEX 512000
|
|
|
|
|
|
|
|
|
|
/* XXX */
|
|
|
|
|
static void error() {}
|
|
|
|
|
|
2009-01-25 21:02:52 +00:00
|
|
|
/* polling - retrieve whether cursor should be set or operator should be done */
|
|
|
|
|
|
|
|
|
|
static int vp_poll(bContext *C)
|
|
|
|
|
{
|
2009-08-15 20:36:15 +00:00
|
|
|
Object *ob = CTX_data_active_object(C);
|
|
|
|
|
|
2009-08-17 02:49:31 +00:00
|
|
|
if(ob && ob->mode & OB_MODE_VERTEX_PAINT &&
|
|
|
|
|
paint_brush(&CTX_data_tool_settings(C)->vpaint->paint)) {
|
2009-01-25 21:02:52 +00:00
|
|
|
ScrArea *sa= CTX_wm_area(C);
|
|
|
|
|
if(sa->spacetype==SPACE_VIEW3D) {
|
|
|
|
|
ARegion *ar= CTX_wm_region(C);
|
|
|
|
|
if(ar->regiontype==RGN_TYPE_WINDOW)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int wp_poll(bContext *C)
|
|
|
|
|
{
|
2009-08-15 21:46:25 +00:00
|
|
|
Object *ob = CTX_data_active_object(C);
|
|
|
|
|
|
2009-08-17 02:49:31 +00:00
|
|
|
if(ob && ob->mode & OB_MODE_WEIGHT_PAINT &&
|
|
|
|
|
paint_brush(&CTX_data_tool_settings(C)->wpaint->paint)) {
|
2009-01-25 21:02:52 +00:00
|
|
|
ScrArea *sa= CTX_wm_area(C);
|
|
|
|
|
if(sa->spacetype==SPACE_VIEW3D) {
|
|
|
|
|
ARegion *ar= CTX_wm_region(C);
|
|
|
|
|
if(ar->regiontype==RGN_TYPE_WINDOW)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Cursors */
|
|
|
|
|
static void vp_drawcursor(bContext *C, int x, int y, void *customdata)
|
|
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&CTX_data_tool_settings(C)->vpaint->paint);
|
2009-01-25 21:02:52 +00:00
|
|
|
|
|
|
|
|
glTranslatef((float)x, (float)y, 0.0f);
|
|
|
|
|
|
|
|
|
|
glColor4ub(255, 255, 255, 128);
|
|
|
|
|
glEnable( GL_LINE_SMOOTH );
|
|
|
|
|
glEnable(GL_BLEND);
|
2009-08-17 02:49:31 +00:00
|
|
|
glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40);
|
2009-01-25 21:02:52 +00:00
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
glDisable( GL_LINE_SMOOTH );
|
|
|
|
|
|
|
|
|
|
glTranslatef((float)-x, (float)-y, 0.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void wp_drawcursor(bContext *C, int x, int y, void *customdata)
|
|
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&CTX_data_tool_settings(C)->wpaint->paint);
|
|
|
|
|
|
2009-01-25 21:02:52 +00:00
|
|
|
glTranslatef((float)x, (float)y, 0.0f);
|
|
|
|
|
|
|
|
|
|
glColor4ub(200, 200, 255, 128);
|
|
|
|
|
glEnable( GL_LINE_SMOOTH );
|
|
|
|
|
glEnable(GL_BLEND);
|
2009-08-17 02:49:31 +00:00
|
|
|
glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40);
|
2009-01-25 21:02:52 +00:00
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
glDisable( GL_LINE_SMOOTH );
|
|
|
|
|
|
|
|
|
|
glTranslatef((float)-x, (float)-y, 0.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void toggle_paint_cursor(bContext *C, int wpaint)
|
|
|
|
|
{
|
|
|
|
|
ToolSettings *ts = CTX_data_scene(C)->toolsettings;
|
|
|
|
|
VPaint *vp = wpaint ? ts->wpaint : ts->vpaint;
|
|
|
|
|
|
|
|
|
|
if(vp->paintcursor) {
|
|
|
|
|
WM_paint_cursor_end(CTX_wm_manager(C), vp->paintcursor);
|
|
|
|
|
vp->paintcursor = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
vp->paintcursor = wpaint ?
|
|
|
|
|
WM_paint_cursor_activate(CTX_wm_manager(C), wp_poll, wp_drawcursor, NULL) :
|
|
|
|
|
WM_paint_cursor_activate(CTX_wm_manager(C), vp_poll, vp_drawcursor, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
static VPaint *new_vpaint(int wpaint)
|
|
|
|
|
{
|
|
|
|
|
VPaint *vp= MEM_callocN(sizeof(VPaint), "VPaint");
|
|
|
|
|
|
|
|
|
|
vp->gamma= vp->mul= 1.0f;
|
|
|
|
|
|
|
|
|
|
vp->flag= VP_AREA+VP_SOFT+VP_SPRAY;
|
|
|
|
|
|
2009-03-11 00:43:08 +00:00
|
|
|
if(wpaint)
|
2009-01-10 14:19:14 +00:00
|
|
|
vp->flag= VP_AREA+VP_SOFT;
|
2009-03-11 00:43:08 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
return vp;
|
|
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
static int *get_indexarray(void)
|
|
|
|
|
{
|
|
|
|
|
return MEM_mallocN(sizeof(int)*MAXINDEX + 2, "vertexpaint");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* in contradiction to cpack drawing colors, the MCOL colors (vpaint colors) are per byte!
|
|
|
|
|
so not endian sensitive. Mcol = ABGR!!! so be cautious with cpack calls */
|
|
|
|
|
|
|
|
|
|
unsigned int rgba_to_mcol(float r, float g, float b, float a)
|
|
|
|
|
{
|
|
|
|
|
int ir, ig, ib, ia;
|
|
|
|
|
unsigned int col;
|
|
|
|
|
char *cp;
|
|
|
|
|
|
|
|
|
|
ir= floor(255.0*r);
|
|
|
|
|
if(ir<0) ir= 0; else if(ir>255) ir= 255;
|
|
|
|
|
ig= floor(255.0*g);
|
|
|
|
|
if(ig<0) ig= 0; else if(ig>255) ig= 255;
|
|
|
|
|
ib= floor(255.0*b);
|
|
|
|
|
if(ib<0) ib= 0; else if(ib>255) ib= 255;
|
|
|
|
|
ia= floor(255.0*a);
|
|
|
|
|
if(ia<0) ia= 0; else if(ia>255) ia= 255;
|
|
|
|
|
|
|
|
|
|
cp= (char *)&col;
|
|
|
|
|
cp[0]= ia;
|
|
|
|
|
cp[1]= ib;
|
|
|
|
|
cp[2]= ig;
|
|
|
|
|
cp[3]= ir;
|
|
|
|
|
|
|
|
|
|
return col;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int vpaint_get_current_col(VPaint *vp)
|
|
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&vp->paint);
|
|
|
|
|
return rgba_to_mcol(brush->rgb[0], brush->rgb[1], brush->rgb[2], 1.0f);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void do_shared_vertexcol(Mesh *me)
|
|
|
|
|
{
|
|
|
|
|
/* if no mcol: do not do */
|
|
|
|
|
/* if tface: only the involved faces, otherwise all */
|
|
|
|
|
MFace *mface;
|
|
|
|
|
MTFace *tface;
|
|
|
|
|
int a;
|
|
|
|
|
short *scolmain, *scol;
|
|
|
|
|
char *mcol;
|
|
|
|
|
|
|
|
|
|
if(me->mcol==0 || me->totvert==0 || me->totface==0) return;
|
|
|
|
|
|
|
|
|
|
scolmain= MEM_callocN(4*sizeof(short)*me->totvert, "colmain");
|
|
|
|
|
|
|
|
|
|
tface= me->mtface;
|
|
|
|
|
mface= me->mface;
|
|
|
|
|
mcol= (char *)me->mcol;
|
|
|
|
|
for(a=me->totface; a>0; a--, mface++, mcol+=16) {
|
|
|
|
|
if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
|
|
|
|
|
scol= scolmain+4*mface->v1;
|
|
|
|
|
scol[0]++; scol[1]+= mcol[1]; scol[2]+= mcol[2]; scol[3]+= mcol[3];
|
|
|
|
|
scol= scolmain+4*mface->v2;
|
|
|
|
|
scol[0]++; scol[1]+= mcol[5]; scol[2]+= mcol[6]; scol[3]+= mcol[7];
|
|
|
|
|
scol= scolmain+4*mface->v3;
|
|
|
|
|
scol[0]++; scol[1]+= mcol[9]; scol[2]+= mcol[10]; scol[3]+= mcol[11];
|
|
|
|
|
if(mface->v4) {
|
|
|
|
|
scol= scolmain+4*mface->v4;
|
|
|
|
|
scol[0]++; scol[1]+= mcol[13]; scol[2]+= mcol[14]; scol[3]+= mcol[15];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(tface) tface++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a= me->totvert;
|
|
|
|
|
scol= scolmain;
|
|
|
|
|
while(a--) {
|
|
|
|
|
if(scol[0]>1) {
|
|
|
|
|
scol[1]/= scol[0];
|
|
|
|
|
scol[2]/= scol[0];
|
|
|
|
|
scol[3]/= scol[0];
|
|
|
|
|
}
|
|
|
|
|
scol+= 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tface= me->mtface;
|
|
|
|
|
mface= me->mface;
|
|
|
|
|
mcol= (char *)me->mcol;
|
|
|
|
|
for(a=me->totface; a>0; a--, mface++, mcol+=16) {
|
|
|
|
|
if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
|
|
|
|
|
scol= scolmain+4*mface->v1;
|
|
|
|
|
mcol[1]= scol[1]; mcol[2]= scol[2]; mcol[3]= scol[3];
|
|
|
|
|
scol= scolmain+4*mface->v2;
|
|
|
|
|
mcol[5]= scol[1]; mcol[6]= scol[2]; mcol[7]= scol[3];
|
|
|
|
|
scol= scolmain+4*mface->v3;
|
|
|
|
|
mcol[9]= scol[1]; mcol[10]= scol[2]; mcol[11]= scol[3];
|
|
|
|
|
if(mface->v4) {
|
|
|
|
|
scol= scolmain+4*mface->v4;
|
|
|
|
|
mcol[13]= scol[1]; mcol[14]= scol[2]; mcol[15]= scol[3];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(tface) tface++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(scolmain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void make_vertexcol(Scene *scene, int shade) /* single ob */
|
|
|
|
|
{
|
|
|
|
|
Object *ob;
|
|
|
|
|
Mesh *me;
|
|
|
|
|
|
|
|
|
|
if(scene->obedit) {
|
|
|
|
|
error("Unable to perform function in Edit Mode");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ob= OBACT;
|
|
|
|
|
if(!ob || ob->id.lib) return;
|
|
|
|
|
me= get_mesh(ob);
|
|
|
|
|
if(me==0) return;
|
|
|
|
|
|
|
|
|
|
/* copies from shadedisplist to mcol */
|
|
|
|
|
if(!me->mcol) {
|
|
|
|
|
CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface);
|
|
|
|
|
mesh_update_customdata_pointers(me);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(shade)
|
|
|
|
|
shadeMeshMCol(scene, ob, me);
|
|
|
|
|
else
|
|
|
|
|
memset(me->mcol, 255, 4*sizeof(MCol)*me->totface);
|
|
|
|
|
|
|
|
|
|
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot)
|
|
|
|
|
{
|
|
|
|
|
if(vp->vpaint_prev) {
|
|
|
|
|
MEM_freeN(vp->vpaint_prev);
|
|
|
|
|
vp->vpaint_prev= NULL;
|
|
|
|
|
}
|
|
|
|
|
vp->tot= tot;
|
|
|
|
|
|
|
|
|
|
if(mcol==NULL || tot==0) return;
|
|
|
|
|
|
|
|
|
|
vp->vpaint_prev= MEM_mallocN(4*sizeof(int)*tot, "vpaint_prev");
|
|
|
|
|
memcpy(vp->vpaint_prev, mcol, 4*sizeof(int)*tot);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
static void copy_wpaint_prev (VPaint *wp, MDeformVert *dverts, int dcount)
|
2009-01-07 19:23:22 +00:00
|
|
|
{
|
2009-01-10 14:19:14 +00:00
|
|
|
if (wp->wpaint_prev) {
|
|
|
|
|
free_dverts(wp->wpaint_prev, wp->tot);
|
|
|
|
|
wp->wpaint_prev= NULL;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(dverts && dcount) {
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
wp->wpaint_prev = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaint prev");
|
|
|
|
|
wp->tot = dcount;
|
|
|
|
|
copy_dverts (wp->wpaint_prev, dverts, dcount);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void clear_vpaint(Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
Mesh *me;
|
|
|
|
|
Object *ob;
|
|
|
|
|
unsigned int *to, paintcol;
|
|
|
|
|
int a;
|
|
|
|
|
|
|
|
|
|
ob= OBACT;
|
|
|
|
|
me= get_mesh(ob);
|
|
|
|
|
if(!ob || ob->id.lib) return;
|
|
|
|
|
|
2009-08-15 20:36:15 +00:00
|
|
|
if(!(ob->mode & OB_MODE_VERTEX_PAINT)) return;
|
|
|
|
|
|
2009-01-07 19:23:22 +00:00
|
|
|
if(me==0 || me->mcol==0 || me->totface==0) return;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
paintcol= vpaint_get_current_col(scene->toolsettings->vpaint);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
to= (unsigned int *)me->mcol;
|
|
|
|
|
a= 4*me->totface;
|
|
|
|
|
while(a--) {
|
|
|
|
|
*to= paintcol;
|
|
|
|
|
to++;
|
|
|
|
|
}
|
|
|
|
|
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clear_vpaint_selectedfaces(Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
Mesh *me;
|
|
|
|
|
MFace *mf;
|
|
|
|
|
Object *ob;
|
|
|
|
|
unsigned int paintcol, *mcol;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
ob= OBACT;
|
|
|
|
|
me= get_mesh(ob);
|
|
|
|
|
if(me==0 || me->totface==0) return;
|
|
|
|
|
|
|
|
|
|
if(!me->mcol)
|
|
|
|
|
make_vertexcol(scene, 0);
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
paintcol= vpaint_get_current_col(scene->toolsettings->vpaint);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
mf = me->mface;
|
|
|
|
|
mcol = (unsigned int*)me->mcol;
|
|
|
|
|
for (i = 0; i < me->totface; i++, mf++, mcol+=4) {
|
|
|
|
|
if (mf->flag & ME_FACE_SEL) {
|
|
|
|
|
mcol[0] = paintcol;
|
|
|
|
|
mcol[1] = paintcol;
|
|
|
|
|
mcol[2] = paintcol;
|
|
|
|
|
mcol[3] = paintcol;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* fills in the selected faces with the current weight and vertex group */
|
|
|
|
|
void clear_wpaint_selectedfaces(Scene *scene)
|
|
|
|
|
{
|
2009-07-09 19:49:04 +00:00
|
|
|
ToolSettings *ts= scene->toolsettings;
|
|
|
|
|
VPaint *wp= ts->wpaint;
|
|
|
|
|
float paintweight= ts->vgroup_weight;
|
2009-01-07 19:23:22 +00:00
|
|
|
Mesh *me;
|
|
|
|
|
MFace *mface;
|
|
|
|
|
Object *ob;
|
|
|
|
|
MDeformWeight *dw, *uw;
|
|
|
|
|
int *indexar;
|
|
|
|
|
int index, vgroup;
|
|
|
|
|
unsigned int faceverts[5]={0,0,0,0,0};
|
|
|
|
|
unsigned char i;
|
|
|
|
|
int vgroup_mirror= -1;
|
|
|
|
|
|
|
|
|
|
ob= OBACT;
|
|
|
|
|
me= ob->data;
|
|
|
|
|
if(me==0 || me->totface==0 || me->dvert==0 || !me->mface) return;
|
|
|
|
|
|
|
|
|
|
indexar= get_indexarray();
|
|
|
|
|
for(index=0, mface=me->mface; index<me->totface; index++, mface++) {
|
|
|
|
|
if((mface->flag & ME_FACE_SEL)==0)
|
|
|
|
|
indexar[index]= 0;
|
|
|
|
|
else
|
|
|
|
|
indexar[index]= index+1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vgroup= ob->actdef-1;
|
|
|
|
|
|
|
|
|
|
/* directly copied from weight_paint, should probaby split into a seperate function */
|
|
|
|
|
/* if mirror painting, find the other group */
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->flag & VP_MIRROR_X) {
|
2009-01-07 19:23:22 +00:00
|
|
|
bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
|
|
|
|
|
if(defgroup) {
|
|
|
|
|
bDeformGroup *curdef;
|
|
|
|
|
int actdef= 0;
|
|
|
|
|
char name[32];
|
|
|
|
|
|
|
|
|
|
BLI_strncpy(name, defgroup->name, 32);
|
|
|
|
|
bone_flip_name(name, 0); /* 0 = don't strip off number extensions */
|
|
|
|
|
|
|
|
|
|
for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
|
|
|
|
|
if (!strcmp(curdef->name, name))
|
|
|
|
|
break;
|
|
|
|
|
if(curdef==NULL) {
|
|
|
|
|
int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
|
|
|
|
|
curdef= add_defgroup_name (ob, name);
|
|
|
|
|
ob->actdef= olddef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(curdef && curdef!=defgroup)
|
|
|
|
|
vgroup_mirror= actdef;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* end copy from weight_paint*/
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
copy_wpaint_prev(wp, me->dvert, me->totvert);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
for(index=0; index<me->totface; index++) {
|
|
|
|
|
if(indexar[index] && indexar[index]<=me->totface) {
|
|
|
|
|
mface= me->mface + (indexar[index]-1);
|
|
|
|
|
/* just so we can loop through the verts */
|
|
|
|
|
faceverts[0]= mface->v1;
|
|
|
|
|
faceverts[1]= mface->v2;
|
|
|
|
|
faceverts[2]= mface->v3;
|
|
|
|
|
faceverts[3]= mface->v4;
|
|
|
|
|
for (i=0; i<3 || faceverts[i]; i++) {
|
|
|
|
|
if(!((me->dvert+faceverts[i])->flag)) {
|
|
|
|
|
dw= verify_defweight(me->dvert+faceverts[i], vgroup);
|
|
|
|
|
if(dw) {
|
2009-01-10 14:19:14 +00:00
|
|
|
uw= verify_defweight(wp->wpaint_prev+faceverts[i], vgroup);
|
2009-01-10 17:20:34 +00:00
|
|
|
uw->weight= dw->weight; /* set the undo weight */
|
2009-01-07 19:23:22 +00:00
|
|
|
dw->weight= paintweight;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->flag & VP_MIRROR_X) { /* x mirror painting */
|
2009-01-07 19:23:22 +00:00
|
|
|
int j= mesh_get_x_mirror_vert(ob, faceverts[i]);
|
|
|
|
|
if(j>=0) {
|
|
|
|
|
/* copy, not paint again */
|
|
|
|
|
if(vgroup_mirror != -1) {
|
|
|
|
|
dw= verify_defweight(me->dvert+j, vgroup_mirror);
|
2009-01-10 14:19:14 +00:00
|
|
|
uw= verify_defweight(wp->wpaint_prev+j, vgroup_mirror);
|
2009-01-07 19:23:22 +00:00
|
|
|
} else {
|
|
|
|
|
dw= verify_defweight(me->dvert+j, vgroup);
|
2009-01-10 14:19:14 +00:00
|
|
|
uw= verify_defweight(wp->wpaint_prev+j, vgroup);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
uw->weight= dw->weight; /* set the undo weight */
|
|
|
|
|
dw->weight= paintweight;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
(me->dvert+faceverts[i])->flag= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
index=0;
|
|
|
|
|
while (index<me->totvert) {
|
|
|
|
|
(me->dvert+index)->flag= 0;
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(indexar);
|
2009-01-10 14:19:14 +00:00
|
|
|
copy_wpaint_prev(wp, NULL, 0);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void vpaint_dogamma(Scene *scene)
|
|
|
|
|
{
|
2009-01-10 14:19:14 +00:00
|
|
|
VPaint *vp= scene->toolsettings->vpaint;
|
2009-01-07 19:23:22 +00:00
|
|
|
Mesh *me;
|
|
|
|
|
Object *ob;
|
|
|
|
|
float igam, fac;
|
|
|
|
|
int a, temp;
|
2009-01-26 09:13:15 +00:00
|
|
|
unsigned char *cp, gamtab[256];
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
ob= OBACT;
|
|
|
|
|
me= get_mesh(ob);
|
2009-08-15 20:36:15 +00:00
|
|
|
|
|
|
|
|
if(!(ob->mode & OB_MODE_VERTEX_PAINT)) return;
|
2009-01-07 19:23:22 +00:00
|
|
|
if(me==0 || me->mcol==0 || me->totface==0) return;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
igam= 1.0/vp->gamma;
|
2009-01-07 19:23:22 +00:00
|
|
|
for(a=0; a<256; a++) {
|
|
|
|
|
|
|
|
|
|
fac= ((float)a)/255.0;
|
2009-01-10 14:19:14 +00:00
|
|
|
fac= vp->mul*pow( fac, igam);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
temp= 255.9*fac;
|
|
|
|
|
|
|
|
|
|
if(temp<=0) gamtab[a]= 0;
|
|
|
|
|
else if(temp>=255) gamtab[a]= 255;
|
|
|
|
|
else gamtab[a]= temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a= 4*me->totface;
|
2009-01-26 09:13:15 +00:00
|
|
|
cp= (unsigned char *)me->mcol;
|
2009-01-07 19:23:22 +00:00
|
|
|
while(a--) {
|
|
|
|
|
|
|
|
|
|
cp[1]= gamtab[ cp[1] ];
|
|
|
|
|
cp[2]= gamtab[ cp[2] ];
|
|
|
|
|
cp[3]= gamtab[ cp[3] ];
|
|
|
|
|
|
|
|
|
|
cp+= 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
|
|
|
|
|
{
|
|
|
|
|
char *cp1, *cp2, *cp;
|
|
|
|
|
int mfac;
|
|
|
|
|
unsigned int col=0;
|
|
|
|
|
|
|
|
|
|
if(fac==0) return col1;
|
|
|
|
|
if(fac>=255) return col2;
|
|
|
|
|
|
|
|
|
|
mfac= 255-fac;
|
|
|
|
|
|
|
|
|
|
cp1= (char *)&col1;
|
|
|
|
|
cp2= (char *)&col2;
|
|
|
|
|
cp= (char *)&col;
|
|
|
|
|
|
|
|
|
|
cp[0]= 255;
|
|
|
|
|
cp[1]= (mfac*cp1[1]+fac*cp2[1])/255;
|
|
|
|
|
cp[2]= (mfac*cp1[2]+fac*cp2[2])/255;
|
|
|
|
|
cp[3]= (mfac*cp1[3]+fac*cp2[3])/255;
|
|
|
|
|
|
|
|
|
|
return col;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
|
|
|
|
|
{
|
|
|
|
|
char *cp1, *cp2, *cp;
|
|
|
|
|
int temp;
|
|
|
|
|
unsigned int col=0;
|
|
|
|
|
|
|
|
|
|
if(fac==0) return col1;
|
|
|
|
|
|
|
|
|
|
cp1= (char *)&col1;
|
|
|
|
|
cp2= (char *)&col2;
|
|
|
|
|
cp= (char *)&col;
|
|
|
|
|
|
|
|
|
|
cp[0]= 255;
|
|
|
|
|
temp= cp1[1] + ((fac*cp2[1])/255);
|
|
|
|
|
if(temp>254) cp[1]= 255; else cp[1]= temp;
|
|
|
|
|
temp= cp1[2] + ((fac*cp2[2])/255);
|
|
|
|
|
if(temp>254) cp[2]= 255; else cp[2]= temp;
|
|
|
|
|
temp= cp1[3] + ((fac*cp2[3])/255);
|
|
|
|
|
if(temp>254) cp[3]= 255; else cp[3]= temp;
|
|
|
|
|
|
|
|
|
|
return col;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
|
|
|
|
|
{
|
|
|
|
|
char *cp1, *cp2, *cp;
|
|
|
|
|
int temp;
|
|
|
|
|
unsigned int col=0;
|
|
|
|
|
|
|
|
|
|
if(fac==0) return col1;
|
|
|
|
|
|
|
|
|
|
cp1= (char *)&col1;
|
|
|
|
|
cp2= (char *)&col2;
|
|
|
|
|
cp= (char *)&col;
|
|
|
|
|
|
|
|
|
|
cp[0]= 255;
|
|
|
|
|
temp= cp1[1] - ((fac*cp2[1])/255);
|
|
|
|
|
if(temp<0) cp[1]= 0; else cp[1]= temp;
|
|
|
|
|
temp= cp1[2] - ((fac*cp2[2])/255);
|
|
|
|
|
if(temp<0) cp[2]= 0; else cp[2]= temp;
|
|
|
|
|
temp= cp1[3] - ((fac*cp2[3])/255);
|
|
|
|
|
if(temp<0) cp[3]= 0; else cp[3]= temp;
|
|
|
|
|
|
|
|
|
|
return col;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
|
|
|
|
|
{
|
|
|
|
|
char *cp1, *cp2, *cp;
|
|
|
|
|
int mfac;
|
|
|
|
|
unsigned int col=0;
|
|
|
|
|
|
|
|
|
|
if(fac==0) return col1;
|
|
|
|
|
|
|
|
|
|
mfac= 255-fac;
|
|
|
|
|
|
|
|
|
|
cp1= (char *)&col1;
|
|
|
|
|
cp2= (char *)&col2;
|
|
|
|
|
cp= (char *)&col;
|
|
|
|
|
|
|
|
|
|
/* first mul, then blend the fac */
|
|
|
|
|
cp[0]= 255;
|
|
|
|
|
cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])/255) )/255;
|
|
|
|
|
cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])/255) )/255;
|
|
|
|
|
cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])/255) )/255;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return col;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac)
|
|
|
|
|
{
|
|
|
|
|
char *cp1, *cp2, *cp;
|
|
|
|
|
int mfac;
|
|
|
|
|
unsigned int col=0;
|
|
|
|
|
|
|
|
|
|
if(fac==0) return col1;
|
|
|
|
|
if(fac>=255) return col2;
|
|
|
|
|
|
|
|
|
|
mfac= 255-fac;
|
|
|
|
|
|
|
|
|
|
cp1= (char *)&col1;
|
|
|
|
|
cp2= (char *)&col2;
|
|
|
|
|
cp= (char *)&col;
|
|
|
|
|
|
|
|
|
|
/* See if are lighter, if so mix, else dont do anything.
|
|
|
|
|
if the paint col is darker then the original, then ignore */
|
|
|
|
|
if (cp1[1]+cp1[2]+cp1[3] > cp2[1]+cp2[2]+cp2[3])
|
|
|
|
|
return col1;
|
|
|
|
|
|
|
|
|
|
cp[0]= 255;
|
|
|
|
|
cp[1]= (mfac*cp1[1]+fac*cp2[1])/255;
|
|
|
|
|
cp[2]= (mfac*cp1[2]+fac*cp2[2])/255;
|
|
|
|
|
cp[3]= (mfac*cp1[3]+fac*cp2[3])/255;
|
|
|
|
|
|
|
|
|
|
return col;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac)
|
|
|
|
|
{
|
|
|
|
|
char *cp1, *cp2, *cp;
|
|
|
|
|
int mfac;
|
|
|
|
|
unsigned int col=0;
|
|
|
|
|
|
|
|
|
|
if(fac==0) return col1;
|
|
|
|
|
if(fac>=255) return col2;
|
|
|
|
|
|
|
|
|
|
mfac= 255-fac;
|
|
|
|
|
|
|
|
|
|
cp1= (char *)&col1;
|
|
|
|
|
cp2= (char *)&col2;
|
|
|
|
|
cp= (char *)&col;
|
|
|
|
|
|
|
|
|
|
/* See if were darker, if so mix, else dont do anything.
|
|
|
|
|
if the paint col is brighter then the original, then ignore */
|
|
|
|
|
if (cp1[1]+cp1[2]+cp1[3] < cp2[1]+cp2[2]+cp2[3])
|
|
|
|
|
return col1;
|
|
|
|
|
|
|
|
|
|
cp[0]= 255;
|
|
|
|
|
cp[1]= (mfac*cp1[1]+fac*cp2[1])/255;
|
|
|
|
|
cp[2]= (mfac*cp1[2]+fac*cp2[2])/255;
|
|
|
|
|
cp[3]= (mfac*cp1[3]+fac*cp2[3])/255;
|
|
|
|
|
return col;
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
static void vpaint_blend(VPaint *vp, unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha)
|
2009-01-07 19:23:22 +00:00
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&vp->paint);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(vp->mode==VP_MIX || vp->mode==VP_BLUR) *col= mcol_blend( *col, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_LIGHTEN) *col= mcol_lighten( *col, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_DARKEN) *col= mcol_darken( *col, paintcol, alpha);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
/* if no spray, clip color adding with colorig & orig alpha */
|
2009-01-10 14:19:14 +00:00
|
|
|
if((vp->flag & VP_SPRAY)==0) {
|
2009-01-07 19:23:22 +00:00
|
|
|
unsigned int testcol=0, a;
|
|
|
|
|
char *cp, *ct, *co;
|
|
|
|
|
|
2009-08-17 02:49:31 +00:00
|
|
|
alpha= (int)(255.0*brush->alpha);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(vp->mode==VP_MIX || vp->mode==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_LIGHTEN) testcol= mcol_lighten( *colorig, paintcol, alpha);
|
|
|
|
|
else if(vp->mode==VP_DARKEN) testcol= mcol_darken( *colorig, paintcol, alpha);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
cp= (char *)col;
|
|
|
|
|
ct= (char *)&testcol;
|
|
|
|
|
co= (char *)colorig;
|
|
|
|
|
|
|
|
|
|
for(a=0; a<4; a++) {
|
|
|
|
|
if( ct[a]<co[a] ) {
|
|
|
|
|
if( cp[a]<ct[a] ) cp[a]= ct[a];
|
|
|
|
|
else if( cp[a]>co[a] ) cp[a]= co[a];
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if( cp[a]<co[a] ) cp[a]= co[a];
|
|
|
|
|
else if( cp[a]>ct[a] ) cp[a]= ct[a];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x, int y, float size)
|
2009-01-07 19:23:22 +00:00
|
|
|
{
|
|
|
|
|
struct ImBuf *ibuf;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
int a, tot=0, index;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
if(totface+4>=MAXINDEX) return 0;
|
|
|
|
|
|
|
|
|
|
if(size>64.0) size= 64.0;
|
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
ibuf= view3d_read_backbuf(vc, x-size, y-size, x+size, y+size);
|
|
|
|
|
if(ibuf) {
|
|
|
|
|
unsigned int *rt= ibuf->rect;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
memset(indexar, 0, sizeof(int)*totface+4); /* plus 2! first element is total, +2 was giving valgrind errors, +4 seems ok */
|
|
|
|
|
|
|
|
|
|
size= ibuf->x*ibuf->y;
|
|
|
|
|
while(size--) {
|
|
|
|
|
|
|
|
|
|
if(*rt) {
|
|
|
|
|
index= WM_framebuffer_to_index(*rt);
|
|
|
|
|
if(index>0 && index<=totface)
|
|
|
|
|
indexar[index] = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rt++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(a=1; a<=totface; a++) {
|
|
|
|
|
if(indexar[a]) indexar[tot++]= a;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
IMB_freeImBuf(ibuf);
|
|
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
return tot;
|
|
|
|
|
}
|
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
static int calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, float vpimat[][3], float *vert_nor, short *mval)
|
2009-01-07 19:23:22 +00:00
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&vp->paint);
|
2009-01-07 19:23:22 +00:00
|
|
|
float fac, dx, dy;
|
|
|
|
|
int alpha;
|
|
|
|
|
short vertco[2];
|
|
|
|
|
|
|
|
|
|
if(vp->flag & VP_SOFT) {
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
project_short_noclip(vc->ar, vert_nor, vertco);
|
2009-01-07 19:23:22 +00:00
|
|
|
dx= mval[0]-vertco[0];
|
|
|
|
|
dy= mval[1]-vertco[1];
|
|
|
|
|
|
|
|
|
|
fac= sqrt(dx*dx + dy*dy);
|
2009-08-17 02:49:31 +00:00
|
|
|
if(fac > brush->size) return 0;
|
2009-01-07 19:23:22 +00:00
|
|
|
if(vp->flag & VP_HARD)
|
|
|
|
|
alpha= 255;
|
|
|
|
|
else
|
2009-08-17 02:49:31 +00:00
|
|
|
alpha= 255.0*brush->alpha*(1.0-fac/brush->size);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-08-17 02:49:31 +00:00
|
|
|
alpha= 255.0*brush->alpha;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(vp->flag & VP_NORMALS) {
|
|
|
|
|
float *no= vert_nor+3;
|
|
|
|
|
|
|
|
|
|
/* transpose ! */
|
|
|
|
|
fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2];
|
|
|
|
|
if(fac>0.0) {
|
|
|
|
|
dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2];
|
|
|
|
|
dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2];
|
|
|
|
|
|
|
|
|
|
alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
|
|
|
|
|
}
|
|
|
|
|
else return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return alpha;
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval)
|
2009-01-07 19:23:22 +00:00
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&wp->paint);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
if(dw==NULL || uw==NULL) return;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->mode==VP_MIX || wp->mode==VP_BLUR)
|
2009-01-07 19:23:22 +00:00
|
|
|
dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
|
2009-01-10 14:19:14 +00:00
|
|
|
else if(wp->mode==VP_ADD)
|
2009-01-07 19:23:22 +00:00
|
|
|
dw->weight += paintval*alpha;
|
2009-01-10 14:19:14 +00:00
|
|
|
else if(wp->mode==VP_SUB)
|
2009-01-07 19:23:22 +00:00
|
|
|
dw->weight -= paintval*alpha;
|
2009-01-10 14:19:14 +00:00
|
|
|
else if(wp->mode==VP_MUL)
|
2009-01-07 19:23:22 +00:00
|
|
|
/* first mul, then blend the fac */
|
|
|
|
|
dw->weight = ((1.0-alpha) + alpha*paintval)*dw->weight;
|
2009-01-10 14:19:14 +00:00
|
|
|
else if(wp->mode==VP_LIGHTEN) {
|
2009-01-07 19:23:22 +00:00
|
|
|
if (dw->weight < paintval)
|
|
|
|
|
dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
|
2009-01-10 14:19:14 +00:00
|
|
|
} else if(wp->mode==VP_DARKEN) {
|
2009-01-07 19:23:22 +00:00
|
|
|
if (dw->weight > paintval)
|
|
|
|
|
dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
|
|
|
|
|
}
|
|
|
|
|
CLAMP(dw->weight, 0.0f, 1.0f);
|
|
|
|
|
|
|
|
|
|
/* if no spray, clip result with orig weight & orig alpha */
|
2009-01-10 14:19:14 +00:00
|
|
|
if((wp->flag & VP_SPRAY)==0) {
|
2009-01-07 19:23:22 +00:00
|
|
|
float testw=0.0f;
|
|
|
|
|
|
2009-08-17 02:49:31 +00:00
|
|
|
alpha= brush->alpha;
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->mode==VP_MIX || wp->mode==VP_BLUR)
|
2009-01-07 19:23:22 +00:00
|
|
|
testw = paintval*alpha + uw->weight*(1.0-alpha);
|
2009-01-10 14:19:14 +00:00
|
|
|
else if(wp->mode==VP_ADD)
|
2009-01-07 19:23:22 +00:00
|
|
|
testw = uw->weight + paintval*alpha;
|
2009-01-10 14:19:14 +00:00
|
|
|
else if(wp->mode==VP_SUB)
|
2009-01-07 19:23:22 +00:00
|
|
|
testw = uw->weight - paintval*alpha;
|
2009-01-10 14:19:14 +00:00
|
|
|
else if(wp->mode==VP_MUL)
|
2009-01-07 19:23:22 +00:00
|
|
|
/* first mul, then blend the fac */
|
|
|
|
|
testw = ((1.0-alpha) + alpha*paintval)*uw->weight;
|
2009-01-10 14:19:14 +00:00
|
|
|
else if(wp->mode==VP_LIGHTEN) {
|
2009-01-07 19:23:22 +00:00
|
|
|
if (uw->weight < paintval)
|
|
|
|
|
testw = paintval*alpha + uw->weight*(1.0-alpha);
|
|
|
|
|
else
|
|
|
|
|
testw = uw->weight;
|
2009-01-10 14:19:14 +00:00
|
|
|
} else if(wp->mode==VP_DARKEN) {
|
2009-01-07 19:23:22 +00:00
|
|
|
if (uw->weight > paintval)
|
|
|
|
|
testw = paintval*alpha + uw->weight*(1.0-alpha);
|
|
|
|
|
else
|
|
|
|
|
testw = uw->weight;
|
|
|
|
|
}
|
|
|
|
|
CLAMP(testw, 0.0f, 1.0f);
|
|
|
|
|
|
|
|
|
|
if( testw<uw->weight ) {
|
|
|
|
|
if(dw->weight < testw) dw->weight= testw;
|
|
|
|
|
else if(dw->weight > uw->weight) dw->weight= uw->weight;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if(dw->weight > testw) dw->weight= testw;
|
|
|
|
|
else if(dw->weight < uw->weight) dw->weight= uw->weight;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/* used for 3d view, on active object, assumes me->dvert exists */
|
|
|
|
|
/* if mode==1: */
|
|
|
|
|
/* samples cursor location, and gives menu with vertex groups to activate */
|
|
|
|
|
/* else */
|
2009-01-10 17:20:34 +00:00
|
|
|
/* sets wp->weight to the closest weight value to vertex */
|
2009-01-07 19:23:22 +00:00
|
|
|
/* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
|
2009-01-10 14:19:14 +00:00
|
|
|
void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode)
|
2009-01-07 19:23:22 +00:00
|
|
|
{
|
|
|
|
|
ViewContext vc;
|
2009-07-09 19:49:04 +00:00
|
|
|
ToolSettings *ts= scene->toolsettings;
|
2009-01-07 19:23:22 +00:00
|
|
|
Object *ob= OBACT;
|
|
|
|
|
Mesh *me= get_mesh(ob);
|
|
|
|
|
int index;
|
|
|
|
|
short mval[2], sco[2];
|
|
|
|
|
|
|
|
|
|
if (!me) return;
|
|
|
|
|
|
|
|
|
|
// getmouseco_areawin(mval);
|
|
|
|
|
index= view3d_sample_backbuf(&vc, mval[0], mval[1]);
|
|
|
|
|
|
|
|
|
|
if(index && index<=me->totface) {
|
|
|
|
|
MFace *mface;
|
|
|
|
|
|
|
|
|
|
mface= ((MFace *)me->mface) + index-1;
|
|
|
|
|
|
|
|
|
|
if(mode==1) { /* sampe which groups are in here */
|
|
|
|
|
MDeformVert *dv;
|
|
|
|
|
int a, totgroup;
|
|
|
|
|
|
|
|
|
|
totgroup= BLI_countlist(&ob->defbase);
|
|
|
|
|
if(totgroup) {
|
|
|
|
|
int totmenu=0;
|
|
|
|
|
int *groups=MEM_callocN(totgroup*sizeof(int), "groups");
|
|
|
|
|
|
|
|
|
|
dv= me->dvert+mface->v1;
|
|
|
|
|
for(a=0; a<dv->totweight; a++) {
|
|
|
|
|
if (dv->dw[a].def_nr<totgroup)
|
|
|
|
|
groups[dv->dw[a].def_nr]= 1;
|
|
|
|
|
}
|
|
|
|
|
dv= me->dvert+mface->v2;
|
|
|
|
|
for(a=0; a<dv->totweight; a++) {
|
|
|
|
|
if (dv->dw[a].def_nr<totgroup)
|
|
|
|
|
groups[dv->dw[a].def_nr]= 1;
|
|
|
|
|
}
|
|
|
|
|
dv= me->dvert+mface->v3;
|
|
|
|
|
for(a=0; a<dv->totweight; a++) {
|
|
|
|
|
if (dv->dw[a].def_nr<totgroup)
|
|
|
|
|
groups[dv->dw[a].def_nr]= 1;
|
|
|
|
|
}
|
|
|
|
|
if(mface->v4) {
|
|
|
|
|
dv= me->dvert+mface->v4;
|
|
|
|
|
for(a=0; a<dv->totweight; a++) {
|
|
|
|
|
if (dv->dw[a].def_nr<totgroup)
|
|
|
|
|
groups[dv->dw[a].def_nr]= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for(a=0; a<totgroup; a++)
|
|
|
|
|
if(groups[a]) totmenu++;
|
|
|
|
|
|
|
|
|
|
if(totmenu==0) {
|
|
|
|
|
//notice("No Vertex Group Selected");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
bDeformGroup *dg;
|
|
|
|
|
short val;
|
|
|
|
|
char item[40], *str= MEM_mallocN(40*totmenu+40, "menu");
|
|
|
|
|
|
|
|
|
|
strcpy(str, "Vertex Groups %t");
|
|
|
|
|
for(a=0, dg=ob->defbase.first; dg && a<totgroup; a++, dg= dg->next) {
|
|
|
|
|
if(groups[a]) {
|
|
|
|
|
sprintf(item, "|%s %%x%d", dg->name, a);
|
|
|
|
|
strcat(str, item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val= 0; // XXX pupmenu(str);
|
|
|
|
|
if(val>=0) {
|
|
|
|
|
ob->actdef= val+1;
|
|
|
|
|
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
|
|
|
|
}
|
|
|
|
|
MEM_freeN(str);
|
|
|
|
|
}
|
|
|
|
|
MEM_freeN(groups);
|
|
|
|
|
}
|
|
|
|
|
// else notice("No Vertex Groups in Object");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
DerivedMesh *dm;
|
|
|
|
|
MDeformWeight *dw;
|
|
|
|
|
float w1, w2, w3, w4, co[3], fac;
|
|
|
|
|
|
|
|
|
|
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
|
|
|
|
if(dm->getVertCo==NULL) {
|
|
|
|
|
//notice("Not supported yet");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* calc 3 or 4 corner weights */
|
|
|
|
|
dm->getVertCo(dm, mface->v1, co);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
project_short_noclip(ar, co, sco);
|
2009-01-07 19:23:22 +00:00
|
|
|
w1= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
|
|
|
|
|
|
|
|
|
|
dm->getVertCo(dm, mface->v2, co);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
project_short_noclip(ar, co, sco);
|
2009-01-07 19:23:22 +00:00
|
|
|
w2= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
|
|
|
|
|
|
|
|
|
|
dm->getVertCo(dm, mface->v3, co);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
project_short_noclip(ar, co, sco);
|
2009-01-07 19:23:22 +00:00
|
|
|
w3= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
|
|
|
|
|
|
|
|
|
|
if(mface->v4) {
|
|
|
|
|
dm->getVertCo(dm, mface->v4, co);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
project_short_noclip(ar, co, sco);
|
2009-01-07 19:23:22 +00:00
|
|
|
w4= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
|
|
|
|
|
}
|
|
|
|
|
else w4= 1.0e10;
|
|
|
|
|
|
|
|
|
|
fac= MIN4(w1, w2, w3, w4);
|
|
|
|
|
if(w1==fac) {
|
|
|
|
|
dw= get_defweight(me->dvert+mface->v1, ob->actdef-1);
|
2009-07-09 19:49:04 +00:00
|
|
|
if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
else if(w2==fac) {
|
|
|
|
|
dw= get_defweight(me->dvert+mface->v2, ob->actdef-1);
|
2009-07-09 19:49:04 +00:00
|
|
|
if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
else if(w3==fac) {
|
|
|
|
|
dw= get_defweight(me->dvert+mface->v3, ob->actdef-1);
|
2009-07-09 19:49:04 +00:00
|
|
|
if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
else if(w4==fac) {
|
|
|
|
|
if(mface->v4) {
|
|
|
|
|
dw= get_defweight(me->dvert+mface->v4, ob->actdef-1);
|
2009-07-09 19:49:04 +00:00
|
|
|
if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dm->release(dm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, int alpha, float paintweight, int vgroup_mirror)
|
2009-01-07 19:23:22 +00:00
|
|
|
{
|
|
|
|
|
Mesh *me= ob->data;
|
2009-01-10 14:19:14 +00:00
|
|
|
MDeformWeight *dw, *uw;
|
2009-01-07 19:23:22 +00:00
|
|
|
int vgroup= ob->actdef-1;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->flag & VP_ONLYVGROUP) {
|
2009-01-07 19:23:22 +00:00
|
|
|
dw= get_defweight(me->dvert+index, vgroup);
|
2009-01-10 14:19:14 +00:00
|
|
|
uw= get_defweight(wp->wpaint_prev+index, vgroup);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
dw= verify_defweight(me->dvert+index, vgroup);
|
2009-01-10 14:19:14 +00:00
|
|
|
uw= verify_defweight(wp->wpaint_prev+index, vgroup);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
if(dw==NULL || uw==NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
wpaint_blend(wp, dw, uw, (float)alpha/255.0, paintweight);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->flag & VP_MIRROR_X) { /* x mirror painting */
|
2009-01-07 19:23:22 +00:00
|
|
|
int j= mesh_get_x_mirror_vert(ob, index);
|
|
|
|
|
if(j>=0) {
|
|
|
|
|
/* copy, not paint again */
|
|
|
|
|
if(vgroup_mirror != -1)
|
|
|
|
|
uw= verify_defweight(me->dvert+j, vgroup_mirror);
|
|
|
|
|
else
|
|
|
|
|
uw= verify_defweight(me->dvert+j, vgroup);
|
|
|
|
|
|
|
|
|
|
uw->weight= dw->weight;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* *************** set wpaint operator ****************** */
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
static int set_wpaint(bContext *C, wmOperator *op) /* toggle */
|
|
|
|
|
{
|
|
|
|
|
Object *ob= CTX_data_active_object(C);
|
|
|
|
|
Scene *scene= CTX_data_scene(C);
|
|
|
|
|
VPaint *wp= scene->toolsettings->wpaint;
|
|
|
|
|
Mesh *me;
|
|
|
|
|
|
2009-01-07 19:23:22 +00:00
|
|
|
me= get_mesh(ob);
|
2009-07-25 13:40:59 +00:00
|
|
|
if(ob->id.lib || me==NULL) return OPERATOR_PASS_THROUGH;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(me && me->totface>=MAXINDEX) {
|
|
|
|
|
error("Maximum number of faces: %d", MAXINDEX-1);
|
2009-08-15 21:46:25 +00:00
|
|
|
ob->mode &= ~OB_MODE_WEIGHT_PAINT;
|
2009-01-10 14:19:14 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-15 21:46:25 +00:00
|
|
|
if(ob->mode & OB_MODE_WEIGHT_PAINT) ob->mode &= ~OB_MODE_WEIGHT_PAINT;
|
|
|
|
|
else ob->mode |= OB_MODE_WEIGHT_PAINT;
|
2009-01-10 14:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Weightpaint works by overriding colors in mesh,
|
|
|
|
|
* so need to make sure we recalc on enter and
|
|
|
|
|
* exit (exit needs doing regardless because we
|
|
|
|
|
* should redeform).
|
|
|
|
|
*/
|
|
|
|
|
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
|
|
|
|
|
2009-08-15 21:46:25 +00:00
|
|
|
if(ob->mode & OB_MODE_WEIGHT_PAINT) {
|
2009-01-10 14:19:14 +00:00
|
|
|
Object *par;
|
|
|
|
|
|
|
|
|
|
if(wp==NULL)
|
|
|
|
|
wp= scene->toolsettings->wpaint= new_vpaint(1);
|
2009-03-11 00:43:08 +00:00
|
|
|
|
2009-08-17 02:49:31 +00:00
|
|
|
paint_init(&wp->paint, "Brush");
|
|
|
|
|
|
2009-01-25 21:02:52 +00:00
|
|
|
toggle_paint_cursor(C, 1);
|
2009-01-10 14:19:14 +00:00
|
|
|
|
|
|
|
|
mesh_octree_table(ob, NULL, NULL, 's');
|
|
|
|
|
|
|
|
|
|
/* verify if active weight group is also active bone */
|
|
|
|
|
par= modifiers_isDeformedByArmature(ob);
|
2009-08-16 03:24:23 +00:00
|
|
|
if(par && (par->mode & OB_MODE_POSE)) {
|
2009-01-07 19:23:22 +00:00
|
|
|
bPoseChannel *pchan;
|
2009-01-10 14:19:14 +00:00
|
|
|
for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next)
|
|
|
|
|
if(pchan->bone->flag & BONE_ACTIVE)
|
2009-01-07 19:23:22 +00:00
|
|
|
break;
|
2009-01-10 14:19:14 +00:00
|
|
|
if(pchan)
|
|
|
|
|
vertexgroup_select_by_name(ob, pchan->name);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
2009-01-10 14:19:14 +00:00
|
|
|
else {
|
|
|
|
|
if(wp)
|
2009-01-25 21:02:52 +00:00
|
|
|
toggle_paint_cursor(C, 1);
|
2009-01-10 14:19:14 +00:00
|
|
|
|
|
|
|
|
mesh_octree_table(ob, NULL, NULL, 'e');
|
|
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-02-10 15:38:00 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_MODE, scene);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-01 13:24:19 +00:00
|
|
|
/* for switching to/from mode */
|
|
|
|
|
static int paint_poll_test(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
if(ED_operator_view3d_active(C)==0)
|
|
|
|
|
return 0;
|
|
|
|
|
if(CTX_data_edit_object(C))
|
|
|
|
|
return 0;
|
|
|
|
|
if(CTX_data_active_object(C)==NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-19 23:53:40 +00:00
|
|
|
void PAINT_OT_weight_paint_toggle(wmOperatorType *ot)
|
2009-01-10 14:19:14 +00:00
|
|
|
{
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name= "Weight Paint Mode";
|
2009-02-19 23:53:40 +00:00
|
|
|
ot->idname= "PAINT_OT_weight_paint_toggle";
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec= set_wpaint;
|
2009-02-01 13:24:19 +00:00
|
|
|
ot->poll= paint_poll_test;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-25 21:02:52 +00:00
|
|
|
/* ************ paint radial controls *************/
|
|
|
|
|
|
|
|
|
|
static int vpaint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->vpaint->paint);
|
|
|
|
|
|
2009-01-25 21:02:52 +00:00
|
|
|
toggle_paint_cursor(C, 0);
|
2009-08-17 02:49:31 +00:00
|
|
|
brush_radial_control_invoke(op, brush, 1);
|
2009-01-25 21:02:52 +00:00
|
|
|
return WM_radial_control_invoke(C, op, event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int vpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
int ret = WM_radial_control_modal(C, op, event);
|
|
|
|
|
if(ret != OPERATOR_RUNNING_MODAL)
|
|
|
|
|
toggle_paint_cursor(C, 0);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int vpaint_radial_control_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->vpaint->paint);
|
|
|
|
|
return brush_radial_control_exec(op, brush, 1);
|
2009-01-25 21:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int wpaint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->wpaint->paint);
|
2009-01-25 21:02:52 +00:00
|
|
|
toggle_paint_cursor(C, 1);
|
2009-08-17 02:49:31 +00:00
|
|
|
brush_radial_control_invoke(op, brush, 1);
|
2009-01-25 21:02:52 +00:00
|
|
|
return WM_radial_control_invoke(C, op, event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int wpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
int ret = WM_radial_control_modal(C, op, event);
|
|
|
|
|
if(ret != OPERATOR_RUNNING_MODAL)
|
|
|
|
|
toggle_paint_cursor(C, 1);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int wpaint_radial_control_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->wpaint->paint);
|
|
|
|
|
return brush_radial_control_exec(op, brush, 1);
|
2009-01-25 21:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-19 23:53:40 +00:00
|
|
|
void PAINT_OT_weight_paint_radial_control(wmOperatorType *ot)
|
2009-01-25 21:02:52 +00:00
|
|
|
{
|
|
|
|
|
WM_OT_radial_control_partial(ot);
|
|
|
|
|
|
|
|
|
|
ot->name= "Weight Paint Radial Control";
|
2009-02-19 23:53:40 +00:00
|
|
|
ot->idname= "PAINT_OT_weight_paint_radial_control";
|
2009-01-25 21:02:52 +00:00
|
|
|
|
|
|
|
|
ot->invoke= wpaint_radial_control_invoke;
|
|
|
|
|
ot->modal= wpaint_radial_control_modal;
|
|
|
|
|
ot->exec= wpaint_radial_control_exec;
|
|
|
|
|
ot->poll= wp_poll;
|
2009-01-31 19:40:40 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2009-07-11 14:51:13 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
|
2009-01-25 21:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-19 23:53:40 +00:00
|
|
|
void PAINT_OT_vertex_paint_radial_control(wmOperatorType *ot)
|
2009-01-25 21:02:52 +00:00
|
|
|
{
|
|
|
|
|
WM_OT_radial_control_partial(ot);
|
|
|
|
|
|
|
|
|
|
ot->name= "Vertex Paint Radial Control";
|
2009-02-19 23:53:40 +00:00
|
|
|
ot->idname= "PAINT_OT_vertex_paint_radial_control";
|
2009-01-25 21:02:52 +00:00
|
|
|
|
|
|
|
|
ot->invoke= vpaint_radial_control_invoke;
|
|
|
|
|
ot->modal= vpaint_radial_control_modal;
|
|
|
|
|
ot->exec= vpaint_radial_control_exec;
|
|
|
|
|
ot->poll= vp_poll;
|
2009-01-31 19:40:40 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2009-07-11 14:51:13 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
|
2009-01-25 21:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* ************ weight paint operator ********** */
|
|
|
|
|
|
|
|
|
|
struct WPaintData {
|
|
|
|
|
ViewContext vc;
|
|
|
|
|
int *indexar;
|
|
|
|
|
int vgroup_mirror;
|
|
|
|
|
float *vertexcosnos;
|
|
|
|
|
float wpimat[3][3];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void wpaint_exit(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
ToolSettings *ts= CTX_data_tool_settings(C);
|
|
|
|
|
Object *ob= CTX_data_active_object(C);
|
|
|
|
|
struct WPaintData *wpd= op->customdata;
|
|
|
|
|
|
|
|
|
|
if(wpd->vertexcosnos)
|
|
|
|
|
MEM_freeN(wpd->vertexcosnos);
|
|
|
|
|
MEM_freeN(wpd->indexar);
|
|
|
|
|
|
|
|
|
|
/* frees prev buffer */
|
|
|
|
|
copy_wpaint_prev(ts->wpaint, NULL, 0);
|
|
|
|
|
|
|
|
|
|
/* and particles too */
|
|
|
|
|
if(ob->particlesystem.first) {
|
|
|
|
|
ParticleSystem *psys;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for(psys= ob->particlesystem.first; psys; psys= psys->next) {
|
|
|
|
|
for(i=0; i<PSYS_TOT_VG; i++) {
|
|
|
|
|
if(psys->vgroup[i]==ob->actdef) {
|
2009-06-05 23:59:33 +00:00
|
|
|
psys->recalc |= PSYS_RECALC_RESET;
|
2009-01-07 19:23:22 +00:00
|
|
|
break;
|
2009-01-10 14:19:14 +00:00
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
DAG_object_flush_update(CTX_data_scene(C), ob, OB_RECALC_DATA);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(wpd);
|
|
|
|
|
op->customdata= NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int wpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
ToolSettings *ts= CTX_data_tool_settings(C);
|
|
|
|
|
VPaint *wp= ts->wpaint;
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&wp->paint);
|
2009-01-10 14:19:14 +00:00
|
|
|
|
|
|
|
|
switch(event->type) {
|
|
|
|
|
case LEFTMOUSE:
|
|
|
|
|
if(event->val==0) { /* release */
|
|
|
|
|
wpaint_exit(C, op);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
/* pass on, first press gets painted too */
|
|
|
|
|
|
|
|
|
|
case MOUSEMOVE:
|
|
|
|
|
{
|
|
|
|
|
struct WPaintData *wpd= op->customdata;
|
|
|
|
|
ViewContext *vc= &wpd->vc;
|
|
|
|
|
Object *ob= vc->obact;
|
|
|
|
|
Mesh *me= ob->data;
|
|
|
|
|
float mat[4][4];
|
2009-07-09 19:49:04 +00:00
|
|
|
float paintweight= ts->vgroup_weight;
|
2009-01-10 14:19:14 +00:00
|
|
|
int *indexar= wpd->indexar;
|
|
|
|
|
int totindex, index, alpha, totw;
|
2009-02-19 23:53:40 +00:00
|
|
|
short mval[2];
|
2009-01-10 14:19:14 +00:00
|
|
|
|
|
|
|
|
view3d_operator_needs_opengl(C);
|
|
|
|
|
|
|
|
|
|
/* load projection matrix */
|
|
|
|
|
wmMultMatrix(ob->obmat);
|
|
|
|
|
wmGetSingleMatrix(mat);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
wmLoadMatrix(wpd->vc.rv3d->viewmat);
|
2009-01-10 14:19:14 +00:00
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
MTC_Mat4SwapMat4(wpd->vc.rv3d->persmat, mat);
|
2009-01-10 14:19:14 +00:00
|
|
|
|
2009-02-19 23:53:40 +00:00
|
|
|
mval[0]= event->x - vc->ar->winrct.xmin;
|
|
|
|
|
mval[1]= event->y - vc->ar->winrct.ymin;
|
|
|
|
|
|
2009-01-07 19:23:22 +00:00
|
|
|
/* which faces are involved */
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->flag & VP_AREA) {
|
2009-08-17 02:49:31 +00:00
|
|
|
totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush->size);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-02-19 23:53:40 +00:00
|
|
|
indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);
|
2009-01-07 19:23:22 +00:00
|
|
|
if(indexar[0]) totindex= 1;
|
|
|
|
|
else totindex= 0;
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->flag & VP_COLINDEX) {
|
2009-01-07 19:23:22 +00:00
|
|
|
for(index=0; index<totindex; index++) {
|
|
|
|
|
if(indexar[index] && indexar[index]<=me->totface) {
|
2009-01-10 14:19:14 +00:00
|
|
|
MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
|
|
|
|
|
|
2009-01-07 19:23:22 +00:00
|
|
|
if(mface->mat_nr!=ob->actcol-1) {
|
|
|
|
|
indexar[index]= 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-01-10 14:19:14 +00:00
|
|
|
|
2009-01-07 19:23:22 +00:00
|
|
|
if((G.f & G_FACESELECT) && me->mface) {
|
|
|
|
|
for(index=0; index<totindex; index++) {
|
|
|
|
|
if(indexar[index] && indexar[index]<=me->totface) {
|
2009-01-10 14:19:14 +00:00
|
|
|
MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
|
|
|
|
|
|
2009-01-07 19:23:22 +00:00
|
|
|
if((mface->flag & ME_FACE_SEL)==0) {
|
|
|
|
|
indexar[index]= 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* make sure each vertex gets treated only once */
|
|
|
|
|
/* and calculate filter weight */
|
|
|
|
|
totw= 0;
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->mode==VP_BLUR)
|
2009-01-07 19:23:22 +00:00
|
|
|
paintweight= 0.0f;
|
|
|
|
|
else
|
2009-07-09 19:49:04 +00:00
|
|
|
paintweight= ts->vgroup_weight;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
for(index=0; index<totindex; index++) {
|
|
|
|
|
if(indexar[index] && indexar[index]<=me->totface) {
|
2009-01-10 14:19:14 +00:00
|
|
|
MFace *mface= me->mface + (indexar[index]-1);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
(me->dvert+mface->v1)->flag= 1;
|
|
|
|
|
(me->dvert+mface->v2)->flag= 1;
|
|
|
|
|
(me->dvert+mface->v3)->flag= 1;
|
|
|
|
|
if(mface->v4) (me->dvert+mface->v4)->flag= 1;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->mode==VP_BLUR) {
|
2009-01-07 19:23:22 +00:00
|
|
|
MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = verify_defweight;
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->flag & VP_ONLYVGROUP)
|
2009-01-07 19:23:22 +00:00
|
|
|
dw_func= get_defweight;
|
|
|
|
|
|
|
|
|
|
dw= dw_func(me->dvert+mface->v1, ob->actdef-1);
|
|
|
|
|
if(dw) {paintweight+= dw->weight; totw++;}
|
|
|
|
|
dw= dw_func(me->dvert+mface->v2, ob->actdef-1);
|
|
|
|
|
if(dw) {paintweight+= dw->weight; totw++;}
|
|
|
|
|
dw= dw_func(me->dvert+mface->v3, ob->actdef-1);
|
|
|
|
|
if(dw) {paintweight+= dw->weight; totw++;}
|
|
|
|
|
if(mface->v4) {
|
|
|
|
|
dw= dw_func(me->dvert+mface->v4, ob->actdef-1);
|
|
|
|
|
if(dw) {paintweight+= dw->weight; totw++;}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(wp->mode==VP_BLUR)
|
2009-01-07 19:23:22 +00:00
|
|
|
paintweight/= (float)totw;
|
|
|
|
|
|
|
|
|
|
for(index=0; index<totindex; index++) {
|
|
|
|
|
|
|
|
|
|
if(indexar[index] && indexar[index]<=me->totface) {
|
2009-01-10 14:19:14 +00:00
|
|
|
MFace *mface= me->mface + (indexar[index]-1);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
if((me->dvert+mface->v1)->flag) {
|
2009-02-19 23:53:40 +00:00
|
|
|
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v1, mval);
|
2009-01-07 19:23:22 +00:00
|
|
|
if(alpha) {
|
2009-01-10 14:19:14 +00:00
|
|
|
do_weight_paint_vertex(wp, ob, mface->v1, alpha, paintweight, wpd->vgroup_mirror);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
(me->dvert+mface->v1)->flag= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if((me->dvert+mface->v2)->flag) {
|
2009-02-19 23:53:40 +00:00
|
|
|
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v2, mval);
|
2009-01-07 19:23:22 +00:00
|
|
|
if(alpha) {
|
2009-01-10 14:19:14 +00:00
|
|
|
do_weight_paint_vertex(wp, ob, mface->v2, alpha, paintweight, wpd->vgroup_mirror);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
(me->dvert+mface->v2)->flag= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if((me->dvert+mface->v3)->flag) {
|
2009-02-19 23:53:40 +00:00
|
|
|
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v3, mval);
|
2009-01-07 19:23:22 +00:00
|
|
|
if(alpha) {
|
2009-01-10 14:19:14 +00:00
|
|
|
do_weight_paint_vertex(wp, ob, mface->v3, alpha, paintweight, wpd->vgroup_mirror);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
(me->dvert+mface->v3)->flag= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if((me->dvert+mface->v4)->flag) {
|
|
|
|
|
if(mface->v4) {
|
2009-02-19 23:53:40 +00:00
|
|
|
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v4, mval);
|
2009-01-07 19:23:22 +00:00
|
|
|
if(alpha) {
|
2009-01-10 14:19:14 +00:00
|
|
|
do_weight_paint_vertex(wp, ob, mface->v4, alpha, paintweight, wpd->vgroup_mirror);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
(me->dvert+mface->v4)->flag= 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
MTC_Mat4SwapMat4(vc->rv3d->persmat, mat);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
DAG_object_flush_update(vc->scene, ob, OB_RECALC_DATA);
|
|
|
|
|
ED_region_tag_redraw(vc->ar);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
Scene *scene= CTX_data_scene(C);
|
2009-01-10 14:19:14 +00:00
|
|
|
ToolSettings *ts= CTX_data_tool_settings(C);
|
|
|
|
|
VPaint *wp= ts->wpaint;
|
|
|
|
|
Object *ob= CTX_data_active_object(C);
|
|
|
|
|
struct WPaintData *wpd;
|
2009-01-07 19:23:22 +00:00
|
|
|
Mesh *me;
|
2009-01-10 14:19:14 +00:00
|
|
|
float mat[4][4], imat[4][4];
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(scene->obedit) return OPERATOR_CANCELLED;
|
|
|
|
|
// XXX if(multires_level1_test()) return;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
me= get_mesh(ob);
|
2009-07-25 13:40:59 +00:00
|
|
|
if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* if nothing was added yet, we make dverts and a vertex deform group */
|
|
|
|
|
if (!me->dvert)
|
|
|
|
|
create_dverts(&me->id);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* make customdata storage */
|
|
|
|
|
op->customdata= wpd= MEM_callocN(sizeof(struct WPaintData), "WPaintData");
|
|
|
|
|
view3d_set_viewcontext(C, &wpd->vc);
|
|
|
|
|
wpd->vgroup_mirror= -1;
|
|
|
|
|
|
|
|
|
|
// if(qual & LR_CTRLKEY) {
|
|
|
|
|
// sample_wpaint(scene, ar, v3d, 0);
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
// if(qual & LR_SHIFTKEY) {
|
|
|
|
|
// sample_wpaint(scene, ar, v3d, 1);
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* ALLOCATIONS! no return after this line */
|
|
|
|
|
/* painting on subsurfs should give correct points too, this returns me->totvert amount */
|
|
|
|
|
wpd->vertexcosnos= mesh_get_mapped_verts_nors(scene, ob);
|
|
|
|
|
wpd->indexar= get_indexarray();
|
|
|
|
|
copy_wpaint_prev(wp, me->dvert, me->totvert);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
/* this happens on a Bone select, when no vgroup existed yet */
|
|
|
|
|
if(ob->actdef<=0) {
|
|
|
|
|
Object *modob;
|
|
|
|
|
if((modob = modifiers_isDeformedByArmature(ob))) {
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
bPoseChannel *pchan;
|
2009-01-10 14:19:14 +00:00
|
|
|
for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next)
|
|
|
|
|
if(pchan->bone->flag & SELECT)
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
break;
|
2009-01-10 14:19:14 +00:00
|
|
|
if(pchan) {
|
|
|
|
|
bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name);
|
|
|
|
|
if(dg==NULL)
|
|
|
|
|
dg= add_defgroup_name(ob, pchan->name); /* sets actdef */
|
|
|
|
|
else
|
|
|
|
|
ob->actdef= get_defgroup_num(ob, dg);
|
|
|
|
|
}
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
2009-01-10 14:19:14 +00:00
|
|
|
if(ob->defbase.first==NULL) {
|
|
|
|
|
add_defgroup(ob);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if(ob->lay & v3d->lay); else error("Active object is not in this layer");
|
|
|
|
|
|
|
|
|
|
/* imat for normals */
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
Mat4MulMat4(mat, ob->obmat, wpd->vc.rv3d->viewmat);
|
2009-01-10 14:19:14 +00:00
|
|
|
Mat4Invert(imat, mat);
|
|
|
|
|
Mat3CpyMat4(wpd->wpimat, imat);
|
|
|
|
|
|
|
|
|
|
/* if mirror painting, find the other group */
|
|
|
|
|
if(wp->flag & VP_MIRROR_X) {
|
|
|
|
|
bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
|
|
|
|
|
if(defgroup) {
|
|
|
|
|
bDeformGroup *curdef;
|
|
|
|
|
int actdef= 0;
|
|
|
|
|
char name[32];
|
|
|
|
|
|
|
|
|
|
BLI_strncpy(name, defgroup->name, 32);
|
|
|
|
|
bone_flip_name(name, 0); /* 0 = don't strip off number extensions */
|
|
|
|
|
|
|
|
|
|
for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
|
|
|
|
|
if (!strcmp(curdef->name, name))
|
|
|
|
|
break;
|
|
|
|
|
if(curdef==NULL) {
|
|
|
|
|
int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
|
|
|
|
|
curdef= add_defgroup_name (ob, name);
|
|
|
|
|
ob->actdef= olddef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(curdef && curdef!=defgroup)
|
|
|
|
|
wpd->vgroup_mirror= actdef;
|
|
|
|
|
}
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
}
|
2009-01-10 14:19:14 +00:00
|
|
|
|
|
|
|
|
/* do paint once for click only paint */
|
|
|
|
|
wpaint_modal(C, op, event);
|
|
|
|
|
|
|
|
|
|
/* add modal handler */
|
|
|
|
|
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-19 23:53:40 +00:00
|
|
|
void PAINT_OT_weight_paint(wmOperatorType *ot)
|
2009-01-10 14:19:14 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name= "Weight Paint";
|
2009-02-19 23:53:40 +00:00
|
|
|
ot->idname= "PAINT_OT_weight_paint";
|
2009-01-10 14:19:14 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke= wpaint_invoke;
|
|
|
|
|
ot->modal= wpaint_modal;
|
|
|
|
|
/* ot->exec= vpaint_exec; <-- needs stroke property */
|
|
|
|
|
ot->poll= wp_poll;
|
|
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2009-07-11 14:51:13 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
|
2009-01-31 19:40:40 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ************ set / clear vertex paint mode ********** */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int set_vpaint(bContext *C, wmOperator *op) /* toggle */
|
|
|
|
|
{
|
|
|
|
|
Object *ob= CTX_data_active_object(C);
|
|
|
|
|
Scene *scene= CTX_data_scene(C);
|
2009-01-10 14:19:14 +00:00
|
|
|
VPaint *vp= scene->toolsettings->vpaint;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
Mesh *me;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-02-10 15:38:00 +00:00
|
|
|
me= get_mesh(ob);
|
|
|
|
|
|
|
|
|
|
if(me==NULL || object_data_is_libdata(ob)) {
|
2009-08-15 20:36:15 +00:00
|
|
|
ob->mode &= ~OB_MODE_VERTEX_PAINT;
|
2009-07-25 13:40:59 +00:00
|
|
|
return OPERATOR_PASS_THROUGH;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
if(me && me->totface>=MAXINDEX) {
|
|
|
|
|
error("Maximum number of faces: %d", MAXINDEX-1);
|
2009-08-15 20:36:15 +00:00
|
|
|
ob->mode &= ~OB_MODE_VERTEX_PAINT;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(me && me->mcol==NULL) make_vertexcol(scene, 0);
|
|
|
|
|
|
|
|
|
|
/* toggle: end vpaint */
|
2009-08-15 20:36:15 +00:00
|
|
|
if(ob->mode & OB_MODE_VERTEX_PAINT) {
|
2009-01-10 14:19:14 +00:00
|
|
|
|
2009-08-15 20:36:15 +00:00
|
|
|
ob->mode &= ~OB_MODE_VERTEX_PAINT;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(vp) {
|
2009-01-25 21:02:52 +00:00
|
|
|
toggle_paint_cursor(C, 0);
|
2009-01-10 14:19:14 +00:00
|
|
|
vp->paintcursor= NULL;
|
|
|
|
|
}
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-08-15 20:36:15 +00:00
|
|
|
ob->mode |= OB_MODE_VERTEX_PAINT;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* Turn off weight painting */
|
2009-08-15 21:46:25 +00:00
|
|
|
if (ob->mode & OB_MODE_WEIGHT_PAINT)
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
set_wpaint(C, op);
|
|
|
|
|
|
2009-01-10 14:19:14 +00:00
|
|
|
if(vp==NULL)
|
|
|
|
|
vp= scene->toolsettings->vpaint= new_vpaint(0);
|
|
|
|
|
|
2009-01-25 21:02:52 +00:00
|
|
|
toggle_paint_cursor(C, 0);
|
2009-08-17 02:49:31 +00:00
|
|
|
|
|
|
|
|
paint_init(&vp->paint, "Brush");
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (me)
|
|
|
|
|
/* update modifier stack for mapping requirements */
|
|
|
|
|
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
|
|
|
|
|
2009-02-10 15:38:00 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_MODE, scene);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-19 23:53:40 +00:00
|
|
|
void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot)
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* identifiers */
|
2009-01-10 14:19:14 +00:00
|
|
|
ot->name= "Vertex Paint Mode";
|
2009-02-19 23:53:40 +00:00
|
|
|
ot->idname= "PAINT_OT_vertex_paint_toggle";
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec= set_vpaint;
|
2009-02-01 13:24:19 +00:00
|
|
|
ot->poll= paint_poll_test;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
|
|
|
|
/* ********************** vertex paint operator ******************* */
|
|
|
|
|
|
|
|
|
|
/* Implementation notes:
|
|
|
|
|
|
|
|
|
|
Operator->invoke()
|
|
|
|
|
- validate context (add mcol)
|
|
|
|
|
- create customdata storage
|
|
|
|
|
- call paint once (mouse click)
|
|
|
|
|
- add modal handler
|
|
|
|
|
|
|
|
|
|
Operator->modal()
|
|
|
|
|
- for every mousemove, apply vertex paint
|
|
|
|
|
- exit on mouse release, free customdata
|
|
|
|
|
(return OPERATOR_FINISHED also removes handler and operator)
|
|
|
|
|
|
|
|
|
|
For future:
|
|
|
|
|
- implement a stroke event (or mousemove with past positons)
|
2009-01-10 14:19:14 +00:00
|
|
|
- revise whether op->customdata should be added in object, in set_vpaint
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
struct VPaintData {
|
|
|
|
|
ViewContext vc;
|
|
|
|
|
unsigned int paintcol;
|
|
|
|
|
int *indexar;
|
|
|
|
|
float *vertexcosnos;
|
|
|
|
|
float vpimat[3][3];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void vpaint_exit(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2009-01-10 14:19:14 +00:00
|
|
|
ToolSettings *ts= CTX_data_tool_settings(C);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
struct VPaintData *vpd= op->customdata;
|
|
|
|
|
|
|
|
|
|
if(vpd->vertexcosnos)
|
|
|
|
|
MEM_freeN(vpd->vertexcosnos);
|
|
|
|
|
MEM_freeN(vpd->indexar);
|
|
|
|
|
|
|
|
|
|
/* frees prev buffer */
|
2009-01-10 14:19:14 +00:00
|
|
|
copy_vpaint_prev(ts->vpaint, NULL, 0);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
|
|
|
|
MEM_freeN(vpd);
|
|
|
|
|
op->customdata= NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
static void vpaint_dot(bContext *C, struct VPaintData *vpd, wmEvent *event)
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
{
|
2009-01-10 14:19:14 +00:00
|
|
|
ToolSettings *ts= CTX_data_tool_settings(C);
|
|
|
|
|
VPaint *vp= ts->vpaint;
|
2009-08-17 02:49:31 +00:00
|
|
|
Brush *brush = paint_brush(&vp->paint);
|
2009-08-19 21:24:52 +00:00
|
|
|
ViewContext *vc= &vpd->vc;
|
|
|
|
|
Object *ob= vc->obact;
|
|
|
|
|
Mesh *me= ob->data;
|
|
|
|
|
float mat[4][4];
|
|
|
|
|
int *indexar= vpd->indexar;
|
|
|
|
|
int totindex, index;
|
|
|
|
|
short mval[2];
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
view3d_operator_needs_opengl(C);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
/* load projection matrix */
|
|
|
|
|
wmMultMatrix(ob->obmat);
|
|
|
|
|
wmGetSingleMatrix(mat);
|
|
|
|
|
wmLoadMatrix(vc->rv3d->viewmat);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
mval[0]= event->x - vc->ar->winrct.xmin;
|
|
|
|
|
mval[1]= event->y - vc->ar->winrct.ymin;
|
2009-02-19 23:53:40 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
/* which faces are involved */
|
|
|
|
|
if(vp->flag & VP_AREA) {
|
|
|
|
|
totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush->size);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);
|
|
|
|
|
if(indexar[0]) totindex= 1;
|
|
|
|
|
else totindex= 0;
|
|
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
MTC_Mat4SwapMat4(vc->rv3d->persmat, mat);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
if(vp->flag & VP_COLINDEX) {
|
|
|
|
|
for(index=0; index<totindex; index++) {
|
|
|
|
|
if(indexar[index] && indexar[index]<=me->totface) {
|
|
|
|
|
MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
if(mface->mat_nr!=ob->actcol-1) {
|
|
|
|
|
indexar[index]= 0;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
2009-08-19 21:24:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if((G.f & G_FACESELECT) && me->mface) {
|
|
|
|
|
for(index=0; index<totindex; index++) {
|
|
|
|
|
if(indexar[index] && indexar[index]<=me->totface) {
|
|
|
|
|
MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
if((mface->flag & ME_FACE_SEL)==0)
|
|
|
|
|
indexar[index]= 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
for(index=0; index<totindex; index++) {
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
if(indexar[index] && indexar[index]<=me->totface) {
|
|
|
|
|
MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
|
|
|
|
|
unsigned int *mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1);
|
|
|
|
|
unsigned int *mcolorig= ( (unsigned int *)vp->vpaint_prev) + 4*(indexar[index]-1);
|
|
|
|
|
int alpha;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
if(vp->mode==VP_BLUR) {
|
|
|
|
|
unsigned int fcol1= mcol_blend( mcol[0], mcol[1], 128);
|
|
|
|
|
if(mface->v4) {
|
|
|
|
|
unsigned int fcol2= mcol_blend( mcol[2], mcol[3], 128);
|
|
|
|
|
vpd->paintcol= mcol_blend( fcol1, fcol2, 128);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
vpd->paintcol= mcol_blend( mcol[2], fcol1, 170);
|
|
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v1, mval);
|
|
|
|
|
if(alpha) vpaint_blend(vp, mcol, mcolorig, vpd->paintcol, alpha);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v2, mval);
|
|
|
|
|
if(alpha) vpaint_blend(vp, mcol+1, mcolorig+1, vpd->paintcol, alpha);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v3, mval);
|
|
|
|
|
if(alpha) vpaint_blend(vp, mcol+2, mcolorig+2, vpd->paintcol, alpha);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
if(mface->v4) {
|
|
|
|
|
alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v4, mval);
|
|
|
|
|
if(alpha) vpaint_blend(vp, mcol+3, mcolorig+3, vpd->paintcol, alpha);
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
2009-08-19 21:24:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
MTC_Mat4SwapMat4(vc->rv3d->persmat, mat);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
do_shared_vertexcol(me);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
ED_region_tag_redraw(vc->ar);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-08-19 21:24:52 +00:00
|
|
|
DAG_object_flush_update(vc->scene, ob, OB_RECALC_DATA);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
switch(event->type) {
|
|
|
|
|
case LEFTMOUSE:
|
|
|
|
|
if(event->val==0) { /* release */
|
|
|
|
|
vpaint_exit(C, op);
|
|
|
|
|
return OPERATOR_FINISHED;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
2009-08-19 21:24:52 +00:00
|
|
|
/* pass on, first press gets painted too */
|
|
|
|
|
|
|
|
|
|
case MOUSEMOVE:
|
|
|
|
|
vpaint_dot(C, op->customdata, event);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2009-08-19 21:24:52 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
2009-01-10 14:19:14 +00:00
|
|
|
ToolSettings *ts= CTX_data_tool_settings(C);
|
|
|
|
|
VPaint *vp= ts->vpaint;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
struct VPaintData *vpd;
|
|
|
|
|
Object *ob= CTX_data_active_object(C);
|
2009-01-07 19:23:22 +00:00
|
|
|
Mesh *me;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
float mat[4][4], imat[4][4];
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* context checks could be a poll() */
|
2009-01-07 19:23:22 +00:00
|
|
|
me= get_mesh(ob);
|
2009-07-25 13:40:59 +00:00
|
|
|
if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
if(me->mcol==NULL) make_vertexcol(CTX_data_scene(C), 0);
|
|
|
|
|
if(me->mcol==NULL) return OPERATOR_CANCELLED;
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* make customdata storage */
|
|
|
|
|
op->customdata= vpd= MEM_callocN(sizeof(struct VPaintData), "VPaintData");
|
|
|
|
|
view3d_set_viewcontext(C, &vpd->vc);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
vpd->vertexcosnos= mesh_get_mapped_verts_nors(vpd->vc.scene, ob);
|
|
|
|
|
vpd->indexar= get_indexarray();
|
2009-01-10 14:19:14 +00:00
|
|
|
vpd->paintcol= vpaint_get_current_col(vp);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* for filtering */
|
2009-01-10 14:19:14 +00:00
|
|
|
copy_vpaint_prev(vp, (unsigned int *)me->mcol, me->totface);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* some old cruft to sort out later */
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
Mat4MulMat4(mat, ob->obmat, vpd->vc.rv3d->viewmat);
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
Mat4Invert(imat, mat);
|
|
|
|
|
Mat3CpyMat4(vpd->vpimat, imat);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* do paint once for click only paint */
|
|
|
|
|
vpaint_modal(C, op, event);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* add modal handler */
|
|
|
|
|
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
2009-01-07 19:23:22 +00:00
|
|
|
|
2009-02-19 23:53:40 +00:00
|
|
|
void PAINT_OT_vertex_paint(wmOperatorType *ot)
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2009-01-10 14:19:14 +00:00
|
|
|
ot->name= "Vertex Paint";
|
2009-02-19 23:53:40 +00:00
|
|
|
ot->idname= "PAINT_OT_vertex_paint";
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke= vpaint_invoke;
|
|
|
|
|
ot->modal= vpaint_modal;
|
|
|
|
|
/* ot->exec= vpaint_exec; <-- needs stroke property */
|
|
|
|
|
ot->poll= vp_poll;
|
|
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2009-07-11 14:51:13 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
|
2009-01-07 19:23:22 +00:00
|
|
|
}
|
|
|
|
|
|