59 const bool use_select,
133 const bool smooth_caps,
134 const bool keep_shape,
138 if (gps->
totpoints <= 2 || iterations <= 0) {
185 float sco[3] = {0.0f, 0.0f, 0.0f};
187 const int n_half = keep_shape ? (iterations * iterations) / 8 + iterations :
188 (iterations * iterations) / 4 + 2 * iterations + 12;
189 double w = keep_shape ? 2.0 : 1.0;
190 double w2 = keep_shape ?
193 double total_w = 0.0;
194 for (
int step = iterations; step > 0; step--) {
195 int before = point_index - step;
196 int after = point_index + step;
197 float w_before =
float(
w - w2);
198 float w_after =
float(
w - w2);
207 w_before *= -before /
float(point_index);
228 w *= (n_half + step) /
double(n_half + 1 - step);
229 w2 *= (n_half * 3 + step) /
double(n_half * 3 + 1 - step);
255 if (gps->
totpoints <= 2 || iterations <= 0) {
263 float strength = 0.0f;
264 const int n_half = (iterations * iterations) / 4 + iterations;
266 double total_w = 0.0;
267 for (
int step = iterations; step > 0; step--) {
268 int before = point_index - step;
269 int after = point_index + step;
270 float w_before =
float(
w);
289 w *= (n_half + step) /
double(n_half + 1 - step);
313 if (gps->
totpoints <= 2 || iterations <= 0) {
321 float pressure = 0.0f;
322 const int n_half = (iterations * iterations) / 4 + iterations;
324 double total_w = 0.0;
325 for (
int step = iterations; step > 0; step--) {
326 int before = point_index - step;
327 int after = point_index + step;
328 float w_before =
float(
w);
347 w *= (n_half + step) /
double(n_half + 1 - step);
371 if (gps->
totpoints <= 2 || iterations <= 0) {
389 const int n_half = iterations * iterations + iterations;
391 double total_w = 0.0;
392 for (
int step = iterations; step > 0; step--) {
393 int before = point_index - step;
394 int after = point_index + step;
395 float w_before =
float(
w);
404 w_before *= -before /
float(point_index);
422 w *= (n_half + step) /
double(n_half + 1 - step);
439 const float influence,
440 const int iterations,
441 const bool smooth_position,
442 const bool smooth_strength,
443 const bool smooth_thickness,
444 const bool smooth_uv,
445 const bool keep_shape,
446 const float *weights)
448 if (influence <= 0 || iterations <= 0) {
453 bGPDstroke gps_old = blender::dna::shallow_copy(*gps);
457 for (
int i = 0; i < gps->
totpoints; i++) {
458 float val = influence;
459 if (weights !=
nullptr) {
470 if (smooth_position) {
473 if (smooth_strength) {
476 if (smooth_thickness) {
490 float (*points2d)[2],
509 if (totpoints == 2) {
529 const bGPDspoint *pt_last = &points[totpoints - 1];
533 points2d[totpoints - 1][0] =
dot_v3v3(tmp, locx);
534 points2d[totpoints - 1][1] =
dot_v3v3(tmp, locy);
539 float *co_prev = (
float *)&points2d[totpoints - 1];
542 for (
int i = 0; i < totpoints - 1; i++) {
549 points2d[i][0] =
dot_v3v3(loc, locx);
550 points2d[i][1] =
dot_v3v3(loc, locy);
553 co_curr = (
float *)&points2d[i][0];
554 cross += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]);
555 co_prev = (
float *)&points2d[i][0];
559 *r_direction = (
cross >= 0.0f) ? 1 : -1;
566 float (*points2d)[2],
574 const bGPDspoint *pt3 = &ref_points[
int(ref_totpoints * 0.75)];
586 if (totpoints == 2) {
606 for (
int i = 0; i < totpoints; i++) {
610 float vn[3] = {0.0f, 0.0f, 0.0f};
624 else if (i == totpoints - 1) {
638 points2d[i][0] =
dot_v3v3(loc, locx);
639 points2d[i][1] =
dot_v3v3(loc, locy);
643 *r_direction =
int(locy[2]);
657 float center[2] = {0.5f, 0.5f};
659 d[0] = maxv[0] - minv[0];
660 d[1] = maxv[1] - minv[1];
661 for (
int i = 0; i < gps->
totpoints; i++) {
662 r_uv[i][0] = (points2d[i][0] - minv[0]) / d[0];
663 r_uv[i][1] = (points2d[i][1] - minv[1]) / d[1];
669 r_uv[i][0] -= center[0];
670 r_uv[i][1] -= center[1];
672 float x = r_uv[i][0] * c - r_uv[i][1] * s;
673 float y = r_uv[i][0] * s + r_uv[i][1] * c;
675 r_uv[i][0] = x + center[0];
676 r_uv[i][1] = y + center[1];
698 "GP Stroke temp triangulation");
700 "GP Stroke temp 2d points");
702 "GP Stroke temp 2d uv data");
724 "GP Stroke triangulation");
731 for (
int i = 0; i < gps->
totpoints; i++) {
752 if (gps ==
nullptr || gps->
totpoints == 0) {
759 for (
int i = 1; i < gps->
totpoints; i++) {
760 totlen +=
len_v3v3(&pt[i - 1].x, &pt[i].x);
767 if (gps ==
nullptr) {
791 float *last_pt = &gps->
points[0].
x;
792 float total_length = 0.0f;
793 for (
int i = 1; i < gps->
totpoints; i++) {
796 total_length +=
len_v3v3(&pt->
x, last_pt);
799 total_length +=
len_v2v2(&pt->
x, last_pt);
807 const int start_index,
815 int index = std::max(start_index, 0) + 1;
816 int last_index = std::min(end_index, gps->
totpoints - 1) + 1;
818 float *last_pt = &gps->
points[index - 1].
x;
819 float total_length = 0.0f;
820 for (
int i = index; i < last_index; i++) {
823 total_length +=
len_v3v3(&pt->
x, last_pt);
826 total_length +=
len_v2v2(&pt->
x, last_pt);
843 for (
int i = 0; i < gps->
totpoints - 2; i++) {
847 for (
int j = start + 2; j < gps->
totpoints - 1; j++) {
854 if (
len_v3(point) > 0.0f) {
858 if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
862 if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
884 if (gps->
dvert !=
nullptr) {
889 int newtot = end - start + 1;
892 if (gps->
dvert !=
nullptr) {
896 for (
int i = 0; i < newtot; i++) {
900 *pt_new = blender::dna::shallow_copy(*pt_src);
901 if (gps->
dvert !=
nullptr) {
902 dvert_src = &old_dvert[idx];
909 if (
ELEM(idx, start, end)) {
936 float dist_tot = 0.0f;
937 for (
int i = 0; i < gps->
totpoints - 1; i++) {
939 pt2 = &gps->
points[i + 1];
943 float dist_avg = dist_tot / (gps->
totpoints - 1);
948 float dist_close =
len_v3v3(&pt1->
x, &pt2->
x);
951 if (dist_close <= dist_avg) {
957 int tot_newpoints = std::max<int>(dist_close / dist_avg, 1);
963 if (gps->
dvert !=
nullptr) {
968 pt1 = &gps->
points[old_tot - 1];
971 for (
int i = 1; i < tot_newpoints + 1; i++, pt++) {
972 float step = (tot_newpoints > 1) ? (
float(i) /
float(tot_newpoints)) : 0.99f;
974 if ((tot_newpoints > 1) && (i == tot_newpoints)) {
990 if (gps->
dvert !=
nullptr) {
993 float weight_1 = dw1 ? dw1->
weight : 0.0f;
997 float weight_2 = dw2 ? dw2->
weight : 0.0f;
1002 if (dvert_final->
dw) {
1054 if (gpd ==
nullptr) {
1087 int total_points = 0;
1089 if (gpd ==
nullptr) {
1108 return total_points;
1113 if (gpd ==
nullptr) {
1143 if (gpd ==
nullptr) {
1176 const float mat[4][4])
1178 if (gpd ==
nullptr) {
1214 float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1219 for (
int i = 0; i < gps->
totpoints; i++) {
1259 join_stroke->
flag &= ~GP_STROKE_CYCLIC;
1266 for (
int i = 0; i < totpoints; i++) {
1267 pt_final = &join_stroke->
points[i];
1268 if (i < gps_last->totpoints) {
1269 pt = &gps_last->
points[e1];
1273 pt = &gps_first->
points[e2];
1281 pt_final->
time = delta;
1290 if ((gps_first->
dvert !=
nullptr) || (gps_last->
dvert !=
nullptr)) {
1298 for (
int i = 0; i < totpoints; i++) {
1299 dvert_dst = &join_stroke->
dvert[i];
1300 dvert_src =
nullptr;
1301 if (i < gps_last->totpoints) {
1302 if (gps_last->
dvert) {
1303 dvert_src = &gps_last->
dvert[e1];
1308 if (gps_first->
dvert) {
1309 dvert_src = &gps_first->
dvert[e2];
1314 if ((dvert_src) && (dvert_src->
dw)) {
1340 const bool flat_cap,
1355 bool in_island =
false;
1356 int num_islands = 0;
1364 for (
int i = 0; i < gps->
totpoints; i++, pt++) {
1365 if (pt->
flag & tag_flags) {
1375 idx = num_islands - 1;
1376 islands[idx].end_idx = i;
1383 idx = num_islands - 1;
1384 islands[idx].start_idx = islands[idx].end_idx = i;
1396 for (idx = 0; idx < num_islands; idx++) {
1404 if ((
is_cyclic) && (gps_first ==
nullptr)) {
1405 gps_first = new_stroke;
1408 new_stroke->
flag &= ~GP_STROKE_CYCLIC;
1415 "gp delete stroke fragment");
1416 memcpy(
static_cast<void *
>(new_stroke->
points),
1421 if (gps->
dvert !=
nullptr) {
1424 "gp delete stroke fragment weight");
1425 memcpy(new_stroke->
dvert,
1431 for (
int i = 0; i < new_stroke->
totpoints; i++) {
1434 if (dvert_src->
dw) {
1455 pts = new_stroke->
points;
1456 for (j = 0; j < new_stroke->
totpoints; j++, pts++) {
1461 pts->
flag &= ~GP_SPOINT_SELECT;
1468 if ((limit > 0) && (new_stroke->
totpoints <= limit)) {
1469 if (gps_first == new_stroke) {
1470 gps_first =
nullptr;
1487 if ((
is_cyclic) && (gps_first !=
nullptr) && (gps_first != new_stroke)) {
1506 const float delta[3],
1514 if (gps->
dvert !=
nullptr) {
1520 if (dvert !=
nullptr) {
1529 newpoint->
x = point->x * delta[0];
1530 newpoint->
y = point->y * delta[1];
1531 newpoint->
z = point->z * delta[2];
1532 newpoint->
flag = point->flag;
1535 newpoint->
time = point->time + deltatime;
1538 if (gps->
dvert !=
nullptr) {
1541 if (dvert !=
nullptr) {
1547 newdvert->
dw =
nullptr;
1554 const bool leave_gaps,
1555 const bool fit_thickness,
1562 const float delta[3] = {1.0f, 1.0f, 1.0f};
1563 float deltatime = 0.0f;
1566 if (
ELEM(
nullptr, gps_a, gps_b)) {
1576 float start_a[3], start_b[3], end_a[3], end_b[3];
1591 bool flip_a =
false;
1592 bool flip_b =
false;
1593 float lowest = dist;
1596 if (dist < lowest) {
1603 if (dist < lowest) {
1610 if (dist < lowest) {
1627 point = blender::dna::shallow_copy(gps_a->
points[gps_a->
totpoints - 1]);
1628 deltatime = point.time;
1633 point = blender::dna::shallow_copy(gps_b->
points[0]);
1639 const float ratio = (fit_thickness && gps_a->
thickness > 0.0f) ?
1644 const int totpoints_a = gps_a->
totpoints;
1645 for (i = 0, pt = gps_b->
points; i < gps_b->
totpoints && pt; i++, pt++) {
1652 const int sample_points = 8;
1654 int start = std::max(0, totpoints_a - sample_points);
1655 int end = std::min(gps_a->
totpoints - 1, start + (sample_points * 2));
1656 const int len = (end - start);
1657 float step = 1.0f / ((
len / 2) + 1);
1660 float avg_pressure = 0.0f;
1661 for (i = start; i < end; i++) {
1665 avg_pressure = avg_pressure /
len;
1669 for (i = start; i < end; i++) {
1677 ratio = ratio - step - step;
1686 float viewmat[4][4],
1687 const float diff_mat[4][4])
1689 for (
int i = 0; i < gps->
totpoints; i++) {
1699 float viewinv[4][4],
1700 const float diff_mat[4][4])
1702 float inverse_diff_mat[4][4];
1705 for (
int i = 0; i < gps->
totpoints; i++) {
1722 for (
int i = 0; i < gps->
totpoints; i++) {
1737 for (
int i = 0; i < gps->
totpoints; i++) {
1739 if (pt->
pressure != first_pressure) {
struct bGPDstroke * BKE_gpencil_stroke_duplicate(struct bGPDstroke *gps_src, bool dup_points, bool dup_curve)
void BKE_gpencil_free_stroke(struct bGPDstroke *gps)
General operations, lookup, etc. for materials.
General operations, lookup, etc. for blender objects.
Generic array manipulation API.
#define BLI_array_reverse(arr, arr_len)
BLI_INLINE float BLI_hash_int_01(unsigned int k)
BLI_INLINE unsigned int BLI_hash_int_2d(unsigned int kx, unsigned int ky)
A min-heap / priority queue ADT.
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE float interpf(float target, float origin, float t)
int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float r_i1[3], float r_i2[3])
float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
float mat4_to_scale(const float mat[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], float t)
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void BLI_polyfill_calc(const float(*coords)[2], unsigned int coords_num, int coords_sign, unsigned int(*r_tris)[3])
#define INIT_MINMAX(min, max)
#define ARRAY_SET_ITEMS(...)
typedef double(DMatrix)[4][4]
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define MEM_reallocN(vmemh, len)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
local_group_size(16, 16) .push_constant(Type b
static bool is_cyclic(const Nurb *nu)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void BKE_gpencil_stroke_flip(bGPDstroke *gps)
float BKE_gpencil_stroke_average_pressure_get(bGPDstroke *gps)
static void gpencil_stroke_join_islands(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps_first, bGPDstroke *gps_last)
void BKE_gpencil_stroke_to_view_space(bGPDstroke *gps, float viewmat[4][4], const float diff_mat[4][4])
void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points, int ref_totpoints, const bGPDspoint *points, int totpoints, float(*points2d)[2], const float scale, int *r_direction)
bool BKE_gpencil_stroke_smooth_uv(bGPDstroke *gps, int point_index, float influence, int iterations, bGPDstroke *r_gps)
static void gpencil_calc_stroke_fill_uv(const float(*points2d)[2], bGPDstroke *gps, const float minv[2], const float maxv[2], float(*r_uv)[2])
bGPDstroke * BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags, const bool select, const bool flat_cap, const int limit)
float BKE_gpencil_stroke_length(const bGPDstroke *gps, bool use_3d)
void BKE_gpencil_stroke_join(bGPDstroke *gps_a, bGPDstroke *gps_b, const bool leave_gaps, const bool fit_thickness, const bool smooth, bool auto_flip)
bool BKE_gpencil_stroke_is_pressure_constant(bGPDstroke *gps)
void BKE_gpencil_stroke_normal(const bGPDstroke *gps, float r_normal[3])
void BKE_gpencil_stroke_from_view_space(bGPDstroke *gps, float viewinv[4][4], const float diff_mat[4][4])
bool BKE_gpencil_stroke_trim(bGPdata *gpd, bGPDstroke *gps)
void BKE_gpencil_point_coords_get(bGPdata *gpd, GPencilPointCoordinates *elem_data)
bool BKE_gpencil_stroke_minmax(const bGPDstroke *gps, const bool use_select, float r_min[3], float r_max[3])
void BKE_gpencil_stroke_smooth(bGPDstroke *gps, const float influence, const int iterations, const bool smooth_position, const bool smooth_strength, const bool smooth_thickness, const bool smooth_uv, const bool keep_shape, const float *weights)
void BKE_gpencil_point_coords_apply_with_mat4(bGPdata *gpd, const GPencilPointCoordinates *elem_data, const float mat[4][4])
bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float influence, int iterations, bGPDstroke *r_gps)
bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float influence, int iterations, bGPDstroke *r_gps)
float BKE_gpencil_stroke_segment_length(const bGPDstroke *gps, const int start_index, const int end_index, bool use_3d)
void BKE_gpencil_transform(bGPdata *gpd, const float mat[4][4])
void BKE_gpencil_stroke_set_random_color(bGPDstroke *gps)
void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction)
static void gpencil_stroke_copy_point(bGPDstroke *gps, MDeformVert *dvert, bGPDspoint *point, const float delta[3], float pressure, float strength, float deltatime)
void BKE_gpencil_stroke_uv_update(bGPDstroke *gps)
void BKE_gpencil_centroid_3d(bGPdata *gpd, float r_centroid[3])
int BKE_gpencil_stroke_point_count(const bGPdata *gpd)
bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int point_index, float influence, int iterations, const bool smooth_caps, const bool keep_shape, bGPDstroke *r_gps)
void BKE_gpencil_stroke_fill_triangulate(bGPDstroke *gps)
void BKE_gpencil_stroke_boundingbox_calc(bGPDstroke *gps)
bool BKE_gpencil_stroke_close(bGPDstroke *gps)
void BKE_gpencil_point_coords_apply(bGPdata *gpd, const GPencilPointCoordinates *elem_data)
std::optional< blender::Bounds< blender::float3 > > BKE_gpencil_data_minmax(const bGPdata *gpd)
void BKE_gpencil_stroke_geometry_update(bGPdata *, bGPDstroke *gps)
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
ccl_device_inline float cross(const float2 a, const float2 b)
ccl_device_inline float3 exp(float3 v)
ccl_device_inline float3 cos(float3 v)
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
T midpoint(const T &a, const T &b)
struct MDeformVert * dvert