// ------------------------------------------------------------------------------------------------- // Split a single Triangle and link it into the mesh. // Will correctly force-split diamonds. // void Patch::Split(TriTreeNode* tri) { // We are already split, no need to do it again. if (!tri->IsLeaf()) return; // If this triangle is not in a proper diamond, force split our base neighbor if (tri->BaseNeighbor && (tri->BaseNeighbor->BaseNeighbor != tri)) Split(tri->BaseNeighbor); // Create children and link into mesh CTriNodePool* pool = CTriNodePool::GetPool(); tri->LeftChild = pool->AllocateTri(); tri->RightChild = pool->AllocateTri(); // If creation failed, just exit. if (!tri->IsBranch()) { // make sure both nodes are NULL if just the right one failed // special handling the cause that only one of them is NULL wouldn't make sense (only less performance) tri->LeftChild = nullptr; tri->RightChild = nullptr; return; } // Fill in the information we can get from the parent (neighbor pointers) tri->LeftChild->BaseNeighbor = tri->LeftNeighbor; tri->LeftChild->LeftNeighbor = tri->RightChild; tri->RightChild->BaseNeighbor = tri->RightNeighbor; tri->RightChild->RightNeighbor = tri->LeftChild; // Link our Left Neighbor to the new children if (tri->LeftNeighbor != nullptr) { if (tri->LeftNeighbor->BaseNeighbor == tri) tri->LeftNeighbor->BaseNeighbor = tri->LeftChild; else if (tri->LeftNeighbor->LeftNeighbor == tri) tri->LeftNeighbor->LeftNeighbor = tri->LeftChild; else if (tri->LeftNeighbor->RightNeighbor == tri) tri->LeftNeighbor->RightNeighbor = tri->LeftChild; else ;// Illegal Left Neighbor! } // Link our Right Neighbor to the new children if (tri->RightNeighbor != nullptr) { if (tri->RightNeighbor->BaseNeighbor == tri) tri->RightNeighbor->BaseNeighbor = tri->RightChild; else if (tri->RightNeighbor->RightNeighbor == tri) tri->RightNeighbor->RightNeighbor = tri->RightChild; else if (tri->RightNeighbor->LeftNeighbor == tri) tri->RightNeighbor->LeftNeighbor = tri->RightChild; else ;// Illegal Right Neighbor! } // Link our Base Neighbor to the new children if (tri->BaseNeighbor != nullptr) { if (tri->BaseNeighbor->IsBranch()) { tri->BaseNeighbor->LeftChild->RightNeighbor = tri->RightChild; tri->BaseNeighbor->RightChild->LeftNeighbor = tri->LeftChild; tri->LeftChild->RightNeighbor = tri->BaseNeighbor->RightChild; tri->RightChild->LeftNeighbor = tri->BaseNeighbor->LeftChild; } else { // Base Neighbor (in a diamond with us) was not split yet, so do that now. Split(tri->BaseNeighbor); } } else { // An edge triangle, trivial case. tri->LeftChild->RightNeighbor = nullptr; tri->RightChild->LeftNeighbor = nullptr; } }
// ------------------------------------------------------------------------------------------------- // Split a single Triangle and link it into the mesh. // Will correctly force-split diamonds. // void Patch::Split(TriTreeNode* tri) { // We are already split, no need to do it again. if (!tri->IsLeaf()) return; // If this triangle is not in a proper diamond, force split our base neighbor if (tri->BaseNeighbor && (tri->BaseNeighbor->BaseNeighbor != tri)) Split(tri->BaseNeighbor); // Create children and link into mesh CTriNodePool* pool = CTriNodePool::GetPool(); tri->LeftChild = pool->AllocateTri(); tri->RightChild = pool->AllocateTri(); // If creation failed, just exit. if (!tri->IsBranch()) return; // Fill in the information we can get from the parent (neighbor pointers) tri->LeftChild->BaseNeighbor = tri->LeftNeighbor; tri->LeftChild->LeftNeighbor = tri->RightChild; tri->RightChild->BaseNeighbor = tri->RightNeighbor; tri->RightChild->RightNeighbor = tri->LeftChild; // Link our Left Neighbor to the new children if (tri->LeftNeighbor != NULL) { if (tri->LeftNeighbor->BaseNeighbor == tri) tri->LeftNeighbor->BaseNeighbor = tri->LeftChild; else if (tri->LeftNeighbor->LeftNeighbor == tri) tri->LeftNeighbor->LeftNeighbor = tri->LeftChild; else if (tri->LeftNeighbor->RightNeighbor == tri) tri->LeftNeighbor->RightNeighbor = tri->LeftChild; else ;// Illegal Left Neighbor! } // Link our Right Neighbor to the new children if (tri->RightNeighbor != NULL) { if (tri->RightNeighbor->BaseNeighbor == tri) tri->RightNeighbor->BaseNeighbor = tri->RightChild; else if (tri->RightNeighbor->RightNeighbor == tri) tri->RightNeighbor->RightNeighbor = tri->RightChild; else if (tri->RightNeighbor->LeftNeighbor == tri) tri->RightNeighbor->LeftNeighbor = tri->RightChild; else ;// Illegal Right Neighbor! } // Link our Base Neighbor to the new children if (tri->BaseNeighbor != NULL) { if (tri->BaseNeighbor->IsBranch()) { tri->BaseNeighbor->LeftChild->RightNeighbor = tri->RightChild; tri->BaseNeighbor->RightChild->LeftNeighbor = tri->LeftChild; tri->LeftChild->RightNeighbor = tri->BaseNeighbor->RightChild; tri->RightChild->LeftNeighbor = tri->BaseNeighbor->LeftChild; } else { Split(tri->BaseNeighbor); // Base Neighbor (in a diamond with us) was not split yet, so do that now. } } else { // An edge triangle, trivial case. tri->LeftChild->RightNeighbor = NULL; tri->RightChild->LeftNeighbor = NULL; } }