diff options
Diffstat (limited to 'source/blender/blenkernel/intern/dynamicpaint.c')
-rw-r--r-- | source/blender/blenkernel/intern/dynamicpaint.c | 158 |
1 files changed, 117 insertions, 41 deletions
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index ed85e5b627b..4e05595b93a 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -107,9 +107,9 @@ static int neighX[8] = {1, 1, 0, -1, -1, -1, 0, 1}; static int neighY[8] = {0, 1, 1, 1, 0, -1, -1, -1}; /* subframe_updateObject() flags */ -#define UPDATE_PARENTS (1 << 0) +#define SUBFRAME_RECURSION 5 #define UPDATE_MESH (1 << 1) -#define UPDATE_EVERYTHING (UPDATE_PARENTS | UPDATE_MESH) +#define UPDATE_EVERYTHING (UPDATE_MESH) // | UPDATE_PARENTS /* surface_getBrushFlags() return vals */ #define BRUSH_USES_VELOCITY (1 << 0) /* brush mesh raycast status */ @@ -340,7 +340,7 @@ int dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object * return 0; } -static int surface_duplicateOutputExists(void *arg, const char *name) +static bool surface_duplicateOutputExists(void *arg, const char *name) { DynamicPaintSurface *t_surface = (DynamicPaintSurface *)arg; DynamicPaintSurface *surface = t_surface->canvas->surfaces.first; @@ -349,11 +349,11 @@ static int surface_duplicateOutputExists(void *arg, const char *name) if (surface != t_surface && surface->type == t_surface->type && surface->format == t_surface->format) { - if (surface->output_name[0] != '\0' && !BLI_path_cmp(name, surface->output_name)) return 1; - if (surface->output_name2[0] != '\0' && !BLI_path_cmp(name, surface->output_name2)) return 1; + if (surface->output_name[0] != '\0' && !BLI_path_cmp(name, surface->output_name)) return true; + if (surface->output_name2[0] != '\0' && !BLI_path_cmp(name, surface->output_name2)) return true; } } - return 0; + return false; } static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *basename, int output) @@ -367,15 +367,15 @@ static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *base } -static int surface_duplicateNameExists(void *arg, const char *name) +static bool surface_duplicateNameExists(void *arg, const char *name) { DynamicPaintSurface *t_surface = (DynamicPaintSurface *)arg; DynamicPaintSurface *surface = t_surface->canvas->surfaces.first; for (; surface; surface = surface->next) { - if (surface != t_surface && !strcmp(name, surface->name)) return 1; + if (surface != t_surface && !strcmp(name, surface->name)) return true; } - return 0; + return false; } void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, const char *basename) @@ -397,7 +397,7 @@ void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) } else { strcpy(surface->output_name, "dp_"); - strcpy(surface->output_name2, surface->output_name); + BLI_strncpy(surface->output_name2, surface->output_name, sizeof(surface->output_name2)); surface->flags &= ~MOD_DPAINT_ANTIALIAS; surface->depth_clamp = 0.0f; } @@ -473,7 +473,9 @@ static float mixColors(float a_color[3], float a_weight, float b_color[3], float } weight_ratio = b_weight / (a_weight + b_weight); } - else return a_weight * (1.0f - ratio); + else { + return a_weight * (1.0f - ratio); + } /* calculate final interpolation factor */ if (ratio <= 0.5f) { @@ -507,7 +509,7 @@ static void object_cacheIgnoreClear(Object *ob, int state) BLI_freelistN(&pidlist); } -static int subframe_updateObject(Scene *scene, Object *ob, int flags, float frame) +static int subframe_updateObject(Scene *scene, Object *ob, int flags, int parent_recursion, float frame) { DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); bConstraint *con; @@ -517,10 +519,11 @@ static int subframe_updateObject(Scene *scene, Object *ob, int flags, float fram return 1; /* if object has parents, update them too */ - if (flags & UPDATE_PARENTS) { + if (parent_recursion) { + int recursion = parent_recursion-1; int is_canvas = 0; - if (ob->parent) is_canvas += subframe_updateObject(scene, ob->parent, 0, frame); - if (ob->track) is_canvas += subframe_updateObject(scene, ob->track, 0, frame); + if (ob->parent) is_canvas += subframe_updateObject(scene, ob->parent, 0, recursion, frame); + if (ob->track) is_canvas += subframe_updateObject(scene, ob->track, 0, recursion, frame); /* skip subframe if object is parented * to vertex of a dynamic paint canvas */ @@ -529,7 +532,7 @@ static int subframe_updateObject(Scene *scene, Object *ob, int flags, float fram /* also update constraint targets */ for (con = ob->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = constraint_get_typeinfo(con); + bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; if (cti && cti->get_constraint_targets) { @@ -537,7 +540,7 @@ static int subframe_updateObject(Scene *scene, Object *ob, int flags, float fram cti->get_constraint_targets(con, &targets); for (ct = targets.first; ct; ct = ct->next) { if (ct->tar) - subframe_updateObject(scene, ct->tar, 0, frame); + subframe_updateObject(scene, ct->tar, 0, recursion, frame); } /* free temp targets */ if (cti->flush_constraint_targets) @@ -687,7 +690,7 @@ static void boundInsert(Bounds3D *b, float point[3]) static float getSurfaceDimension(PaintSurfaceData *sData) { Bounds3D *mb = &sData->bData->mesh_bounds; - return MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2])); + return max_fff((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2])); } static void freeGrid(PaintSurfaceData *data) @@ -754,14 +757,14 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface) /* get dimensions */ sub_v3_v3v3(dim, grid->grid_bounds.max, grid->grid_bounds.min); copy_v3_v3(td, dim); - min_dim = MAX3(td[0], td[1], td[2]) / 1000.f; + min_dim = max_fff(td[0], td[1], td[2]) / 1000.f; /* deactivate zero axises */ for (i = 0; i < 3; i++) { if (td[i] < min_dim) { td[i] = 1.0f; axis -= 1; } } - if (axis == 0 || MAX3(td[0], td[1], td[2]) < 0.0001f) { + if (axis == 0 || max_fff(td[0], td[1], td[2]) < 0.0001f) { MEM_freeN(grid_bounds); MEM_freeN(bData->grid); bData->grid = NULL; @@ -1150,7 +1153,7 @@ int dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, stru { CBData *ramp; - brush->paint_ramp = add_colorband(0); + brush->paint_ramp = add_colorband(false); if (!brush->paint_ramp) return 0; ramp = brush->paint_ramp->data; @@ -1166,7 +1169,7 @@ int dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, stru { CBData *ramp; - brush->vel_ramp = add_colorband(0); + brush->vel_ramp = add_colorband(false); if (!brush->vel_ramp) return 0; ramp = brush->vel_ramp->data; @@ -1193,7 +1196,68 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn /* Copy data */ if (tpmd->canvas) { + DynamicPaintSurface *surface; tpmd->canvas->pmd = tpmd; + /* free default surface */ + if (tpmd->canvas->surfaces.first) + dynamicPaint_freeSurface(tpmd->canvas->surfaces.first); + + /* copy existing surfaces */ + for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { + DynamicPaintSurface *t_surface = dynamicPaint_createNewSurface(tpmd->canvas, NULL); + + /* surface settings */ + t_surface->brush_group = surface->brush_group; + MEM_freeN(t_surface->effector_weights); + t_surface->effector_weights = MEM_dupallocN(surface->effector_weights); + + BLI_strncpy(t_surface->name, surface->name, sizeof(t_surface->name)); + t_surface->format = surface->format; + t_surface->type = surface->type; + t_surface->disp_type = surface->disp_type; + t_surface->image_fileformat = surface->image_fileformat; + 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->flags = surface->flags; + t_surface->effect = surface->effect; + + t_surface->image_resolution = surface->image_resolution; + t_surface->substeps = surface->substeps; + t_surface->start_frame = surface->start_frame; + t_surface->end_frame = surface->end_frame; + + copy_v4_v4(t_surface->init_color, surface->init_color); + t_surface->init_texture = surface->init_texture; + BLI_strncpy(t_surface->init_layername, surface->init_layername, sizeof(t_surface->init_layername)); + + t_surface->dry_speed = surface->dry_speed; + t_surface->diss_speed = surface->diss_speed; + t_surface->color_dry_threshold = surface->color_dry_threshold; + t_surface->depth_clamp = surface->depth_clamp; + t_surface->disp_factor = surface->disp_factor; + + + t_surface->spread_speed = surface->spread_speed; + t_surface->color_spread_speed = surface->color_spread_speed; + t_surface->shrink_speed = surface->shrink_speed; + t_surface->drip_vel = surface->drip_vel; + t_surface->drip_acc = surface->drip_acc; + + t_surface->influence_scale = surface->influence_scale; + t_surface->radius_scale = surface->radius_scale; + + t_surface->wave_damping = surface->wave_damping; + t_surface->wave_speed = surface->wave_speed; + t_surface->wave_timescale = surface->wave_timescale; + t_surface->wave_spring = surface->wave_spring; + + BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name)); + BLI_strncpy(t_surface->image_output_path, 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_name2, surface->output_name2, sizeof(t_surface->output_name2)); + } + dynamicPaint_resetPreview(tpmd->canvas); } else if (tpmd->brush) { DynamicPaintBrushSettings *brush = pmd->brush, *t_brush = tpmd->brush; @@ -1422,7 +1486,9 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) /* for vertex surface loop through tfaces and find uv color * that provides highest alpha */ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { - #pragma omp parallel for schedule(static) + struct ImagePool *pool = BKE_image_pool_new(); + + #pragma omp parallel for schedule(static) shared(pool) for (i = 0; i < numOfFaces; i++) { int numOfVert = (mface[i].v4) ? 4 : 3; float uv[3] = {0.0f}; @@ -1435,7 +1501,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) uv[0] = tface[i].uv[j][0] * 2.0f - 1.0f; uv[1] = tface[i].uv[j][1] * 2.0f - 1.0f; - multitex_ext_safe(tex, uv, &texres); + multitex_ext_safe(tex, uv, &texres, pool); if (texres.tin > pPoint[*vert].alpha) { copy_v3_v3(pPoint[*vert].color, &texres.tr); @@ -1443,6 +1509,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) } } } + BKE_image_pool_free(pool); } else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data; @@ -1468,7 +1535,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) uv_final[0] = uv_final[0] * 2.0f - 1.0f; uv_final[1] = uv_final[1] * 2.0f - 1.0f; - multitex_ext_safe(tex, uv_final, &texres); + multitex_ext_safe(tex, uv_final, &texres, NULL); /* apply color */ copy_v3_v3(pPoint[i].color, &texres.tr); @@ -2315,7 +2382,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) dot11 = d2[0] * d2[0] + d2[1] * d2[1]; dot12 = d2[0] * d3[0] + d2[1] * d3[1]; - invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + invDenom = (dot00 * dot11 - dot01 * dot01); + invDenom = invDenom ? 1.0f / invDenom : 1.0f; u = (dot11 * dot02 - dot01 * dot12) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom; @@ -2335,7 +2403,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) dot11 = d2[0] * d2[0] + d2[1] * d2[1]; dot12 = d2[0] * d3[0] + d2[1] * d3[1]; - invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + invDenom = (dot00 * dot11 - dot01 * dot01); + invDenom = invDenom ? 1.0f / invDenom : 1.0f; u = (dot11 * dot02 - dot01 * dot12) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom; @@ -2540,7 +2609,9 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) if (!f_data->uv_p || !f_data->barycentricWeights) error = 1; } - else error = 1; + else { + error = 1; + } sData->total_points = active_points; @@ -2628,7 +2699,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam if (format == R_IMF_IMTYPE_OPENEXR) format = R_IMF_IMTYPE_PNG; #endif BLI_strncpy(output_file, filename, sizeof(output_file)); - BKE_add_image_extension(output_file, format); + BKE_add_image_extension_from_type(output_file, format); /* Validate output file path */ BLI_path_abs(output_file, G.main->name); @@ -2778,7 +2849,9 @@ static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats) /* * Get material diffuse color and alpha (including linked textures) in given coordinates */ -static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, const float volume_co[3], const float surface_co[3], int faceIndex, short isQuad, DerivedMesh *orcoDm) +static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, + const float volume_co[3], const float surface_co[3], + int faceIndex, short isQuad, DerivedMesh *orcoDm) { Material *mat = bMats->mat; MFace *mface = orcoDm->getTessFaceArray(orcoDm); @@ -2791,7 +2864,9 @@ static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], fl mat = bMats->ob_mats[mat_nr]; if (mat == NULL) return; /* No material assigned */ } - else return; + else { + return; + } } RE_sample_material_color(mat, color, alpha, volume_co, surface_co, faceIndex, isQuad, orcoDm, brushOb); @@ -3109,7 +3184,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Scene *scene, Object *ob, Dy scene->r.cfra = prev_fra; scene->r.subframe = prev_sfra; - subframe_updateObject(scene, ob, UPDATE_EVERYTHING, BKE_scene_frame_get(scene)); + subframe_updateObject(scene, ob, UPDATE_EVERYTHING, SUBFRAME_RECURSION, BKE_scene_frame_get(scene)); dm_p = CDDM_copy(brush->dm); numOfVerts_p = dm_p->getNumVerts(dm_p); mvert_p = dm_p->getVertArray(dm_p); @@ -3119,7 +3194,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Scene *scene, Object *ob, Dy scene->r.cfra = cur_fra; scene->r.subframe = cur_sfra; - subframe_updateObject(scene, ob, UPDATE_EVERYTHING, BKE_scene_frame_get(scene)); + subframe_updateObject(scene, ob, UPDATE_EVERYTHING, SUBFRAME_RECURSION, BKE_scene_frame_get(scene)); dm_c = brush->dm; numOfVerts_c = dm_c->getNumVerts(dm_c); mvert_c = dm_p->getVertArray(dm_c); @@ -3169,13 +3244,13 @@ static void dynamicPaint_brushObjectCalculateVelocity(Scene *scene, Object *ob, /* previous frame dm */ scene->r.cfra = prev_fra; scene->r.subframe = prev_sfra; - subframe_updateObject(scene, ob, UPDATE_PARENTS, BKE_scene_frame_get(scene)); + subframe_updateObject(scene, ob, 0, SUBFRAME_RECURSION, BKE_scene_frame_get(scene)); copy_m4_m4(prev_obmat, ob->obmat); /* current frame dm */ scene->r.cfra = cur_fra; scene->r.subframe = cur_sfra; - subframe_updateObject(scene, ob, UPDATE_PARENTS, BKE_scene_frame_get(scene)); + subframe_updateObject(scene, ob, 0, SUBFRAME_RECURSION, BKE_scene_frame_get(scene)); /* calculate speed */ mul_m4_v3(prev_obmat, prev_loc); @@ -3856,7 +3931,9 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po strength = 1.0f - distance / brush_radius; CLAMP(strength, 0.0f, 1.0f); } - else strength = 1.0f; + else { + strength = 1.0f; + } if (strength >= 0.001f) { float paintColor[3] = {0.0f}; @@ -4199,7 +4276,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s if (surface->effect & MOD_DPAINT_EFFECT_DO_SHRINK) shrink_speed = surface->shrink_speed; - fastest_effect = MAX3(spread_speed, shrink_speed, average_force); + fastest_effect = max_fff(spread_speed, shrink_speed, average_force); avg_dist = bData->average_dist * CANVAS_REL_SIZE / getSurfaceDimension(sData); steps = (int)ceil(1.5f * EFF_MOVEMENT_PER_FRAME * fastest_effect / avg_dist * timescale); @@ -4383,8 +4460,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal float dt, min_dist, damp_factor; float wave_speed = surface->wave_speed; double average_dist = 0.0f; - Bounds3D *mb = &sData->bData->mesh_bounds; - float canvas_size = MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2])); + const float canvas_size = getSurfaceDimension(sData); float wave_scale = CANVAS_REL_SIZE / canvas_size; /* allocate memory */ @@ -4898,7 +4974,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su /* update object data on this subframe */ if (subframe) { scene_setSubframe(scene, subframe); - subframe_updateObject(scene, brushObj, UPDATE_EVERYTHING, BKE_scene_frame_get(scene)); + subframe_updateObject(scene, brushObj, UPDATE_EVERYTHING, SUBFRAME_RECURSION, BKE_scene_frame_get(scene)); } /* Prepare materials if required */ if (brush_usesMaterial(brush, scene)) @@ -4932,7 +5008,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su if (subframe) { scene->r.cfra = scene_frame; scene->r.subframe = scene_subframe; - subframe_updateObject(scene, brushObj, UPDATE_EVERYTHING, BKE_scene_frame_get(scene)); + subframe_updateObject(scene, brushObj, UPDATE_EVERYTHING, SUBFRAME_RECURSION, BKE_scene_frame_get(scene)); } /* process special brush effects, like smudge */ |