public void decrement(int index, short decrement = 1) { Util.gDevAssert(isValid(index)); ref_counts[index] -= decrement; Util.gDevAssert(ref_counts[index] >= 0); if (ref_counts[index] == 0) { free_indices.push_back(index); ref_counts[index] = invalid; used_count--; } }
/// <summary> /// Grow selection outwards from seed triangles, until it hits boundaries defined by triangle and edge filters. /// Edge filter is not effective unless it (possibly combined w/ triangle filter) defines closed loops. /// </summary> public void FloodFill(int[] Seeds, Func <int, bool> TriFilterF = null, Func <int, bool> EdgeFilterF = null) { DVector <int> stack = new DVector <int>(Seeds); for (int k = 0; k < Seeds.Length; ++k) { add(Seeds[k]); } while (stack.size > 0) { int tID = stack.back; stack.pop_back(); Index3i nbrs = Mesh.GetTriNeighbourTris(tID); for (int j = 0; j < 3; ++j) { int nbr_tid = nbrs[j]; if (nbr_tid == DMesh3.InvalidID || IsSelected(nbr_tid)) { continue; } if (TriFilterF != null && TriFilterF(nbr_tid) == false) { continue; } if (EdgeFilterF != null && EdgeFilterF(Mesh.GetTriEdge(tID, j)) == false) { continue; } add(nbr_tid); stack.push_back(nbr_tid); } } }
/// <summary> /// remove all elements from list at list_index /// </summary> public void Clear(int list_index) { int block_ptr = list_heads[list_index]; if (block_ptr != Null) { int N = block_store[block_ptr]; // if we have spilled to linked-list, free nodes if (N > BLOCKSIZE) { int cur_ptr = block_store[block_ptr + BLOCK_LIST_OFFSET]; while (cur_ptr != Null) { int free_ptr = cur_ptr; cur_ptr = linked_store[cur_ptr + 1]; add_free_link(free_ptr); } block_store[block_ptr + BLOCK_LIST_OFFSET] = Null; } // free our block block_store[block_ptr] = 0; free_blocks.push_back(block_ptr); list_heads[list_index] = Null; } }
/// <summary> /// Grow selection outwards from seed vertex, until it hits boundaries defined by vertex filter. /// </summary> public void FloodFill(int[] Seeds, Func <int, bool> VertIncludedF = null) { var stack = new DVector <int>(Seeds); for (int k = 0; k < Seeds.Length; ++k) { add(Seeds[k]); } while (stack.size > 0) { int vID = stack.back; stack.pop_back(); foreach (int nbr_vid in Mesh.VtxVerticesItr(vID)) { if (IsSelected(nbr_vid) == true || VertIncludedF(nbr_vid) == false) { continue; } add(nbr_vid); stack.push_back(nbr_vid); } } }
/// <summary> /// Grow selection outwards from seed vertex, until it hits boundaries defined by vertex filter. /// </summary> public void FloodFill(int[] Seeds, Func <int, bool> VertIncludedF = null) { DVector <int> stack = new DVector <int>(Seeds); for (int k = 0; k < Seeds.Length; ++k) { add(Seeds[k]); } while (stack.size > 0) { int vID = stack.back; stack.pop_back(); foreach (int nbr_vid in Mesh.VtxVerticesItr(vID)) { // cherry-picked from https://github.com/ZelimDamian/geometry3Sharp/tree/zelim if (IsSelected(nbr_vid) || VertIncludedF?.Invoke(nbr_vid) == false) { continue; } add(nbr_vid); stack.push_back(nbr_vid); } } }
public void FloodFill(int[] Seeds, Func <int, bool> FilterF = null) { DVector <int> stack = new DVector <int>(Seeds); while (stack.size > 0) { int tID = stack.back; stack.pop_back(); Index3i nbrs = Mesh.GetTriNeighbourTris(tID); for (int j = 0; j < 3; ++j) { int nbr_tid = nbrs[j]; if (nbr_tid == DMesh3.InvalidID || IsSelected(nbr_tid)) { continue; } if (FilterF != null && FilterF(nbr_tid) == false) { continue; } add(nbr_tid); stack.push_back(nbr_tid); } } }
// optimizations: // - no need to store negative-count. that means we could // save one integer per list by using .a or .b // (but code would be horrible...) void add_submesh_mapv(int orig_vid, int submesh_i, int submesh_vid) { // if we have not used this vertex at all, we can store one // (submesh,vid) pair in mapTo if (mapTo[orig_vid].a == 0) { mapTo[orig_vid].a = submesh_i; mapTo[orig_vid].b = submesh_vid; } else { // collision. Need to handle if (mapTo[orig_vid].a > 0) { // if this is the first collision, we push the original // index pair onto the multi-list, then this new one int idx0 = mapToMulti.size; mapToMulti.push_back(mapTo[orig_vid].a); mapToMulti.push_back(mapTo[orig_vid].b); mapToMulti.push_back(-1); // end of list int idx1 = mapToMulti.size; mapToMulti.push_back(submesh_i); mapToMulti.push_back(submesh_vid); mapToMulti.push_back(idx0); // point to first element mapTo[orig_vid].a = -2; // negative element count mapTo[orig_vid].b = idx1; // point to second element } else { // we're already using the multi-list for this index, // push this new index pair onto head of list mapTo[orig_vid].a--; // increment negative-counter int cur_front = mapTo[orig_vid].b; int idx = mapToMulti.size; mapToMulti.push_back(submesh_i); mapToMulti.push_back(submesh_vid); mapToMulti.push_back(cur_front); // point to current front of list mapTo[orig_vid].b = idx; // point to new element } } }
public int allocate() { used_count++; if (free_indices.empty) { // [RMS] do we need this branch anymore? ref_counts.push_back(1); return(ref_counts.size - 1); } else { int iFree = invalid; while (iFree == invalid && free_indices.empty == false) { iFree = free_indices.back; free_indices.pop_back(); } if (iFree != invalid) { ref_counts[iFree] = 1; return(iFree); } else { ref_counts.push_back(1); return(ref_counts.size - 1); } } }
public int allocate() { used_count++; if (free_indices.empty) { ref_counts.push_back(1); return(ref_counts.size - 1); } else { int iFree = free_indices.back; free_indices.pop_back(); ref_counts[iFree] = 1; return(iFree); } }
public void Append(T a, T b, T c) { vector.push_back(a); vector.push_back(b); vector.push_back(c); }