public int AppendVertex(Vector2d v) { int vid = vertices_refcount.allocate(); int i = 2 * vid; vertices.insert(v[1], i + 1); vertices.insert(v[0], i); vertex_edges.insert(new List <int>(), vid); updateTimeStamp(true); return(vid); }
// helper fn for above, just makes code cleaner void add_tri_edge(int tid, int v0, int v1, int j, int eid) { if (eid != InvalidID) { edges[4 * eid + 3] = tid; triangle_edges.insert(eid, 3 * tid + j); } else { triangle_edges.insert(add_edge(v0, v1, tid), 3 * tid + j); } }
public int AppendTriangle(Index3i tv, int gid = -1) { if (IsVertex(tv[0]) == false || IsVertex(tv[1]) == false || IsVertex(tv[2]) == false) { Util.gDevAssert(false); return(InvalidID); } if (tv[0] == tv[1] || tv[0] == tv[2] || tv[1] == tv[2]) { Util.gDevAssert(false); return(InvalidID); } // look up edges. if any already have two triangles, this would // create non-manifold geometry and so we do not allow it int e0 = find_edge(tv[0], tv[1]); int e1 = find_edge(tv[1], tv[2]); int e2 = find_edge(tv[2], tv[0]); if ((e0 != InvalidID && edge_is_boundary(e0) == false) || (e1 != InvalidID && edge_is_boundary(e1) == false) || (e2 != InvalidID && edge_is_boundary(e2) == false)) { return(NonManifoldID); } // now safe to insert triangle int tid = triangles_refcount.allocate(); int i = 3 * tid; triangles.insert(tv[2], i + 2); triangles.insert(tv[1], i + 1); triangles.insert(tv[0], i); if (triangle_groups != null) { triangle_groups.insert(gid, tid); } // increment ref counts and update/create edges vertices_refcount.increment(tv[0]); vertices_refcount.increment(tv[1]); vertices_refcount.increment(tv[2]); add_tri_edge(tid, tv[0], tv[1], 0, e0); add_tri_edge(tid, tv[1], tv[2], 1, e1); add_tri_edge(tid, tv[2], tv[0], 2, e2); updateTimeStamp(); return(tid); }
// [RMS] estimate can be zero void compute(IEnumerable <int> triangles, int tri_count_est) { int est_verts = tri_count_est / 2; SubMesh = new DMesh3(BaseMesh.Components & WantComponents); BaseSubmeshV = new IndexFlagSet(BaseMesh.MaxVertexID, est_verts); BaseToSubV = new IndexMap(BaseMesh.MaxVertexID, est_verts); SubToBaseV = new DVector <int>(); if (ComputeTriMaps) { BaseToSubT = new IndexMap(BaseMesh.MaxTriangleID, tri_count_est); SubToBaseT = new DVector <int>(); } foreach (int tid in triangles) { if (!BaseMesh.IsTriangle(tid)) { throw new Exception("DSubmesh3.compute: triangle " + tid + " does not exist in BaseMesh!"); } Index3i base_t = BaseMesh.GetTriangle(tid); Index3i new_t = Index3i.Zero; int gid = BaseMesh.GetTriangleGroup(tid); for (int j = 0; j < 3; ++j) { int base_v = base_t[j]; int sub_v = -1; if (BaseSubmeshV[base_v] == false) { sub_v = SubMesh.AppendVertex(BaseMesh, base_v); BaseSubmeshV[base_v] = true; BaseToSubV[base_v] = sub_v; SubToBaseV.insert(base_v, sub_v); } else { sub_v = BaseToSubV[base_v]; } new_t[j] = sub_v; } if (OverrideGroupID >= 0) { gid = OverrideGroupID; } int sub_tid = SubMesh.AppendTriangle(new_t, gid); if (ComputeTriMaps) { BaseToSubT[tid] = sub_tid; SubToBaseT.insert(tid, sub_tid); } } }
// Appends a box that contains free triangles in one-ring of vertex vid. // If tri count is < spill threshold, push onto spill list instead. // Returns # of free tris found. int add_one_ring_box(int vid, byte[] used_triangles, int[] temp_tris, ref int iBoxCur, ref int iIndicesCur, DVector <int> spill, int nSpillThresh) { // collect free triangles int num_free = 0; foreach (int tid in mesh.VtxTrianglesItr(vid)) { if (used_triangles[tid] == 0) { temp_tris[num_free++] = tid; } } // none free, get out if (num_free == 0) { return(0); } // if we only had a couple free triangles, wait and see if // they get picked up by another vert if (num_free < nSpillThresh) { spill.Add(vid); return(num_free); } // append new box AxisAlignedBox3f box = AxisAlignedBox3f.Empty; int iBox = iBoxCur++; box_to_index.insert(iIndicesCur, iBox); index_list.insert(num_free, iIndicesCur++); for (int i = 0; i < num_free; ++i) { index_list.insert(temp_tris[i], iIndicesCur++); used_triangles[temp_tris[i]]++; // incrementing for sanity check below, just need to set to 1 box.Contain(mesh.GetTriBounds(temp_tris[i])); } box_centers.insert(box.Center, iBox); box_extents.insert(box.Extents, iBox); return(num_free); }
protected int append_vertex_internal() { int vid = vertices_refcount.allocate(); vertex_edges.insert(new List <int>(), vid); updateTimeStamp(true); return(vid); }
protected int add_edge(int a, int b, int gid) { if (b < a) { int t = b; b = a; a = t; } int eid = edges_refcount.allocate(); int i = 3 * eid; edges.insert(a, i); edges.insert(b, i + 1); edges.insert(gid, i + 2); vertex_edges[a].Add(eid); vertex_edges[b].Add(eid); return(eid); }
public int AppendVertex(Vector3d v, Vector3f c) { int vid = append_vertex_internal(); int i = 3 * vid; vertices.insert(v[2], i + 2); vertices.insert(v[1], i + 1); vertices.insert(v[0], i); if (colors != null) { colors.insert(c.z, i + 2); colors.insert(c.y, i + 1); colors.insert(c.x, i); } return(vid); }
public int AppendVertex(Vector2d v, Vector3f c) { int vid = vertices_refcount.allocate(); int i = 2 * vid; vertices.insert(v[1], i + 1); vertices.insert(v[0], i); if (colors != null) { i = 3 * vid; colors.insert(c.z, i + 2); colors.insert(c.y, i + 1); colors.insert(c.x, i); } vertex_edges.insert(new List <int>(), vid); updateTimeStamp(true); return(vid); }
void build_top_down(bool bSorted) { int i = 0; int[] triangles = new int[mesh.TriangleCount]; Vector3d[] centers = new Vector3d[mesh.TriangleCount]; foreach (int ti in mesh.TriangleIndices()) { triangles[i] = ti; centers[i++] = mesh.GetTriCentroid(ti); } boxes_set tris = new boxes_set(); boxes_set nodes = new boxes_set(); AxisAlignedBox3f rootBox; int rootnode = (bSorted) ? split_tri_set_sorted(triangles, centers, 0, mesh.TriangleCount, 0, TopDownLeafMaxTriCount, tris, nodes, out rootBox) : split_tri_set_midpoint(triangles, centers, 0, mesh.TriangleCount, 0, TopDownLeafMaxTriCount, tris, nodes, out rootBox); box_to_index = tris.box_to_index; box_centers = tris.box_centers; box_extents = tris.box_extents; index_list = tris.index_list; triangles_end = tris.iIndicesCur; int iIndexShift = triangles_end; int iBoxShift = tris.iBoxCur; // ok now append internal node boxes & index ptrs for (i = 0; i < nodes.iBoxCur; ++i) { box_centers.insert(nodes.box_centers[i], iBoxShift + i); box_extents.insert(nodes.box_extents[i], iBoxShift + i); // internal node indices are shifted box_to_index.insert(iIndexShift + nodes.box_to_index[i], iBoxShift + i); } // now append index list for (i = 0; i < nodes.iIndicesCur; ++i) { int child_box = nodes.index_list[i]; if (child_box < 0) // this is a triangles box { child_box = (-child_box) - 1; } else { child_box += iBoxShift; } child_box = child_box + 1; index_list.insert(child_box, iIndexShift + i); } root_index = rootnode + iBoxShift; }
/// <summary> /// Add node to list w/ given priority /// Behavior is undefined if you call w/ same node twice /// </summary> public void Enqueue(T node, float priority) { if (EnableDebugChecks && Contains(node) == true) { throw new Exception("DynamicPriorityQueue.Enqueue: tried to add node that is already in queue!"); } node.priority = priority; num_nodes++; nodes.insert(node, num_nodes); node.index = num_nodes; move_up(nodes[num_nodes]); }
public int AppendVertex(NewVertexInfo info) { int vid = vertices_refcount.allocate(); int i = 3 * vid; vertices.insert(info.v[2], i + 2); vertices.insert(info.v[1], i + 1); vertices.insert(info.v[0], i); if (normals != null) { Vector3f n = (info.bHaveN) ? info.n : Vector3f.AxisY; normals.insert(n[2], i + 2); normals.insert(n[1], i + 1); normals.insert(n[0], i); } if (colors != null) { Vector3f c = (info.bHaveC) ? info.c : Vector3f.One; colors.insert(c[2], i + 2); colors.insert(c[1], i + 1); colors.insert(c[0], i); } if (uv != null) { Vector2f u = (info.bHaveUV) ? info.uv : Vector2f.Zero; int j = 2 * vid; uv.insert(u[1], j + 1); uv.insert(u[0], j); } vertex_edges.insert(new List <int>(), vid); updateTimeStamp(); return(vid); }
/// <summary> /// create a new list at list_index /// </summary> public void AllocateAt(int list_index) { if (list_index >= list_heads.size) { list_heads.insert(Null, list_index); } else { if (list_heads[list_index] != Null) { throw new Exception("SmallListSet: list at " + list_index + " is not empty!"); } } }
// grab a block from the free list, or allocate a new one protected int allocate_block() { int nfree = free_blocks.size; if (nfree > 0) { int ptr = free_blocks[nfree - 1]; free_blocks.pop_back(); return(ptr); } int nsize = block_store.size; block_store.insert(Null, nsize + BLOCK_LIST_OFFSET); block_store[nsize] = 0; allocated_count++; return(nsize); }
/// <summary> /// Add id to list w/ given priority /// Behavior is undefined if you call w/ same id twice /// </summary> public void Enqueue(int id, float priority) { if (EnableDebugChecks && Contains(id) == true) { throw new Exception("IndexPriorityQueue.Enqueue: tried to add node that is already in queue!"); } QueueNode node = new QueueNode(); node.id = id; node.priority = priority; num_nodes++; node.index = num_nodes; id_to_index[id] = node.index; nodes.insert(node, num_nodes); move_up(nodes[num_nodes].index); }
/// <summary> /// create a new list at list_index /// </summary> public void AllocateAt(int list_index) { if (list_index >= list_heads.size) { int j = list_heads.size; list_heads.insert(Null, list_index); // need to set intermediate values to null! while (j < list_index) { list_heads[j] = Null; j++; } } else { if (list_heads[list_index] != Null) { throw new Exception("SmallListSet: list at " + list_index + " is not empty!"); } } }
void compute(IEnumerable <int> triangles, int tri_count) { int est_verts = tri_count / 2; SubMesh = new DMesh3(BaseMesh.Components & WantComponents); BaseSubmeshV = new IndexFlagSet(BaseMesh.MaxVertexID, est_verts); BaseToSubV = new IndexMap(BaseMesh.MaxVertexID, est_verts); SubToBaseV = new DVector <int>(); foreach (int ti in triangles) { Index3i base_t = BaseMesh.GetTriangle(ti); Index3i new_t = Index3i.Zero; int gid = BaseMesh.GetTriangleGroup(ti); for (int j = 0; j < 3; ++j) { int base_v = base_t[j]; int sub_v = -1; if (BaseSubmeshV[base_v] == false) { sub_v = SubMesh.AppendVertex(BaseMesh, base_v); BaseSubmeshV[base_v] = true; BaseToSubV[base_v] = sub_v; SubToBaseV.insert(base_v, sub_v); } else { sub_v = BaseToSubV[base_v]; } new_t[j] = sub_v; } SubMesh.AppendTriangle(new_t, gid); } }
void build_top_down(bool bSorted) { // build list of valid triangles & centers. We skip any // triangles that have infinite/garbage vertices... int i = 0; int[] triangles = new int[mesh.TriangleCount]; Vector3d[] centers = new Vector3d[mesh.TriangleCount]; foreach (int ti in mesh.TriangleIndices()) { Vector3d centroid = mesh.GetTriCentroid(ti); double d2 = centroid.LengthSquared; bool bInvalid = double.IsNaN(d2) || double.IsInfinity(d2); Debug.Assert(bInvalid == false); if (bInvalid == false) { triangles[i] = ti; centers[i] = mesh.GetTriCentroid(ti); i++; } // otherwise skip this tri } boxes_set tris = new boxes_set(); boxes_set nodes = new boxes_set(); AxisAlignedBox3f rootBox; int rootnode = (bSorted) ? split_tri_set_sorted(triangles, centers, 0, mesh.TriangleCount, 0, TopDownLeafMaxTriCount, tris, nodes, out rootBox) : split_tri_set_midpoint(triangles, centers, 0, mesh.TriangleCount, 0, TopDownLeafMaxTriCount, tris, nodes, out rootBox); box_to_index = tris.box_to_index; box_centers = tris.box_centers; box_extents = tris.box_extents; index_list = tris.index_list; triangles_end = tris.iIndicesCur; int iIndexShift = triangles_end; int iBoxShift = tris.iBoxCur; // ok now append internal node boxes & index ptrs for (i = 0; i < nodes.iBoxCur; ++i) { box_centers.insert(nodes.box_centers[i], iBoxShift + i); box_extents.insert(nodes.box_extents[i], iBoxShift + i); // internal node indices are shifted box_to_index.insert(iIndexShift + nodes.box_to_index[i], iBoxShift + i); } // now append index list for (i = 0; i < nodes.iIndicesCur; ++i) { int child_box = nodes.index_list[i]; if (child_box < 0) // this is a triangles box { child_box = (-child_box) - 1; } else { child_box += iBoxShift; } child_box = child_box + 1; index_list.insert(child_box, iIndexShift + i); } root_index = rootnode + iBoxShift; }
void build_top_down(bool bSorted) { // build list of valid elements. We skip any // elements that have infinite/garbage positoins... int i = 0; int N = points.VertexCount; int[] valid_indices = new int[N]; Vector3d[] valid_points = new Vector3d[N]; foreach (int vi in points.VertexIndices()) { Vector3d pt = points.GetVertex(vi); double d2 = pt.LengthSquared; bool bInvalid = double.IsNaN(d2) || double.IsInfinity(d2); Debug.Assert(bInvalid == false); if (bInvalid == false) { valid_indices[i] = vi; valid_points[i] = pt; i++; } // otherwise skip this element } boxes_set leafs = new boxes_set(); boxes_set nodes = new boxes_set(); AxisAlignedBox3d rootBox; int rootnode = (bSorted) ? split_point_set_sorted(valid_indices, valid_points, 0, N, 0, LeafMaxPointCount, leafs, nodes, out rootBox) : split_point_set_midpoint(valid_indices, valid_points, 0, N, 0, LeafMaxPointCount, leafs, nodes, out rootBox); box_to_index = leafs.box_to_index; box_centers = leafs.box_centers; box_extents = leafs.box_extents; index_list = leafs.index_list; points_end = leafs.iIndicesCur; int iIndexShift = points_end; int iBoxShift = leafs.iBoxCur; // ok now append internal node boxes & index ptrs for (i = 0; i < nodes.iBoxCur; ++i) { box_centers.insert(nodes.box_centers[i], iBoxShift + i); box_extents.insert(nodes.box_extents[i], iBoxShift + i); // internal node indices are shifted box_to_index.insert(iIndexShift + nodes.box_to_index[i], iBoxShift + i); } // now append index list for (i = 0; i < nodes.iIndicesCur; ++i) { int child_box = nodes.index_list[i]; if (child_box < 0) // this is a points box { child_box = (-child_box) - 1; } else { child_box += iBoxShift; } child_box = child_box + 1; index_list.insert(child_box, iIndexShift + i); } root_index = rootnode + iBoxShift; }
public void Set(int i, T a, T b) { vector.insert(a, 2 * i); vector.insert(b, 2 * i + 1); }
public void Set(int i, T a, T b, T c) { vector.insert(a, 3 * i); vector.insert(b, 3 * i + 1); vector.insert(c, 3 * i + 2); }