Blender V4.5
CCGSubSurf_inline.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include "BLI_assert.h"
12#include "BLI_compiler_compat.h"
13
14#include "CCGSubSurf_intern.h"
15
16#include <cmath>
17#include <cstdint>
18#include <cstring>
19
21{
22 BLI_assert(level > 0);
23 BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
24 return (1 << (level - 1)) + 1;
25}
26
28{
29 BLI_assert(level > 0);
30 BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
31 return 1 + (1 << level);
32}
33
34BLI_INLINE int ccg_spacing(int high_level, int low_level)
35{
36 BLI_assert(high_level > 0 && low_level > 0);
37 BLI_assert(high_level >= low_level);
38 BLI_assert((high_level - low_level) <= CCGSUBSURF_LEVEL_MAX);
39 return 1 << (high_level - low_level);
40}
41
43{
44 BLI_assert(level > 0);
45 BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
46 return level + (1 << level) - 1;
47}
48
49/* **** */
50
52{
53 return (uint8_t *)(&(v)[1]);
54}
55
57{
58 return (uint8_t *)(&(e)[1]);
59}
60
62{
63 return (CCGVert **)(&f[1]);
64}
65
67{
68 return (CCGEdge **)(&(FACE_getVerts(f)[f->numVerts]));
69}
70
72{
73 return (uint8_t *)(&(FACE_getEdges(f)[(f)->numVerts]));
74}
75
76/* **** */
77
78BLI_INLINE void *ccg_vert_getCo(CCGVert *v, int lvl, int dataSize)
79{
80 return &VERT_getLevelData(v)[lvl * dataSize];
81}
82
83BLI_INLINE float *ccg_vert_getNo(CCGVert *v, int lvl, int dataSize, int normalDataOffset)
84{
85 return (float *)&VERT_getLevelData(v)[lvl * dataSize + normalDataOffset];
86}
87
88BLI_INLINE void *ccg_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize)
89{
90 int levelBase = ccg_edgebase(lvl);
91 return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
92}
93
94BLI_INLINE float *ccg_edge_getNo(CCGEdge *e, int lvl, int x, int dataSize, int normalDataOffset)
95{
96 int levelBase = ccg_edgebase(lvl);
97 return (float *)&EDGE_getLevelData(e)[dataSize * (levelBase + x) + normalDataOffset];
98}
99
100BLI_INLINE void *ccg_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize)
101{
102 int maxGridSize = ccg_gridsize(levels);
103 int spacing = ccg_spacing(levels, lvl);
104 uint8_t *gridBase = FACE_getCenterData(f) +
105 dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
106 return &gridBase[dataSize * x * spacing];
107}
108
110 CCGFace *f, int lvl, int S, int x, int levels, int dataSize, int normalDataOffset)
111{
112 int maxGridSize = ccg_gridsize(levels);
113 int spacing = ccg_spacing(levels, lvl);
114 uint8_t *gridBase = FACE_getCenterData(f) +
115 dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
116 return &gridBase[dataSize * x * spacing + normalDataOffset];
117}
118
120 CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize)
121{
122 int maxGridSize = ccg_gridsize(levels);
123 int spacing = ccg_spacing(levels, lvl);
124 uint8_t *gridBase = FACE_getCenterData(f) +
125 dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
126 return &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing)];
127}
128
130 CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset)
131{
132 int maxGridSize = ccg_gridsize(levels);
133 int spacing = ccg_spacing(levels, lvl);
134 uint8_t *gridBase = FACE_getCenterData(f) +
135 dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
136 return (float *)&gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing) +
137 normalDataOffset];
138}
139
141{
142 for (int i = 0; i < f->numVerts; i++) {
143 if (FACE_getVerts(f)[i] == v) {
144 return i;
145 }
146 }
147 return -1;
148}
149
151{
152 for (int i = 0; i < f->numVerts; i++) {
153 if (FACE_getEdges(f)[i] == e) {
154 return i;
155 }
156 }
157 return -1;
158}
159
161 CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize)
162{
163 int maxGridSize = ccg_gridsize(levels);
164 int spacing = ccg_spacing(levels, lvl);
165 int x, y, cx, cy;
166
167 BLI_assert(f_ed_idx == ccg_face_getEdgeIndex(f, e));
168
169 eX = eX * spacing;
170 eY = eY * spacing;
171 if (e->v0 != FACE_getVerts(f)[f_ed_idx]) {
172 eX = (maxGridSize * 2 - 1) - 1 - eX;
173 }
174 y = maxGridSize - 1 - eX;
175 x = maxGridSize - 1 - eY;
176 if (x < 0) {
177 f_ed_idx = (f_ed_idx + f->numVerts - 1) % f->numVerts;
178 cx = y;
179 cy = -x;
180 }
181 else if (y < 0) {
182 f_ed_idx = (f_ed_idx + 1) % f->numVerts;
183 cx = -y;
184 cy = x;
185 }
186 else {
187 cx = x;
188 cy = y;
189 }
190 return ccg_face_getIFCo(f, levels, f_ed_idx, cx, cy, levels, dataSize);
191}
192
193BLI_INLINE void Normalize(float no[3])
194{
195 const float length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]);
196
197 if (length > EPSILON) {
198 const float length_inv = 1.0f / length;
199
200 no[0] *= length_inv;
201 no[1] *= length_inv;
202 no[2] *= length_inv;
203 }
204 else {
205 NormZero(no);
206 }
207}
208
209/* Data layers mathematics. */
210
211BLI_INLINE bool VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss)
212{
213 for (int i = 0; i < ss->meshIFC.numLayers; i++) {
214 if (a[i] != b[i]) {
215 return false;
216 }
217 }
218 return true;
219}
220
221BLI_INLINE void VertDataZero(float v[], const CCGSubSurf *ss)
222{
223 memset(v, 0, sizeof(float) * ss->meshIFC.numLayers);
224}
225
226BLI_INLINE void VertDataCopy(float dst[], const float src[], const CCGSubSurf *ss)
227{
228 for (int i = 0; i < ss->meshIFC.numLayers; i++) {
229 dst[i] = src[i];
230 }
231}
232
233BLI_INLINE void VertDataAdd(float a[], const float b[], const CCGSubSurf *ss)
234{
235 for (int i = 0; i < ss->meshIFC.numLayers; i++) {
236 a[i] += b[i];
237 }
238}
239
240BLI_INLINE void VertDataSub(float a[], const float b[], const CCGSubSurf *ss)
241{
242 for (int i = 0; i < ss->meshIFC.numLayers; i++) {
243 a[i] -= b[i];
244 }
245}
246
247BLI_INLINE void VertDataMulN(float v[], float f, const CCGSubSurf *ss)
248{
249 for (int i = 0; i < ss->meshIFC.numLayers; i++) {
250 v[i] *= f;
251 }
252}
253
255 const float a[],
256 const float b[],
257 const float c[],
258 const float d[],
259 const CCGSubSurf *ss)
260{
261 for (int i = 0; i < ss->meshIFC.numLayers; i++) {
262 v[i] = (a[i] + b[i] + c[i] + d[i]) * 0.25f;
263 }
264}
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_INLINE
BLI_INLINE uint8_t * VERT_getLevelData(CCGVert *v)
BLI_INLINE int ccg_edgesize(int level)
BLI_INLINE uint8_t * EDGE_getLevelData(CCGEdge *e)
BLI_INLINE void Normalize(float no[3])
BLI_INLINE CCGVert ** FACE_getVerts(CCGFace *f)
BLI_INLINE float * ccg_edge_getNo(CCGEdge *e, int lvl, int x, int dataSize, int normalDataOffset)
BLI_INLINE int ccg_gridsize(int level)
BLI_INLINE void * ccg_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize)
BLI_INLINE void VertDataZero(float v[], const CCGSubSurf *ss)
BLI_INLINE float * ccg_vert_getNo(CCGVert *v, int lvl, int dataSize, int normalDataOffset)
BLI_INLINE CCGEdge ** FACE_getEdges(CCGFace *f)
BLI_INLINE bool VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss)
BLI_INLINE int ccg_edgebase(int level)
BLI_INLINE int ccg_face_getEdgeIndex(CCGFace *f, CCGEdge *e)
BLI_INLINE void * ccg_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize)
BLI_INLINE int ccg_spacing(int high_level, int low_level)
BLI_INLINE uint8_t * FACE_getCenterData(CCGFace *f)
BLI_INLINE void VertDataSub(float a[], const float b[], const CCGSubSurf *ss)
BLI_INLINE void VertDataCopy(float dst[], const float src[], const CCGSubSurf *ss)
BLI_INLINE void * ccg_vert_getCo(CCGVert *v, int lvl, int dataSize)
BLI_INLINE void * ccg_face_getIENo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize, int normalDataOffset)
BLI_INLINE int ccg_face_getVertIndex(CCGFace *f, CCGVert *v)
BLI_INLINE float * ccg_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset)
BLI_INLINE void VertDataMulN(float v[], float f, const CCGSubSurf *ss)
BLI_INLINE void VertDataAvg4(float v[], const float a[], const float b[], const float c[], const float d[], const CCGSubSurf *ss)
BLI_INLINE void * ccg_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize)
BLI_INLINE void VertDataAdd(float a[], const float b[], const CCGSubSurf *ss)
BLI_INLINE void * ccg_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize)
#define EPSILON
#define NormZero(av)
#define CCGSUBSURF_LEVEL_MAX
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define sqrtf(x)
float length(VecOp< float, D >) RET
int numLayers
Definition CCGSubSurf.h:23
CCGMeshIFC meshIFC
i
Definition text_draw.cc:230