/* change stroke thickness */ static void deformStroke(GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), Object *ob, bGPDlayer *gpl, bGPDframe *UNUSED(gpf), bGPDstroke *gps) { WeightCurvGpencilModifierData *mmd = (WeightCurvGpencilModifierData *)md; const int def_nr = BKE_object_defgroup_name_index(ob, mmd->vgname); if (!is_stroke_affected_by_modifier(ob, mmd->layername, mmd->material, mmd->pass_index, mmd->layer_pass, 1, gpl, gps, mmd->flag & GP_WEIGHT_INVERT_LAYER, mmd->flag & GP_WEIGHT_INVERT_PASS, mmd->flag & GP_WEIGHT_INVERT_LAYERPASS, mmd->flag & GP_WEIGHT_INVERT_MATERIAL)) { return; } const int target_def_nr = BKE_object_defgroup_name_index(ob, mmd->target_vgname); if (target_def_nr == -1) { return; } /* Ensure there is a vertex group. */ BKE_gpencil_dvert_ensure(gps); float *angle_weighted = MEM_callocN(sizeof(float) * (gps->totpoints - 2) * 3, "gp angle weighted"); float *dists = MEM_callocN(sizeof(float) * gps->totpoints - 1, "gp dist weighted"); float dist_sum = 0; float vec1[3], vec2[3]; sub_v3_v3v3(vec1, &gps->points[1].x, &gps->points->x); for (int i = 1; i < gps->totpoints; i++) { bGPDspoint *pt = &gps->points[i - 1]; dists[i - 1] = len_v3v3(&pt->x, &pt[1].x); dist_sum += dists[i - 1]; if (i < gps->totpoints - 1) { float *no = &angle_weighted[(i - 1) * 3]; float angle = angle_normalized_v3v3(vec1, vec2); sub_v3_v3v3(vec2, &pt[2].x, &pt[1].x); cross_v3_v3v3(no, vec1, vec2); normalize_v3_length(no, angle); copy_v3_v3(vec1, vec2); } } float dist_lim = mmd->overshoot_distance / 2; /* Half the distance for each side. */ if (mmd->flag & GP_WEIGHT_CURVATURE_RELATIVE_LENGTH) { dist_lim *= dist_sum; } float weight_pt = 1.0f; for (int i = 1; i < gps->totpoints - 1; i++) { MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; /* Verify point is part of vertex group. */ float weight = get_modifier_point_weight( dvert, (mmd->flag & GP_WEIGHT_INVERT_VGROUP) != 0, def_nr); if (weight < 0.0f) { continue; } // what now bGPDspoint *pt = &gps->points[i]; float use_dist = 0; float sum_angle[3] = {0}; for (int j = i + 1; j < gps->totpoints; j++) { if ((use_dist + dists[j]) < dist_lim) { add_v3_v3(sum_angle, ) } } // float angle = angle_v3v3v3(&pt[0].x, &pt[1].x, &pt[2].x); float abc = len_v3v3(&pt[0].x, &pt[1].x) * len_v3v3(&pt[1].x, &pt[2].x) * len_v3v3(&pt[0].x, &pt[2].x); float v1[3], v2[3], crs[3]; sub_v3_v3v3(v1, &pt[0].x, &pt[1].x); sub_v3_v3v3(v2, &pt[1].x, &pt[2].x); cross_v3_v3v3(crs, v1, v2); float k4 = len_v3(crs) * 2; /* = Area * 4 */ float radius = k4 == 0 ? 0 : (abc / k4); weight_pt = radius == 0 ? 0 : (mmd->min_radius / radius); CLAMP(weight_pt, 0, 1); /* Invert weight if required. */ if (mmd->flag & GP_WEIGHT_INVERT_OUTPUT) { weight_pt = 1.0f - weight_pt; } weight_pt = 0; /* Assign weight. */ dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; if (dvert != NULL) { MDeformWeight *dw = BKE_defvert_ensure_index(dvert, target_def_nr); if (dw) { dw->weight = (mmd->flag & GP_WEIGHT_MULTIPLY_DATA) ? dw->weight * weight_pt : weight_pt; CLAMP(dw->weight, mmd->min_weight, 1.0f); } } } } /* change stroke thickness */ static void deformStroke(GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), Object *ob, bGPDlayer *gpl, bGPDframe *UNUSED(gpf), bGPDstroke *gps) { WeightCurvGpencilModifierData *mmd = (WeightCurvGpencilModifierData *)md; const int def_nr = BKE_object_defgroup_name_index(ob, mmd->vgname); if (!is_stroke_affected_by_modifier(ob, mmd->layername, mmd->material, mmd->pass_index, mmd->layer_pass, 1, gpl, gps, mmd->flag & GP_WEIGHT_INVERT_LAYER, mmd->flag & GP_WEIGHT_INVERT_PASS, mmd->flag & GP_WEIGHT_INVERT_LAYERPASS, mmd->flag & GP_WEIGHT_INVERT_MATERIAL)) { return; } const int target_def_nr = BKE_object_defgroup_name_index(ob, mmd->target_vgname); if (target_def_nr == -1) { return; } /* Ensure there is a vertex group. */ BKE_gpencil_dvert_ensure(gps); float *angle_weighted = MEM_callocN(sizeof(float) * (gps->totpoints - 2) * 3, "gp angle weighted"); float *dists = MEM_callocN(sizeof(float) * gps->totpoints - 1, "gp dist weighted"); float dist_sum = 0; float vec1[3], vec2[3]; sub_v3_v3v3(vec1, &gps->points[1].x, &gps->points->x); for (int i = 1; i < gps->totpoints; i++) { bGPDspoint *pt = &gps->points[i - 1]; dists[i - 1] = len_v3v3(&pt->x, &pt[1].x); dist_sum += dists[i - 1]; if (i < gps->totpoints - 1) { float *no = &angle_weighted[(i - 1) * 3]; float angle = angle_normalized_v3v3(vec1, vec2); sub_v3_v3v3(vec2, &pt[2].x, &pt[1].x); cross_v3_v3v3(no, vec1, vec2); normalize_v3_length(no, angle); copy_v3_v3(vec1, vec2); } } float dist_lim = mmd->overshoot_distance / 2; /* Half the distance for each side. */ if (mmd->flag & GP_WEIGHT_CURVATURE_RELATIVE_LENGTH) { dist_lim *= dist_sum; } float weight_pt = 1.0f; for (int i = 1; i < gps->totpoints - 1; i++) { MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; /* Verify point is part of vertex group. */ float weight = get_modifier_point_weight( dvert, (mmd->flag & GP_WEIGHT_INVERT_VGROUP) != 0, def_nr); if (weight < 0.0f) { continue; } // what now? /* Assign weight. */ dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; if (dvert != NULL) { MDeformWeight *dw = BKE_defvert_ensure_index(dvert, target_def_nr); if (dw) { dw->weight = (mmd->flag & GP_WEIGHT_MULTIPLY_DATA) ? dw->weight * weight_pt : weight_pt; CLAMP(dw->weight, mmd->min_weight, 1.0f); } } } }