예제 #1
0
 public unsafe void GetVertexNormalBuffer(float *pBuffer)
 {
     if (this.HasVertexNormals)
     {
         DVector <float> .FastGetBuffer(this.Normals, pBuffer);
     }
 }
예제 #2
0
        public void copy(DVector <T> copyIn)
        {
            if (this.Blocks != null && copyIn.Blocks.Count == this.Blocks.Count)
            {
                int N = copyIn.Blocks.Count;
                for (int k = 0; k < N; ++k)
                {
                    Array.Copy(copyIn.Blocks[k], this.Blocks[k], copyIn.Blocks[k].Length);
                }

                iCurBlock     = copyIn.iCurBlock;
                iCurBlockUsed = copyIn.iCurBlockUsed;
            }
            else
            {
                resize(copyIn.size);
                int N = copyIn.Blocks.Count;
                for (int k = 0; k < N; ++k)
                {
                    Array.Copy(copyIn.Blocks[k], this.Blocks[k], copyIn.Blocks[k].Length);
                }

                iCurBlock     = copyIn.iCurBlock;
                iCurBlockUsed = copyIn.iCurBlockUsed;
            }
        }
예제 #3
0
        /// <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);
                }
            }
        }
예제 #4
0
 public unsafe void GetVertexColorBuffer(float *pBuffer)
 {
     if (this.HasVertexColors)
     {
         DVector <float> .FastGetBuffer(this.Colors, pBuffer);
     }
 }
예제 #5
0
 public unsafe void GetVertexUVBuffer(float *pBuffer)
 {
     if (this.HasVertexUVs)
     {
         DVector <float> .FastGetBuffer(this.UVs, pBuffer);
     }
 }
예제 #6
0
 public MeshNormals(IMesh mesh, NormalsTypes eType = NormalsTypes.Vertex_OneRingFaceAverage_AreaWeighted)
 {
     Mesh       = mesh;
     NormalType = eType;
     Normals    = new DVector <Vector3d>();
     VertexF    = Mesh.GetVertex;
 }
예제 #7
0
 public unsafe void GetFaceGroupsBuffer(int *pBuffer)
 {
     if (this.HasTriangleGroups)
     {
         DVector <int> .FastGetBuffer(this.FaceGroups, pBuffer);
     }
 }
예제 #8
0
        // [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);
                }
            }
        }
예제 #9
0
        /// <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);
                }
            }
        }
예제 #10
0
        public DMesh3(bool bWantNormals = true, bool bWantColors = false, bool bWantUVs = false, bool bWantTriGroups = false)
        {
            vertices = new DVector <double>();
            if (bWantNormals)
            {
                normals = new DVector <float>();
            }
            if (bWantColors)
            {
                colors = new DVector <float>();
            }
            if (bWantUVs)
            {
                uv = new DVector <float>();
            }
            vertex_edges      = new DVector <List <int> >();
            vertices_refcount = new RefCountVector();

            triangles          = new DVector <int>();
            triangle_edges     = new DVector <int>();
            triangles_refcount = new RefCountVector();
            if (bWantTriGroups)
            {
                triangle_groups = new DVector <int>();
            }

            edges          = new DVector <int>();
            edges_refcount = new RefCountVector();
        }
예제 #11
0
        public void Copy(DMesh3 copy, bool bNormals = true, bool bColors = true, bool bUVs = true)
        {
            vertices = new DVector <double>(copy.vertices);

            normals = (bNormals && copy.normals != null) ? new DVector <float>(copy.normals) : null;
            colors  = (bColors && copy.colors != null) ? new DVector <float>(copy.colors) : null;
            uv      = (bUVs && copy.uv != null) ? new DVector <float>(copy.uv) : null;

            vertices_refcount = new RefCountVector(copy.vertices_refcount);
            vertex_edges      = new DVector <List <int> >(copy.vertex_edges);
            int N = vertex_edges.Length;

            for (int i = 0; i < N; ++i)
            {
                if (vertices_refcount.isValid(i))
                {
                    vertex_edges[i] = new List <int>(copy.vertex_edges[i]);
                }
                else
                {
                    vertex_edges[i] = null;
                }
            }

            triangles          = new DVector <int>(copy.triangles);
            triangle_edges     = new DVector <int>(copy.triangle_edges);
            triangles_refcount = new RefCountVector(copy.triangles_refcount);
            if (copy.triangle_groups != null)
            {
                triangle_groups = new DVector <int>(copy.triangle_groups);
            }

            edges          = new DVector <int>(copy.edges);
            edges_refcount = new RefCountVector(copy.edges_refcount);
        }
예제 #12
0
        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);
                }
            }
        }
예제 #13
0
        public void Initialize(VectorArray3d v, VectorArray3i t,
                               VectorArray3f n = null, VectorArray3f c = null, VectorArray2f uv = null, int[] g = null)
        {
            Vertices   = new DVector <double>(v);
            Triangles  = new DVector <int>(t);
            Normals    = Colors = UVs = null;
            FaceGroups = null;
            if (n != null)
            {
                Normals = new DVector <float>(n);
            }

            if (c != null)
            {
                Colors = new DVector <float>(c);
            }

            if (uv != null)
            {
                UVs = new DVector <float>(uv);
            }

            if (g != null)
            {
                FaceGroups = new DVector <int>(g);
            }
        }
예제 #14
0
        /// <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);
                }
            }
        }
예제 #15
0
        public IOReadResult Read(BinaryReader reader, ReadOptions options, IMeshBuilder builder)
        {
            if (options.CustomFlags != null)
            {
                ParseArguments(options.CustomFlags);
            }

            /*byte[] header = */
            reader.ReadBytes(80);
            int totalTris = reader.ReadInt32();

            Objects = new List <STLSolid>();
            Objects.Add(new STLSolid());

            int    tri_size = 50;               // bytes
            IntPtr bufptr   = Marshal.AllocHGlobal(tri_size);
            var    tmp      = new stl_triangle();
            Type   tri_type = tmp.GetType();

            var tri_attribs = new DVector <short>();

            try
            {
                for (int i = 0; i < totalTris; ++i)
                {
                    byte[] tri_bytes = reader.ReadBytes(50);
                    if (tri_bytes.Length < 50)
                    {
                        break;
                    }

                    Marshal.Copy(tri_bytes, 0, bufptr, tri_size);
                    var tri = (stl_triangle)Marshal.PtrToStructure(bufptr, tri_type);

                    append_vertex(tri.ax, tri.ay, tri.az);
                    append_vertex(tri.bx, tri.by, tri.bz);
                    append_vertex(tri.cx, tri.cy, tri.cz);
                    tri_attribs.Add(tri.attrib);
                }
            }
            catch (Exception e)
            {
                return(new IOReadResult(IOCode.GenericReaderError, "exception: " + e.Message));
            }

            Marshal.FreeHGlobal(bufptr);

            if (Objects.Count == 1)
            {
                Objects[0].TriAttribs = tri_attribs;
            }

            foreach (STLSolid solid in Objects)
            {
                BuildMesh(solid, builder);
            }

            return(new IOReadResult(IOCode.Ok, ""));
        }
예제 #16
0
        public PackedSparseMatrix Square()
        {
            if (Rows.Length != Columns)
            {
                throw new Exception("PackedSparseMatrix.Square: matrix is not square!");
            }

            int N = Columns;

            var entries      = new DVector <matrix_entry>();
            var entries_lock = new SpinLock();

            gParallel.BlockStartEnd(0, N - 1, (r_start, r_end) =>
            {
                for (int r1i = r_start; r1i <= r_end; r1i++)
                {
                    // determine which entries of squared matrix might be nonzeros
                    var nbrs = new HashSet <int>();
                    nbrs.Add(r1i);
                    PackedSparseMatrix.nonzero[] row = Rows[r1i];
                    for (int k = 0; k < row.Length; ++k)
                    {
                        if (row[k].j > r1i)
                        {
                            nbrs.Add(row[k].j);
                        }

                        PackedSparseMatrix.nonzero[] row2 = Rows[row[k].j];
                        for (int j = 0; j < row2.Length; ++j)
                        {
                            if (row2[j].j > r1i)                                 // only compute lower-triangular entries
                            {
                                nbrs.Add(row2[j].j);
                            }
                        }
                    }

                    // compute them!
                    foreach (int c2i in nbrs)
                    {
                        double v = DotRowColumn(r1i, c2i, this);
                        if (Math.Abs(v) > MathUtil.ZeroTolerance)
                        {
                            bool taken = false;
                            entries_lock.Enter(ref taken);
                            entries.Add(new matrix_entry()
                            {
                                r = r1i, c = c2i, value = v
                            });
                            entries_lock.Exit();
                        }
                    }
                }
            });

            var R = new PackedSparseMatrix(entries, N, N, true);

            return(R);
        }
예제 #17
0
 public DVectorArray3(int nCount = 0)
 {
     vector = new DVector <T>();
     if (nCount > 0)
     {
         vector.resize(nCount * 3);
     }
 }
예제 #18
0
        int free_head_ptr;              // index of first free element in linked_store


        public SmallListSet()
        {
            list_heads    = new DVector <int>();
            linked_store  = new DVector <int>();
            free_head_ptr = Null;
            block_store   = new DVector <int>();
            free_blocks   = new DVector <int>();
        }
예제 #19
0
 public SmallListSet(SmallListSet copy)
 {
     linked_store  = new DVector <int>(copy.linked_store);
     free_head_ptr = copy.free_head_ptr;
     list_heads    = new DVector <int>(copy.list_heads);
     block_store   = new DVector <int>(copy.block_store);
     free_blocks   = new DVector <int>(copy.free_blocks);
 }
 /// <summary>
 /// reset the queue to empty state.
 /// if bFreeMemory is false, we don't discard internal data structures, so there will be less allocation next time
 /// (this does not make a huge difference...)
 /// </summary>
 public void Clear(bool bFreeMemory = true)
 {
     if (bFreeMemory)
     {
         nodes = new DVector <T>();
     }
     num_nodes = 0;
 }
예제 #21
0
 public void Initialize(bool bWantNormals = true, bool bWantColors = true, bool bWantUVs = true, bool bWantFaceGroups = true)
 {
     Vertices   = new DVector <double>();
     Normals    = (bWantNormals) ? new DVector <float>() : null;
     Colors     = (bWantColors) ? new DVector <float>() : null;
     UVs        = (bWantUVs) ? new DVector <float>() : null;
     Triangles  = new DVector <int>();
     FaceGroups = (bWantFaceGroups) ? new DVector <int>() : null;
 }
예제 #22
0
 /// <summary>
 /// reset the queue to empty state.
 /// if bFreeMemory is false, we don't discard internal data structures, so there will be less allocation next time
 /// (this does not make a huge difference...)
 /// </summary>
 public void Clear(bool bFreeMemory = true)
 {
     if (bFreeMemory)
     {
         nodes = new DVector <QueueNode>();
     }
     Array.Clear(id_to_index, 0, id_to_index.Length);
     num_nodes = 0;
 }
예제 #23
0
        public DGraph()
        {
            vertex_edges      = new DVector <List <int> >();
            vertices_refcount = new RefCountVector();

            edges          = new DVector <int>();
            edges_refcount = new RefCountVector();
            max_group_id   = 0;
        }
예제 #24
0
        public static void Restore(DVector <short> vec, BinaryReader reader)
        {
            int N = reader.ReadInt32();

            byte[]  bytes  = reader.ReadBytes(N * sizeof(short));
            short[] buffer = new short[N];
            Buffer.BlockCopy(bytes, 0, buffer, 0, bytes.Length);
            vec.Initialize(buffer);
        }
예제 #25
0
 public RefCountVector(short[] raw_ref_counts, bool build_free_list = false)
 {
     ref_counts   = new DVector <short>(raw_ref_counts);
     free_indices = new DVector <int>();
     used_count   = 0;
     if (build_free_list)
     {
         rebuild_free_list();
     }
 }
예제 #26
0
        int[] id_to_index;              // mapping from external ids to internal node indices
                                        // [TODO] could make this sparse using SparseList...


        /// <summary>
        /// maxIndex parameter is required because internally a fixed-size array is used to track mapping
        /// from IDs to internal node indices. If this seems problematic because you won't be inserting the
        /// full index space, consider a DynamicPriorityQueue instead.
        /// </summary>
        public IndexPriorityQueue(int maxID)
        {
            nodes       = new DVector <QueueNode>();
            id_to_index = new int[maxID];
            for (int i = 0; i < maxID; ++i)
            {
                id_to_index[i] = -1;
            }
            num_nodes = 0;
        }
예제 #27
0
        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;
        }
예제 #28
0
 public DVector(DVector <T> copy)
 {
     nBlockSize    = copy.nBlockSize;
     iCurBlock     = copy.iCurBlock;
     iCurBlockUsed = copy.iCurBlockUsed;
     Blocks        = new List <T[]>();
     for (int i = 0; i < copy.Blocks.Count; ++i)
     {
         Blocks.Add(new T[nBlockSize]);
         Array.Copy(copy.Blocks[i], Blocks[i], copy.Blocks[i].Length);
     }
 }
예제 #29
0
        public static void Store(DVector <short> vec, BinaryWriter writer)
        {
            byte[] buffer = new byte[vec.BlockCount * sizeof(short)];
            int    N      = vec.Length;

            writer.Write(N);
            foreach (DVector <short> .DBlock block in vec.BlockIterator())
            {
                Buffer.BlockCopy(block.data, 0, buffer, 0, block.usedCount * sizeof(short));
                writer.Write(buffer, 0, block.usedCount * sizeof(short));
            }
        }
예제 #30
0
        public static unsafe void FastGetBuffer(DVector <int> v, int *pBuffer)
        {
            IntPtr pCur = new IntPtr(pBuffer);
            int    N    = v.Blocks.Count;

            for (int k = 0; k < N - 1; k++)
            {
                System.Runtime.InteropServices.Marshal.Copy(v.Blocks[k], 0, pCur, v.nBlockSize);
                pCur = new IntPtr(
                    pCur.ToInt64() + v.nBlockSize * sizeof(int));
            }
            System.Runtime.InteropServices.Marshal.Copy(v.Blocks[N - 1], 0, pCur, v.iCurBlockUsed);
        }