Blender  V2.93
view3d_buttons.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  * The Original Code is Copyright (C) 2009 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <float.h>
25 #include <math.h>
26 #include <stdio.h>
27 #include <string.h>
28 
29 #include "DNA_armature_types.h"
30 #include "DNA_curve_types.h"
31 #include "DNA_lattice_types.h"
32 #include "DNA_mesh_types.h"
33 #include "DNA_meshdata_types.h"
34 #include "DNA_meta_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
37 
38 #include "MEM_guardedalloc.h"
39 
40 #include "BLT_translation.h"
41 
42 #include "BLI_blenlib.h"
43 #include "BLI_math.h"
44 #include "BLI_utildefines.h"
45 
46 #include "BKE_action.h"
47 #include "BKE_armature.h"
48 #include "BKE_context.h"
49 #include "BKE_curve.h"
50 #include "BKE_customdata.h"
51 #include "BKE_deform.h"
52 #include "BKE_editmesh.h"
53 #include "BKE_object.h"
54 #include "BKE_object_deform.h"
55 #include "BKE_report.h"
56 #include "BKE_screen.h"
57 
58 #include "DEG_depsgraph.h"
59 
60 #include "WM_api.h"
61 #include "WM_types.h"
62 
63 #include "RNA_access.h"
64 
65 #include "ED_mesh.h"
66 #include "ED_object.h"
67 #include "ED_screen.h"
68 
69 #include "UI_interface.h"
70 #include "UI_resources.h"
71 
72 #include "view3d_intern.h" /* own include */
73 
74 /* ******************* view3d space & buttons ************** */
75 enum {
76  B_REDR = 2,
79 };
80 
81 /* All must start w/ location */
82 
83 typedef struct {
84  float location[3];
86 
87 typedef struct {
88  float location[3], bv_weight, be_weight, skin[2], crease;
90 
91 typedef struct {
92  float location[3], weight, b_weight, radius, tilt;
94 
95 typedef struct {
96  float location[3], weight;
98 
99 typedef union {
105 
106 /* temporary struct for storing transform properties */
107 
108 typedef struct {
109  float ob_obmat_orig[4][4];
110  float ob_dims_orig[3];
111  float ob_scale_orig[3];
112  float ob_dims[3];
113  /* Floats only (treated as an array). */
116 
117 #define TRANSFORM_MEDIAN_ARRAY_LEN (sizeof(TransformMedian) / sizeof(float))
118 
119 /* Helper function to compute a median changed value,
120  * when the value should be clamped in [0.0, 1.0].
121  * Returns either 0.0, 1.0 (both can be applied directly), a positive scale factor
122  * for scale down, or a negative one for scale up.
123  */
124 static float compute_scale_factor(const float ve_median, const float median)
125 {
126  if (ve_median <= 0.0f) {
127  return 0.0f;
128  }
129  if (ve_median >= 1.0f) {
130  return 1.0f;
131  }
132 
133  /* Scale value to target median. */
134  float median_new = ve_median;
135  float median_orig = ve_median - median; /* Previous median value. */
136 
137  /* In case of floating point error. */
138  CLAMP(median_orig, 0.0f, 1.0f);
139  CLAMP(median_new, 0.0f, 1.0f);
140 
141  if (median_new <= median_orig) {
142  /* Scale down. */
143  return median_new / median_orig;
144  }
145 
146  /* Scale up, negative to indicate it... */
147  return -(1.0f - median_new) / (1.0f - median_orig);
148 }
149 
156 static void apply_raw_diff(float *val, const int tot, const float ve_median, const float median)
157 {
158  *val = (tot == 1) ? ve_median : (*val + median);
159 }
160 
161 static void apply_raw_diff_v3(float val[3],
162  const int tot,
163  const float ve_median[3],
164  const float median[3])
165 {
166  if (tot == 1) {
167  copy_v3_v3(val, ve_median);
168  }
169  else {
170  add_v3_v3(val, median);
171  }
172 }
173 
174 static void apply_scale_factor(
175  float *val, const int tot, const float ve_median, const float median, const float sca)
176 {
177  if (tot == 1 || ve_median == median) {
178  *val = ve_median;
179  }
180  else {
181  *val *= sca;
182  }
183 }
184 
185 static void apply_scale_factor_clamp(float *val,
186  const int tot,
187  const float ve_median,
188  const float sca)
189 {
190  if (tot == 1) {
191  *val = ve_median;
192  CLAMP(*val, 0.0f, 1.0f);
193  }
194  else if (ELEM(sca, 0.0f, 1.0f)) {
195  *val = sca;
196  }
197  else {
198  *val = (sca > 0.0f) ? (*val * sca) : (1.0f + ((1.0f - *val) * sca));
199  CLAMP(*val, 0.0f, 1.0f);
200  }
201 }
202 
204 {
205  if (v3d->runtime.properties_storage == NULL) {
207  "TransformProperties");
208  }
209  return v3d->runtime.properties_storage;
210 }
211 
212 /* is used for both read and write... */
213 static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
214 {
215  uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
217  TransformMedian median_basis, ve_median_basis;
218  int tot, totedgedata, totcurvedata, totlattdata, totcurvebweight;
219  bool has_meshdata = false;
220  bool has_skinradius = false;
221  PointerRNA data_ptr;
222 
223  copy_vn_fl((float *)&median_basis, TRANSFORM_MEDIAN_ARRAY_LEN, 0.0f);
224  tot = totedgedata = totcurvedata = totlattdata = totcurvebweight = 0;
225 
226  if (ob->type == OB_MESH) {
227  TransformMedian_Mesh *median = &median_basis.mesh;
228  Mesh *me = ob->data;
229  BMEditMesh *em = me->edit_mesh;
230  BMesh *bm = em->bm;
231  BMVert *eve;
232  BMEdge *eed;
233  BMIter iter;
234 
235  const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
236  const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
237  const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
238  const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
239 
240  has_skinradius = (cd_vert_skin_offset != -1);
241 
242  if (bm->totvertsel) {
243  BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
244  if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
245  tot++;
246  add_v3_v3(median->location, eve->co);
247 
248  if (cd_vert_bweight_offset != -1) {
249  median->bv_weight += BM_ELEM_CD_GET_FLOAT(eve, cd_vert_bweight_offset);
250  }
251 
252  if (has_skinradius) {
253  MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
254  add_v2_v2(median->skin, vs->radius); /* Third val not used currently. */
255  }
256  }
257  }
258  }
259 
260  if ((cd_edge_bweight_offset != -1) || (cd_edge_crease_offset != -1)) {
261  if (bm->totedgesel) {
262  BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
263  if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
264  if (cd_edge_bweight_offset != -1) {
265  median->be_weight += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset);
266  }
267 
268  if (cd_edge_crease_offset != -1) {
269  median->crease += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
270  }
271 
272  totedgedata++;
273  }
274  }
275  }
276  }
277  else {
278  totedgedata = bm->totedgesel;
279  }
280 
281  has_meshdata = (tot || totedgedata);
282  }
283  else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
284  TransformMedian_Curve *median = &median_basis.curve;
285  Curve *cu = ob->data;
286  BPoint *bp;
287  BezTriple *bezt;
288  int a;
289  ListBase *nurbs = BKE_curve_editNurbs_get(cu);
290  StructRNA *seltype = NULL;
291  void *selp = NULL;
292 
293  LISTBASE_FOREACH (Nurb *, nu, nurbs) {
294  if (nu->type == CU_BEZIER) {
295  bezt = nu->bezt;
296  a = nu->pntsu;
297  while (a--) {
298  if (bezt->f2 & SELECT) {
299  add_v3_v3(median->location, bezt->vec[1]);
300  tot++;
301  median->weight += bezt->weight;
302  median->radius += bezt->radius;
303  median->tilt += bezt->tilt;
304  if (!totcurvedata) { /* I.e. first time... */
305  selp = bezt;
306  seltype = &RNA_BezierSplinePoint;
307  }
308  totcurvedata++;
309  }
310  else {
311  if (bezt->f1 & SELECT) {
312  add_v3_v3(median->location, bezt->vec[0]);
313  tot++;
314  }
315  if (bezt->f3 & SELECT) {
316  add_v3_v3(median->location, bezt->vec[2]);
317  tot++;
318  }
319  }
320  bezt++;
321  }
322  }
323  else {
324  bp = nu->bp;
325  a = nu->pntsu * nu->pntsv;
326  while (a--) {
327  if (bp->f1 & SELECT) {
328  add_v3_v3(median->location, bp->vec);
329  median->b_weight += bp->vec[3];
330  totcurvebweight++;
331  tot++;
332  median->weight += bp->weight;
333  median->radius += bp->radius;
334  median->tilt += bp->tilt;
335  if (!totcurvedata) { /* I.e. first time... */
336  selp = bp;
337  seltype = &RNA_SplinePoint;
338  }
339  totcurvedata++;
340  }
341  bp++;
342  }
343  }
344  }
345 
346  if (totcurvedata == 1) {
347  RNA_pointer_create(&cu->id, seltype, selp, &data_ptr);
348  }
349  }
350  else if (ob->type == OB_LATTICE) {
351  Lattice *lt = ob->data;
352  TransformMedian_Lattice *median = &median_basis.lattice;
353  BPoint *bp;
354  int a;
355  StructRNA *seltype = NULL;
356  void *selp = NULL;
357 
358  a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
359  bp = lt->editlatt->latt->def;
360  while (a--) {
361  if (bp->f1 & SELECT) {
362  add_v3_v3(median->location, bp->vec);
363  tot++;
364  median->weight += bp->weight;
365  if (!totlattdata) { /* I.e. first time... */
366  selp = bp;
367  seltype = &RNA_LatticePoint;
368  }
369  totlattdata++;
370  }
371  bp++;
372  }
373 
374  if (totlattdata == 1) {
375  RNA_pointer_create(&lt->id, seltype, selp, &data_ptr);
376  }
377  }
378 
379  if (tot == 0) {
380  uiDefBut(block,
382  0,
383  IFACE_("Nothing selected"),
384  0,
385  130,
386  200,
387  20,
388  NULL,
389  0,
390  0,
391  0,
392  0,
393  "");
394  return;
395  }
396 
397  /* Location, X/Y/Z */
398  mul_v3_fl(median_basis.generic.location, 1.0f / (float)tot);
399  if (v3d->flag & V3D_GLOBAL_STATS) {
400  mul_m4_v3(ob->obmat, median_basis.generic.location);
401  }
402 
403  if (has_meshdata) {
404  TransformMedian_Mesh *median = &median_basis.mesh;
405  if (totedgedata) {
406  median->crease /= (float)totedgedata;
407  median->be_weight /= (float)totedgedata;
408  }
409  if (tot) {
410  median->bv_weight /= (float)tot;
411  if (has_skinradius) {
412  median->skin[0] /= (float)tot;
413  median->skin[1] /= (float)tot;
414  }
415  }
416  }
417  else if (totcurvedata) {
418  TransformMedian_Curve *median = &median_basis.curve;
419  if (totcurvebweight) {
420  median->b_weight /= (float)totcurvebweight;
421  }
422  median->weight /= (float)totcurvedata;
423  median->radius /= (float)totcurvedata;
424  median->tilt /= (float)totcurvedata;
425  }
426  else if (totlattdata) {
427  TransformMedian_Lattice *median = &median_basis.lattice;
428  median->weight /= (float)totlattdata;
429  }
430 
431  if (block) { /* buttons */
432  uiBut *but;
433  int yi = 200;
434  const float tilt_limit = DEG2RADF(21600.0f);
435  const int butw = 200;
436  const int buth = 20 * UI_DPI_FAC;
437  const int but_margin = 2;
438  const char *c;
439 
440  memcpy(&tfp->ve_median, &median_basis, sizeof(tfp->ve_median));
441 
442  UI_block_align_begin(block);
443  if (tot == 1) {
444  if (totcurvedata) {
445  /* Curve */
446  c = IFACE_("Control Point:");
447  }
448  else {
449  /* Mesh or lattice */
450  c = IFACE_("Vertex:");
451  }
452  }
453  else {
454  c = IFACE_("Median:");
455  }
456  uiDefBut(block, UI_BTYPE_LABEL, 0, c, 0, yi -= buth, butw, buth, NULL, 0, 0, 0, 0, "");
457 
458  UI_block_align_begin(block);
459 
460  /* Should be no need to translate these. */
461  but = uiDefButF(block,
462  UI_BTYPE_NUM,
464  IFACE_("X:"),
465  0,
466  yi -= buth,
467  butw,
468  buth,
469  &tfp->ve_median.generic.location[0],
470  -lim,
471  lim,
472  0,
473  0,
474  "");
478  but = uiDefButF(block,
479  UI_BTYPE_NUM,
481  IFACE_("Y:"),
482  0,
483  yi -= buth,
484  butw,
485  buth,
486  &tfp->ve_median.generic.location[1],
487  -lim,
488  lim,
489  0,
490  0,
491  "");
495  but = uiDefButF(block,
496  UI_BTYPE_NUM,
498  IFACE_("Z:"),
499  0,
500  yi -= buth,
501  butw,
502  buth,
503  &tfp->ve_median.generic.location[2],
504  -lim,
505  lim,
506  0,
507  0,
508  "");
512 
513  if (totcurvebweight == tot) {
514  but = uiDefButF(block,
515  UI_BTYPE_NUM,
517  IFACE_("W:"),
518  0,
519  yi -= buth,
520  butw,
521  buth,
522  &(tfp->ve_median.curve.b_weight),
523  0.01,
524  100.0,
525  0,
526  0,
527  "");
530  }
531 
532  UI_block_align_begin(block);
533  uiDefButBitS(block,
536  B_REDR,
537  IFACE_("Global"),
538  0,
539  yi -= buth + but_margin,
540  100,
541  buth,
542  &v3d->flag,
543  0,
544  0,
545  0,
546  0,
547  TIP_("Displays global values"));
548  uiDefButBitS(block,
551  B_REDR,
552  IFACE_("Local"),
553  100,
554  yi,
555  100,
556  buth,
557  &v3d->flag,
558  0,
559  0,
560  0,
561  0,
562  TIP_("Displays local values"));
563  UI_block_align_end(block);
564 
565  /* Meshes... */
566  if (has_meshdata) {
567  TransformMedian_Mesh *ve_median = &tfp->ve_median.mesh;
568  if (tot) {
569  uiDefBut(block,
571  0,
572  tot == 1 ? IFACE_("Vertex Data:") : IFACE_("Vertices Data:"),
573  0,
574  yi -= buth + but_margin,
575  butw,
576  buth,
577  NULL,
578  0.0,
579  0.0,
580  0,
581  0,
582  "");
583  /* customdata layer added on demand */
584  but = uiDefButF(block,
585  UI_BTYPE_NUM,
587  tot == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
588  0,
589  yi -= buth + but_margin,
590  butw,
591  buth,
592  &ve_median->bv_weight,
593  0.0,
594  1.0,
595  0,
596  0,
597  TIP_("Vertex weight used by Bevel modifier"));
600  }
601  if (has_skinradius) {
602  UI_block_align_begin(block);
603  but = uiDefButF(block,
604  UI_BTYPE_NUM,
606  tot == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"),
607  0,
608  yi -= buth + but_margin,
609  butw,
610  buth,
611  &ve_median->skin[0],
612  0.0,
613  100.0,
614  0,
615  0,
616  TIP_("X radius used by Skin modifier"));
619  but = uiDefButF(block,
620  UI_BTYPE_NUM,
622  tot == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"),
623  0,
624  yi -= buth + but_margin,
625  butw,
626  buth,
627  &ve_median->skin[1],
628  0.0,
629  100.0,
630  0,
631  0,
632  TIP_("Y radius used by Skin modifier"));
635  UI_block_align_end(block);
636  }
637  if (totedgedata) {
638  uiDefBut(block,
640  0,
641  totedgedata == 1 ? IFACE_("Edge Data:") : IFACE_("Edges Data:"),
642  0,
643  yi -= buth + but_margin,
644  butw,
645  buth,
646  NULL,
647  0.0,
648  0.0,
649  0,
650  0,
651  "");
652  /* customdata layer added on demand */
653  but = uiDefButF(block,
654  UI_BTYPE_NUM,
656  totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
657  0,
658  yi -= buth + but_margin,
659  butw,
660  buth,
661  &ve_median->be_weight,
662  0.0,
663  1.0,
664  0,
665  0,
666  TIP_("Edge weight used by Bevel modifier"));
669  /* customdata layer added on demand */
670  but = uiDefButF(block,
671  UI_BTYPE_NUM,
673  totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
674  0,
675  yi -= buth + but_margin,
676  butw,
677  buth,
678  &ve_median->crease,
679  0.0,
680  1.0,
681  0,
682  0,
683  TIP_("Weight used by the Subdivision Surface modifier"));
686  }
687  }
688  /* Curve... */
689  else if (totcurvedata) {
690  TransformMedian_Curve *ve_median = &tfp->ve_median.curve;
691  if (totcurvedata == 1) {
692  but = uiDefButR(block,
693  UI_BTYPE_NUM,
694  0,
695  IFACE_("Weight:"),
696  0,
697  yi -= buth + but_margin,
698  butw,
699  buth,
700  &data_ptr,
701  "weight_softbody",
702  0,
703  0.0,
704  1.0,
705  0,
706  0,
707  NULL);
710  but = uiDefButR(block,
711  UI_BTYPE_NUM,
712  0,
713  IFACE_("Radius:"),
714  0,
715  yi -= buth + but_margin,
716  butw,
717  buth,
718  &data_ptr,
719  "radius",
720  0,
721  0.0,
722  100.0,
723  0,
724  0,
725  NULL);
728  but = uiDefButR(block,
729  UI_BTYPE_NUM,
730  0,
731  IFACE_("Tilt:"),
732  0,
733  yi -= buth + but_margin,
734  butw,
735  buth,
736  &data_ptr,
737  "tilt",
738  0,
739  -tilt_limit,
740  tilt_limit,
741  0,
742  0,
743  NULL);
746  }
747  else if (totcurvedata > 1) {
748  but = uiDefButF(block,
749  UI_BTYPE_NUM,
751  IFACE_("Mean Weight:"),
752  0,
753  yi -= buth + but_margin,
754  butw,
755  buth,
756  &ve_median->weight,
757  0.0,
758  1.0,
759  0,
760  0,
761  TIP_("Weight used for Soft Body Goal"));
764  but = uiDefButF(block,
765  UI_BTYPE_NUM,
767  IFACE_("Mean Radius:"),
768  0,
769  yi -= buth + but_margin,
770  butw,
771  buth,
772  &ve_median->radius,
773  0.0,
774  100.0,
775  0,
776  0,
777  TIP_("Radius of curve control points"));
780  but = uiDefButF(block,
781  UI_BTYPE_NUM,
783  IFACE_("Mean Tilt:"),
784  0,
785  yi -= buth + but_margin,
786  butw,
787  buth,
788  &ve_median->tilt,
789  -tilt_limit,
790  tilt_limit,
791  0,
792  0,
793  TIP_("Tilt of curve control points"));
797  }
798  }
799  /* Lattice... */
800  else if (totlattdata) {
801  TransformMedian_Lattice *ve_median = &tfp->ve_median.lattice;
802  if (totlattdata == 1) {
803  uiDefButR(block,
804  UI_BTYPE_NUM,
805  0,
806  IFACE_("Weight:"),
807  0,
808  yi -= buth + but_margin,
809  butw,
810  buth,
811  &data_ptr,
812  "weight_softbody",
813  0,
814  0.0,
815  1.0,
816  0,
817  0,
818  NULL);
821  }
822  else if (totlattdata > 1) {
823  but = uiDefButF(block,
824  UI_BTYPE_NUM,
826  IFACE_("Mean Weight:"),
827  0,
828  yi -= buth + but_margin,
829  butw,
830  buth,
831  &ve_median->weight,
832  0.0,
833  1.0,
834  0,
835  0,
836  TIP_("Weight used for Soft Body Goal"));
839  }
840  }
841 
842  UI_block_align_end(block);
843  }
844  else { /* apply */
845  memcpy(&ve_median_basis, &tfp->ve_median, sizeof(tfp->ve_median));
846 
847  if (v3d->flag & V3D_GLOBAL_STATS) {
848  invert_m4_m4(ob->imat, ob->obmat);
849  mul_m4_v3(ob->imat, median_basis.generic.location);
850  mul_m4_v3(ob->imat, ve_median_basis.generic.location);
851  }
852  sub_vn_vnvn((float *)&median_basis,
853  (float *)&ve_median_basis,
854  (float *)&median_basis,
856 
857  /* Note with a single element selected, we always do. */
858  const bool apply_vcos = (tot == 1) || (len_squared_v3(median_basis.generic.location) != 0.0f);
859 
860  if ((ob->type == OB_MESH) &&
861  (apply_vcos || median_basis.mesh.bv_weight || median_basis.mesh.skin[0] ||
862  median_basis.mesh.skin[1] || median_basis.mesh.be_weight || median_basis.mesh.crease)) {
863  const TransformMedian_Mesh *median = &median_basis.mesh, *ve_median = &ve_median_basis.mesh;
864  Mesh *me = ob->data;
865  BMEditMesh *em = me->edit_mesh;
866  BMesh *bm = em->bm;
867  BMIter iter;
868  BMVert *eve;
869  BMEdge *eed;
870 
871  int cd_vert_bweight_offset = -1;
872  int cd_vert_skin_offset = -1;
873  int cd_edge_bweight_offset = -1;
874  int cd_edge_crease_offset = -1;
875 
876  float scale_bv_weight = 1.0f;
877  float scale_skin[2] = {1.0f, 1.0f};
878  float scale_be_weight = 1.0f;
879  float scale_crease = 1.0f;
880 
881  /* Vertices */
882 
883  if (apply_vcos || median->bv_weight || median->skin[0] || median->skin[1]) {
884  if (median->bv_weight) {
886  cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
887  BLI_assert(cd_vert_bweight_offset != -1);
888 
889  scale_bv_weight = compute_scale_factor(ve_median->bv_weight, median->bv_weight);
890  }
891 
892  for (int i = 0; i < 2; i++) {
893  if (median->skin[i]) {
894  cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
895  BLI_assert(cd_vert_skin_offset != -1);
896 
897  if (ve_median->skin[i] != median->skin[i]) {
898  scale_skin[i] = ve_median->skin[i] / (ve_median->skin[i] - median->skin[i]);
899  }
900  }
901  }
902 
903  BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
904  if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
905  if (apply_vcos) {
906  apply_raw_diff_v3(eve->co, tot, ve_median->location, median->location);
907  }
908 
909  if (cd_vert_bweight_offset != -1) {
910  float *b_weight = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset);
911  apply_scale_factor_clamp(b_weight, tot, ve_median->bv_weight, scale_bv_weight);
912  }
913 
914  if (cd_vert_skin_offset != -1) {
915  MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
916 
917  /* That one is not clamped to [0.0, 1.0]. */
918  for (int i = 0; i < 2; i++) {
919  if (median->skin[i] != 0.0f) {
921  &vs->radius[i], tot, ve_median->skin[i], median->skin[i], scale_skin[i]);
922  }
923  }
924  }
925  }
926  }
927  }
928 
929  if (apply_vcos) {
932  }
933 
934  /* Edges */
935 
936  if (median->be_weight || median->crease) {
937  if (median->be_weight) {
939  cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
940  BLI_assert(cd_edge_bweight_offset != -1);
941 
942  scale_be_weight = compute_scale_factor(ve_median->be_weight, median->be_weight);
943  }
944 
945  if (median->crease) {
947  cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
948  BLI_assert(cd_edge_crease_offset != -1);
949 
950  scale_crease = compute_scale_factor(ve_median->crease, median->crease);
951  }
952 
953  BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
954  if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
955  if (median->be_weight != 0.0f) {
956  float *b_weight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
957  apply_scale_factor_clamp(b_weight, tot, ve_median->be_weight, scale_be_weight);
958  }
959 
960  if (median->crease != 0.0f) {
961  float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
962  apply_scale_factor_clamp(crease, tot, ve_median->crease, scale_crease);
963  }
964  }
965  }
966  }
967  }
968  else if (ELEM(ob->type, OB_CURVE, OB_SURF) &&
969  (apply_vcos || median_basis.curve.b_weight || median_basis.curve.weight ||
970  median_basis.curve.radius || median_basis.curve.tilt)) {
971  const TransformMedian_Curve *median = &median_basis.curve,
972  *ve_median = &ve_median_basis.curve;
973  Curve *cu = ob->data;
974  BPoint *bp;
975  BezTriple *bezt;
976  int a;
977  ListBase *nurbs = BKE_curve_editNurbs_get(cu);
978  const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
979 
980  LISTBASE_FOREACH (Nurb *, nu, nurbs) {
981  if (nu->type == CU_BEZIER) {
982  for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
983  if (bezt->f2 & SELECT) {
984  if (apply_vcos) {
985  /* Here we always have to use the diff... :/
986  * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see T37327),
987  * unless we use doubles.
988  */
989  add_v3_v3(bezt->vec[0], median->location);
990  add_v3_v3(bezt->vec[1], median->location);
991  add_v3_v3(bezt->vec[2], median->location);
992  }
993  if (median->weight) {
994  apply_scale_factor_clamp(&bezt->weight, tot, ve_median->weight, scale_w);
995  }
996  if (median->radius) {
997  apply_raw_diff(&bezt->radius, tot, ve_median->radius, median->radius);
998  }
999  if (median->tilt) {
1000  apply_raw_diff(&bezt->tilt, tot, ve_median->tilt, median->tilt);
1001  }
1002  }
1003  else if (apply_vcos) {
1004  /* Handles can only have their coordinates changed here. */
1005  if (bezt->f1 & SELECT) {
1006  apply_raw_diff_v3(bezt->vec[0], tot, ve_median->location, median->location);
1007  }
1008  if (bezt->f3 & SELECT) {
1009  apply_raw_diff_v3(bezt->vec[2], tot, ve_median->location, median->location);
1010  }
1011  }
1012  }
1013  }
1014  else {
1015  for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a--; bp++) {
1016  if (bp->f1 & SELECT) {
1017  if (apply_vcos) {
1018  apply_raw_diff_v3(bp->vec, tot, ve_median->location, median->location);
1019  }
1020  if (median->b_weight) {
1021  apply_raw_diff(&bp->vec[3], tot, ve_median->b_weight, median->b_weight);
1022  }
1023  if (median->weight) {
1024  apply_scale_factor_clamp(&bp->weight, tot, ve_median->weight, scale_w);
1025  }
1026  if (median->radius) {
1027  apply_raw_diff(&bp->radius, tot, ve_median->radius, median->radius);
1028  }
1029  if (median->tilt) {
1030  apply_raw_diff(&bp->tilt, tot, ve_median->tilt, median->tilt);
1031  }
1032  }
1033  }
1034  }
1035  if (CU_IS_2D(cu)) {
1036  BKE_nurb_project_2d(nu);
1037  }
1038  BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
1039  }
1040  }
1041  else if ((ob->type == OB_LATTICE) && (apply_vcos || median_basis.lattice.weight)) {
1042  const TransformMedian_Lattice *median = &median_basis.lattice,
1043  *ve_median = &ve_median_basis.lattice;
1044  Lattice *lt = ob->data;
1045  BPoint *bp;
1046  int a;
1047  const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
1048 
1049  a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
1050  bp = lt->editlatt->latt->def;
1051  while (a--) {
1052  if (bp->f1 & SELECT) {
1053  if (apply_vcos) {
1054  apply_raw_diff_v3(bp->vec, tot, ve_median->location, median->location);
1055  }
1056  if (median->weight) {
1057  apply_scale_factor_clamp(&bp->weight, tot, ve_median->weight, scale_w);
1058  }
1059  }
1060  bp++;
1061  }
1062  }
1063 
1064  /* ED_undo_push(C, "Transform properties"); */
1065  }
1066 }
1067 
1068 #undef TRANSFORM_MEDIAN_ARRAY_LEN
1069 
1070 static void v3d_object_dimension_buts(bContext *C, uiLayout *layout, View3D *v3d, Object *ob)
1071 {
1072  uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
1074 
1075  if (block) {
1076  BLI_assert(C == NULL);
1077  int yi = 200;
1078  const int butw = 200;
1079  const int buth = 20 * UI_DPI_FAC;
1080 
1082  copy_v3_v3(tfp->ob_dims_orig, tfp->ob_dims);
1083  copy_v3_v3(tfp->ob_scale_orig, ob->scale);
1084  copy_m4_m4(tfp->ob_obmat_orig, ob->obmat);
1085 
1086  uiDefBut(block,
1088  0,
1089  IFACE_("Dimensions:"),
1090  0,
1091  yi -= buth,
1092  butw,
1093  buth,
1094  NULL,
1095  0,
1096  0,
1097  0,
1098  0,
1099  "");
1100  UI_block_align_begin(block);
1101  const float lim = FLT_MAX;
1102  for (int i = 0; i < 3; i++) {
1103  uiBut *but;
1104  const char text[3] = {'X' + i, ':', '\0'};
1105  but = uiDefButF(block,
1106  UI_BTYPE_NUM,
1108  text,
1109  0,
1110  yi -= buth,
1111  butw,
1112  buth,
1113  &(tfp->ob_dims[i]),
1114  0.0f,
1115  lim,
1116  0,
1117  0,
1118  "");
1119  UI_but_number_step_size_set(but, 10);
1122  }
1123  UI_block_align_end(block);
1124  }
1125  else { /* apply */
1126  int axis_mask = 0;
1127  for (int i = 0; i < 3; i++) {
1128  if (tfp->ob_dims[i] == tfp->ob_dims_orig[i]) {
1129  axis_mask |= (1 << i);
1130  }
1131  }
1133  ob, tfp->ob_dims, axis_mask, tfp->ob_scale_orig, tfp->ob_obmat_orig);
1134 
1135  PointerRNA obptr;
1136  RNA_id_pointer_create(&ob->id, &obptr);
1137  PropertyRNA *prop = RNA_struct_find_property(&obptr, "scale");
1138  RNA_property_update(C, &obptr, prop);
1139  }
1140 }
1141 
1142 #define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
1143 
1144 static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
1145 {
1146  if (event < B_VGRP_PNL_EDIT_SINGLE) {
1147  /* not for me */
1148  return;
1149  }
1150 
1151  ViewLayer *view_layer = CTX_data_view_layer(C);
1152  Object *ob = view_layer->basact->object;
1156 }
1157 
1159 {
1160  ViewLayer *view_layer = CTX_data_view_layer(C);
1161  Object *ob = OBACT(view_layer);
1163  MDeformVert *dvert_act = ED_mesh_active_dvert_get_only(ob);
1164  if (dvert_act) {
1165  return (dvert_act->totweight != 0);
1166  }
1167  }
1168 
1169  return false;
1170 }
1171 
1172 static void view3d_panel_vgroup(const bContext *C, Panel *panel)
1173 {
1174  uiBlock *block = uiLayoutAbsoluteBlock(panel->layout);
1176  ViewLayer *view_layer = CTX_data_view_layer(C);
1177  Object *ob = view_layer->basact->object;
1178 
1179  MDeformVert *dv;
1180 
1182 
1183  if (dv && dv->totweight) {
1185 
1186  wmOperatorType *ot;
1187  PointerRNA op_ptr, tools_ptr;
1188  PointerRNA *but_ptr;
1189 
1190  uiLayout *col, *bcol;
1191  uiLayout *row;
1192  uiBut *but;
1193  bDeformGroup *dg;
1194  uint i;
1195  int subset_count, vgroup_tot;
1196  const bool *vgroup_validmap;
1197  eVGroupSelect subset_type = ts->vgroupsubset;
1198  int yco = 0;
1199  int lock_count = 0;
1200 
1202 
1203  bcol = uiLayoutColumn(panel->layout, true);
1204  row = uiLayoutRow(bcol, true); /* The filter button row */
1205 
1206  RNA_pointer_create(NULL, &RNA_ToolSettings, ts, &tools_ptr);
1207  uiItemR(row, &tools_ptr, "vertex_group_subset", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1208 
1209  col = uiLayoutColumn(bcol, true);
1210 
1212  ob, subset_type, &vgroup_tot, &subset_count);
1213  for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
1214  bool locked = (dg->flag & DG_LOCK_WEIGHT) != 0;
1215  if (vgroup_validmap[i]) {
1217  if (dw) {
1218  int x, xco = 0;
1219  int icon;
1220  uiLayout *split = uiLayoutSplit(col, 0.45, true);
1221  row = uiLayoutRow(split, true);
1222 
1223  /* The Weight Group Name */
1224 
1225  ot = WM_operatortype_find("OBJECT_OT_vertex_weight_set_active", true);
1226  but = uiDefButO_ptr(block,
1227  UI_BTYPE_BUT,
1228  ot,
1230  dg->name,
1231  xco,
1232  yco,
1233  (x = UI_UNIT_X * 5),
1234  UI_UNIT_Y,
1235  "");
1236  but_ptr = UI_but_operator_ptr_get(but);
1237  RNA_int_set(but_ptr, "weight_group", i);
1239  if (ob->actdef != i + 1) {
1241  }
1242  xco += x;
1243 
1244  row = uiLayoutRow(split, true);
1245  uiLayoutSetEnabled(row, !locked);
1246 
1247  /* The weight group value */
1248  /* To be reworked still */
1249  but = uiDefButF(block,
1250  UI_BTYPE_NUM,
1252  "",
1253  xco,
1254  yco,
1255  (x = UI_UNIT_X * 4),
1256  UI_UNIT_Y,
1257  &dw->weight,
1258  0.0,
1259  1.0,
1260  0,
1261  0,
1262  "");
1266  if (locked) {
1267  lock_count++;
1268  }
1269  xco += x;
1270 
1271  /* The weight group paste function */
1272  icon = (locked) ? ICON_BLANK1 : ICON_PASTEDOWN;
1273  uiItemFullO(row,
1274  "OBJECT_OT_vertex_weight_paste",
1275  "",
1276  icon,
1277  NULL,
1279  0,
1280  &op_ptr);
1281  RNA_int_set(&op_ptr, "weight_group", i);
1282 
1283  /* The weight entry delete function */
1284  icon = (locked) ? ICON_LOCKED : ICON_X;
1285  uiItemFullO(row,
1286  "OBJECT_OT_vertex_weight_delete",
1287  "",
1288  icon,
1289  NULL,
1291  0,
1292  &op_ptr);
1293  RNA_int_set(&op_ptr, "weight_group", i);
1294 
1295  yco -= UI_UNIT_Y;
1296  }
1297  }
1298  }
1299  MEM_freeN((void *)vgroup_validmap);
1300 
1301  yco -= 2;
1302 
1303  col = uiLayoutColumn(panel->layout, true);
1304  row = uiLayoutRow(col, true);
1305 
1306  ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active_vertex", 1);
1307  but = uiDefButO_ptr(
1308  block,
1309  UI_BTYPE_BUT,
1310  ot,
1312  "Normalize",
1313  0,
1314  yco,
1315  UI_UNIT_X * 5,
1316  UI_UNIT_Y,
1317  TIP_("Normalize weights of active vertex (if affected groups are unlocked)"));
1318  if (lock_count) {
1320  }
1321 
1322  ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1);
1323  but = uiDefButO_ptr(
1324  block,
1325  UI_BTYPE_BUT,
1326  ot,
1328  "Copy",
1329  UI_UNIT_X * 5,
1330  yco,
1331  UI_UNIT_X * 5,
1332  UI_UNIT_Y,
1333  TIP_("Copy active vertex to other selected vertices (if affected groups are unlocked)"));
1334  if (lock_count) {
1336  }
1337  }
1338 }
1339 
1341 {
1342  uiLayout *split, *colsub;
1343 
1344  split = uiLayoutSplit(layout, 0.8f, false);
1345 
1346  if (ptr->type == &RNA_PoseBone) {
1347  PointerRNA boneptr;
1348  Bone *bone;
1349 
1350  boneptr = RNA_pointer_get(ptr, "bone");
1351  bone = boneptr.data;
1352  uiLayoutSetActive(split, !(bone->parent && bone->flag & BONE_CONNECTED));
1353  }
1354  colsub = uiLayoutColumn(split, true);
1355  uiItemR(colsub, ptr, "location", 0, NULL, ICON_NONE);
1356  colsub = uiLayoutColumn(split, true);
1358  uiItemL(colsub, "", ICON_NONE);
1359  uiItemR(colsub,
1360  ptr,
1361  "lock_location",
1363  "",
1364  ICON_DECORATE_UNLOCKED);
1365 
1366  split = uiLayoutSplit(layout, 0.8f, false);
1367 
1368  switch (RNA_enum_get(ptr, "rotation_mode")) {
1369  case ROT_MODE_QUAT: /* quaternion */
1370  colsub = uiLayoutColumn(split, true);
1371  uiItemR(colsub, ptr, "rotation_quaternion", 0, IFACE_("Rotation"), ICON_NONE);
1372  colsub = uiLayoutColumn(split, true);
1374  uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
1375  if (RNA_boolean_get(ptr, "lock_rotations_4d")) {
1376  uiItemR(colsub,
1377  ptr,
1378  "lock_rotation_w",
1380  "",
1381  ICON_DECORATE_UNLOCKED);
1382  }
1383  else {
1384  uiItemL(colsub, "", ICON_NONE);
1385  }
1386  uiItemR(colsub,
1387  ptr,
1388  "lock_rotation",
1390  "",
1391  ICON_DECORATE_UNLOCKED);
1392  break;
1393  case ROT_MODE_AXISANGLE: /* axis angle */
1394  colsub = uiLayoutColumn(split, true);
1395  uiItemR(colsub, ptr, "rotation_axis_angle", 0, IFACE_("Rotation"), ICON_NONE);
1396  colsub = uiLayoutColumn(split, true);
1398  uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
1399  if (RNA_boolean_get(ptr, "lock_rotations_4d")) {
1400  uiItemR(colsub,
1401  ptr,
1402  "lock_rotation_w",
1404  "",
1405  ICON_DECORATE_UNLOCKED);
1406  }
1407  else {
1408  uiItemL(colsub, "", ICON_NONE);
1409  }
1410  uiItemR(colsub,
1411  ptr,
1412  "lock_rotation",
1414  "",
1415  ICON_DECORATE_UNLOCKED);
1416  break;
1417  default: /* euler rotations */
1418  colsub = uiLayoutColumn(split, true);
1419  uiItemR(colsub, ptr, "rotation_euler", 0, IFACE_("Rotation"), ICON_NONE);
1420  colsub = uiLayoutColumn(split, true);
1422  uiItemL(colsub, "", ICON_NONE);
1423  uiItemR(colsub,
1424  ptr,
1425  "lock_rotation",
1427  "",
1428  ICON_DECORATE_UNLOCKED);
1429  break;
1430  }
1431  uiItemR(layout, ptr, "rotation_mode", 0, "", ICON_NONE);
1432 
1433  split = uiLayoutSplit(layout, 0.8f, false);
1434  colsub = uiLayoutColumn(split, true);
1435  uiItemR(colsub, ptr, "scale", 0, NULL, ICON_NONE);
1436  colsub = uiLayoutColumn(split, true);
1438  uiItemL(colsub, "", ICON_NONE);
1439  uiItemR(colsub,
1440  ptr,
1441  "lock_scale",
1443  "",
1444  ICON_DECORATE_UNLOCKED);
1445 }
1446 
1447 static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
1448 {
1449  bPoseChannel *pchan;
1450  PointerRNA pchanptr;
1451  uiLayout *col;
1452 
1453  pchan = BKE_pose_channel_active(ob);
1454 
1455  if (!pchan) {
1456  uiItemL(layout, IFACE_("No Bone Active"), ICON_NONE);
1457  return;
1458  }
1459 
1460  RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &pchanptr);
1461 
1462  col = uiLayoutColumn(layout, false);
1463 
1464  /* XXX: RNA buts show data in native types (i.e. quats, 4-component axis/angle, etc.)
1465  * but old-school UI shows in eulers always. Do we want to be able to still display in Eulers?
1466  * Maybe needs RNA/ui options to display rotations as different types... */
1467  v3d_transform_butsR(col, &pchanptr);
1468 }
1469 
1470 static void v3d_editarmature_buts(uiLayout *layout, Object *ob)
1471 {
1472  bArmature *arm = ob->data;
1473  EditBone *ebone;
1474  uiLayout *col;
1475  PointerRNA eboneptr;
1476 
1477  ebone = arm->act_edbone;
1478 
1479  if (!ebone || (ebone->layer & arm->layer) == 0) {
1480  uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE);
1481  return;
1482  }
1483 
1484  RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr);
1485 
1486  col = uiLayoutColumn(layout, false);
1487  uiItemR(col, &eboneptr, "head", 0, NULL, ICON_NONE);
1488  if (ebone->parent && ebone->flag & BONE_CONNECTED) {
1489  PointerRNA parptr = RNA_pointer_get(&eboneptr, "parent");
1490  uiItemR(col, &parptr, "tail_radius", 0, IFACE_("Radius (Parent)"), ICON_NONE);
1491  }
1492  else {
1493  uiItemR(col, &eboneptr, "head_radius", 0, IFACE_("Radius"), ICON_NONE);
1494  }
1495 
1496  uiItemR(col, &eboneptr, "tail", 0, NULL, ICON_NONE);
1497  uiItemR(col, &eboneptr, "tail_radius", 0, IFACE_("Radius"), ICON_NONE);
1498 
1499  uiItemR(col, &eboneptr, "roll", 0, NULL, ICON_NONE);
1500  uiItemR(col, &eboneptr, "length", 0, NULL, ICON_NONE);
1501  uiItemR(col, &eboneptr, "envelope_distance", 0, IFACE_("Envelope"), ICON_NONE);
1502 }
1503 
1504 static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
1505 {
1506  PointerRNA mbptr, ptr;
1507  MetaBall *mball = ob->data;
1508  uiLayout *col;
1509 
1510  if (!mball || !(mball->lastelem)) {
1511  uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE);
1512  return;
1513  }
1514 
1515  RNA_pointer_create(&mball->id, &RNA_MetaBall, mball, &mbptr);
1516 
1517  RNA_pointer_create(&mball->id, &RNA_MetaElement, mball->lastelem, &ptr);
1518 
1519  col = uiLayoutColumn(layout, false);
1520  uiItemR(col, &ptr, "co", 0, NULL, ICON_NONE);
1521 
1522  uiItemR(col, &ptr, "radius", 0, NULL, ICON_NONE);
1523  uiItemR(col, &ptr, "stiffness", 0, NULL, ICON_NONE);
1524 
1525  uiItemR(col, &ptr, "type", 0, NULL, ICON_NONE);
1526 
1527  col = uiLayoutColumn(layout, true);
1528  switch (RNA_enum_get(&ptr, "type")) {
1529  case MB_BALL:
1530  break;
1531  case MB_CUBE:
1532  uiItemL(col, IFACE_("Size:"), ICON_NONE);
1533  uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
1534  uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
1535  uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NONE);
1536  break;
1537  case MB_TUBE:
1538  uiItemL(col, IFACE_("Size:"), ICON_NONE);
1539  uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
1540  break;
1541  case MB_PLANE:
1542  uiItemL(col, IFACE_("Size:"), ICON_NONE);
1543  uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
1544  uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
1545  break;
1546  case MB_ELIPSOID:
1547  uiItemL(col, IFACE_("Size:"), ICON_NONE);
1548  uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
1549  uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
1550  uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NONE);
1551  break;
1552  }
1553 }
1554 
1555 static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event)
1556 {
1557  ViewLayer *view_layer = CTX_data_view_layer(C);
1558  View3D *v3d = CTX_wm_view3d(C);
1559  Object *ob = OBACT(view_layer);
1560 
1561  switch (event) {
1562 
1563  case B_REDR:
1565  return; /* no notifier! */
1566 
1568  if (ob) {
1569  v3d_editvertex_buts(NULL, v3d, ob, 1.0);
1571  }
1572  break;
1574  if (ob) {
1575  v3d_object_dimension_buts(C, NULL, v3d, ob);
1576  }
1577  break;
1578  }
1579 
1580  /* default for now */
1582 }
1583 
1585 {
1586  ViewLayer *view_layer = CTX_data_view_layer(C);
1587  return (view_layer->basact != NULL);
1588 }
1589 
1590 static void view3d_panel_transform(const bContext *C, Panel *panel)
1591 {
1592  uiBlock *block;
1593  ViewLayer *view_layer = CTX_data_view_layer(C);
1594  Object *ob = view_layer->basact->object;
1595  Object *obedit = OBEDIT_FROM_OBACT(ob);
1596  uiLayout *col;
1597 
1598  block = uiLayoutGetBlock(panel->layout);
1600 
1601  col = uiLayoutColumn(panel->layout, false);
1602 
1603  if (ob == obedit) {
1604  if (ob->type == OB_ARMATURE) {
1606  }
1607  else if (ob->type == OB_MBALL) {
1609  }
1610  else {
1611  View3D *v3d = CTX_wm_view3d(C);
1612  v3d_editvertex_buts(col, v3d, ob, FLT_MAX);
1613  }
1614  }
1615  else if (ob->mode & OB_MODE_POSE) {
1617  }
1618  else {
1619  PointerRNA obptr;
1620 
1621  RNA_id_pointer_create(&ob->id, &obptr);
1622  v3d_transform_butsR(col, &obptr);
1623 
1624  /* Dimensions and editmode are mostly the same check. */
1626  View3D *v3d = CTX_wm_view3d(C);
1627  v3d_object_dimension_buts(NULL, col, v3d, ob);
1628  }
1629  }
1630 }
1631 
1632 static void hide_collections_menu_draw(const bContext *C, Menu *menu)
1633 {
1635 }
1636 
1638 {
1639  PanelType *pt;
1640 
1641  pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
1642  strcpy(pt->idname, "VIEW3D_PT_transform");
1643  strcpy(pt->label, N_("Transform")); /* XXX C panels unavailable through RNA bpy.types! */
1644  strcpy(pt->category, "Item");
1648  BLI_addtail(&art->paneltypes, pt);
1649 
1650  pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
1651  strcpy(pt->idname, "VIEW3D_PT_vgroup");
1652  strcpy(pt->label, N_("Vertex Weights")); /* XXX C panels unavailable through RNA bpy.types! */
1653  strcpy(pt->category, "Item");
1655  pt->draw = view3d_panel_vgroup;
1657  BLI_addtail(&art->paneltypes, pt);
1658 
1659  MenuType *mt;
1660 
1661  mt = MEM_callocN(sizeof(MenuType), "spacetype view3d menu collections");
1662  strcpy(mt->idname, "VIEW3D_MT_collection");
1663  strcpy(mt->label, N_("Collection"));
1666  WM_menutype_add(mt);
1667 }
1668 
1670 {
1672  if (ob == NULL) {
1673  BKE_report(op->reports, RPT_WARNING, "No active object found");
1674  return OPERATOR_CANCELLED;
1675  }
1676  if (((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) {
1678  return OPERATOR_CANCELLED;
1679  }
1680 
1681  UI_pie_menu_invoke(C, "VIEW3D_MT_object_mode_pie", CTX_wm_window(C)->eventstate);
1682  return OPERATOR_CANCELLED;
1683 }
1684 
1686 {
1687  ot->name = "Object Mode Menu";
1688  ot->idname = "VIEW3D_OT_object_mode_pie_or_toggle";
1689 
1692 
1693  /* flags */
1694  ot->flag = 0;
1695 }
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_active(struct Object *ob)
Definition: action.c:708
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
struct ListBase * BKE_curve_editNurbs_get(struct Curve *cu)
Definition: curve.c:437
#define CU_IS_2D(cu)
Definition: BKE_curve.h:83
void BKE_nurb_project_2d(struct Nurb *nu)
Definition: curve.c:748
void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles, const bool use_around_local)
Definition: curve.c:4217
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const struct CustomData *data, int type)
support for deformation groups and hooks.
struct MDeformWeight * BKE_defvert_find_index(const struct MDeformVert *dv, const int defgroup)
void BKE_editmesh_looptri_calc(BMEditMesh *em)
Definition: editmesh.c:135
General operations, lookup, etc. for blender objects.
void BKE_object_dimensions_get(struct Object *ob, float r_vec[3])
Definition: object.c:3901
bool BKE_object_is_in_wpaint_select_vert(const struct Object *ob)
bool BKE_object_is_in_editmode_vgroup(const struct Object *ob)
void BKE_object_dimensions_set_ex(struct Object *ob, const float value[3], int axis_mask, const float ob_scale_orig[3], const float ob_obmat_orig[4][4])
Definition: object.c:3926
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, ReportType type, const char *message)
Definition: report.c:104
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
#define DEG2RADF(_deg)
void copy_vn_fl(float *array_tar, const int size, const float val)
Definition: math_vector.c:1410
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
Definition: math_vector.c:1322
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void add_v3_v3(float r[3], const float a[3])
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define ELEM(...)
#define TIP_(msgid)
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
#define N_(msgid)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ ROT_MODE_QUAT
@ ROT_MODE_AXISANGLE
@ BONE_CONNECTED
@ CU_BEZIER
@ CD_MVERT_SKIN
@ CD_BWEIGHT
@ ME_CDFLAG_EDGE_CREASE
@ ME_CDFLAG_VERT_BWEIGHT
@ ME_CDFLAG_EDGE_BWEIGHT
#define MB_BALL
#define MB_TUBE
#define MB_ELIPSOID
#define MB_PLANE
#define MB_CUBE
@ OB_MODE_EDIT
@ OB_MODE_POSE
@ OB_MODE_OBJECT
Object is a sort of wrapper for general info.
#define DG_LOCK_WEIGHT
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_ARMATURE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_HAIR
@ OB_VOLUME
@ OB_CURVE
#define OB_TYPE_SUPPORT_EDITMODE(_type)
#define OBEDIT_FROM_OBACT(ob)
#define OBACT(_view_layer)
eVGroupSelect
#define V3D_GLOBAL_STATS
@ OPERATOR_CANCELLED
struct MDeformVert * ED_mesh_active_dvert_get_only(struct Object *ob)
Definition: meshtools.c:1512
void ED_vgroup_vert_active_mirror(struct Object *ob, int def_nr)
void EDBM_mesh_normals_update(struct BMEditMesh *em)
bool ED_object_mode_set(struct bContext *C, eObjectMode mode)
Definition: object_modes.c:235
void ED_collection_hide_menu_draw(const struct bContext *C, struct uiLayout *layout)
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:745
bool ED_operator_view3d_active(struct bContext *C)
Definition: screen_ops.c:230
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
StructRNA RNA_BezierSplinePoint
StructRNA RNA_SplinePoint
StructRNA RNA_MetaBall
StructRNA RNA_MetaElement
StructRNA RNA_EditBone
StructRNA RNA_PoseBone
StructRNA RNA_LatticePoint
StructRNA RNA_ToolSettings
@ PROP_UNIT_ROTATION
Definition: RNA_types.h:89
@ PROP_UNIT_LENGTH
Definition: RNA_types.h:85
#define RNA_TRANSLATION_PREC_DEFAULT
Definition: RNA_types.h:104
#define C
Definition: RandGen.cpp:39
#define UI_UNIT_Y
void uiLayoutSetActive(uiLayout *layout, bool active)
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_ICON_ONLY
uiBlock * uiLayoutGetBlock(uiLayout *layout)
@ UI_BUT_TEXT_RIGHT
Definition: UI_interface.h:261
@ UI_BUT_TEXT_LEFT
Definition: UI_interface.h:259
@ UI_EMBOSS_NONE
Definition: UI_interface.h:108
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
@ UI_BUT_DISABLED
Definition: UI_interface.h:199
@ UI_BUT_INACTIVE
Definition: UI_interface.h:206
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr)
uiBut * uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:4687
uiBut * uiDefButF(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:4896
struct PointerRNA * UI_but_operator_ptr_get(uiBut *but)
Definition: interface.c:6218
void uiItemL(uiLayout *layout, const char *name, int icon)
void UI_but_drawflag_enable(uiBut *but, int flag)
Definition: interface.c:6092
uiBlock * uiLayoutAbsoluteBlock(uiLayout *layout)
void UI_but_number_step_size_set(uiBut *but, float step_size)
Definition: interface.c:6827
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
Definition: interface.c:6247
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
uiBut * uiDefButR(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5144
void UI_but_unit_type_set(uiBut *but, const int unit_type)
Definition: interface.c:6228
#define UI_DPI_FAC
Definition: UI_interface.h:309
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
uiBut * uiDefButBitS(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5050
void UI_block_align_begin(uiBlock *block)
Definition: interface.c:3821
void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss)
uiLayout * uiLayoutSplit(uiLayout *layout, float percentage, bool align)
void UI_but_number_precision_set(uiBut *but, float precision)
Definition: interface.c:6836
#define UI_UNIT_X
@ UI_BTYPE_BUT
Definition: UI_interface.h:334
@ UI_BTYPE_TOGGLE
Definition: UI_interface.h:344
@ UI_BTYPE_TOGGLE_N
Definition: UI_interface.h:345
@ UI_BTYPE_LABEL
Definition: UI_interface.h:358
@ UI_BTYPE_NUM
Definition: UI_interface.h:341
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.c:6077
int UI_pie_menu_invoke(struct bContext *C, const char *idname, const struct wmEvent *event)
uiBut * uiDefButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.c:5189
void UI_block_align_end(uiBlock *block)
Definition: interface.c:3834
#define NC_GEOM
Definition: WM_types.h:294
#define ND_DATA
Definition: WM_types.h:408
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:197
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:204
#define ND_SPACE_VIEW3D
Definition: WM_types.h:423
#define NC_SPACE
Definition: WM_types.h:293
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
Definition: bmesh_class.h:542
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
Definition: bmesh_class.h:530
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:26
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
#define SELECT
Scene scene
uint col
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:115
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6319
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2317
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
static const float tilt_limit
Definition: rna_curve.c:861
ListBase paneltypes
Definition: BKE_screen.h:216
struct BMesh * bm
Definition: BKE_editmesh.h:52
float co[3]
Definition: bmesh_class.h:99
CustomData vdata
Definition: bmesh_class.h:337
CustomData edata
Definition: bmesh_class.h:337
int totvertsel
Definition: bmesh_class.h:298
int totedgesel
Definition: bmesh_class.h:298
float weight
uint8_t f1
float vec[4]
float radius
float tilt
struct Object * object
float vec[3][3]
struct Bone * parent
struct EditBone * parent
Definition: BKE_armature.h:55
struct Lattice * latt
struct EditLatt * editlatt
struct BPoint * def
void * first
Definition: DNA_listBase.h:47
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:376
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:375
void(* draw)(const struct bContext *C, struct Menu *menu)
Definition: BKE_screen.h:384
char translation_context[BKE_ST_MAXNAME]
Definition: BKE_screen.h:377
struct uiLayout * layout
Definition: BKE_screen.h:392
struct BMEditMesh * edit_mesh
MetaElem * lastelem
ListBase defbase
float scale[3]
float imat[4][4]
unsigned short actdef
float obmat[4][4]
void * data
void(* draw)(const struct bContext *C, struct Panel *panel)
Definition: BKE_screen.h:266
bool(* poll)(const struct bContext *C, struct PanelType *pt)
Definition: BKE_screen.h:260
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:241
char translation_context[BKE_ST_MAXNAME]
Definition: BKE_screen.h:244
char category[BKE_ST_MAXNAME]
Definition: BKE_screen.h:246
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:242
struct uiLayout * layout
struct StructRNA * type
Definition: RNA_types.h:51
void * data
Definition: RNA_types.h:52
struct ToolSettings * toolsettings
float ob_obmat_orig[4][4]
TransformMedian ve_median
TransformMedian median
View3D_Runtime runtime
struct Base * basact
struct EditBone * act_edbone
unsigned int layer
struct bDeformGroup * next
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
TransformMedian_Mesh mesh
TransformMedian_Lattice lattice
TransformMedian_Generic generic
TransformMedian_Curve curve
static void apply_raw_diff_v3(float val[3], const int tot, const float ve_median[3], const float median[3])
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)
@ B_TRANSFORM_PANEL_DIMS
@ B_TRANSFORM_PANEL_MEDIAN
@ B_REDR
#define TRANSFORM_MEDIAN_ARRAY_LEN
static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
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_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
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 bool view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
static float compute_scale_factor(const float ve_median, const float median)
static int view3d_object_mode_menu(bContext *C, wmOperator *op)
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 void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
static TransformProperties * v3d_transform_props_ensure(View3D *v3d)
static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
static bool view3d_panel_transform_poll(const bContext *C, PanelType *UNUSED(pt))
static void view3d_panel_vgroup(const bContext *C, Panel *panel)
static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event)
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.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
bool WM_menutype_add(MenuType *mt)
Definition: wm_menu_type.c:65
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)