Blender  V3.3
overlay_armature.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2019 Blender Foundation. */
3 
8 #include <math.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "DNA_armature_types.h"
13 #include "DNA_constraint_types.h"
14 #include "DNA_mesh_types.h"
15 #include "DNA_object_types.h"
16 #include "DNA_scene_types.h"
17 #include "DNA_view3d_types.h"
18 
19 #include "DRW_render.h"
20 
21 #include "BLI_math.h"
22 #include "BLI_utildefines.h"
23 
24 #include "BKE_action.h"
25 #include "BKE_armature.h"
26 #include "BKE_deform.h"
27 #include "BKE_modifier.h"
28 #include "BKE_object.h"
29 
30 #include "DEG_depsgraph_query.h"
31 
32 #include "ED_armature.h"
33 #include "ED_view3d.h"
34 
35 #include "UI_resources.h"
36 
37 #include "draw_common.h"
38 #include "draw_manager_text.h"
39 
40 #include "overlay_private.h"
41 
42 #include "draw_cache_impl.h"
43 
44 #define BONE_VAR(eBone, pchan, var) ((eBone) ? (eBone->var) : (pchan->var))
45 #define BONE_FLAG(eBone, pchan) ((eBone) ? (eBone->flag) : (pchan->bone->flag))
46 
47 #define PT_DEFAULT_RAD 0.05f /* radius of the point batch. */
48 
49 typedef struct ArmatureDrawContext {
50  /* Current armature object */
52  /* bArmature *arm; */ /* TODO */
53 
54  union {
55  struct {
59  };
60  struct {
64  };
65  struct {
67  };
68  };
69 
78 
80 
81  /* not a theme, this is an override */
82  const float *const_color;
83  float const_wire;
84 
88 
89  const ThemeWireColor *bcolor; /* pchan color */
91 
93 {
94  Object *active_ob = draw_ctx->obact;
95 
96  /* Pose armature is handled by pose mode engine. */
97  if (((ob == active_ob) || (ob->mode & OB_MODE_POSE)) &&
98  ((draw_ctx->object_mode & OB_MODE_POSE) != 0)) {
99  return true;
100  }
101 
102  /* Armature parent is also handled by pose mode engine. */
103  if ((active_ob != NULL) && (draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
104  if (ob == draw_ctx->object_pose) {
105  return true;
106  }
107  }
108 
109  return false;
110 }
111 
113 {
114  OVERLAY_PassList *psl = vedata->psl;
115  OVERLAY_PrivateData *pd = vedata->stl->pd;
116 
117  const DRWContextState *draw_ctx = DRW_context_state_get();
118  const bool is_select_mode = DRW_state_is_select();
119  pd->armature.transparent = (draw_ctx->v3d->shading.type == OB_WIRE) ||
120  XRAY_FLAG_ENABLED(draw_ctx->v3d);
121  pd->armature.show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0) &&
122  !is_select_mode;
125  ((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0) &&
126  draw_ctx->object_pose != NULL;
127 
128  const float wire_alpha = pd->overlay.bone_wire_alpha;
129  const bool use_wire_alpha = (wire_alpha < 1.0f);
130 
131  DRWState state;
132 
133  if (pd->armature.do_pose_fade_geom) {
136 
137  float alpha = pd->overlay.xray_alpha_bone;
139  DRWShadingGroup *grp;
140 
142  DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){0.0f, 0.0f, 0.0f, alpha});
143 
145  DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){0.0f, 0.0f, 0.0f, pow(alpha, 4)});
146  }
147 
148  for (int i = 0; i < 2; i++) {
149  struct GPUShader *sh;
150  struct GPUVertFormat *format;
151  DRWShadingGroup *grp = NULL;
152 
155 
158 
159  DRWPass **p_armature_ps = &psl->armature_ps[i];
160  DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
162  DRW_PASS_CREATE(*p_armature_ps, state | pd->clipping_state | infront_state);
163  DRWPass *armature_ps = *p_armature_ps;
164 
165  DRWPass **p_armature_trans_ps = &psl->armature_transp_ps[i];
167  DRW_PASS_CREATE(*p_armature_trans_ps, state | pd->clipping_state);
168  DRWPass *armature_transp_ps = *p_armature_trans_ps;
169 
170 #define BUF_INSTANCE DRW_shgroup_call_buffer_instance
171 #define BUF_LINE(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_LINES)
172 #define BUF_POINT(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_POINTS)
173 
174  {
175  format = formats->instance_bone;
176 
178  grp = DRW_shgroup_create(sh, armature_ps);
179  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
181 
182  grp = DRW_shgroup_create(sh, armature_ps);
185  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha * 0.4f);
187 
189  grp = DRW_shgroup_create(sh, armature_ps);
190  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
191  cb->solid.custom_fill = grp;
194 
195  grp = DRW_shgroup_create(sh, armature_ps);
198  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha * 0.6f);
199  cb->transp.custom_fill = grp;
202 
204  grp = DRW_shgroup_create(sh, armature_ps);
205  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
206  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
208 
209  if (use_wire_alpha) {
210  grp = DRW_shgroup_create(sh, armature_ps);
212  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
213  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
216  }
217  else {
219  }
220 
222  cb->solid.custom_outline = grp = DRW_shgroup_create(sh, armature_ps);
223  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
224  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
227 
228  if (use_wire_alpha) {
229  cb->transp.custom_outline = grp = DRW_shgroup_create(sh, armature_ps);
231  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
232  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
235  }
236  else {
240  }
241 
243  cb->solid.custom_wire = grp = DRW_shgroup_create(sh, armature_ps);
244  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
245  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
246 
247  if (use_wire_alpha) {
248  cb->transp.custom_wire = grp = DRW_shgroup_create(sh, armature_ps);
250  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
251  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
252  }
253  else {
255  }
256  }
257  {
258  format = formats->instance_extra;
259 
261  grp = DRW_shgroup_create(sh, armature_ps);
262  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
263  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
265 
266  if (use_wire_alpha) {
267  grp = DRW_shgroup_create(sh, armature_ps);
269  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
270  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
272  }
273  else {
274  cb->transp.dof_lines = cb->solid.dof_lines;
275  }
276 
278  grp = DRW_shgroup_create(sh, armature_transp_ps);
279  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
280  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
282 
283  if (use_wire_alpha) {
284  grp = DRW_shgroup_create(sh, armature_transp_ps);
285  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
286  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
288  }
289  else {
290  cb->transp.dof_sphere = cb->solid.dof_sphere;
291  }
292  }
293  {
294  format = formats->instance_bone_stick;
295 
297  grp = DRW_shgroup_create(sh, armature_ps);
298  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
299  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
301 
302  if (use_wire_alpha) {
303  grp = DRW_shgroup_create(sh, armature_ps);
305  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
306  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
308  }
309  else {
310  cb->transp.stick = cb->solid.stick;
311  }
312  }
313  {
314  format = formats->instance_bone_envelope;
315 
317  grp = DRW_shgroup_create(sh, armature_ps);
319  DRW_shgroup_uniform_bool_copy(grp, "isDistance", false);
320  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
322 
323  grp = DRW_shgroup_create(sh, armature_ps);
326  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha * 0.6f);
328 
330 
332  grp = DRW_shgroup_create(sh, armature_ps);
333  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
334  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
337 
338  if (use_wire_alpha) {
339  grp = DRW_shgroup_create(sh, armature_ps);
341  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
342  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
345  }
346  else {
348  }
349 
351 
353  grp = DRW_shgroup_create(sh, armature_transp_ps);
354  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
355  DRW_shgroup_uniform_bool_copy(grp, "isDistance", true);
358 
359  if (use_wire_alpha) {
360  grp = DRW_shgroup_create(sh, armature_transp_ps);
361  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
362  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
363  DRW_shgroup_uniform_bool_copy(grp, "isDistance", true);
367  }
368  else {
370  }
371  }
372  {
373  format = formats->pos_color;
374 
376  grp = DRW_shgroup_create(sh, armature_ps);
377  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
378  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
379  cb->solid.wire = BUF_LINE(grp, format);
380 
381  if (use_wire_alpha) {
382  grp = DRW_shgroup_create(sh, armature_ps);
384  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
385  DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha);
386  cb->transp.wire = BUF_LINE(grp, format);
387  }
388  else {
389  cb->transp.wire = cb->solid.wire;
390  }
391  }
392  }
393 }
394 
395 /* -------------------------------------------------------------------- */
400  const float aminx,
401  const float aminz,
402  const float amaxx,
403  const float amaxz)
404 {
405  data->amin_a = aminx;
406  data->amin_b = aminz;
407  data->amax_a = amaxx;
408  data->amax_b = amaxz;
409 }
410 
411 /* Encode 2 units float with byte precision into a float. */
412 static float encode_2f_to_float(float a, float b)
413 {
414  CLAMP(a, 0.0f, 1.0f);
415  CLAMP(b, 0.0f, 2.0f); /* Can go up to 2. Needed for wire size. */
416  return (float)((int)(a * 255) | ((int)(b * 255) << 8));
417 }
418 
420 {
421  /* Encoded color into 2 floats to be able to use the obmat to color the custom bones. */
422  data->color_hint_a = encode_2f_to_float(hint_color[0], hint_color[1]);
423  data->color_hint_b = encode_2f_to_float(hint_color[2], hint_color[3]);
424 }
425 
427 {
428  /* Encoded color into 2 floats to be able to use the obmat to color the custom bones. */
429  data->color_a = encode_2f_to_float(bone_color[0], bone_color[1]);
430  data->color_b = encode_2f_to_float(bone_color[2], bone_color[3]);
431 }
432 
433 /* Octahedral */
435  const float (*bone_mat)[4],
436  const float bone_color[4],
437  const float hint_color[4],
438  const float outline_color[4])
439 {
440  BoneInstanceData inst_data;
441  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
442  if (ctx->solid) {
443  OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
444  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
445  DRW_buffer_add_entry_struct(ctx->solid, &inst_data);
446  }
447  if (outline_color[3] > 0.0f) {
448  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
449  DRW_buffer_add_entry_struct(ctx->outline, &inst_data);
450  }
451 }
452 
453 /* Box / B-Bone */
455  const float (*bone_mat)[4],
456  const float bone_color[4],
457  const float hint_color[4],
458  const float outline_color[4])
459 {
460  BoneInstanceData inst_data;
461  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
462  if (ctx->solid) {
463  OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
464  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
465  DRW_buffer_add_entry_struct(ctx->solid, &inst_data);
466  }
467  if (outline_color[3] > 0.0f) {
468  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
469  DRW_buffer_add_entry_struct(ctx->outline, &inst_data);
470  }
471 }
472 
473 /* Wire */
475  const float (*bone_mat)[4],
476  const float color[4])
477 {
478  float head[3], tail[3];
479  mul_v3_m4v3(head, ctx->ob->obmat, bone_mat[3]);
480  add_v3_v3v3(tail, bone_mat[3], bone_mat[1]);
481  mul_m4_v3(ctx->ob->obmat, tail);
482 
483  DRW_buffer_add_entry(ctx->wire, head, color);
484  DRW_buffer_add_entry(ctx->wire, tail, color);
485 }
486 
487 /* Stick */
489  const float (*bone_mat)[4],
490  const float col_wire[4],
491  const float col_bone[4],
492  const float col_head[4],
493  const float col_tail[4])
494 {
495  float head[3], tail[3];
496  mul_v3_m4v3(head, ctx->ob->obmat, bone_mat[3]);
497  add_v3_v3v3(tail, bone_mat[3], bone_mat[1]);
498  mul_m4_v3(ctx->ob->obmat, tail);
499 
500  DRW_buffer_add_entry(ctx->stick, head, tail, col_wire, col_bone, col_head, col_tail);
501 }
502 
503 /* Envelope */
505  const float (*bone_mat)[4],
506  const float *radius_head,
507  const float *radius_tail,
508  const float *distance)
509 {
510  if (ctx->envelope_distance) {
511  float head_sph[4] = {0.0f, 0.0f, 0.0f, 1.0f}, tail_sph[4] = {0.0f, 1.0f, 0.0f, 1.0f};
512  float xaxis[4] = {1.0f, 0.0f, 0.0f, 1.0f};
513  /* Still less operation than m4 multiplication. */
514  mul_m4_v4(bone_mat, head_sph);
515  mul_m4_v4(bone_mat, tail_sph);
516  mul_m4_v4(bone_mat, xaxis);
517  mul_m4_v4(ctx->ob->obmat, head_sph);
518  mul_m4_v4(ctx->ob->obmat, tail_sph);
519  mul_m4_v4(ctx->ob->obmat, xaxis);
520  sub_v3_v3(xaxis, head_sph);
521  float obscale = mat4_to_scale(ctx->ob->obmat);
522  head_sph[3] = *radius_head * obscale;
523  head_sph[3] += *distance * obscale;
524  tail_sph[3] = *radius_tail * obscale;
525  tail_sph[3] += *distance * obscale;
526  DRW_buffer_add_entry(ctx->envelope_distance, head_sph, tail_sph, xaxis);
527  }
528 }
529 
531  const float (*bone_mat)[4],
532  const float bone_col[4],
533  const float hint_col[4],
534  const float outline_col[4],
535  const float *radius_head,
536  const float *radius_tail)
537 {
538  float head_sph[4] = {0.0f, 0.0f, 0.0f, 1.0f}, tail_sph[4] = {0.0f, 1.0f, 0.0f, 1.0f};
539  float xaxis[4] = {1.0f, 0.0f, 0.0f, 1.0f};
540  /* Still less operation than m4 multiplication. */
541  mul_m4_v4(bone_mat, head_sph);
542  mul_m4_v4(bone_mat, tail_sph);
543  mul_m4_v4(bone_mat, xaxis);
544  mul_m4_v4(ctx->ob->obmat, head_sph);
545  mul_m4_v4(ctx->ob->obmat, tail_sph);
546  mul_m4_v4(ctx->ob->obmat, xaxis);
547  float obscale = mat4_to_scale(ctx->ob->obmat);
548  head_sph[3] = *radius_head * obscale;
549  tail_sph[3] = *radius_tail * obscale;
550 
551  if (head_sph[3] < 0.0f || tail_sph[3] < 0.0f) {
552  BoneInstanceData inst_data;
553  if (head_sph[3] < 0.0f) {
554  /* Draw Tail only */
555  scale_m4_fl(inst_data.mat, tail_sph[3] / PT_DEFAULT_RAD);
556  copy_v3_v3(inst_data.mat[3], tail_sph);
557  }
558  else {
559  /* Draw Head only */
560  scale_m4_fl(inst_data.mat, head_sph[3] / PT_DEFAULT_RAD);
561  copy_v3_v3(inst_data.mat[3], head_sph);
562  }
563 
564  if (ctx->point_solid) {
565  OVERLAY_bone_instance_data_set_color(&inst_data, bone_col);
566  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_col);
567  DRW_buffer_add_entry_struct(ctx->point_solid, &inst_data);
568  }
569  if (outline_col[3] > 0.0f) {
570  OVERLAY_bone_instance_data_set_color(&inst_data, outline_col);
571  DRW_buffer_add_entry_struct(ctx->point_outline, &inst_data);
572  }
573  }
574  else {
575  /* Draw Body */
576  float tmp_sph[4];
577  float len = len_v3v3(tail_sph, head_sph);
578  float fac_head = (len - head_sph[3]) / len;
579  float fac_tail = (len - tail_sph[3]) / len;
580  /* Small epsilon to avoid problem with float precision in shader. */
581  if (len > (tail_sph[3] + head_sph[3]) + 1e-8f) {
582  copy_v4_v4(tmp_sph, head_sph);
583  interp_v4_v4v4(head_sph, tail_sph, head_sph, fac_head);
584  interp_v4_v4v4(tail_sph, tmp_sph, tail_sph, fac_tail);
585  if (ctx->envelope_solid) {
586  DRW_buffer_add_entry(ctx->envelope_solid, head_sph, tail_sph, bone_col, hint_col, xaxis);
587  }
588  if (outline_col[3] > 0.0f) {
589  DRW_buffer_add_entry(ctx->envelope_outline, head_sph, tail_sph, outline_col, xaxis);
590  }
591  }
592  else {
593  /* Distance between endpoints is too small for a capsule. Draw a Sphere instead. */
594  float fac = max_ff(fac_head, 1.0f - fac_tail);
595  interp_v4_v4v4(tmp_sph, tail_sph, head_sph, clamp_f(fac, 0.0f, 1.0f));
596 
597  BoneInstanceData inst_data;
598  scale_m4_fl(inst_data.mat, tmp_sph[3] / PT_DEFAULT_RAD);
599  copy_v3_v3(inst_data.mat[3], tmp_sph);
600  if (ctx->point_solid) {
601  OVERLAY_bone_instance_data_set_color(&inst_data, bone_col);
602  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_col);
603  DRW_buffer_add_entry_struct(ctx->point_solid, &inst_data);
604  }
605  if (outline_col[3] > 0.0f) {
606  OVERLAY_bone_instance_data_set_color(&inst_data, outline_col);
607  DRW_buffer_add_entry_struct(ctx->point_outline, &inst_data);
608  }
609  }
610  }
611 }
612 
613 /* Custom (geometry) */
614 
615 extern void drw_batch_cache_validate(Object *custom);
617 
619  DRWShadingGroup *grp,
620  struct GPUBatch *custom_geom)
621 {
622  DRWCallBuffer *buf = BLI_ghash_lookup(ctx->custom_shapes_ghash, custom_geom);
623  if (buf == NULL) {
625  buf = DRW_shgroup_call_buffer_instance(grp, formats->instance_bone, custom_geom);
626  BLI_ghash_insert(ctx->custom_shapes_ghash, custom_geom, buf);
627  }
628  return buf;
629 }
630 
632  Mesh *mesh,
633  const float (*bone_mat)[4],
634  const float bone_color[4],
635  const float hint_color[4],
636  const float outline_color[4],
637  Object *custom)
638 {
639  /* TODO(fclem): arg... less than ideal but we never iter on this object
640  * to assure batch cache is valid. */
642 
646  BoneInstanceData inst_data;
647  DRWCallBuffer *buf;
648 
649  if (surf || edges || ledges) {
650  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
651  }
652 
653  if (surf && ctx->custom_solid) {
654  buf = custom_bone_instance_shgroup(ctx, ctx->custom_solid, surf);
655  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
656  OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
657  DRW_buffer_add_entry_struct(buf, inst_data.mat);
658  }
659 
660  if (edges && ctx->custom_outline) {
661  buf = custom_bone_instance_shgroup(ctx, ctx->custom_outline, edges);
662  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
663  DRW_buffer_add_entry_struct(buf, inst_data.mat);
664  }
665 
666  if (ledges) {
667  buf = custom_bone_instance_shgroup(ctx, ctx->custom_wire, ledges);
668  OVERLAY_bone_instance_data_set_color_hint(&inst_data, outline_color);
669  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
670  DRW_buffer_add_entry_struct(buf, inst_data.mat);
671  }
672 
673  /* TODO(fclem): needs to be moved elsewhere. */
675 }
676 
678  Mesh *mesh,
679  const float (*bone_mat)[4],
680  const float color[4],
681  Object *custom)
682 {
683  /* TODO(fclem): arg... less than ideal but we never iter on this object
684  * to assure batch cache is valid. */
686 
688  if (geom) {
690  BoneInstanceData inst_data;
691  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
694  DRW_buffer_add_entry_struct(buf, inst_data.mat);
695  }
696 
697  /* TODO(fclem): needs to be moved elsewhere. */
699 }
700 
702  Curve *curve,
703  const float (*bone_mat)[4],
704  const float outline_color[4],
705  Object *custom)
706 {
707  /* TODO(fclem): arg... less than ideal but we never iter on this object
708  * to assure batch cache is valid. */
710 
711  /* This only handles curves without any surface. The other curve types should have been converted
712  * to meshes and rendered in the mesh drawing function. */
713  struct GPUBatch *ledges = NULL;
714  if (custom->type == OB_FONT) {
715  ledges = DRW_cache_text_edge_wire_get(custom);
716  }
717  else {
718  ledges = DRW_cache_curve_edge_wire_get(custom);
719  }
720 
721  if (ledges) {
722  BoneInstanceData inst_data;
723  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
724 
725  DRWCallBuffer *buf = custom_bone_instance_shgroup(ctx, ctx->custom_wire, ledges);
726  OVERLAY_bone_instance_data_set_color_hint(&inst_data, outline_color);
727  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
728  DRW_buffer_add_entry_struct(buf, inst_data.mat);
729  }
730 
731  /* TODO(fclem): needs to be moved elsewhere. */
733 }
734 
736  const float (*bone_mat)[4],
737  const float bone_color[4],
738  const float hint_color[4],
739  const float outline_color[4],
740  Object *custom)
741 {
742  /* The custom object is not an evaluated object, so its object->data field hasn't been replaced
743  * by #data_eval. This is bad since it gives preference to an object's evaluated mesh over any
744  * other data type, but supporting all evaluated geometry components would require a much
745  * larger refactor of this area. */
747  if (mesh != NULL) {
749  ctx, mesh, bone_mat, bone_color, hint_color, outline_color, custom);
750  return;
751  }
752 
753  if (ELEM(custom->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
754  drw_shgroup_custom_bone_curve(ctx, custom->data, bone_mat, outline_color, custom);
755  }
756 }
757 
759  const float (*bone_mat)[4],
760  const float color[4],
761  Object *custom)
762 {
763  /* See comments in #drw_shgroup_bone_custom_solid. */
765  if (mesh != NULL) {
766  drw_shgroup_bone_custom_mesh_wire(ctx, mesh, bone_mat, color, custom);
767  return;
768  }
769 
770  if (ELEM(custom->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
771  drw_shgroup_custom_bone_curve(ctx, custom->data, bone_mat, color, custom);
772  }
773 }
774 
776  const float (*bone_mat)[4],
777  const float color[4],
778  Object *custom)
779 {
780  const float final_color[4] = {color[0], color[1], color[2], 1.0f};
781  float mat[4][4];
782  mul_m4_m4m4(mat, ctx->ob->obmat, bone_mat);
783 
784  switch (custom->empty_drawtype) {
785  case OB_PLAINAXES:
786  case OB_SINGLE_ARROW:
787  case OB_CUBE:
788  case OB_CIRCLE:
789  case OB_EMPTY_SPHERE:
790  case OB_EMPTY_CONE:
791  case OB_ARROWS:
793  ctx->extras, mat, custom->empty_drawsize, custom->empty_drawtype, final_color);
794  break;
795  case OB_EMPTY_IMAGE:
796  break;
797  }
798 }
799 
800 /* Head and tail sphere */
802  const float (*bone_mat)[4],
803  const float bone_color[4],
804  const float hint_color[4],
805  const float outline_color[4])
806 {
807  BoneInstanceData inst_data;
808  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
809  if (ctx->point_solid) {
810  OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
811  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
812  DRW_buffer_add_entry_struct(ctx->point_solid, &inst_data);
813  }
814  if (outline_color[3] > 0.0f) {
815  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
816  DRW_buffer_add_entry_struct(ctx->point_outline, &inst_data);
817  }
818 }
819 
820 /* Axes */
822  const float (*bone_mat)[4],
823  const float color[4])
824 {
825  float mat[4][4];
826  mul_m4_m4m4(mat, ctx->ob->obmat, bone_mat);
827  /* Move to bone tail. */
828  add_v3_v3(mat[3], mat[1]);
829  OVERLAY_empty_shape(ctx->extras, mat, 0.25f, OB_ARROWS, color);
830 }
831 
832 /* Relationship lines */
834  const float start[3],
835  const float end[3],
836  const float color[4])
837 {
838  float s[3], e[3];
839  mul_v3_m4v3(s, ctx->ob->obmat, start);
840  mul_v3_m4v3(e, ctx->ob->obmat, end);
841  /* reverse order to have less stipple overlap */
843 }
844 
846  const float start[3],
847  const float end[3])
848 {
850 }
851 
853  const float start[3],
854  const float end[3])
855 {
857 }
858 
860  const float start[3],
861  const float end[3])
862 {
864  ctx, start, end, G_draw.block.color_bone_ik_line_no_target);
865 }
866 
868  const float start[3],
869  const float end[3])
870 {
872 }
873 
876 /* -------------------------------------------------------------------- */
883 /* values of colCode for set_pchan_color */
884 enum {
885  PCHAN_COLOR_NORMAL = 0, /* normal drawing */
886  PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */
887  PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */
888 };
889 
890 /* This function sets the color-set for coloring a certain bone */
892 {
893  bPose *pose = (ob) ? ob->pose : NULL;
894  bArmature *arm = (ob) ? ob->data : NULL;
895  bActionGroup *grp = NULL;
896  short color_index = 0;
897 
898  /* sanity check */
899  if (ELEM(NULL, ob, arm, pose, pchan)) {
900  ctx->bcolor = NULL;
901  return;
902  }
903 
904  /* only try to set custom color if enabled for armature */
905  if (arm->flag & ARM_COL_CUSTOM) {
906  /* currently, a bone can only use a custom color set if its group (if it has one),
907  * has been set to use one
908  */
909  if (pchan->agrp_index) {
910  grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
911  if (grp) {
912  color_index = grp->customCol;
913  }
914  }
915  }
916 
917  /* bcolor is a pointer to the color set to use. If NULL, then the default
918  * color set (based on the theme colors for 3d-view) is used.
919  */
920  if (color_index > 0) {
921  bTheme *btheme = UI_GetTheme();
922  ctx->bcolor = &btheme->tarm[(color_index - 1)];
923  }
924  else if (color_index == -1) {
925  /* use the group's own custom color set (grp is always != NULL here) */
926  ctx->bcolor = &grp->cs;
927  }
928  else {
929  ctx->bcolor = NULL;
930  }
931 }
932 
933 /* This function is for brightening/darkening a given color (like UI_GetThemeColorShade3ubv()) */
934 static void cp_shade_color3ub(uchar cp[3], const int offset)
935 {
936  int r, g, b;
937 
938  r = offset + (int)cp[0];
939  CLAMP(r, 0, 255);
940  g = offset + (int)cp[1];
941  CLAMP(g, 0, 255);
942  b = offset + (int)cp[2];
943  CLAMP(b, 0, 255);
944 
945  cp[0] = r;
946  cp[1] = g;
947  cp[2] = b;
948 }
949 
950 /* This function sets the gl-color for coloring a certain bone (based on bcolor) */
951 static bool set_pchan_color(const ArmatureDrawContext *ctx,
952  short colCode,
953  const int boneflag,
954  const short constflag,
955  float r_color[4])
956 {
957  float *fcolor = r_color;
958  const ThemeWireColor *bcolor = ctx->bcolor;
959 
960  switch (colCode) {
961  case PCHAN_COLOR_NORMAL: {
962  if (bcolor) {
963  uchar cp[4] = {255};
964  if (boneflag & BONE_DRAW_ACTIVE) {
965  copy_v3_v3_uchar(cp, bcolor->active);
966  if (!(boneflag & BONE_SELECTED)) {
967  cp_shade_color3ub(cp, -80);
968  }
969  }
970  else if (boneflag & BONE_SELECTED) {
971  copy_v3_v3_uchar(cp, bcolor->select);
972  }
973  else {
974  /* a bit darker than solid */
975  copy_v3_v3_uchar(cp, bcolor->solid);
976  cp_shade_color3ub(cp, -50);
977  }
978  rgb_uchar_to_float(fcolor, cp);
979  /* Meh, hardcoded srgb transform here. */
980  srgb_to_linearrgb_v4(fcolor, fcolor);
981  }
982  else {
983  if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
985  }
986  else if (boneflag & BONE_DRAW_ACTIVE) {
988  }
989  else if (boneflag & BONE_SELECTED) {
991  }
992  else {
994  }
995  }
996  return true;
997  }
998  case PCHAN_COLOR_SOLID: {
999  if (bcolor) {
1000  rgb_uchar_to_float(fcolor, (uchar *)bcolor->solid);
1001  fcolor[3] = 1.0f;
1002  /* Meh, hardcoded srgb transform here. */
1003  srgb_to_linearrgb_v4(fcolor, fcolor);
1004  }
1005  else {
1007  }
1008  return true;
1009  }
1010  case PCHAN_COLOR_CONSTS: {
1011  if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
1012  if (constflag & PCHAN_HAS_TARGET) {
1014  }
1015  else if (constflag & PCHAN_HAS_IK) {
1017  }
1018  else if (constflag & PCHAN_HAS_SPLINEIK) {
1020  }
1021  else if (constflag & PCHAN_HAS_CONST) {
1023  }
1024  else {
1025  return false;
1026  }
1027  return true;
1028  }
1029  return false;
1030  }
1031  }
1032 
1033  return false;
1034 }
1035 
1038 /* -------------------------------------------------------------------- */
1042 static void bone_locked_color_shade(float color[4])
1043 {
1044  float *locked_color = G_draw.block.color_bone_locked;
1045 
1046  interp_v3_v3v3(color, color, locked_color, locked_color[3]);
1047 }
1048 
1049 static const float *get_bone_solid_color(const ArmatureDrawContext *ctx,
1050  const EditBone *UNUSED(eBone),
1051  const bPoseChannel *pchan,
1052  const bArmature *arm,
1053  const int boneflag,
1054  const short constflag)
1055 {
1056  if (ctx->const_color) {
1057  return G_draw.block.color_bone_solid;
1058  }
1059 
1060  if (arm->flag & ARM_POSEMODE) {
1061  static float disp_color[4];
1062  copy_v4_v4(disp_color, pchan->draw_data->solid_color);
1063  set_pchan_color(ctx, PCHAN_COLOR_SOLID, boneflag, constflag, disp_color);
1064 
1065  if (boneflag & BONE_DRAW_LOCKED_WEIGHT) {
1066  bone_locked_color_shade(disp_color);
1067  }
1068 
1069  return disp_color;
1070  }
1071 
1072  return G_draw.block.color_bone_solid;
1073 }
1074 
1076  const EditBone *eBone,
1077  const bPoseChannel *pchan,
1078  const bArmature *arm,
1079  const int boneflag,
1080  const short constflag)
1081 {
1082  if (ctx->const_color) {
1083  return G_draw.block.color_bone_solid;
1084  }
1085 
1086  const float *col = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag);
1087 
1088  static float consts_color[4];
1089  if ((arm->flag & ARM_POSEMODE) && !(boneflag & BONE_DRAW_LOCKED_WEIGHT) &&
1090  set_pchan_color(ctx, PCHAN_COLOR_CONSTS, boneflag, constflag, consts_color)) {
1091  interp_v3_v3v3(consts_color, col, consts_color, 0.5f);
1092  }
1093  else {
1094  copy_v4_v4(consts_color, col);
1095  }
1096  return consts_color;
1097 }
1098 
1099 static float get_bone_wire_thickness(const ArmatureDrawContext *ctx, int boneflag)
1100 {
1101  if (ctx->const_color) {
1102  return ctx->const_wire;
1103  }
1104  if (boneflag & (BONE_DRAW_ACTIVE | BONE_SELECTED)) {
1105  return 2.0f;
1106  }
1107 
1108  return 1.0f;
1109 }
1110 
1111 static const float *get_bone_wire_color(const ArmatureDrawContext *ctx,
1112  const EditBone *eBone,
1113  const bPoseChannel *pchan,
1114  const bArmature *arm,
1115  const int boneflag,
1116  const short constflag)
1117 {
1118  static float disp_color[4];
1119 
1120  if (ctx->const_color) {
1121  copy_v3_v3(disp_color, ctx->const_color);
1122  }
1123  else if (eBone) {
1124  if (boneflag & BONE_SELECTED) {
1125  if (boneflag & BONE_DRAW_ACTIVE) {
1127  }
1128  else {
1130  }
1131  }
1132  else {
1133  if (boneflag & BONE_DRAW_ACTIVE) {
1135  }
1136  else {
1137  copy_v3_v3(disp_color, G_draw.block.color_wire_edit);
1138  }
1139  }
1140  }
1141  else if (arm->flag & ARM_POSEMODE) {
1142  copy_v4_v4(disp_color, pchan->draw_data->wire_color);
1143  set_pchan_color(ctx, PCHAN_COLOR_NORMAL, boneflag, constflag, disp_color);
1144 
1145  if (boneflag & BONE_DRAW_LOCKED_WEIGHT) {
1146  bone_locked_color_shade(disp_color);
1147  }
1148  }
1149  else {
1150  copy_v3_v3(disp_color, G_draw.block.color_vertex);
1151  }
1152 
1153  disp_color[3] = get_bone_wire_thickness(ctx, boneflag);
1154 
1155  return disp_color;
1156 }
1157 
1158 static void bone_hint_color_shade(float hint_color[4], const float color[4])
1159 {
1160  /* Increase contrast. */
1161  mul_v3_v3v3(hint_color, color, color);
1162  /* Decrease value to add mode shading to the shape. */
1163  mul_v3_fl(hint_color, 0.1f);
1164  hint_color[3] = 1.0f;
1165 }
1166 
1167 static const float *get_bone_hint_color(const ArmatureDrawContext *ctx,
1168  const EditBone *eBone,
1169  const bPoseChannel *pchan,
1170  const bArmature *arm,
1171  const int boneflag,
1172  const short constflag)
1173 {
1174  static float hint_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
1175 
1176  if (ctx->const_color) {
1178  }
1179  else {
1180  const float *wire_color = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1181  bone_hint_color_shade(hint_color, wire_color);
1182  }
1183 
1184  return hint_color;
1185 }
1186 
1189 /* -------------------------------------------------------------------- */
1194 {
1195  if (pchan->draw_data != NULL) {
1196  if (pchan->draw_data->bbone_matrix_len != pchan->bone->segments) {
1197  MEM_SAFE_FREE(pchan->draw_data);
1198  }
1199  }
1200 
1201  if (pchan->draw_data == NULL) {
1202  pchan->draw_data = MEM_mallocN(
1203  sizeof(*pchan->draw_data) + sizeof(Mat4) * pchan->bone->segments, __func__);
1204  pchan->draw_data->bbone_matrix_len = pchan->bone->segments;
1205  }
1206 }
1207 
1209 {
1210  float ebmat[4][4];
1211  float bone_scale[3];
1212  float(*bone_mat)[4];
1213  float(*disp_mat)[4];
1214  float(*disp_tail_mat)[4];
1215 
1216  /* TODO: This should be moved to depsgraph or armature refresh
1217  * and not be tight to the draw pass creation.
1218  * This would refresh armature without invalidating the draw cache */
1219  if (pchan) {
1220  bone_mat = pchan->pose_mat;
1221  disp_mat = pchan->disp_mat;
1222  disp_tail_mat = pchan->disp_tail_mat;
1223  copy_v3_fl(bone_scale, pchan->bone->length);
1224  }
1225  else {
1226  eBone->length = len_v3v3(eBone->tail, eBone->head);
1227  ED_armature_ebone_to_mat4(eBone, ebmat);
1228 
1229  copy_v3_fl(bone_scale, eBone->length);
1230  bone_mat = ebmat;
1231  disp_mat = eBone->disp_mat;
1232  disp_tail_mat = eBone->disp_tail_mat;
1233  }
1234 
1235  copy_m4_m4(disp_mat, bone_mat);
1236  rescale_m4(disp_mat, bone_scale);
1237  copy_m4_m4(disp_tail_mat, disp_mat);
1238  translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f);
1239 }
1240 
1241 /* compute connected child pointer for B-Bone drawing */
1243 {
1244  EditBone *eBone;
1245 
1246  for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
1247  eBone->bbone_child = NULL;
1248  }
1249 
1250  for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
1251  if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
1252  eBone->parent->bbone_child = eBone;
1253  }
1254  }
1255 }
1256 
1257 /* A version of BKE_pchan_bbone_spline_setup() for previewing editmode curve settings. */
1258 static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_BBONE_SUBDIV][4][4])
1259 {
1260  BBoneSplineParameters param;
1261  EditBone *prev, *next;
1262  float imat[4][4], bonemat[4][4];
1263  float tmp[3];
1264 
1265  memset(&param, 0, sizeof(param));
1266 
1267  param.segments = ebone->segments;
1268  param.length = ebone->length;
1269 
1270  /* Get "next" and "prev" bones - these are used for handle calculations. */
1271  if (ebone->bbone_prev_type == BBONE_HANDLE_AUTO) {
1272  /* Use connected parent. */
1273  if (ebone->flag & BONE_CONNECTED) {
1274  prev = ebone->parent;
1275  }
1276  else {
1277  prev = NULL;
1278  }
1279  }
1280  else {
1281  prev = ebone->bbone_prev;
1282  }
1283 
1284  if (ebone->bbone_next_type == BBONE_HANDLE_AUTO) {
1285  /* Use connected child. */
1286  next = ebone->bbone_child;
1287  }
1288  else {
1289  next = ebone->bbone_next;
1290  }
1291 
1292  /* compute handles from connected bones */
1293  if (prev || next) {
1294  ED_armature_ebone_to_mat4(ebone, imat);
1295  invert_m4(imat);
1296 
1297  if (prev) {
1298  param.use_prev = true;
1299 
1300  if (ebone->bbone_prev_type == BBONE_HANDLE_RELATIVE) {
1301  zero_v3(param.prev_h);
1302  }
1303  else if (ebone->bbone_prev_type == BBONE_HANDLE_TANGENT) {
1304  sub_v3_v3v3(tmp, prev->tail, prev->head);
1305  sub_v3_v3v3(tmp, ebone->head, tmp);
1306  mul_v3_m4v3(param.prev_h, imat, tmp);
1307  }
1308  else {
1309  param.prev_bbone = (prev->segments > 1);
1310 
1311  mul_v3_m4v3(param.prev_h, imat, prev->head);
1312  }
1313 
1314  if (!param.prev_bbone) {
1315  ED_armature_ebone_to_mat4(prev, bonemat);
1316  mul_m4_m4m4(param.prev_mat, imat, bonemat);
1317  }
1318  }
1319 
1320  if (next) {
1321  param.use_next = true;
1322 
1323  if (ebone->bbone_next_type == BBONE_HANDLE_RELATIVE) {
1324  copy_v3_fl3(param.next_h, 0.0f, param.length, 0.0);
1325  }
1326  else if (ebone->bbone_next_type == BBONE_HANDLE_TANGENT) {
1327  sub_v3_v3v3(tmp, next->tail, next->head);
1328  add_v3_v3v3(tmp, ebone->tail, tmp);
1329  mul_v3_m4v3(param.next_h, imat, tmp);
1330  }
1331  else {
1332  param.next_bbone = (next->segments > 1);
1333 
1334  mul_v3_m4v3(param.next_h, imat, next->tail);
1335  }
1336 
1337  ED_armature_ebone_to_mat4(next, bonemat);
1338  mul_m4_m4m4(param.next_mat, imat, bonemat);
1339  }
1340  }
1341 
1342  param.ease1 = ebone->ease1;
1343  param.ease2 = ebone->ease2;
1344  param.roll1 = ebone->roll1;
1345  param.roll2 = ebone->roll2;
1346 
1347  if (prev && (ebone->bbone_flag & BBONE_ADD_PARENT_END_ROLL)) {
1348  param.roll1 += prev->roll2;
1349  }
1350 
1351  copy_v3_v3(param.scale_in, ebone->scale_in);
1352  copy_v3_v3(param.scale_out, ebone->scale_out);
1353 
1354  param.curve_in_x = ebone->curve_in_x;
1355  param.curve_in_z = ebone->curve_in_z;
1356 
1357  param.curve_out_x = ebone->curve_out_x;
1358  param.curve_out_z = ebone->curve_out_z;
1359 
1360  if (ebone->bbone_flag & BBONE_SCALE_EASING) {
1361  param.ease1 *= param.scale_in[1];
1362  param.curve_in_x *= param.scale_in[1];
1363  param.curve_in_z *= param.scale_in[1];
1364 
1365  param.ease2 *= param.scale_out[1];
1366  param.curve_out_x *= param.scale_out[1];
1367  param.curve_out_z *= param.scale_out[1];
1368  }
1369 
1370  ebone->segments = BKE_pchan_bbone_spline_compute(&param, false, (Mat4 *)result_array);
1371 }
1372 
1374 {
1375  float s[4][4], ebmat[4][4];
1376  float length, xwidth, zwidth;
1377  float(*bone_mat)[4];
1378  short bbone_segments;
1379 
1380  /* TODO: This should be moved to depsgraph or armature refresh
1381  * and not be tight to the draw pass creation.
1382  * This would refresh armature without invalidating the draw cache. */
1383  if (pchan) {
1384  length = pchan->bone->length;
1385  xwidth = pchan->bone->xwidth;
1386  zwidth = pchan->bone->zwidth;
1387  bone_mat = pchan->pose_mat;
1388  bbone_segments = pchan->bone->segments;
1389  }
1390  else {
1391  eBone->length = len_v3v3(eBone->tail, eBone->head);
1392  ED_armature_ebone_to_mat4(eBone, ebmat);
1393 
1394  length = eBone->length;
1395  xwidth = eBone->xwidth;
1396  zwidth = eBone->zwidth;
1397  bone_mat = ebmat;
1398  bbone_segments = eBone->segments;
1399  }
1400 
1401  size_to_mat4(s, (const float[3]){xwidth, length / bbone_segments, zwidth});
1402 
1403  /* Compute BBones segment matrices... */
1404  /* Note that we need this even for one-segment bones, because box drawing need specific weirdo
1405  * matrix for the box, that we cannot use to draw end points & co. */
1406  if (pchan) {
1407  Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
1408  if (bbone_segments > 1) {
1409  BKE_pchan_bbone_spline_setup(pchan, false, false, bbones_mat);
1410 
1411  for (int i = bbone_segments; i--; bbones_mat++) {
1412  mul_m4_m4m4(bbones_mat->mat, bbones_mat->mat, s);
1413  mul_m4_m4m4(bbones_mat->mat, bone_mat, bbones_mat->mat);
1414  }
1415  }
1416  else {
1417  mul_m4_m4m4(bbones_mat->mat, bone_mat, s);
1418  }
1419  }
1420  else {
1421  float(*bbones_mat)[4][4] = eBone->disp_bbone_mat;
1422 
1423  if (bbone_segments > 1) {
1424  ebone_spline_preview(eBone, bbones_mat);
1425 
1426  for (int i = bbone_segments; i--; bbones_mat++) {
1427  mul_m4_m4m4(*bbones_mat, *bbones_mat, s);
1428  mul_m4_m4m4(*bbones_mat, bone_mat, *bbones_mat);
1429  }
1430  }
1431  else {
1432  mul_m4_m4m4(*bbones_mat, bone_mat, s);
1433  }
1434  }
1435 
1436  /* Grrr... We need default display matrix to draw end points, axes, etc. :( */
1438 }
1439 
1441 {
1442  float bone_scale[3];
1443  float(*bone_mat)[4];
1444  float(*disp_mat)[4];
1445  float(*disp_tail_mat)[4];
1446  float rot_mat[3][3];
1447 
1448  /* See TODO: above. */
1449  mul_v3_v3fl(bone_scale, pchan->custom_scale_xyz, PCHAN_CUSTOM_BONE_LENGTH(pchan));
1450  bone_mat = pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat;
1451  disp_mat = pchan->disp_mat;
1452  disp_tail_mat = pchan->disp_tail_mat;
1453 
1455 
1456  copy_m4_m4(disp_mat, bone_mat);
1457  translate_m4(disp_mat,
1458  pchan->custom_translation[0],
1459  pchan->custom_translation[1],
1460  pchan->custom_translation[2]);
1461  mul_m4_m4m3(disp_mat, disp_mat, rot_mat);
1462  rescale_m4(disp_mat, bone_scale);
1463  copy_m4_m4(disp_tail_mat, disp_mat);
1464  translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f);
1465 }
1466 
1468  const EditBone *eBone,
1469  const bPoseChannel *pchan,
1470  const bArmature *arm)
1471 {
1472  float final_col[4];
1473  const float *col = (ctx->const_color) ? ctx->const_color :
1474  (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? G_draw.block.color_text_hi :
1476  copy_v4_v4(final_col, col);
1477  /* Mix with axes color. */
1478  final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.1 : 0.65;
1479 
1480  if (pchan && pchan->custom && !(arm->flag & ARM_NO_CUSTOM)) {
1481  /* Special case: Custom bones can have different scale than the bone.
1482  * Recompute display matrix without the custom scaling applied. (T65640). */
1483  float axis_mat[4][4];
1484  float length = pchan->bone->length;
1485  copy_m4_m4(axis_mat, pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat);
1486  rescale_m4(axis_mat, (float[3]){length, length, length});
1487  translate_m4(axis_mat, 0.0, arm->axes_position - 1.0, 0.0);
1488 
1489  drw_shgroup_bone_axes(ctx, axis_mat, final_col);
1490  }
1491  else {
1492  float disp_mat[4][4];
1493  copy_m4_m4(disp_mat, BONE_VAR(eBone, pchan, disp_mat));
1494  translate_m4(disp_mat, 0.0, arm->axes_position - 1.0, 0.0);
1495  drw_shgroup_bone_axes(ctx, disp_mat, final_col);
1496  }
1497 }
1498 
1500  const EditBone *eBone,
1501  const bPoseChannel *pchan,
1502  const bArmature *arm,
1503  const int boneflag,
1504  const short constflag,
1505  const int select_id)
1506 {
1507  float col_solid_root[4], col_solid_tail[4], col_wire_root[4], col_wire_tail[4];
1508  float col_hint_root[4], col_hint_tail[4];
1509 
1510  copy_v4_v4(col_solid_root, G_draw.block.color_bone_solid);
1511  copy_v4_v4(col_solid_tail, G_draw.block.color_bone_solid);
1512  copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : G_draw.block.color_vertex);
1513  copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : G_draw.block.color_vertex);
1514 
1515  const bool is_envelope_draw = (arm->drawtype == ARM_ENVELOPE);
1516  const float envelope_ignore = -1.0f;
1517 
1518  col_wire_tail[3] = col_wire_root[3] = get_bone_wire_thickness(ctx, boneflag);
1519 
1520  /* Edit bone points can be selected */
1521  if (eBone) {
1522  if (eBone->flag & BONE_ROOTSEL) {
1523  copy_v3_v3(col_wire_root, G_draw.block.color_vertex_select);
1524  }
1525  if (eBone->flag & BONE_TIPSEL) {
1526  copy_v3_v3(col_wire_tail, G_draw.block.color_vertex_select);
1527  }
1528  }
1529  else if (arm->flag & ARM_POSEMODE) {
1530  const float *solid_color = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag);
1531  const float *wire_color = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1532  copy_v4_v4(col_wire_tail, wire_color);
1533  copy_v4_v4(col_wire_root, wire_color);
1534  copy_v4_v4(col_solid_tail, solid_color);
1535  copy_v4_v4(col_solid_root, solid_color);
1536  }
1537 
1538  bone_hint_color_shade(col_hint_root, (ctx->const_color) ? col_solid_root : col_wire_root);
1539  bone_hint_color_shade(col_hint_tail, (ctx->const_color) ? col_solid_tail : col_wire_tail);
1540 
1541  /* Draw root point if we are not connected to our parent */
1542  if (!(eBone ? (eBone->parent && (boneflag & BONE_CONNECTED)) :
1543  (pchan->bone->parent && (boneflag & BONE_CONNECTED)))) {
1544  if (select_id != -1) {
1545  DRW_select_load_id(select_id | BONESEL_ROOT);
1546  }
1547 
1548  if (eBone) {
1549  if (is_envelope_draw) {
1551  eBone->disp_mat,
1552  col_solid_root,
1553  col_hint_root,
1554  col_wire_root,
1555  &eBone->rad_head,
1556  &envelope_ignore);
1557  }
1558  else {
1559  drw_shgroup_bone_point(ctx, eBone->disp_mat, col_solid_root, col_hint_root, col_wire_root);
1560  }
1561  }
1562  else {
1563  Bone *bone = pchan->bone;
1564  if (is_envelope_draw) {
1566  pchan->disp_mat,
1567  col_solid_root,
1568  col_hint_root,
1569  col_wire_root,
1570  &bone->rad_head,
1571  &envelope_ignore);
1572  }
1573  else {
1574  drw_shgroup_bone_point(ctx, pchan->disp_mat, col_solid_root, col_hint_root, col_wire_root);
1575  }
1576  }
1577  }
1578 
1579  /* Draw tip point */
1580  if (select_id != -1) {
1581  DRW_select_load_id(select_id | BONESEL_TIP);
1582  }
1583 
1584  if (is_envelope_draw) {
1585  const float *rad_tail = eBone ? &eBone->rad_tail : &pchan->bone->rad_tail;
1587  BONE_VAR(eBone, pchan, disp_mat),
1588  col_solid_tail,
1589  col_hint_tail,
1590  col_wire_tail,
1591  &envelope_ignore,
1592  rad_tail);
1593  }
1594  else {
1596  ctx, BONE_VAR(eBone, pchan, disp_tail_mat), col_solid_tail, col_hint_tail, col_wire_tail);
1597  }
1598 
1599  if (select_id != -1) {
1600  DRW_select_load_id(-1);
1601  }
1602 }
1603 
1606 /* -------------------------------------------------------------------- */
1611  EditBone *eBone,
1612  bPoseChannel *pchan,
1613  bArmature *arm,
1614  const int boneflag,
1615  const short constflag,
1616  const int select_id)
1617 {
1618  const float *col_solid = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag);
1619  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1620  const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag);
1621  const float(*disp_mat)[4] = pchan->disp_mat;
1622 
1623  if (select_id != -1) {
1624  DRW_select_load_id(select_id | BONESEL_BONE);
1625  }
1626 
1627  if (pchan->custom->type == OB_EMPTY) {
1628  Object *ob = pchan->custom;
1629  if (ob->empty_drawtype != OB_EMPTY_IMAGE) {
1630  drw_shgroup_bone_custom_empty(ctx, disp_mat, col_wire, pchan->custom);
1631  }
1632  }
1633  if ((boneflag & BONE_DRAWWIRE) == 0 && (boneflag & BONE_DRAW_LOCKED_WEIGHT) == 0) {
1634  drw_shgroup_bone_custom_solid(ctx, disp_mat, col_solid, col_hint, col_wire, pchan->custom);
1635  }
1636  else {
1637  drw_shgroup_bone_custom_wire(ctx, disp_mat, col_wire, pchan->custom);
1638  }
1639 
1640  if (select_id != -1) {
1641  DRW_select_load_id(-1);
1642  }
1643 }
1644 
1646  EditBone *eBone,
1647  bPoseChannel *pchan,
1648  bArmature *arm,
1649  const int boneflag,
1650  const short constflag,
1651  const int select_id)
1652 {
1653  const float *col_solid = get_bone_solid_with_consts_color(
1654  ctx, eBone, pchan, arm, boneflag, constflag);
1655  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1656  const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag);
1657 
1658  float *rad_head, *rad_tail, *distance;
1659  if (eBone) {
1660  rad_tail = &eBone->rad_tail;
1661  distance = &eBone->dist;
1662  rad_head = (eBone->parent && (boneflag & BONE_CONNECTED)) ? &eBone->parent->rad_tail :
1663  &eBone->rad_head;
1664  }
1665  else {
1666  rad_tail = &pchan->bone->rad_tail;
1667  distance = &pchan->bone->dist;
1668  rad_head = (pchan->parent && (boneflag & BONE_CONNECTED)) ? &pchan->parent->bone->rad_tail :
1669  &pchan->bone->rad_head;
1670  }
1671 
1672  if ((select_id == -1) && (boneflag & BONE_NO_DEFORM) == 0 &&
1673  ((boneflag & BONE_SELECTED) || (eBone && (boneflag & (BONE_ROOTSEL | BONE_TIPSEL))))) {
1675  ctx, BONE_VAR(eBone, pchan, disp_mat), rad_head, rad_tail, distance);
1676  }
1677 
1678  if (select_id != -1) {
1679  DRW_select_load_id(select_id | BONESEL_BONE);
1680  }
1681 
1683  ctx, BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire, rad_head, rad_tail);
1684 
1685  if (select_id != -1) {
1686  DRW_select_load_id(-1);
1687  }
1688 
1689  draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id);
1690 }
1691 
1693  EditBone *eBone,
1694  bPoseChannel *pchan,
1695  bArmature *arm,
1696  const int boneflag,
1697  const short constflag,
1698  const int select_id)
1699 {
1700  const float *col_bone = get_bone_solid_with_consts_color(
1701  ctx, eBone, pchan, arm, boneflag, constflag);
1702  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1703  const float no_display[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1704  const float *col_head = no_display;
1705  const float *col_tail = col_bone;
1706 
1707  if (ctx->const_color != NULL) {
1708  col_wire = no_display; /* actually shrink the display. */
1709  col_bone = col_head = col_tail = ctx->const_color;
1710  }
1711  else {
1712  if (eBone) {
1713  if (eBone->flag & BONE_TIPSEL) {
1714  col_tail = G_draw.block.color_vertex_select;
1715  }
1716  if (boneflag & BONE_SELECTED) {
1717  col_bone = G_draw.block.color_bone_active;
1718  }
1719  col_wire = G_draw.block.color_wire;
1720  }
1721 
1722  /* Draw root point if we are not connected to our parent. */
1723  if (!(eBone ? (eBone->parent && (boneflag & BONE_CONNECTED)) :
1724  (pchan->bone->parent && (boneflag & BONE_CONNECTED)))) {
1725 
1726  if (eBone) {
1727  col_head = (eBone->flag & BONE_ROOTSEL) ? G_draw.block.color_vertex_select : col_bone;
1728  }
1729  else {
1730  col_head = col_bone;
1731  }
1732  }
1733  }
1734 
1735  if (select_id == -1) {
1736  /* Not in selection mode, draw everything at once. */
1738  ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, col_head, col_tail);
1739  }
1740  else {
1741  /* In selection mode, draw bone, root and tip separately. */
1742  DRW_select_load_id(select_id | BONESEL_BONE);
1744  ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, no_display, no_display);
1745 
1746  if (col_head[3] > 0.0f) {
1747  DRW_select_load_id(select_id | BONESEL_ROOT);
1749  ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, col_head, no_display);
1750  }
1751 
1752  DRW_select_load_id(select_id | BONESEL_TIP);
1754  ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, no_display, col_tail);
1755 
1756  DRW_select_load_id(-1);
1757  }
1758 }
1759 
1761  EditBone *eBone,
1762  bPoseChannel *pchan,
1763  bArmature *arm,
1764  const int boneflag,
1765  const short constflag,
1766  const int select_id)
1767 {
1768  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1769 
1770  if (select_id != -1) {
1771  DRW_select_load_id(select_id | BONESEL_BONE);
1772  }
1773 
1774  if (pchan) {
1775  Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
1776  BLI_assert(bbones_mat != NULL);
1777 
1778  for (int i = pchan->bone->segments; i--; bbones_mat++) {
1779  drw_shgroup_bone_wire(ctx, bbones_mat->mat, col_wire);
1780  }
1781  }
1782  else if (eBone) {
1783  for (int i = 0; i < eBone->segments; i++) {
1784  drw_shgroup_bone_wire(ctx, eBone->disp_bbone_mat[i], col_wire);
1785  }
1786  }
1787 
1788  if (select_id != -1) {
1789  DRW_select_load_id(-1);
1790  }
1791 
1792  if (eBone) {
1793  draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id);
1794  }
1795 }
1796 
1798  EditBone *eBone,
1799  bPoseChannel *pchan,
1800  bArmature *arm,
1801  const int boneflag,
1802  const short constflag,
1803  const int select_id)
1804 {
1805  const float *col_solid = get_bone_solid_with_consts_color(
1806  ctx, eBone, pchan, arm, boneflag, constflag);
1807  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1808  const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag);
1809 
1810  if (select_id != -1) {
1811  DRW_select_load_id(select_id | BONESEL_BONE);
1812  }
1813 
1814  if (pchan) {
1815  Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
1816  BLI_assert(bbones_mat != NULL);
1817 
1818  for (int i = pchan->bone->segments; i--; bbones_mat++) {
1819  drw_shgroup_bone_box(ctx, bbones_mat->mat, col_solid, col_hint, col_wire);
1820  }
1821  }
1822  else if (eBone) {
1823  for (int i = 0; i < eBone->segments; i++) {
1824  drw_shgroup_bone_box(ctx, eBone->disp_bbone_mat[i], col_solid, col_hint, col_wire);
1825  }
1826  }
1827 
1828  if (select_id != -1) {
1829  DRW_select_load_id(-1);
1830  }
1831 
1832  if (eBone) {
1833  draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id);
1834  }
1835 }
1836 
1838  EditBone *eBone,
1839  bPoseChannel *pchan,
1840  bArmature *arm,
1841  const int boneflag,
1842  const short constflag,
1843  const int select_id)
1844 {
1845  const float *col_solid = get_bone_solid_with_consts_color(
1846  ctx, eBone, pchan, arm, boneflag, constflag);
1847  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1848  const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag);
1849 
1850  if (select_id != -1) {
1851  DRW_select_load_id(select_id | BONESEL_BONE);
1852  }
1853 
1855  ctx, BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire);
1856 
1857  if (select_id != -1) {
1858  DRW_select_load_id(-1);
1859  }
1860 
1861  draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id);
1862 }
1863 
1866 /* -------------------------------------------------------------------- */
1871 {
1872  BoneInstanceData inst_data;
1873  float tmp[4][4], posetrans[4][4];
1874  float xminmax[2], zminmax[2];
1875  float color[4];
1876 
1877  if (ctx->dof_sphere == NULL) {
1878  return;
1879  }
1880 
1881  /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
1882  xminmax[0] = sinf(pchan->limitmin[0] * 0.5f);
1883  xminmax[1] = sinf(pchan->limitmax[0] * 0.5f);
1884  zminmax[0] = sinf(pchan->limitmin[2] * 0.5f);
1885  zminmax[1] = sinf(pchan->limitmax[2] * 0.5f);
1886 
1887  unit_m4(posetrans);
1888  translate_m4(posetrans, pchan->pose_mat[3][0], pchan->pose_mat[3][1], pchan->pose_mat[3][2]);
1889  /* In parent-bone pose space... */
1890  if (pchan->parent) {
1891  copy_m4_m4(tmp, pchan->parent->pose_mat);
1892  zero_v3(tmp[3]);
1893  mul_m4_m4m4(posetrans, posetrans, tmp);
1894  }
1895  /* ... but own rest-space. */
1896  mul_m4_m4m3(posetrans, posetrans, pchan->bone->bone_mat);
1897 
1898  float scale = pchan->bone->length * pchan->size[1];
1899  scale_m4_fl(tmp, scale);
1900  tmp[1][1] = -tmp[1][1];
1901  mul_m4_m4m4(posetrans, posetrans, tmp);
1902 
1903  /* into world space. */
1904  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, posetrans);
1905 
1906  if ((pchan->ikflag & BONE_IK_XLIMIT) && (pchan->ikflag & BONE_IK_ZLIMIT)) {
1908  &inst_data, xminmax[0], zminmax[0], xminmax[1], zminmax[1]);
1909 
1910  copy_v4_fl4(color, 0.25f, 0.25f, 0.25f, 0.25f);
1911  DRW_buffer_add_entry(ctx->dof_sphere, color, &inst_data);
1912 
1913  copy_v4_fl4(color, 0.0f, 0.0f, 0.0f, 1.0f);
1914  DRW_buffer_add_entry(ctx->dof_lines, color, &inst_data);
1915  }
1916  if (pchan->ikflag & BONE_IK_XLIMIT) {
1917  bone_instance_data_set_angle_minmax(&inst_data, xminmax[0], 0.0f, xminmax[1], 0.0f);
1918  copy_v4_fl4(color, 1.0f, 0.0f, 0.0f, 1.0f);
1919  DRW_buffer_add_entry(ctx->dof_lines, color, &inst_data);
1920  }
1921  if (pchan->ikflag & BONE_IK_ZLIMIT) {
1922  bone_instance_data_set_angle_minmax(&inst_data, 0.0f, zminmax[0], 0.0f, zminmax[1]);
1923  copy_v4_fl4(color, 0.0f, 0.0f, 1.0f, 1.0f);
1924  DRW_buffer_add_entry(ctx->dof_lines, color, &inst_data);
1925  }
1926 }
1927 
1930 /* -------------------------------------------------------------------- */
1935  bPoseChannel *pchan,
1936  const bool only_temp,
1937  const int constflag)
1938 {
1939  bConstraint *con;
1940  bPoseChannel *parchan;
1941  float *line_start = NULL, *line_end = NULL;
1942 
1943  for (con = pchan->constraints.first; con; con = con->next) {
1944  if (con->enforce == 0.0f) {
1945  continue;
1946  }
1947 
1948  switch (con->type) {
1951  int segcount = 0;
1952 
1953  /* if only_temp, only draw if it is a temporary ik-chain */
1954  if (only_temp && !(data->flag & CONSTRAINT_IK_TEMP)) {
1955  continue;
1956  }
1957 
1958  /* exclude tip from chain? */
1959  parchan = ((data->flag & CONSTRAINT_IK_TIP) == 0) ? pchan->parent : pchan;
1960  line_start = parchan->pose_tail;
1961 
1962  /* Find the chain's root */
1963  while (parchan->parent) {
1964  segcount++;
1965  if (segcount == data->rootbone || segcount > 255) {
1966  break; /* 255 is weak */
1967  }
1968  parchan = parchan->parent;
1969  }
1970 
1971  if (parchan) {
1972  line_end = parchan->pose_head;
1973 
1974  if (constflag & PCHAN_HAS_TARGET) {
1975  drw_shgroup_bone_ik_lines(ctx, line_start, line_end);
1976  }
1977  else {
1978  drw_shgroup_bone_ik_no_target_lines(ctx, line_start, line_end);
1979  }
1980  }
1981  break;
1982  }
1983  case CONSTRAINT_TYPE_SPLINEIK: {
1985  int segcount = 0;
1986 
1987  /* don't draw if only_temp, as Spline IK chains cannot be temporary */
1988  if (only_temp) {
1989  continue;
1990  }
1991 
1992  parchan = pchan;
1993  line_start = parchan->pose_tail;
1994 
1995  /* Find the chain's root */
1996  while (parchan->parent) {
1997  segcount++;
1998  /* FIXME: revise the breaking conditions */
1999  if (segcount == data->chainlen || segcount > 255) {
2000  break; /* 255 is weak */
2001  }
2002  parchan = parchan->parent;
2003  }
2004  /* Only draw line in case our chain is more than one bone long! */
2005  if (parchan != pchan) { /* XXX revise the breaking conditions to only stop at the tail? */
2006  line_end = parchan->pose_head;
2007  drw_shgroup_bone_ik_spline_lines(ctx, line_start, line_end);
2008  }
2009  break;
2010  }
2011  }
2012  }
2013 }
2014 
2016  EditBone *ebone,
2017  bPoseChannel *pchan,
2018  bArmature *arm,
2019  const int boneflag,
2020  const short constflag)
2021 {
2022  if (ebone && ebone->parent) {
2023  if (ctx->do_relations) {
2024  /* Always draw for unconnected bones, regardless of selection,
2025  * since riggers will want to know about the links between bones
2026  */
2027  if ((boneflag & BONE_CONNECTED) == 0) {
2028  drw_shgroup_bone_relationship_lines(ctx, ebone->head, ebone->parent->tail);
2029  }
2030  }
2031  }
2032  else if (pchan && pchan->parent) {
2033  if (ctx->do_relations) {
2034  /* Only draw if bone or its parent is selected - reduces viewport complexity with complex
2035  * rigs */
2036  if ((boneflag & BONE_SELECTED) ||
2037  (pchan->parent->bone && (pchan->parent->bone->flag & BONE_SELECTED))) {
2038  if ((boneflag & BONE_CONNECTED) == 0) {
2040  }
2041  }
2042  }
2043 
2044  /* Draw a line to IK root bone if bone is selected. */
2045  if (arm->flag & ARM_POSEMODE) {
2046  if (constflag & (PCHAN_HAS_IK | PCHAN_HAS_SPLINEIK)) {
2047  if (boneflag & BONE_SELECTED) {
2048  pchan_draw_ik_lines(ctx, pchan, !ctx->do_relations, constflag);
2049  }
2050  }
2051  }
2052  }
2053 }
2054 
2056  EditBone *eBone,
2057  bPoseChannel *pchan,
2058  bArmature *arm,
2059  const int boneflag)
2060 {
2061  struct DRWTextStore *dt = DRW_text_cache_ensure();
2062  uchar color[4];
2063  float vec[3];
2064 
2065  bool highlight = (pchan && (arm->flag & ARM_POSEMODE) && (boneflag & BONE_SELECTED)) ||
2066  (eBone && (eBone->flag & BONE_SELECTED));
2067 
2068  /* Color Management: Exception here as texts are drawn in sRGB space directly. */
2069  UI_GetThemeColor4ubv(highlight ? TH_TEXT_HI : TH_TEXT, color);
2070 
2071  float *head = pchan ? pchan->pose_head : eBone->head;
2072  float *tail = pchan ? pchan->pose_tail : eBone->tail;
2073  mid_v3_v3v3(vec, head, tail);
2074  mul_m4_v3(ctx->ob->obmat, vec);
2075 
2076  DRW_text_cache_add(dt,
2077  vec,
2078  (pchan) ? pchan->name : eBone->name,
2079  (pchan) ? strlen(pchan->name) : strlen(eBone->name),
2080  10,
2081  0,
2083  color);
2084 }
2085 
2088 /* -------------------------------------------------------------------- */
2099 static void pchan_culling_calc_bsphere(const Object *ob,
2100  const bPoseChannel *pchan,
2101  BoundSphere *r_bsphere)
2102 {
2103  float min[3], max[3];
2104  INIT_MINMAX(min, max);
2105  BKE_pchan_minmax(ob, pchan, true, min, max);
2106  mid_v3_v3v3(r_bsphere->center, min, max);
2107  r_bsphere->radius = len_v3v3(min, r_bsphere->center);
2108 }
2109 
2115  const Object *ob,
2116  const bPoseChannel *pchan)
2117 {
2118  BoundSphere bsphere;
2119  pchan_culling_calc_bsphere(ob, pchan, &bsphere);
2120  return DRW_culling_sphere_test(view, &bsphere);
2121 }
2122 
2124  const Object *ob,
2125  const bPoseChannel *pchan,
2126  const float scale)
2127 {
2128  BoundSphere bsphere;
2129  pchan_culling_calc_bsphere(ob, pchan, &bsphere);
2130  bsphere.radius *= scale;
2131  return DRW_culling_sphere_test(view, &bsphere);
2132 }
2133 
2135  const Object *ob,
2136  const bPoseChannel *pchan)
2137 {
2138  /* For more aggressive culling the bounding box of the custom-object could be used. */
2139  return pchan_culling_test_simple(view, ob, pchan);
2140 }
2141 
2143  const Object *ob,
2144  const bPoseChannel *pchan)
2145 {
2146  BLI_assert(((const bArmature *)ob->data)->drawtype == ARM_WIRE);
2147  return pchan_culling_test_simple(view, ob, pchan);
2148 }
2149 
2151  const Object *ob,
2152  const bPoseChannel *pchan)
2153 {
2154  BLI_assert(((const bArmature *)ob->data)->drawtype == ARM_LINE);
2155  /* Account for the end-points, as the line end-points size is in pixels, this is a rough value.
2156  * Since the end-points are small the difference between having any margin or not is unlikely
2157  * to be noticeable. */
2158  const float scale = 1.1f;
2159  return pchan_culling_test_with_radius_scale(view, ob, pchan, scale);
2160 }
2161 
2163  const Object *ob,
2164  const bPoseChannel *pchan)
2165 {
2166  const bArmature *arm = ob->data;
2167  BLI_assert(arm->drawtype == ARM_ENVELOPE);
2168  UNUSED_VARS_NDEBUG(arm);
2169  BoundSphere bsphere;
2170  pchan_culling_calc_bsphere(ob, pchan, &bsphere);
2171  bsphere.radius += max_ff(pchan->bone->rad_head, pchan->bone->rad_tail) *
2173  return DRW_culling_sphere_test(view, &bsphere);
2174 }
2175 
2177  const Object *ob,
2178  const bPoseChannel *pchan)
2179 {
2180  const bArmature *arm = ob->data;
2181  BLI_assert(arm->drawtype == ARM_B_BONE);
2182  UNUSED_VARS_NDEBUG(arm);
2183  const float ob_scale = mat4_to_size_max_axis(ob->obmat);
2184  const Mat4 *bbones_mat = (const Mat4 *)pchan->draw_data->bbone_matrix;
2185  for (int i = pchan->bone->segments; i--; bbones_mat++) {
2186  BoundSphere bsphere;
2187  float size[3];
2188  mat4_to_size(size, bbones_mat->mat);
2189  mul_v3_m4v3(bsphere.center, ob->obmat, bbones_mat->mat[3]);
2190  bsphere.radius = len_v3(size) * ob_scale;
2191  if (DRW_culling_sphere_test(view, &bsphere)) {
2192  return true;
2193  }
2194  }
2195  return false;
2196 }
2197 
2199  const Object *ob,
2200  const bPoseChannel *pchan)
2201 {
2202  /* No type assertion as this is a fallback (files from the future will end up here). */
2203  /* Account for spheres on the end-points. */
2204  const float scale = 1.2f;
2205  return pchan_culling_test_with_radius_scale(view, ob, pchan, scale);
2206 }
2207 
2210 /* -------------------------------------------------------------------- */
2215 {
2216  Object *ob = ctx->ob;
2217  EditBone *eBone;
2218  int index;
2219  const bool is_select = DRW_state_is_select();
2220  const bool show_text = DRW_state_show_text();
2221 
2222  const Object *ob_orig = DEG_get_original_object(ob);
2223  /* FIXME(campbell): We should be able to use the CoW object,
2224  * however the active bone isn't updated. Long term solution is an 'EditArmature' struct.
2225  * for now we can draw from the original armature. See: T66773. */
2226  // bArmature *arm = ob->data;
2227  bArmature *arm = ob_orig->data;
2228 
2230 
2231  for (eBone = arm->edbo->first, index = ob_orig->runtime.select_id; eBone;
2232  eBone = eBone->next, index += 0x10000) {
2233  if (eBone->layer & arm->layer) {
2234  if ((eBone->flag & BONE_HIDDEN_A) == 0) {
2235  const int select_id = is_select ? index : (uint)-1;
2236  const short constflag = 0;
2237 
2238  /* catch exception for bone with hidden parent */
2239  int boneflag = eBone->flag;
2240  if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) {
2241  boneflag &= ~BONE_CONNECTED;
2242  }
2243 
2244  /* set temporary flag for drawing bone as active, but only if selected */
2245  if (eBone == arm->act_edbone) {
2246  boneflag |= BONE_DRAW_ACTIVE;
2247  }
2248 
2249  boneflag &= ~BONE_DRAW_LOCKED_WEIGHT;
2250 
2251  if (!is_select) {
2252  draw_bone_relations(ctx, eBone, NULL, arm, boneflag, constflag);
2253  }
2254 
2255  if (arm->drawtype == ARM_ENVELOPE) {
2257  draw_bone_envelope(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
2258  }
2259  else if (arm->drawtype == ARM_LINE) {
2261  draw_bone_line(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
2262  }
2263  else if (arm->drawtype == ARM_WIRE) {
2265  draw_bone_wire(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
2266  }
2267  else if (arm->drawtype == ARM_B_BONE) {
2269  draw_bone_box(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
2270  }
2271  else {
2273  draw_bone_octahedral(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
2274  }
2275 
2276  if (!is_select) {
2277  if (show_text && (arm->flag & ARM_DRAWNAMES)) {
2278  draw_bone_name(ctx, eBone, NULL, arm, boneflag);
2279  }
2280 
2281  if (arm->flag & ARM_DRAWAXES) {
2282  draw_axes(ctx, eBone, NULL, arm);
2283  }
2284  }
2285  }
2286  }
2287  }
2288 }
2289 
2291 {
2292  Object *ob = ctx->ob;
2293  const DRWContextState *draw_ctx = DRW_context_state_get();
2294  const Scene *scene = draw_ctx->scene;
2295  bArmature *arm = ob->data;
2296  bPoseChannel *pchan;
2297  int index = -1;
2298  const bool show_text = DRW_state_show_text();
2299  bool draw_locked_weights = false;
2300 
2301  /* We can't safely draw non-updated pose, might contain NULL bone pointers... */
2302  if (ob->pose->flag & POSE_RECALC) {
2303  return;
2304  }
2305 
2306  bool is_pose_select = false;
2307  /* Object can be edited in the scene. */
2308  if ((ob->base_flag & (BASE_FROM_SET | BASE_FROM_DUPLI)) == 0) {
2309  if ((draw_ctx->object_mode & OB_MODE_POSE) || (ob == draw_ctx->object_pose)) {
2310  arm->flag |= ARM_POSEMODE;
2311  }
2312  is_pose_select =
2313  /* If we're in pose-mode or object-mode with the ability to enter pose mode. */
2314  (
2315  /* Draw as if in pose mode (when selection is possible). */
2316  (arm->flag & ARM_POSEMODE) ||
2317  /* When we're in object mode, which may select bones. */
2318  ((ob->mode & OB_MODE_POSE) &&
2319  (
2320  /* Switch from object mode when object lock is disabled. */
2321  ((draw_ctx->object_mode == OB_MODE_OBJECT) &&
2323  /* Allow selection when in weight-paint mode
2324  * (selection code ensures this won't become active). */
2325  ((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) &&
2326  (draw_ctx->object_pose != NULL))))) &&
2328 
2329  if (is_pose_select) {
2330  const Object *ob_orig = DEG_get_original_object(ob);
2331  index = ob_orig->runtime.select_id;
2332  }
2333  }
2334 
2335  /* In weight paint mode retrieve the vertex group lock status. */
2336  if ((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) && (draw_ctx->object_pose == ob) &&
2337  (draw_ctx->obact != NULL)) {
2338  draw_locked_weights = true;
2339 
2340  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
2341  pchan->bone->flag &= ~BONE_DRAW_LOCKED_WEIGHT;
2342  }
2343 
2344  const Object *obact_orig = DEG_get_original_object(draw_ctx->obact);
2345 
2346  const ListBase *defbase = BKE_object_defgroup_list(obact_orig);
2347  LISTBASE_FOREACH (const bDeformGroup *, dg, defbase) {
2348  if (dg->flag & DG_LOCK_WEIGHT) {
2349  pchan = BKE_pose_channel_find_name(ob->pose, dg->name);
2350 
2351  if (pchan) {
2352  pchan->bone->flag |= BONE_DRAW_LOCKED_WEIGHT;
2353  }
2354  }
2355  }
2356  }
2357 
2358  const DRWView *view = is_pose_select ? DRW_view_default_get() : NULL;
2359 
2360  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, index += 0x10000) {
2361  Bone *bone = pchan->bone;
2362  const bool bone_visible = (bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0;
2363 
2364  if (bone_visible) {
2365  if (bone->layer & arm->layer) {
2366  const bool draw_dofs = !is_pose_select && ctx->show_relations &&
2367  (arm->flag & ARM_POSEMODE) && (bone->flag & BONE_SELECTED) &&
2368  ((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
2369  (pchan->ikflag & (BONE_IK_XLIMIT | BONE_IK_ZLIMIT));
2370  const int select_id = is_pose_select ? index : (uint)-1;
2371  const short constflag = pchan->constflag;
2372 
2373  pchan_draw_data_init(pchan);
2374 
2375  if (!ctx->const_color) {
2376  set_pchan_colorset(ctx, ob, pchan);
2377  }
2378 
2379  /* catch exception for bone with hidden parent */
2380  int boneflag = bone->flag;
2381  if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) {
2382  boneflag &= ~BONE_CONNECTED;
2383  }
2384 
2385  /* set temporary flag for drawing bone as active, but only if selected */
2386  if (bone == arm->act_bone) {
2387  boneflag |= BONE_DRAW_ACTIVE;
2388  }
2389 
2390  if (!draw_locked_weights) {
2391  boneflag &= ~BONE_DRAW_LOCKED_WEIGHT;
2392  }
2393 
2394  if (!is_pose_select) {
2395  draw_bone_relations(ctx, NULL, pchan, arm, boneflag, constflag);
2396  }
2397 
2398  if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
2400  if (!is_pose_select || pchan_culling_test_custom(view, ob, pchan)) {
2401  draw_bone_custom_shape(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2402  }
2403  }
2404  else if (arm->drawtype == ARM_ENVELOPE) {
2406  if (!is_pose_select || pchan_culling_test_envelope(view, ob, pchan)) {
2407  draw_bone_envelope(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2408  }
2409  }
2410  else if (arm->drawtype == ARM_LINE) {
2412  if (!is_pose_select || pchan_culling_test_line(view, ob, pchan)) {
2413  draw_bone_line(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2414  }
2415  }
2416  else if (arm->drawtype == ARM_WIRE) {
2418  if (!is_pose_select || pchan_culling_test_wire(view, ob, pchan)) {
2419  draw_bone_wire(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2420  }
2421  }
2422  else if (arm->drawtype == ARM_B_BONE) {
2424  if (!is_pose_select || pchan_culling_test_bbone(view, ob, pchan)) {
2425  draw_bone_box(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2426  }
2427  }
2428  else {
2430  if (!is_pose_select || pchan_culling_test_octohedral(view, ob, pchan)) {
2431  draw_bone_octahedral(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2432  }
2433  }
2434 
2435  /* These aren't included in the selection. */
2436  if (!is_pose_select) {
2437  if (draw_dofs) {
2438  draw_bone_degrees_of_freedom(ctx, pchan);
2439  }
2440 
2441  if (show_text && (arm->flag & ARM_DRAWNAMES)) {
2442  draw_bone_name(ctx, NULL, pchan, arm, boneflag);
2443  }
2444 
2445  if (arm->flag & ARM_DRAWAXES) {
2446  draw_axes(ctx, NULL, pchan, arm);
2447  }
2448  }
2449  }
2450  }
2451  }
2452 
2453  arm->flag &= ~ARM_POSEMODE;
2454 }
2455 
2457  OVERLAY_PrivateData *pd,
2458  Object *ob,
2459  const bool do_envelope_dist,
2460  const bool is_edit_mode,
2461  const bool is_pose_mode,
2462  const float *const_color)
2463 {
2464  const bool is_object_mode = !do_envelope_dist;
2465  const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0 ||
2466  (pd->armature.do_pose_xray && is_pose_mode);
2467  const bool draw_as_wire = (ob->dt < OB_SOLID);
2468  const bool is_filled = (!pd->armature.transparent && !draw_as_wire) || !is_object_mode;
2469  const bool is_transparent = pd->armature.transparent || (draw_as_wire && !is_object_mode);
2470  bArmature *arm = ob->data;
2472  OVERLAY_ArmatureCallBuffersInner *cb = is_transparent ? &cbo->transp : &cbo->solid;
2473 
2474  static const float select_const_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2475 
2476  switch (arm->drawtype) {
2477  case ARM_ENVELOPE:
2479  ctx->envelope_solid = (is_filled) ? cb->envelope_fill : NULL;
2480  ctx->envelope_distance = (do_envelope_dist) ? cb->envelope_distance : NULL;
2481  break;
2482  case ARM_LINE:
2483  ctx->stick = cb->stick;
2484  break;
2485  case ARM_WIRE:
2486  ctx->wire = cb->wire;
2487  break;
2488  case ARM_B_BONE:
2489  ctx->outline = cb->box_outline;
2490  ctx->solid = (is_filled) ? cb->box_fill : NULL;
2491  break;
2492  case ARM_OCTA:
2493  ctx->outline = cb->octa_outline;
2494  ctx->solid = (is_filled) ? cb->octa_fill : NULL;
2495  break;
2496  }
2497  ctx->ob = ob;
2498  ctx->extras = &pd->extra_call_buffers[is_xray];
2499  ctx->dof_lines = cb->dof_lines;
2500  ctx->dof_sphere = cb->dof_sphere;
2501  ctx->point_solid = (is_filled) ? cb->point_fill : NULL;
2502  ctx->point_outline = cb->point_outline;
2503  ctx->custom_solid = (is_filled) ? cb->custom_fill : NULL;
2504  ctx->custom_outline = cb->custom_outline;
2505  ctx->custom_wire = cb->custom_wire;
2509  (is_edit_mode | is_pose_mode);
2510  ctx->const_color = DRW_state_is_select() ? select_const_color : const_color;
2511  ctx->const_wire = ((((ob->base_flag & BASE_SELECTED) && (pd->v3d_flag & V3D_SELECT_OUTLINE)) ||
2512  (arm->drawtype == ARM_WIRE)) ?
2513  1.5f :
2514  ((!is_filled || is_transparent) ? 1.0f : 0.0f));
2515 }
2516 
2518 {
2519  OVERLAY_PrivateData *pd = vedata->stl->pd;
2520  ArmatureDrawContext arm_ctx;
2521  armature_context_setup(&arm_ctx, pd, ob, true, true, false, NULL);
2522  draw_armature_edit(&arm_ctx);
2523 }
2524 
2526 {
2527  OVERLAY_PrivateData *pd = vedata->stl->pd;
2528  ArmatureDrawContext arm_ctx;
2529  armature_context_setup(&arm_ctx, pd, ob, true, false, true, NULL);
2530  draw_armature_pose(&arm_ctx);
2531 }
2532 
2534 {
2535  const DRWContextState *draw_ctx = DRW_context_state_get();
2536  OVERLAY_PrivateData *pd = vedata->stl->pd;
2537  ArmatureDrawContext arm_ctx;
2538  float *color;
2539 
2540  if (ob->dt == OB_BOUNDBOX) {
2541  return;
2542  }
2543 
2544  DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
2545  armature_context_setup(&arm_ctx, pd, ob, false, false, false, color);
2546  draw_armature_pose(&arm_ctx);
2547 }
2548 
2550 {
2552  if (ob_arm) {
2553  const DRWContextState *draw_ctx = DRW_context_state_get();
2554  bool is_active = OVERLAY_armature_is_pose_mode(ob_arm, draw_ctx);
2555  return is_active;
2556  }
2557 
2558  Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob);
2559  if (ob_mesh_deform) {
2560  /* Recursive. */
2561  return POSE_is_driven_by_active_armature(ob_mesh_deform);
2562  }
2563 
2564  return false;
2565 }
2566 
2568 {
2569  OVERLAY_PrivateData *pd = vedata->stl->pd;
2570 
2571  struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
2572  if (geom) {
2575  }
2576  else {
2578  }
2579  }
2580 }
2581 
2583 {
2584  OVERLAY_PrivateData *pd = vedata->stl->pd;
2585 
2586  for (int i = 0; i < 2; i++) {
2588  /* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */
2591  }
2592  }
2593 }
2594 
2596 {
2597  OVERLAY_PassList *psl = vedata->psl;
2598 
2600  DRW_draw_pass(psl->armature_ps[0]);
2601 }
2602 
2604 {
2605  OVERLAY_PassList *psl = vedata->psl;
2606 
2609  DRW_draw_pass(psl->armature_ps[1]);
2610  }
2611 }
2612 
2614 {
2615  OVERLAY_PassList *psl = vedata->psl;
2616  OVERLAY_FramebufferList *fbl = vedata->fbl;
2617 
2618  if (psl->armature_bone_select_ps != NULL) {
2619  if (DRW_state_is_fbo()) {
2621  }
2622 
2624 
2625  if (DRW_state_is_fbo()) {
2627  GPU_framebuffer_clear_depth(fbl->overlay_line_in_front_fb, 1.0f);
2628  }
2629 
2631  DRW_draw_pass(psl->armature_ps[1]);
2632  }
2633 }
2634 
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
#define MAX_BBONE_SUBDIV
Definition: BKE_armature.h:461
void BKE_pchan_minmax(const struct Object *ob, const struct bPoseChannel *pchan, const bool use_empty_drawtype, float r_min[3], float r_max[3])
void BKE_pchan_bbone_spline_setup(struct bPoseChannel *pchan, bool rest, bool for_deform, Mat4 *result_array)
Definition: armature.c:1178
int BKE_pchan_bbone_spline_compute(struct BBoneSplineParameters *param, bool for_deform, Mat4 *result_array)
Definition: armature.c:1350
support for deformation groups and hooks.
const struct ListBase * BKE_object_defgroup_list(const struct Object *ob)
struct Object * BKE_modifiers_is_deformed_by_armature(struct Object *ob)
struct Object * BKE_modifiers_is_deformed_by_meshdeform(struct Object *ob)
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh_no_subsurf(const struct Object *object)
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_INLINE
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE float clamp_f(float value, float min, float max)
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
Definition: math_color.c:376
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
bool invert_m4(float R[4][4])
Definition: math_matrix.c:1206
void mul_m4_v4(const float M[4][4], float r[4])
Definition: math_matrix.c:862
void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3])
Definition: math_matrix.c:434
void unit_m4(float m[4][4])
Definition: rct.c:1090
void translate_m4(float mat[4][4], float tx, float ty, float tz)
Definition: math_matrix.c:2318
void rescale_m4(float mat[4][4], const float scale[3])
Definition: math_matrix.c:2362
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2111
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void scale_m4_fl(float R[4][4], float scale)
Definition: math_matrix.c:2297
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
float mat4_to_size_max_axis(const float M[4][4])
Definition: math_matrix.c:2150
float mat4_to_scale(const float M[4][4])
Definition: math_matrix.c:2185
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2138
void eulO_to_mat3(float mat[3][3], const float eul[3], short order)
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
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3_uchar(unsigned char r[3], const unsigned char a[3])
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)
Definition: math_vector.c:38
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:29
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:237
MINLINE void copy_v3_fl(float r[3], float f)
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 len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
#define INIT_MINMAX(min, max)
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define ELEM(...)
struct Object * DEG_get_original_object(struct Object *object)
#define PCHAN_CUSTOM_BONE_LENGTH(pchan)
@ ROT_MODE_XYZ
@ BONE_IK_ZLIMIT
@ BONE_IK_XLIMIT
@ PCHAN_HAS_CONST
@ PCHAN_HAS_IK
@ PCHAN_HAS_TARGET
@ PCHAN_HAS_SPLINEIK
@ POSE_RECALC
@ BBONE_HANDLE_AUTO
@ BBONE_HANDLE_TANGENT
@ BBONE_HANDLE_RELATIVE
@ BONE_DRAW_LOCKED_WEIGHT
@ BONE_ROOTSEL
@ BONE_DRAWWIRE
@ BONE_SELECTED
@ BONE_HIDDEN_A
@ BONE_HIDDEN_P
@ BONE_DRAW_ACTIVE
@ BONE_TIPSEL
@ BONE_NO_DEFORM
@ BONE_CONNECTED
@ BONE_HIDDEN_PG
@ ARM_NO_CUSTOM
@ ARM_COL_CUSTOM
@ ARM_POSEMODE
@ ARM_DRAWNAMES
@ ARM_DRAWAXES
@ ARM_OCTA
@ ARM_LINE
@ ARM_B_BONE
@ ARM_ENVELOPE
@ ARM_WIRE
@ BBONE_ADD_PARENT_END_ROLL
@ BBONE_SCALE_EASING
@ CONSTRAINT_IK_TEMP
@ CONSTRAINT_IK_TIP
@ CONSTRAINT_TYPE_SPLINEIK
@ CONSTRAINT_TYPE_KINEMATIC
@ BASE_FROM_DUPLI
@ BASE_FROM_SET
@ BASE_SELECTED
@ OB_WIRE
@ OB_BOUNDBOX
@ OB_SOLID
#define OB_MODE_ALL_WEIGHT_PAINT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_POSE
@ OB_MODE_OBJECT
Object is a sort of wrapper for general info.
@ OB_EMPTY_CONE
@ OB_SINGLE_ARROW
@ OB_PLAINAXES
@ OB_ARROWS
@ OB_CIRCLE
@ OB_CUBE
@ OB_EMPTY_IMAGE
@ OB_EMPTY_SPHERE
@ OB_EMPTY
@ OB_SURF
@ OB_FONT
@ OB_CURVES_LEGACY
@ OB_DRAW_IN_FRONT
#define DG_LOCK_WEIGHT
@ SCE_OBJECT_MODE_LOCK
@ TH_WIRECOLOR_CONSTCOLS
@ V3D_OVERLAY_BONE_SELECT
#define V3D_HIDE_HELPLINES
#define V3D_SELECT_OUTLINE
#define DRW_buffer_add_entry(buffer,...)
Definition: DRW_render.h:486
DRWState
Definition: DRW_render.h:298
@ DRW_STATE_BLEND_ALPHA
Definition: DRW_render.h:328
@ DRW_STATE_BLEND_ADD
Definition: DRW_render.h:324
@ DRW_STATE_CULL_FRONT
Definition: DRW_render.h:317
@ DRW_STATE_IN_FRONT_SELECT
Definition: DRW_render.h:340
@ DRW_STATE_DEPTH_EQUAL
Definition: DRW_render.h:312
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:302
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:303
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:311
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:316
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:690
#define DRW_shgroup_uniform_block(shgroup, name, ubo)
Definition: DRW_render.h:651
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:414
#define EBONE_VISIBLE(arm, ebone)
Definition: ED_armature.h:47
#define BONESEL_ROOT
Definition: ED_armature.h:41
#define BONESEL_TIP
Definition: ED_armature.h:42
#define BONESEL_BONE
Definition: ED_armature.h:43
#define XRAY_FLAG_ENABLED(v3d)
Definition: ED_view3d.h:1298
static AppView * view
GPUBatch
Definition: GPU_batch.h:78
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
struct GPUShader GPUShader
Definition: GPU_shader.h:20
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
@ TH_TEXT
Definition: UI_resources.h:42
@ TH_TEXT_HI
Definition: UI_resources.h:43
struct bTheme * UI_GetTheme(void)
Definition: resources.c:1067
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
Definition: resources.c:1352
void ED_armature_ebone_to_mat4(EditBone *ebone, float r_mat[4][4])
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define sinf(x)
Definition: cuda/compat.h:102
Scene scene
Curve curve
GPUBatch * DRW_cache_bone_octahedral_wire_get(void)
Definition: draw_cache.c:2065
GPUBatch * DRW_cache_curve_edge_wire_get(Object *ob)
Definition: draw_cache.c:2926
GPUBatch * DRW_cache_bone_dof_lines_get(void)
Definition: draw_cache.c:2637
GPUBatch * DRW_cache_text_edge_wire_get(Object *ob)
Definition: draw_cache.c:2995
GPUBatch * DRW_cache_bone_box_get(void)
Definition: draw_cache.c:2090
GPUBatch * DRW_cache_bone_octahedral_get(void)
Definition: draw_cache.c:2029
GPUBatch * DRW_cache_bone_point_wire_outline_get(void)
Definition: draw_cache.c:2327
GPUBatch * DRW_cache_bone_stick_get(void)
Definition: draw_cache.c:2375
GPUBatch * DRW_cache_bone_envelope_outline_get(void)
Definition: draw_cache.c:2207
GPUBatch * DRW_cache_bone_envelope_solid_get(void)
Definition: draw_cache.c:2157
GPUBatch * DRW_cache_bone_point_get(void)
Definition: draw_cache.c:2252
GPUBatch * DRW_cache_bone_box_wire_get(void)
Definition: draw_cache.c:2123
GPUBatch * DRW_cache_object_surface_get(Object *ob)
Definition: draw_cache.c:887
GPUBatch * DRW_cache_bone_dof_sphere_get(void)
Definition: draw_cache.c:2584
struct GPUBatch * DRW_mesh_batch_cache_get_edge_detection(struct Mesh *me, bool *r_is_manifold)
void DRW_mesh_batch_cache_validate(struct Object *object, struct Mesh *me)
struct GPUBatch * DRW_mesh_batch_cache_get_loose_edges(struct Mesh *me)
struct GPUBatch * DRW_mesh_batch_cache_get_all_edges(struct Mesh *me)
void DRW_curve_batch_cache_validate(struct Curve *cu)
struct GPUBatch * DRW_mesh_batch_cache_get_surface(struct Mesh *me)
int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color)
Definition: draw_common.c:279
struct DRW_Global G_draw
Definition: draw_common.c:32
int len
Definition: draw_manager.c:108
bool DRW_state_is_select(void)
bool DRW_state_show_text(void)
bool DRW_state_is_fbo(void)
const DRWContextState * DRW_context_state_get(void)
struct DRWTextStore * DRW_text_cache_ensure(void)
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state)
const DRWView * DRW_view_default_get(void)
void DRW_buffer_add_entry_struct(DRWCallBuffer *callbuf, const void *data)
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state)
DRWCallBuffer * DRW_shgroup_call_buffer_instance(DRWShadingGroup *shgroup, struct GPUVertFormat *format, GPUBatch *geom)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
bool DRW_culling_sphere_test(const DRWView *view, const BoundSphere *bsphere)
void DRW_draw_pass(DRWPass *pass)
void DRW_select_load_id(uint id)
void DRW_text_cache_add(DRWTextStore *dt, const float co[3], const char *str, const int str_len, short xoffs, short yoffs, short flag, const uchar col[4])
@ DRW_TEXT_CACHE_GLOBALSPACE
@ DRW_TEXT_CACHE_STRING_PTR
uint col
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
const int state
ccl_gpu_kernel_postfix ccl_global float int int int int sh
format
Definition: logImageCore.h:38
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
static ulong * next
static unsigned a[3]
Definition: RandGen.cpp:78
T length(const vec_base< T, Size > &a)
T distance(const T &a, const T &b)
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
static void draw_bone_line(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *pchan, bArmature *arm, const int boneflag, const short constflag, const int select_id)
static void drw_shgroup_bone_ik_spline_lines(ArmatureDrawContext *ctx, const float start[3], const float end[3])
static void draw_bone_update_disp_matrix_bbone(EditBone *eBone, bPoseChannel *pchan)
static void drw_shgroup_bone_stick(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float col_wire[4], const float col_bone[4], const float col_head[4], const float col_tail[4])
#define BONE_VAR(eBone, pchan, var)
void drw_batch_cache_validate(Object *custom)
Definition: draw_cache.c:3298
static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_BBONE_SUBDIV][4][4])
void drw_batch_cache_generate_requested_delayed(Object *custom)
Definition: draw_cache.c:3392
static void drw_shgroup_bone_point(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float bone_color[4], const float hint_color[4], const float outline_color[4])
static const float * get_bone_hint_color(const ArmatureDrawContext *ctx, const EditBone *eBone, const bPoseChannel *pchan, const bArmature *arm, const int boneflag, const short constflag)
static void draw_bone_box(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *pchan, bArmature *arm, const int boneflag, const short constflag, const int select_id)
static bool POSE_is_driven_by_active_armature(Object *ob)
static void armature_context_setup(ArmatureDrawContext *ctx, OVERLAY_PrivateData *pd, Object *ob, const bool do_envelope_dist, const bool is_edit_mode, const bool is_pose_mode, const float *const_color)
void OVERLAY_armature_in_front_draw(OVERLAY_Data *vedata)
static void drw_shgroup_bone_envelope(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float bone_col[4], const float hint_col[4], const float outline_col[4], const float *radius_head, const float *radius_tail)
bool OVERLAY_armature_is_pose_mode(Object *ob, const DRWContextState *draw_ctx)
void OVERLAY_edit_armature_cache_populate(OVERLAY_Data *vedata, Object *ob)
static void draw_bone_degrees_of_freedom(ArmatureDrawContext *ctx, bPoseChannel *pchan)
static bool pchan_culling_test_with_radius_scale(const DRWView *view, const Object *ob, const bPoseChannel *pchan, const float scale)
static bool pchan_culling_test_octohedral(const DRWView *view, const Object *ob, const bPoseChannel *pchan)
static void pchan_culling_calc_bsphere(const Object *ob, const bPoseChannel *pchan, BoundSphere *r_bsphere)
static void draw_bone_relations(ArmatureDrawContext *ctx, EditBone *ebone, bPoseChannel *pchan, bArmature *arm, const int boneflag, const short constflag)
static bool pchan_culling_test_wire(const DRWView *view, const Object *ob, const bPoseChannel *pchan)
static bool pchan_culling_test_bbone(const DRWView *view, const Object *ob, const bPoseChannel *pchan)
void OVERLAY_armature_cache_finish(OVERLAY_Data *vedata)
static void drw_shgroup_bone_custom_mesh_wire(ArmatureDrawContext *ctx, Mesh *mesh, const float(*bone_mat)[4], const float color[4], Object *custom)
void OVERLAY_bone_instance_data_set_color_hint(BoneInstanceData *data, const float hint_color[4])
static void drw_shgroup_bone_relationship_lines_ex(ArmatureDrawContext *ctx, const float start[3], const float end[3], const float color[4])
void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
static void drw_shgroup_bone_custom_solid_mesh(ArmatureDrawContext *ctx, Mesh *mesh, const float(*bone_mat)[4], const float bone_color[4], const float hint_color[4], const float outline_color[4], Object *custom)
static void draw_armature_pose(ArmatureDrawContext *ctx)
static const float * get_bone_solid_with_consts_color(const ArmatureDrawContext *ctx, const EditBone *eBone, const bPoseChannel *pchan, const bArmature *arm, const int boneflag, const short constflag)
static void drw_shgroup_bone_relationship_lines(ArmatureDrawContext *ctx, const float start[3], const float end[3])
static void drw_shgroup_bone_custom_solid(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float bone_color[4], const float hint_color[4], const float outline_color[4], Object *custom)
static void draw_bone_update_disp_matrix_default(EditBone *eBone, bPoseChannel *pchan)
static void drw_shgroup_bone_octahedral(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float bone_color[4], const float hint_color[4], const float outline_color[4])
#define BUF_INSTANCE
static void draw_bone_wire(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *pchan, bArmature *arm, const int boneflag, const short constflag, const int select_id)
static void drw_shgroup_bone_ik_no_target_lines(ArmatureDrawContext *ctx, const float start[3], const float end[3])
static void edbo_compute_bbone_child(bArmature *arm)
struct ArmatureDrawContext ArmatureDrawContext
void OVERLAY_pose_armature_cache_populate(OVERLAY_Data *vedata, Object *ob)
static void draw_bone_envelope(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *pchan, bArmature *arm, const int boneflag, const short constflag, const int select_id)
static void bone_hint_color_shade(float hint_color[4], const float color[4])
static void drw_shgroup_bone_wire(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float color[4])
static void drw_shgroup_bone_custom_wire(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float color[4], Object *custom)
void OVERLAY_pose_cache_populate(OVERLAY_Data *vedata, Object *ob)
static void draw_axes(ArmatureDrawContext *ctx, const EditBone *eBone, const bPoseChannel *pchan, const bArmature *arm)
#define BONE_FLAG(eBone, pchan)
static void bone_locked_color_shade(float color[4])
void OVERLAY_armature_cache_populate(OVERLAY_Data *vedata, Object *ob)
static bool set_pchan_color(const ArmatureDrawContext *ctx, short colCode, const int boneflag, const short constflag, float r_color[4])
static void drw_shgroup_custom_bone_curve(ArmatureDrawContext *ctx, Curve *curve, const float(*bone_mat)[4], const float outline_color[4], Object *custom)
static void draw_bone_octahedral(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *pchan, bArmature *arm, const int boneflag, const short constflag, const int select_id)
static void draw_armature_edit(ArmatureDrawContext *ctx)
static float encode_2f_to_float(float a, float b)
#define BUF_LINE(grp, format)
static bool pchan_culling_test_custom(const DRWView *view, const Object *ob, const bPoseChannel *pchan)
static void bone_instance_data_set_angle_minmax(BoneInstanceData *data, const float aminx, const float aminz, const float amaxx, const float amaxz)
static void drw_shgroup_bone_envelope_distance(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float *radius_head, const float *radius_tail, const float *distance)
static void drw_shgroup_bone_box(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float bone_color[4], const float hint_color[4], const float outline_color[4])
static void draw_points(ArmatureDrawContext *ctx, const EditBone *eBone, const bPoseChannel *pchan, const bArmature *arm, const int boneflag, const short constflag, const int select_id)
static void draw_bone_name(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *pchan, bArmature *arm, const int boneflag)
static const float * get_bone_solid_color(const ArmatureDrawContext *ctx, const EditBone *UNUSED(eBone), const bPoseChannel *pchan, const bArmature *arm, const int boneflag, const short constflag)
static void draw_bone_custom_shape(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *pchan, bArmature *arm, const int boneflag, const short constflag, const int select_id)
static void pchan_draw_data_init(bPoseChannel *pchan)
void OVERLAY_pose_draw(OVERLAY_Data *vedata)
static bool pchan_culling_test_simple(const DRWView *view, const Object *ob, const bPoseChannel *pchan)
static void set_pchan_colorset(ArmatureDrawContext *ctx, Object *ob, bPoseChannel *pchan)
static bool pchan_culling_test_envelope(const DRWView *view, const Object *ob, const bPoseChannel *pchan)
static float get_bone_wire_thickness(const ArmatureDrawContext *ctx, int boneflag)
static void drw_shgroup_bone_ik_lines(ArmatureDrawContext *ctx, const float start[3], const float end[3])
void OVERLAY_armature_draw(OVERLAY_Data *vedata)
static void cp_shade_color3ub(uchar cp[3], const int offset)
static void drw_shgroup_bone_axes(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float color[4])
static void pchan_draw_ik_lines(ArmatureDrawContext *ctx, bPoseChannel *pchan, const bool only_temp, const int constflag)
static void draw_bone_update_disp_matrix_custom(bPoseChannel *pchan)
void OVERLAY_bone_instance_data_set_color(BoneInstanceData *data, const float bone_color[4])
#define PT_DEFAULT_RAD
static bool pchan_culling_test_line(const DRWView *view, const Object *ob, const bPoseChannel *pchan)
static const float * get_bone_wire_color(const ArmatureDrawContext *ctx, const EditBone *eBone, const bPoseChannel *pchan, const bArmature *arm, const int boneflag, const short constflag)
BLI_INLINE DRWCallBuffer * custom_bone_instance_shgroup(ArmatureDrawContext *ctx, DRWShadingGroup *grp, struct GPUBatch *custom_geom)
@ PCHAN_COLOR_NORMAL
@ PCHAN_COLOR_SOLID
@ PCHAN_COLOR_CONSTS
static void drw_shgroup_bone_custom_empty(ArmatureDrawContext *ctx, const float(*bone_mat)[4], const float color[4], Object *custom)
void OVERLAY_empty_shape(OVERLAY_ExtraCallBuffers *cb, const float mat[4][4], const float draw_size, const char draw_type, const float color[4])
void OVERLAY_extra_line_dashed(OVERLAY_ExtraCallBuffers *cb, const float start[3], const float end[3], const float color[4])
GPUShader * OVERLAY_shader_armature_degrees_of_freedom_wire(void)
GPUShader * OVERLAY_shader_armature_sphere(bool use_outline)
GPUShader * OVERLAY_shader_armature_degrees_of_freedom_solid(void)
GPUShader * OVERLAY_shader_armature_shape_wire(void)
GPUShader * OVERLAY_shader_armature_shape(bool use_outline)
GPUShader * OVERLAY_shader_armature_wire(void)
GPUShader * OVERLAY_shader_armature_envelope(bool use_outline)
GPUShader * OVERLAY_shader_uniform_color(void)
GPUShader * OVERLAY_shader_armature_stick(void)
OVERLAY_InstanceFormats * OVERLAY_shader_instance_formats_get(void)
#define min(a, b)
Definition: sort.c:35
DRWCallBuffer * solid
DRWShadingGroup * custom_outline
DRWCallBuffer * envelope_distance
DRWCallBuffer * dof_lines
DRWCallBuffer * point_solid
DRWCallBuffer * dof_sphere
const float * const_color
const ThemeWireColor * bcolor
OVERLAY_ExtraCallBuffers * extras
DRWShadingGroup * custom_solid
DRWCallBuffer * point_outline
DRWCallBuffer * envelope_solid
DRWCallBuffer * stick
DRWCallBuffer * envelope_outline
DRWShadingGroup * custom_wire
DRWCallBuffer * outline
DRWCallBuffer * wire
float zwidth
struct Bone * parent
float xwidth
short segments
float rad_head
float length
float rad_tail
float bone_mat[3][3]
float dist
float center[3]
Definition: DRW_render.h:86
float radius
Definition: DRW_render.h:86
struct Object * obact
Definition: DRW_render.h:983
struct Scene * scene
Definition: DRW_render.h:979
struct ViewLayer * view_layer
Definition: DRW_render.h:980
eObjectMode object_mode
Definition: DRW_render.h:991
struct View3D * v3d
Definition: DRW_render.h:976
struct Object * object_pose
Definition: DRW_render.h:1002
GlobalsUboStorage block
Definition: draw_common.h:127
struct GPUUniformBuf * block_ubo
Definition: draw_common.h:129
float curve_out_z
Definition: BKE_armature.h:74
float scale_in[3]
Definition: BKE_armature.h:76
char name[64]
Definition: BKE_armature.h:43
float ease2
Definition: BKE_armature.h:75
struct EditBone * bbone_child
Definition: BKE_armature.h:101
float roll1
Definition: BKE_armature.h:72
int bbone_flag
Definition: BKE_armature.h:85
struct EditBone * next
Definition: BKE_armature.h:33
short segments
Definition: BKE_armature.h:71
float tail[3]
Definition: BKE_armature.h:54
char bbone_prev_type
Definition: BKE_armature.h:82
float roll2
Definition: BKE_armature.h:72
float disp_bbone_mat[32][4][4]
Definition: BKE_armature.h:98
float curve_in_x
Definition: BKE_armature.h:73
float disp_mat[4][4]
Definition: BKE_armature.h:94
float zwidth
Definition: BKE_armature.h:67
struct EditBone * bbone_next
Definition: BKE_armature.h:90
float curve_in_z
Definition: BKE_armature.h:73
float length
Definition: BKE_armature.h:67
float xwidth
Definition: BKE_armature.h:67
float disp_tail_mat[4][4]
Definition: BKE_armature.h:96
float dist
Definition: BKE_armature.h:65
char bbone_next_type
Definition: BKE_armature.h:83
struct EditBone * parent
Definition: BKE_armature.h:41
float rad_tail
Definition: BKE_armature.h:68
float ease1
Definition: BKE_armature.h:75
float rad_head
Definition: BKE_armature.h:68
float scale_out[3]
Definition: BKE_armature.h:76
float curve_out_x
Definition: BKE_armature.h:74
struct EditBone * bbone_prev
Definition: BKE_armature.h:89
float head[3]
Definition: BKE_armature.h:53
void * first
Definition: DNA_listBase.h:31
float mat[4][4]
Definition: BKE_armature.h:464
OVERLAY_ArmatureCallBuffersInner transp
OVERLAY_ArmatureCallBuffersInner solid
OVERLAY_PassList * psl
OVERLAY_StorageList * stl
OVERLAY_FramebufferList * fbl
struct GPUFrameBuffer * overlay_line_in_front_fb
struct GPUFrameBuffer * overlay_default_fb
struct GPUVertFormat * instance_bone_envelope_outline
struct GPUVertFormat * instance_bone
struct GPUVertFormat * pos_color
struct GPUVertFormat * instance_extra
struct GPUVertFormat * instance_bone_envelope
struct GPUVertFormat * instance_bone_stick
struct GPUVertFormat * instance_bone_envelope_distance
DRWPass * armature_ps[2]
DRWPass * armature_bone_select_ps
DRWPass * armature_transp_ps[2]
OVERLAY_ExtraCallBuffers extra_call_buffers[2]
View3DOverlay overlay
struct OVERLAY_PrivateData::@256 armature
DRWShadingGroup * armature_bone_select_grp
OVERLAY_ArmatureCallBuffers armature_call_buffers[2]
DRWShadingGroup * armature_bone_select_act_grp
struct OVERLAY_PrivateData * pd
short base_flag
struct bPose * pose
char empty_drawtype
Object_Runtime runtime
float empty_drawsize
float obmat[4][4]
void * data
struct ToolSettings * toolsettings
unsigned char select[4]
unsigned char solid[4]
unsigned char active[4]
View3DShading shading
ThemeWireColor cs
struct EditBone * act_edbone
unsigned int layer
ListBase * edbo
struct bConstraint * next
float bbone_matrix[0][4][4]
ListBase constraints
float custom_scale_xyz[3]
bPoseChannelDrawData * draw_data
float custom_rotation_euler[3]
struct Bone * bone
struct bPoseChannel * parent
struct bPoseChannel * custom_tx
float pose_head[3]
float pose_tail[3]
struct Object * custom
struct bPoseChannel * next
float custom_translation[3]
float disp_mat[4][4]
float disp_tail_mat[4][4]
float pose_mat[4][4]
ListBase chanbase
ListBase agroups
short flag
ThemeWireColor tarm[20]
float max