Пример #1
0
        /// <summary>
        /// This method converts a quad based 'Geometry' object to a triangle based one.
        /// </summary>
        private void TriangulateGeometry()
        {
            List<HandleFace> LtmpFaces = new List<HandleFace>();

            foreach (HandleFace currentFace in _LfaceHndl)
            {
                // Pruefe zuerst ob man das face triangulaten sollte oder nicht.
                if (EnFaceAdjacentHalfEdges(currentFace).Count() == 3)
                    continue;

                // Hole aktuelles face und merke den index.
                FacePtrCont currentFaceCont = _LfacePtrCont[currentFace];
                // Merke erste hedge h0.
                HandleHalfEdge h0H = currentFaceCont._h;
                HEdgePtrCont h0Cont = _LhedgePtrCont[h0H];
                // Merke ersten vert v0.
                HandleVertex v0H = _LhedgePtrCont[h0Cont._he]._v;
                // Merke die letzte hedge im face hl.
                //HandleHalfEdge hlH = RetLastHalfEdgeInFaceCw(currentFace);
                HandleHalfEdge hlH = EnFaceAdjacentHalfEdges(currentFace).Last();
                HEdgePtrCont hlCont = _LhedgePtrCont[hlH];
                // Lege zwei neue hedges an und fülle sie korrekt.
                int hedgeCount = _LhedgePtrCont.Count;
                HandleHalfEdge hedge0H = new HandleHalfEdge() { _DataIndex = hedgeCount };
                HandleHalfEdge hedge1H = new HandleHalfEdge() { _DataIndex = hedgeCount + 1 };
                HandleEdge edgeHNew = new HandleEdge() { _DataIndex = _LedgeHndl.Count };
                EdgePtrCont edgeContNew = new EdgePtrCont() { _he1 = hedge0H, _he2 = hedge1H };

                HEdgePtrCont newhedge0 = new HEdgePtrCont()
                {
                    _nhe = h0H,
                    _v = v0H,
                    _he = hedge1H,
                    _f = currentFace,
                    _vn = hlCont._vn,
                    _vuv = hlCont._vuv
                };
                // Hole h1 und h2 zum Merken.
                HandleHalfEdge h1H = h0Cont._nhe;
                HEdgePtrCont h1Cont = _LhedgePtrCont[h1H];
                HandleHalfEdge h2H = h1Cont._nhe;
                HEdgePtrCont h2Cont = _LhedgePtrCont[h2H];

                HEdgePtrCont newhedge1 = new HEdgePtrCont()
                {
                    _nhe = h1Cont._nhe,
                    _v = h1Cont._v,
                    _he = hedge0H,
                    _f = new HandleFace(-1),
                    _vn = h1Cont._vn,
                    _vuv = h1Cont._vuv,
                };
                // Update die jeweiligen next pointer der angrenzenden hedges.
                h1Cont._nhe = hedge0H;
                hlCont._nhe = hedge1H;
                // Lege ein neues face an für das triangle 2.
                HandleFace f1H = new HandleFace() { _DataIndex = (_LfaceHndl.Count - 1) + LtmpFaces.Count + 1 };
                FacePtrCont f1Cont = new FacePtrCont() { _fn = currentFaceCont._fn, _h = hlH };
                // Update das neue triangle bezüglich des neuen faces. Dazu erstmal h2 holen noch.
                newhedge1._f = f1H;
                h2Cont._f = f1H;
                hlCont._f = f1H;
                // Sichere die Änderungen in den listen.
                _LedgeHndl.Add(edgeHNew);
                _LedgePtrCont.Add(edgeContNew);
                _LhedgePtrCont.Add(newhedge0);
                _LhedgePtrCont.Add(newhedge1);

                // Speichere das face handle erstmal in tmp faces wegen der iteration.
                LtmpFaces.Add(f1H);
                _LfacePtrCont.Add(f1Cont);

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

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

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

            foreach (HandleFace handleFace in LtmpFaces)
            {
                _LfaceHndl.Add(handleFace);
            }
            LtmpFaces.Clear();
        }
Пример #2
0
 /// <summary>
 /// Iterator.
 /// Circulate around all the vertices of a given face handle.
 /// </summary>
 /// <param name="faceHandle">A handle to a face used as the 'center' face.</param>
 /// <returns>An Enumerable of vertex handles to be used in loops, etc.</returns>
 public IEnumerable<HandleVertex> EnFaceAdjacentVertices(HandleFace faceHandle)
 {
     return EnFaceAdjacentHalfEdges(faceHandle).Select(handleHalfEdge => _LhedgePtrCont[handleHalfEdge]._v).AsEnumerable();
 }
Пример #3
0
 /// <summary>
 /// Iterator.
 /// Circulate around all the faces surrounding a specific face.
 /// </summary>
 /// <param name="faceHandle">A handle to a face used as the 'center' face.</param>
 /// <returns>An Enumerable of face handles to be used in loops, etc.</returns>
 public IEnumerable<HandleFace> EnFaceAdjacentFaces(HandleFace faceHandle)
 {
     return EnFaceAdjacentHalfEdges(faceHandle).Select(handleHalfEdge => _LhedgePtrCont[_LhedgePtrCont[handleHalfEdge]._he]._f).AsEnumerable();
 }
Пример #4
0
        /// <summary>
        /// Iterator.
        /// This is a method that retrieves all halfedge handles which belong to a specific face handle.
        /// </summary>
        /// <param name="faceHandle">A handle to the face to get the half-edges from.</param>
        /// <returns>An Enumerable of haldedge pointer containers.</returns>
        public IEnumerable<HandleHalfEdge> EnFaceAdjacentHalfEdges(HandleFace faceHandle)
        {
            int startHedgeIndex = _LfacePtrCont[faceHandle]._h;
            int currentIndex = startHedgeIndex;
            List<HandleHalfEdge> LHedgeHandles = new List<HandleHalfEdge>();
            do
            {
                LHedgeHandles.Add(new HandleHalfEdge(currentIndex));
                if (_LhedgePtrCont[_LhedgePtrCont[currentIndex]._nhe]._f != faceHandle)
                    break;

                currentIndex = _LhedgePtrCont[currentIndex]._nhe;
            } while (currentIndex != startHedgeIndex);
            return LHedgeHandles.AsEnumerable();
        }
Пример #5
0
        /// <summary>
        /// This method adds a face normal vector to a list.
        /// The vector is calculated for the face which handle the method expects.
        /// </summary>
        /// <param name="faceHandle">Handle to a face to calculate the normal for.</param>
        public void CalcFaceNormal(HandleFace faceHandle)
        {
            List<HandleVertex> tmpList = EnFaceAdjacentVertices(faceHandle).ToList();
            if (tmpList.Count < 3)
                return;

            var v0 = _LvertexVal[tmpList[0]];
            var v1 = _LvertexVal[tmpList[1]];
            var v2 = _LvertexVal[tmpList[2]];

            float3 c1 = float3.Subtract(v0, v1);
            float3 c2 = float3.Subtract(v0, v2);
            float3 n = float3.Cross(c1, c2);

            _LfaceNormals.Add(float3.NormalizeFast(n));

            FacePtrCont fc = _LfacePtrCont[faceHandle];
            _LfacePtrCont[faceHandle] = new FacePtrCont()
            {
                _fn = new HandleFaceNormal(_LfaceNormals.Count - 1),
                _h = fc._h
            };
        }