コード例 #1
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
        /// <summary>
        /// For testing only now.
        /// </summary>
        /// <param name="existingEdge"></param>
        /// <param name="fromVert"></param>
        /// <param name="toVert"></param>
        /// <returns></returns>
        private HandleHalfEdge ReuseExistingConnection(HandleEdge existingEdge, HandleVertex fromVert, HandleVertex toVert)
        {
            // Check half-edge 1 and 2 if one points to the actual face. This is the one we use for our face then. If no one we build a new connection.
            HEdgePtrCont hedge1 = _LhedgePtrCont[_LedgePtrCont[existingEdge]._he1];
            HEdgePtrCont hedge2 = _LhedgePtrCont[_LedgePtrCont[existingEdge]._he2];

            HandleHalfEdge hedgeToUse = new HandleHalfEdge(-1);

            if (hedge2._f == -1)
            {
                // It is hedge 2 that is free. We should use it.
                hedgeToUse = _LedgePtrCont[existingEdge]._he2;

            }
            else if (hedge1._f == -1)
            {
                // It is hedge 1 that is free. We should use it. Should never happen. TODO: Exception throw?
                hedgeToUse = _LedgePtrCont[existingEdge]._he1;
            }
            else
            {
                // Neither one of the faces of the existing half-edges was free so we build a new edge.
                return CreateAllNewConnection(fromVert, toVert);
            }
            // Updating the face pointer.
            HEdgePtrCont hedge = _LhedgePtrCont[hedgeToUse];
            hedge._f = new HandleFace(_LfacePtrCont.Count - 1);

            _LhedgePtrCont[hedgeToUse] = new HEdgePtrCont()
            {
                _f = hedge._f,
                _he = hedge._he,
                _nhe = hedge._nhe,
                _v = hedge._v,
                _vn = hedge._vn,
                _vuv = hedge._vuv
            };

            return hedgeToUse;
        }
コード例 #2
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
        /// <summary>
        /// For testing now only.
        /// </summary>
        /// <returns></returns>
        private HandleHalfEdge CreateAllNewConnection(HandleVertex fromVert, HandleVertex toVert)
        {
            HEdgePtrCont hedge1 = new HEdgePtrCont()
            {
                _f = new HandleFace(_LfacePtrCont.Count - 1),
                _he = new HandleHalfEdge(_LedgePtrCont.Count == 0 ? 1 : _LhedgePtrCont.Count + 1),
                _v = new HandleVertex(toVert),
                _vn = new HandleVertexNormal(-1),
                _vuv = new HandleVertexUV(-1),
                _nhe = new HandleHalfEdge(-1)
            };

            HEdgePtrCont hedge2 = new HEdgePtrCont()
            {
                _f = new HandleFace(-1),
                _he = new HandleHalfEdge(_LedgePtrCont.Count == 0 ? 0 : _LhedgePtrCont.Count),
                _v = new HandleVertex(fromVert),
                _vn = new HandleVertexNormal(-1),
                _vuv = new HandleVertexUV(-1),
                _nhe = new HandleHalfEdge(-1)
            };

            _LhedgePtrCont.Add(hedge1);
            _LhedgePtrCont.Add(hedge2);

            _LedgePtrCont.Add(
                new EdgePtrCont()
                {
                    _he1 = new HandleHalfEdge(_LhedgePtrCont.Count - 2),
                    _he2 = new HandleHalfEdge(_LhedgePtrCont.Count - 1)
                }
                );
            _LedgeHndl.Add(
                new HandleEdge() { _DataIndex = _LedgePtrCont.Count - 1 }
                );

            // Update the vertices.
            VertexPtrCont vertFrom = _LvertexPtrCont[fromVert._DataIndex];
            VertexPtrCont vertTo = _LvertexPtrCont[toVert._DataIndex];

            if (!vertFrom._h.isValid)
            {
                vertFrom._h = _LedgePtrCont[_LedgePtrCont.Count - 1]._he1;
                _LvertexPtrCont[fromVert] = new VertexPtrCont() { _h = vertFrom._h };
            }
            if (!vertTo._h.isValid)
            {
                vertTo._h = _LedgePtrCont[_LedgePtrCont.Count - 1]._he2;
                _LvertexPtrCont[toVert] = new VertexPtrCont() { _h = vertTo._h };
            }

            return _LedgePtrCont.Last()._he1;
        }
コード例 #3
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
 /// <summary>
 /// Only for testing now.
 /// </summary>
 /// <param name="fromVert"></param>
 /// <param name="toVert"></param>
 /// <returns></returns>
 private HandleEdge DoesConnectionExist(HandleVertex fromVert, HandleVertex toVert)
 {
     return new HandleEdge(
         _LedgePtrCont.FindIndex(
             edgePtrCont => _LhedgePtrCont[edgePtrCont._he1]._v == fromVert && _LhedgePtrCont[edgePtrCont._he2]._v == toVert || _LhedgePtrCont[edgePtrCont._he1]._v._DataIndex == toVert && _LhedgePtrCont[edgePtrCont._he2]._v == fromVert)
         );
 }
コード例 #4
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
        /// <summary>
        /// Iterator.
        /// Circulate around a given vertex and enumerate all incoming halfedges.
        /// </summary>
        /// <param name="vertexHandle">A handle to a vertex to use as a 'center' vertex.</param>
        /// <returns>An Enumerable of HalfEdge handles to be used in loops, etc.</returns>
        public IEnumerable<HandleHalfEdge> EnVertexIncomingHalfEdge(HandleVertex vertexHandle)
        {
            List<HandleHalfEdge> LTmpIncomingHedges = new List<HandleHalfEdge>();

            //Get the one outgoing half-edge for the vertex.
            HandleHalfEdge currentHedge = _LvertexPtrCont[vertexHandle]._h;
            //Remember the index of the first half-edge
            int startHedgeIndex = currentHedge;
            do
            {
                if (currentHedge == -1)
                    break;

                HEdgePtrCont currentHedgeContainer = _LhedgePtrCont[currentHedge];
                if (vertexHandle == _LhedgePtrCont[currentHedgeContainer._he]._v)
                {
                    LTmpIncomingHedges.Add(currentHedgeContainer._he);
                }
                currentHedge = _LhedgePtrCont[currentHedgeContainer._he]._nhe;
            } while (currentHedge != startHedgeIndex);

            return LTmpIncomingHedges.AsEnumerable();

            //return _LhedgePtrCont.Where(e => e._v == vertexHandle).AsParallel().Select(e => _LhedgePtrCont[e._he._DataIndex]._he).AsParallel().ToList();
            //return (from e in _LhedgePtrCont where e._v == vertexHandle select _LhedgePtrCont[e._he]._he).AsParallel().ToList();
        }
コード例 #5
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
 /// <summary>
 /// Iterator.
 /// Circulate around a given vertex and enumerate all outgoing halfedges.
 /// </summary>
 /// <param name="vertexHandle">A handle to a vertex to use as a 'center' vertex.</param>
 /// <returns>An Enumerable of HalfEdge handles to be used in loops, etc.</returns>
 public IEnumerable<HandleHalfEdge> EnVertexOutgoingHalfEdge(HandleVertex vertexHandle)
 {
     return EnVertexIncomingHalfEdge(vertexHandle).Select(handleHalfEdge => _LhedgePtrCont[handleHalfEdge]._he).AsEnumerable();
 }
コード例 #6
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
 /// <summary>
 /// Iterator.
 /// Circulate around a given vertex and enumerate all faces adjacent to the center vertex.
 /// </summary>
 /// <param name="hv">A handle to a vertex to use as a 'center' vertex.</param>
 /// <param name="vertexHandle">Handle to the vertex to do this operation on.</param>
 /// <returns>An Enumerable of HalfEdge handles to be used in loops, etc.</returns>
 public IEnumerable<HandleFace> EnVertexAdjacentFaces(HandleVertex vertexHandle)
 {
     return EnVertexIncomingHalfEdge(vertexHandle).Select(handleHalfEdge => _LhedgePtrCont[handleHalfEdge]._f).AsEnumerable();
 }
コード例 #7
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
 /// <summary>
 /// Iterator.
 /// Circulate around a given vertex and enumerate all vertices connected by a direct edge.
 /// </summary>
 /// <param name="vertexHandle">A handle to a vertex to use as a 'center' vertex.</param>
 /// <returns>An Enumerable of VertexHandles to be used in loops, etc.</returns>
 public IEnumerable<HandleVertex> EnStarVertexVertex(HandleVertex vertexHandle)
 {
     return EnVertexIncomingHalfEdge(vertexHandle).Select(handleHalfEdge => _LhedgePtrCont[_LhedgePtrCont[handleHalfEdge]._he]._v).AsEnumerable();
 }
コード例 #8
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
 /// <summary>
 /// Establishes a connection between two vertices.
 /// 1) Creates two half-edges
 /// 2) Fills them with information
 /// 3) Creates an edge pointer container and adds it to the geo container.
 /// 4) returns a handle to an edge
 /// </summary>
 /// <param name="fromVert">HandleVertex from which vertex</param>
 /// <param name="toVert">Handlevertex to which vertex</param>
 /// <returns>Returns a handle to the half-edge that has just been inserted</returns>
 public HandleHalfEdge CreateConnection(HandleVertex fromVert, HandleVertex toVert)
 {
     // Check if the connection does already exist.
     HandleEdge existingEdge = DoesConnectionExist(fromVert, toVert);
     if (existingEdge != -1)
     {
         return ReuseExistingConnection(existingEdge, fromVert, toVert);
     }
     else
     {
         return CreateAllNewConnection(fromVert, toVert);
     }
 }
コード例 #9
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
        /// <summary>
        /// This method calculates vertex normals for a specific vertex in the geometry and inserts them at the corresponding half-edges on the correct faces.
        /// This method uses an angle based algorithm to determine whether to calculate with another faces normal or not.
        /// </summary>
        /// <param name="vertexHandle">A handle for the vertex to calc the normals for.</param>
        public void CalcVertexNormal(HandleVertex vertexHandle)
        {
            List<HandleHalfEdge> EincomingHEdges = EnVertexIncomingHalfEdge(vertexHandle).ToList();

            // Loop over every incoming half-edge.
            foreach (HandleHalfEdge handleHedge in EincomingHEdges)
            {
                int hedgeIndex = handleHedge;
                // Check if the half-edge is pointing to a face.
                int faceIndex = _LhedgePtrCont[hedgeIndex]._f;
                if (faceIndex == -1)
                    return;

                float3 currentFaceNormal = _LfaceNormals[_LfacePtrCont[faceIndex]._fn];
                float3 normalAggregate = new float3();
                // Loop over every incoming half-edge again, so we can compare the angles between the current one and all the others.
                // We do this to decide which normal should be added to the sum and which not.
                foreach (int eincomingHEdge in EincomingHEdges)
                {
                    // Add the current normal if the index is on it and do not compare any angles etc.
                    if (eincomingHEdge == hedgeIndex)
                    {
                        normalAggregate += currentFaceNormal;
                        continue;
                    }
                    // Stop when the current half-edge is not pointing to a face.
                    int faceIndex2 = _LhedgePtrCont[eincomingHEdge]._f;
                    if (faceIndex2 == -1)
                        continue;

                    float3 normalToCompare = _LfaceNormals[_LfacePtrCont[faceIndex2]._fn];

                    float dot = float3.Dot(currentFaceNormal, normalToCompare);
                    if (System.Math.Acos(dot) * _constPiFactor < _SmoothingAngle)
                        normalAggregate += float3.Add(normalAggregate, normalToCompare);
                }

                _LVertexNormals.Add(float3.NormalizeFast(normalAggregate));

                HEdgePtrCont currentHedge = _LhedgePtrCont[hedgeIndex];
                _LhedgePtrCont[hedgeIndex] = new HEdgePtrCont()
                {
                    _f = currentHedge._f,
                    _he = currentHedge._he,
                    _nhe = currentHedge._nhe,
                    _v = currentHedge._v,
                    _vn = new HandleVertexNormal(_LVertexNormals.Count - 1),
                    _vuv = currentHedge._vuv
                };
            }
        }
コード例 #10
0
ファイル: Geometry.cs プロジェクト: dNovel/LinqForGeometry
        /// <summary>
        /// Adds a vertex to the geometry container.
        /// Will return a handle to the newly inserted or still existing vertex.
        /// </summary>
        /// <param name="val">float3 value to insert</param>
        /// <returns>Returns a handle to the just inserted vertex or a handle to an existing one because the given one was already inserterd.</returns>
        public HandleVertex AddVertex(float3 val)
        {
            int index = DoesVertexExist(val);
            HandleVertex hvToAdd = new HandleVertex() { _DataIndex = -1 };

            // When vertex does not exist - insert it
            if (index == -1)
            {
                _LvertexVal.Add(val);

                _LvertexPtrCont.Add(
                    new VertexPtrCont()
                    {
                        _h = new HandleHalfEdge()
                        {
                            _DataIndex = -1
                        }
                    }
                );
                hvToAdd = new HandleVertex() { _DataIndex = _LvertexPtrCont.Count - 1 };
            }
            else
            {
                HandleVertex vHndl = new HandleVertex();
                vHndl._DataIndex = index;
                hvToAdd = vHndl;
            }

            if (!_LverticeHndl.Contains(hvToAdd))
            {
                _LverticeHndl.Add(hvToAdd);
            }
            else
            {
                if (LFGMessages._DEBUGOUTPUT)
                {
                    Debug.WriteLine("$$$ Vertex has been already inserted!");
                }
            }
            return hvToAdd;
        }