Ejemplo n.º 1
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.Normalize(n));

            FacePtrCont fc = _LfacePtrCont[faceHandle];

            _LfacePtrCont[faceHandle] = new FacePtrCont()
            {
                _fn = new HandleFaceNormal(_LfaceNormals.Count - 1),
                _h  = fc._h
            };
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adds a face from the importer to the geometry container
        /// </summary>
        /// <param name="gf">GeoFace object from the importer</param>
        private void AddFace(GeoFace gf)
        {
            // Add a face container.
            _LfacePtrCont.Add(
                new FacePtrCont()
            {
                _h = new HandleHalfEdge()
                {
                    _DataIndex = -1
                }
            }
                );
            // Add a face handle.
            _LfaceHndl.Add(
                new HandleFace()
            {
                _DataIndex = _LfacePtrCont.Count - 1
            }
                );

            // Insert all the vertices for the face.
            List <HandleVertex> LHandleVertsForFace = new List <HandleVertex>();

            foreach (float3 vVal in gf._LFVertices)
            {
                LHandleVertsForFace.Add(
                    AddVertex(vVal)
                    );
            }
            // Insert all the uv coordinates for the face.
            List <HandleVertexUV> LHandleUVsForFace = new List <HandleVertexUV>();

            foreach (float2 uvVal in gf._UV)
            {
                _LuvCoordinates.Add(uvVal);
                LHandleUVsForFace.Add(new HandleVertexUV()
                {
                    _DataIndex = _LuvCoordinates.Count - 1
                });
            }

            // Build up the half-edge connections for the face
            List <HandleHalfEdge> LHandleHEForFace = new List <HandleHalfEdge>();

            for (int i = 0; i < LHandleVertsForFace.Count; i++)
            {
                HandleVertex fromVert = LHandleVertsForFace[i];
                HandleVertex toVert   = i + 1 < LHandleVertsForFace.Count ? LHandleVertsForFace[i + 1] : LHandleVertsForFace[0];

                LHandleHEForFace.Add(
                    CreateConnection(fromVert, toVert)
                    );
            }

            // Loop over all the half-edges for the face and concat them and set the correct uv coordinates.
            for (int i = 0; i < LHandleHEForFace.Count; i++)
            {
                HandleHalfEdge currentHedge = LHandleHEForFace[i];
                HEdgePtrCont   hedge        = _LhedgePtrCont[currentHedge];
                HandleHalfEdge nextHedge    = i + 1 < LHandleHEForFace.Count ? LHandleHEForFace[i + 1] : LHandleHEForFace[0];
                hedge._nhe = nextHedge;
                if (LHandleUVsForFace.Count > 0)
                {
                    HandleVertexUV currentUV = i + 1 < LHandleUVsForFace.Count ? LHandleUVsForFace[i + 1] : LHandleUVsForFace[0];
                    hedge._vuv = currentUV;
                }
                //_LhedgePtrCont.RemoveAt(currentHedge);
                //_LhedgePtrCont.Insert(currentHedge, hedge);
                _LhedgePtrCont[currentHedge] = new HEdgePtrCont()
                {
                    _f   = hedge._f,
                    _he  = hedge._he,
                    _nhe = hedge._nhe,
                    _v   = hedge._v,
                    _vn  = hedge._vn,
                    _vuv = hedge._vuv
                };
            }

            // Set the half-edge the face points to.
            FacePtrCont face = _LfacePtrCont[_LfacePtrCont.Count - 1];

            face._h = new HandleHalfEdge(LHandleHEForFace.First());
            _LfacePtrCont.RemoveAt(_LfacePtrCont.Count - 1);
            _LfacePtrCont.Add(face);
        }
Ejemplo n.º 3
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);

                var temp = EnFaceAdjacentHalfEdges(currentFace);


                HandleHalfEdge hlH    = temp.ElementAt(temp.Count() - 1);
                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();
        }