style cleanup: comment blocks
[blender-staging.git] / source / blender / modifiers / intern / MOD_bevel.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Daniel Dunbar
22  *                 Ton Roosendaal,
23  *                 Ben Batt,
24  *                 Brecht Van Lommel,
25  *                 Campbell Barton
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  */
30
31 /** \file blender/modifiers/intern/MOD_bevel.c
32  *  \ingroup modifiers
33  */
34
35 #include "BLI_utildefines.h"
36 #include "BLI_math.h"
37 #include "BLI_string.h"
38
39 #include "BKE_cdderivedmesh.h"
40 #include "BKE_modifier.h"
41 #include "BKE_tessmesh.h"
42 #include "BKE_mesh.h"
43
44 #include "BKE_bmesh.h" /* only for defines */
45
46 #include "DNA_object_types.h"
47
48 #include "MEM_guardedalloc.h"
49
50
51 static void initData(ModifierData *md)
52 {
53         BevelModifierData *bmd = (BevelModifierData*) md;
54
55         bmd->value = 0.1f;
56         bmd->res = 1;
57         bmd->flags = 0;
58         bmd->val_flags = 0;
59         bmd->lim_flags = 0;
60         bmd->e_flags = 0;
61         bmd->bevel_angle = 30;
62         bmd->defgrp_name[0] = '\0';
63 }
64
65 static void copyData(ModifierData *md, ModifierData *target)
66 {
67         BevelModifierData *bmd = (BevelModifierData*) md;
68         BevelModifierData *tbmd = (BevelModifierData*) target;
69
70         tbmd->value = bmd->value;
71         tbmd->res = bmd->res;
72         tbmd->flags = bmd->flags;
73         tbmd->val_flags = bmd->val_flags;
74         tbmd->lim_flags = bmd->lim_flags;
75         tbmd->e_flags = bmd->e_flags;
76         tbmd->bevel_angle = bmd->bevel_angle;
77         BLI_strncpy(tbmd->defgrp_name, bmd->defgrp_name, sizeof(tbmd->defgrp_name));
78 }
79
80 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
81 {
82         BevelModifierData *bmd = (BevelModifierData *)md;
83         CustomDataMask dataMask = 0;
84
85         /* ask for vertexgroups if we need them */
86         if(bmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT;
87
88         return dataMask;
89 }
90
91 #define EDGE_MARK       1
92
93
94 /* BMESH_TODO
95  *
96  * this bevel calls the operator which is missing many of the options
97  * which the bevel modifier in trunk has.
98  * - width is interpreted as percent (not distance)
99  * - no vertex bevel
100  * - no weight bevel
101  *
102  * These will need to be added to the bmesh operator.
103  *       - campbell
104  *
105  * note: this code is very close to MOD_edgesplit.c.
106  * note: if 0'd code from trunk included below.
107  */
108 static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
109                                                 DerivedMesh *dm,
110                                                 int UNUSED(useRenderParams),
111                                                 int UNUSED(isFinalCalc))
112 {
113         DerivedMesh *result;
114         BMesh *bm;
115         BMEditMesh *em;
116         BMIter iter;
117         BMEdge *e;
118         BevelModifierData *bmd = (BevelModifierData*) md;
119         float threshold = cos((bmd->bevel_angle + 0.00001) * M_PI / 180.0);
120
121         em = DM_to_editbmesh(ob, dm, NULL, FALSE);
122         bm = em->bm;
123
124         BM_mesh_normals_update(bm, FALSE);
125         BMO_push(bm, NULL);
126
127         if (bmd->lim_flags & BME_BEVEL_ANGLE) {
128                 BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
129                         /* check for 1 edge having 2 face users */
130                         BMLoop *l1, *l2;
131                         if ( (l1= e->l) &&
132                              (l2= e->l->radial_next) != l1)
133                         {
134                                 if (dot_v3v3(l1->f->no, l2->f->no) < threshold) {
135                                         BMO_elem_flag_enable(bm, e, EDGE_MARK);
136                                 }
137                         }
138                 }
139         }
140         else {
141                 /* crummy, is there a way just to operator on all? - campbell */
142                 BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
143                         BMO_elem_flag_enable(bm, e, EDGE_MARK);
144                 }
145         }
146
147         BMO_op_callf(bm, "bevel geom=%fe percent=%f use_even=%b use_dist=%b",
148                      EDGE_MARK, bmd->value, (bmd->flags & BME_BEVEL_EVEN) != 0, (bmd->flags & BME_BEVEL_DIST) != 0);
149         BMO_pop(bm);
150
151         BLI_assert(em->looptris == NULL);
152         result = CDDM_from_BMEditMesh(em, NULL, TRUE, FALSE);
153         BMEdit_Free(em);
154         MEM_freeN(em);
155
156         return result;
157 }
158
159
160 #if 0 /* from trunk, see note above */
161
162 static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
163                                                 DerivedMesh *derivedData,
164                                                 int UNUSED(useRenderParams),
165                                                 int UNUSED(isFinalCalc))
166 {
167         DerivedMesh *result;
168         BME_Mesh *bm;
169
170         /*bDeformGroup *def;*/
171         int /*i,*/ options, defgrp_index = -1;
172         BevelModifierData *bmd = (BevelModifierData*) md;
173
174         options = bmd->flags|bmd->val_flags|bmd->lim_flags|bmd->e_flags;
175
176 #if 0
177         if ((options & BME_BEVEL_VWEIGHT) && bmd->defgrp_name[0]) {
178                 defgrp_index = defgroup_name_index(ob, bmd->defgrp_name);
179                 if (defgrp_index < 0) {
180                         options &= ~BME_BEVEL_VWEIGHT;
181                 }
182         }
183 #endif
184
185         bm = BME_derivedmesh_to_bmesh(derivedData);
186         BME_bevel(bm,bmd->value,bmd->res,options,defgrp_index,bmd->bevel_angle,NULL);
187         result = BME_bmesh_to_derivedmesh(bm,derivedData);
188         BME_free_mesh(bm);
189
190         CDDM_calc_normals(result);
191
192         return result;
193 }
194
195 #endif
196
197 static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
198                                                 struct BMEditMesh *UNUSED(editData),
199                                                 DerivedMesh *derivedData)
200 {
201         return applyModifier(md, ob, derivedData, 0, 1);
202 }
203
204
205 ModifierTypeInfo modifierType_Bevel = {
206         /* name */              "Bevel",
207         /* structName */        "BevelModifierData",
208         /* structSize */        sizeof(BevelModifierData),
209         /* type */              eModifierTypeType_Constructive,
210         /* flags */             eModifierTypeFlag_AcceptsMesh
211                                                         | eModifierTypeFlag_SupportsEditmode
212                                                         | eModifierTypeFlag_EnableInEditmode,
213
214         /* copyData */          copyData,
215         /* deformVerts */       NULL,
216         /* deformMatrices */    NULL,
217         /* deformVertsEM */     NULL,
218         /* deformMatricesEM */  NULL,
219         /* applyModifier */     applyModifier,
220         /* applyModifierEM */   applyModifierEM,
221         /* initData */          initData,
222         /* requiredDataMask */  requiredDataMask,
223         /* freeData */          NULL,
224         /* isDisabled */        NULL,
225         /* updateDepgraph */    NULL,
226         /* dependsOnTime */     NULL,
227         /* dependsOnNormals */  NULL,
228         /* foreachObjectLink */ NULL,
229         /* foreachIDLink */     NULL,
230         /* foreachTexLink */    NULL,
231 };