Blender V4.3
view3d_buttons.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cfloat>
10#include <cmath>
11#include <cstdio>
12#include <cstring>
13
14#include "DNA_armature_types.h"
15#include "DNA_curve_types.h"
16#include "DNA_lattice_types.h"
17#include "DNA_mesh_types.h"
18#include "DNA_meshdata_types.h"
19#include "DNA_meta_types.h"
20#include "DNA_object_types.h"
21#include "DNA_scene_types.h"
22
23#include "MEM_guardedalloc.h"
24
25#include "BLT_translation.hh"
26
27#include "BLI_array_utils.h"
28#include "BLI_bitmap.h"
29#include "BLI_blenlib.h"
30#include "BLI_math_matrix.h"
31#include "BLI_math_rotation.h"
32#include "BLI_math_vector.h"
33#include "BLI_utildefines.h"
34
35#include "BKE_action.hh"
36#include "BKE_armature.hh"
37#include "BKE_context.hh"
38#include "BKE_curve.hh"
39#include "BKE_customdata.hh"
40#include "BKE_deform.hh"
41#include "BKE_editmesh.hh"
42#include "BKE_layer.hh"
43#include "BKE_mesh_types.hh"
44#include "BKE_object.hh"
45#include "BKE_object_deform.h"
46#include "BKE_object_types.hh"
47#include "BKE_report.hh"
48#include "BKE_screen.hh"
49
50#include "DEG_depsgraph.hh"
51
52#include "WM_api.hh"
53#include "WM_types.hh"
54
55#include "RNA_access.hh"
56#include "RNA_prototypes.hh"
57
58#include "ED_mesh.hh"
59#include "ED_object.hh"
60#include "ED_object_vgroup.hh"
61#include "ED_screen.hh"
62
64
65#include "UI_interface.hh"
66#include "UI_resources.hh"
67
68#include "view3d_intern.hh" /* own include */
69
70/* ******************* view3d space & buttons ************** */
71enum {
72 B_REDR = 2,
75};
76
77/* All must start w/ location */
78
80 float location[3];
81};
82
84 float location[3], bv_weight, v_crease, be_weight, skin[2], e_crease;
85};
86
88 float location[3], weight, b_weight, radius, tilt;
89};
90
92 float location[3], weight;
93};
94
101
102/* temporary struct for storing transform properties */
103
105 float ob_obmat_orig[4][4];
106 float ob_dims_orig[3];
107 float ob_scale_orig[3];
108 float ob_dims[3];
110 /* Floats only (treated as an array). */
113};
114
115#define TRANSFORM_MEDIAN_ARRAY_LEN (sizeof(TransformMedian) / sizeof(float))
116
118
119/* -------------------------------------------------------------------- */
125 void *arg1)
126{
127 const int retval_test = B_TRANSFORM_PANEL_MEDIAN;
129 params->unique_retval_ids, params->unique_retval_ids_len, &retval_test) == -1)
130 {
131 return nullptr;
132 }
133
134 BMEditMesh *em = static_cast<BMEditMesh *>(arg1);
135
136 int verts_mask_count = 0;
137 BMIter iter;
138 BMVert *eve;
139 int i;
140
141 BLI_bitmap *verts_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__);
142 BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
144 continue;
145 }
146 BLI_BITMAP_ENABLE(verts_mask, i);
147 verts_mask_count += 1;
148 }
149
150 BMPartialUpdate_Params update_params{};
151 update_params.do_tessellate = true;
152 update_params.do_normals = true;
154 em->bm, &update_params, verts_mask, verts_mask_count);
155
156 MEM_freeN(verts_mask);
157
158 return bmpinfo;
159}
160
162 const uiBlockInteraction_Params * /*params*/,
163 void * /*arg1*/,
164 void *user_data)
165{
166 BMPartialUpdate *bmpinfo = static_cast<BMPartialUpdate *>(user_data);
167 if (bmpinfo == nullptr) {
168 return;
169 }
171}
172
174 const uiBlockInteraction_Params * /*params*/,
175 void *arg1,
176 void *user_data)
177{
178 BMPartialUpdate *bmpinfo = static_cast<BMPartialUpdate *>(user_data);
179 if (bmpinfo == nullptr) {
180 return;
181 }
182
183 View3D *v3d = CTX_wm_view3d(C);
185 if (tfp->tag_for_update == false) {
186 return;
187 }
188 tfp->tag_for_update = false;
189
190 BMEditMesh *em = static_cast<BMEditMesh *>(arg1);
191
193}
194
197/* Helper function to compute a median changed value,
198 * when the value should be clamped in [0.0, 1.0].
199 * Returns either 0.0, 1.0 (both can be applied directly), a positive scale factor
200 * for scale down, or a negative one for scale up.
201 */
202static float compute_scale_factor(const float ve_median, const float median)
203{
204 if (ve_median <= 0.0f) {
205 return 0.0f;
206 }
207 if (ve_median >= 1.0f) {
208 return 1.0f;
209 }
210
211 /* Scale value to target median. */
212 float median_new = ve_median;
213 float median_orig = ve_median - median; /* Previous median value. */
214
215 /* In case of floating point error. */
216 CLAMP(median_orig, 0.0f, 1.0f);
217 CLAMP(median_new, 0.0f, 1.0f);
218
219 if (median_new <= median_orig) {
220 /* Scale down. */
221 return median_new / median_orig;
222 }
223
224 /* Scale up, negative to indicate it... */
225 return -(1.0f - median_new) / (1.0f - median_orig);
226}
227
234static void apply_raw_diff(float *val, const int tot, const float ve_median, const float median)
235{
236 *val = (tot == 1) ? ve_median : (*val + median);
237}
238
239static void apply_raw_diff_v3(float val[3],
240 const int tot,
241 const float ve_median[3],
242 const float median[3])
243{
244 if (tot == 1) {
245 copy_v3_v3(val, ve_median);
246 }
247 else {
248 add_v3_v3(val, median);
249 }
250}
251
253 float *val, const int tot, const float ve_median, const float median, const float sca)
254{
255 if (tot == 1 || ve_median == median) {
256 *val = ve_median;
257 }
258 else {
259 *val *= sca;
260 }
261}
262
263static void apply_scale_factor_clamp(float *val,
264 const int tot,
265 const float ve_median,
266 const float sca)
267{
268 if (tot == 1) {
269 *val = ve_median;
270 CLAMP(*val, 0.0f, 1.0f);
271 }
272 else if (ELEM(sca, 0.0f, 1.0f)) {
273 *val = sca;
274 }
275 else {
276 *val = (sca > 0.0f) ? (*val * sca) : (1.0f + ((1.0f - *val) * sca));
277 CLAMP(*val, 0.0f, 1.0f);
278 }
279}
280
282{
283 if (v3d->runtime.properties_storage == nullptr) {
284 TransformProperties *tfp = static_cast<TransformProperties *>(
285 MEM_callocN(sizeof(TransformProperties), "TransformProperties"));
286 /* Construct C++ structures in otherwise zero initialized struct. */
287 new (tfp) TransformProperties();
288
289 v3d->runtime.properties_storage = tfp;
290 v3d->runtime.properties_storage_free = [](void *properties_storage) {
291 MEM_delete(static_cast<TransformProperties *>(properties_storage));
292 };
293 }
294 return static_cast<TransformProperties *>(v3d->runtime.properties_storage);
295}
296
297/* is used for both read and write... */
298static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
299{
300 uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : nullptr;
302 TransformMedian median_basis, ve_median_basis;
303 int tot, totedgedata, totcurvedata, totlattdata, totcurvebweight;
304 bool has_meshdata = false;
305 bool has_skinradius = false;
306 PointerRNA data_ptr;
307
308 copy_vn_fl((float *)&median_basis, TRANSFORM_MEDIAN_ARRAY_LEN, 0.0f);
309 tot = totedgedata = totcurvedata = totlattdata = totcurvebweight = 0;
310
311 if (ob->type == OB_MESH) {
312 TransformMedian_Mesh *median = &median_basis.mesh;
313 Mesh *mesh = static_cast<Mesh *>(ob->data);
314 BMEditMesh *em = mesh->runtime->edit_mesh.get();
315 BMesh *bm = em->bm;
316 BMVert *eve;
317 BMEdge *eed;
318 BMIter iter;
319
320 const int cd_vert_bweight_offset = CustomData_get_offset_named(
321 &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert");
322 const int cd_vert_crease_offset = CustomData_get_offset_named(
323 &bm->vdata, CD_PROP_FLOAT, "crease_vert");
324 const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
325 const int cd_edge_bweight_offset = CustomData_get_offset_named(
326 &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge");
327 const int cd_edge_crease_offset = CustomData_get_offset_named(
328 &bm->edata, CD_PROP_FLOAT, "crease_edge");
329
330 has_skinradius = (cd_vert_skin_offset != -1);
331
332 if (bm->totvertsel) {
333 BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
335 tot++;
336 add_v3_v3(median->location, eve->co);
337
338 if (cd_vert_bweight_offset != -1) {
339 median->bv_weight += BM_ELEM_CD_GET_FLOAT(eve, cd_vert_bweight_offset);
340 }
341
342 if (cd_vert_crease_offset != -1) {
343 median->v_crease += BM_ELEM_CD_GET_FLOAT(eve, cd_vert_crease_offset);
344 }
345
346 if (has_skinradius) {
347 MVertSkin *vs = static_cast<MVertSkin *>(
348 BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset));
349 add_v2_v2(median->skin, vs->radius); /* Third val not used currently. */
350 }
351 }
352 }
353 }
354
355 if ((cd_edge_bweight_offset != -1) || (cd_edge_crease_offset != -1)) {
356 if (bm->totedgesel) {
357 BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
359 if (cd_edge_bweight_offset != -1) {
360 median->be_weight += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset);
361 }
362
363 if (cd_edge_crease_offset != -1) {
364 median->e_crease += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
365 }
366
367 totedgedata++;
368 }
369 }
370 }
371 }
372 else {
373 totedgedata = bm->totedgesel;
374 }
375
376 has_meshdata = (tot || totedgedata);
377 }
378 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
379 TransformMedian_Curve *median = &median_basis.curve;
380 Curve *cu = static_cast<Curve *>(ob->data);
381 BPoint *bp;
382 BezTriple *bezt;
383 int a;
385 StructRNA *seltype = nullptr;
386 void *selp = nullptr;
387
388 LISTBASE_FOREACH (Nurb *, nu, nurbs) {
389 if (nu->type == CU_BEZIER) {
390 bezt = nu->bezt;
391 a = nu->pntsu;
392 while (a--) {
393 if (bezt->f2 & SELECT) {
394 add_v3_v3(median->location, bezt->vec[1]);
395 tot++;
396 median->weight += bezt->weight;
397 median->radius += bezt->radius;
398 median->tilt += bezt->tilt;
399 if (!totcurvedata) { /* I.e. first time... */
400 selp = bezt;
401 seltype = &RNA_BezierSplinePoint;
402 }
403 totcurvedata++;
404 }
405 else {
406 if (bezt->f1 & SELECT) {
407 add_v3_v3(median->location, bezt->vec[0]);
408 tot++;
409 }
410 if (bezt->f3 & SELECT) {
411 add_v3_v3(median->location, bezt->vec[2]);
412 tot++;
413 }
414 }
415 bezt++;
416 }
417 }
418 else {
419 bp = nu->bp;
420 a = nu->pntsu * nu->pntsv;
421 while (a--) {
422 if (bp->f1 & SELECT) {
423 add_v3_v3(median->location, bp->vec);
424 median->b_weight += bp->vec[3];
425 totcurvebweight++;
426 tot++;
427 median->weight += bp->weight;
428 median->radius += bp->radius;
429 median->tilt += bp->tilt;
430 if (!totcurvedata) { /* I.e. first time... */
431 selp = bp;
432 seltype = &RNA_SplinePoint;
433 }
434 totcurvedata++;
435 }
436 bp++;
437 }
438 }
439 }
440
441 if (totcurvedata == 1) {
442 data_ptr = RNA_pointer_create(&cu->id, seltype, selp);
443 }
444 }
445 else if (ob->type == OB_LATTICE) {
446 Lattice *lt = static_cast<Lattice *>(ob->data);
447 TransformMedian_Lattice *median = &median_basis.lattice;
448 BPoint *bp;
449 int a;
450 StructRNA *seltype = nullptr;
451 void *selp = nullptr;
452
453 a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
454 bp = lt->editlatt->latt->def;
455 while (a--) {
456 if (bp->f1 & SELECT) {
457 add_v3_v3(median->location, bp->vec);
458 tot++;
459 median->weight += bp->weight;
460 if (!totlattdata) { /* I.e. first time... */
461 selp = bp;
462 seltype = &RNA_LatticePoint;
463 }
464 totlattdata++;
465 }
466 bp++;
467 }
468
469 if (totlattdata == 1) {
470 data_ptr = RNA_pointer_create(&lt->id, seltype, selp);
471 }
472 }
473
474 if (tot == 0) {
475 uiDefBut(
476 block, UI_BTYPE_LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, nullptr, 0, 0, "");
477 return;
478 }
479
480 /* Location, X/Y/Z */
481 mul_v3_fl(median_basis.generic.location, 1.0f / float(tot));
482 if (v3d->flag & V3D_GLOBAL_STATS) {
483 mul_m4_v3(ob->object_to_world().ptr(), median_basis.generic.location);
484 }
485
486 if (has_meshdata) {
487 TransformMedian_Mesh *median = &median_basis.mesh;
488 if (totedgedata) {
489 median->e_crease /= float(totedgedata);
490 median->be_weight /= float(totedgedata);
491 }
492 if (tot) {
493 median->bv_weight /= float(tot);
494 median->v_crease /= float(tot);
495 if (has_skinradius) {
496 median->skin[0] /= float(tot);
497 median->skin[1] /= float(tot);
498 }
499 }
500 }
501 else if (totcurvedata) {
502 TransformMedian_Curve *median = &median_basis.curve;
503 if (totcurvebweight) {
504 median->b_weight /= float(totcurvebweight);
505 }
506 median->weight /= float(totcurvedata);
507 median->radius /= float(totcurvedata);
508 median->tilt /= float(totcurvedata);
509 }
510 else if (totlattdata) {
511 TransformMedian_Lattice *median = &median_basis.lattice;
512 median->weight /= float(totlattdata);
513 }
514
515 if (block) { /* buttons */
516 uiBut *but;
517 int yi = 200;
518 const float tilt_limit = DEG2RADF(21600.0f);
519 const int butw = 200;
520 const int buth = 20 * UI_SCALE_FAC;
521 const int but_margin = 2;
522 const char *c;
523
524 memcpy(&tfp->ve_median, &median_basis, sizeof(tfp->ve_median));
525
527 if (tot == 1) {
528 if (totcurvedata) {
529 /* Curve */
530 c = IFACE_("Control Point:");
531 }
532 else {
533 /* Mesh or lattice */
534 c = IFACE_("Vertex:");
535 }
536 }
537 else {
538 c = IFACE_("Median:");
539 }
540 uiDefBut(block, UI_BTYPE_LABEL, 0, c, 0, yi -= buth, butw, buth, nullptr, 0, 0, "");
541
543
544 /* Should be no need to translate these. */
545 but = uiDefButF(block,
548 IFACE_("X:"),
549 0,
550 yi -= buth,
551 butw,
552 buth,
553 &tfp->ve_median.generic.location[0],
554 -lim,
555 lim,
556 "");
560 but = uiDefButF(block,
563 IFACE_("Y:"),
564 0,
565 yi -= buth,
566 butw,
567 buth,
568 &tfp->ve_median.generic.location[1],
569 -lim,
570 lim,
571 "");
575 but = uiDefButF(block,
578 IFACE_("Z:"),
579 0,
580 yi -= buth,
581 butw,
582 buth,
583 &tfp->ve_median.generic.location[2],
584 -lim,
585 lim,
586 "");
590
591 if (totcurvebweight == tot) {
592 but = uiDefButF(block,
595 IFACE_("W:"),
596 0,
597 yi -= buth,
598 butw,
599 buth,
600 &(tfp->ve_median.curve.b_weight),
601 0.01,
602 100.0,
603 "");
606 }
607
609 uiDefButBitS(block,
612 B_REDR,
613 IFACE_("Global"),
614 0,
615 yi -= buth + but_margin,
616 100,
617 buth,
618 &v3d->flag,
619 0,
620 0,
621 TIP_("Displays global values"));
622 uiDefButBitS(block,
625 B_REDR,
626 IFACE_("Local"),
627 100,
628 yi,
629 100,
630 buth,
631 &v3d->flag,
632 0,
633 0,
634 TIP_("Displays local values"));
635 UI_block_align_end(block);
636
637 /* Meshes... */
638 if (has_meshdata) {
639 TransformMedian_Mesh *ve_median = &tfp->ve_median.mesh;
640 if (tot) {
641 uiDefBut(block,
643 0,
644 tot == 1 ? IFACE_("Vertex Data:") : IFACE_("Vertices Data:"),
645 0,
646 yi -= buth + but_margin,
647 butw,
648 buth,
649 nullptr,
650 0.0,
651 0.0,
652 "");
653 /* customdata layer added on demand */
654 but = uiDefButF(block,
657 tot == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
658 0,
659 yi -= buth + but_margin,
660 butw,
661 buth,
662 &ve_median->bv_weight,
663 0.0,
664 1.0,
665 TIP_("Vertex weight used by Bevel modifier"));
668 /* customdata layer added on demand */
669 but = uiDefButF(block,
672 tot == 1 ? IFACE_("Vertex Crease:") : IFACE_("Mean Vertex Crease:"),
673 0,
674 yi -= buth + but_margin,
675 butw,
676 buth,
677 &ve_median->v_crease,
678 0.0,
679 1.0,
680 TIP_("Weight used by the Subdivision Surface modifier"));
683 }
684 if (has_skinradius) {
686 but = uiDefButF(block,
689 tot == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"),
690 0,
691 yi -= buth + but_margin,
692 butw,
693 buth,
694 &ve_median->skin[0],
695 0.0,
696 100.0,
697 TIP_("X radius used by Skin modifier"));
700 but = uiDefButF(block,
703 tot == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"),
704 0,
705 yi -= buth + but_margin,
706 butw,
707 buth,
708 &ve_median->skin[1],
709 0.0,
710 100.0,
711 TIP_("Y radius used by Skin modifier"));
714 UI_block_align_end(block);
715 }
716 if (totedgedata) {
717 uiDefBut(block,
719 0,
720 totedgedata == 1 ? IFACE_("Edge Data:") : IFACE_("Edges Data:"),
721 0,
722 yi -= buth + but_margin,
723 butw,
724 buth,
725 nullptr,
726 0.0,
727 0.0,
728 "");
729 /* customdata layer added on demand */
730 but = uiDefButF(block,
733 totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
734 0,
735 yi -= buth + but_margin,
736 butw,
737 buth,
738 &ve_median->be_weight,
739 0.0,
740 1.0,
741 TIP_("Edge weight used by Bevel modifier"));
744 /* customdata layer added on demand */
745 but = uiDefButF(block,
748 totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
749 0,
750 yi -= buth + but_margin,
751 butw,
752 buth,
753 &ve_median->e_crease,
754 0.0,
755 1.0,
756 TIP_("Weight used by the Subdivision Surface modifier"));
759 }
760 }
761 /* Curve... */
762 else if (totcurvedata) {
763 TransformMedian_Curve *ve_median = &tfp->ve_median.curve;
764 if (totcurvedata == 1) {
765 but = uiDefButR(block,
767 0,
768 IFACE_("Weight:"),
769 0,
770 yi -= buth + but_margin,
771 butw,
772 buth,
773 &data_ptr,
774 "weight_softbody",
775 0,
776 0.0,
777 1.0,
778 nullptr);
781 but = uiDefButR(block,
783 0,
784 IFACE_("Radius:"),
785 0,
786 yi -= buth + but_margin,
787 butw,
788 buth,
789 &data_ptr,
790 "radius",
791 0,
792 0.0,
793 100.0,
794 nullptr);
797 but = uiDefButR(block,
799 0,
800 IFACE_("Tilt:"),
801 0,
802 yi -= buth + but_margin,
803 butw,
804 buth,
805 &data_ptr,
806 "tilt",
807 0,
808 -tilt_limit,
810 nullptr);
813 }
814 else if (totcurvedata > 1) {
815 but = uiDefButF(block,
818 IFACE_("Mean Weight:"),
819 0,
820 yi -= buth + but_margin,
821 butw,
822 buth,
823 &ve_median->weight,
824 0.0,
825 1.0,
826 TIP_("Weight used for Soft Body Goal"));
829 but = uiDefButF(block,
832 IFACE_("Mean Radius:"),
833 0,
834 yi -= buth + but_margin,
835 butw,
836 buth,
837 &ve_median->radius,
838 0.0,
839 100.0,
840 TIP_("Radius of curve control points"));
843 but = uiDefButF(block,
846 IFACE_("Mean Tilt:"),
847 0,
848 yi -= buth + but_margin,
849 butw,
850 buth,
851 &ve_median->tilt,
852 -tilt_limit,
854 TIP_("Tilt of curve control points"));
858 }
859 }
860 /* Lattice... */
861 else if (totlattdata) {
862 TransformMedian_Lattice *ve_median = &tfp->ve_median.lattice;
863 if (totlattdata == 1) {
864 but = uiDefButR(block,
866 0,
867 IFACE_("Weight:"),
868 0,
869 yi -= buth + but_margin,
870 butw,
871 buth,
872 &data_ptr,
873 "weight_softbody",
874 0,
875 0.0,
876 1.0,
877 nullptr);
880 }
881 else if (totlattdata > 1) {
882 but = uiDefButF(block,
885 IFACE_("Mean Weight:"),
886 0,
887 yi -= buth + but_margin,
888 butw,
889 buth,
890 &ve_median->weight,
891 0.0,
892 1.0,
893 TIP_("Weight used for Soft Body Goal"));
896 }
897 }
898
899 UI_block_align_end(block);
900
901 if (ob->type == OB_MESH) {
902 Mesh *mesh = static_cast<Mesh *>(ob->data);
903 if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
904 uiBlockInteraction_CallbackData callback_data{};
906 callback_data.end_fn = editmesh_partial_update_end_fn;
907 callback_data.update_fn = editmesh_partial_update_update_fn;
908 callback_data.arg1 = em;
909 UI_block_interaction_set(block, &callback_data);
910 }
911 }
912 }
913 else { /* apply */
914 memcpy(&ve_median_basis, &tfp->ve_median, sizeof(tfp->ve_median));
915
916 if (v3d->flag & V3D_GLOBAL_STATS) {
917 invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
918 mul_m4_v3(ob->world_to_object().ptr(), median_basis.generic.location);
919 mul_m4_v3(ob->world_to_object().ptr(), ve_median_basis.generic.location);
920 }
921 sub_vn_vnvn((float *)&median_basis,
922 (float *)&ve_median_basis,
923 (float *)&median_basis,
925
926 /* Note with a single element selected, we always do. */
927 const bool apply_vcos = (tot == 1) || (len_squared_v3(median_basis.generic.location) != 0.0f);
928
929 if ((ob->type == OB_MESH) &&
930 (apply_vcos || median_basis.mesh.bv_weight || median_basis.mesh.v_crease ||
931 median_basis.mesh.skin[0] || median_basis.mesh.skin[1] || median_basis.mesh.be_weight ||
932 median_basis.mesh.e_crease))
933 {
934 const TransformMedian_Mesh *median = &median_basis.mesh, *ve_median = &ve_median_basis.mesh;
935 Mesh *mesh = static_cast<Mesh *>(ob->data);
936 BMEditMesh *em = mesh->runtime->edit_mesh.get();
937 BMesh *bm = em->bm;
938 BMIter iter;
939 BMVert *eve;
940 BMEdge *eed;
941
942 int cd_vert_bweight_offset = -1;
943 int cd_vert_crease_offset = -1;
944 int cd_vert_skin_offset = -1;
945 int cd_edge_bweight_offset = -1;
946 int cd_edge_crease_offset = -1;
947
948 float scale_bv_weight = 1.0f;
949 float scale_v_crease = 1.0f;
950 float scale_skin[2] = {1.0f, 1.0f};
951 float scale_be_weight = 1.0f;
952 float scale_e_crease = 1.0f;
953
954 /* Vertices */
955
956 if (apply_vcos || median->bv_weight || median->v_crease || median->skin[0] ||
957 median->skin[1])
958 {
959 if (median->bv_weight) {
960 if (!CustomData_has_layer_named(&bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert")) {
961 BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert");
962 }
963 cd_vert_bweight_offset = CustomData_get_offset_named(
964 &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert");
965 BLI_assert(cd_vert_bweight_offset != -1);
966
967 scale_bv_weight = compute_scale_factor(ve_median->bv_weight, median->bv_weight);
968 }
969
970 if (median->v_crease) {
971 if (!CustomData_has_layer_named(&bm->vdata, CD_PROP_FLOAT, "crease_vert")) {
972 BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_FLOAT, "crease_vert");
973 }
974 cd_vert_crease_offset = CustomData_get_offset_named(
975 &bm->vdata, CD_PROP_FLOAT, "crease_vert");
976 BLI_assert(cd_vert_crease_offset != -1);
977
978 scale_v_crease = compute_scale_factor(ve_median->v_crease, median->v_crease);
979 }
980
981 for (int i = 0; i < 2; i++) {
982 if (median->skin[i]) {
983 cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
984 BLI_assert(cd_vert_skin_offset != -1);
985
986 if (ve_median->skin[i] != median->skin[i]) {
987 scale_skin[i] = ve_median->skin[i] / (ve_median->skin[i] - median->skin[i]);
988 }
989 }
990 }
991
992 BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
994 if (apply_vcos) {
995 apply_raw_diff_v3(eve->co, tot, ve_median->location, median->location);
996 }
997
998 if (cd_vert_bweight_offset != -1) {
999 float *b_weight = static_cast<float *>(
1000 BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset));
1001 apply_scale_factor_clamp(b_weight, tot, ve_median->bv_weight, scale_bv_weight);
1002 }
1003
1004 if (cd_vert_crease_offset != -1) {
1005 float *crease = static_cast<float *>(
1006 BM_ELEM_CD_GET_VOID_P(eve, cd_vert_crease_offset));
1007 apply_scale_factor_clamp(crease, tot, ve_median->v_crease, scale_v_crease);
1008 }
1009
1010 if (cd_vert_skin_offset != -1) {
1011 MVertSkin *vs = static_cast<MVertSkin *>(
1012 BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset));
1013
1014 /* That one is not clamped to [0.0, 1.0]. */
1015 for (int i = 0; i < 2; i++) {
1016 if (median->skin[i] != 0.0f) {
1018 &vs->radius[i], tot, ve_median->skin[i], median->skin[i], scale_skin[i]);
1019 }
1020 }
1021 }
1022 }
1023 }
1024 }
1025
1026 if (apply_vcos) {
1027 /* Tell the update callback to run. */
1028 tfp->tag_for_update = true;
1029 }
1030
1031 /* Edges */
1032
1033 if (median->be_weight || median->e_crease) {
1034 if (median->be_weight) {
1035 if (!CustomData_has_layer_named(&bm->edata, CD_PROP_FLOAT, "bevel_weight_edge")) {
1036 BM_data_layer_add_named(bm, &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge");
1037 }
1038 cd_edge_bweight_offset = CustomData_get_offset_named(
1039 &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge");
1040 BLI_assert(cd_edge_bweight_offset != -1);
1041
1042 scale_be_weight = compute_scale_factor(ve_median->be_weight, median->be_weight);
1043 }
1044
1045 if (median->e_crease) {
1046 if (!CustomData_has_layer_named(&bm->edata, CD_PROP_FLOAT, "crease_edge")) {
1047 BM_data_layer_add_named(bm, &bm->edata, CD_PROP_FLOAT, "crease_edge");
1048 }
1049 cd_edge_crease_offset = CustomData_get_offset_named(
1050 &bm->edata, CD_PROP_FLOAT, "crease_edge");
1051 BLI_assert(cd_edge_crease_offset != -1);
1052
1053 scale_e_crease = compute_scale_factor(ve_median->e_crease, median->e_crease);
1054 }
1055
1056 BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
1058 if (median->be_weight != 0.0f) {
1059 float *b_weight = static_cast<float *>(
1060 BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset));
1061 apply_scale_factor_clamp(b_weight, tot, ve_median->be_weight, scale_be_weight);
1062 }
1063
1064 if (median->e_crease != 0.0f) {
1065 float *crease = static_cast<float *>(
1066 BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset));
1067 apply_scale_factor_clamp(crease, tot, ve_median->e_crease, scale_e_crease);
1068 }
1069 }
1070 }
1071 }
1072 }
1073 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF) &&
1074 (apply_vcos || median_basis.curve.b_weight || median_basis.curve.weight ||
1075 median_basis.curve.radius || median_basis.curve.tilt))
1076 {
1077 const TransformMedian_Curve *median = &median_basis.curve,
1078 *ve_median = &ve_median_basis.curve;
1079 Curve *cu = static_cast<Curve *>(ob->data);
1080 BPoint *bp;
1081 BezTriple *bezt;
1082 int a;
1083 ListBase *nurbs = BKE_curve_editNurbs_get(cu);
1084 const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
1085
1086 LISTBASE_FOREACH (Nurb *, nu, nurbs) {
1087 if (nu->type == CU_BEZIER) {
1088 for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
1089 if (bezt->f2 & SELECT) {
1090 if (apply_vcos) {
1091 /* Here we always have to use the diff... :/
1092 * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see #37327),
1093 * unless we use doubles.
1094 */
1095 add_v3_v3(bezt->vec[0], median->location);
1096 add_v3_v3(bezt->vec[1], median->location);
1097 add_v3_v3(bezt->vec[2], median->location);
1098 }
1099 if (median->weight) {
1100 apply_scale_factor_clamp(&bezt->weight, tot, ve_median->weight, scale_w);
1101 }
1102 if (median->radius) {
1103 apply_raw_diff(&bezt->radius, tot, ve_median->radius, median->radius);
1104 }
1105 if (median->tilt) {
1106 apply_raw_diff(&bezt->tilt, tot, ve_median->tilt, median->tilt);
1107 }
1108 }
1109 else if (apply_vcos) {
1110 /* Handles can only have their coordinates changed here. */
1111 if (bezt->f1 & SELECT) {
1112 apply_raw_diff_v3(bezt->vec[0], tot, ve_median->location, median->location);
1113 }
1114 if (bezt->f3 & SELECT) {
1115 apply_raw_diff_v3(bezt->vec[2], tot, ve_median->location, median->location);
1116 }
1117 }
1118 }
1119 }
1120 else {
1121 for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a--; bp++) {
1122 if (bp->f1 & SELECT) {
1123 if (apply_vcos) {
1124 apply_raw_diff_v3(bp->vec, tot, ve_median->location, median->location);
1125 }
1126 if (median->b_weight) {
1127 apply_raw_diff(&bp->vec[3], tot, ve_median->b_weight, median->b_weight);
1128 }
1129 if (median->weight) {
1130 apply_scale_factor_clamp(&bp->weight, tot, ve_median->weight, scale_w);
1131 }
1132 if (median->radius) {
1133 apply_raw_diff(&bp->radius, tot, ve_median->radius, median->radius);
1134 }
1135 if (median->tilt) {
1136 apply_raw_diff(&bp->tilt, tot, ve_median->tilt, median->tilt);
1137 }
1138 }
1139 }
1140 }
1141 if (CU_IS_2D(cu)) {
1143 }
1144 /* In the case of weight, tilt or radius (these don't change positions),
1145 * don't change handle types. */
1146 if ((nu->type == CU_BEZIER) && apply_vcos) {
1147 BKE_nurb_handles_test(nu, NURB_HANDLE_TEST_EACH, false); /* test for bezier too */
1148 }
1149 }
1150 }
1151 else if ((ob->type == OB_LATTICE) && (apply_vcos || median_basis.lattice.weight)) {
1152 const TransformMedian_Lattice *median = &median_basis.lattice,
1153 *ve_median = &ve_median_basis.lattice;
1154 Lattice *lt = static_cast<Lattice *>(ob->data);
1155 BPoint *bp;
1156 int a;
1157 const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
1158
1159 a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
1160 bp = lt->editlatt->latt->def;
1161 while (a--) {
1162 if (bp->f1 & SELECT) {
1163 if (apply_vcos) {
1164 apply_raw_diff_v3(bp->vec, tot, ve_median->location, median->location);
1165 }
1166 if (median->weight) {
1167 apply_scale_factor_clamp(&bp->weight, tot, ve_median->weight, scale_w);
1168 }
1169 }
1170 bp++;
1171 }
1172 }
1173
1174 // ED_undo_push(C, "Transform properties");
1175 }
1176}
1177
1178#undef TRANSFORM_MEDIAN_ARRAY_LEN
1179
1180static void v3d_object_dimension_buts(bContext *C, uiLayout *layout, View3D *v3d, Object *ob)
1181{
1182 uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : nullptr;
1184
1185 if (block) {
1186 BLI_assert(C == nullptr);
1187 int yi = 200;
1188 const int butw = 200;
1189 const int buth = 20 * UI_SCALE_FAC;
1190
1192 copy_v3_v3(tfp->ob_dims_orig, tfp->ob_dims);
1193 copy_v3_v3(tfp->ob_scale_orig, ob->scale);
1194 copy_m4_m4(tfp->ob_obmat_orig, ob->object_to_world().ptr());
1195
1196 uiDefBut(block,
1198 0,
1199 IFACE_("Dimensions:"),
1200 0,
1201 yi -= buth,
1202 butw,
1203 buth,
1204 nullptr,
1205 0,
1206 0,
1207 "");
1208 UI_block_align_begin(block);
1209 const float lim = FLT_MAX;
1210 for (int i = 0; i < 3; i++) {
1211 uiBut *but;
1212 const char text[3] = {char('X' + i), ':', '\0'};
1213 but = uiDefButF(block,
1216 text,
1217 0,
1218 yi -= buth,
1219 butw,
1220 buth,
1221 &(tfp->ob_dims[i]),
1222 0.0f,
1223 lim,
1224 "");
1228 }
1229 UI_block_align_end(block);
1230 }
1231 else { /* apply */
1232 int axis_mask = 0;
1233 for (int i = 0; i < 3; i++) {
1234 if (tfp->ob_dims[i] == tfp->ob_dims_orig[i]) {
1235 axis_mask |= (1 << i);
1236 }
1237 }
1239 ob, tfp->ob_dims, axis_mask, tfp->ob_scale_orig, tfp->ob_obmat_orig);
1240
1241 PointerRNA obptr = RNA_id_pointer_create(&ob->id);
1242 PropertyRNA *prop = RNA_struct_find_property(&obptr, "scale");
1243 RNA_property_update(C, &obptr, prop);
1244 }
1245}
1246
1247#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
1248
1249static void do_view3d_vgroup_buttons(bContext *C, void * /*arg*/, int event)
1250{
1251 if (event < B_VGRP_PNL_EDIT_SINGLE) {
1252 /* not for me */
1253 return;
1254 }
1255
1256 const Scene *scene = CTX_data_scene(C);
1257 ViewLayer *view_layer = CTX_data_view_layer(C);
1258 BKE_view_layer_synced_ensure(scene, view_layer);
1259 Object *ob = BKE_view_layer_active_object_get(view_layer);
1261 DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_GEOMETRY);
1263}
1264
1265static bool view3d_panel_vgroup_poll(const bContext *C, PanelType * /*pt*/)
1266{
1267 const Scene *scene = CTX_data_scene(C);
1268 ViewLayer *view_layer = CTX_data_view_layer(C);
1269 BKE_view_layer_synced_ensure(scene, view_layer);
1270 Object *ob = BKE_view_layer_active_object_get(view_layer);
1273 if (dvert_act) {
1274 return (dvert_act->totweight != 0);
1275 }
1276 }
1277
1278 return false;
1279}
1280
1281static void update_active_vertex_weight(bContext *C, void *arg1, void * /*arg2*/)
1282{
1283 View3D *v3d = CTX_wm_view3d(C);
1285 ViewLayer *view_layer = CTX_data_view_layer(C);
1286 Object *ob = BKE_view_layer_active_object_get(view_layer);
1288 const int vertex_group_index = POINTER_AS_INT(arg1);
1289 MDeformWeight *dw = BKE_defvert_find_index(dv, vertex_group_index);
1290 dw->weight = tfp->vertex_weights[vertex_group_index];
1291}
1292
1293static void view3d_panel_vgroup(const bContext *C, Panel *panel)
1294{
1295 uiBlock *block = uiLayoutAbsoluteBlock(panel->layout);
1296 Scene *scene = CTX_data_scene(C);
1297 ViewLayer *view_layer = CTX_data_view_layer(C);
1298 BKE_view_layer_synced_ensure(scene, view_layer);
1299 Object *ob = BKE_view_layer_active_object_get(view_layer);
1300 View3D *v3d = CTX_wm_view3d(C);
1302
1303 MDeformVert *dv;
1304
1306
1307 if (dv && dv->totweight) {
1308 ToolSettings *ts = scene->toolsettings;
1309
1311 PointerRNA op_ptr;
1312 PointerRNA *but_ptr;
1313
1314 uiLayout *col, *bcol;
1315 uiLayout *row;
1316 uiBut *but;
1317 bDeformGroup *dg;
1318 uint i;
1319 int subset_count, vgroup_tot;
1320 const bool *vgroup_validmap;
1321 eVGroupSelect subset_type = eVGroupSelect(ts->vgroupsubset);
1322 int yco = 0;
1323 int lock_count = 0;
1324
1326
1327 bcol = uiLayoutColumn(panel->layout, true);
1328 row = uiLayoutRow(bcol, true); /* The filter button row */
1329
1330 PointerRNA tools_ptr = RNA_pointer_create(nullptr, &RNA_ToolSettings, ts);
1331 uiItemR(row, &tools_ptr, "vertex_group_subset", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
1332
1333 col = uiLayoutColumn(bcol, true);
1334
1336 ob, subset_type, &vgroup_tot, &subset_count);
1337 const ListBase *defbase = BKE_object_defgroup_list(ob);
1338 const int vgroup_num = BLI_listbase_count(defbase);
1339 tfp->vertex_weights.resize(vgroup_num);
1340
1341 for (i = 0, dg = static_cast<bDeformGroup *>(defbase->first); dg; i++, dg = dg->next) {
1342 bool locked = (dg->flag & DG_LOCK_WEIGHT) != 0;
1343 if (vgroup_validmap[i]) {
1345 if (dw) {
1346 int x, xco = 0;
1347 int icon;
1348 uiLayout *split = uiLayoutSplit(col, 0.45, true);
1349 row = uiLayoutRow(split, true);
1350
1351 /* The Weight Group Name */
1352
1353 ot = WM_operatortype_find("OBJECT_OT_vertex_weight_set_active", true);
1354 but = uiDefButO_ptr(block,
1356 ot,
1358 dg->name,
1359 xco,
1360 yco,
1361 (x = UI_UNIT_X * 5),
1362 UI_UNIT_Y,
1363 "");
1364 but_ptr = UI_but_operator_ptr_ensure(but);
1365 RNA_int_set(but_ptr, "weight_group", i);
1367 if (BKE_object_defgroup_active_index_get(ob) != i + 1) {
1369 }
1370 xco += x;
1371
1372 row = uiLayoutRow(split, true);
1373 uiLayoutSetEnabled(row, !locked);
1374
1375 /* The weight group value */
1376 /* To be reworked still */
1377 float &vertex_weight = tfp->vertex_weights[i];
1378 vertex_weight = dw->weight;
1379 but = uiDefButF(block,
1382 "",
1383 xco,
1384 yco,
1385 (x = UI_UNIT_X * 4),
1386 UI_UNIT_Y,
1387 &vertex_weight,
1388 0.0,
1389 1.0,
1390 "");
1395 if (locked) {
1396 lock_count++;
1397 }
1398 xco += x;
1399
1400 /* The weight group paste function */
1401 icon = (locked) ? ICON_BLANK1 : ICON_PASTEDOWN;
1402 uiItemFullO(row,
1403 "OBJECT_OT_vertex_weight_paste",
1404 "",
1405 icon,
1406 nullptr,
1409 &op_ptr);
1410 RNA_int_set(&op_ptr, "weight_group", i);
1411
1412 /* The weight entry delete function */
1413 icon = (locked) ? ICON_LOCKED : ICON_X;
1414 uiItemFullO(row,
1415 "OBJECT_OT_vertex_weight_delete",
1416 "",
1417 icon,
1418 nullptr,
1421 &op_ptr);
1422 RNA_int_set(&op_ptr, "weight_group", i);
1423
1424 yco -= UI_UNIT_Y;
1425 }
1426 }
1427 }
1428 MEM_freeN((void *)vgroup_validmap);
1429
1430 yco -= 2;
1431
1432 col = uiLayoutColumn(panel->layout, true);
1433 row = uiLayoutRow(col, true);
1434
1435 ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active_vertex", true);
1436 but = uiDefButO_ptr(
1437 block,
1439 ot,
1441 IFACE_("Normalize"),
1442 0,
1443 yco,
1444 UI_UNIT_X * 5,
1445 UI_UNIT_Y,
1446 TIP_("Normalize weights of active vertex (if affected groups are unlocked)"));
1447 if (lock_count) {
1449 }
1450
1451 ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", true);
1452 but = uiDefButO_ptr(
1453 block,
1455 ot,
1457 IFACE_("Copy"),
1458 UI_UNIT_X * 5,
1459 yco,
1460 UI_UNIT_X * 5,
1461 UI_UNIT_Y,
1462 TIP_("Copy active vertex to other selected vertices (if affected groups are unlocked)"));
1463 if (lock_count) {
1465 }
1466 }
1467}
1468
1470{
1471 uiLayout *split, *colsub;
1472
1473 split = uiLayoutSplit(layout, 0.8f, false);
1474
1475 if (ptr->type == &RNA_PoseBone) {
1476 PointerRNA boneptr;
1477 Bone *bone;
1478
1479 boneptr = RNA_pointer_get(ptr, "bone");
1480 bone = static_cast<Bone *>(boneptr.data);
1481 uiLayoutSetActive(split, !(bone->parent && bone->flag & BONE_CONNECTED));
1482 }
1483 colsub = uiLayoutColumn(split, true);
1484 uiItemR(colsub, ptr, "location", UI_ITEM_NONE, nullptr, ICON_NONE);
1485 colsub = uiLayoutColumn(split, true);
1487 uiItemL(colsub, "", ICON_NONE);
1488 uiItemR(colsub,
1489 ptr,
1490 "lock_location",
1492 "",
1493 ICON_DECORATE_UNLOCKED);
1494
1495 split = uiLayoutSplit(layout, 0.8f, false);
1496
1497 switch (RNA_enum_get(ptr, "rotation_mode")) {
1498 case ROT_MODE_QUAT: /* quaternion */
1499 colsub = uiLayoutColumn(split, true);
1500 uiItemR(colsub, ptr, "rotation_quaternion", UI_ITEM_NONE, IFACE_("Rotation"), ICON_NONE);
1501 colsub = uiLayoutColumn(split, true);
1503 uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
1504 if (RNA_boolean_get(ptr, "lock_rotations_4d")) {
1505 uiItemR(colsub,
1506 ptr,
1507 "lock_rotation_w",
1509 "",
1510 ICON_DECORATE_UNLOCKED);
1511 }
1512 else {
1513 uiItemL(colsub, "", ICON_NONE);
1514 }
1515 uiItemR(colsub,
1516 ptr,
1517 "lock_rotation",
1519 "",
1520 ICON_DECORATE_UNLOCKED);
1521 break;
1522 case ROT_MODE_AXISANGLE: /* axis angle */
1523 colsub = uiLayoutColumn(split, true);
1524 uiItemR(colsub, ptr, "rotation_axis_angle", UI_ITEM_NONE, IFACE_("Rotation"), ICON_NONE);
1525 colsub = uiLayoutColumn(split, true);
1527 uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
1528 if (RNA_boolean_get(ptr, "lock_rotations_4d")) {
1529 uiItemR(colsub,
1530 ptr,
1531 "lock_rotation_w",
1533 "",
1534 ICON_DECORATE_UNLOCKED);
1535 }
1536 else {
1537 uiItemL(colsub, "", ICON_NONE);
1538 }
1539 uiItemR(colsub,
1540 ptr,
1541 "lock_rotation",
1543 "",
1544 ICON_DECORATE_UNLOCKED);
1545 break;
1546 default: /* euler rotations */
1547 colsub = uiLayoutColumn(split, true);
1548 uiItemR(colsub, ptr, "rotation_euler", UI_ITEM_NONE, IFACE_("Rotation"), ICON_NONE);
1549 colsub = uiLayoutColumn(split, true);
1551 uiItemL(colsub, "", ICON_NONE);
1552 uiItemR(colsub,
1553 ptr,
1554 "lock_rotation",
1556 "",
1557 ICON_DECORATE_UNLOCKED);
1558 break;
1559 }
1560 uiItemR(layout, ptr, "rotation_mode", UI_ITEM_NONE, "", ICON_NONE);
1561
1562 split = uiLayoutSplit(layout, 0.8f, false);
1563 colsub = uiLayoutColumn(split, true);
1564 uiItemR(colsub, ptr, "scale", UI_ITEM_NONE, nullptr, ICON_NONE);
1565 colsub = uiLayoutColumn(split, true);
1567 uiItemL(colsub, "", ICON_NONE);
1568 uiItemR(colsub,
1569 ptr,
1570 "lock_scale",
1572 "",
1573 ICON_DECORATE_UNLOCKED);
1574}
1575
1576static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
1577{
1578 bPoseChannel *pchan;
1579 uiLayout *col;
1580
1582
1583 if (!pchan) {
1584 uiItemL(layout, IFACE_("No Bone Active"), ICON_NONE);
1585 return;
1586 }
1587
1588 PointerRNA pchanptr = RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan);
1589
1590 col = uiLayoutColumn(layout, false);
1591
1592 /* XXX: RNA buts show data in native types (i.e. quaternion, 4-component axis/angle, etc.)
1593 * but old-school UI shows in eulers always. Do we want to be able to still display in Eulers?
1594 * Maybe needs RNA/UI options to display rotations as different types. */
1595 v3d_transform_butsR(col, &pchanptr);
1596}
1597
1598static void v3d_editarmature_buts(uiLayout *layout, Object *ob)
1599{
1600 bArmature *arm = static_cast<bArmature *>(ob->data);
1601 EditBone *ebone;
1602 uiLayout *col;
1603
1604 ebone = arm->act_edbone;
1605
1606 if (!ebone || !ANIM_bonecoll_is_visible_editbone(arm, ebone)) {
1607 uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE);
1608 return;
1609 }
1610
1611 PointerRNA eboneptr = RNA_pointer_create(&arm->id, &RNA_EditBone, ebone);
1612
1613 col = uiLayoutColumn(layout, false);
1614 uiItemR(col, &eboneptr, "head", UI_ITEM_NONE, nullptr, ICON_NONE);
1615 if (ebone->parent && ebone->flag & BONE_CONNECTED) {
1616 PointerRNA parptr = RNA_pointer_get(&eboneptr, "parent");
1617 uiItemR(col, &parptr, "tail_radius", UI_ITEM_NONE, IFACE_("Radius (Parent)"), ICON_NONE);
1618 }
1619 else {
1620 uiItemR(col, &eboneptr, "head_radius", UI_ITEM_NONE, IFACE_("Radius"), ICON_NONE);
1621 }
1622
1623 uiItemR(col, &eboneptr, "tail", UI_ITEM_NONE, nullptr, ICON_NONE);
1624 uiItemR(col, &eboneptr, "tail_radius", UI_ITEM_NONE, IFACE_("Radius"), ICON_NONE);
1625
1626 uiItemR(col, &eboneptr, "roll", UI_ITEM_NONE, nullptr, ICON_NONE);
1627 uiItemR(col, &eboneptr, "length", UI_ITEM_NONE, nullptr, ICON_NONE);
1628 uiItemR(col, &eboneptr, "envelope_distance", UI_ITEM_NONE, IFACE_("Envelope"), ICON_NONE);
1629}
1630
1631static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
1632{
1633 MetaBall *mball = static_cast<MetaBall *>(ob->data);
1634 uiLayout *col;
1635
1636 if (!mball || !(mball->lastelem)) {
1637 uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE);
1638 return;
1639 }
1640
1641 PointerRNA ptr = RNA_pointer_create(&mball->id, &RNA_MetaElement, mball->lastelem);
1642
1643 col = uiLayoutColumn(layout, false);
1644 uiItemR(col, &ptr, "co", UI_ITEM_NONE, nullptr, ICON_NONE);
1645
1646 uiItemR(col, &ptr, "radius", UI_ITEM_NONE, nullptr, ICON_NONE);
1647 uiItemR(col, &ptr, "stiffness", UI_ITEM_NONE, nullptr, ICON_NONE);
1648
1649 uiItemR(col, &ptr, "type", UI_ITEM_NONE, nullptr, ICON_NONE);
1650
1651 col = uiLayoutColumn(layout, true);
1652 switch (RNA_enum_get(&ptr, "type")) {
1653 case MB_BALL:
1654 break;
1655 case MB_CUBE:
1656 uiItemL(col, IFACE_("Size:"), ICON_NONE);
1657 uiItemR(col, &ptr, "size_x", UI_ITEM_NONE, "X", ICON_NONE);
1658 uiItemR(col, &ptr, "size_y", UI_ITEM_NONE, "Y", ICON_NONE);
1659 uiItemR(col, &ptr, "size_z", UI_ITEM_NONE, "Z", ICON_NONE);
1660 break;
1661 case MB_TUBE:
1662 uiItemL(col, IFACE_("Size:"), ICON_NONE);
1663 uiItemR(col, &ptr, "size_x", UI_ITEM_NONE, "X", ICON_NONE);
1664 break;
1665 case MB_PLANE:
1666 uiItemL(col, IFACE_("Size:"), ICON_NONE);
1667 uiItemR(col, &ptr, "size_x", UI_ITEM_NONE, "X", ICON_NONE);
1668 uiItemR(col, &ptr, "size_y", UI_ITEM_NONE, "Y", ICON_NONE);
1669 break;
1670 case MB_ELIPSOID:
1671 uiItemL(col, IFACE_("Size:"), ICON_NONE);
1672 uiItemR(col, &ptr, "size_x", UI_ITEM_NONE, "X", ICON_NONE);
1673 uiItemR(col, &ptr, "size_y", UI_ITEM_NONE, "Y", ICON_NONE);
1674 uiItemR(col, &ptr, "size_z", UI_ITEM_NONE, "Z", ICON_NONE);
1675 break;
1676 }
1677}
1678
1679static void do_view3d_region_buttons(bContext *C, void * /*index*/, int event)
1680{
1681 Scene *scene = CTX_data_scene(C);
1682 ViewLayer *view_layer = CTX_data_view_layer(C);
1683 View3D *v3d = CTX_wm_view3d(C);
1684 BKE_view_layer_synced_ensure(scene, view_layer);
1685 Object *ob = BKE_view_layer_active_object_get(view_layer);
1686
1687 switch (event) {
1688
1689 case B_REDR:
1691 return; /* no notifier! */
1692
1694 if (ob) {
1695 v3d_editvertex_buts(nullptr, v3d, ob, 1.0);
1696 DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_GEOMETRY);
1697 }
1698 break;
1700 if (ob) {
1701 v3d_object_dimension_buts(C, nullptr, v3d, ob);
1702 }
1703 break;
1704 }
1705
1706 /* default for now */
1708}
1709
1710static bool view3d_panel_transform_poll(const bContext *C, PanelType * /*pt*/)
1711{
1712 const Scene *scene = CTX_data_scene(C);
1713 ViewLayer *view_layer = CTX_data_view_layer(C);
1714 BKE_view_layer_synced_ensure(scene, view_layer);
1715 return (BKE_view_layer_active_base_get(view_layer) != nullptr);
1716}
1717
1718static void view3d_panel_transform(const bContext *C, Panel *panel)
1719{
1720 uiBlock *block;
1721 const Scene *scene = CTX_data_scene(C);
1722 ViewLayer *view_layer = CTX_data_view_layer(C);
1723 BKE_view_layer_synced_ensure(scene, view_layer);
1724 Object *ob = BKE_view_layer_active_object_get(view_layer);
1725 Object *obedit = OBEDIT_FROM_OBACT(ob);
1726 uiLayout *col;
1727
1728 block = uiLayoutGetBlock(panel->layout);
1730
1731 col = uiLayoutColumn(panel->layout, false);
1732
1733 if (ob == obedit) {
1734 if (ob->type == OB_ARMATURE) {
1736 }
1737 else if (ob->type == OB_MBALL) {
1739 }
1740 else {
1741 View3D *v3d = CTX_wm_view3d(C);
1742 v3d_editvertex_buts(col, v3d, ob, FLT_MAX);
1743 }
1744 }
1745 else if (ob->mode & OB_MODE_POSE) {
1747 }
1748 else {
1749 PointerRNA obptr = RNA_id_pointer_create(&ob->id);
1750 v3d_transform_butsR(col, &obptr);
1751
1752 /* Dimensions and editmode are mostly the same check. */
1754 {
1755 View3D *v3d = CTX_wm_view3d(C);
1756 v3d_object_dimension_buts(nullptr, col, v3d, ob);
1757 }
1758 }
1759}
1760
1765
1767{
1768 PanelType *pt;
1769
1770 pt = static_cast<PanelType *>(MEM_callocN(sizeof(PanelType), "spacetype view3d panel object"));
1771 STRNCPY(pt->idname, "VIEW3D_PT_transform");
1772 STRNCPY(pt->label, N_("Transform")); /* XXX C panels unavailable through RNA bpy.types! */
1773 STRNCPY(pt->category, "Item");
1777 BLI_addtail(&art->paneltypes, pt);
1778
1779 pt = static_cast<PanelType *>(MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup"));
1780 STRNCPY(pt->idname, "VIEW3D_PT_vgroup");
1781 STRNCPY(pt->label, N_("Vertex Weights")); /* XXX C panels unavailable through RNA bpy.types! */
1782 STRNCPY(pt->category, "Item");
1786 BLI_addtail(&art->paneltypes, pt);
1787
1788 MenuType *mt;
1789
1790 mt = static_cast<MenuType *>(MEM_callocN(sizeof(MenuType), "spacetype view3d menu collections"));
1791 STRNCPY(mt->idname, "VIEW3D_MT_collection");
1792 STRNCPY(mt->label, N_("Collection"));
1795 WM_menutype_add(mt);
1796}
1797
1799{
1801 if (ob == nullptr) {
1802 BKE_report(op->reports, RPT_WARNING, "No active object found");
1803 return OPERATOR_CANCELLED;
1804 }
1805 if (((ob->mode & OB_MODE_EDIT) == 0) && ELEM(ob->type, OB_ARMATURE)) {
1807 return OPERATOR_CANCELLED;
1808 }
1809
1810 UI_pie_menu_invoke(C, "VIEW3D_MT_object_mode_pie", CTX_wm_window(C)->eventstate);
1811 return OPERATOR_CANCELLED;
1812}
1813
1815{
1816 ot->name = "Object Mode Menu";
1817 ot->idname = "VIEW3D_OT_object_mode_pie_or_toggle";
1818
1821
1822 /* flags */
1823 ot->flag = 0;
1824}
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
bool ANIM_bonecoll_is_visible_editbone(const bArmature *armature, const EditBone *ebone)
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_active_if_bonecoll_visible(Object *ob) ATTR_WARN_UNUSED_RESULT
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
@ NURB_HANDLE_TEST_EACH
Definition BKE_curve.hh:58
void BKE_nurb_project_2d(Nurb *nu)
Definition curve.cc:683
#define CU_IS_2D(cu)
Definition BKE_curve.hh:86
void BKE_nurb_handles_test(Nurb *nu, eNurbHandleTest_Mode handle_mode, bool use_around_local)
Definition curve.cc:4082
ListBase * BKE_curve_editNurbs_get(Curve *cu)
Definition curve.cc:398
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
support for deformation groups and hooks.
int BKE_object_defgroup_active_index_get(const Object *ob)
Definition deform.cc:601
const ListBase * BKE_object_defgroup_list(const Object *ob)
Definition deform.cc:579
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dv, int defgroup)
Definition deform.cc:795
void BKE_editmesh_looptris_and_normals_calc_with_partial(BMEditMesh *em, BMPartialUpdate *bmpinfo)
Definition editmesh.cc:110
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Base * BKE_view_layer_active_base_get(ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
General operations, lookup, etc. for blender objects.
void BKE_object_dimensions_set_ex(Object *ob, const float value[3], int axis_mask, const float ob_scale_orig[3], const float ob_obmat_orig[4][4])
bool BKE_object_is_in_wpaint_select_vert(const Object *ob)
void BKE_object_dimensions_eval_cached_get(Object *ob, float r_vec[3])
bool BKE_object_is_in_editmode_vgroup(const Object *ob)
Functions for dealing with objects and deform verts, used by painting and tools.
bool * BKE_object_defgroup_subset_from_select_type(struct Object *ob, enum eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
Generic array manipulation API.
#define BLI_array_findindex(arr, arr_len, p)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition BLI_bitmap.h:41
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition BLI_bitmap.h:82
unsigned int BLI_bitmap
Definition BLI_bitmap.h:17
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void mul_m4_v3(const float M[4][4], float r[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
#define DEG2RADF(_deg)
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_fl(float r[3], float f)
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void copy_vn_fl(float *array_tar, int size, float val)
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void add_v3_v3(float r[3], const float a[3])
#define STRNCPY(dst, src)
Definition BLI_string.h:593
unsigned int uint
#define CLAMP(a, b, c)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define ELEM(...)
#define TIP_(msgid)
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ROT_MODE_QUAT
@ ROT_MODE_AXISANGLE
@ BONE_CONNECTED
@ CU_BEZIER
@ CD_MVERT_SKIN
@ CD_PROP_FLOAT
@ MB_PLANE
@ MB_ELIPSOID
@ MB_TUBE
@ MB_CUBE
@ MB_BALL
@ OB_MODE_EDIT
@ OB_MODE_POSE
@ OB_MODE_OBJECT
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_ARMATURE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
@ DG_LOCK_WEIGHT
#define OB_TYPE_SUPPORT_EDITMODE(_type)
eVGroupSelect
#define OBEDIT_FROM_OBACT(ob)
#define UI_SCALE_FAC
@ V3D_GLOBAL_STATS
MDeformVert * ED_mesh_active_dvert_get_only(Object *ob)
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:708
bool ED_operator_view3d_active(bContext *C)
static void split(const char *text, const char *seps, char ***str, int *count)
Read Guarded memory(de)allocation.
@ PROP_UNIT_ROTATION
Definition RNA_types.hh:81
@ PROP_UNIT_LENGTH
Definition RNA_types.hh:77
#define RNA_TRANSLATION_PREC_DEFAULT
Definition RNA_types.hh:127
void UI_but_func_set(uiBut *but, std::function< void(bContext &)> func)
#define UI_UNIT_Y
void uiLayoutSetActive(uiLayout *layout, bool active)
@ UI_EMBOSS_NONE_OR_STATUS
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
void UI_block_interaction_set(uiBlock *block, uiBlockInteraction_CallbackData *callbacks)
uiBut * uiDefBut(uiBlock *block, int type, int retval, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, const char *tip)
void uiItemL(uiLayout *layout, const char *name, int icon)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, IDProperty *properties, wmOperatorCallContext context, eUI_Item_Flag flag, PointerRNA *r_opptr)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void UI_but_drawflag_enable(uiBut *but, int flag)
void UI_but_number_step_size_set(uiBut *but, float step_size)
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
uiBut * uiDefButO_ptr(uiBlock *block, int type, wmOperatorType *ot, wmOperatorCallContext opcontext, blender::StringRef str, int x, int y, short width, short height, const char *tip)
#define UI_ITEM_NONE
uiBut * uiDefButF(uiBlock *block, int type, int retval, blender::StringRef str, int x, int y, short width, short height, float *poin, float min, float max, const char *tip)
uiBut * uiDefButBitS(uiBlock *block, int type, int bit, int retval, blender::StringRef str, int x, int y, short width, short height, short *poin, float min, float max, const char *tip)
PointerRNA * UI_but_operator_ptr_ensure(uiBut *but)
void UI_block_align_begin(uiBlock *block)
void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss)
void UI_but_number_precision_set(uiBut *but, float precision)
int UI_pie_menu_invoke(bContext *C, const char *idname, const wmEvent *event)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
uiLayout * uiLayoutSplit(uiLayout *layout, float percentage, bool align)
uiBlock * uiLayoutAbsoluteBlock(uiLayout *layout)
#define UI_UNIT_X
@ UI_BTYPE_BUT
@ UI_BTYPE_TOGGLE
@ UI_BTYPE_TOGGLE_N
@ UI_BTYPE_LABEL
@ UI_BTYPE_NUM
uiBut * uiDefButR(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, const char *tip)
void UI_but_unit_type_set(uiBut *but, int unit_type)
void UI_but_flag_enable(uiBut *but, int flag)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_BUT_TEXT_RIGHT
@ UI_BUT_TEXT_LEFT
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_ICON_ONLY
@ UI_BUT_DISABLED
@ UI_BUT_INACTIVE
void UI_block_align_end(uiBlock *block)
#define NC_GEOM
Definition WM_types.hh:360
#define ND_DATA
Definition WM_types.hh:475
@ WM_OP_INVOKE_DEFAULT
Definition WM_types.hh:218
@ WM_OP_EXEC_DEFAULT
Definition WM_types.hh:225
#define ND_SPACE_VIEW3D
Definition WM_types.hh:494
#define NC_SPACE
Definition WM_types.hh:359
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
@ BM_ELEM_SELECT
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_flag_test(ele, hflag)
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMPartialUpdate * BM_mesh_partial_create_from_verts_group_single(BMesh *bm, const BMPartialUpdate_Params *params, const BLI_bitmap *verts_mask, const int verts_mask_count)
void BM_mesh_partial_destroy(BMPartialUpdate *bmpinfo)
void resize(const int64_t new_size)
#define SELECT
draw_view in_light_buf[] float
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void collection_hide_menu_draw(const bContext *C, uiLayout *layout)
bool mode_set(bContext *C, eObjectMode mode)
void vgroup_vert_active_mirror(Object *ob, int def_nr)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_id_pointer_create(ID *id)
static const float tilt_limit
Definition rna_curve.cc:884
#define FLT_MAX
Definition stdcycles.h:14
ListBase paneltypes
float co[3]
int totvert
CustomData vdata
CustomData edata
int totvertsel
int totedgesel
uint8_t f1
float vec[4]
float vec[3][3]
struct Bone * parent
EditBone * parent
struct Lattice * latt
Definition DNA_ID.h:413
struct EditLatt * editlatt
struct BPoint * def
void * first
char label[BKE_ST_MAXNAME]
char idname[BKE_ST_MAXNAME]
void(* draw)(const bContext *C, Menu *menu)
char translation_context[BKE_ST_MAXNAME]
uiLayout * layout
MetaElem * lastelem
ObjectRuntimeHandle * runtime
float scale[3]
void(* draw)(const bContext *C, Panel *panel)
char idname[BKE_ST_MAXNAME]
bool(* poll)(const bContext *C, PanelType *pt)
char translation_context[BKE_ST_MAXNAME]
char category[BKE_ST_MAXNAME]
char label[BKE_ST_MAXNAME]
struct uiLayout * layout
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
TransformMedian ve_median
blender::Vector< float > vertex_weights
TransformMedian median
void(* properties_storage_free)(void *properties_storage)
View3D_Runtime runtime
struct EditBone * act_edbone
struct bDeformGroup * next
uiBlockInteractionBeginFn begin_fn
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
struct ReportList * reports
TransformMedian_Mesh mesh
TransformMedian_Lattice lattice
TransformMedian_Generic generic
TransformMedian_Curve curve
#define N_(msgid)
static void apply_raw_diff_v3(float val[3], const int tot, const float ve_median[3], const float median[3])
static void do_view3d_vgroup_buttons(bContext *C, void *, int event)
static void v3d_editarmature_buts(uiLayout *layout, Object *ob)
static void apply_raw_diff(float *val, const int tot, const float ve_median, const float median)
static int view3d_object_mode_menu_exec(bContext *C, wmOperator *op)
#define TRANSFORM_MEDIAN_ARRAY_LEN
static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
@ B_TRANSFORM_PANEL_DIMS
@ B_TRANSFORM_PANEL_MEDIAN
@ B_REDR
static void view3d_panel_transform(const bContext *C, Panel *panel)
static void v3d_object_dimension_buts(bContext *C, uiLayout *layout, View3D *v3d, Object *ob)
static void do_view3d_region_buttons(bContext *C, void *, int event)
static void editmesh_partial_update_update_fn(bContext *C, const uiBlockInteraction_Params *, void *arg1, void *user_data)
static void * editmesh_partial_update_begin_fn(bContext *, const uiBlockInteraction_Params *params, void *arg1)
static void apply_scale_factor_clamp(float *val, const int tot, const float ve_median, const float sca)
void view3d_buttons_register(ARegionType *art)
static float compute_scale_factor(const float ve_median, const float median)
static void editmesh_partial_update_end_fn(bContext *, const uiBlockInteraction_Params *, void *, void *user_data)
static void update_active_vertex_weight(bContext *C, void *arg1, void *)
static void hide_collections_menu_draw(const bContext *C, Menu *menu)
void VIEW3D_OT_object_mode_pie_or_toggle(wmOperatorType *ot)
#define B_VGRP_PNL_EDIT_SINGLE
static bool view3d_panel_transform_poll(const bContext *C, PanelType *)
static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
static void view3d_panel_vgroup(const bContext *C, Panel *panel)
static bool view3d_panel_vgroup_poll(const bContext *C, PanelType *)
static TransformProperties * v3d_transform_props_ensure(View3D *v3d)
static void apply_scale_factor(float *val, const int tot, const float ve_median, const float median, const float sca)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125
bool WM_menutype_add(MenuType *mt)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)