Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/dynamicpaint.c
| Show First 20 Lines • Show All 296 Lines • ▼ Show 20 Lines | static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface) | ||||
| else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| const Mesh *canvas_mesh = dynamicPaint_canvas_mesh_get(surface->canvas); | const Mesh *canvas_mesh = dynamicPaint_canvas_mesh_get(surface->canvas); | ||||
| return (canvas_mesh) ? canvas_mesh->totvert : 0; | return (canvas_mesh) ? canvas_mesh->totvert : 0; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /* checks whether surface's format/type has realtime preview */ | |||||
| bool dynamicPaint_surfaceHasColorPreview(DynamicPaintSurface *surface) | |||||
| { | |||||
| if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { | |||||
| return false; | |||||
| } | |||||
| else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | |||||
| return !ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WAVE); | |||||
| } | |||||
| return true; | |||||
| } | |||||
| /* get currently active surface (in user interface) */ | /* get currently active surface (in user interface) */ | ||||
| DynamicPaintSurface *get_activeSurface(DynamicPaintCanvasSettings *canvas) | DynamicPaintSurface *get_activeSurface(DynamicPaintCanvasSettings *canvas) | ||||
| { | { | ||||
| return BLI_findlink(&canvas->surfaces, canvas->active_sur); | return BLI_findlink(&canvas->surfaces, canvas->active_sur); | ||||
| } | } | ||||
| /* set preview to first previewable surface */ | |||||
| void dynamicPaint_resetPreview(DynamicPaintCanvasSettings *canvas) | |||||
| { | |||||
| DynamicPaintSurface *surface = canvas->surfaces.first; | |||||
| bool done = false; | |||||
| for (; surface; surface = surface->next) { | |||||
| if (!done && dynamicPaint_surfaceHasColorPreview(surface)) { | |||||
| surface->flags |= MOD_DPAINT_PREVIEW; | |||||
| done = true; | |||||
| } | |||||
| else { | |||||
| surface->flags &= ~MOD_DPAINT_PREVIEW; | |||||
| } | |||||
| } | |||||
| } | |||||
| /* set preview to defined surface */ | |||||
| static void dynamicPaint_setPreview(DynamicPaintSurface *t_surface) | |||||
| { | |||||
| DynamicPaintSurface *surface = t_surface->canvas->surfaces.first; | |||||
| for (; surface; surface = surface->next) { | |||||
| if (surface == t_surface) { | |||||
| surface->flags |= MOD_DPAINT_PREVIEW; | |||||
| } | |||||
| else { | |||||
| surface->flags &= ~MOD_DPAINT_PREVIEW; | |||||
| } | |||||
| } | |||||
| } | |||||
| bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object *ob, int output) | bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object *ob, int output) | ||||
| { | { | ||||
| const char *name; | const char *name; | ||||
| if (output == 0) { | if (output == 0) { | ||||
| name = surface->output_name; | name = surface->output_name; | ||||
| } | } | ||||
| else if (output == 1) { | else if (output == 1) { | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) | ||||
| else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { | else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { | ||||
| strcat(surface->output_name, "weight"); | strcat(surface->output_name, "weight"); | ||||
| } | } | ||||
| else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) { | else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) { | ||||
| strcat(surface->output_name, "wave"); | strcat(surface->output_name, "wave"); | ||||
| } | } | ||||
| surface_setUniqueOutputName(surface, surface->output_name, 0); | surface_setUniqueOutputName(surface, surface->output_name, 0); | ||||
| /* update preview */ | |||||
| if (dynamicPaint_surfaceHasColorPreview(surface)) { | |||||
| dynamicPaint_setPreview(surface); | |||||
| } | |||||
| else { | |||||
| dynamicPaint_resetPreview(surface->canvas); | |||||
| } | |||||
| } | } | ||||
| static int surface_totalSamples(DynamicPaintSurface *surface) | static int surface_totalSamples(DynamicPaintSurface *surface) | ||||
| { | { | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->flags & MOD_DPAINT_ANTIALIAS) { | if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->flags & MOD_DPAINT_ANTIALIAS) { | ||||
| return (surface->data->total_points * 5); | return (surface->data->total_points * 5); | ||||
| } | } | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX && surface->flags & MOD_DPAINT_ANTIALIAS && | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX && surface->flags & MOD_DPAINT_ANTIALIAS && | ||||
| ▲ Show 20 Lines • Show All 584 Lines • ▼ Show 20 Lines | DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas, | ||||
| /* cache */ | /* cache */ | ||||
| surface->pointcache = BKE_ptcache_add(&(surface->ptcaches)); | surface->pointcache = BKE_ptcache_add(&(surface->ptcaches)); | ||||
| surface->pointcache->flag |= PTCACHE_DISK_CACHE; | surface->pointcache->flag |= PTCACHE_DISK_CACHE; | ||||
| surface->pointcache->step = 1; | surface->pointcache->step = 1; | ||||
| /* Set initial values */ | /* Set initial values */ | ||||
| surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | | surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | | ||||
| MOD_DPAINT_DISSOLVE_LOG | MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW | | MOD_DPAINT_DISSOLVE_LOG | MOD_DPAINT_ACTIVE | | ||||
| MOD_DPAINT_OUT1 | MOD_DPAINT_USE_DRYING; | MOD_DPAINT_OUT1 | MOD_DPAINT_USE_DRYING; | ||||
| surface->effect = 0; | surface->effect = 0; | ||||
| surface->effect_ui = 1; | surface->effect_ui = 1; | ||||
| surface->diss_speed = 250; | surface->diss_speed = 250; | ||||
| surface->dry_speed = 500; | surface->dry_speed = 500; | ||||
| surface->color_dry_threshold = 1.0f; | surface->color_dry_threshold = 1.0f; | ||||
| surface->depth_clamp = 0.0f; | surface->depth_clamp = 0.0f; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { | ||||
| t_surface->effector_weights = MEM_dupallocN(surface->effector_weights); | t_surface->effector_weights = MEM_dupallocN(surface->effector_weights); | ||||
| BLI_strncpy(t_surface->name, surface->name, sizeof(t_surface->name)); | BLI_strncpy(t_surface->name, surface->name, sizeof(t_surface->name)); | ||||
| t_surface->format = surface->format; | t_surface->format = surface->format; | ||||
| t_surface->type = surface->type; | t_surface->type = surface->type; | ||||
| t_surface->disp_type = surface->disp_type; | t_surface->disp_type = surface->disp_type; | ||||
| t_surface->image_fileformat = surface->image_fileformat; | t_surface->image_fileformat = surface->image_fileformat; | ||||
| t_surface->effect_ui = surface->effect_ui; | t_surface->effect_ui = surface->effect_ui; | ||||
| t_surface->preview_id = surface->preview_id; | |||||
| t_surface->init_color_type = surface->init_color_type; | t_surface->init_color_type = surface->init_color_type; | ||||
| t_surface->flags = surface->flags; | t_surface->flags = surface->flags; | ||||
| t_surface->effect = surface->effect; | t_surface->effect = surface->effect; | ||||
| t_surface->image_resolution = surface->image_resolution; | t_surface->image_resolution = surface->image_resolution; | ||||
| t_surface->substeps = surface->substeps; | t_surface->substeps = surface->substeps; | ||||
| t_surface->start_frame = surface->start_frame; | t_surface->start_frame = surface->start_frame; | ||||
| t_surface->end_frame = surface->end_frame; | t_surface->end_frame = surface->end_frame; | ||||
| Show All 26 Lines | for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { | ||||
| BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name)); | BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name)); | ||||
| BLI_strncpy(t_surface->image_output_path, | BLI_strncpy(t_surface->image_output_path, | ||||
| surface->image_output_path, | surface->image_output_path, | ||||
| sizeof(t_surface->image_output_path)); | sizeof(t_surface->image_output_path)); | ||||
| BLI_strncpy(t_surface->output_name, surface->output_name, sizeof(t_surface->output_name)); | BLI_strncpy(t_surface->output_name, surface->output_name, sizeof(t_surface->output_name)); | ||||
| BLI_strncpy(t_surface->output_name2, surface->output_name2, sizeof(t_surface->output_name2)); | BLI_strncpy(t_surface->output_name2, surface->output_name2, sizeof(t_surface->output_name2)); | ||||
| } | } | ||||
| dynamicPaint_resetPreview(tpmd->canvas); | |||||
| } | } | ||||
| else if (tpmd->brush) { | else if (tpmd->brush) { | ||||
| DynamicPaintBrushSettings *brush = pmd->brush, *t_brush = tpmd->brush; | DynamicPaintBrushSettings *brush = pmd->brush, *t_brush = tpmd->brush; | ||||
| t_brush->pmd = tpmd; | t_brush->pmd = tpmd; | ||||
| t_brush->flags = brush->flags; | t_brush->flags = brush->flags; | ||||
| t_brush->collision = brush->collision; | t_brush->collision = brush->collision; | ||||
| ▲ Show 20 Lines • Show All 501 Lines • ▼ Show 20 Lines | typedef struct DynamicPaintModifierApplyData { | ||||
| MVert *mvert; | MVert *mvert; | ||||
| const MLoop *mloop; | const MLoop *mloop; | ||||
| const MPoly *mpoly; | const MPoly *mpoly; | ||||
| float (*fcolor)[4]; | float (*fcolor)[4]; | ||||
| MLoopCol *mloopcol; | MLoopCol *mloopcol; | ||||
| MLoopCol *mloopcol_wet; | MLoopCol *mloopcol_wet; | ||||
| MLoopCol *mloopcol_preview; | |||||
| } DynamicPaintModifierApplyData; | } DynamicPaintModifierApplyData; | ||||
| static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata, | static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata, | ||||
| const int i, | const int i, | ||||
| const ParallelRangeTLS *__restrict UNUSED(tls)) | const ParallelRangeTLS *__restrict UNUSED(tls)) | ||||
| { | { | ||||
| const DynamicPaintModifierApplyData *data = userdata; | const DynamicPaintModifierApplyData *data = userdata; | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | blendColors( | ||||
| pPoint[i].color, pPoint[i].color[3], pPoint[i].e_color, pPoint[i].e_color[3], fcolor[i]); | pPoint[i].color, pPoint[i].color[3], pPoint[i].e_color, pPoint[i].e_color[3], fcolor[i]); | ||||
| } | } | ||||
| static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, | static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, | ||||
| const int p_index, | const int p_index, | ||||
| const ParallelRangeTLS *__restrict UNUSED(tls)) | const ParallelRangeTLS *__restrict UNUSED(tls)) | ||||
| { | { | ||||
| const DynamicPaintModifierApplyData *data = userdata; | const DynamicPaintModifierApplyData *data = userdata; | ||||
| Object *ob = data->ob; | |||||
| const MLoop *mloop = data->mloop; | const MLoop *mloop = data->mloop; | ||||
| const MPoly *mpoly = data->mpoly; | const MPoly *mpoly = data->mpoly; | ||||
| const DynamicPaintSurface *surface = data->surface; | const DynamicPaintSurface *surface = data->surface; | ||||
| PaintPoint *pPoint = (PaintPoint *)surface->data->type_data; | PaintPoint *pPoint = (PaintPoint *)surface->data->type_data; | ||||
| float(*fcolor)[4] = data->fcolor; | float(*fcolor)[4] = data->fcolor; | ||||
| MLoopCol *mloopcol = data->mloopcol; | MLoopCol *mloopcol = data->mloopcol; | ||||
| MLoopCol *mloopcol_wet = data->mloopcol_wet; | MLoopCol *mloopcol_wet = data->mloopcol_wet; | ||||
| MLoopCol *mloopcol_preview = data->mloopcol_preview; | |||||
| const Material *material = mloopcol_preview ? | |||||
| give_current_material(ob, mpoly[p_index].mat_nr + 1) : | |||||
| NULL; | |||||
| for (int j = 0; j < mpoly[p_index].totloop; j++) { | for (int j = 0; j < mpoly[p_index].totloop; j++) { | ||||
| const int l_index = mpoly[p_index].loopstart + j; | const int l_index = mpoly[p_index].loopstart + j; | ||||
| const int v_index = mloop[l_index].v; | const int v_index = mloop[l_index].v; | ||||
| /* save layer data to output layer */ | /* save layer data to output layer */ | ||||
| /* apply color */ | /* apply color */ | ||||
| if (mloopcol) { | if (mloopcol) { | ||||
| rgba_float_to_uchar((unsigned char *)&mloopcol[l_index].r, fcolor[v_index]); | rgba_float_to_uchar((unsigned char *)&mloopcol[l_index].r, fcolor[v_index]); | ||||
| } | } | ||||
| /* apply wetness */ | /* apply wetness */ | ||||
| if (mloopcol_wet) { | if (mloopcol_wet) { | ||||
| const char c = unit_float_to_uchar_clamp(pPoint[v_index].wetness); | const char c = unit_float_to_uchar_clamp(pPoint[v_index].wetness); | ||||
| mloopcol_wet[l_index].r = c; | mloopcol_wet[l_index].r = c; | ||||
| mloopcol_wet[l_index].g = c; | mloopcol_wet[l_index].g = c; | ||||
| mloopcol_wet[l_index].b = c; | mloopcol_wet[l_index].b = c; | ||||
| mloopcol_wet[l_index].a = 255; | mloopcol_wet[l_index].a = 255; | ||||
| } | } | ||||
| /* viewport preview */ | |||||
| if (mloopcol_preview) { | |||||
| if (surface->preview_id == MOD_DPAINT_SURFACE_PREV_PAINT) { | |||||
| float c[3]; | |||||
| /* Apply material color as base vertex color for preview */ | |||||
| mloopcol_preview[l_index].a = 255; | |||||
| if (material) { | |||||
| c[0] = material->r; | |||||
| c[1] = material->g; | |||||
| c[2] = material->b; | |||||
| } | |||||
| else { /* default gray */ | |||||
| c[0] = 0.65f; | |||||
| c[1] = 0.65f; | |||||
| c[2] = 0.65f; | |||||
| } | |||||
| /* mix surface color */ | |||||
| interp_v3_v3v3(c, c, fcolor[v_index], fcolor[v_index][3]); | |||||
| rgb_float_to_uchar((unsigned char *)&mloopcol_preview[l_index].r, c); | |||||
| } | |||||
| else { | |||||
| const char c = unit_float_to_uchar_clamp(pPoint[v_index].wetness); | |||||
| mloopcol_preview[l_index].r = c; | |||||
| mloopcol_preview[l_index].g = c; | |||||
| mloopcol_preview[l_index].b = c; | |||||
| mloopcol_preview[l_index].a = 255; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata, | static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata, | ||||
| const int i, | const int i, | ||||
| const ParallelRangeTLS *__restrict UNUSED(tls)) | const ParallelRangeTLS *__restrict UNUSED(tls)) | ||||
| { | { | ||||
| const DynamicPaintModifierApplyData *data = userdata; | const DynamicPaintModifierApplyData *data = userdata; | ||||
| ▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { | ||||
| MLoopCol *mloopcol_wet = CustomData_get_layer_named( | MLoopCol *mloopcol_wet = CustomData_get_layer_named( | ||||
| &result->ldata, CD_MLOOPCOL, surface->output_name2); | &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->ldata, 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 */ | |||||
| MLoopCol *mloopcol_preview = NULL; | |||||
| if (surface->flags & MOD_DPAINT_PREVIEW) { | |||||
| mloopcol_preview = CustomData_get_layer(&result->ldata, CD_PREVIEW_MLOOPCOL); | |||||
| if (!mloopcol_preview) { | |||||
| mloopcol_preview = CustomData_add_layer( | |||||
| &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; | |||||
| { | { | ||||
| 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, &data, dynamic_paint_apply_surface_vpaint_cb, &settings); | 0, totpoly, &data, dynamic_paint_apply_surface_vpaint_cb, &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 = CustomData_get_layer(&result->vdata, 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 */ | |||||
| if (surface->flags & MOD_DPAINT_PREVIEW) { | |||||
| /* Save preview results to weight layer to be | |||||
| * able to share same drawing methods. | |||||
| * Note this func also sets DM_DIRTY_TESS_CDLAYERS flag! */ | |||||
| //TODO port this function | |||||
| //DM_update_weight_mcol(ob, result, 0, weight, 0, NULL); | |||||
| } | |||||
| /* apply weights into a vertex group, if doesn't exists add a new layer */ | /* apply weights into a vertex group, if doesn't 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( | dvert = CustomData_add_layer( | ||||
| &result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, sData->total_points); | &result->vdata, CD_MDEFORMVERT, CD_CALLOC, 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++) { | ||||
| ▲ Show 20 Lines • Show All 4,368 Lines • Show Last 20 Lines | |||||