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 
17 #pragma once
18 
19 /** \file
20  * \ingroup bmesh
21  */
22 
23 #include "bmesh_class.h"
24 
25 struct BMAllocTemplate;
26 struct BMLoopNorEditDataArray;
27 struct MLoopNorSpaceArray;
28 
29 void BM_mesh_elem_toolflags_ensure(BMesh *bm);
30 void BM_mesh_elem_toolflags_clear(BMesh *bm);
31 
32 struct BMeshCreateParams {
33   uint use_toolflags : 1;
34 };
35 
36 BMesh *BM_mesh_create(const struct BMAllocTemplate *allocsize,
37                       const struct BMeshCreateParams *params);
38 
39 void BM_mesh_free(BMesh *bm);
40 void BM_mesh_data_free(BMesh *bm);
41 void BM_mesh_clear(BMesh *bm);
42 
43 void BM_mesh_normals_update(BMesh *bm);
44 void BM_verts_calc_normal_vcos(BMesh *bm,
45                                const float (*fnos)[3],
46                                const float (*vcos)[3],
47                                float (*vnos)[3]);
48 void BM_loops_calc_normal_vcos(BMesh *bm,
49                                const float (*vcos)[3],
50                                const float (*vnos)[3],
51                                const float (*fnos)[3],
52                                const bool use_split_normals,
53                                const float split_angle,
54                                float (*r_lnos)[3],
55                                struct MLoopNorSpaceArray *r_lnors_spacearr,
56                                short (*clnors_data)[2],
57                                const int cd_loop_clnors_offset,
58                                const bool do_rebuild);
59 
60 bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr);
61 void BM_lnorspacearr_store(BMesh *bm, float (*r_lnors)[3]);
62 void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all);
63 void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor);
64 void BM_lnorspace_update(BMesh *bm);
65 void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges);
66 #ifndef NDEBUG
67 void BM_lnorspace_err(BMesh *bm);
68 #endif
69 
70 /* Loop Generics */
71 struct BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm,
72                                                                   const bool do_all_loops_of_vert);
73 void BM_loop_normal_editdata_array_free(struct BMLoopNorEditDataArray *lnors_ed_arr);
74 
75 bool BM_custom_loop_normals_to_vector_layer(struct BMesh *bm);
76 void BM_custom_loop_normals_from_vector_layer(struct BMesh *bm, bool add_sharp_edges);
77 
78 void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle);
79 
80 void bmesh_edit_begin(BMesh *bm, const BMOpTypeFlag type_flag);
81 void bmesh_edit_end(BMesh *bm, const BMOpTypeFlag type_flag);
82 
83 void BM_mesh_elem_index_ensure_ex(BMesh *bm, const char htype, int elem_offset[4]);
84 void BM_mesh_elem_index_ensure(BMesh *bm, const char htype);
85 void BM_mesh_elem_index_validate(
86     BMesh *bm, const char *location, const char *func, const char *msg_a, const char *msg_b);
87 
88 void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags);
89 
90 #ifndef NDEBUG
91 bool BM_mesh_elem_table_check(BMesh *bm);
92 #endif
93 
94 void BM_mesh_elem_table_ensure(BMesh *bm, const char htype);
95 void BM_mesh_elem_table_init(BMesh *bm, const char htype);
96 void BM_mesh_elem_table_free(BMesh *bm, const char htype);
97 
BM_vert_at_index(BMesh * bm,const int index)98 BLI_INLINE BMVert *BM_vert_at_index(BMesh *bm, const int index)
99 {
100   BLI_assert((index >= 0) && (index < bm->totvert));
101   BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
102   return bm->vtable[index];
103 }
BM_edge_at_index(BMesh * bm,const int index)104 BLI_INLINE BMEdge *BM_edge_at_index(BMesh *bm, const int index)
105 {
106   BLI_assert((index >= 0) && (index < bm->totedge));
107   BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
108   return bm->etable[index];
109 }
BM_face_at_index(BMesh * bm,const int index)110 BLI_INLINE BMFace *BM_face_at_index(BMesh *bm, const int index)
111 {
112   BLI_assert((index >= 0) && (index < bm->totface));
113   BLI_assert((bm->elem_table_dirty & BM_FACE) == 0);
114   return bm->ftable[index];
115 }
116 
117 BMVert *BM_vert_at_index_find(BMesh *bm, const int index);
118 BMEdge *BM_edge_at_index_find(BMesh *bm, const int index);
119 BMFace *BM_face_at_index_find(BMesh *bm, const int index);
120 BMLoop *BM_loop_at_index_find(BMesh *bm, const int index);
121 
122 BMVert *BM_vert_at_index_find_or_table(BMesh *bm, const int index);
123 BMEdge *BM_edge_at_index_find_or_table(BMesh *bm, const int index);
124 BMFace *BM_face_at_index_find_or_table(BMesh *bm, const int index);
125 
126 // XXX
127 
128 int BM_mesh_elem_count(BMesh *bm, const char htype);
129 
130 void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const uint *face_idx);
131 
132 void BM_mesh_rebuild(BMesh *bm,
133                      const struct BMeshCreateParams *params,
134                      struct BLI_mempool *vpool,
135                      struct BLI_mempool *epool,
136                      struct BLI_mempool *lpool,
137                      struct BLI_mempool *fpool);
138 
139 typedef struct BMAllocTemplate {
140   int totvert, totedge, totloop, totface;
141 } BMAllocTemplate;
142 
143 extern const BMAllocTemplate bm_mesh_allocsize_default;
144 extern const BMAllocTemplate bm_mesh_chunksize_default;
145 
146 #define BMALLOC_TEMPLATE_FROM_BM(bm) \
147   { \
148     (CHECK_TYPE_INLINE(bm, BMesh *), (bm)->totvert), (bm)->totedge, (bm)->totloop, (bm)->totface \
149   }
150 
151 #define _VA_BMALLOC_TEMPLATE_FROM_ME_1(me) \
152   { \
153     (CHECK_TYPE_INLINE(me, Mesh *), (me)->totvert), (me)->totedge, (me)->totloop, (me)->totpoly, \
154   }
155 #define _VA_BMALLOC_TEMPLATE_FROM_ME_2(me_a, me_b) \
156   { \
157     (CHECK_TYPE_INLINE(me_a, Mesh *), \
158      CHECK_TYPE_INLINE(me_b, Mesh *), \
159      (me_a)->totvert + (me_b)->totvert), \
160         (me_a)->totedge + (me_b)->totedge, (me_a)->totloop + (me_b)->totloop, \
161         (me_a)->totpoly + (me_b)->totpoly, \
162   }
163 #define BMALLOC_TEMPLATE_FROM_ME(...) \
164   VA_NARGS_CALL_OVERLOAD(_VA_BMALLOC_TEMPLATE_FROM_ME_, __VA_ARGS__)
165 
166 /* Vertex coords access. */
167 void BM_mesh_vert_coords_get(BMesh *bm, float (*vert_coords)[3]);
168 float (*BM_mesh_vert_coords_alloc(BMesh *bm, int *r_vert_len))[3];
169 void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3]);
170 void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
171                                          const float (*vert_coords)[3],
172                                          const float mat[4][4]);
173