void NvStripifier::Stripify(const WordVec &in_indices, const int in_cacheSize, const int in_minStripLength, const unsigned short maxIndex, NvStripInfoVec &outStrips, NvFaceInfoVec& outFaceList) { meshJump = 0.0f; bFirstTimeResetPoint = true; //used in FindGoodResetPoint() //the number of times to run the experiments int numSamples = 10; int i; //the cache size, clamped to one cacheSize = max(1, in_cacheSize - CACHE_INEFFICIENCY); minStripLength = in_minStripLength; //this is the strip size threshold below which we dump the strip into a list indices = in_indices; // build the stripification info NvFaceInfoVec allFaceInfos; NvEdgeInfoVec allEdgeInfos; BuildStripifyInfo(allFaceInfos, allEdgeInfos, maxIndex); NvStripInfoVec allStrips; // stripify FindAllStrips(allStrips, allFaceInfos, allEdgeInfos, numSamples); //split up the strips into cache friendly pieces, optimize them, then dump these into outStrips SplitUpStripsAndOptimize(allStrips, outStrips, allEdgeInfos, outFaceList); //clean up for(i = 0; i < allStrips.size(); i++) { delete allStrips[i]; } for (i = 0; i < allEdgeInfos.size(); i++) { NvEdgeInfo *info = allEdgeInfos[i]; while (info != NULL) { NvEdgeInfo *next = (info->m_v0 == i ? info->m_nextV0 : info->m_nextV1); info->Unref(); info = next; } } }
/////////////////////////////////////////////////////////////////////////////////////////// // BuildStripifyInfo() // // Builds the list of all face and edge infos // void NvStripifier::BuildStripifyInfo(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, const unsigned short maxIndex) { // reserve space for the face infos, but do not resize them. int numIndices = indices.size(); faceInfos.reserve(numIndices / 3); // we actually resize the edge infos, so we must initialize to NULL edgeInfos.resize(maxIndex + 1); for (unsigned short i = 0; i < maxIndex + 1; i++) edgeInfos[i] = NULL; // iterate through the triangles of the triangle list int numTriangles = numIndices / 3; int index = 0; bool bFaceUpdated[3]; for (int i = 0; i < numTriangles; i++) { bool bMightAlreadyExist = true; bFaceUpdated[0] = false; bFaceUpdated[1] = false; bFaceUpdated[2] = false; // grab the indices int v0 = indices[index++]; int v1 = indices[index++]; int v2 = indices[index++]; //we disregard degenerates if(IsDegenerate(v0, v1, v2)) continue; // create the face info and add it to the list of faces, but only if this exact face doesn't already // exist in the list NvFaceInfo *faceInfo = new NvFaceInfo(v0, v1, v2); // grab the edge infos, creating them if they do not already exist NvEdgeInfo *edgeInfo01 = FindEdgeInfo(edgeInfos, v0, v1); if (edgeInfo01 == NULL) { //since one of it's edges isn't in the edge data structure, it can't already exist in the face structure bMightAlreadyExist = false; // create the info edgeInfo01 = new NvEdgeInfo(v0, v1); // update the linked list on both edgeInfo01->m_nextV0 = edgeInfos[v0]; edgeInfo01->m_nextV1 = edgeInfos[v1]; edgeInfos[v0] = edgeInfo01; edgeInfos[v1] = edgeInfo01; // set face 0 edgeInfo01->m_face0 = faceInfo; } else { if (edgeInfo01->m_face1 != NULL) { printf("BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences\n"); } else { edgeInfo01->m_face1 = faceInfo; bFaceUpdated[0] = true; } } // grab the edge infos, creating them if they do not already exist NvEdgeInfo *edgeInfo12 = FindEdgeInfo(edgeInfos, v1, v2); if (edgeInfo12 == NULL) { bMightAlreadyExist = false; // create the info edgeInfo12 = new NvEdgeInfo(v1, v2); // update the linked list on both edgeInfo12->m_nextV0 = edgeInfos[v1]; edgeInfo12->m_nextV1 = edgeInfos[v2]; edgeInfos[v1] = edgeInfo12; edgeInfos[v2] = edgeInfo12; // set face 0 edgeInfo12->m_face0 = faceInfo; } else { if (edgeInfo12->m_face1 != NULL) { printf("BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences\n"); } else { edgeInfo12->m_face1 = faceInfo; bFaceUpdated[1] = true; } } // grab the edge infos, creating them if they do not already exist NvEdgeInfo *edgeInfo20 = FindEdgeInfo(edgeInfos, v2, v0); if (edgeInfo20 == NULL) { bMightAlreadyExist = false; // create the info edgeInfo20 = new NvEdgeInfo(v2, v0); // update the linked list on both edgeInfo20->m_nextV0 = edgeInfos[v2]; edgeInfo20->m_nextV1 = edgeInfos[v0]; edgeInfos[v2] = edgeInfo20; edgeInfos[v0] = edgeInfo20; // set face 0 edgeInfo20->m_face0 = faceInfo; } else { if (edgeInfo20->m_face1 != NULL) { printf("BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences\n"); } else { edgeInfo20->m_face1 = faceInfo; bFaceUpdated[2] = true; } } if(bMightAlreadyExist) { if(!AlreadyExists(faceInfo, faceInfos)) faceInfos.push_back(faceInfo); else { delete faceInfo; //cleanup pointers that point to this deleted face if(bFaceUpdated[0]) edgeInfo01->m_face1 = NULL; if(bFaceUpdated[1]) edgeInfo12->m_face1 = NULL; if(bFaceUpdated[2]) edgeInfo20->m_face1 = NULL; } } else { faceInfos.push_back(faceInfo); } } }
/////////////////////////////////////////////////////////////////////////////////////////// // BuildStripifyInfo() // // Builds the list of all face and edge infos // void NvStripifier::BuildStripifyInfo(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos){ // reserve space for the face infos, but do not resize them. int numIndices = indices.size(); faceInfos.reserve(numIndices); // we actually resize the edge infos, so we must initialize to NULL edgeInfos.resize (numIndices); for (int i = 0; i < numIndices; i++) edgeInfos[i] = NULL; // iterate through the triangles of the triangle list int numTriangles = numIndices / 3; int index = 0; for (u32 i = 0; i < numTriangles; i++) { // grab the indices int v0 = indices[index++]; int v1 = indices[index++]; int v2 = indices[index++]; // create the face info and add it to the list of faces, but only if this exact face doesn't already // exist in the list NvFaceInfo *faceInfo = xr_new<NvFaceInfo>(v0, v1, v2); if(!AlreadyExists(faceInfo, faceInfos)) { faceInfos.push_back(faceInfo); // grab the edge infos, creating them if they do not already exist NvEdgeInfo *edgeInfo01 = FindEdgeInfo(edgeInfos, v0, v1); if (edgeInfo01 == NULL){ // create the info edgeInfo01 = xr_new<NvEdgeInfo>(v0, v1); // update the linked list on both edgeInfo01->m_nextV0 = edgeInfos[v0]; edgeInfo01->m_nextV1 = edgeInfos[v1]; edgeInfos[v0] = edgeInfo01; edgeInfos[v1] = edgeInfo01; // set face 0 edgeInfo01->m_face0 = faceInfo; } else { if (edgeInfo01->m_face1 != NULL) ; //Msg("! WARNING: BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences"); else edgeInfo01->m_face1 = faceInfo; } // grab the edge infos, creating them if they do not already exist NvEdgeInfo *edgeInfo12 = FindEdgeInfo(edgeInfos, v1, v2); if (edgeInfo12 == NULL){ // create the info edgeInfo12 = xr_new<NvEdgeInfo> (v1, v2); // update the linked list on both edgeInfo12->m_nextV0 = edgeInfos[v1]; edgeInfo12->m_nextV1 = edgeInfos[v2]; edgeInfos[v1] = edgeInfo12; edgeInfos[v2] = edgeInfo12; // set face 0 edgeInfo12->m_face0 = faceInfo; } else { if (edgeInfo12->m_face1 != NULL) ; //Msg("! WARNING: BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences"); else edgeInfo12->m_face1 = faceInfo; } // grab the edge infos, creating them if they do not already exist NvEdgeInfo *edgeInfo20 = FindEdgeInfo(edgeInfos, v2, v0); if (edgeInfo20 == NULL){ // create the info edgeInfo20 = xr_new<NvEdgeInfo>(v2, v0); // update the linked list on both edgeInfo20->m_nextV0 = edgeInfos[v2]; edgeInfo20->m_nextV1 = edgeInfos[v0]; edgeInfos[v2] = edgeInfo20; edgeInfos[v0] = edgeInfo20; // set face 0 edgeInfo20->m_face0 = faceInfo; } else { if (edgeInfo20->m_face1 != NULL) ; //Msg("! WARNING: BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences"); else edgeInfo20->m_face1 = faceInfo; } } } }