int avtExtractor::ConstructBounds(const double (*pts)[3], int npts) { double fminx = +FLT_MAX; double fmaxx = -FLT_MAX; double fminy = +FLT_MAX; double fmaxy = -FLT_MAX; double fminz = +FLT_MAX; double fmaxz = -FLT_MAX; for (int i = 0 ; i < npts ; i++) { if (pts[i][0] < fminx) { fminx = pts[i][0]; } if (pts[i][0] > fmaxx) { fmaxx = pts[i][0]; } if (pts[i][1] < fminy) { fminy = pts[i][1]; } if (pts[i][1] > fmaxy) { fmaxy = pts[i][1]; } if (pts[i][2] < fminz) { fminz = pts[i][2]; } if (pts[i][2] > fmaxz) { fmaxz = pts[i][2]; } } // // We can get snapped to the frustum if we are outside it, so explicitly // check for this. // double smallest_x = XFromIndex(restrictedMinWidth); double biggest_x = XFromIndex(restrictedMaxWidth); double smallest_y = YFromIndex(restrictedMinHeight); double biggest_y = YFromIndex(restrictedMaxHeight); if (fmaxx < smallest_x || fminx > biggest_x || fmaxy < smallest_y || fminy > biggest_y || fmaxz < FRUSTUM_MIN_Z || fminz > FRUSTUM_MAX_Z) { return 0; } // // We don't want to worry about planes that don't intersect this // cell, so when finding the min, round up and when going towards the // max, round down. // minx = SnapXRight(fminx); maxx = SnapXLeft(fmaxx); miny = SnapYTop(fminy); maxy = SnapYBottom(fmaxy); minz = SnapZBack(fminz); maxz = SnapZFront(fmaxz); if (minx > maxx) return 0; if (miny > maxy) return 0; if (minz > maxz) return 0; // // Return the number of samples in the bounding box. // return (maxx - minx + 1)*(maxy - miny + 1)*(maxz - minz + 1); }
void avtExtractor::ContributeSmallCell(const double (*pts)[3], const double (*vals)[AVT_VARIABLE_LIMIT], int npts) { // This method ends up causing virtually all resampling artifacts. I am // disabling it for now. return; // // Note that this assumes the cell is very small, that it does not span // multiple sample points. // // The calling functions don't actually check for this -- they just see if // it intersects any of the sample points. These two measures typically // coincide, but they don't when we have cells with high aspect ratios. // // In practice, this doesn't come up very much and is only noticable in // rare cases when we are resampling onto a very small rectilinear grid // (often for the preview method -- hardware accelerated). // for (int i = 0 ; i < npts ; i++) { double smallest_x = XFromIndex(restrictedMinWidth); double biggest_x = XFromIndex(restrictedMaxWidth); double smallest_y = YFromIndex(restrictedMinHeight); double biggest_y = YFromIndex(restrictedMaxHeight); if (pts[i][0] < smallest_x || pts[i][0] > biggest_x || pts[i][1] < smallest_y || pts[i][1] > biggest_y || pts[i][2] < FRUSTUM_MIN_Z || pts[i][2] > FRUSTUM_MAX_Z) { continue; } // // Identify the closest sample. // int X_idx = 0; if (x_step > 0.) { double close_to_X_idx = (pts[i][0] - FRUSTUM_MIN_X) / x_step; X_idx = (int) floor(close_to_X_idx); if ((close_to_X_idx - (double)X_idx) > 0.5) X_idx++; } int Y_idx = 0; if (y_step > 0.) { double close_to_Y_idx = (pts[i][1] - FRUSTUM_MIN_Y) / y_step; Y_idx = (int) floor(close_to_Y_idx); if ((close_to_Y_idx - (double)Y_idx) > 0.5) Y_idx++; } int Z_idx = 0; if (z_step > 0.) { double close_to_Z_idx = (pts[i][2] - FRUSTUM_MIN_Z) / z_step; Z_idx = (int) floor(close_to_Z_idx); if ((close_to_Z_idx - (double)Z_idx) > 0.5) Z_idx++; } avtRay *ray = volume->GetRay(X_idx, Y_idx); ray->SetSample(Z_idx, vals[i]); } }
void avtPyramidExtractor::Extract(const avtPyramid &pyr) { int potentialNumSamples = ConstructBounds(pyr.pts, 5); if (potentialNumSamples <= 0) { ContributeSmallCell(pyr.pts, pyr.val, 5); return; } if (sendCellsMode && potentialNumSamples > 64) { celllist->Store(pyr, minx, maxx, miny, maxy); return; } // // minx and maxx are calculated in ConstructBounds. // int minx_iter = (minx < restrictedMinWidth ? restrictedMinWidth : minx); int maxx_iter = (maxx > restrictedMaxWidth ? restrictedMaxWidth : maxx); for (int xi = minx_iter ; xi <= maxx_iter ; xi++) { double x = XFromIndex(xi); int triIndex = IndexToTriangulationTable(pyr.pts, 5, x); // // The triCase will have sets of three vertices, each of which makes // up a triangle that is part of the intersection of this cell with // the plane. Take each triangle and find the sample points from it. // int *triCase = triangulationTables[triIndex]; while (*triCase != -1) { // // Find the triangle for this tri case by seeing which edge the // triangle intersects and then interpolating along that edge // three times to form the triangle. // double y[3], z[3], v[3][AVT_VARIABLE_LIMIT]; for (int tri_vertex = 0 ; tri_vertex < 3 ; tri_vertex++) { int pyr_vertex1 = verticesFromEdges[triCase[tri_vertex]][0]; int pyr_vertex2 = verticesFromEdges[triCase[tri_vertex]][1]; InterpolateToPlane(pyr.pts[pyr_vertex1], pyr.pts[pyr_vertex2], pyr.val[pyr_vertex1], pyr.val[pyr_vertex2], x, y[tri_vertex], z[tri_vertex], v[tri_vertex], pyr.nVars); } // // Call the base class method for extracting sample points from a // triangle. // ExtractTriangle(xi, y, z, v, pyr.nVars); triCase += 3; } } }