Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2006 by Nicholas Bishop 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 * 00027 * Implements the Sculpt Mode tools 00028 * 00029 */ 00030 00036 #include "MEM_guardedalloc.h" 00037 00038 #include "BLI_math.h" 00039 #include "BLI_utildefines.h" 00040 #include "BLI_string.h" 00041 #include "BLI_listbase.h" 00042 #include "BLI_ghash.h" 00043 #include "BLI_threads.h" 00044 00045 #include "DNA_meshdata_types.h" 00046 #include "DNA_object_types.h" 00047 #include "DNA_scene_types.h" 00048 #include "DNA_mesh_types.h" 00049 00050 #include "BKE_cdderivedmesh.h" 00051 #include "BKE_context.h" 00052 #include "BKE_depsgraph.h" 00053 #include "BKE_modifier.h" 00054 #include "BKE_multires.h" 00055 #include "BKE_paint.h" 00056 #include "BKE_key.h" 00057 #include "BKE_mesh.h" 00058 00059 #include "WM_api.h" 00060 #include "WM_types.h" 00061 00062 #include "GPU_buffers.h" 00063 00064 #include "ED_sculpt.h" 00065 #include "paint_intern.h" 00066 #include "sculpt_intern.h" 00067 00068 /************************** Undo *************************/ 00069 00070 static void update_cb(PBVHNode *node, void *unused) 00071 { 00072 (void)unused; 00073 BLI_pbvh_node_mark_update(node); 00074 } 00075 00076 static void sculpt_restore_deformed(SculptSession *ss, SculptUndoNode *unode, int uindex, int oindex, float coord[3]) 00077 { 00078 if(unode->orig_co) { 00079 swap_v3_v3(coord, unode->orig_co[uindex]); 00080 copy_v3_v3(unode->co[uindex], ss->deform_cos[oindex]); 00081 } else swap_v3_v3(coord, unode->co[uindex]); 00082 } 00083 00084 static void sculpt_undo_restore(bContext *C, ListBase *lb) 00085 { 00086 Scene *scene = CTX_data_scene(C); 00087 Sculpt *sd = CTX_data_tool_settings(C)->sculpt; 00088 Object *ob = CTX_data_active_object(C); 00089 DerivedMesh *dm = mesh_get_derived_final(scene, ob, 0); 00090 SculptSession *ss = ob->sculpt; 00091 SculptUndoNode *unode; 00092 MVert *mvert; 00093 MultiresModifierData *mmd; 00094 int *index; 00095 int i, j, update= 0; 00096 00097 sculpt_update_mesh_elements(scene, sd, ob, 0); 00098 00099 for(unode=lb->first; unode; unode=unode->next) { 00100 if(!(strcmp(unode->idname, ob->id.name)==0)) 00101 continue; 00102 00103 if(unode->maxvert) { 00104 /* regular mesh restore */ 00105 if(ss->totvert != unode->maxvert) 00106 continue; 00107 00108 if (ss->kb && strcmp(ss->kb->name, unode->shapeName)) { 00109 /* shape key has been changed before calling undo operator */ 00110 00111 Key *key= ob_get_key(ob); 00112 KeyBlock *kb= key_get_named_keyblock(key, unode->shapeName); 00113 00114 if (kb) { 00115 ob->shapenr= BLI_findindex(&key->block, kb) + 1; 00116 00117 sculpt_update_mesh_elements(scene, sd, ob, 0); 00118 WM_event_add_notifier(C, NC_OBJECT|ND_DATA, ob); 00119 } else { 00120 /* key has been removed -- skip this undo node */ 00121 continue; 00122 } 00123 } 00124 00125 index= unode->index; 00126 mvert= ss->mvert; 00127 00128 if (ss->kb) { 00129 float (*vertCos)[3]; 00130 vertCos= key_to_vertcos(ob, ss->kb); 00131 00132 for(i=0; i<unode->totvert; i++) { 00133 if(ss->modifiers_active) sculpt_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]); 00134 else { 00135 if(unode->orig_co) swap_v3_v3(vertCos[index[i]], unode->orig_co[i]); 00136 else swap_v3_v3(vertCos[index[i]], unode->co[i]); 00137 } 00138 } 00139 00140 /* propagate new coords to keyblock */ 00141 sculpt_vertcos_to_key(ob, ss->kb, vertCos); 00142 00143 /* pbvh uses it's own mvert array, so coords should be */ 00144 /* propagated to pbvh here */ 00145 BLI_pbvh_apply_vertCos(ss->pbvh, vertCos); 00146 00147 MEM_freeN(vertCos); 00148 } else { 00149 for(i=0; i<unode->totvert; i++) { 00150 if(ss->modifiers_active) sculpt_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co); 00151 else { 00152 if(unode->orig_co) swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]); 00153 else swap_v3_v3(mvert[index[i]].co, unode->co[i]); 00154 } 00155 mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE; 00156 } 00157 } 00158 } 00159 else if(unode->maxgrid && dm->getGridData) { 00160 /* multires restore */ 00161 DMGridData **grids, *grid; 00162 float (*co)[3]; 00163 int gridsize; 00164 00165 if(dm->getNumGrids(dm) != unode->maxgrid) 00166 continue; 00167 if(dm->getGridSize(dm) != unode->gridsize) 00168 continue; 00169 00170 grids= dm->getGridData(dm); 00171 gridsize= dm->getGridSize(dm); 00172 00173 co = unode->co; 00174 for(j=0; j<unode->totgrid; j++) { 00175 grid= grids[unode->grids[j]]; 00176 00177 for(i=0; i<gridsize*gridsize; i++, co++) 00178 swap_v3_v3(grid[i].co, co[0]); 00179 } 00180 } 00181 00182 update= 1; 00183 } 00184 00185 if(update) { 00186 int tag_update= 0; 00187 /* we update all nodes still, should be more clever, but also 00188 needs to work correct when exiting/entering sculpt mode and 00189 the nodes get recreated, though in that case it could do all */ 00190 BLI_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, NULL); 00191 BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw, NULL); 00192 00193 if((mmd=sculpt_multires_active(scene, ob))) 00194 multires_mark_as_modified(ob); 00195 00196 tag_update= ((Mesh*)ob->data)->id.us > 1; 00197 00198 if(ss->modifiers_active) { 00199 Mesh *me= ob->data; 00200 mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); 00201 00202 free_sculptsession_deformMats(ss); 00203 tag_update|= 1; 00204 } 00205 00206 if(tag_update) 00207 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00208 00209 /* for non-PBVH drawing, need to recreate VBOs */ 00210 GPU_drawobject_free(ob->derivedFinal); 00211 } 00212 } 00213 00214 static void sculpt_undo_free(ListBase *lb) 00215 { 00216 SculptUndoNode *unode; 00217 00218 for(unode=lb->first; unode; unode=unode->next) { 00219 if(unode->co) 00220 MEM_freeN(unode->co); 00221 if(unode->no) 00222 MEM_freeN(unode->no); 00223 if(unode->index) 00224 MEM_freeN(unode->index); 00225 if(unode->grids) 00226 MEM_freeN(unode->grids); 00227 if(unode->layer_disp) 00228 MEM_freeN(unode->layer_disp); 00229 if(unode->orig_co) 00230 MEM_freeN(unode->orig_co); 00231 } 00232 } 00233 00234 SculptUndoNode *sculpt_undo_get_node(PBVHNode *node) 00235 { 00236 ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH); 00237 SculptUndoNode *unode; 00238 00239 if(!lb) 00240 return NULL; 00241 00242 for(unode=lb->first; unode; unode=unode->next) 00243 if(unode->node == node) 00244 return unode; 00245 00246 return NULL; 00247 } 00248 00249 SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node) 00250 { 00251 ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH); 00252 SculptSession *ss = ob->sculpt; 00253 SculptUndoNode *unode; 00254 int totvert, allvert, totgrid, maxgrid, gridsize, *grids; 00255 00256 /* list is manipulated by multiple threads, so we lock */ 00257 BLI_lock_thread(LOCK_CUSTOM1); 00258 00259 if((unode= sculpt_undo_get_node(node))) { 00260 BLI_unlock_thread(LOCK_CUSTOM1); 00261 return unode; 00262 } 00263 00264 unode= MEM_callocN(sizeof(SculptUndoNode), "SculptUndoNode"); 00265 BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname)); 00266 unode->node= node; 00267 00268 BLI_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert); 00269 BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid, 00270 &maxgrid, &gridsize, NULL, NULL); 00271 00272 unode->totvert= totvert; 00273 /* we will use this while sculpting, is mapalloc slow to access then? */ 00274 unode->co= MEM_mapallocN(sizeof(float)*3*allvert, "SculptUndoNode.co"); 00275 unode->no= MEM_mapallocN(sizeof(short)*3*allvert, "SculptUndoNode.no"); 00276 undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float)*3 + sizeof(short)*3 + sizeof(int))*allvert); 00277 BLI_addtail(lb, unode); 00278 00279 if(maxgrid) { 00280 /* multires */ 00281 unode->maxgrid= maxgrid; 00282 unode->totgrid= totgrid; 00283 unode->gridsize= gridsize; 00284 unode->grids= MEM_mapallocN(sizeof(int)*totgrid, "SculptUndoNode.grids"); 00285 } 00286 else { 00287 /* regular mesh */ 00288 unode->maxvert= ss->totvert; 00289 unode->index= MEM_mapallocN(sizeof(int)*allvert, "SculptUndoNode.index"); 00290 } 00291 00292 if(ss->modifiers_active) 00293 unode->orig_co= MEM_callocN(allvert*sizeof(*unode->orig_co), "undoSculpt orig_cos"); 00294 00295 BLI_unlock_thread(LOCK_CUSTOM1); 00296 00297 /* copy threaded, hopefully this is the performance critical part */ 00298 { 00299 PBVHVertexIter vd; 00300 00301 BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) { 00302 copy_v3_v3(unode->co[vd.i], vd.co); 00303 if(vd.no) copy_v3_v3_short(unode->no[vd.i], vd.no); 00304 else normal_float_to_short_v3(unode->no[vd.i], vd.fno); 00305 if(vd.vert_indices) unode->index[vd.i]= vd.vert_indices[vd.i]; 00306 00307 if(ss->modifiers_active) 00308 copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]); 00309 } 00310 BLI_pbvh_vertex_iter_end; 00311 } 00312 00313 if(unode->grids) 00314 memcpy(unode->grids, grids, sizeof(int)*totgrid); 00315 00316 /* store active shape key */ 00317 if(ss->kb) BLI_strncpy(unode->shapeName, ss->kb->name, sizeof(ss->kb->name)); 00318 else unode->shapeName[0]= '\0'; 00319 00320 return unode; 00321 } 00322 00323 void sculpt_undo_push_begin(const char *name) 00324 { 00325 undo_paint_push_begin(UNDO_PAINT_MESH, name, 00326 sculpt_undo_restore, sculpt_undo_free); 00327 } 00328 00329 void sculpt_undo_push_end(void) 00330 { 00331 ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH); 00332 SculptUndoNode *unode; 00333 00334 /* we don't need normals in the undo stack */ 00335 for(unode=lb->first; unode; unode=unode->next) { 00336 if(unode->no) { 00337 MEM_freeN(unode->no); 00338 unode->no= NULL; 00339 } 00340 00341 if(unode->layer_disp) { 00342 MEM_freeN(unode->layer_disp); 00343 unode->layer_disp= NULL; 00344 } 00345 } 00346 00347 undo_paint_push_end(UNDO_PAINT_MESH); 00348 }