in layer1/Extrude.cpp [1712:2039]
int ExtrudeCGOSurfaceStrand(CExtrude * I, CGO * cgo, int sampling, const float *color_override)
{
int a, b;
unsigned int *i;
float *v;
float *n;
float *c;
const float *alpha;
float *sv, *sn, *tv, *tn, *tv1, *tn1, *TV = NULL, *TN = NULL;
float v0[3], n0[3], s0[3], z[3] = { 1.0, 0.0, 1.0 };
int subN;
int ok = true;
subN = I->N - sampling;
PRINTFD(I->G, FB_Extrude)
" ExtrudeCGOSurfaceStrand-DEBUG: entered.\n" ENDFD;
if(I->N && I->Ns) {
TV = Alloc(float, 3 * (I->Ns + 1) * I->N);
CHECKOK(ok, TV);
if (ok)
TN = Alloc(float, 3 * (I->Ns + 1) * I->N);
CHECKOK(ok, TN);
/* compute transformed shape vertices */
if (ok){
tn = TN;
tv = TV;
sv = I->sv;
sn = I->sn;
for(b = 0; b <= I->Ns; b++) {
if(b == I->Ns) {
sv = I->sv;
sn = I->sn;
}
v = I->p;
n = I->n;
for(a = 0; a < I->N; a++) {
copy3f(sv, s0);
if(a == subN) {
scale3f(s0, 0.50F, s0);
}
transform33Tf3f(n, s0, tv);
add3f(v, tv, tv);
tv += 3;
transform33Tf3f(n, sn, tn);
tn += 3;
n += 9;
v += 3;
}
sv += 3;
sn += 3;
}
/* fill in each strip of arrow separately */
tv = TV;
tn = TN;
tv1 = TV + 3 * I->N;
tn1 = TN + 3 * I->N;
}
for(b = 0; ok && b < I->Ns; b += 2) {
if(SettingGetGlobal_i(I->G, cSetting_cartoon_debug) < 1.5)
ok &= CGOBegin(cgo, GL_TRIANGLE_STRIP);
else {
ok &= CGOBegin(cgo, GL_LINE_STRIP);
}
c = I->c;
alpha = I->alpha;
i = I->i;
for(a = 0; ok && a < I->N; a++) {
if(a < subN) {
if(color_override && ((b == 2) || (b == 3) || (b == 6) || (b == 7)))
ok &= CGOColorv(cgo, color_override);
else
ok &= CGOColorv(cgo, c);
if (ok){
ok &= CGOAlpha(cgo, *alpha);
}
if (ok)
ok &= CGOPickColor(cgo, *i, cPickableAtom);
if (ok)
ok &= CGONormalv(cgo, tn);
if (ok)
ok &= CGOVertexv(cgo, tv);
}
tn += 3;
tv += 3;
if(ok && a < subN) {
ok &= CGONormalv(cgo, tn1);
if (ok)
ok &= CGOVertexv(cgo, tv1);
}
tn1 += 3;
tv1 += 3;
c += 3;
alpha++;
i++;
}
tv += 3 * I->N;
tn += 3 * I->N;
tv1 += 3 * I->N;
tn1 += 3 * I->N;
if (ok)
ok &= CGOEnd(cgo);
if (ok)
ok &= CGOPickColor(cgo, -1, cPickableNoPick);
}
if(ok) {
n = I->n;
v = I->p;
sv = I->sv;
tv = I->tv;
for(b = 0; b < I->Ns; b++) {
transform33Tf3f(n, sv, tv);
add3f(v, tv, tv);
sv += 3;
tv += 3;
}
copy3f(I->n, v0);
invert3f(v0);
if (ok){
if(color_override)
ok &= CGOColorv(cgo, color_override);
else
ok &= CGOColorv(cgo, I->c);
}
if(ok){
ok &= CGOAlpha(cgo, I->alpha[0]);
}
if (ok)
ok &= CGOPickColor(cgo, I->i[0], cPickableAtom);
if (ok)
ok &= CGOBegin(cgo, GL_TRIANGLE_STRIP);
if (ok)
ok &= CGONormalv(cgo, v0);
ok &= CGOVertexv(cgo, I->tv + 6 * 3);
ok &= CGOVertexv(cgo, I->tv + 4 * 3);
ok &= CGOVertexv(cgo, I->tv + 0 * 3);
ok &= CGOVertexv(cgo, I->tv + 2 * 3);
if (ok)
ok &= CGOEnd(cgo);
if (ok)
ok &= CGOPickColor(cgo, -1, cPickableNoPick);
}
/* now do the arrow part */
tn = TN;
tv = TV;
sv = I->sv;
sn = I->sn;
if (ok){
for(b = 0; b <= I->Ns; b++) {
if(b == I->Ns) {
sv = I->sv;
sn = I->sn;
}
v = I->p;
n = I->n;
for(a = 0; a < I->N; a++) {
copy3f(sv, s0);
s0[2] = s0[2] * ((1.5F * ((I->N - 1) - a)) / sampling);
transform33Tf3f(n, s0, tv);
add3f(v, tv, tv);
tv += 3;
copy3f(sn, n0);
if(fabs(dot_product3f(sn, z)) > R_SMALL4) {
n0[0] += 0.4F;
normalize3f(n0);
}
transform33Tf3f(n, n0, tn);
tn += 3;
n += 9;
v += 3;
}
sv += 3;
sn += 3;
}
}
tv = TV;
tn = TN;
tv1 = TV + 3 * I->N;
tn1 = TN + 3 * I->N;
for(b = 0; ok && b < I->Ns; b += 2) {
if (ok){
if(SettingGetGlobal_i(I->G, cSetting_cartoon_debug) < 1.5)
ok &= CGOBegin(cgo, GL_TRIANGLE_STRIP);
else {
ok &= CGOBegin(cgo, GL_LINE_STRIP);
}
}
c = I->c;
alpha = I->alpha;
i = I->i;
for(a = 0; ok && a < I->N; a++) {
if(a >= (subN - 1)) {
if(color_override && ((b == 2) || (b == 3) || (b == 6) || (b == 7)))
ok &= CGOColorv(cgo, color_override);
else
ok &= CGOColorv(cgo, c);
if (ok){
ok &= CGOAlpha(cgo, *alpha);
}
if (ok)
ok &= CGOPickColor(cgo, *i, cPickableAtom);
if (ok)
ok &= CGONormalv(cgo, tn);
if (ok)
ok &= CGOVertexv(cgo, tv);
}
tn += 3;
tv += 3;
if(ok && a >= (subN - 1)) {
ok &= CGONormalv(cgo, tn1);
if (ok)
ok &= CGOVertexv(cgo, tv1);
}
tn1 += 3;
tv1 += 3;
c += 3;
alpha++;
i++;
}
tv += 3 * I->N;
tn += 3 * I->N;
tv1 += 3 * I->N;
tn1 += 3 * I->N;
if (ok)
ok &= CGOEnd(cgo);
if (ok)
ok &= CGOPickColor(cgo, -1, cPickableNoPick);
}
n = I->n + 9 * (subN - 1);
v = I->p + 3 * (subN - 1);
sv = I->sv;
tv = I->tv;
if (ok){
for(b = 0; b < I->Ns; b++) {
copy3f(sv, s0);
s0[2] = s0[2] * ((s0[2] < 0.f) ? -1.f : 1.5F) ;
transform33Tf3f(n, s0, tv);
add3f(v, tv, tv);
sv += 3;
tv += 3;
}
}
// Back end/flat surface of the arrow,
// now split into two pieces, one for each side
copy3f(n, v0);
invert3f(v0);
if (ok){
if(color_override)
ok &= CGOColorv(cgo, color_override);
else
ok &= CGOColorv(cgo, I->c + 3 * (subN - 1));
}
if (ok){
ok &= CGOAlpha(cgo, I->alpha[(subN - 1)]);
}
if (ok)
ok &= CGOPickColor(cgo, I->i[(subN - 1)], cPickableAtom);
// draw first side
tv = I->tv;
if (ok)
ok &= CGOBegin(cgo, GL_TRIANGLE_STRIP);
if (ok)
ok &= CGONormalv(cgo, v0);
ok &= CGOVertexv(cgo, I->tv + 6 * 3);
ok &= CGOVertexv(cgo, I->tv + 4 * 3);
ok &= CGOVertexv(cgo, I->tv + 0 * 3);
ok &= CGOVertexv(cgo, I->tv + 2 * 3);
if (ok)
ok &= CGOEnd(cgo);
// switch vertices to other side of flat surface of arrow
sv = I->sv;
tv = I->tv;
if (ok){
for(b = 0; b < I->Ns; b++) {
copy3f(sv, s0);
s0[2] = s0[2] * ((s0[2] < 0.f) ? 1.f : -1.5F) ;
transform33Tf3f(n, s0, tv);
add3f(v, tv, tv);
sv += 3;
tv += 3;
}
}
// draw other side
if (ok)
ok &= CGOBegin(cgo, GL_TRIANGLE_STRIP);
if (ok)
ok &= CGONormalv(cgo, v0);
ok &= CGOVertexv(cgo, I->tv + 0 * 3);
ok &= CGOVertexv(cgo, I->tv + 2 * 3);
ok &= CGOVertexv(cgo, I->tv + 6 * 3);
ok &= CGOVertexv(cgo, I->tv + 4 * 3);
if (ok)
ok &= CGOEnd(cgo);
if (ok)
ok &= CGOPickColor(cgo, -1, cPickableNoPick);
FreeP(TV);
FreeP(TN);
}
PRINTFD(I->G, FB_Extrude)
" ExtrudeCGOSurfaceStrand-DEBUG: exiting...\n" ENDFD;
return ok;
}