Revision: 18383 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=18383 Author: nicholasbishop Date: 2009-01-06 22:23:42 +0100 (Tue, 06 Jan 2009)
Log Message: ----------- Brought back sculpt code. Commented out a lot of things, so it compiles. Does nothing more impressive than that for now. Added Paths: ----------- branches/blender2.5/blender/source/blender/editors/sculpt/ branches/blender2.5/blender/source/blender/editors/sculpt/sculpt.c branches/blender2.5/blender/source/blender/editors/sculpt/sculpt_intern.h branches/blender2.5/blender/source/blender/editors/sculpt/stroke.c Added: branches/blender2.5/blender/source/blender/editors/sculpt/sculpt.c =================================================================== --- branches/blender2.5/blender/source/blender/editors/sculpt/sculpt.c (rev 0) +++ branches/blender2.5/blender/source/blender/editors/sculpt/sculpt.c 2009-01-06 21:23:42 UTC (rev 18383) @@ -0,0 +1,2137 @@ +/* + * $Id: sculptmode.c 18309 2009-01-04 07:47:11Z nicholasbishop $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 by Nicholas Bishop + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * + * Implements the Sculpt Mode tools + * + * BDR_sculptmode.h + * + */ + +#include "GHOST_Types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_dynstr.h" + +#include "DNA_armature_types.h" +#include "DNA_brush_types.h" +#include "DNA_image_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" +#include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" +#include "DNA_color_types.h" + +#include "BKE_customdata.h" +#include "BKE_DerivedMesh.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_key.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_multires.h" +#include "BKE_sculpt.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" +#include "BKE_colortools.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "sculpt_intern.h" + +#include "IMB_imbuf_types.h" + +#include "RE_render_ext.h" +#include "RE_shader_ext.h" /*for multitex_ext*/ + +#include "GPU_draw.h" + +#include <math.h> +#include <stdlib.h> +#include <string.h> + +/* Number of vertices to average in order to determine the flatten distance */ +#define FLATTEN_SAMPLE_SIZE 10 + +/* Texture cache size */ +#define TC_SIZE 256 + +/* ===== STRUCTS ===== + * + */ + +/* ActiveData stores an Index into the mvert array of Mesh, plus Fade, which + stores how far the vertex is from the brush center, scaled to the range [0,1]. */ +typedef struct ActiveData { + struct ActiveData *next, *prev; + unsigned int Index; + float Fade; + float dist; +} ActiveData; + +typedef struct BrushActionSymm { + float center_3d[3]; + char index; + + float up[3], right[3], out[3]; + + /* Grab brush */ + float grab_delta[3]; +} BrushActionSymm; + +typedef struct BrushAction { + BrushActionSymm symm; + + char firsttime; + + /* Some brushes need access to original mesh vertices */ + vec3f *mesh_store; + short (*orig_norms)[3]; + + short mouse[2]; + float size_3d; + + float prev_radius; + float radius; + + float *layer_disps; + char flip; + + char clip[3]; + float cliptol[3]; + + float anchored_rot; + + /* Grab brush */ + ListBase grab_active_verts[8]; + float depth; + + /* Adjust brush strength along each axis + to adjust for object scaling */ + float scale[3]; +} BrushAction; + +typedef struct RectNode { + struct RectNode *next, *prev; + rcti r; +} RectNode; + +/* Used to store to 2D screen coordinates of each vertex in the mesh. */ +typedef struct ProjVert { + short co[2]; + + /* Used to mark whether a vertex is inside a rough bounding box + containing the brush. */ + char inside; +} ProjVert; + +static Object *active_ob= NULL; + +SculptData *sculpt_data(void) +{ + return NULL; /*XXX: return &G.scene->sculptdata; */ +} + +static void sculpt_init_session(void); +static void init_brushaction(BrushAction *a, short *, short *); +static void sculpt_undo_push(const short); + +SculptSession *sculpt_session(void) +{ + if(!sculpt_data()->session) + sculpt_init_session(); + return sculpt_data()->session; +} + +/* ===== MEMORY ===== + * + * Allocate/initialize/free data + */ + +static void sculpt_init_session(void) +{ + if(sculpt_data()->session) + ;/*XXX: sculptsession_free(G.scene); */ + sculpt_data()->session= MEM_callocN(sizeof(SculptSession), "SculptSession"); +} + +/* vertex_users is an array of Lists that store all the faces that use a + particular vertex. vertex_users is in the same order as mesh.mvert */ +static void calc_vertex_users() +{ + SculptSession *ss= sculpt_session(); + int i,j; + IndexNode *node= NULL; + + sculpt_vertexusers_free(ss); + + /* For efficiency, use vertex_users_mem as a memory pool (may be larger + than necessary if mesh has triangles, but only one alloc is needed.) */ + ss->vertex_users= MEM_callocN(sizeof(ListBase) * ss->totvert, "vertex_users"); + ss->vertex_users_size= ss->totvert; + ss->vertex_users_mem= MEM_callocN(sizeof(IndexNode)*ss->totface*4, "vertex_users_mem"); + node= ss->vertex_users_mem; + + /* Find the users */ + for(i=0; i<ss->totface; ++i){ + for(j=0; j<(ss->mface[i].v4?4:3); ++j, ++node) { + node->index=i; + BLI_addtail(&ss->vertex_users[((unsigned int*)(&ss->mface[i]))[j]], node); + } + } +} + +/* ===== INTERFACE ===== + */ + +/* XXX: this can probably removed entirely */ +#if 0 +void sculptmode_rem_tex(void *junk0,void *junk1) +{ + MTex *mtex= G.scene->sculptdata.mtex[G.scene->sculptdata.texact]; + if(mtex) { + SculptSession *ss= sculpt_session(); + if(mtex->tex) mtex->tex->id.us--; + MEM_freeN(mtex); + G.scene->sculptdata.mtex[G.scene->sculptdata.texact]= NULL; + /* Clear brush preview */ + if(ss->texcache) { + MEM_freeN(ss->texcache); + ss->texcache= NULL; + } + BIF_undo_push("Unlink brush texture"); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWOOPS, 0); + } +} +#endif + +/* ===== OPENGL ===== + * + * Simple functions to get data from the GL + */ + +/* Store the modelview and projection matrices and viewport. */ +void init_sculptmatrices() +{ + /* XXX: probably becomes context data? + + SculptSession *ss= sculpt_session(); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMultMatrixf(OBACT->obmat); + + if(!ss->mats) + ss->mats = MEM_callocN(sizeof(bglMats), "sculpt bglmats"); + bgl_get_mats(ss->mats); + + glPopMatrix(); + */ +} + +/* Uses window coordinates (x,y) to find the depth in the GL depth buffer. If + available, G.vd->depths is used so that the brush doesn't sculpt on top of + itself (G.vd->depths is only updated at the end of a brush stroke.) */ +float get_depth(short x, short y) +{ + /* XXX + float depth; + + if(x<0 || y<0) return 1; + if(x>=curarea->winx || y>=curarea->winy) return 1; + + if(G.vd->depths && x<G.vd->depths->w && y<G.vd->depths->h) + return G.vd->depths->depths[y*G.vd->depths->w+x]; + + x+= curarea->winrct.xmin; + y+= curarea->winrct.ymin; + + glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + + return depth; */ + return 0; +} + +/* Uses window coordinates (x,y) and depth component z to find a point in + modelspace */ +void unproject(float out[3], const short x, const short y, const float z) +{ + SculptSession *ss= sculpt_session(); + double ux, uy, uz; + + gluUnProject(x,y,z, ss->mats->modelview, ss->mats->projection, + (GLint *)ss->mats->viewport, &ux, &uy, &uz ); + out[0] = ux; + out[1] = uy; + out[2] = uz; +} + +/* Convert a point in model coordinates to 2D screen coordinates. */ +static void projectf(const float v[3], float p[2]) +{ + SculptSession *ss= sculpt_session(); + double ux, uy, uz; + + gluProject(v[0],v[1],v[2], ss->mats->modelview, ss->mats->projection, + (GLint *)ss->mats->viewport, &ux, &uy, &uz); + p[0]= ux; + p[1]= uy; +} + +static void project(const float v[3], short p[2]) +{ + float f[2]; + projectf(v, f); + + p[0]= f[0]; + p[1]= f[1]; +} + +/* ===== Sculpting ===== + * + */ + +/* Return modified brush size. Uses current tablet pressure (if available) to + shrink the brush. Skipped for grab brush because only the first mouse down + size is used, which is small if the user has just touched the pen to the + tablet */ +char brush_size() +{ + SculptData *sd = NULL; /* XXX */ + const BrushData *b= sculptmode_brush(); + float size= b->size; + float pressure= get_pressure(); + short activedevice= get_activedevice(); + + if(sculpt_data()->brush_type!=GRAB_BRUSH) { + const float size_factor= sd->tablet_size / 10.0f; + + /* XXX: tablet stuff + if(ELEM(activedevice, DEV_STYLUS, DEV_ERASER)) + size*= sd->tablet_size==0?1: + (1-size_factor) + pressure*size_factor;*/ + } + + return size; +} + +/* Return modified brush strength. Includes the direction of the brush, positive + values pull vertices, negative values push. Uses tablet pressure and a + special multiplier found experimentally to scale the strength factor. */ +float brush_strength(BrushAction *a) +{ + SculptData *sd = NULL; /* XXX */ + const BrushData* b= sculptmode_brush(); + float dir= b->dir==1 ? 1 : -1; + float pressure= 1; + short activedevice= get_activedevice(); + float flip= a->flip ? -1:1; + float anchored = b->flag & SCULPT_BRUSH_ANCHORED ? 25 : 1; + + const float strength_factor= sd->tablet_strength / 10.0f; + + /* XXX: tablet stuff */ +#if 0 + if(ELEM(activedevice, DEV_STYLUS, DEV_ERASER)) + pressure= sd->sculptdata.tablet_strength==0?1: + (1-strength_factor) + get_pressure()*strength_factor; + + /* Flip direction for eraser */ + if(activedevice==DEV_ERASER) + dir= -dir; +#endif + + switch(sd->brush_type){ + case DRAW_BRUSH: + case LAYER_BRUSH: + return b->strength / 5000.0f * dir * pressure * flip * anchored; /*XXX: not sure why? multiplied by G.vd->grid */; + case SMOOTH_BRUSH: + return b->strength / 50.0f * pressure * anchored; + case PINCH_BRUSH: + return b->strength / 1000.0f * dir * pressure * flip * anchored; + case GRAB_BRUSH: + return 1; + case INFLATE_BRUSH: + return b->strength / 5000.0f * dir * pressure * flip * anchored; + case FLATTEN_BRUSH: @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs