11 #include <muParser/muParser.h>
20 "title" :
"VuoMeshParametric",
23 "VuoMathExpressionParser",
33 static inline void add(
float *normals,
int index, VuoPoint3d normal)
35 normals[index * 3 ] += normal.x;
36 normals[index * 3 + 1] += normal.y;
37 normals[index * 3 + 2] += normal.z;
43 VuoMesh VuoMeshParametric_generate(
VuoReal time,
VuoText xExp,
VuoText yExp,
VuoText zExp,
VuoInteger uSubdivisions,
VuoInteger vSubdivisions,
bool closeU,
VuoReal uMin,
VuoReal uMax,
bool closeV,
VuoReal vMin,
VuoReal vMax,
VuoDictionary_VuoText_VuoReal *constants)
45 if (uSubdivisions < 2 || vSubdivisions < 2 || !xExp || !yExp || !zExp)
48 mu::Parser xParser, yParser, zParser;
50 xParser.SetExpr(xExp);
51 yParser.SetExpr(yExp);
52 zParser.SetExpr(zExp);
54 mu::value_type uVar = 0;
55 mu::value_type vVar = 0;
57 xParser.DefineVar(
"u", &uVar); xParser.DefineVar(
"U", &uVar);
58 yParser.DefineVar(
"u", &uVar); yParser.DefineVar(
"U", &uVar);
59 zParser.DefineVar(
"u", &uVar); zParser.DefineVar(
"U", &uVar);
60 xParser.DefineVar(
"v", &vVar); xParser.DefineVar(
"V", &vVar);
61 yParser.DefineVar(
"v", &vVar); yParser.DefineVar(
"V", &vVar);
62 zParser.DefineVar(
"v", &vVar); zParser.DefineVar(
"V", &vVar);
64 mu::value_type iVar = 0;
65 mu::value_type jVar = 0;
67 xParser.DefineVar(
"i", &iVar); xParser.DefineVar(
"I", &iVar);
68 yParser.DefineVar(
"i", &iVar); yParser.DefineVar(
"I", &iVar);
69 zParser.DefineVar(
"i", &iVar); zParser.DefineVar(
"I", &iVar);
70 xParser.DefineVar(
"j", &jVar); xParser.DefineVar(
"J", &jVar);
71 yParser.DefineVar(
"j", &jVar); yParser.DefineVar(
"J", &jVar);
72 zParser.DefineVar(
"j", &jVar); zParser.DefineVar(
"J", &jVar);
74 xParser.DefineConst(
"time", (
double)time); xParser.DefineConst(
"Time", (
double)time); xParser.DefineConst(
"TIME", (
double)time);
75 yParser.DefineConst(
"time", (
double)time); yParser.DefineConst(
"Time", (
double)time); yParser.DefineConst(
"TIME", (
double)time);
76 zParser.DefineConst(
"time", (
double)time); zParser.DefineConst(
"Time", (
double)time); zParser.DefineConst(
"TIME", (
double)time);
87 for (
unsigned long i = 0; i < constantCount; ++i)
89 xParser.DefineConst(constantKeys[i], constantValues[i]);
90 yParser.DefineConst(constantKeys[i], constantValues[i]);
91 zParser.DefineConst(constantKeys[i], constantValues[i]);
95 int width = uSubdivisions;
96 int height = vSubdivisions;
98 float ustep = 1./(width-1.), vstep = 1./(height-1.);
100 int vertexCount = width * height;
102 unsigned int elementCount = ((uSubdivisions-1)*(vSubdivisions-1))*3*2;
103 float *positions, *normals, *textureCoordinates;
104 unsigned int *elements;
106 bzero(normals,
sizeof(
float) * 3 * vertexCount);
111 float u = 0., v = 0.;
112 for(
int y = 0; y < height; y++)
114 vVar =
VuoReal_lerp(vMin, vMax, (closeV && y==height-1) ? 0 : v);
115 for(
int x = 0; x < width; x++)
117 uVar =
VuoReal_lerp(uMin, uMax, (closeU && x==width-1) ? 0 : u);
122 positions[i * 3 ] = xParser.Eval();
123 positions[i * 3 + 1] = yParser.Eval();
124 positions[i * 3 + 2] = zParser.Eval();
126 textureCoordinates[i * 2 ] = u;
127 textureCoordinates[i * 2 + 1] = v;
137 catch (mu::Parser::exception_type &e)
139 VUserLog(
"Error: %s", e.GetMsg().c_str());
142 free(textureCoordinates);
148 width = uSubdivisions-1;
149 height = vSubdivisions-1;
152 unsigned int* normalCount = (
unsigned int*)calloc(
sizeof(
unsigned int) * vertexCount,
sizeof(
unsigned int));
155 int one, two, three, four;
159 int stride = width+1;
161 for(
int y=0;y<height;++y)
163 for(
int x=0;x<width;++x)
167 three = x+row+stride;
168 four = x+row+stride+1;
176 add(normals, one, faceNormal);
177 add(normals, two, faceNormal);
178 add(normals, three, faceNormal);
179 add(normals, four, faceNormal);
183 normalCount[three]++;
186 if(closeU && x == width-1)
194 add(normals, two, uNrm);
195 add(normals, four, uNrm);
197 add(normals, row, faceNormal);
198 add(normals, row + stride, faceNormal);
203 normalCount[row+stride]++;
206 if(closeV && y==height-1)
213 add(normals, three, vNrm);
214 add(normals, four, vNrm);
215 add(normals, x, faceNormal);
216 add(normals, x + 1, faceNormal);
218 normalCount[three]++;
227 elements[index ] = three;
228 elements[index + 1] = one;
229 elements[index + 2] = two;
230 elements[index + 3] = two;
231 elements[index + 4] = four;
232 elements[index + 5] = three;
240 for(
int i = 0; i < vertexCount; i++)
242 normals[i * 3 ] /= normalCount[i];
243 normals[i * 3 + 1] /= normalCount[i];
244 normals[i * 3 + 2] /= normalCount[i];
249 positions, normals, textureCoordinates,
nullptr,