Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / CCGSubSurf_inline.h
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 /** \file
18  * \ingroup bke
19  */
20
21 #ifndef __CCGSUBSURF_INLINE_H__
22 #define __CCGSUBSURF_INLINE_H__
23
24 BLI_INLINE int ccg_gridsize(int level)
25 {
26   BLI_assert(level > 0);
27   BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
28   return (1 << (level - 1)) + 1;
29 }
30
31 BLI_INLINE int ccg_edgesize(int level)
32 {
33   BLI_assert(level > 0);
34   BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
35   return 1 + (1 << level);
36 }
37
38 BLI_INLINE int ccg_spacing(int high_level, int low_level)
39 {
40   BLI_assert(high_level > 0 && low_level > 0);
41   BLI_assert(high_level >= low_level);
42   BLI_assert((high_level - low_level) <= CCGSUBSURF_LEVEL_MAX);
43   return 1 << (high_level - low_level);
44 }
45
46 BLI_INLINE int ccg_edgebase(int level)
47 {
48   BLI_assert(level > 0);
49   BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
50   return level + (1 << level) - 1;
51 }
52
53 /* **** */
54
55 BLI_INLINE byte *VERT_getLevelData(CCGVert *v)
56 {
57   return (byte *)(&(v)[1]);
58 }
59
60 BLI_INLINE byte *EDGE_getLevelData(CCGEdge *e)
61 {
62   return (byte *)(&(e)[1]);
63 }
64
65 BLI_INLINE CCGVert **FACE_getVerts(CCGFace *f)
66 {
67   return (CCGVert **)(&f[1]);
68 }
69
70 BLI_INLINE CCGEdge **FACE_getEdges(CCGFace *f)
71 {
72   return (CCGEdge **)(&(FACE_getVerts(f)[f->numVerts]));
73 }
74
75 BLI_INLINE byte *FACE_getCenterData(CCGFace *f)
76 {
77   return (byte *)(&(FACE_getEdges(f)[(f)->numVerts]));
78 }
79
80 /* **** */
81
82 BLI_INLINE void *ccg_vert_getCo(CCGVert *v, int lvl, int dataSize)
83 {
84   return &VERT_getLevelData(v)[lvl * dataSize];
85 }
86
87 BLI_INLINE float *ccg_vert_getNo(CCGVert *v, int lvl, int dataSize, int normalDataOffset)
88 {
89   return (float *)&VERT_getLevelData(v)[lvl * dataSize + normalDataOffset];
90 }
91
92 BLI_INLINE void *ccg_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize)
93 {
94   int levelBase = ccg_edgebase(lvl);
95   return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
96 }
97
98 BLI_INLINE float *ccg_edge_getNo(CCGEdge *e, int lvl, int x, int dataSize, int normalDataOffset)
99 {
100   int levelBase = ccg_edgebase(lvl);
101   return (float *)&EDGE_getLevelData(e)[dataSize * (levelBase + x) + normalDataOffset];
102 }
103
104 BLI_INLINE void *ccg_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize)
105 {
106   int maxGridSize = ccg_gridsize(levels);
107   int spacing = ccg_spacing(levels, lvl);
108   byte *gridBase = FACE_getCenterData(f) +
109                    dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
110   return &gridBase[dataSize * x * spacing];
111 }
112
113 BLI_INLINE void *ccg_face_getIENo(
114     CCGFace *f, int lvl, int S, int x, int levels, int dataSize, int normalDataOffset)
115 {
116   int maxGridSize = ccg_gridsize(levels);
117   int spacing = ccg_spacing(levels, lvl);
118   byte *gridBase = FACE_getCenterData(f) +
119                    dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
120   return &gridBase[dataSize * x * spacing + normalDataOffset];
121 }
122
123 BLI_INLINE void *ccg_face_getIFCo(
124     CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize)
125 {
126   int maxGridSize = ccg_gridsize(levels);
127   int spacing = ccg_spacing(levels, lvl);
128   byte *gridBase = FACE_getCenterData(f) +
129                    dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
130   return &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing)];
131 }
132
133 BLI_INLINE float *ccg_face_getIFNo(
134     CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset)
135 {
136   int maxGridSize = ccg_gridsize(levels);
137   int spacing = ccg_spacing(levels, lvl);
138   byte *gridBase = FACE_getCenterData(f) +
139                    dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
140   return (float *)&gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing) +
141                             normalDataOffset];
142 }
143
144 BLI_INLINE int ccg_face_getVertIndex(CCGFace *f, CCGVert *v)
145 {
146   int i;
147   for (i = 0; i < f->numVerts; i++) {
148     if (FACE_getVerts(f)[i] == v) {
149       return i;
150     }
151   }
152   return -1;
153 }
154
155 BLI_INLINE int ccg_face_getEdgeIndex(CCGFace *f, CCGEdge *e)
156 {
157   int i;
158   for (i = 0; i < f->numVerts; i++) {
159     if (FACE_getEdges(f)[i] == e) {
160       return i;
161     }
162   }
163   return -1;
164 }
165
166 BLI_INLINE void *ccg_face_getIFCoEdge(
167     CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize)
168 {
169   int maxGridSize = ccg_gridsize(levels);
170   int spacing = ccg_spacing(levels, lvl);
171   int x, y, cx, cy;
172
173   BLI_assert(f_ed_idx == ccg_face_getEdgeIndex(f, e));
174
175   eX = eX * spacing;
176   eY = eY * spacing;
177   if (e->v0 != FACE_getVerts(f)[f_ed_idx]) {
178     eX = (maxGridSize * 2 - 1) - 1 - eX;
179   }
180   y = maxGridSize - 1 - eX;
181   x = maxGridSize - 1 - eY;
182   if (x < 0) {
183     f_ed_idx = (f_ed_idx + f->numVerts - 1) % f->numVerts;
184     cx = y;
185     cy = -x;
186   }
187   else if (y < 0) {
188     f_ed_idx = (f_ed_idx + 1) % f->numVerts;
189     cx = -y;
190     cy = x;
191   }
192   else {
193     cx = x;
194     cy = y;
195   }
196   return ccg_face_getIFCo(f, levels, f_ed_idx, cx, cy, levels, dataSize);
197 }
198
199 BLI_INLINE void Normalize(float no[3])
200 {
201   const float length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]);
202
203   if (length > EPSILON) {
204     const float length_inv = 1.0f / length;
205
206     no[0] *= length_inv;
207     no[1] *= length_inv;
208     no[2] *= length_inv;
209   }
210   else {
211     NormZero(no);
212   }
213 }
214
215 /* Data layers mathematics. */
216
217 BLI_INLINE int VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss)
218 {
219   int i;
220   for (i = 0; i < ss->meshIFC.numLayers; i++) {
221     if (a[i] != b[i]) {
222       return 0;
223     }
224   }
225   return 1;
226 }
227
228 BLI_INLINE void VertDataZero(float v[], const CCGSubSurf *ss)
229 {
230   memset(v, 0, sizeof(float) * ss->meshIFC.numLayers);
231 }
232
233 BLI_INLINE void VertDataCopy(float dst[], const float src[], const CCGSubSurf *ss)
234 {
235   int i;
236   for (i = 0; i < ss->meshIFC.numLayers; i++) {
237     dst[i] = src[i];
238   }
239 }
240
241 BLI_INLINE void VertDataAdd(float a[], const float b[], const CCGSubSurf *ss)
242 {
243   int i;
244   for (i = 0; i < ss->meshIFC.numLayers; i++) {
245     a[i] += b[i];
246   }
247 }
248
249 BLI_INLINE void VertDataSub(float a[], const float b[], const CCGSubSurf *ss)
250 {
251   int i;
252   for (i = 0; i < ss->meshIFC.numLayers; i++) {
253     a[i] -= b[i];
254   }
255 }
256
257 BLI_INLINE void VertDataMulN(float v[], float f, const CCGSubSurf *ss)
258 {
259   int i;
260   for (i = 0; i < ss->meshIFC.numLayers; i++) {
261     v[i] *= f;
262   }
263 }
264
265 BLI_INLINE void VertDataAvg4(float v[],
266                              const float a[],
267                              const float b[],
268                              const float c[],
269                              const float d[],
270                              const CCGSubSurf *ss)
271 {
272   int i;
273   for (i = 0; i < ss->meshIFC.numLayers; i++) {
274     v[i] = (a[i] + b[i] + c[i] + d[i]) * 0.25f;
275   }
276 }
277
278 #endif /* __CCGSUBSURF_INLINE_H__ */