Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/dynamicpaint.c
| Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
| #include "DNA_texture_types.h" | #include "DNA_texture_types.h" | ||||
| #include "BKE_animsys.h" | #include "BKE_animsys.h" | ||||
| #include "BKE_armature.h" | #include "BKE_armature.h" | ||||
| #include "BKE_bvhutils.h" /* bvh tree */ | #include "BKE_bvhutils.h" /* bvh tree */ | ||||
| #include "BKE_collection.h" | #include "BKE_collection.h" | ||||
| #include "BKE_collision.h" | #include "BKE_collision.h" | ||||
| #include "BKE_colorband.h" | #include "BKE_colorband.h" | ||||
| #include "BKE_cdderivedmesh.h" | |||||
| #include "BKE_constraint.h" | #include "BKE_constraint.h" | ||||
| #include "BKE_customdata.h" | #include "BKE_customdata.h" | ||||
| #include "BKE_deform.h" | #include "BKE_deform.h" | ||||
| #include "BKE_DerivedMesh.h" | |||||
| #include "BKE_dynamicpaint.h" | #include "BKE_dynamicpaint.h" | ||||
| #include "BKE_effect.h" | #include "BKE_effect.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_mesh.h" | |||||
| #include "BKE_mesh_mapping.h" | #include "BKE_mesh_mapping.h" | ||||
| #include "BKE_mesh_runtime.h" | |||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_particle.h" | #include "BKE_particle.h" | ||||
| #include "BKE_pointcache.h" | #include "BKE_pointcache.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| ▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
| /* Get number of surface points for cached types */ | /* Get number of surface points for cached types */ | ||||
| static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface) | static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface) | ||||
| { | { | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) { | ||||
| return 0; /* not supported atm */ | return 0; /* not supported atm */ | ||||
| } | } | ||||
| else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| return (surface->canvas->dm) ? surface->canvas->dm->getNumVerts(surface->canvas->dm) : 0; | return (surface->canvas->mesh) ? surface->canvas->mesh->totvert : 0; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /* checks whether surface's format/type has realtime preview */ | /* checks whether surface's format/type has realtime preview */ | ||||
| bool dynamicPaint_surfaceHasColorPreview(DynamicPaintSurface *surface) | bool dynamicPaint_surfaceHasColorPreview(DynamicPaintSurface *surface) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 546 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /***************************** Freeing data ******************************/ | /***************************** Freeing data ******************************/ | ||||
| /* Free brush data */ | /* Free brush data */ | ||||
| void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd) | void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd) | ||||
| { | { | ||||
| if (pmd->brush) { | if (pmd->brush) { | ||||
| if (pmd->brush->dm) | if (pmd->brush->mesh) { | ||||
| pmd->brush->dm->release(pmd->brush->dm); | BKE_id_free(NULL, pmd->brush->mesh); | ||||
| pmd->brush->dm = NULL; | } | ||||
| pmd->brush->mesh = NULL; | |||||
| if (pmd->brush->paint_ramp) | if (pmd->brush->paint_ramp) | ||||
| MEM_freeN(pmd->brush->paint_ramp); | MEM_freeN(pmd->brush->paint_ramp); | ||||
| if (pmd->brush->vel_ramp) | if (pmd->brush->vel_ramp) | ||||
| MEM_freeN(pmd->brush->vel_ramp); | MEM_freeN(pmd->brush->vel_ramp); | ||||
| MEM_freeN(pmd->brush); | MEM_freeN(pmd->brush); | ||||
| pmd->brush = NULL; | pmd->brush = NULL; | ||||
| ▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | if (pmd->canvas) { | ||||
| DynamicPaintSurface *next_surface = NULL; | DynamicPaintSurface *next_surface = NULL; | ||||
| while (surface) { | while (surface) { | ||||
| next_surface = surface->next; | next_surface = surface->next; | ||||
| dynamicPaint_freeSurface(surface); | dynamicPaint_freeSurface(surface); | ||||
| surface = next_surface; | surface = next_surface; | ||||
| } | } | ||||
| /* free dm copy */ | /* free mesh copy */ | ||||
| if (pmd->canvas->dm) | if (pmd->canvas->mesh) { | ||||
| pmd->canvas->dm->release(pmd->canvas->dm); | BKE_id_free(NULL, pmd->canvas->mesh); | ||||
| pmd->canvas->dm = NULL; | } | ||||
| pmd->canvas->mesh = NULL; | |||||
| MEM_freeN(pmd->canvas); | MEM_freeN(pmd->canvas); | ||||
| pmd->canvas = NULL; | pmd->canvas = NULL; | ||||
| } | } | ||||
| } | } | ||||
| /* Free whole dp modifier */ | /* Free whole dp modifier */ | ||||
| void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd) | void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd) | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | if (type == MOD_DYNAMICPAINT_TYPE_CANVAS) { | ||||
| DynamicPaintCanvasSettings *canvas; | DynamicPaintCanvasSettings *canvas; | ||||
| if (pmd->canvas) | if (pmd->canvas) | ||||
| dynamicPaint_freeCanvas(pmd); | dynamicPaint_freeCanvas(pmd); | ||||
| canvas = pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas"); | canvas = pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas"); | ||||
| if (!canvas) | if (!canvas) | ||||
| return false; | return false; | ||||
| canvas->pmd = pmd; | canvas->pmd = pmd; | ||||
| canvas->dm = NULL; | canvas->mesh = NULL; | ||||
| /* Create one surface */ | /* Create one surface */ | ||||
| if (!dynamicPaint_createNewSurface(canvas, scene)) | if (!dynamicPaint_createNewSurface(canvas, scene)) | ||||
| return false; | return false; | ||||
| } | } | ||||
| else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH) { | else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH) { | ||||
| DynamicPaintBrushSettings *brush; | DynamicPaintBrushSettings *brush; | ||||
| Show All 23 Lines | else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH) { | ||||
| brush->particle_smooth = 0.05f; | brush->particle_smooth = 0.05f; | ||||
| brush->wave_type = MOD_DPAINT_WAVEB_CHANGE; | brush->wave_type = MOD_DPAINT_WAVEB_CHANGE; | ||||
| brush->wave_factor = 1.0f; | brush->wave_factor = 1.0f; | ||||
| brush->wave_clamp = 0.0f; | brush->wave_clamp = 0.0f; | ||||
| brush->smudge_strength = 0.3f; | brush->smudge_strength = 0.3f; | ||||
| brush->max_velocity = 1.0f; | brush->max_velocity = 1.0f; | ||||
| brush->dm = NULL; | brush->mesh = NULL; | ||||
| /* Paint proximity falloff colorramp. */ | /* Paint proximity falloff colorramp. */ | ||||
| { | { | ||||
| CBData *ramp; | CBData *ramp; | ||||
| brush->paint_ramp = BKE_colorband_add(false); | brush->paint_ramp = BKE_colorband_add(false); | ||||
| if (!brush->paint_ramp) | if (!brush->paint_ramp) | ||||
| return false; | return false; | ||||
| ▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | static bool surface_usesAdjData(DynamicPaintSurface *surface) | ||||
| return (surface_usesAdjDistance(surface) || | return (surface_usesAdjDistance(surface) || | ||||
| (surface->format == MOD_DPAINT_SURFACE_F_VERTEX && surface->flags & MOD_DPAINT_ANTIALIAS)); | (surface->format == MOD_DPAINT_SURFACE_F_VERTEX && surface->flags & MOD_DPAINT_ANTIALIAS)); | ||||
| } | } | ||||
| /* initialize surface adjacency data */ | /* initialize surface adjacency data */ | ||||
| static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const bool force_init) | static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const bool force_init) | ||||
| { | { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| DerivedMesh *dm = surface->canvas->dm; | Mesh *mesh = surface->canvas->mesh; | ||||
| PaintAdjData *ad; | PaintAdjData *ad; | ||||
| int *temp_data; | int *temp_data; | ||||
| int neigh_points = 0; | int neigh_points = 0; | ||||
| if (!force_init && !surface_usesAdjData(surface)) | if (!force_init && !surface_usesAdjData(surface)) | ||||
| return; | return; | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| /* For vertex format, neighbors are connected by edges */ | /* For vertex format, neighbors are connected by edges */ | ||||
| neigh_points = 2 * dm->getNumEdges(dm); | neigh_points = 2 * mesh->totedge; | ||||
| } | } | ||||
| else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { | else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { | ||||
| neigh_points = sData->total_points * 8; | neigh_points = sData->total_points * 8; | ||||
| } | } | ||||
| if (!neigh_points) | if (!neigh_points) | ||||
| return; | return; | ||||
| Show All 19 Lines | if (!ad->n_index || !ad->n_num || !ad->n_target || !temp_data) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| int i; | int i; | ||||
| int n_pos; | int n_pos; | ||||
| /* For vertex format, count every vertex that is connected by an edge */ | /* For vertex format, count every vertex that is connected by an edge */ | ||||
| int numOfEdges = dm->getNumEdges(dm); | int numOfEdges = mesh->totedge; | ||||
| int numOfPolys = dm->getNumPolys(dm); | int numOfPolys = mesh->totpoly; | ||||
| struct MEdge *edge = dm->getEdgeArray(dm); | struct MEdge *edge = mesh->medge; | ||||
| struct MPoly *mpoly = dm->getPolyArray(dm); | struct MPoly *mpoly = mesh->mpoly; | ||||
| struct MLoop *mloop = dm->getLoopArray(dm); | struct MLoop *mloop = mesh->mloop; | ||||
| /* count number of edges per vertex */ | /* count number of edges per vertex */ | ||||
| for (i = 0; i < numOfEdges; i++) { | for (i = 0; i < numOfEdges; i++) { | ||||
| ad->n_num[edge[i].v1]++; | ad->n_num[edge[i].v1]++; | ||||
| ad->n_num[edge[i].v2]++; | ad->n_num[edge[i].v2]++; | ||||
| temp_data[edge[i].v1]++; | temp_data[edge[i].v1]++; | ||||
| temp_data[edge[i].v2]++; | temp_data[edge[i].v2]++; | ||||
| ▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | static void dynamic_paint_set_init_color_vcol_to_imseq_cb( | ||||
| copy_v4_v4(pPoint[i].color, final_color); | copy_v4_v4(pPoint[i].color, final_color); | ||||
| } | } | ||||
| static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface *surface) | static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface *surface) | ||||
| { | { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| PaintPoint *pPoint = (PaintPoint *)sData->type_data; | PaintPoint *pPoint = (PaintPoint *)sData->type_data; | ||||
| DerivedMesh *dm = surface->canvas->dm; | Mesh *mesh = surface->canvas->mesh; | ||||
| int i; | int i; | ||||
| const bool scene_color_manage = BKE_scene_check_color_management_enabled(scene); | const bool scene_color_manage = BKE_scene_check_color_management_enabled(scene); | ||||
| if (surface->type != MOD_DPAINT_SURFACE_T_PAINT) | if (surface->type != MOD_DPAINT_SURFACE_T_PAINT) | ||||
| return; | return; | ||||
| if (surface->init_color_type == MOD_DPAINT_INITIAL_NONE) | if (surface->init_color_type == MOD_DPAINT_INITIAL_NONE) | ||||
| return; | return; | ||||
| /* Single color */ | /* Single color */ | ||||
| if (surface->init_color_type == MOD_DPAINT_INITIAL_COLOR) { | if (surface->init_color_type == MOD_DPAINT_INITIAL_COLOR) { | ||||
| /* apply color to every surface point */ | /* apply color to every surface point */ | ||||
| for (i = 0; i < sData->total_points; i++) { | for (i = 0; i < sData->total_points; i++) { | ||||
| copy_v4_v4(pPoint[i].color, surface->init_color); | copy_v4_v4(pPoint[i].color, surface->init_color); | ||||
| } | } | ||||
| } | } | ||||
| /* UV mapped texture */ | /* UV mapped texture */ | ||||
| else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { | else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { | ||||
| Tex *tex = surface->init_texture; | Tex *tex = surface->init_texture; | ||||
| const MLoop *mloop = dm->getLoopArray(dm); | const MLoop *mloop = mesh->mloop; | ||||
| const MLoopTri *mlooptri = dm->getLoopTriArray(dm); | const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| const int tottri = dm->getNumLoopTri(dm); | const int tottri = BKE_mesh_runtime_looptri_len(mesh); | ||||
| const MLoopUV *mloopuv = NULL; | const MLoopUV *mloopuv = NULL; | ||||
| char uvname[MAX_CUSTOMDATA_LAYER_NAME]; | char uvname[MAX_CUSTOMDATA_LAYER_NAME]; | ||||
| if (!tex) | if (!tex) | ||||
| return; | return; | ||||
| /* get uv map */ | /* get uv map */ | ||||
| CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, surface->init_layername, uvname); | CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, surface->init_layername, uvname); | ||||
| mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname); | mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname); | ||||
| if (!mloopuv) | if (!mloopuv) | ||||
| return; | return; | ||||
| /* for vertex surface loop through tfaces and find uv color | /* for vertex surface loop through tfaces and find uv color | ||||
| * that provides highest alpha */ | * that provides highest alpha */ | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| struct ImagePool *pool = BKE_image_pool_new(); | struct ImagePool *pool = BKE_image_pool_new(); | ||||
| Show All 26 Lines | else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { | ||||
| &settings); | &settings); | ||||
| } | } | ||||
| } | } | ||||
| /* vertex color layer */ | /* vertex color layer */ | ||||
| else if (surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) { | else if (surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) { | ||||
| /* for vertex surface, just copy colors from mcol */ | /* for vertex surface, just copy colors from mcol */ | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| const MLoop *mloop = dm->getLoopArray(dm); | const MLoop *mloop = mesh->mloop; | ||||
| const int totloop = dm->getNumLoops(dm); | const int totloop = mesh->totloop; | ||||
| const MLoopCol *col = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, surface->init_layername); | const MLoopCol *col = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPCOL, surface->init_layername); | ||||
| if (!col) | if (!col) | ||||
| return; | return; | ||||
| for (i = 0; i < totloop; i++) { | for (i = 0; i < totloop; i++) { | ||||
| rgba_uchar_to_float(pPoint[mloop[i].v].color, (const unsigned char *)&col[mloop[i].v].r); | rgba_uchar_to_float(pPoint[mloop[i].v].color, (const unsigned char *)&col[mloop[i].v].r); | ||||
| } | } | ||||
| } | } | ||||
| else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { | else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { | ||||
| const MLoopTri *mlooptri = dm->getLoopTriArray(dm); | const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| MLoopCol *col = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, surface->init_layername); | MLoopCol *col = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPCOL, surface->init_layername); | ||||
| if (!col) | if (!col) | ||||
| return; | return; | ||||
| DynamicPaintSetInitColorData data = { | DynamicPaintSetInitColorData data = { | ||||
| .surface = surface, | .surface = surface, | ||||
| .mlooptri = mlooptri, .mloopcol = col, | .mlooptri = mlooptri, .mloopcol = col, | ||||
| }; | }; | ||||
| ParallelRangeSettings settings; | ParallelRangeSettings settings; | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | static void dynamic_paint_apply_surface_displace_cb( | ||||
| normal_short_to_float_v3(normal, mvert[i].no); | normal_short_to_float_v3(normal, mvert[i].no); | ||||
| /* same as 'mvert[i].co[0] -= normal[0] * val' etc. */ | /* same as 'mvert[i].co[0] -= normal[0] * val' etc. */ | ||||
| madd_v3_v3fl(mvert[i].co, normal, -val); | madd_v3_v3fl(mvert[i].co, normal, -val); | ||||
| } | } | ||||
| /* apply displacing vertex surface to the derived mesh */ | /* apply displacing vertex surface to the derived mesh */ | ||||
| static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, DerivedMesh *result) | static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh *result) | ||||
| { | { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| if (!sData || surface->format != MOD_DPAINT_SURFACE_F_VERTEX) | if (!sData || surface->format != MOD_DPAINT_SURFACE_F_VERTEX) | ||||
| return; | return; | ||||
| /* displace paint */ | /* displace paint */ | ||||
| if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { | if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { | ||||
| MVert *mvert = result->getVertArray(result); | MVert *mvert = result->mvert; | ||||
| DynamicPaintModifierApplyData data = {.surface = surface, .mvert = mvert}; | DynamicPaintModifierApplyData data = {.surface = surface, .mvert = mvert}; | ||||
| ParallelRangeSettings settings; | ParallelRangeSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (sData->total_points > 10000); | settings.use_threading = (sData->total_points > 10000); | ||||
| BLI_task_parallel_range(0, sData->total_points, | BLI_task_parallel_range(0, sData->total_points, | ||||
| &data, | &data, | ||||
| dynamic_paint_apply_surface_displace_cb, | dynamic_paint_apply_surface_displace_cb, | ||||
| ▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | static void dynamic_paint_apply_surface_wave_cb( | ||||
| normal_short_to_float_v3(normal, mvert[i].no); | normal_short_to_float_v3(normal, mvert[i].no); | ||||
| madd_v3_v3fl(mvert[i].co, normal, wPoint[i].height); | madd_v3_v3fl(mvert[i].co, normal, wPoint[i].height); | ||||
| } | } | ||||
| /* | /* | ||||
| * Apply canvas data to the object derived mesh | * Apply canvas data to the object derived mesh | ||||
| */ | */ | ||||
| static DerivedMesh *dynamicPaint_Modifier_apply( | static Mesh *dynamicPaint_Modifier_apply( | ||||
| DynamicPaintModifierData *pmd, Object *ob, DerivedMesh *dm) | DynamicPaintModifierData *pmd, Object *ob, Mesh *mesh) | ||||
| { | { | ||||
| DerivedMesh *result = CDDM_copy(dm); | Mesh *result = BKE_mesh_copy_for_eval(mesh, false); | ||||
| if (pmd->canvas && !(pmd->canvas->flags & MOD_DPAINT_BAKING)) { | if (pmd->canvas && !(pmd->canvas->flags & MOD_DPAINT_BAKING)) { | ||||
| DynamicPaintSurface *surface; | DynamicPaintSurface *surface; | ||||
| bool update_normals = false; | bool update_normals = false; | ||||
| /* loop through surfaces */ | /* loop through surfaces */ | ||||
| for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { | for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && sData) { | if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && sData) { | ||||
| if (!(surface->flags & MOD_DPAINT_ACTIVE)) | if (!(surface->flags & MOD_DPAINT_ACTIVE)) | ||||
| continue; | continue; | ||||
| /* process vertex surface previews */ | /* process vertex surface previews */ | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| /* vertex color paint */ | /* vertex color paint */ | ||||
| if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { | if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { | ||||
| MLoop *mloop = CDDM_get_loops(result); | MLoop *mloop = result->mloop; | ||||
| const int totloop = result->numLoopData; | const int totloop = result->totloop; | ||||
| MPoly *mpoly = CDDM_get_polys(result); | MPoly *mpoly = result->mpoly; | ||||
| const int totpoly = result->numPolyData; | const int totpoly = result->totpoly; | ||||
| /* paint is stored on dry and wet layers, so mix final color first */ | /* paint is stored on dry and wet layers, so mix final color first */ | ||||
| float (*fcolor)[4] = MEM_callocN(sizeof(*fcolor) * sData->total_points, "Temp paint color"); | float (*fcolor)[4] = MEM_callocN(sizeof(*fcolor) * sData->total_points, "Temp paint color"); | ||||
| DynamicPaintModifierApplyData data = {.surface = surface, .fcolor = fcolor}; | DynamicPaintModifierApplyData data = {.surface = surface, .fcolor = fcolor}; | ||||
| { | { | ||||
| ParallelRangeSettings settings; | ParallelRangeSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (sData->total_points > 1000); | settings.use_threading = (sData->total_points > 1000); | ||||
| BLI_task_parallel_range( | BLI_task_parallel_range( | ||||
| 0, sData->total_points, | 0, sData->total_points, | ||||
| &data, | &data, | ||||
| dynamic_paint_apply_surface_vpaint_blend_cb, | dynamic_paint_apply_surface_vpaint_blend_cb, | ||||
| &settings); | &settings); | ||||
| } | } | ||||
| /* paint layer */ | /* paint layer */ | ||||
| MLoopCol *mloopcol = CustomData_get_layer_named(&result->loopData, CD_MLOOPCOL, surface->output_name); | MLoopCol *mloopcol = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, surface->output_name); | ||||
| /* if output layer is lost from a constructive modifier, re-add it */ | /* if output layer is lost from a constructive modifier, re-add it */ | ||||
| if (!mloopcol && dynamicPaint_outputLayerExists(surface, ob, 0)) { | if (!mloopcol && dynamicPaint_outputLayerExists(surface, ob, 0)) { | ||||
| mloopcol = CustomData_add_layer_named( | mloopcol = CustomData_add_layer_named( | ||||
| &result->loopData, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name); | &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name); | ||||
| } | } | ||||
| /* wet layer */ | /* wet layer */ | ||||
| MLoopCol *mloopcol_wet = CustomData_get_layer_named(&result->loopData, CD_MLOOPCOL, surface->output_name2); | MLoopCol *mloopcol_wet = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, surface->output_name2); | ||||
| /* if output layer is lost from a constructive modifier, re-add it */ | /* if output layer is lost from a constructive modifier, re-add it */ | ||||
| if (!mloopcol_wet && dynamicPaint_outputLayerExists(surface, ob, 1)) { | if (!mloopcol_wet && dynamicPaint_outputLayerExists(surface, ob, 1)) { | ||||
| mloopcol_wet = CustomData_add_layer_named( | mloopcol_wet = CustomData_add_layer_named( | ||||
| &result->loopData, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name2); | &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name2); | ||||
| } | } | ||||
| /* Save preview results to weight layer to be able to share same drawing methods */ | /* Save preview results to weight layer to be able to share same drawing methods */ | ||||
| MLoopCol *mloopcol_preview = NULL; | MLoopCol *mloopcol_preview = NULL; | ||||
| if (surface->flags & MOD_DPAINT_PREVIEW) { | if (surface->flags & MOD_DPAINT_PREVIEW) { | ||||
| mloopcol_preview = CustomData_get_layer(&result->loopData, CD_PREVIEW_MLOOPCOL); | mloopcol_preview = CustomData_get_layer(&result->ldata, CD_PREVIEW_MLOOPCOL); | ||||
| if (!mloopcol_preview) { | if (!mloopcol_preview) { | ||||
| mloopcol_preview = CustomData_add_layer( | mloopcol_preview = CustomData_add_layer( | ||||
| &result->loopData, CD_PREVIEW_MLOOPCOL, CD_CALLOC, NULL, totloop); | &result->ldata, CD_PREVIEW_MLOOPCOL, CD_CALLOC, NULL, totloop); | ||||
| } | } | ||||
| } | } | ||||
| data.ob = ob; | data.ob = ob; | ||||
| data.mloop = mloop; | data.mloop = mloop; | ||||
| data.mpoly = mpoly; | data.mpoly = mpoly; | ||||
| data.mloopcol = mloopcol; | data.mloopcol = mloopcol; | ||||
| data.mloopcol_wet = mloopcol_wet; | data.mloopcol_wet = mloopcol_wet; | ||||
| data.mloopcol_preview = mloopcol_preview; | data.mloopcol_preview = mloopcol_preview; | ||||
| { | { | ||||
| ParallelRangeSettings settings; | ParallelRangeSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (totpoly > 1000); | settings.use_threading = (totpoly > 1000); | ||||
| BLI_task_parallel_range( | BLI_task_parallel_range( | ||||
| 0, totpoly, | 0, totpoly, | ||||
| &data, | &data, | ||||
| dynamic_paint_apply_surface_vpaint_cb, | dynamic_paint_apply_surface_vpaint_cb, | ||||
| &settings); | &settings); | ||||
| } | } | ||||
| MEM_freeN(fcolor); | MEM_freeN(fcolor); | ||||
| /* Mark tessellated CD layers as dirty. */ | /* Mark tessellated CD layers as dirty. */ | ||||
| result->dirty |= DM_DIRTY_TESS_CDLAYERS; | //result->dirty |= DM_DIRTY_TESS_CDLAYERS; | ||||
| } | } | ||||
| /* vertex group paint */ | /* vertex group paint */ | ||||
| else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { | else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { | ||||
| int defgrp_index = defgroup_name_index(ob, surface->output_name); | int defgrp_index = defgroup_name_index(ob, surface->output_name); | ||||
| MDeformVert *dvert = result->getVertDataArray(result, CD_MDEFORMVERT); | MDeformVert *dvert = CustomData_get_layer(&result->vdata, CD_MDEFORMVERT); | ||||
| float *weight = (float *)sData->type_data; | float *weight = (float *)sData->type_data; | ||||
| /* viewport preview */ | /* viewport preview */ | ||||
| if (surface->flags & MOD_DPAINT_PREVIEW) { | if (surface->flags & MOD_DPAINT_PREVIEW) { | ||||
| /* Save preview results to weight layer to be | /* Save preview results to weight layer to be | ||||
| * able to share same drawing methods. | * able to share same drawing methods. | ||||
| * Note this func also sets DM_DIRTY_TESS_CDLAYERS flag! */ | * Note this func also sets DM_DIRTY_TESS_CDLAYERS flag! */ | ||||
| DM_update_weight_mcol(ob, result, 0, weight, 0, NULL); | //TODO port this function | ||||
| //DM_update_weight_mcol(ob, result, 0, weight, 0, NULL); | |||||
| } | } | ||||
| /* apply weights into a vertex group, if doesnt exists add a new layer */ | /* apply weights into a vertex group, if doesnt exists add a new layer */ | ||||
| if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) { | if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) { | ||||
| dvert = CustomData_add_layer(&result->vertData, CD_MDEFORMVERT, CD_CALLOC, | dvert = CustomData_add_layer(&result->vdata, CD_MDEFORMVERT, CD_CALLOC, | ||||
| NULL, sData->total_points); | NULL, sData->total_points); | ||||
| } | } | ||||
| if (defgrp_index != -1 && dvert) { | if (defgrp_index != -1 && dvert) { | ||||
| int i; | int i; | ||||
| for (i = 0; i < sData->total_points; i++) { | for (i = 0; i < sData->total_points; i++) { | ||||
| MDeformVert *dv = &dvert[i]; | MDeformVert *dv = &dvert[i]; | ||||
| MDeformWeight *def_weight = defvert_find_index(dv, defgrp_index); | MDeformWeight *def_weight = defvert_find_index(dv, defgrp_index); | ||||
| /* skip if weight value is 0 and no existing weight is found */ | /* skip if weight value is 0 and no existing weight is found */ | ||||
| if ((def_weight != NULL) || (weight[i] != 0.0f)) { | if ((def_weight != NULL) || (weight[i] != 0.0f)) { | ||||
| /* if not found, add a weight for it */ | /* if not found, add a weight for it */ | ||||
| if (def_weight == NULL) { | if (def_weight == NULL) { | ||||
| def_weight = defvert_verify_index(dv, defgrp_index); | def_weight = defvert_verify_index(dv, defgrp_index); | ||||
| } | } | ||||
| /* set weight value */ | /* set weight value */ | ||||
| def_weight->weight = weight[i]; | def_weight->weight = weight[i]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* wave simulation */ | /* wave simulation */ | ||||
| else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) { | else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) { | ||||
| MVert *mvert = result->getVertArray(result); | MVert *mvert = result->mvert; | ||||
| DynamicPaintModifierApplyData data = {.surface = surface, .mvert = mvert}; | DynamicPaintModifierApplyData data = {.surface = surface, .mvert = mvert}; | ||||
| ParallelRangeSettings settings; | ParallelRangeSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (sData->total_points > 1000); | settings.use_threading = (sData->total_points > 1000); | ||||
| BLI_task_parallel_range( | BLI_task_parallel_range( | ||||
| 0, sData->total_points, | 0, sData->total_points, | ||||
| &data, | &data, | ||||
| dynamic_paint_apply_surface_wave_cb, | dynamic_paint_apply_surface_wave_cb, | ||||
| &settings); | &settings); | ||||
| update_normals = true; | update_normals = true; | ||||
| } | } | ||||
| /* displace */ | /* displace */ | ||||
| if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { | if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { | ||||
| dynamicPaint_applySurfaceDisplace(surface, result); | dynamicPaint_applySurfaceDisplace(surface, result); | ||||
| update_normals = true; | update_normals = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (update_normals) { | if (update_normals) { | ||||
| result->dirty |= DM_DIRTY_NORMALS; | //result->dirty |= DM_DIRTY_NORMALS; | ||||
| } | } | ||||
| } | } | ||||
| /* make a copy of dm to use as brush data */ | /* make a copy of mesh to use as brush data */ | ||||
| if (pmd->brush) { | if (pmd->brush) { | ||||
| if (pmd->brush->dm) | if (pmd->brush->mesh) { | ||||
| pmd->brush->dm->release(pmd->brush->dm); | BKE_id_free(NULL, pmd->brush->mesh); | ||||
| pmd->brush->dm = CDDM_copy(result); | } | ||||
| pmd->brush->mesh = BKE_mesh_copy_for_eval(result, false); | |||||
| } | } | ||||
| return result; | return result; | ||||
| } | } | ||||
| /* update cache frame range */ | /* update cache frame range */ | ||||
| void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface) | void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface) | ||||
| { | { | ||||
| if (surface->pointcache) { | if (surface->pointcache) { | ||||
| surface->pointcache->startframe = surface->start_frame; | surface->pointcache->startframe = surface->start_frame; | ||||
| surface->pointcache->endframe = surface->end_frame; | surface->pointcache->endframe = surface->end_frame; | ||||
| } | } | ||||
| } | } | ||||
| static void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMesh *dm) | static void canvas_copyMesh(DynamicPaintCanvasSettings *canvas, Mesh *mesh) | ||||
| { | { | ||||
| if (canvas->dm) { | if (canvas->mesh) { | ||||
| canvas->dm->release(canvas->dm); | BKE_id_free(NULL, canvas->mesh); | ||||
| } | } | ||||
| canvas->dm = CDDM_copy(dm); | canvas->mesh = BKE_mesh_copy_for_eval(mesh, false); | ||||
| } | } | ||||
| /* | /* | ||||
| * Updates derived mesh copy and processes dynamic paint step / caches. | * Updates derived mesh copy and processes dynamic paint step / caches. | ||||
| */ | */ | ||||
| static void dynamicPaint_frameUpdate( | static void dynamicPaint_frameUpdate( | ||||
| DynamicPaintModifierData *pmd, struct Depsgraph *depsgraph, Scene *scene, | DynamicPaintModifierData *pmd, struct Depsgraph *depsgraph, Scene *scene, | ||||
| Object *ob, DerivedMesh *dm) | Object *ob, Mesh *mesh) | ||||
| { | { | ||||
| if (pmd->canvas) { | if (pmd->canvas) { | ||||
| DynamicPaintCanvasSettings *canvas = pmd->canvas; | DynamicPaintCanvasSettings *canvas = pmd->canvas; | ||||
| DynamicPaintSurface *surface = canvas->surfaces.first; | DynamicPaintSurface *surface = canvas->surfaces.first; | ||||
| /* update derived mesh copy */ | /* update derived mesh copy */ | ||||
| canvas_copyDerivedMesh(canvas, dm); | canvas_copyMesh(canvas, mesh); | ||||
| /* in case image sequence baking, stop here */ | /* in case image sequence baking, stop here */ | ||||
| if (canvas->flags & MOD_DPAINT_BAKING) | if (canvas->flags & MOD_DPAINT_BAKING) | ||||
| return; | return; | ||||
| /* loop through surfaces */ | /* loop through surfaces */ | ||||
| for (; surface; surface = surface->next) { | for (; surface; surface = surface->next) { | ||||
| int current_frame = (int)scene->r.cfra; | int current_frame = (int)scene->r.cfra; | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | for (; surface; surface = surface->next) { | ||||
| } | } | ||||
| /* if read failed and we're on surface range do recalculate */ | /* if read failed and we're on surface range do recalculate */ | ||||
| else if (can_simulate) { | else if (can_simulate) { | ||||
| /* calculate surface frame */ | /* calculate surface frame */ | ||||
| canvas->flags |= MOD_DPAINT_BAKING; | canvas->flags |= MOD_DPAINT_BAKING; | ||||
| dynamicPaint_calculateFrame(surface, depsgraph, scene, ob, current_frame); | dynamicPaint_calculateFrame(surface, depsgraph, scene, ob, current_frame); | ||||
| canvas->flags &= ~MOD_DPAINT_BAKING; | canvas->flags &= ~MOD_DPAINT_BAKING; | ||||
| /* restore canvas derivedmesh if required */ | /* restore canvas mesh if required */ | ||||
| if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE && | if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE && | ||||
| surface->flags & MOD_DPAINT_DISP_INCREMENTAL && surface->next) | surface->flags & MOD_DPAINT_DISP_INCREMENTAL && surface->next) | ||||
| { | { | ||||
| canvas_copyDerivedMesh(canvas, dm); | canvas_copyMesh(canvas, mesh); | ||||
| } | } | ||||
| BKE_ptcache_validate(cache, surface->current_frame); | BKE_ptcache_validate(cache, surface->current_frame); | ||||
| BKE_ptcache_write(&pid, surface->current_frame); | BKE_ptcache_write(&pid, surface->current_frame); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Modifier call. Processes dynamic paint modifier step. */ | /* Modifier call. Processes dynamic paint modifier step. */ | ||||
| DerivedMesh *dynamicPaint_Modifier_do( | Mesh *dynamicPaint_Modifier_do( | ||||
| DynamicPaintModifierData *pmd, struct Depsgraph *depsgraph, Scene *scene, | DynamicPaintModifierData *pmd, struct Depsgraph *depsgraph, Scene *scene, | ||||
| Object *ob, DerivedMesh *dm) | Object *ob, Mesh *mesh) | ||||
| { | { | ||||
| if (pmd->canvas) { | if (pmd->canvas) { | ||||
| DerivedMesh *ret; | Mesh *ret; | ||||
| /* Update canvas data for a new frame */ | /* Update canvas data for a new frame */ | ||||
| dynamicPaint_frameUpdate(pmd, depsgraph, scene, ob, dm); | dynamicPaint_frameUpdate(pmd, depsgraph, scene, ob, mesh); | ||||
| /* Return output mesh */ | /* Return output mesh */ | ||||
| ret = dynamicPaint_Modifier_apply(pmd, ob, dm); | ret = dynamicPaint_Modifier_apply(pmd, ob, mesh); | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| else { | else { | ||||
| /* Update canvas data for a new frame */ | /* Update canvas data for a new frame */ | ||||
| dynamicPaint_frameUpdate(pmd, depsgraph, scene, ob, dm); | dynamicPaint_frameUpdate(pmd, depsgraph, scene, ob, mesh); | ||||
| /* Return output mesh */ | /* Return output mesh */ | ||||
| return dynamicPaint_Modifier_apply(pmd, ob, dm); | return dynamicPaint_Modifier_apply(pmd, ob, mesh); | ||||
| } | } | ||||
| } | } | ||||
| /***************************** Image Sequence / UV Image Surface Calls ******************************/ | /***************************** Image Sequence / UV Image Surface Calls ******************************/ | ||||
| /* | /* | ||||
| * Create a surface for uv image sequence format | * Create a surface for uv image sequence format | ||||
| ▲ Show 20 Lines • Show All 585 Lines • ▼ Show 20 Lines | int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface, float *progress, short *do_update) | ||||
| /* Antialias jitter point relative coords */ | /* Antialias jitter point relative coords */ | ||||
| const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; | const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; | ||||
| char uvname[MAX_CUSTOMDATA_LAYER_NAME]; | char uvname[MAX_CUSTOMDATA_LAYER_NAME]; | ||||
| uint32_t active_points = 0; | uint32_t active_points = 0; | ||||
| bool error = false; | bool error = false; | ||||
| PaintSurfaceData *sData; | PaintSurfaceData *sData; | ||||
| DynamicPaintCanvasSettings *canvas = surface->canvas; | DynamicPaintCanvasSettings *canvas = surface->canvas; | ||||
| DerivedMesh *dm = canvas->dm; | Mesh *mesh = canvas->mesh; | ||||
| PaintUVPoint *tempPoints = NULL; | PaintUVPoint *tempPoints = NULL; | ||||
| Vec3f *tempWeights = NULL; | Vec3f *tempWeights = NULL; | ||||
| const MLoopTri *mlooptri = NULL; | const MLoopTri *mlooptri = NULL; | ||||
| const MLoopUV *mloopuv = NULL; | const MLoopUV *mloopuv = NULL; | ||||
| const MLoop *mloop = NULL; | const MLoop *mloop = NULL; | ||||
| Bounds2D *faceBB = NULL; | Bounds2D *faceBB = NULL; | ||||
| int *final_index; | int *final_index; | ||||
| *progress = 0.0f; | *progress = 0.0f; | ||||
| *do_update = true; | *do_update = true; | ||||
| if (!dm) | if (!mesh) | ||||
| return setError(canvas, N_("Canvas mesh not updated")); | return setError(canvas, N_("Canvas mesh not updated")); | ||||
| if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) | if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) | ||||
| return setError(canvas, N_("Cannot bake non-'image sequence' formats")); | return setError(canvas, N_("Cannot bake non-'image sequence' formats")); | ||||
| mloop = dm->getLoopArray(dm); | mloop = mesh->mloop; | ||||
| mlooptri = dm->getLoopTriArray(dm); | mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);; | ||||
| const int tottri = dm->getNumLoopTri(dm); | const int tottri = BKE_mesh_runtime_looptri_len(mesh); | ||||
| /* get uv map */ | /* get uv map */ | ||||
| if (CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) { | if (CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { | ||||
| CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, surface->uvlayer_name, uvname); | CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, surface->uvlayer_name, uvname); | ||||
| mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname); | mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname); | ||||
| } | } | ||||
| /* Check for validity */ | /* Check for validity */ | ||||
| if (!mloopuv) | if (!mloopuv) | ||||
| return setError(canvas, N_("No UV data on canvas")); | return setError(canvas, N_("No UV data on canvas")); | ||||
| if (surface->image_resolution < 16 || surface->image_resolution > 8192) | if (surface->image_resolution < 16 || surface->image_resolution > 8192) | ||||
| return setError(canvas, N_("Invalid resolution")); | return setError(canvas, N_("Invalid resolution")); | ||||
| ▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | /* Generate surface adjacency data. */ | ||||
| PaintAdjData *ed = sData->adj_data; | PaintAdjData *ed = sData->adj_data; | ||||
| int n_pos = 0; | int n_pos = 0; | ||||
| MeshElemMap *vert_to_looptri_map; | MeshElemMap *vert_to_looptri_map; | ||||
| int *vert_to_looptri_map_mem; | int *vert_to_looptri_map_mem; | ||||
| BKE_mesh_vert_looptri_map_create( | BKE_mesh_vert_looptri_map_create( | ||||
| &vert_to_looptri_map, &vert_to_looptri_map_mem, | &vert_to_looptri_map, &vert_to_looptri_map_mem, | ||||
| dm->getVertArray(dm), dm->getNumVerts(dm), mlooptri, tottri, mloop, dm->getNumLoops(dm)); | mesh->mvert, mesh->totvert, mlooptri, tottri, mloop, mesh->totloop); | ||||
| int total_border = 0; | int total_border = 0; | ||||
| for (int ty = 0; ty < h; ty++) { | for (int ty = 0; ty < h; ty++) { | ||||
| for (int tx = 0; tx < w; tx++) { | for (int tx = 0; tx < w; tx++) { | ||||
| const int index = tx + w * ty; | const int index = tx + w * ty; | ||||
| if (tempPoints[index].tri_index != -1) { | if (tempPoints[index].tri_index != -1) { | ||||
| ▲ Show 20 Lines • Show All 720 Lines • ▼ Show 20 Lines | static void dynamic_paint_brush_velocity_compute_cb( | ||||
| mul_v3_fl(brush_vel[i].v, 1.0f / timescale); | mul_v3_fl(brush_vel[i].v, 1.0f / timescale); | ||||
| } | } | ||||
| static void dynamicPaint_brushMeshCalculateVelocity( | static void dynamicPaint_brushMeshCalculateVelocity( | ||||
| Depsgraph *depsgraph, Scene *scene, | Depsgraph *depsgraph, Scene *scene, | ||||
| Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale) | Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale) | ||||
| { | { | ||||
| float prev_obmat[4][4]; | float prev_obmat[4][4]; | ||||
| DerivedMesh *dm_p, *dm_c; | Mesh *mesh_p, *mesh_c; | ||||
| MVert *mvert_p, *mvert_c; | MVert *mvert_p, *mvert_c; | ||||
| int numOfVerts_p, numOfVerts_c; | int numOfVerts_p, numOfVerts_c; | ||||
| float cur_sfra = scene->r.subframe; | float cur_sfra = scene->r.subframe; | ||||
| int cur_fra = scene->r.cfra; | int cur_fra = scene->r.cfra; | ||||
| float prev_sfra = cur_sfra - timescale; | float prev_sfra = cur_sfra - timescale; | ||||
| int prev_fra = cur_fra; | int prev_fra = cur_fra; | ||||
| if (prev_sfra < 0.0f) { | if (prev_sfra < 0.0f) { | ||||
| prev_sfra += 1.0f; | prev_sfra += 1.0f; | ||||
| prev_fra = cur_fra - 1; | prev_fra = cur_fra - 1; | ||||
| } | } | ||||
| /* previous frame dm */ | /* previous frame mesh */ | ||||
| scene->r.cfra = prev_fra; | scene->r.cfra = prev_fra; | ||||
| scene->r.subframe = prev_sfra; | scene->r.subframe = prev_sfra; | ||||
| BKE_object_modifier_update_subframe( | BKE_object_modifier_update_subframe( | ||||
| depsgraph, scene, ob, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); | depsgraph, scene, ob, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); | ||||
| dm_p = CDDM_copy(brush->dm); | mesh_p = BKE_mesh_copy_for_eval(brush->mesh, false); | ||||
| numOfVerts_p = dm_p->getNumVerts(dm_p); | numOfVerts_p = mesh_p->totvert; | ||||
| mvert_p = dm_p->getVertArray(dm_p); | mvert_p = mesh_p->mvert; | ||||
| copy_m4_m4(prev_obmat, ob->obmat); | copy_m4_m4(prev_obmat, ob->obmat); | ||||
| /* current frame dm */ | /* current frame mesh */ | ||||
| scene->r.cfra = cur_fra; | scene->r.cfra = cur_fra; | ||||
| scene->r.subframe = cur_sfra; | scene->r.subframe = cur_sfra; | ||||
| BKE_object_modifier_update_subframe( | BKE_object_modifier_update_subframe( | ||||
| depsgraph, scene, ob, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); | depsgraph, scene, ob, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); | ||||
| dm_c = brush->dm; | mesh_c = brush->mesh; | ||||
| numOfVerts_c = dm_c->getNumVerts(dm_c); | numOfVerts_c = mesh_c->totvert; | ||||
| mvert_c = dm_p->getVertArray(dm_c); | mvert_c = mesh_c->mvert; | ||||
| (*brushVel) = (struct Vec3f *) MEM_mallocN(numOfVerts_c * sizeof(Vec3f), "Dynamic Paint brush velocity"); | (*brushVel) = (struct Vec3f *) MEM_mallocN(numOfVerts_c * sizeof(Vec3f), "Dynamic Paint brush velocity"); | ||||
| if (!(*brushVel)) | if (!(*brushVel)) | ||||
| return; | return; | ||||
| /* if mesh is constructive -> num of verts has changed, only use current frame derived mesh */ | /* if mesh is constructive -> num of verts has changed, only use current frame derived mesh */ | ||||
| if (numOfVerts_p != numOfVerts_c) | if (numOfVerts_p != numOfVerts_c) | ||||
| mvert_p = mvert_c; | mvert_p = mvert_c; | ||||
| /* calculate speed */ | /* calculate speed */ | ||||
| DynamicPaintBrushVelocityData data = { | DynamicPaintBrushVelocityData data = { | ||||
| .brush_vel = *brushVel, | .brush_vel = *brushVel, | ||||
| .mvert_p = mvert_p, .mvert_c = mvert_c, .obmat = ob->obmat, .prev_obmat = prev_obmat, | .mvert_p = mvert_p, .mvert_c = mvert_c, .obmat = ob->obmat, .prev_obmat = prev_obmat, | ||||
| .timescale = timescale, | .timescale = timescale, | ||||
| }; | }; | ||||
| ParallelRangeSettings settings; | ParallelRangeSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (numOfVerts_c > 10000); | settings.use_threading = (numOfVerts_c > 10000); | ||||
| BLI_task_parallel_range(0, numOfVerts_c, | BLI_task_parallel_range(0, numOfVerts_c, | ||||
| &data, | &data, | ||||
| dynamic_paint_brush_velocity_compute_cb, | dynamic_paint_brush_velocity_compute_cb, | ||||
| &settings); | &settings); | ||||
| dm_p->release(dm_p); | BKE_id_free(NULL, mesh_p); | ||||
| } | } | ||||
| /* calculate velocity for object center point */ | /* calculate velocity for object center point */ | ||||
| static void dynamicPaint_brushObjectCalculateVelocity( | static void dynamicPaint_brushObjectCalculateVelocity( | ||||
| Depsgraph *depsgraph, Scene *scene, Object *ob, Vec3f *brushVel, float timescale) | Depsgraph *depsgraph, Scene *scene, Object *ob, Vec3f *brushVel, float timescale) | ||||
| { | { | ||||
| float prev_obmat[4][4]; | float prev_obmat[4][4]; | ||||
| float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f}; | float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f}; | ||||
| float cur_sfra = scene->r.subframe; | float cur_sfra = scene->r.subframe; | ||||
| int cur_fra = scene->r.cfra; | int cur_fra = scene->r.cfra; | ||||
| float prev_sfra = cur_sfra - timescale; | float prev_sfra = cur_sfra - timescale; | ||||
| int prev_fra = cur_fra; | int prev_fra = cur_fra; | ||||
| if (prev_sfra < 0.0f) { | if (prev_sfra < 0.0f) { | ||||
| prev_sfra += 1.0f; | prev_sfra += 1.0f; | ||||
| prev_fra = cur_fra - 1; | prev_fra = cur_fra - 1; | ||||
| } | } | ||||
| /* previous frame dm */ | /* previous frame mesh */ | ||||
| scene->r.cfra = prev_fra; | scene->r.cfra = prev_fra; | ||||
| scene->r.subframe = prev_sfra; | scene->r.subframe = prev_sfra; | ||||
| BKE_object_modifier_update_subframe( | BKE_object_modifier_update_subframe( | ||||
| depsgraph, scene, ob, false, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); | depsgraph, scene, ob, false, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); | ||||
| copy_m4_m4(prev_obmat, ob->obmat); | copy_m4_m4(prev_obmat, ob->obmat); | ||||
| /* current frame dm */ | /* current frame mesh */ | ||||
| scene->r.cfra = cur_fra; | scene->r.cfra = cur_fra; | ||||
| scene->r.subframe = cur_sfra; | scene->r.subframe = cur_sfra; | ||||
| BKE_object_modifier_update_subframe( | BKE_object_modifier_update_subframe( | ||||
| depsgraph, scene, ob, false, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); | depsgraph, scene, ob, false, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); | ||||
| /* calculate speed */ | /* calculate speed */ | ||||
| mul_m4_v3(prev_obmat, prev_loc); | mul_m4_v3(prev_obmat, prev_loc); | ||||
| mul_m4_v3(ob->obmat, cur_loc); | mul_m4_v3(ob->obmat, cur_loc); | ||||
| sub_v3_v3v3(brushVel->v, cur_loc, prev_loc); | sub_v3_v3v3(brushVel->v, cur_loc, prev_loc); | ||||
| mul_v3_fl(brushVel->v, 1.0f / timescale); | mul_v3_fl(brushVel->v, 1.0f / timescale); | ||||
| } | } | ||||
| typedef struct DynamicPaintPaintData { | typedef struct DynamicPaintPaintData { | ||||
| const DynamicPaintSurface *surface; | const DynamicPaintSurface *surface; | ||||
| const DynamicPaintBrushSettings *brush; | const DynamicPaintBrushSettings *brush; | ||||
| Object *brushOb; | Object *brushOb; | ||||
| const Scene *scene; | const Scene *scene; | ||||
| const float timescale; | const float timescale; | ||||
| const int c_index; | const int c_index; | ||||
| DerivedMesh *dm; | Mesh *mesh; | ||||
| const MVert *mvert; | const MVert *mvert; | ||||
| const MLoop *mloop; | const MLoop *mloop; | ||||
| const MLoopTri *mlooptri; | const MLoopTri *mlooptri; | ||||
| const float brush_radius; | const float brush_radius; | ||||
| const float *avg_brushNor; | const float *avg_brushNor; | ||||
| const Vec3f *brushVelocity; | const Vec3f *brushVelocity; | ||||
| const ParticleSystem *psys; | const ParticleSystem *psys; | ||||
| ▲ Show 20 Lines • Show All 333 Lines • ▼ Show 20 Lines | |||||
| static int dynamicPaint_paintMesh(Depsgraph *depsgraph, DynamicPaintSurface *surface, | static int dynamicPaint_paintMesh(Depsgraph *depsgraph, DynamicPaintSurface *surface, | ||||
| DynamicPaintBrushSettings *brush, | DynamicPaintBrushSettings *brush, | ||||
| Object *brushOb, | Object *brushOb, | ||||
| Scene *scene, | Scene *scene, | ||||
| float timescale) | float timescale) | ||||
| { | { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| PaintBakeData *bData = sData->bData; | PaintBakeData *bData = sData->bData; | ||||
| DerivedMesh *dm = NULL; | Mesh *mesh = NULL; | ||||
| Vec3f *brushVelocity = NULL; | Vec3f *brushVelocity = NULL; | ||||
| MVert *mvert = NULL; | MVert *mvert = NULL; | ||||
| const MLoopTri *mlooptri = NULL; | const MLoopTri *mlooptri = NULL; | ||||
| const MLoop *mloop = NULL; | const MLoop *mloop = NULL; | ||||
| if (brush->flags & MOD_DPAINT_USES_VELOCITY) | if (brush->flags & MOD_DPAINT_USES_VELOCITY) | ||||
| dynamicPaint_brushMeshCalculateVelocity(depsgraph, scene, brushOb, brush, &brushVelocity, timescale); | dynamicPaint_brushMeshCalculateVelocity(depsgraph, scene, brushOb, brush, &brushVelocity, timescale); | ||||
| if (!brush->dm) | if (!brush->mesh) | ||||
| return 0; | return 0; | ||||
| { | { | ||||
| BVHTreeFromMesh treeData = {NULL}; | BVHTreeFromMesh treeData = {NULL}; | ||||
| float avg_brushNor[3] = {0.0f}; | float avg_brushNor[3] = {0.0f}; | ||||
| const float brush_radius = brush->paint_distance * surface->radius_scale; | const float brush_radius = brush->paint_distance * surface->radius_scale; | ||||
| int numOfVerts; | int numOfVerts; | ||||
| int ii; | int ii; | ||||
| Bounds3D mesh_bb = {{0}}; | Bounds3D mesh_bb = {{0}}; | ||||
| VolumeGrid *grid = bData->grid; | VolumeGrid *grid = bData->grid; | ||||
| dm = CDDM_copy(brush->dm); | mesh = BKE_mesh_copy_for_eval(brush->mesh, false); | ||||
| mvert = dm->getVertArray(dm); | mvert = mesh->mvert; | ||||
| mlooptri = dm->getLoopTriArray(dm); | mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| mloop = dm->getLoopArray(dm); | mloop = mesh->mloop; | ||||
| numOfVerts = dm->getNumVerts(dm); | numOfVerts = mesh->totvert; | ||||
| /* Transform collider vertices to global space | /* Transform collider vertices to global space | ||||
| * (Faster than transforming per surface point | * (Faster than transforming per surface point | ||||
| * coordinates and normals to object space) */ | * coordinates and normals to object space) */ | ||||
| for (ii = 0; ii < numOfVerts; ii++) { | for (ii = 0; ii < numOfVerts; ii++) { | ||||
| mul_m4_v3(brushOb->obmat, mvert[ii].co); | mul_m4_v3(brushOb->obmat, mvert[ii].co); | ||||
| boundInsert(&mesh_bb, mvert[ii].co); | boundInsert(&mesh_bb, mvert[ii].co); | ||||
| Show All 14 Lines | if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) { | ||||
| if (UNLIKELY(normalize_v3(avg_brushNor) == 0.0f)) { | if (UNLIKELY(normalize_v3(avg_brushNor) == 0.0f)) { | ||||
| avg_brushNor[2] = 1.0f; | avg_brushNor[2] = 1.0f; | ||||
| } | } | ||||
| } | } | ||||
| /* check bounding box collision */ | /* check bounding box collision */ | ||||
| if (grid && meshBrush_boundsIntersect(&grid->grid_bounds, &mesh_bb, brush, brush_radius)) { | if (grid && meshBrush_boundsIntersect(&grid->grid_bounds, &mesh_bb, brush, brush_radius)) { | ||||
| /* Build a bvh tree from transformed vertices */ | /* Build a bvh tree from transformed vertices */ | ||||
| if (bvhtree_from_mesh_get(&treeData, dm, BVHTREE_FROM_LOOPTRI, 4)) { | if (BKE_bvhtree_from_mesh_get(&treeData, mesh, BVHTREE_FROM_LOOPTRI, 4)) { | ||||
| int c_index; | int c_index; | ||||
| int total_cells = grid->dim[0] * grid->dim[1] * grid->dim[2]; | int total_cells = grid->dim[0] * grid->dim[1] * grid->dim[2]; | ||||
| /* loop through space partitioning grid */ | /* loop through space partitioning grid */ | ||||
| for (c_index = 0; c_index < total_cells; c_index++) { | for (c_index = 0; c_index < total_cells; c_index++) { | ||||
| /* check grid cell bounding box */ | /* check grid cell bounding box */ | ||||
| if (!grid->s_num[c_index] || | if (!grid->s_num[c_index] || | ||||
| !meshBrush_boundsIntersect(&grid->bounds[c_index], &mesh_bb, brush, brush_radius)) | !meshBrush_boundsIntersect(&grid->bounds[c_index], &mesh_bb, brush, brush_radius)) | ||||
| { | { | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* loop through cell points and process brush */ | /* loop through cell points and process brush */ | ||||
| DynamicPaintPaintData data = { | DynamicPaintPaintData data = { | ||||
| .surface = surface, | .surface = surface, | ||||
| .brush = brush, .brushOb = brushOb, | .brush = brush, .brushOb = brushOb, | ||||
| .scene = scene, .timescale = timescale, .c_index = c_index, | .scene = scene, .timescale = timescale, .c_index = c_index, | ||||
| .dm = dm, .mvert = mvert, .mloop = mloop, .mlooptri = mlooptri, | .mesh = mesh, .mvert = mvert, .mloop = mloop, .mlooptri = mlooptri, | ||||
| .brush_radius = brush_radius, .avg_brushNor = avg_brushNor, .brushVelocity = brushVelocity, | .brush_radius = brush_radius, .avg_brushNor = avg_brushNor, .brushVelocity = brushVelocity, | ||||
| .treeData = &treeData | .treeData = &treeData | ||||
| }; | }; | ||||
| ParallelRangeSettings settings; | ParallelRangeSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (grid->s_num[c_index] > 250); | settings.use_threading = (grid->s_num[c_index] > 250); | ||||
| BLI_task_parallel_range(0, grid->s_num[c_index], | BLI_task_parallel_range(0, grid->s_num[c_index], | ||||
| &data, | &data, | ||||
| dynamic_paint_paint_mesh_cell_point_cb_ex, | dynamic_paint_paint_mesh_cell_point_cb_ex, | ||||
| &settings); | &settings); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* free bvh tree */ | /* free bvh tree */ | ||||
| free_bvhtree_from_mesh(&treeData); | free_bvhtree_from_mesh(&treeData); | ||||
| dm->release(dm); | BKE_id_free(NULL, mesh); | ||||
| } | } | ||||
| /* free brush velocity data */ | /* free brush velocity data */ | ||||
| if (brushVelocity) | if (brushVelocity) | ||||
| MEM_freeN(brushVelocity); | MEM_freeN(brushVelocity); | ||||
| return 1; | return 1; | ||||
| ▲ Show 20 Lines • Show All 383 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| float brush_radius = brush->paint_distance * surface->radius_scale; | float brush_radius = brush->paint_distance * surface->radius_scale; | ||||
| Vec3f brushVel; | Vec3f brushVel; | ||||
| if (brush->flags & MOD_DPAINT_USES_VELOCITY) | if (brush->flags & MOD_DPAINT_USES_VELOCITY) | ||||
| dynamicPaint_brushObjectCalculateVelocity(depsgraph, scene, brushOb, &brushVel, timescale); | dynamicPaint_brushObjectCalculateVelocity(depsgraph, scene, brushOb, &brushVel, timescale); | ||||
| const MVert *mvert = brush->dm->getVertArray(brush->dm); | const MVert *mvert = brush->mesh->mvert; | ||||
| /* | /* | ||||
| * Loop through every surface point | * Loop through every surface point | ||||
| */ | */ | ||||
| DynamicPaintPaintData data = { | DynamicPaintPaintData data = { | ||||
| .surface = surface, | .surface = surface, | ||||
| .brush = brush, .brushOb = brushOb, | .brush = brush, .brushOb = brushOb, | ||||
| .scene = scene, .timescale = timescale, | .scene = scene, .timescale = timescale, | ||||
| ▲ Show 20 Lines • Show All 1,002 Lines • ▼ Show 20 Lines | else if (surface->flags & MOD_DPAINT_DISSOLVE && | ||||
| CLAMP_MIN(*point, 0.0f); | CLAMP_MIN(*point, 0.0f); | ||||
| } | } | ||||
| } | } | ||||
| static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *ob) | static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *ob) | ||||
| { | { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| PaintBakeData *bData = sData->bData; | PaintBakeData *bData = sData->bData; | ||||
| DerivedMesh *dm = surface->canvas->dm; | Mesh *mesh = surface->canvas->mesh; | ||||
| MVert *mvert = dm->getVertArray(dm); | MVert *mvert = mesh->mvert; | ||||
| int numOfVerts = dm->getNumVerts(dm); | int numOfVerts = mesh->totvert; | ||||
| int i; | int i; | ||||
| if (!bData->prev_verts) | if (!bData->prev_verts) | ||||
| return true; | return true; | ||||
| /* matrix comparison */ | /* matrix comparison */ | ||||
| if (!equals_m4m4(bData->prev_obmat, ob->obmat)) | if (!equals_m4m4(bData->prev_obmat, ob->obmat)) | ||||
| return true; | return true; | ||||
| ▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | if (do_velocity_data && !new_bdata && !bData->clear) { | ||||
| sub_v3_v3v3(bData->velocity[index].v, bData->realCoord[bData->s_pos[index]].v, prev_point); | sub_v3_v3v3(bData->velocity[index].v, bData->realCoord[bData->s_pos[index]].v, prev_point); | ||||
| } | } | ||||
| } | } | ||||
| static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, Depsgraph *depsgraph, Object *ob) | static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, Depsgraph *depsgraph, Object *ob) | ||||
| { | { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| PaintBakeData *bData = sData->bData; | PaintBakeData *bData = sData->bData; | ||||
| DerivedMesh *dm = surface->canvas->dm; | Mesh *mesh = surface->canvas->mesh; | ||||
| int index; | int index; | ||||
| bool new_bdata = false; | bool new_bdata = false; | ||||
| const bool do_velocity_data = ((surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) || | const bool do_velocity_data = ((surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) || | ||||
| (surface_getBrushFlags(surface, depsgraph) & BRUSH_USES_VELOCITY)); | (surface_getBrushFlags(surface, depsgraph) & BRUSH_USES_VELOCITY)); | ||||
| const bool do_accel_data = (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) != 0; | const bool do_accel_data = (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) != 0; | ||||
| int canvasNumOfVerts = dm->getNumVerts(dm); | int canvasNumOfVerts = mesh->totvert; | ||||
| MVert *mvert = dm->getVertArray(dm); | MVert *mvert = mesh->mvert; | ||||
| Vec3f *canvas_verts; | Vec3f *canvas_verts; | ||||
| if (bData) { | if (bData) { | ||||
| const bool surface_moved = dynamicPaint_surfaceHasMoved(surface, ob); | const bool surface_moved = dynamicPaint_surfaceHasMoved(surface, ob); | ||||
| /* get previous speed for accelertaion */ | /* get previous speed for accelertaion */ | ||||
| if (do_accel_data && bData->prev_velocity && bData->velocity) | if (do_accel_data && bData->prev_velocity && bData->velocity) | ||||
| memcpy(bData->prev_velocity, bData->velocity, sData->total_points * sizeof(Vec3f)); | memcpy(bData->prev_velocity, bData->velocity, sData->total_points * sizeof(Vec3f)); | ||||
| ▲ Show 20 Lines • Show All 252 Lines • ▼ Show 20 Lines | |||||
| int dynamicPaint_calculateFrame( | int dynamicPaint_calculateFrame( | ||||
| DynamicPaintSurface *surface, struct Depsgraph *depsgraph, | DynamicPaintSurface *surface, struct Depsgraph *depsgraph, | ||||
| Scene *scene, Object *cObject, int frame) | Scene *scene, Object *cObject, int frame) | ||||
| { | { | ||||
| float timescale = 1.0f; | float timescale = 1.0f; | ||||
| /* apply previous displace on derivedmesh if incremental surface */ | /* apply previous displace on derivedmesh if incremental surface */ | ||||
| if (surface->flags & MOD_DPAINT_DISP_INCREMENTAL) | if (surface->flags & MOD_DPAINT_DISP_INCREMENTAL) | ||||
| dynamicPaint_applySurfaceDisplace(surface, surface->canvas->dm); | dynamicPaint_applySurfaceDisplace(surface, surface->canvas->mesh); | ||||
| /* update bake data */ | /* update bake data */ | ||||
| dynamicPaint_generateBakeData(surface, depsgraph, cObject); | dynamicPaint_generateBakeData(surface, depsgraph, cObject); | ||||
| /* don't do substeps for first frame */ | /* don't do substeps for first frame */ | ||||
| if (surface->substeps && (frame != surface->start_frame)) { | if (surface->substeps && (frame != surface->start_frame)) { | ||||
| int st; | int st; | ||||
| timescale = 1.0f / (surface->substeps + 1); | timescale = 1.0f / (surface->substeps + 1); | ||||
| Show All 10 Lines | |||||