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) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup edtransform
22 */
23
24 #include "DNA_mesh_types.h"
25
26 #include "MEM_guardedalloc.h"
27
28 #include "BLI_math.h"
29
30 #include "BKE_context.h"
31 #include "BKE_editmesh.h"
32 #include "BKE_mesh.h"
33
34 #include "transform.h"
35 #include "transform_convert.h"
36
37 /* -------------------------------------------------------------------- */
38 /** \name Edge (for crease) Transform Creation
39 *
40 * \{ */
41
createTransEdge(TransInfo * t)42 void createTransEdge(TransInfo *t)
43 {
44 FOREACH_TRANS_DATA_CONTAINER (t, tc) {
45
46 BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
47 TransData *td = NULL;
48 BMEdge *eed;
49 BMIter iter;
50 float mtx[3][3], smtx[3][3];
51 int count = 0, countsel = 0;
52 const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
53 const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
54 int cd_edge_float_offset;
55
56 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
57 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
58 if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
59 countsel++;
60 }
61 if (is_prop_edit) {
62 count++;
63 }
64 }
65 }
66
67 if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) {
68 tc->data_len = 0;
69 continue;
70 }
71
72 if (is_prop_edit) {
73 tc->data_len = count;
74 }
75 else {
76 tc->data_len = countsel;
77 }
78
79 td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease");
80
81 copy_m3_m4(mtx, tc->obedit->obmat);
82 pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
83
84 /* create data we need */
85 if (t->mode == TFM_BWEIGHT) {
86 BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT);
87 cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
88 }
89 else { /* if (t->mode == TFM_CREASE) { */
90 BLI_assert(t->mode == TFM_CREASE);
91 BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE);
92 cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
93 }
94
95 BLI_assert(cd_edge_float_offset != -1);
96
97 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
98 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) &&
99 (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) {
100 float *fl_ptr;
101 /* need to set center for center calculations */
102 mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
103
104 td->loc = NULL;
105 if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
106 td->flag = TD_SELECTED;
107 }
108 else {
109 td->flag = 0;
110 }
111
112 copy_m3_m3(td->smtx, smtx);
113 copy_m3_m3(td->mtx, mtx);
114
115 td->ext = NULL;
116
117 fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset);
118 td->val = fl_ptr;
119 td->ival = *fl_ptr;
120
121 td++;
122 }
123 }
124 }
125 }
126
127 /** \} */
128