code cleanup: misc warnings/style
[blender.git] / source / blender / editors / mesh / editmesh_knife_project.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) 2007 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Campbell Barton
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/mesh/editmesh_knife_project.c
28  *  \ingroup edmesh
29  */
30
31 #include "DNA_curve_types.h"
32 #include "DNA_scene_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_screen_types.h"
35 #include "DNA_windowmanager_types.h"
36
37 #include "BLI_utildefines.h"
38 #include "BLI_math.h"
39 #include "BLI_linklist.h"
40 #include "BLI_listbase.h"
41
42 #include "BKE_library.h"
43 #include "BKE_mesh.h"
44 #include "BKE_context.h"
45 #include "BKE_curve.h"
46 #include "BKE_cdderivedmesh.h"
47 #include "BKE_tessmesh.h"
48 #include "BKE_report.h"
49
50 #include "MEM_guardedalloc.h"
51
52 #include "WM_types.h"
53
54 #include "ED_mesh.h"
55 #include "ED_screen.h"
56 #include "ED_view3d.h"
57
58 #include "mesh_intern.h"
59
60
61 static LinkNode *knifeproject_poly_from_object(ARegion *ar, Scene *scene, Object *ob, LinkNode *polys)
62 {
63         DerivedMesh *dm;
64         bool dm_needsFree;
65
66         if (ob->type == OB_MESH || ob->derivedFinal) {
67                 dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
68                 dm_needsFree = false;
69         }
70         else if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
71                 dm = CDDM_from_curve(ob);
72                 dm_needsFree = true;
73         }
74         else {
75                 dm = NULL;
76         }
77
78         if (dm) {
79                 ListBase nurbslist = {NULL, NULL};
80                 float projmat[4][4];
81
82                 BKE_mesh_to_curve_nurblist(dm, &nurbslist, 0);  /* wire */
83                 BKE_mesh_to_curve_nurblist(dm, &nurbslist, 1);  /* boundary */
84
85                 ED_view3d_ob_project_mat_get(ar->regiondata, ob, projmat);
86
87                 if (nurbslist.first) {
88                         Nurb *nu;
89                         for (nu = nurbslist.first; nu; nu = nu->next) {
90                                 if (nu->bp) {
91                                         int a;
92                                         BPoint *bp;
93                                         bool is_cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
94                                         float (*mval)[2] = MEM_mallocN(sizeof(*mval) * (nu->pntsu + is_cyclic), __func__);
95
96                                         for (bp = nu->bp, a = 0; a < nu->pntsu; a++, bp++) {
97                                                 ED_view3d_project_float_v3_m4(ar, bp->vec, mval[a], projmat);
98                                         }
99                                         if (is_cyclic) {
100                                                 copy_v2_v2(mval[a], mval[0]);
101                                         }
102
103                                         BLI_linklist_prepend(&polys, mval);
104                                 }
105                         }
106                 }
107
108                 BKE_nurbList_free(&nurbslist);
109
110                 if (dm_needsFree) {
111                         dm->release(dm);
112                 }
113         }
114
115
116         return polys;
117 }
118
119 static int knifeproject_exec(bContext *C, wmOperator *op)
120 {
121         ARegion *ar = CTX_wm_region(C);
122         Scene *scene = CTX_data_scene(C);
123         Object *obedit = CTX_data_edit_object(C);
124         BMEditMesh *em = BMEdit_FromObject(obedit);
125
126         LinkNode *polys = NULL;
127
128         CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
129         {
130                 if (ob != obedit) {
131                         polys = knifeproject_poly_from_object(ar, scene, ob, polys);
132                 }
133         }
134         CTX_DATA_END;
135
136         if (polys) {
137                 EDBM_mesh_knife(C, polys, true);
138
139                 /* select only tagged faces */
140                 BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
141
142                 /* not essential, but switch out of vertex mode since the
143                  * selected regions wont be nicely isolated after flushing.
144                  * note: call after de-select to avoid selection flushing */
145                 EDBM_selectmode_disable(scene, em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
146
147                 BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_TAG);
148
149                 BM_mesh_select_mode_flush(em->bm);
150
151                 BLI_linklist_freeN(polys);
152
153                 return OPERATOR_FINISHED;
154         }
155         else {
156                 BKE_report(op->reports, RPT_ERROR, "No other selected objects found to use for projection");
157                 return OPERATOR_CANCELLED;
158         }
159 }
160
161 void MESH_OT_knife_project(wmOperatorType *ot)
162 {
163         /* description */
164         ot->name = "Knife Project";
165         ot->idname = "MESH_OT_knife_project";
166         ot->description = "Use other objects outlines & boundaries to project knife cuts";
167
168         /* callbacks */
169         ot->exec = knifeproject_exec;
170         ot->poll = ED_operator_editmesh_view3d;
171
172         /* flags */
173         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
174 }