double NgonGridDataDecomposer::computeFacetAverageZValue(double* z, int numX, int numY, int i, int j) { double avgz = 0.; int pointIndex = 0; avgz = 0.0; pointIndex = getPointIndex(numX, numY, i, j); avgz += z[pointIndex]; pointIndex = getPointIndex(numX, numY, i+1, j); avgz += z[pointIndex]; pointIndex = getPointIndex(numX, numY, i, j+1); avgz += z[pointIndex]; pointIndex = getPointIndex(numX, numY, i+1, j+1); avgz += z[pointIndex]; avgz *= 0.25; return avgz; }
void NgonGridDataDecomposer::fillDirectGridColors(float* buffer, int bufferLength, int elementsSize, double* colormap, int colormapSize, double* z, int numX, int numY) { int currentPointIndex = 0; int bufferOffset = 0; #if PER_VERTEX_VALUES for (int j = 0; j < numY; j++) { for (int i = 0; i < numX; i++) { currentPointIndex = getPointIndex(numX, numY, i, j); ColorComputer::getDirectColor(z[currentPointIndex] - 1.0, colormap, colormapSize, &buffer[bufferOffset]); if (elementsSize == 4) { buffer[bufferOffset +3] = 1.0; } bufferOffset += elementsSize; } } #else for (int j = 0; j < numY-1; j++) { for (int i = 0; i < numX-1; i++) { float facetColor[3]; currentPointIndex = getPointIndex(numX, numY, i, j); ColorComputer::getDirectColor(z[currentPointIndex] - 1.0, colormap, colormapSize, facetColor); writeFacetColorToBuffer(buffer, bufferOffset, facetColor, elementsSize); bufferOffset += 4*elementsSize; } } #endif }
bool IndexPseudoPyramidTree::insert(const Point& point) { // TODO: add boundary check w/ point here??? int pointIndex = getPointIndex(point); if (pointIndex >= 0) // if point already exists in structure { return false; } else // if point does not exist, insert it! { bool searchKeyExists = (pointIndex == -2); insertToStructure(point, searchKeyExists); return true; } }
void NgonGridDataDecomposer::computeMinMaxZValues(double* z, int numX, int numY, double* zMin, double* zMax) { double maxDouble = 0; double tmpZMin = 0; double tmpZMax = 0; double zi = 0; int currentPoint = 0; maxDouble = DecompositionUtils::getMaxDoubleValue(); tmpZMin = maxDouble; tmpZMax = -maxDouble; for (int j = 0; j < numY; j++) { for (int i = 0; i < numX; i++) { currentPoint = getPointIndex(numX, numY, i, j); zi = z[currentPoint]; if (DecompositionUtils::isValid(zi)) { if(zi < tmpZMin) { tmpZMin = zi; } if (zi > tmpZMax) { tmpZMax = zi; } } } } *zMin = tmpZMin; *zMax = tmpZMax; }
int NgonGridMatplotDataDecomposer::isFacetValid(double* z, double* values, int perNodeValues, int numX, int numY, int i, int j, int logUsed, int currentEdgeValid, int* nextEdgeValid) { double zij = 0.; int facetValid = 0; zij = getZCoordinate(z, numX, numY, i, j, logUsed); facetValid = DecompositionUtils::isValid(zij); if (logUsed) { facetValid &= DecompositionUtils::isLogValid(zij); } /* Transposed relative to Grayplot */ facetValid &= DecompositionUtils::isValid(values[getPointIndex(numY - 1, numX - 1, numY - 2 - j, i)]); /* Edge validity is always 1 since it is not used at all to determine facet validity for Matplot decomposition */ *nextEdgeValid = 1; return facetValid; }
//calculate triangles vertices void generateTriangles(Mat &M, std::vector<Triangle> &triangles){ int rows = M.rows; int cols = M.cols; //triangles.clear(); unsigned int triangleid = 0; for(int i = 0; i < rows-1; i++){ for(int j = 0; j < cols-1; j++){ Triangle *t = &triangles[triangleid]; t->p1idx = getPointIndex(i, j, M.cols); t->p2idx = getPointIndex(i, j+1, M.cols); t->p3idx = getPointIndex(i+1, j+1, M.cols); t->p1 = Point3_<int>(i,j,M.at<unsigned int>(i,j)); t->p2 = Point3_<int>(i,j+1,M.at<unsigned int>(i,j+1)); t->p3 = Point3_<int>(i+1,j+1,M.at<unsigned int>(i+1,j+1)); t->calculateNormal(); //t->id = triangleid; triangleid++; //triangles.push_back(t); } } for(int i = 0; i < rows-1; i++){ for(int j = 0; j < cols-1; j++){ Triangle *t = &triangles[triangleid]; t->p1idx = getPointIndex(i, j, M.cols); t->p2idx = getPointIndex(i+1, j+1, M.cols); t->p3idx = getPointIndex(i+1, j, M.cols); t->p1 = Point3_<int>(i,j,M.at<unsigned int>(i,j)); t->p2 = Point3_<int>(i+1,j+1,M.at<unsigned int>(i+1,j+1)); t->p3 = Point3_<int>(i+1,j,M.at<unsigned int>(i+1,j)); t->calculateNormal(); //t->id = triangleid; triangleid++; //triangles.push_back(t); } } }
/* * To do: merge with Plot3DDecomposer::fillWireIndices, as these functions perform a lot of redundant work. */ int NgonGridDataDecomposer::fillTriangleIndices(int* buffer, int bufferLength, int logMask, double* x, double* y, double* z, double* values, int perNodeValues, int numX, int numY) { int bufferOffset = 0; int currentRowValid = 0; int nextRowValid = 0; int currentColumnValid = 0; int nextColumnValid = 0; int currentEdgeValid = 0; int nextEdgeValid = 0; int currentFacetValid = 0; int ij = 0; int ip1j = 0; int ip1jp1 = 0; int ijp1 = 0; /* 0 indices if less than 2 points along either dimension */ if (numX < 2 || numY < 2) { return 0; } /* First row */ currentRowValid = DecompositionUtils::isValid(y[0]); if (logMask & 0x2) { currentRowValid &= DecompositionUtils::isLogValid(y[0]); } /* To do: optimize */ for (int j = 0; j < numY-1; j++) { nextRowValid = DecompositionUtils::isValid(y[j+1]); if (logMask & 0x2) { nextRowValid &= DecompositionUtils::isLogValid(y[j+1]); } if (!currentRowValid || !nextRowValid) { currentRowValid = nextRowValid; continue; } else { currentRowValid = nextRowValid; } currentColumnValid = DecompositionUtils::isValid(x[0]); if (logMask & 0x1) { currentColumnValid &= DecompositionUtils::isLogValid(x[0]); } ij = getPointIndex(numX, numY, 0, j); ijp1 = getPointIndex(numX, numY, 0, j+1); currentEdgeValid = isFacetEdgeValid(z, values, perNodeValues, numX, numY, 0, j, logMask & 0x4); for (int i = 0; i < numX-1; i++) { nextColumnValid = DecompositionUtils::isValid(x[i+1]); if (logMask & 0x1) { nextColumnValid &= DecompositionUtils::isLogValid(x[i+1]); } ip1j = getPointIndex(numX, numY, i+1, j); ip1jp1 = getPointIndex(numX, numY, i+1, j+1); currentFacetValid = isFacetValid(z, values, perNodeValues, numX, numY, i, j, logMask & 0x4, currentEdgeValid, &nextEdgeValid); if (currentColumnValid && nextColumnValid && (currentFacetValid)) { int facetVertexIndices[4]; int triangleVertexIndices[6]; int firstVertexIndex; #if PER_VERTEX_VALUES facetVertexIndices[0] = ij; facetVertexIndices[1] = ip1j; facetVertexIndices[2] = ip1jp1; facetVertexIndices[3] = ijp1; #else firstVertexIndex = getFirstVertexIndex(numX, numY, i, j); facetVertexIndices[0] = firstVertexIndex; facetVertexIndices[1] = firstVertexIndex+1; facetVertexIndices[2] = firstVertexIndex+3; facetVertexIndices[3] = firstVertexIndex+2; #endif getFacetTriangles(x, y, z, numX, numY, i, j, facetVertexIndices, triangleVertexIndices); buffer[bufferOffset] = triangleVertexIndices[0]; buffer[bufferOffset+1] = triangleVertexIndices[1]; buffer[bufferOffset+2] = triangleVertexIndices[2]; buffer[bufferOffset+3] = triangleVertexIndices[3]; buffer[bufferOffset+4] = triangleVertexIndices[4]; buffer[bufferOffset+5] = triangleVertexIndices[5]; bufferOffset += 6; } currentColumnValid = nextColumnValid; currentEdgeValid = nextEdgeValid; ij = ip1j; ijp1 = ip1jp1; } } return bufferOffset; }
void NgonGridDataDecomposer::fillNormalizedZGridColors(float* buffer, int bufferLength, int elementsSize, double* colormap, int colormapSize, double* z, int numX, int numY) { double zMin = 0.; double zMax = 0.; double zRange = 0.; double minDoubleValue = 0.; int bufferOffset = 0; computeMinMaxZValues(z, numX, numY, &zMin, &zMax); minDoubleValue = DecompositionUtils::getMinDoubleValue(); /* To be verified */ if ((zMax - zMin) < minDoubleValue) { zRange = 1.0; } else { zRange = zMax - zMin; } #if PER_VERTEX_VALUES for (int j = 0; j < numY; j++) { for (int i = 0; i < numX; i++) { int currentPointIndex = getPointIndex(numX, numY, i, j); ColorComputer::getColor(z[currentPointIndex], zMin, zRange, Z_COLOR_OFFSET, colormap, colormapSize, &buffer[bufferOffset]); if (elementsSize == 4) { buffer[bufferOffset +3] = 1.0; } bufferOffset += elementsSize; } } #else for (int j = 0; j < numY-1; j++) { for (int i = 0; i < numX-1; i++) { double avgz; float facetColor[3]; avgz = computeFacetAverageZValue(z, numX, numY, i, j); ColorComputer::getColor(avgz, zMin, zRange, Z_COLOR_OFFSET, colormap, colormapSize, facetColor); writeFacetColorToBuffer(buffer, bufferOffset, facetColor, elementsSize); bufferOffset += 4*elementsSize; } } #endif }
/* * To be optimized: * -a lot of work performed redundantly with NgonGridDataDecomposer::fillIndices, ought to be merged * with it. */ int Plot3DDecomposer::fillWireIndices(char* id, int* buffer, int bufferLength, int logMask) { double* x = NULL; double* y = NULL; double* z = NULL; int numX = 0; int* piNumX = &numX; int numY = 0; int* piNumY = &numY; int previousRowValid = 0; int currentRowValid = 0; int nextRowValid = 0; int previousColumnValid = 0; int currentColumnValid = 0; int nextColumnValid = 0; int lowerLeftZValid = 0; int lowerRightZValid = 0; int upperLeftZValid = 0; int upperRightZValid = 0; int jm1HorizontalEdgeZValid = 0; int im1VerticalEdgeZValid = 0; int jHorizontalEdgeZValid = 0; int iVerticalEdgeZValid = 0; int jp1HorizontalEdgeZValid = 0; int ip1VerticalEdgeZValid = 0; int ij = 0; int ip1j = 0; int ijp1 = 0; int ip1jp1 = 0; int ijm1 = 0; int ip1jm1 = 0; int firstVertexIndex = 0; int bufferOffset = 0; getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_X__, jni_int, (void**) &piNumX); getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_Y__, jni_int, (void**) &piNumY); /* 0 indices if less than 2 points along either dimension */ if (numX < 2 || numY < 2) { return 0; } getGraphicObjectProperty(id, __GO_DATA_MODEL_X__, jni_double_vector, (void**) &x); getGraphicObjectProperty(id, __GO_DATA_MODEL_Y__, jni_double_vector, (void**) &y); getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_double_vector, (void**) &z); /* First row */ previousRowValid = 0; currentRowValid = DecompositionUtils::isValid(y[0]); if (logMask & 0x2) { currentRowValid &= DecompositionUtils::isLogValid(y[0]); } /* Set to 0 as it is not relevant for the first row iteration */ jm1HorizontalEdgeZValid = 0; /* x-axis and y-axis indices (respectively) */ for (int j = 0; j < numY-1; j++) { nextRowValid = DecompositionUtils::isValid(y[j+1]); if (logMask & 0x2) { nextRowValid &= DecompositionUtils::isLogValid(y[j+1]); } if (!currentRowValid) { previousRowValid = currentRowValid; currentRowValid = nextRowValid; continue; } previousColumnValid = 0; currentColumnValid = DecompositionUtils::isValid(x[0]); if (logMask & 0x1) { currentColumnValid &= DecompositionUtils::isLogValid(x[0]); } ij = getPointIndex(numX, numY, 0, j); ijp1 = getPointIndex(numX, numY, 0, j+1); lowerLeftZValid = DecompositionUtils::isValid(z[ij]); upperLeftZValid = DecompositionUtils::isValid(z[ijp1]); if (logMask & 0x4) { lowerLeftZValid &= DecompositionUtils::isLogValid(z[ij]); upperLeftZValid &= DecompositionUtils::isLogValid(z[ijp1]); } iVerticalEdgeZValid = lowerLeftZValid && upperLeftZValid; /* Set to 0 as not relevant for the first column iteration */ im1VerticalEdgeZValid = 0; for (int i = 0; i < numX-1; i++) { #if !PER_VERTEX_VALUES firstVertexIndex = getFirstVertexIndex(numX, numY, i, j); #endif ip1j = getPointIndex(numX, numY, i+1, j); ip1jp1 = getPointIndex(numX, numY, i+1, j+1); nextColumnValid = DecompositionUtils::isValid(x[i+1]); if (logMask & 0x1) { nextColumnValid &= DecompositionUtils::isLogValid(x[i+1]); } lowerRightZValid = DecompositionUtils::isValid(z[ip1j]); upperRightZValid = DecompositionUtils::isValid(z[ip1jp1]); if (logMask & 0x4) { lowerRightZValid &= DecompositionUtils::isLogValid(z[ip1j]); upperRightZValid &= DecompositionUtils::isLogValid(z[ip1jp1]); } if (j > 0) { ijm1 = getPointIndex(numX, numY, i, j-1); ip1jm1 = getPointIndex(numX, numY, i+1, j-1); jm1HorizontalEdgeZValid = DecompositionUtils::isValid(z[ijm1]) && DecompositionUtils::isValid(z[ip1jm1]); if (logMask & 0x4) { jm1HorizontalEdgeZValid &= (DecompositionUtils::isLogValid(z[ijm1]) && DecompositionUtils::isLogValid(z[ip1jm1])); } } jHorizontalEdgeZValid = lowerLeftZValid && lowerRightZValid; jp1HorizontalEdgeZValid = upperLeftZValid && upperRightZValid; ip1VerticalEdgeZValid = lowerRightZValid && upperRightZValid; /* * Two segments: between points (i,j) and (i+1,j) * and points (i,j) and (i,j+1) . */ if ((currentColumnValid && nextColumnValid) && jHorizontalEdgeZValid && ((previousRowValid && jm1HorizontalEdgeZValid) || (nextRowValid && jp1HorizontalEdgeZValid))) { #if PER_VERTEX_VALUES buffer[bufferOffset] = ij; buffer[bufferOffset+1] = ip1j; #else buffer[bufferOffset] = firstVertexIndex; buffer[bufferOffset+1] = firstVertexIndex +1; #endif bufferOffset += 2; } if (currentColumnValid && nextRowValid && iVerticalEdgeZValid && ((previousColumnValid && im1VerticalEdgeZValid) || (nextColumnValid && ip1VerticalEdgeZValid))) { #if PER_VERTEX_VALUES buffer[bufferOffset] = ij; buffer[bufferOffset+1] = ijp1; #else buffer[bufferOffset] = firstVertexIndex; buffer[bufferOffset+1] = firstVertexIndex +2; #endif bufferOffset += 2; } previousColumnValid = currentColumnValid; currentColumnValid = nextColumnValid; lowerLeftZValid = lowerRightZValid; upperLeftZValid = upperRightZValid; im1VerticalEdgeZValid = iVerticalEdgeZValid; iVerticalEdgeZValid = ip1VerticalEdgeZValid; ij = ip1j; ijp1 = ip1jp1; } /* Rightmost vertical line */ if (currentColumnValid && nextRowValid && iVerticalEdgeZValid && (previousColumnValid && im1VerticalEdgeZValid)) { #if PER_VERTEX_VALUES buffer[bufferOffset] = ij; buffer[bufferOffset+1] = ijp1; #else firstVertexIndex = getFirstVertexIndex(numX, numY, numX-2, j); buffer[bufferOffset] = firstVertexIndex +1; buffer[bufferOffset+1] = firstVertexIndex +3; #endif bufferOffset += 2; } previousRowValid = currentRowValid; currentRowValid = nextRowValid; } /* Topmost horizontal lines */ currentRowValid = DecompositionUtils::isValid(y[numY-1]); if (logMask & 0x2) { currentRowValid &= DecompositionUtils::isLogValid(y[numY-1]); } currentColumnValid = DecompositionUtils::isValid(x[0]); if (logMask & 0x1) { currentColumnValid = DecompositionUtils::isValid(x[0]); } ij = getPointIndex(numX, numY, 0, numY-1); lowerLeftZValid = DecompositionUtils::isValid(z[ij]); if (logMask & 0x4) { lowerLeftZValid &= DecompositionUtils::isValid(z[ij]); } ij = getPointIndex(numX, numY, 0, numY-1); for (int i = 0; i < numX-1; i++) { nextColumnValid = DecompositionUtils::isValid(x[i+1]); if (logMask & 0x1) { nextColumnValid &= DecompositionUtils::isLogValid(x[i+1]); } ip1j = getPointIndex(numX, numY, i+1, numY-1); lowerRightZValid = DecompositionUtils::isValid(z[ip1j]); if (logMask & 0x4) { lowerRightZValid &= DecompositionUtils::isLogValid(z[ip1j]); } ijm1 = getPointIndex(numX, numY, i, numY-2); ip1jm1 = getPointIndex(numX, numY, i+1, numY-2); jm1HorizontalEdgeZValid = DecompositionUtils::isValid(z[ijm1]) && DecompositionUtils::isValid(z[ip1jm1]); if (logMask & 0x4) { jm1HorizontalEdgeZValid &= (DecompositionUtils::isLogValid(z[ijm1]) && DecompositionUtils::isLogValid(z[ip1jm1])); } jHorizontalEdgeZValid = lowerLeftZValid && lowerRightZValid; if (currentRowValid && (currentColumnValid && nextColumnValid) && jHorizontalEdgeZValid && (previousRowValid && jm1HorizontalEdgeZValid)) { #if PER_VERTEX_VALUES buffer[bufferOffset] = ij; buffer[bufferOffset+1] = ip1j; #else firstVertexIndex = getFirstVertexIndex(numX, numY, i, numY-2); buffer[bufferOffset] = firstVertexIndex +2; buffer[bufferOffset+1] = firstVertexIndex +3; #endif bufferOffset += 2; } currentColumnValid = nextColumnValid; lowerLeftZValid = lowerRightZValid; ij = ip1j; } return bufferOffset; }
bool IndexPseudoPyramidTree::pointExists(const Point& point) { return (getPointIndex(point) >= 0); }