Blender  V2.93
overlay_armature.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2019, Blender Foundation.
17  */
18 
23 #include <math.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "DNA_armature_types.h"
28 #include "DNA_constraint_types.h"
29 #include "DNA_object_types.h"
30 #include "DNA_scene_types.h"
31 #include "DNA_view3d_types.h"
32 
33 #include "DRW_render.h"
34 
35 #include "BLI_math.h"
36 #include "BLI_utildefines.h"
37 
38 #include "BKE_action.h"
39 #include "BKE_armature.h"
40 #include "BKE_modifier.h"
41 
42 #include "DEG_depsgraph_query.h"
43 
44 #include "ED_armature.h"
45 #include "ED_view3d.h"
46 
47 #include "UI_resources.h"
48 
49 #include "draw_common.h"
50 #include "draw_manager_text.h"
51 
52 #include "overlay_private.h"
53 
54 #define BONE_VAR(eBone, pchan, var) ((eBone) ? (eBone->var) : (pchan->var))
55 #define BONE_FLAG(eBone, pchan) ((eBone) ? (eBone->flag) : (pchan->bone->flag))
56 
57 #define PT_DEFAULT_RAD 0.05f /* radius of the point batch. */
58 
59 typedef struct ArmatureDrawContext {
60  /* Current armature object */
62  /* bArmature *arm; */ /* TODO */
63 
64  union {
65  struct {
69  };
70  struct {
74  };
75  struct {
77  };
78  };
79 
88 
90 
91  /* not a theme, this is an override */
92  const float *const_color;
93  float const_wire;
94 
98 
99  const ThemeWireColor *bcolor; /* pchan color */
101 
106 {
107  Object *active_ob = draw_ctx->obact;
108 
109  /* Pose armature is handled by pose mode engine. */
110  if (((ob == active_ob) || (ob->mode & OB_MODE_POSE)) &&
111  ((draw_ctx->object_mode & OB_MODE_POSE) != 0)) {
112  return true;
113  }
114 
115  /* Armature parent is also handled by pose mode engine. */
116  if ((active_ob != NULL) && (draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
117  if (ob == draw_ctx->object_pose) {
118  return true;
119  }
120  }
121 
122  return false;
123 }
124 
126 {
127  OVERLAY_PassList *psl = vedata->psl;
128  OVERLAY_PrivateData *pd = vedata->stl->pd;
129 
130  const DRWContextState *draw_ctx = DRW_context_state_get();
131  const bool is_select_mode = DRW_state_is_select();
132  pd->armature.transparent = (draw_ctx->v3d->shading.type == OB_WIRE) ||
133  XRAY_FLAG_ENABLED(draw_ctx->v3d);
134  pd->armature.show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0) &&
135  !is_select_mode;
138  ((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0) &&
139  draw_ctx->object_pose != NULL;
140  DRWState state;
141 
142  if (pd->armature.do_pose_fade_geom) {
145 
146  float alpha = pd->overlay.xray_alpha_bone;
148  DRWShadingGroup *grp;
149 
151  DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){0.0f, 0.0f, 0.0f, alpha});
152 
154  DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){0.0f, 0.0f, 0.0f, pow(alpha, 4)});
155  }
156 
157  for (int i = 0; i < 2; i++) {
158  struct GPUShader *sh;
159  struct GPUVertFormat *format;
160  DRWShadingGroup *grp = NULL;
161 
164 
165  cb->custom_shapes_ghash = BLI_ghash_ptr_new(__func__);
167 
168  DRWPass **p_armature_ps = &psl->armature_ps[i];
169  DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
171  DRW_PASS_CREATE(*p_armature_ps, state | pd->clipping_state | infront_state);
172  DRWPass *armature_ps = *p_armature_ps;
173 
174  DRWPass **p_armature_trans_ps = &psl->armature_transp_ps[i];
176  DRW_PASS_CREATE(*p_armature_trans_ps, state | pd->clipping_state);
177  DRWPass *armature_transp_ps = *p_armature_trans_ps;
178 
179 #define BUF_INSTANCE DRW_shgroup_call_buffer_instance
180 #define BUF_LINE(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_LINES)
181 #define BUF_POINT(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_POINTS)
182 
183  {
184  format = formats->instance_bone;
185 
186  sh = OVERLAY_shader_armature_sphere(false);
187  grp = DRW_shgroup_create(sh, armature_ps);
188  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
189  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
191 
192  grp = DRW_shgroup_create(sh, armature_ps);
195  DRW_shgroup_uniform_float_copy(grp, "alpha", 0.4f);
197 
198  sh = OVERLAY_shader_armature_shape(false);
199  grp = DRW_shgroup_create(sh, armature_ps);
200  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
201  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
202  cb->custom_solid = grp;
205 
206  grp = DRW_shgroup_create(sh, armature_ps);
209  DRW_shgroup_uniform_float_copy(grp, "alpha", 0.6f);
210  cb->custom_transp = grp;
213 
215  grp = DRW_shgroup_create(sh, armature_ps);
216  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
218 
220  cb->custom_outline = grp = DRW_shgroup_create(sh, armature_ps);
221  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
224 
226  cb->custom_wire = grp = DRW_shgroup_create(sh, armature_ps);
227  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
228  }
229  {
230  format = formats->instance_extra;
231 
233  grp = DRW_shgroup_create(sh, armature_ps);
234  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
236 
238  grp = DRW_shgroup_create(sh, armature_transp_ps);
239  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
241  }
242  {
243  format = formats->instance_bone_stick;
244 
246  grp = DRW_shgroup_create(sh, armature_ps);
247  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
249  }
250  {
251  format = formats->instance_bone_envelope;
252 
254  grp = DRW_shgroup_create(sh, armature_ps);
256  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
257  DRW_shgroup_uniform_bool_copy(grp, "isDistance", false);
258  DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
260 
261  grp = DRW_shgroup_create(sh, armature_ps);
264  DRW_shgroup_uniform_float_copy(grp, "alpha", 0.6f);
266 
268 
270  grp = DRW_shgroup_create(sh, armature_ps);
271  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
273 
275 
277  grp = DRW_shgroup_create(sh, armature_transp_ps);
278  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
279  DRW_shgroup_uniform_bool_copy(grp, "isDistance", true);
282  }
283  {
284  format = formats->pos_color;
285 
287  grp = DRW_shgroup_create(sh, armature_ps);
288  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
289  cb->wire = BUF_LINE(grp, format);
290  }
291  }
292 }
293 
294 /* -------------------------------------------------------------------- */
299  const float aminx,
300  const float aminz,
301  const float amaxx,
302  const float amaxz)
303 {
304  data->amin_a = aminx;
305  data->amin_b = aminz;
306  data->amax_a = amaxx;
307  data->amax_b = amaxz;
308 }
309 
310 /* Encode 2 units float with byte precision into a float. */
311 static float encode_2f_to_float(float a, float b)
312 {
313  CLAMP(a, 0.0f, 1.0f);
314  CLAMP(b, 0.0f, 2.0f); /* Can go up to 2. Needed for wire size. */
315  return (float)((int)(a * 255) | ((int)(b * 255) << 8));
316 }
317 
319 {
320  /* Encoded color into 2 floats to be able to use the obmat to color the custom bones. */
321  data->color_hint_a = encode_2f_to_float(hint_color[0], hint_color[1]);
322  data->color_hint_b = encode_2f_to_float(hint_color[2], hint_color[3]);
323 }
324 
326 {
327  /* Encoded color into 2 floats to be able to use the obmat to color the custom bones. */
328  data->color_a = encode_2f_to_float(bone_color[0], bone_color[1]);
329  data->color_b = encode_2f_to_float(bone_color[2], bone_color[3]);
330 }
331 
332 /* Octahedral */
334  const float (*bone_mat)[4],
335  const float bone_color[4],
336  const float hint_color[4],
337  const float outline_color[4])
338 {
339  BoneInstanceData inst_data;
340  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
341  if (ctx->solid) {
342  OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
343  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
344  DRW_buffer_add_entry_struct(ctx->solid, &inst_data);
345  }
346  if (outline_color[3] > 0.0f) {
347  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
348  DRW_buffer_add_entry_struct(ctx->outline, &inst_data);
349  }
350 }
351 
352 /* Box / B-Bone */
354  const float (*bone_mat)[4],
355  const float bone_color[4],
356  const float hint_color[4],
357  const float outline_color[4])
358 {
359  BoneInstanceData inst_data;
360  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
361  if (ctx->solid) {
362  OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
363  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
364  DRW_buffer_add_entry_struct(ctx->solid, &inst_data);
365  }
366  if (outline_color[3] > 0.0f) {
367  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
368  DRW_buffer_add_entry_struct(ctx->outline, &inst_data);
369  }
370 }
371 
372 /* Wire */
374  const float (*bone_mat)[4],
375  const float color[4])
376 {
377  float head[3], tail[3];
378  mul_v3_m4v3(head, ctx->ob->obmat, bone_mat[3]);
379  add_v3_v3v3(tail, bone_mat[3], bone_mat[1]);
380  mul_m4_v3(ctx->ob->obmat, tail);
381 
382  DRW_buffer_add_entry(ctx->wire, head, color);
383  DRW_buffer_add_entry(ctx->wire, tail, color);
384 }
385 
386 /* Stick */
388  const float (*bone_mat)[4],
389  const float col_wire[4],
390  const float col_bone[4],
391  const float col_head[4],
392  const float col_tail[4])
393 {
394  float head[3], tail[3];
395  mul_v3_m4v3(head, ctx->ob->obmat, bone_mat[3]);
396  add_v3_v3v3(tail, bone_mat[3], bone_mat[1]);
397  mul_m4_v3(ctx->ob->obmat, tail);
398 
399  DRW_buffer_add_entry(ctx->stick, head, tail, col_wire, col_bone, col_head, col_tail);
400 }
401 
402 /* Envelope */
404  const float (*bone_mat)[4],
405  const float *radius_head,
406  const float *radius_tail,
407  const float *distance)
408 {
409  if (ctx->envelope_distance) {
410  float head_sph[4] = {0.0f, 0.0f, 0.0f, 1.0f}, tail_sph[4] = {0.0f, 1.0f, 0.0f, 1.0f};
411  float xaxis[4] = {1.0f, 0.0f, 0.0f, 1.0f};
412  /* Still less operation than m4 multiplication. */
413  mul_m4_v4(bone_mat, head_sph);
414  mul_m4_v4(bone_mat, tail_sph);
415  mul_m4_v4(bone_mat, xaxis);
416  mul_m4_v4(ctx->ob->obmat, head_sph);
417  mul_m4_v4(ctx->ob->obmat, tail_sph);
418  mul_m4_v4(ctx->ob->obmat, xaxis);
419  sub_v3_v3(xaxis, head_sph);
420  float obscale = mat4_to_scale(ctx->ob->obmat);
421  head_sph[3] = *radius_head * obscale;
422  head_sph[3] += *distance * obscale;
423  tail_sph[3] = *radius_tail * obscale;
424  tail_sph[3] += *distance * obscale;
425  DRW_buffer_add_entry(ctx->envelope_distance, head_sph, tail_sph, xaxis);
426  }
427 }
428 
430  const float (*bone_mat)[4],
431  const float bone_col[4],
432  const float hint_col[4],
433  const float outline_col[4],
434  const float *radius_head,
435  const float *radius_tail)
436 {
437  float head_sph[4] = {0.0f, 0.0f, 0.0f, 1.0f}, tail_sph[4] = {0.0f, 1.0f, 0.0f, 1.0f};
438  float xaxis[4] = {1.0f, 0.0f, 0.0f, 1.0f};
439  /* Still less operation than m4 multiplication. */
440  mul_m4_v4(bone_mat, head_sph);
441  mul_m4_v4(bone_mat, tail_sph);
442  mul_m4_v4(bone_mat, xaxis);
443  mul_m4_v4(ctx->ob->obmat, head_sph);
444  mul_m4_v4(ctx->ob->obmat, tail_sph);
445  mul_m4_v4(ctx->ob->obmat, xaxis);
446  float obscale = mat4_to_scale(ctx->ob->obmat);
447  head_sph[3] = *radius_head * obscale;
448  tail_sph[3] = *radius_tail * obscale;
449 
450  if (head_sph[3] < 0.0f || tail_sph[3] < 0.0f) {
451  BoneInstanceData inst_data;
452  if (head_sph[3] < 0.0f) {
453  /* Draw Tail only */
454  scale_m4_fl(inst_data.mat, tail_sph[3] / PT_DEFAULT_RAD);
455  copy_v3_v3(inst_data.mat[3], tail_sph);
456  }
457  else {
458  /* Draw Head only */
459  scale_m4_fl(inst_data.mat, head_sph[3] / PT_DEFAULT_RAD);
460  copy_v3_v3(inst_data.mat[3], head_sph);
461  }
462 
463  if (ctx->point_solid) {
464  OVERLAY_bone_instance_data_set_color(&inst_data, bone_col);
465  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_col);
466  DRW_buffer_add_entry_struct(ctx->point_solid, &inst_data);
467  }
468  if (outline_col[3] > 0.0f) {
469  OVERLAY_bone_instance_data_set_color(&inst_data, outline_col);
470  DRW_buffer_add_entry_struct(ctx->point_outline, &inst_data);
471  }
472  }
473  else {
474  /* Draw Body */
475  float tmp_sph[4];
476  float len = len_v3v3(tail_sph, head_sph);
477  float fac_head = (len - head_sph[3]) / len;
478  float fac_tail = (len - tail_sph[3]) / len;
479  /* Small epsilon to avoid problem with float precision in shader. */
480  if (len > (tail_sph[3] + head_sph[3]) + 1e-8f) {
481  copy_v4_v4(tmp_sph, head_sph);
482  interp_v4_v4v4(head_sph, tail_sph, head_sph, fac_head);
483  interp_v4_v4v4(tail_sph, tmp_sph, tail_sph, fac_tail);
484  if (ctx->envelope_solid) {
485  DRW_buffer_add_entry(ctx->envelope_solid, head_sph, tail_sph, bone_col, hint_col, xaxis);
486  }
487  if (outline_col[3] > 0.0f) {
488  DRW_buffer_add_entry(ctx->envelope_outline, head_sph, tail_sph, outline_col, xaxis);
489  }
490  }
491  else {
492  /* Distance between endpoints is too small for a capsule. Draw a Sphere instead. */
493  float fac = max_ff(fac_head, 1.0f - fac_tail);
494  interp_v4_v4v4(tmp_sph, tail_sph, head_sph, clamp_f(fac, 0.0f, 1.0f));
495 
496  BoneInstanceData inst_data;
497  scale_m4_fl(inst_data.mat, tmp_sph[3] / PT_DEFAULT_RAD);
498  copy_v3_v3(inst_data.mat[3], tmp_sph);
499  if (ctx->point_solid) {
500  OVERLAY_bone_instance_data_set_color(&inst_data, bone_col);
501  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_col);
502  DRW_buffer_add_entry_struct(ctx->point_solid, &inst_data);
503  }
504  if (outline_col[3] > 0.0f) {
505  OVERLAY_bone_instance_data_set_color(&inst_data, outline_col);
506  DRW_buffer_add_entry_struct(ctx->point_outline, &inst_data);
507  }
508  }
509  }
510 }
511 
512 /* Custom (geometry) */
513 
514 extern void drw_batch_cache_validate(Object *custom);
516 
518  DRWShadingGroup *grp,
519  struct GPUBatch *custom_geom)
520 {
521  DRWCallBuffer *buf = BLI_ghash_lookup(ctx->custom_shapes_ghash, custom_geom);
522  if (buf == NULL) {
524  buf = DRW_shgroup_call_buffer_instance(grp, formats->instance_bone, custom_geom);
525  BLI_ghash_insert(ctx->custom_shapes_ghash, custom_geom, buf);
526  }
527  return buf;
528 }
529 
531  const float (*bone_mat)[4],
532  const float bone_color[4],
533  const float hint_color[4],
534  const float outline_color[4],
535  Object *custom)
536 {
537  /* TODO(fclem): arg... less than ideal but we never iter on this object
538  * to assure batch cache is valid. */
539  drw_batch_cache_validate(custom);
540 
541  struct GPUBatch *surf = DRW_cache_object_surface_get(custom);
542  struct GPUBatch *edges = DRW_cache_object_edge_detection_get(custom, NULL);
543  struct GPUBatch *ledges = DRW_cache_object_loose_edges_get(custom);
544  BoneInstanceData inst_data;
545  DRWCallBuffer *buf;
546 
547  if (surf || edges || ledges) {
548  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
549  }
550 
551  if (surf && ctx->custom_solid) {
552  buf = custom_bone_instance_shgroup(ctx, ctx->custom_solid, surf);
553  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
554  OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
555  DRW_buffer_add_entry_struct(buf, inst_data.mat);
556  }
557 
558  if (edges && ctx->custom_outline) {
559  buf = custom_bone_instance_shgroup(ctx, ctx->custom_outline, edges);
560  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
561  DRW_buffer_add_entry_struct(buf, inst_data.mat);
562  }
563 
564  if (ledges) {
565  buf = custom_bone_instance_shgroup(ctx, ctx->custom_wire, ledges);
566  OVERLAY_bone_instance_data_set_color_hint(&inst_data, outline_color);
567  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
568  DRW_buffer_add_entry_struct(buf, inst_data.mat);
569  }
570 
571  /* TODO(fclem): needs to be moved elsewhere. */
573 }
574 
576  const float (*bone_mat)[4],
577  const float color[4],
578  Object *custom)
579 {
580  /* TODO(fclem): arg... less than ideal but we never iter on this object
581  * to assure batch cache is valid. */
582  drw_batch_cache_validate(custom);
583 
584  struct GPUBatch *geom = DRW_cache_object_all_edges_get(custom);
585 
586  if (geom) {
588  BoneInstanceData inst_data;
589  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
591  OVERLAY_bone_instance_data_set_color(&inst_data, color);
592  DRW_buffer_add_entry_struct(buf, inst_data.mat);
593  }
594 
595  /* TODO(fclem): needs to be moved elsewhere. */
597 }
598 
600  const float (*bone_mat)[4],
601  const float color[4],
602  Object *custom)
603 {
604  const float final_color[4] = {color[0], color[1], color[2], 1.0f};
605  float mat[4][4];
606  mul_m4_m4m4(mat, ctx->ob->obmat, bone_mat);
607 
608  switch (custom->empty_drawtype) {
609  case OB_PLAINAXES:
610  case OB_SINGLE_ARROW:
611  case OB_CUBE:
612  case OB_CIRCLE:
613  case OB_EMPTY_SPHERE:
614  case OB_EMPTY_CONE:
615  case OB_ARROWS:
617  ctx->extras, mat, custom->empty_drawsize, custom->empty_drawtype, final_color);
618  break;
619  case OB_EMPTY_IMAGE:
620  break;
621  }
622 }
623 
624 /* Head and tail sphere */
626  const float (*bone_mat)[4],
627  const float bone_color[4],
628  const float hint_color[4],
629  const float outline_color[4])
630 {
631  BoneInstanceData inst_data;
632  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
633  if (ctx->point_solid) {
634  OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
635  OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
636  DRW_buffer_add_entry_struct(ctx->point_solid, &inst_data);
637  }
638  if (outline_color[3] > 0.0f) {
639  OVERLAY_bone_instance_data_set_color(&inst_data, outline_color);
640  DRW_buffer_add_entry_struct(ctx->point_outline, &inst_data);
641  }
642 }
643 
644 /* Axes */
646  const float (*bone_mat)[4],
647  const float color[4])
648 {
649  float mat[4][4];
650  mul_m4_m4m4(mat, ctx->ob->obmat, bone_mat);
651  /* Move to bone tail. */
652  add_v3_v3(mat[3], mat[1]);
653  OVERLAY_empty_shape(ctx->extras, mat, 0.25f, OB_ARROWS, color);
654 }
655 
656 /* Relationship lines */
658  const float start[3],
659  const float end[3],
660  const float color[4])
661 {
662  float s[3], e[3];
663  mul_v3_m4v3(s, ctx->ob->obmat, start);
664  mul_v3_m4v3(e, ctx->ob->obmat, end);
665  /* reverse order to have less stipple overlap */
666  OVERLAY_extra_line_dashed(ctx->extras, s, e, color);
667 }
668 
670  const float start[3],
671  const float end[3])
672 {
674 }
675 
677  const float start[3],
678  const float end[3])
679 {
681 }
682 
684  const float start[3],
685  const float end[3])
686 {
688 }
689 
691  const float start[3],
692  const float end[3])
693 {
695 }
696 
699 /* -------------------------------------------------------------------- */
706 /* values of colCode for set_pchan_color */
707 enum {
708  PCHAN_COLOR_NORMAL = 0, /* normal drawing */
709  PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */
710  PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */
711 };
712 
713 /* This function sets the color-set for coloring a certain bone */
715 {
716  bPose *pose = (ob) ? ob->pose : NULL;
717  bArmature *arm = (ob) ? ob->data : NULL;
718  bActionGroup *grp = NULL;
719  short color_index = 0;
720 
721  /* sanity check */
722  if (ELEM(NULL, ob, arm, pose, pchan)) {
723  ctx->bcolor = NULL;
724  return;
725  }
726 
727  /* only try to set custom color if enabled for armature */
728  if (arm->flag & ARM_COL_CUSTOM) {
729  /* currently, a bone can only use a custom color set if its group (if it has one),
730  * has been set to use one
731  */
732  if (pchan->agrp_index) {
733  grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
734  if (grp) {
735  color_index = grp->customCol;
736  }
737  }
738  }
739 
740  /* bcolor is a pointer to the color set to use. If NULL, then the default
741  * color set (based on the theme colors for 3d-view) is used.
742  */
743  if (color_index > 0) {
744  bTheme *btheme = UI_GetTheme();
745  ctx->bcolor = &btheme->tarm[(color_index - 1)];
746  }
747  else if (color_index == -1) {
748  /* use the group's own custom color set (grp is always != NULL here) */
749  ctx->bcolor = &grp->cs;
750  }
751  else {
752  ctx->bcolor = NULL;
753  }
754 }
755 
756 /* This function is for brightening/darkening a given color (like UI_GetThemeColorShade3ubv()) */
757 static void cp_shade_color3ub(uchar cp[3], const int offset)
758 {
759  int r, g, b;
760 
761  r = offset + (int)cp[0];
762  CLAMP(r, 0, 255);
763  g = offset + (int)cp[1];
764  CLAMP(g, 0, 255);
765  b = offset + (int)cp[2];
766  CLAMP(b, 0, 255);
767 
768  cp[0] = r;
769  cp[1] = g;
770  cp[2] = b;
771 }
772 
773 /* This function sets the gl-color for coloring a certain bone (based on bcolor) */
774 static bool set_pchan_color(const ArmatureDrawContext *ctx,
775  short colCode,
776  const int boneflag,
777  const short constflag,
778  float r_color[4])
779 {
780  float *fcolor = r_color;
781  const ThemeWireColor *bcolor = ctx->bcolor;
782 
783  switch (colCode) {
784  case PCHAN_COLOR_NORMAL: {
785  if (bcolor) {
786  uchar cp[4] = {255};
787  if (boneflag & BONE_DRAW_ACTIVE) {
788  copy_v3_v3_uchar(cp, bcolor->active);
789  if (!(boneflag & BONE_SELECTED)) {
790  cp_shade_color3ub(cp, -80);
791  }
792  }
793  else if (boneflag & BONE_SELECTED) {
794  copy_v3_v3_uchar(cp, bcolor->select);
795  }
796  else {
797  /* a bit darker than solid */
798  copy_v3_v3_uchar(cp, bcolor->solid);
799  cp_shade_color3ub(cp, -50);
800  }
801  rgb_uchar_to_float(fcolor, cp);
802  /* Meh, hardcoded srgb transform here. */
803  srgb_to_linearrgb_v4(fcolor, fcolor);
804  }
805  else {
806  if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
808  }
809  else if (boneflag & BONE_DRAW_ACTIVE) {
811  }
812  else if (boneflag & BONE_SELECTED) {
814  }
815  else {
816  copy_v4_v4(fcolor, G_draw.block.colorWire);
817  }
818  }
819  return true;
820  }
821  case PCHAN_COLOR_SOLID: {
822  if (bcolor) {
823  rgb_uchar_to_float(fcolor, (uchar *)bcolor->solid);
824  fcolor[3] = 1.0f;
825  /* Meh, hardcoded srgb transform here. */
826  srgb_to_linearrgb_v4(fcolor, fcolor);
827  }
828  else {
830  }
831  return true;
832  }
833  case PCHAN_COLOR_CONSTS: {
834  if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
835  if (constflag & PCHAN_HAS_TARGET) {
837  }
838  else if (constflag & PCHAN_HAS_IK) {
840  }
841  else if (constflag & PCHAN_HAS_SPLINEIK) {
843  }
844  else if (constflag & PCHAN_HAS_CONST) {
846  }
847  else {
848  return false;
849  }
850  return true;
851  }
852  return false;
853  }
854  }
855 
856  return false;
857 }
858 
861 /* -------------------------------------------------------------------- */
865 static void bone_locked_color_shade(float color[4])
866 {
867  float *locked_color = G_draw.block.colorBoneLocked;
868 
869  interp_v3_v3v3(color, color, locked_color, locked_color[3]);
870 }
871 
872 static const float *get_bone_solid_color(const ArmatureDrawContext *ctx,
873  const EditBone *UNUSED(eBone),
874  const bPoseChannel *pchan,
875  const bArmature *arm,
876  const int boneflag,
877  const short constflag)
878 {
879  if (ctx->const_color) {
880  return G_draw.block.colorBoneSolid;
881  }
882 
883  if (arm->flag & ARM_POSEMODE) {
884  static float disp_color[4];
885  copy_v4_v4(disp_color, pchan->draw_data->solid_color);
886  set_pchan_color(ctx, PCHAN_COLOR_SOLID, boneflag, constflag, disp_color);
887 
888  if (boneflag & BONE_DRAW_LOCKED_WEIGHT) {
889  bone_locked_color_shade(disp_color);
890  }
891 
892  return disp_color;
893  }
894 
895  return G_draw.block.colorBoneSolid;
896 }
897 
899  const EditBone *eBone,
900  const bPoseChannel *pchan,
901  const bArmature *arm,
902  const int boneflag,
903  const short constflag)
904 {
905  if (ctx->const_color) {
906  return G_draw.block.colorBoneSolid;
907  }
908 
909  const float *col = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag);
910 
911  static float consts_color[4];
912  if ((arm->flag & ARM_POSEMODE) && !(boneflag & BONE_DRAW_LOCKED_WEIGHT) &&
913  set_pchan_color(ctx, PCHAN_COLOR_CONSTS, boneflag, constflag, consts_color)) {
914  interp_v3_v3v3(consts_color, col, consts_color, 0.5f);
915  }
916  else {
917  copy_v4_v4(consts_color, col);
918  }
919  return consts_color;
920 }
921 
922 static float get_bone_wire_thickness(const ArmatureDrawContext *ctx, int boneflag)
923 {
924  if (ctx->const_color) {
925  return ctx->const_wire;
926  }
927  if (boneflag & (BONE_DRAW_ACTIVE | BONE_SELECTED)) {
928  return 2.0f;
929  }
930 
931  return 1.0f;
932 }
933 
934 static const float *get_bone_wire_color(const ArmatureDrawContext *ctx,
935  const EditBone *eBone,
936  const bPoseChannel *pchan,
937  const bArmature *arm,
938  const int boneflag,
939  const short constflag)
940 {
941  static float disp_color[4];
942 
943  if (ctx->const_color) {
944  copy_v3_v3(disp_color, ctx->const_color);
945  }
946  else if (eBone) {
947  if (boneflag & BONE_SELECTED) {
948  if (boneflag & BONE_DRAW_ACTIVE) {
949  copy_v3_v3(disp_color, G_draw.block.colorBoneActive);
950  }
951  else {
952  copy_v3_v3(disp_color, G_draw.block.colorBoneSelect);
953  }
954  }
955  else {
956  if (boneflag & BONE_DRAW_ACTIVE) {
958  }
959  else {
960  copy_v3_v3(disp_color, G_draw.block.colorWireEdit);
961  }
962  }
963  }
964  else if (arm->flag & ARM_POSEMODE) {
965  copy_v4_v4(disp_color, pchan->draw_data->wire_color);
966  set_pchan_color(ctx, PCHAN_COLOR_NORMAL, boneflag, constflag, disp_color);
967 
968  if (boneflag & BONE_DRAW_LOCKED_WEIGHT) {
969  bone_locked_color_shade(disp_color);
970  }
971  }
972  else {
973  copy_v3_v3(disp_color, G_draw.block.colorVertex);
974  }
975 
976  disp_color[3] = get_bone_wire_thickness(ctx, boneflag);
977 
978  return disp_color;
979 }
980 
981 static void bone_hint_color_shade(float hint_color[4], const float color[4])
982 {
983  /* Increase contrast. */
984  mul_v3_v3v3(hint_color, color, color);
985  /* Decrease value to add mode shading to the shape. */
986  mul_v3_fl(hint_color, 0.1f);
987  hint_color[3] = 1.0f;
988 }
989 
990 static const float *get_bone_hint_color(const ArmatureDrawContext *ctx,
991  const EditBone *eBone,
992  const bPoseChannel *pchan,
993  const bArmature *arm,
994  const int boneflag,
995  const short constflag)
996 {
997  static float hint_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
998 
999  if (ctx->const_color) {
1001  }
1002  else {
1003  const float *wire_color = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1004  bone_hint_color_shade(hint_color, wire_color);
1005  }
1006 
1007  return hint_color;
1008 }
1009 
1012 /* -------------------------------------------------------------------- */
1017 {
1018  if (pchan->draw_data != NULL) {
1019  if (pchan->draw_data->bbone_matrix_len != pchan->bone->segments) {
1020  MEM_SAFE_FREE(pchan->draw_data);
1021  }
1022  }
1023 
1024  if (pchan->draw_data == NULL) {
1025  pchan->draw_data = MEM_mallocN(
1026  sizeof(*pchan->draw_data) + sizeof(Mat4) * pchan->bone->segments, __func__);
1027  pchan->draw_data->bbone_matrix_len = pchan->bone->segments;
1028  }
1029 }
1030 
1032 {
1033  float ebmat[4][4];
1034  float length;
1035  float(*bone_mat)[4];
1036  float(*disp_mat)[4];
1037  float(*disp_tail_mat)[4];
1038 
1039  /* TODO : This should be moved to depsgraph or armature refresh
1040  * and not be tight to the draw pass creation.
1041  * This would refresh armature without invalidating the draw cache */
1042  if (pchan) {
1043  length = pchan->bone->length;
1044  bone_mat = pchan->pose_mat;
1045  disp_mat = pchan->disp_mat;
1046  disp_tail_mat = pchan->disp_tail_mat;
1047  }
1048  else {
1049  eBone->length = len_v3v3(eBone->tail, eBone->head);
1050  ED_armature_ebone_to_mat4(eBone, ebmat);
1051 
1052  length = eBone->length;
1053  bone_mat = ebmat;
1054  disp_mat = eBone->disp_mat;
1055  disp_tail_mat = eBone->disp_tail_mat;
1056  }
1057 
1058  copy_m4_m4(disp_mat, bone_mat);
1059  rescale_m4(disp_mat, (float[3]){length, length, length});
1060  copy_m4_m4(disp_tail_mat, disp_mat);
1061  translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f);
1062 }
1063 
1064 /* compute connected child pointer for B-Bone drawing */
1066 {
1067  EditBone *eBone;
1068 
1069  for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
1070  eBone->bbone_child = NULL;
1071  }
1072 
1073  for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
1074  if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
1075  eBone->parent->bbone_child = eBone;
1076  }
1077  }
1078 }
1079 
1080 /* A version of BKE_pchan_bbone_spline_setup() for previewing editmode curve settings. */
1081 static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_BBONE_SUBDIV][4][4])
1082 {
1083  BBoneSplineParameters param;
1084  EditBone *prev, *next;
1085  float imat[4][4], bonemat[4][4];
1086  float tmp[3];
1087 
1088  memset(&param, 0, sizeof(param));
1089 
1090  param.segments = ebone->segments;
1091  param.length = ebone->length;
1092 
1093  /* Get "next" and "prev" bones - these are used for handle calculations. */
1094  if (ebone->bbone_prev_type == BBONE_HANDLE_AUTO) {
1095  /* Use connected parent. */
1096  if (ebone->flag & BONE_CONNECTED) {
1097  prev = ebone->parent;
1098  }
1099  else {
1100  prev = NULL;
1101  }
1102  }
1103  else {
1104  prev = ebone->bbone_prev;
1105  }
1106 
1107  if (ebone->bbone_next_type == BBONE_HANDLE_AUTO) {
1108  /* Use connected child. */
1109  next = ebone->bbone_child;
1110  }
1111  else {
1112  next = ebone->bbone_next;
1113  }
1114 
1115  /* compute handles from connected bones */
1116  if (prev || next) {
1117  ED_armature_ebone_to_mat4(ebone, imat);
1118  invert_m4(imat);
1119 
1120  if (prev) {
1121  param.use_prev = true;
1122 
1123  if (ebone->bbone_prev_type == BBONE_HANDLE_RELATIVE) {
1124  zero_v3(param.prev_h);
1125  }
1126  else if (ebone->bbone_prev_type == BBONE_HANDLE_TANGENT) {
1127  sub_v3_v3v3(tmp, prev->tail, prev->head);
1128  sub_v3_v3v3(tmp, ebone->head, tmp);
1129  mul_v3_m4v3(param.prev_h, imat, tmp);
1130  }
1131  else {
1132  param.prev_bbone = (prev->segments > 1);
1133 
1134  mul_v3_m4v3(param.prev_h, imat, prev->head);
1135  }
1136 
1137  if (!param.prev_bbone) {
1138  ED_armature_ebone_to_mat4(prev, bonemat);
1139  mul_m4_m4m4(param.prev_mat, imat, bonemat);
1140  }
1141  }
1142 
1143  if (next) {
1144  param.use_next = true;
1145 
1146  if (ebone->bbone_next_type == BBONE_HANDLE_RELATIVE) {
1147  copy_v3_fl3(param.next_h, 0.0f, param.length, 0.0);
1148  }
1149  else if (ebone->bbone_next_type == BBONE_HANDLE_TANGENT) {
1150  sub_v3_v3v3(tmp, next->tail, next->head);
1151  add_v3_v3v3(tmp, ebone->tail, tmp);
1152  mul_v3_m4v3(param.next_h, imat, tmp);
1153  }
1154  else {
1155  param.next_bbone = (next->segments > 1);
1156 
1157  mul_v3_m4v3(param.next_h, imat, next->tail);
1158  }
1159 
1160  ED_armature_ebone_to_mat4(next, bonemat);
1161  mul_m4_m4m4(param.next_mat, imat, bonemat);
1162  }
1163  }
1164 
1165  param.ease1 = ebone->ease1;
1166  param.ease2 = ebone->ease2;
1167  param.roll1 = ebone->roll1;
1168  param.roll2 = ebone->roll2;
1169 
1170  if (prev && (ebone->flag & BONE_ADD_PARENT_END_ROLL)) {
1171  param.roll1 += prev->roll2;
1172  }
1173 
1174  param.scale_in_x = ebone->scale_in_x;
1175  param.scale_in_y = ebone->scale_in_y;
1176 
1177  param.scale_out_x = ebone->scale_out_x;
1178  param.scale_out_y = ebone->scale_out_y;
1179 
1180  param.curve_in_x = ebone->curve_in_x;
1181  param.curve_in_y = ebone->curve_in_y;
1182 
1183  param.curve_out_x = ebone->curve_out_x;
1184  param.curve_out_y = ebone->curve_out_y;
1185 
1186  ebone->segments = BKE_pchan_bbone_spline_compute(&param, false, (Mat4 *)result_array);
1187 }
1188 
1190 {
1191  float s[4][4], ebmat[4][4];
1192  float length, xwidth, zwidth;
1193  float(*bone_mat)[4];
1194  short bbone_segments;
1195 
1196  /* TODO : This should be moved to depsgraph or armature refresh
1197  * and not be tight to the draw pass creation.
1198  * This would refresh armature without invalidating the draw cache */
1199  if (pchan) {
1200  length = pchan->bone->length;
1201  xwidth = pchan->bone->xwidth;
1202  zwidth = pchan->bone->zwidth;
1203  bone_mat = pchan->pose_mat;
1204  bbone_segments = pchan->bone->segments;
1205  }
1206  else {
1207  eBone->length = len_v3v3(eBone->tail, eBone->head);
1208  ED_armature_ebone_to_mat4(eBone, ebmat);
1209 
1210  length = eBone->length;
1211  xwidth = eBone->xwidth;
1212  zwidth = eBone->zwidth;
1213  bone_mat = ebmat;
1214  bbone_segments = eBone->segments;
1215  }
1216 
1217  size_to_mat4(s, (const float[3]){xwidth, length / bbone_segments, zwidth});
1218 
1219  /* Compute BBones segment matrices... */
1220  /* Note that we need this even for one-segment bones, because box drawing need specific weirdo
1221  * matrix for the box, that we cannot use to draw end points & co. */
1222  if (pchan) {
1223  Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
1224  if (bbone_segments > 1) {
1225  BKE_pchan_bbone_spline_setup(pchan, false, false, bbones_mat);
1226 
1227  for (int i = bbone_segments; i--; bbones_mat++) {
1228  mul_m4_m4m4(bbones_mat->mat, bbones_mat->mat, s);
1229  mul_m4_m4m4(bbones_mat->mat, bone_mat, bbones_mat->mat);
1230  }
1231  }
1232  else {
1233  mul_m4_m4m4(bbones_mat->mat, bone_mat, s);
1234  }
1235  }
1236  else {
1237  float(*bbones_mat)[4][4] = eBone->disp_bbone_mat;
1238 
1239  if (bbone_segments > 1) {
1240  ebone_spline_preview(eBone, bbones_mat);
1241 
1242  for (int i = bbone_segments; i--; bbones_mat++) {
1243  mul_m4_m4m4(*bbones_mat, *bbones_mat, s);
1244  mul_m4_m4m4(*bbones_mat, bone_mat, *bbones_mat);
1245  }
1246  }
1247  else {
1248  mul_m4_m4m4(*bbones_mat, bone_mat, s);
1249  }
1250  }
1251 
1252  /* Grrr... We need default display matrix to draw end points, axes, etc. :( */
1254 }
1255 
1257 {
1258  float length;
1259  float(*bone_mat)[4];
1260  float(*disp_mat)[4];
1261  float(*disp_tail_mat)[4];
1262 
1263  /* See TODO above */
1264  length = PCHAN_CUSTOM_DRAW_SIZE(pchan);
1265  bone_mat = pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat;
1266  disp_mat = pchan->disp_mat;
1267  disp_tail_mat = pchan->disp_tail_mat;
1268 
1269  copy_m4_m4(disp_mat, bone_mat);
1270  rescale_m4(disp_mat, (float[3]){length, length, length});
1271  copy_m4_m4(disp_tail_mat, disp_mat);
1272  translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f);
1273 }
1274 
1276  const EditBone *eBone,
1277  const bPoseChannel *pchan,
1278  const bArmature *arm)
1279 {
1280  float final_col[4];
1281  const float *col = (ctx->const_color) ?
1282  ctx->const_color :
1283  (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? G_draw.block.colorTextHi :
1285  copy_v4_v4(final_col, col);
1286  /* Mix with axes color. */
1287  final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.1 : 0.65;
1288 
1289  if (pchan && pchan->custom && !(arm->flag & ARM_NO_CUSTOM)) {
1290  /* Special case: Custom bones can have different scale than the bone.
1291  * Recompute display matrix without the custom scaling applied. (T65640). */
1292  float axis_mat[4][4];
1293  float length = pchan->bone->length;
1294  copy_m4_m4(axis_mat, pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat);
1295  rescale_m4(axis_mat, (float[3]){length, length, length});
1296  translate_m4(axis_mat, 0.0, arm->axes_position - 1.0, 0.0);
1297 
1298  drw_shgroup_bone_axes(ctx, axis_mat, final_col);
1299  }
1300  else {
1301  float disp_mat[4][4];
1302  copy_m4_m4(disp_mat, BONE_VAR(eBone, pchan, disp_mat));
1303  translate_m4(disp_mat, 0.0, arm->axes_position - 1.0, 0.0);
1304  drw_shgroup_bone_axes(ctx, disp_mat, final_col);
1305  }
1306 }
1307 
1309  const EditBone *eBone,
1310  const bPoseChannel *pchan,
1311  const bArmature *arm,
1312  const int boneflag,
1313  const short constflag,
1314  const int select_id)
1315 {
1316  float col_solid_root[4], col_solid_tail[4], col_wire_root[4], col_wire_tail[4];
1317  float col_hint_root[4], col_hint_tail[4];
1318 
1319  copy_v4_v4(col_solid_root, G_draw.block.colorBoneSolid);
1320  copy_v4_v4(col_solid_tail, G_draw.block.colorBoneSolid);
1321  copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : G_draw.block.colorVertex);
1322  copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : G_draw.block.colorVertex);
1323 
1324  const bool is_envelope_draw = (arm->drawtype == ARM_ENVELOPE);
1325  const float envelope_ignore = -1.0f;
1326 
1327  col_wire_tail[3] = col_wire_root[3] = get_bone_wire_thickness(ctx, boneflag);
1328 
1329  /* Edit bone points can be selected */
1330  if (eBone) {
1331  if (eBone->flag & BONE_ROOTSEL) {
1332  copy_v3_v3(col_wire_root, G_draw.block.colorVertexSelect);
1333  }
1334  if (eBone->flag & BONE_TIPSEL) {
1335  copy_v3_v3(col_wire_tail, G_draw.block.colorVertexSelect);
1336  }
1337  }
1338  else if (arm->flag & ARM_POSEMODE) {
1339  const float *solid_color = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag);
1340  const float *wire_color = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1341  copy_v4_v4(col_wire_tail, wire_color);
1342  copy_v4_v4(col_wire_root, wire_color);
1343  copy_v4_v4(col_solid_tail, solid_color);
1344  copy_v4_v4(col_solid_root, solid_color);
1345  }
1346 
1347  bone_hint_color_shade(col_hint_root, (ctx->const_color) ? col_solid_root : col_wire_root);
1348  bone_hint_color_shade(col_hint_tail, (ctx->const_color) ? col_solid_tail : col_wire_tail);
1349 
1350  /* Draw root point if we are not connected to our parent */
1351  if (!(eBone ? (eBone->parent && (boneflag & BONE_CONNECTED)) :
1352  (pchan->bone->parent && (boneflag & BONE_CONNECTED)))) {
1353  if (select_id != -1) {
1354  DRW_select_load_id(select_id | BONESEL_ROOT);
1355  }
1356 
1357  if (eBone) {
1358  if (is_envelope_draw) {
1360  eBone->disp_mat,
1361  col_solid_root,
1362  col_hint_root,
1363  col_wire_root,
1364  &eBone->rad_head,
1365  &envelope_ignore);
1366  }
1367  else {
1368  drw_shgroup_bone_point(ctx, eBone->disp_mat, col_solid_root, col_hint_root, col_wire_root);
1369  }
1370  }
1371  else {
1372  Bone *bone = pchan->bone;
1373  if (is_envelope_draw) {
1375  pchan->disp_mat,
1376  col_solid_root,
1377  col_hint_root,
1378  col_wire_root,
1379  &bone->rad_head,
1380  &envelope_ignore);
1381  }
1382  else {
1383  drw_shgroup_bone_point(ctx, pchan->disp_mat, col_solid_root, col_hint_root, col_wire_root);
1384  }
1385  }
1386  }
1387 
1388  /* Draw tip point */
1389  if (select_id != -1) {
1390  DRW_select_load_id(select_id | BONESEL_TIP);
1391  }
1392 
1393  if (is_envelope_draw) {
1394  const float *rad_tail = eBone ? &eBone->rad_tail : &pchan->bone->rad_tail;
1396  BONE_VAR(eBone, pchan, disp_mat),
1397  col_solid_tail,
1398  col_hint_tail,
1399  col_wire_tail,
1400  &envelope_ignore,
1401  rad_tail);
1402  }
1403  else {
1405  ctx, BONE_VAR(eBone, pchan, disp_tail_mat), col_solid_tail, col_hint_tail, col_wire_tail);
1406  }
1407 
1408  if (select_id != -1) {
1409  DRW_select_load_id(-1);
1410  }
1411 }
1412 
1415 /* -------------------------------------------------------------------- */
1420  EditBone *eBone,
1421  bPoseChannel *pchan,
1422  bArmature *arm,
1423  const int boneflag,
1424  const short constflag,
1425  const int select_id)
1426 {
1427  const float *col_solid = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag);
1428  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1429  const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag);
1430  const float(*disp_mat)[4] = pchan->disp_mat;
1431 
1432  if (select_id != -1) {
1433  DRW_select_load_id(select_id | BONESEL_BONE);
1434  }
1435 
1436  if (pchan->custom->type == OB_EMPTY) {
1437  Object *ob = pchan->custom;
1438  if (ob->empty_drawtype != OB_EMPTY_IMAGE) {
1439  drw_shgroup_bone_custom_empty(ctx, disp_mat, col_wire, pchan->custom);
1440  }
1441  }
1442  if ((boneflag & BONE_DRAWWIRE) == 0 && (boneflag & BONE_DRAW_LOCKED_WEIGHT) == 0) {
1443  drw_shgroup_bone_custom_solid(ctx, disp_mat, col_solid, col_hint, col_wire, pchan->custom);
1444  }
1445  else {
1446  drw_shgroup_bone_custom_wire(ctx, disp_mat, col_wire, pchan->custom);
1447  }
1448 
1449  if (select_id != -1) {
1450  DRW_select_load_id(-1);
1451  }
1452 }
1453 
1455  EditBone *eBone,
1456  bPoseChannel *pchan,
1457  bArmature *arm,
1458  const int boneflag,
1459  const short constflag,
1460  const int select_id)
1461 {
1462  const float *col_solid = get_bone_solid_with_consts_color(
1463  ctx, eBone, pchan, arm, boneflag, constflag);
1464  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1465  const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag);
1466 
1467  float *rad_head, *rad_tail, *distance;
1468  if (eBone) {
1469  rad_tail = &eBone->rad_tail;
1470  distance = &eBone->dist;
1471  rad_head = (eBone->parent && (boneflag & BONE_CONNECTED)) ? &eBone->parent->rad_tail :
1472  &eBone->rad_head;
1473  }
1474  else {
1475  rad_tail = &pchan->bone->rad_tail;
1476  distance = &pchan->bone->dist;
1477  rad_head = (pchan->parent && (boneflag & BONE_CONNECTED)) ? &pchan->parent->bone->rad_tail :
1478  &pchan->bone->rad_head;
1479  }
1480 
1481  if ((select_id == -1) && (boneflag & BONE_NO_DEFORM) == 0 &&
1482  ((boneflag & BONE_SELECTED) || (eBone && (boneflag & (BONE_ROOTSEL | BONE_TIPSEL))))) {
1484  ctx, BONE_VAR(eBone, pchan, disp_mat), rad_head, rad_tail, distance);
1485  }
1486 
1487  if (select_id != -1) {
1488  DRW_select_load_id(select_id | BONESEL_BONE);
1489  }
1490 
1492  ctx, BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire, rad_head, rad_tail);
1493 
1494  if (select_id != -1) {
1495  DRW_select_load_id(-1);
1496  }
1497 
1498  draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id);
1499 }
1500 
1502  EditBone *eBone,
1503  bPoseChannel *pchan,
1504  bArmature *arm,
1505  const int boneflag,
1506  const short constflag,
1507  const int select_id)
1508 {
1509  const float *col_bone = get_bone_solid_with_consts_color(
1510  ctx, eBone, pchan, arm, boneflag, constflag);
1511  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1512  const float no_display[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1513  const float *col_head = no_display;
1514  const float *col_tail = col_bone;
1515 
1516  if (ctx->const_color != NULL) {
1517  col_wire = no_display; /* actually shrink the display. */
1518  col_bone = col_head = col_tail = ctx->const_color;
1519  }
1520  else {
1521  if (eBone) {
1522  if (eBone->flag & BONE_TIPSEL) {
1523  col_tail = G_draw.block.colorVertexSelect;
1524  }
1525  if (boneflag & BONE_SELECTED) {
1526  col_bone = G_draw.block.colorBoneActive;
1527  }
1528  col_wire = G_draw.block.colorWire;
1529  }
1530 
1531  /* Draw root point if we are not connected to our parent. */
1532  if (!(eBone ? (eBone->parent && (boneflag & BONE_CONNECTED)) :
1533  (pchan->bone->parent && (boneflag & BONE_CONNECTED)))) {
1534 
1535  if (eBone) {
1536  col_head = (eBone->flag & BONE_ROOTSEL) ? G_draw.block.colorVertexSelect : col_bone;
1537  }
1538  else {
1539  col_head = col_bone;
1540  }
1541  }
1542  }
1543 
1544  if (select_id == -1) {
1545  /* Not in selection mode, draw everything at once. */
1547  ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, col_head, col_tail);
1548  }
1549  else {
1550  /* In selection mode, draw bone, root and tip separately. */
1551  DRW_select_load_id(select_id | BONESEL_BONE);
1553  ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, no_display, no_display);
1554 
1555  if (col_head[3] > 0.0f) {
1556  DRW_select_load_id(select_id | BONESEL_ROOT);
1558  ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, col_head, no_display);
1559  }
1560 
1561  DRW_select_load_id(select_id | BONESEL_TIP);
1563  ctx, BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, no_display, col_tail);
1564 
1565  DRW_select_load_id(-1);
1566  }
1567 }
1568 
1570  EditBone *eBone,
1571  bPoseChannel *pchan,
1572  bArmature *arm,
1573  const int boneflag,
1574  const short constflag,
1575  const int select_id)
1576 {
1577  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1578 
1579  if (select_id != -1) {
1580  DRW_select_load_id(select_id | BONESEL_BONE);
1581  }
1582 
1583  if (pchan) {
1584  Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
1585  BLI_assert(bbones_mat != NULL);
1586 
1587  for (int i = pchan->bone->segments; i--; bbones_mat++) {
1588  drw_shgroup_bone_wire(ctx, bbones_mat->mat, col_wire);
1589  }
1590  }
1591  else if (eBone) {
1592  for (int i = 0; i < eBone->segments; i++) {
1593  drw_shgroup_bone_wire(ctx, eBone->disp_bbone_mat[i], col_wire);
1594  }
1595  }
1596 
1597  if (select_id != -1) {
1598  DRW_select_load_id(-1);
1599  }
1600 
1601  if (eBone) {
1602  draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id);
1603  }
1604 }
1605 
1607  EditBone *eBone,
1608  bPoseChannel *pchan,
1609  bArmature *arm,
1610  const int boneflag,
1611  const short constflag,
1612  const int select_id)
1613 {
1614  const float *col_solid = get_bone_solid_with_consts_color(
1615  ctx, eBone, pchan, arm, boneflag, constflag);
1616  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1617  const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag);
1618 
1619  if (select_id != -1) {
1620  DRW_select_load_id(select_id | BONESEL_BONE);
1621  }
1622 
1623  if (pchan) {
1624  Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
1625  BLI_assert(bbones_mat != NULL);
1626 
1627  for (int i = pchan->bone->segments; i--; bbones_mat++) {
1628  drw_shgroup_bone_box(ctx, bbones_mat->mat, col_solid, col_hint, col_wire);
1629  }
1630  }
1631  else if (eBone) {
1632  for (int i = 0; i < eBone->segments; i++) {
1633  drw_shgroup_bone_box(ctx, eBone->disp_bbone_mat[i], col_solid, col_hint, col_wire);
1634  }
1635  }
1636 
1637  if (select_id != -1) {
1638  DRW_select_load_id(-1);
1639  }
1640 
1641  if (eBone) {
1642  draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id);
1643  }
1644 }
1645 
1647  EditBone *eBone,
1648  bPoseChannel *pchan,
1649  bArmature *arm,
1650  const int boneflag,
1651  const short constflag,
1652  const int select_id)
1653 {
1654  const float *col_solid = get_bone_solid_with_consts_color(
1655  ctx, eBone, pchan, arm, boneflag, constflag);
1656  const float *col_wire = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
1657  const float *col_hint = get_bone_hint_color(ctx, eBone, pchan, arm, boneflag, constflag);
1658 
1659  if (select_id != -1) {
1660  DRW_select_load_id(select_id | BONESEL_BONE);
1661  }
1662 
1664  ctx, BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire);
1665 
1666  if (select_id != -1) {
1667  DRW_select_load_id(-1);
1668  }
1669 
1670  draw_points(ctx, eBone, pchan, arm, boneflag, constflag, select_id);
1671 }
1672 
1675 /* -------------------------------------------------------------------- */
1680 {
1681  BoneInstanceData inst_data;
1682  float tmp[4][4], posetrans[4][4];
1683  float xminmax[2], zminmax[2];
1684  float color[4];
1685 
1686  if (ctx->dof_sphere == NULL) {
1687  return;
1688  }
1689 
1690  /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
1691  xminmax[0] = sinf(pchan->limitmin[0] * 0.5f);
1692  xminmax[1] = sinf(pchan->limitmax[0] * 0.5f);
1693  zminmax[0] = sinf(pchan->limitmin[2] * 0.5f);
1694  zminmax[1] = sinf(pchan->limitmax[2] * 0.5f);
1695 
1696  unit_m4(posetrans);
1697  translate_m4(posetrans, pchan->pose_mat[3][0], pchan->pose_mat[3][1], pchan->pose_mat[3][2]);
1698  /* In parent-bone pose space... */
1699  if (pchan->parent) {
1700  copy_m4_m4(tmp, pchan->parent->pose_mat);
1701  zero_v3(tmp[3]);
1702  mul_m4_m4m4(posetrans, posetrans, tmp);
1703  }
1704  /* ... but own rest-space. */
1705  mul_m4_m4m3(posetrans, posetrans, pchan->bone->bone_mat);
1706 
1707  float scale = pchan->bone->length * pchan->size[1];
1708  scale_m4_fl(tmp, scale);
1709  tmp[1][1] = -tmp[1][1];
1710  mul_m4_m4m4(posetrans, posetrans, tmp);
1711 
1712  /* into world space. */
1713  mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, posetrans);
1714 
1715  if ((pchan->ikflag & BONE_IK_XLIMIT) && (pchan->ikflag & BONE_IK_ZLIMIT)) {
1717  &inst_data, xminmax[0], zminmax[0], xminmax[1], zminmax[1]);
1718 
1719  copy_v4_fl4(color, 0.25f, 0.25f, 0.25f, 0.25f);
1720  DRW_buffer_add_entry(ctx->dof_sphere, color, &inst_data);
1721 
1722  copy_v4_fl4(color, 0.0f, 0.0f, 0.0f, 1.0f);
1723  DRW_buffer_add_entry(ctx->dof_lines, color, &inst_data);
1724  }
1725  if (pchan->ikflag & BONE_IK_XLIMIT) {
1726  bone_instance_data_set_angle_minmax(&inst_data, xminmax[0], 0.0f, xminmax[1], 0.0f);
1727  copy_v4_fl4(color, 1.0f, 0.0f, 0.0f, 1.0f);
1728  DRW_buffer_add_entry(ctx->dof_lines, color, &inst_data);
1729  }
1730  if (pchan->ikflag & BONE_IK_ZLIMIT) {
1731  bone_instance_data_set_angle_minmax(&inst_data, 0.0f, zminmax[0], 0.0f, zminmax[1]);
1732  copy_v4_fl4(color, 0.0f, 0.0f, 1.0f, 1.0f);
1733  DRW_buffer_add_entry(ctx->dof_lines, color, &inst_data);
1734  }
1735 }
1736 
1739 /* -------------------------------------------------------------------- */
1744  bPoseChannel *pchan,
1745  const bool only_temp,
1746  const int constflag)
1747 {
1748  bConstraint *con;
1749  bPoseChannel *parchan;
1750  float *line_start = NULL, *line_end = NULL;
1751 
1752  for (con = pchan->constraints.first; con; con = con->next) {
1753  if (con->enforce == 0.0f) {
1754  continue;
1755  }
1756 
1757  switch (con->type) {
1760  int segcount = 0;
1761 
1762  /* if only_temp, only draw if it is a temporary ik-chain */
1763  if (only_temp && !(data->flag & CONSTRAINT_IK_TEMP)) {
1764  continue;
1765  }
1766 
1767  /* exclude tip from chain? */
1768  parchan = ((data->flag & CONSTRAINT_IK_TIP) == 0) ? pchan->parent : pchan;
1769  line_start = parchan->pose_tail;
1770 
1771  /* Find the chain's root */
1772  while (parchan->parent) {
1773  segcount++;
1774  if (segcount == data->rootbone || segcount > 255) {
1775  break; /* 255 is weak */
1776  }
1777  parchan = parchan->parent;
1778  }
1779 
1780  if (parchan) {
1781  line_end = parchan->pose_head;
1782 
1783  if (constflag & PCHAN_HAS_TARGET) {
1784  drw_shgroup_bone_ik_lines(ctx, line_start, line_end);
1785  }
1786  else {
1787  drw_shgroup_bone_ik_no_target_lines(ctx, line_start, line_end);
1788  }
1789  }
1790  break;
1791  }
1792  case CONSTRAINT_TYPE_SPLINEIK: {
1794  int segcount = 0;
1795 
1796  /* don't draw if only_temp, as Spline IK chains cannot be temporary */
1797  if (only_temp) {
1798  continue;
1799  }
1800 
1801  parchan = pchan;
1802  line_start = parchan->pose_tail;
1803 
1804  /* Find the chain's root */
1805  while (parchan->parent) {
1806  segcount++;
1807  /* FIXME: revise the breaking conditions */
1808  if (segcount == data->chainlen || segcount > 255) {
1809  break; /* 255 is weak */
1810  }
1811  parchan = parchan->parent;
1812  }
1813  /* Only draw line in case our chain is more than one bone long! */
1814  if (parchan != pchan) { /* XXX revise the breaking conditions to only stop at the tail? */
1815  line_end = parchan->pose_head;
1816  drw_shgroup_bone_ik_spline_lines(ctx, line_start, line_end);
1817  }
1818  break;
1819  }
1820  }
1821  }
1822 }
1823 
1825  EditBone *ebone,
1826  bPoseChannel *pchan,
1827  bArmature *arm,
1828  const int boneflag,
1829  const short constflag)
1830 {
1831  if (ebone && ebone->parent) {
1832  if (ctx->do_relations) {
1833  /* Always draw for unconnected bones, regardless of selection,
1834  * since riggers will want to know about the links between bones
1835  */
1836  if ((boneflag & BONE_CONNECTED) == 0) {
1837  drw_shgroup_bone_relationship_lines(ctx, ebone->head, ebone->parent->tail);
1838  }
1839  }
1840  }
1841  else if (pchan && pchan->parent) {
1842  if (ctx->do_relations) {
1843  /* Only draw if bone or its parent is selected - reduces viewport complexity with complex
1844  * rigs */
1845  if ((boneflag & BONE_SELECTED) ||
1846  (pchan->parent->bone && (pchan->parent->bone->flag & BONE_SELECTED))) {
1847  if ((boneflag & BONE_CONNECTED) == 0) {
1849  }
1850  }
1851  }
1852 
1853  /* Draw a line to IK root bone if bone is selected. */
1854  if (arm->flag & ARM_POSEMODE) {
1855  if (constflag & (PCHAN_HAS_IK | PCHAN_HAS_SPLINEIK)) {
1856  if (boneflag & BONE_SELECTED) {
1857  pchan_draw_ik_lines(ctx, pchan, !ctx->do_relations, constflag);
1858  }
1859  }
1860  }
1861  }
1862 }
1863 
1865  EditBone *eBone,
1866  bPoseChannel *pchan,
1867  bArmature *arm,
1868  const int boneflag)
1869 {
1870  struct DRWTextStore *dt = DRW_text_cache_ensure();
1871  uchar color[4];
1872  float vec[3];
1873 
1874  bool highlight = (pchan && (arm->flag & ARM_POSEMODE) && (boneflag & BONE_SELECTED)) ||
1875  (eBone && (eBone->flag & BONE_SELECTED));
1876 
1877  /* Color Management: Exception here as texts are drawn in sRGB space directly. */
1878  UI_GetThemeColor4ubv(highlight ? TH_TEXT_HI : TH_TEXT, color);
1879 
1880  float *head = pchan ? pchan->pose_head : eBone->head;
1881  float *tail = pchan ? pchan->pose_tail : eBone->tail;
1882  mid_v3_v3v3(vec, head, tail);
1883  mul_m4_v3(ctx->ob->obmat, vec);
1884 
1885  DRW_text_cache_add(dt,
1886  vec,
1887  (pchan) ? pchan->name : eBone->name,
1888  (pchan) ? strlen(pchan->name) : strlen(eBone->name),
1889  10,
1890  0,
1892  color);
1893 }
1896 /* -------------------------------------------------------------------- */
1901 {
1902  Object *ob = ctx->ob;
1903  EditBone *eBone;
1904  int index;
1905  const bool is_select = DRW_state_is_select();
1906  const bool show_text = DRW_state_show_text();
1907 
1908  const Object *ob_orig = DEG_get_original_object(ob);
1909  /* FIXME(campbell): We should be able to use the CoW object,
1910  * however the active bone isn't updated. Long term solution is an 'EditArmature' struct.
1911  * for now we can draw from the original armature. See: T66773. */
1912  // bArmature *arm = ob->data;
1913  bArmature *arm = ob_orig->data;
1914 
1916 
1917  for (eBone = arm->edbo->first, index = ob_orig->runtime.select_id; eBone;
1918  eBone = eBone->next, index += 0x10000) {
1919  if (eBone->layer & arm->layer) {
1920  if ((eBone->flag & BONE_HIDDEN_A) == 0) {
1921  const int select_id = is_select ? index : (uint)-1;
1922  const short constflag = 0;
1923 
1924  /* catch exception for bone with hidden parent */
1925  int boneflag = eBone->flag;
1926  if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) {
1927  boneflag &= ~BONE_CONNECTED;
1928  }
1929 
1930  /* set temporary flag for drawing bone as active, but only if selected */
1931  if (eBone == arm->act_edbone) {
1932  boneflag |= BONE_DRAW_ACTIVE;
1933  }
1934 
1935  boneflag &= ~BONE_DRAW_LOCKED_WEIGHT;
1936 
1937  draw_bone_relations(ctx, eBone, NULL, arm, boneflag, constflag);
1938 
1939  if (arm->drawtype == ARM_ENVELOPE) {
1941  draw_bone_envelope(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
1942  }
1943  else if (arm->drawtype == ARM_LINE) {
1945  draw_bone_line(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
1946  }
1947  else if (arm->drawtype == ARM_WIRE) {
1949  draw_bone_wire(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
1950  }
1951  else if (arm->drawtype == ARM_B_BONE) {
1953  draw_bone_box(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
1954  }
1955  else {
1957  draw_bone_octahedral(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
1958  }
1959 
1960  if (show_text && (arm->flag & ARM_DRAWNAMES)) {
1961  draw_bone_name(ctx, eBone, NULL, arm, boneflag);
1962  }
1963 
1964  if (arm->flag & ARM_DRAWAXES) {
1965  draw_axes(ctx, eBone, NULL, arm);
1966  }
1967  }
1968  }
1969  }
1970 }
1971 
1973 {
1974  Object *ob = ctx->ob;
1975  const DRWContextState *draw_ctx = DRW_context_state_get();
1976  const Scene *scene = draw_ctx->scene;
1977  bArmature *arm = ob->data;
1978  bPoseChannel *pchan;
1979  int index = -1;
1980  const bool show_text = DRW_state_show_text();
1981  bool draw_locked_weights = false;
1982 
1983  /* We can't safely draw non-updated pose, might contain NULL bone pointers... */
1984  if (ob->pose->flag & POSE_RECALC) {
1985  return;
1986  }
1987 
1988  bool is_pose_select = false;
1989  /* Object can be edited in the scene. */
1990  if ((ob->base_flag & (BASE_FROM_SET | BASE_FROM_DUPLI)) == 0) {
1991  if ((draw_ctx->object_mode & OB_MODE_POSE) || (ob == draw_ctx->object_pose)) {
1992  arm->flag |= ARM_POSEMODE;
1993  }
1994  is_pose_select =
1995  /* If we're in pose-mode or object-mode with the ability to enter pose mode. */
1996  (
1997  /* Draw as if in pose mode (when selection is possible). */
1998  (arm->flag & ARM_POSEMODE) ||
1999  /* When we're in object mode, which may select bones. */
2000  ((ob->mode & OB_MODE_POSE) &&
2001  (
2002  /* Switch from object mode when object lock is disabled. */
2003  ((draw_ctx->object_mode == OB_MODE_OBJECT) &&
2005  /* Allow selection when in weight-paint mode
2006  * (selection code ensures this wont become active). */
2007  ((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) &&
2008  (draw_ctx->object_pose != NULL))))) &&
2010 
2011  if (is_pose_select) {
2012  const Object *ob_orig = DEG_get_original_object(ob);
2013  index = ob_orig->runtime.select_id;
2014  }
2015  }
2016 
2017  /* In weight paint mode retrieve the vertex group lock status. */
2018  if ((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) && (draw_ctx->object_pose == ob) &&
2019  (draw_ctx->obact != NULL)) {
2020  draw_locked_weights = true;
2021 
2022  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
2023  pchan->bone->flag &= ~BONE_DRAW_LOCKED_WEIGHT;
2024  }
2025 
2026  const Object *obact_orig = DEG_get_original_object(draw_ctx->obact);
2027 
2028  LISTBASE_FOREACH (bDeformGroup *, dg, &obact_orig->defbase) {
2029  if (dg->flag & DG_LOCK_WEIGHT) {
2030  pchan = BKE_pose_channel_find_name(ob->pose, dg->name);
2031 
2032  if (pchan) {
2033  pchan->bone->flag |= BONE_DRAW_LOCKED_WEIGHT;
2034  }
2035  }
2036  }
2037  }
2038 
2039  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, index += 0x10000) {
2040  Bone *bone = pchan->bone;
2041  const bool bone_visible = (bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0;
2042 
2043  if (bone_visible) {
2044  if (bone->layer & arm->layer) {
2045  const bool draw_dofs = !is_pose_select && ctx->show_relations &&
2046  (arm->flag & ARM_POSEMODE) && (bone->flag & BONE_SELECTED) &&
2047  ((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
2048  (pchan->ikflag & (BONE_IK_XLIMIT | BONE_IK_ZLIMIT));
2049  const int select_id = is_pose_select ? index : (uint)-1;
2050  const short constflag = pchan->constflag;
2051 
2052  pchan_draw_data_init(pchan);
2053 
2054  if (!ctx->const_color) {
2055  set_pchan_colorset(ctx, ob, pchan);
2056  }
2057 
2058  int boneflag = bone->flag;
2059  /* catch exception for bone with hidden parent */
2060  boneflag = bone->flag;
2061  if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) {
2062  boneflag &= ~BONE_CONNECTED;
2063  }
2064 
2065  /* set temporary flag for drawing bone as active, but only if selected */
2066  if (bone == arm->act_bone) {
2067  boneflag |= BONE_DRAW_ACTIVE;
2068  }
2069 
2070  if (!draw_locked_weights) {
2071  boneflag &= ~BONE_DRAW_LOCKED_WEIGHT;
2072  }
2073 
2074  draw_bone_relations(ctx, NULL, pchan, arm, boneflag, constflag);
2075 
2076  if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
2078  draw_bone_custom_shape(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2079  }
2080  else if (arm->drawtype == ARM_ENVELOPE) {
2082  draw_bone_envelope(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2083  }
2084  else if (arm->drawtype == ARM_LINE) {
2086  draw_bone_line(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2087  }
2088  else if (arm->drawtype == ARM_WIRE) {
2090  draw_bone_wire(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2091  }
2092  else if (arm->drawtype == ARM_B_BONE) {
2094  draw_bone_box(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2095  }
2096  else {
2098  draw_bone_octahedral(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
2099  }
2100 
2101  if (draw_dofs) {
2102  draw_bone_degrees_of_freedom(ctx, pchan);
2103  }
2104 
2105  if (show_text && (arm->flag & ARM_DRAWNAMES)) {
2106  draw_bone_name(ctx, NULL, pchan, arm, boneflag);
2107  }
2108 
2109  if (arm->flag & ARM_DRAWAXES) {
2110  draw_axes(ctx, NULL, pchan, arm);
2111  }
2112  }
2113  }
2114  }
2115 
2116  arm->flag &= ~ARM_POSEMODE;
2117 }
2118 
2120  OVERLAY_PrivateData *pd,
2121  Object *ob,
2122  const bool do_envelope_dist,
2123  const bool is_edit_mode,
2124  const bool is_pose_mode,
2125  const float *const_color)
2126 {
2127  const bool is_object_mode = !do_envelope_dist;
2128  const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0 ||
2129  (pd->armature.do_pose_xray && is_pose_mode);
2130  const bool draw_as_wire = (ob->dt < OB_SOLID);
2131  const bool is_filled = (!pd->armature.transparent && !draw_as_wire) || !is_object_mode;
2132  const bool is_transparent = pd->armature.transparent || (draw_as_wire && !is_object_mode);
2133  bArmature *arm = ob->data;
2135 
2136  static const float select_const_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2137 
2138  switch (arm->drawtype) {
2139  case ARM_ENVELOPE:
2141  ctx->envelope_solid = (is_filled) ?
2142  (is_transparent ? cb->envelope_transp : cb->envelope_solid) :
2143  NULL;
2144  ctx->envelope_distance = (do_envelope_dist) ? cb->envelope_distance : NULL;
2145  break;
2146  case ARM_LINE:
2147  ctx->stick = cb->stick;
2148  break;
2149  case ARM_WIRE:
2150  ctx->wire = cb->wire;
2151  break;
2152  case ARM_B_BONE:
2153  ctx->outline = cb->box_outline;
2154  ctx->solid = (is_filled) ? (is_transparent ? cb->box_transp : cb->box_solid) : NULL;
2155  break;
2156  case ARM_OCTA:
2157  ctx->outline = cb->octa_outline;
2158  ctx->solid = (is_filled) ? (is_transparent ? cb->octa_transp : cb->octa_solid) : NULL;
2159  break;
2160  }
2161  ctx->ob = ob;
2162  ctx->extras = &pd->extra_call_buffers[is_xray];
2163  ctx->dof_lines = cb->dof_lines;
2164  ctx->dof_sphere = cb->dof_sphere;
2165  ctx->point_solid = (is_filled) ? (is_transparent ? cb->point_transp : cb->point_solid) : NULL;
2166  ctx->point_outline = cb->point_outline;
2167  ctx->custom_solid = (is_filled) ? (is_transparent ? cb->custom_transp : cb->custom_solid) : NULL;
2168  ctx->custom_outline = cb->custom_outline;
2169  ctx->custom_wire = cb->custom_wire;
2170  ctx->custom_shapes_ghash = is_transparent ? cb->custom_shapes_transp_ghash :
2171  cb->custom_shapes_ghash;
2174  (is_edit_mode | is_pose_mode);
2175  ctx->const_color = DRW_state_is_select() ? select_const_color : const_color;
2176  ctx->const_wire = ((((ob->base_flag & BASE_SELECTED) && (pd->v3d_flag & V3D_SELECT_OUTLINE)) ||
2177  (arm->drawtype == ARM_WIRE)) ?
2178  1.5f :
2179  ((!is_filled || is_transparent) ? 1.0f : 0.0f));
2180 }
2181 
2183 {
2184  OVERLAY_PrivateData *pd = vedata->stl->pd;
2185  ArmatureDrawContext arm_ctx;
2186  armature_context_setup(&arm_ctx, pd, ob, true, true, false, NULL);
2187  draw_armature_edit(&arm_ctx);
2188 }
2189 
2191 {
2192  OVERLAY_PrivateData *pd = vedata->stl->pd;
2193  ArmatureDrawContext arm_ctx;
2194  armature_context_setup(&arm_ctx, pd, ob, true, false, true, NULL);
2195  draw_armature_pose(&arm_ctx);
2196 }
2197 
2199 {
2200  const DRWContextState *draw_ctx = DRW_context_state_get();
2201  OVERLAY_PrivateData *pd = vedata->stl->pd;
2202  ArmatureDrawContext arm_ctx;
2203  float *color;
2204 
2205  if (ob->dt == OB_BOUNDBOX) {
2206  return;
2207  }
2208 
2209  DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
2210  armature_context_setup(&arm_ctx, pd, ob, false, false, false, color);
2211  draw_armature_pose(&arm_ctx);
2212 }
2213 
2215 {
2217  if (ob_arm) {
2218  const DRWContextState *draw_ctx = DRW_context_state_get();
2219  bool is_active = OVERLAY_armature_is_pose_mode(ob_arm, draw_ctx);
2220  if (!is_active && ob_arm->proxy_from) {
2221  is_active = OVERLAY_armature_is_pose_mode(ob_arm->proxy_from, draw_ctx);
2222  }
2223  return is_active;
2224  }
2225 
2226  Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob);
2227  if (ob_mesh_deform) {
2228  /* Recursive. */
2229  return POSE_is_driven_by_active_armature(ob_mesh_deform);
2230  }
2231 
2232  return false;
2233 }
2234 
2236 {
2237  OVERLAY_PrivateData *pd = vedata->stl->pd;
2238 
2239  struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
2240  if (geom) {
2243  }
2244  else {
2246  }
2247  }
2248 }
2249 
2251 {
2252  OVERLAY_PrivateData *pd = vedata->stl->pd;
2253 
2254  for (int i = 0; i < 2; i++) {
2256  /* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */
2259  }
2260  }
2261 }
2262 
2264 {
2265  OVERLAY_PassList *psl = vedata->psl;
2266 
2268  DRW_draw_pass(psl->armature_ps[0]);
2269 }
2270 
2272 {
2273  OVERLAY_PassList *psl = vedata->psl;
2274 
2277  DRW_draw_pass(psl->armature_ps[1]);
2278  }
2279 }
2280 
2282 {
2283  OVERLAY_PassList *psl = vedata->psl;
2284  OVERLAY_FramebufferList *fbl = vedata->fbl;
2285 
2286  if (psl->armature_bone_select_ps != NULL) {
2287  if (DRW_state_is_fbo()) {
2289  }
2290 
2292 
2293  if (DRW_state_is_fbo()) {
2295  GPU_framebuffer_clear_depth(fbl->overlay_line_in_front_fb, 1.0f);
2296  }
2297 
2299  DRW_draw_pass(psl->armature_ps[1]);
2300  }
2301 }
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
int BKE_pchan_bbone_spline_compute(struct BBoneSplineParameters *param, const bool for_deform, Mat4 *result_array)
Definition: armature.c:1306
#define MAX_BBONE_SUBDIV
Definition: BKE_armature.h:277
void BKE_pchan_bbone_spline_setup(struct bPoseChannel *pchan, const bool rest, const bool for_deform, Mat4 *result_array)
Definition: armature.c:1134
struct Object * BKE_modifiers_is_deformed_by_armature(struct Object *ob)
struct Object * BKE_modifiers_is_deformed_by_meshdeform(struct Object *ob)
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
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:407
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
bool invert_m4(float R[4][4])
Definition: math_matrix.c:1187
void mul_m4_v4(const float M[4][4], float r[4])
Definition: math_matrix.c:866
void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3])
Definition: math_matrix.c:437
void unit_m4(float m[4][4])
Definition: rct.c:1140
void translate_m4(float mat[4][4], float tx, float ty, float tz)
Definition: math_matrix.c:2325
void rescale_m4(float mat[4][4], const float scale[3])
Definition: math_matrix.c:2396
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2118
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void scale_m4_fl(float R[4][4], float scale)
Definition: math_matrix.c:2309
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
float mat4_to_scale(const float M[4][4])
Definition: math_matrix.c:2196
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
MINLINE void copy_v4_v4(float r[4], const float a[4])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
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])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], const float t)
Definition: math_vector.c:58
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])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
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:270
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define ELEM(...)
struct Object * DEG_get_original_object(struct Object *object)
@ BONE_IK_ZLIMIT
@ BONE_IK_XLIMIT
@ PCHAN_HAS_CONST
@ PCHAN_HAS_IK
@ PCHAN_HAS_TARGET
@ PCHAN_HAS_SPLINEIK
#define PCHAN_CUSTOM_DRAW_SIZE(pchan)
@ 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_ADD_PARENT_END_ROLL
@ 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
@ 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_DRAW_IN_FRONT
@ OB_EMPTY_CONE
@ OB_SINGLE_ARROW
@ OB_PLAINAXES
@ OB_ARROWS
@ OB_CIRCLE
@ OB_CUBE
@ OB_EMPTY_IMAGE
@ OB_EMPTY_SPHERE
#define DG_LOCK_WEIGHT
@ OB_EMPTY
@ SCE_OBJECT_MODE_LOCK
@ TH_WIRECOLOR_CONSTCOLS
#define V3D_HIDE_HELPLINES
#define V3D_SELECT_OUTLINE
@ V3D_OVERLAY_BONE_SELECT
#define DRW_buffer_add_entry(buffer,...)
Definition: DRW_render.h:468
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_BLEND_ALPHA
Definition: DRW_render.h:340
@ DRW_STATE_BLEND_ADD
Definition: DRW_render.h:336
@ DRW_STATE_CULL_FRONT
Definition: DRW_render.h:329
@ DRW_STATE_IN_FRONT_SELECT
Definition: DRW_render.h:352
@ DRW_STATE_DEPTH_EQUAL
Definition: DRW_render.h:324
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:314
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:323
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:328
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:420
#define EBONE_VISIBLE(arm, ebone)
Definition: ED_armature.h:56
#define BONESEL_ROOT
Definition: ED_armature.h:50
#define BONESEL_TIP
Definition: ED_armature.h:51
#define BONESEL_BONE
Definition: ED_armature.h:52
#define XRAY_FLAG_ENABLED(v3d)
Definition: ED_view3d.h:709
GPUBatch
Definition: GPU_batch.h:93
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:33
#define MEM_SAFE_FREE(v)
Group RGB to Bright Vector Camera CLAMP
@ TH_TEXT
Definition: UI_resources.h:58
@ TH_TEXT_HI
Definition: UI_resources.h:59
struct bTheme * UI_GetTheme(void)
Definition: resources.c:1086
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
Definition: resources.c:1381
void ED_armature_ebone_to_mat4(EditBone *ebone, float r_mat[4][4])
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
Scene scene
static CCL_NAMESPACE_BEGIN const double alpha
GPUBatch * DRW_cache_bone_octahedral_wire_get(void)
Definition: draw_cache.c:2066
GPUBatch * DRW_cache_object_all_edges_get(Object *ob)
Definition: draw_cache.c:799
GPUBatch * DRW_cache_bone_dof_lines_get(void)
Definition: draw_cache.c:2638
GPUBatch * DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
Definition: draw_cache.c:811
GPUBatch * DRW_cache_bone_box_get(void)
Definition: draw_cache.c:2091
GPUBatch * DRW_cache_bone_octahedral_get(void)
Definition: draw_cache.c:2030
GPUBatch * DRW_cache_bone_point_wire_outline_get(void)
Definition: draw_cache.c:2328
GPUBatch * DRW_cache_bone_stick_get(void)
Definition: draw_cache.c:2376
GPUBatch * DRW_cache_bone_envelope_outline_get(void)
Definition: draw_cache.c:2208
GPUBatch * DRW_cache_bone_envelope_solid_get(void)
Definition: draw_cache.c:2158
GPUBatch * DRW_cache_bone_point_get(void)
Definition: draw_cache.c:2253
GPUBatch * DRW_cache_bone_box_wire_get(void)
Definition: draw_cache.c:2124
GPUBatch * DRW_cache_object_surface_get(Object *ob)
Definition: draw_cache.c:886
GPUBatch * DRW_cache_object_loose_edges_get(struct Object *ob)
Definition: draw_cache.c:862
GPUBatch * DRW_cache_bone_dof_sphere_get(void)
Definition: draw_cache.c:2585
int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color)
Definition: draw_common.c:299
struct DRW_Global G_draw
Definition: draw_common.c:45
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_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuf *ubo)
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state)
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)
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
#define sinf(x)
format
Definition: logImageCore.h:47
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static ulong * next
static ulong state[N]
static unsigned a[3]
Definition: RandGen.cpp:92
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
Definition: rall1d.h:359
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:3538
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:3608
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 void draw_bone_relations(ArmatureDrawContext *ctx, EditBone *ebone, bPoseChannel *pchan, bArmature *arm, const int boneflag, const short constflag)
void OVERLAY_armature_cache_finish(OVERLAY_Data *vedata)
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)
@ PCHAN_COLOR_NORMAL
@ PCHAN_COLOR_SOLID
@ PCHAN_COLOR_CONSTS
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 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 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 void set_pchan_colorset(ArmatureDrawContext *ctx, Object *ob, 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 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)
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)
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
struct Object * obact
Definition: DRW_render.h:749
struct Scene * scene
Definition: DRW_render.h:745
struct ViewLayer * view_layer
Definition: DRW_render.h:746
eObjectMode object_mode
Definition: DRW_render.h:757
struct View3D * v3d
Definition: DRW_render.h:742
struct Object * object_pose
Definition: DRW_render.h:768
GlobalsUboStorage block
Definition: draw_common.h:208
struct GPUUniformBuf * block_ubo
Definition: draw_common.h:210
char name[64]
Definition: BKE_armature.h:57
float ease2
Definition: BKE_armature.h:85
struct EditBone * bbone_child
Definition: BKE_armature.h:108
float roll1
Definition: BKE_armature.h:82
float scale_out_y
Definition: BKE_armature.h:87
struct EditBone * next
Definition: BKE_armature.h:49
short segments
Definition: BKE_armature.h:81
float tail[3]
Definition: BKE_armature.h:66
char bbone_prev_type
Definition: BKE_armature.h:93
float roll2
Definition: BKE_armature.h:82
float disp_bbone_mat[32][4][4]
Definition: BKE_armature.h:105
float curve_in_x
Definition: BKE_armature.h:83
float disp_mat[4][4]
Definition: BKE_armature.h:101
float scale_out_x
Definition: BKE_armature.h:87
float zwidth
Definition: BKE_armature.h:77
struct EditBone * bbone_next
Definition: BKE_armature.h:97
float length
Definition: BKE_armature.h:77
float xwidth
Definition: BKE_armature.h:77
float disp_tail_mat[4][4]
Definition: BKE_armature.h:103
float dist
Definition: BKE_armature.h:75
float curve_in_y
Definition: BKE_armature.h:83
char bbone_next_type
Definition: BKE_armature.h:94
struct EditBone * parent
Definition: BKE_armature.h:55
float rad_tail
Definition: BKE_armature.h:78
float ease1
Definition: BKE_armature.h:85
float rad_head
Definition: BKE_armature.h:78
float curve_out_y
Definition: BKE_armature.h:84
float curve_out_x
Definition: BKE_armature.h:84
struct EditBone * bbone_prev
Definition: BKE_armature.h:96
float scale_in_y
Definition: BKE_armature.h:86
float head[3]
Definition: BKE_armature.h:65
float scale_in_x
Definition: BKE_armature.h:86
float colorBonePoseTarget[4]
Definition: draw_common.h:111
float colorBoneSelect[4]
Definition: draw_common.h:116
float colorBoneIKLineSpline[4]
Definition: draw_common.h:119
float colorBoneIKLine[4]
Definition: draw_common.h:117
float colorBoneIKLineNoTarget[4]
Definition: draw_common.h:118
float colorBonePoseActive[4]
Definition: draw_common.h:106
float colorBonePoseIK[4]
Definition: draw_common.h:109
float colorVertex[4]
Definition: draw_common.h:55
float colorWireEdit[4]
Definition: draw_common.h:42
float colorBonePoseActiveUnsel[4]
Definition: draw_common.h:107
float colorBoneLocked[4]
Definition: draw_common.h:113
float colorVertexSelect[4]
Definition: draw_common.h:56
float colorBoneActiveUnsel[4]
Definition: draw_common.h:115
float colorBonePoseConstraint[4]
Definition: draw_common.h:108
float colorBonePose[4]
Definition: draw_common.h:105
float colorText[4]
Definition: draw_common.h:121
float colorBoneSolid[4]
Definition: draw_common.h:112
float colorWire[4]
Definition: draw_common.h:41
float colorBonePoseSplineIK[4]
Definition: draw_common.h:110
float colorBoneActive[4]
Definition: draw_common.h:114
float colorTextHi[4]
Definition: draw_common.h:122
void * first
Definition: DNA_listBase.h:47
float mat[4][4]
Definition: BKE_armature.h:280
DRWCallBuffer * envelope_distance
DRWShadingGroup * custom_transp
DRWCallBuffer * envelope_outline
DRWShadingGroup * custom_outline
DRWShadingGroup * custom_wire
DRWShadingGroup * custom_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::@245 armature
DRWShadingGroup * armature_bone_select_grp
OVERLAY_ArmatureCallBuffers armature_call_buffers[2]
DRWShadingGroup * armature_bone_select_act_grp
struct OVERLAY_PrivateData * pd
ListBase defbase
short base_flag
struct bPose * pose
struct Object * proxy_from
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
bPoseChannelDrawData * draw_data
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 disp_mat[4][4]
float disp_tail_mat[4][4]
float pose_mat[4][4]
ListBase chanbase
ListBase agroups
short flag
ThemeWireColor tarm[20]
ccl_device_inline float distance(const float2 &a, const float2 &b)
uint len