avtLegacyStreamlineFilter::avtLegacyStreamlineFilter() { stepLength = 1.; maxTime = 100.; showStart = true; radius = 0.125; pointDensity = 1; coloringMethod = STREAMLINE_COLOR_SPEED; displayMethod = STREAMLINE_DISPLAY_LINES; streamlineDirection = VTK_INTEGRATE_FORWARD; // // Initialize source values. // sourceType = STREAMLINE_SOURCE_POINT; INIT_POINT(pointSource, 0., 0., 0.); INIT_POINT(lineStart, 0., 0., 0.); INIT_POINT(lineEnd, 1., 0., 0.); INIT_POINT(planeOrigin, 0., 0., 0.); INIT_POINT(planeNormal, 0., 0., 1.); INIT_POINT(planeUpAxis, 0., 1., 0.); planeRadius = 1.4142136; INIT_POINT(sphereOrigin, 0., 0., 0.); sphereRadius = 1.; INIT_POINT(boxExtents, 0., 1., 0.); INIT_POINT(boxExtents+3, 1., 0., 1.); useWholeBox = false; // Set all of the filters to 0. streamline = 0; tubes = 0; ribbons = 0; }
void yprToTrans(const YPRTrans* ypr, RotMat o){ /* * In our coordinates, yaw = y, pitch = x, roll = z * We will compose our rotations as Y_1 X_2 Z_3 */ const float yaw = ypr->yaw, pitch = ypr->pitch, roll = ypr->roll, c1 = cos(yaw), s1 = sin(yaw), c2 = cos(pitch),s2 = sin(pitch), c3 = cos(roll), s3 = sin(roll); INIT_POINT(o[0], c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3, c2*s1); INIT_POINT(o[1], c2*s3, c2*c3, -s2); INIT_POINT(o[2], c1*s2*s3 - c3 * s1, c1*c3*s2 + s1*s3, c1*c2); }
void rotateTrans(const Point *p, Point *o, const RotMat rot) { Point tmp; INIT_POINT(tmp, dot(p,rot + 0), dot(p,rot + 1), dot(p,rot + 2)); *o = tmp; }
void scaleProj(const Point *p, Point *o, const float * scale){ Point tmp; INIT_POINT(tmp, *scale * p->x, *scale * p->y, *scale * p->z); *o = tmp; }
void snapOntoProj(const Point *p, Point *o, const OntoProj * state){ Point tmp; const float x = state->zeroCoord == offsetof(Point, x) ? state->planeValue : p->x, y = state->zeroCoord == offsetof(Point, y) ? state->planeValue : p->y, z = state->zeroCoord == offsetof(Point, z) ? state->planeValue : p->z; INIT_POINT(tmp,roundOwn(x),roundOwn(y),roundOwn(z)); *o = tmp; }
void orthoProj(const Point *p, Point *o, const Edge * viewportSpan){ const Point * min = (*viewportSpan)[START]; const Point * max = (*viewportSpan)[END]; const float l = min->x, r = max->x, b = min->y, t = max->y, n = min->z, f = max->z, x = (2*p->x - (l + r))/(r-l), y = (2*p->y - (t + b))/(t-b), z = (-2*p->z + (f + n))/(f-n); Point tmp; INIT_POINT(tmp, x,y,z); *o = tmp; }
void render(PaletteRef *raster, int lineWidth, int numLines, const rb_red_blk_tree *scanLinePrimBuckets){ static OntoProj screenPlaneData = {offsetof(Point, z), 0}; static const Transformation screenPlane = {(TransformationF)(&snapOntoProj), &screenPlaneData}; { int line; rb_red_blk_tree activePrimSet; ActiveEdgeList ael = freshAEL(); rb_red_blk_map_tree inFlags; rb_red_blk_tree deFlags; /* This ensures that both trees are initialized and in a cleared state */ RBTreeMapInit(&inFlags, pointerDiffF, NULL, &RBMapNodeAlloc, NULL); RBTreeInit(&deFlags, pointerDiffF, NULL, &RBNodeAlloc); RBTreeInit(&activePrimSet, pointerDiffF, NULL, &RBNodeAlloc); dPrintf(("Scanning line: 0\n")); for(line = 0; line < numLines; (++line), (raster += lineWidth)) { rb_red_blk_node *primIt, *p = NULL, *nextP; dPrintf(("\tUpdating activePrimSet\n")); for (primIt = activePrimSet.first; primIt != activePrimSet.sentinel; (p = primIt), (primIt = nextP)) { const Primitive* prim = primIt->key; const int top = roundOwn(topMostPoint(prim)); nextP = TreeSuccessor(&activePrimSet, primIt); if(top < line){ #ifndef NDEBUG { const int bottom = roundOwn(bottomMostPoint(prim)); dPrintf(("\t\t%d -> %d ( %s ) is not valid here: %d\n",top,bottom,fmtColor(prim->color), line)); } #endif RBDelete(&activePrimSet, primIt); primIt = p; /* We don't want to advance p into garbage data */ } } { const rb_red_blk_tree *bucket = scanLinePrimBuckets + line; const rb_red_blk_node *node; for(node = bucket->first; node != bucket->sentinel; node = TreeSuccessor(bucket, node)) { Primitive * prim = node->key; #ifndef NDEBUG { const int top = roundOwn(topMostPoint(prim)), bottom = roundOwn(bottomMostPoint(prim)); dPrintf(("\t\t%d -> %d ( %s ) is added here: %d\n",top,bottom,fmtColor(prim->color), line)); } #endif RBTreeInsert(&activePrimSet, prim); } } stepEdges(&ael, &activePrimSet); { int curPixel = 0; const Primitive *curDraw = NULL; EdgeListEntry *nextEdge; LinkN* i = ael.activeEdges; if(i){ nextEdge = i->data; while(nextEdge && curPixel < lineWidth){ EdgeListEntry *const startEdge = nextEdge; Primitive *const startOwner = startEdge->owner; int startX = roundOwn(getSmartXForLine(startEdge, line)), nextX; rb_red_blk_map_node *inFlag = (rb_red_blk_map_node *)RBExactQuery((rb_red_blk_tree*)(&inFlags), startOwner); if(inFlag){ static Point localPoints[6]; /* We don't recurse, so this is fine */ static Edge flatHere = {localPoints, localPoints + 1}, flatIn = {localPoints + 2, localPoints + 3}, vert = {localPoints + 4, localPoints + 5}; const EdgeListEntry *const edgeInEntry = inFlag->info; Point **const edgeHere = startEdge->edge, **edgeIn = edgeInEntry->edge; const Point *const s = edgeHere[START], *const e = edgeHere[END]; Point here; bool sV, eV, v; float dotH, dotIn; transformEdge(&screenPlane, edgeHere, flatHere); transformEdge(&screenPlane, edgeIn, flatIn); INIT_POINT(here, startX, line, 0); sV = contains(edgeIn, s); eV = contains(edgeIn, e); v = (sV || eV) && contains(flatIn, &here) && contains(flatHere, &here) && (startOwner->arity != 1); vert[START] = &here; INIT_POINT(*(vert[END]), startX, line+1, 0); dotH = v ? dotEdge(vert, flatHere) : 0; dotIn = v ? dotEdge(vert, flatIn) : 0; if(!v || dotH * dotIn > 0){ dPrintf(("\tNot *in* old %s at %f\n", fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); RBSetAdd(&deFlags, startOwner); } else { dPrintf(("\tFound horizontal vertex %s at %f. Don't delete it yet\n",fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); } } else { dPrintf(("\tNow *in* new %s at %f\n",fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); /* This might happen if a polygon is parallel to the x-axis */ RBMapPut(&inFlags, startOwner, startEdge); } if(curPixel < startX){ dPrintf(("\tcurPixel has fallen behind, dragging from %d to %d\n",curPixel, startX)); curPixel = startX; } i = i->tail; if(i){ nextEdge = i->data; nextX = roundOwn(getSmartXForLine(nextEdge, line)); dPrintf(("\tNext edges @ x = %d from %s\n",nextX, fmtColor(nextEdge->owner->color))); } else { dPrintf(("\tNo more edges\n")); nextEdge = NULL; nextX = 0; } nextX = min(nextX, lineWidth); while ((!nextEdge && curPixel < lineWidth) || (curPixel < nextX)) { bool zFight = false, solitary = false; float bestZ = HUGE_VAL; const rb_red_blk_node *node; curDraw = NULL; dPrintf(("\tTesting depth:\n")); for(node = inFlags.tree.first; node != inFlags.tree.sentinel; node = TreeSuccessor((rb_red_blk_tree*)(&inFlags), node)) { const Primitive *prim = node->key; /* We need sub-pixel accuracy */ const float testZ = getZForXY(prim, curPixel, line); if(testZ <= bestZ + PT_EPS){ dPrintf(("\t\tHit: %f <= %f for %s\n",testZ, bestZ, fmtColor(prim->color))); if (CLOSE_ENOUGH(testZ, bestZ)) { if (prim->arity == 1) { zFight = curDraw && curDraw->arity == 1; curDraw = prim; solitary = RBSetContains(&deFlags, prim); } else { zFight = curDraw && curDraw->arity != 1; } } else { zFight = false; bestZ = testZ; curDraw = prim; solitary = RBSetContains(&deFlags, prim); } } else { dPrintf(("\t\tMiss: %f > %f for %s\n",testZ, bestZ, fmtColor(prim->color))); } } if(curDraw){ #ifndef NDEBUG if(nextEdge || solitary){ #endif const int drawWidth = (zFight || solitary) ? 1 : ((nextEdge ? nextX : lineWidth) - curPixel), stopPixel = curPixel + min(lineWidth - curPixel, max(0, drawWidth)); const PaletteRef drawColor = /*(uint16_t)roundOwn(63 * bestZ / 100) << 5;*/decodeColor(curDraw->color); dPrintf(("Drawing %d @ (%d, %d)\n",drawWidth,curPixel,line)); dPrintf(("Drawing %d @ (%d, %d)\n",stopPixel - curPixel,curPixel,line)); while(curPixel < stopPixel){ raster[curPixel++] = drawColor; } #ifndef NDEBUG } else { dPrintf(("Warning: we probably shouldn't have to draw if there are no more edges to turn us off. Look for parity errors\n"); RBTreeClear((rb_red_blk_tree*)&inFlags)); } #endif } else if(!inFlags.tree.size && nextEdge){ /* fast forward, we aren't in any polys */ dPrintf(("Not in any polys at the moment, fast-forwarding(1) to %d\n", nextX)); curPixel = nextX; } else { /* Nothing left */ dPrintf(("Nothing to draw at end of line\n")); curPixel = lineWidth; } for(node = deFlags.first; node != deFlags.sentinel; node = TreeSuccessor(&deFlags, node)){ RBMapRemove(&inFlags, node->key); } RBTreeClear(&deFlags); } if (!inFlags.tree.size && nextEdge) { dPrintf(("Not in any polys at the moment, fast-forwarding(2) to %d\n", nextX)); curPixel = nextX; } } } } #ifndef NDEBUG { dPrintf(("Scanning line: %d\n", line+1)); if(inFlags.tree.size){ rb_red_blk_node *node; dPrintf(("\tGarbage left in inFlags:\n")); for (node = inFlags.tree.first; node != inFlags.tree.sentinel; node = TreeSuccessor((rb_red_blk_tree*)&inFlags, node)) { dPrintf(("\t\t%s\n",fmtColor(((const Primitive*)node->key)->color))); } } } #endif RBTreeClear(&deFlags); RBTreeClear((rb_red_blk_tree*)(&inFlags)); } RBTreeDestroy(&activePrimSet, false); RBTreeDestroy(&deFlags, false); RBTreeDestroy((rb_red_blk_tree*)(&inFlags), false); }