internal void CompileDataOfThisObject(Component_Mesh.CompiledData compiledData)          // Component_Mesh mesh, Component_Mesh.CompiledData result )
        {
            VertexElement[] vertexStructureV = VertexStructure;
            UnwrappedUVEnum unwrappedUVV     = UnwrappedUV;

            byte[]             verticesV = Vertices;
            int[]              indicesV  = Indices;
            Component_Material materialV = Material;

            Component_Mesh.StructureClass structure = null;

            OnGetDataOfThisObject(ref vertexStructureV, ref verticesV, ref indicesV, ref materialV, ref structure);
            GetDataOfThisObjectEvent?.Invoke(this, ref vertexStructureV, ref verticesV, ref indicesV, ref materialV, ref structure);

            //add to result
            if (vertexStructureV != null && vertexStructureV.Length != 0 && verticesV != null && verticesV.Length != 0 && (indicesV == null || indicesV.Length != 0))
            {
                vertexStructureV.GetInfo(out var vertexSize, out var holes);
                //if( !holes )
                {
                    int vertexCount = verticesV.Length / vertexSize;

                    var op = new Component_RenderingPipeline.RenderSceneData.MeshDataRenderOperation(this);

                    op.VertexStructure = vertexStructureV;
                    op.VertexStructureContainsColor = op.VertexStructure.Any(e => e.Semantic == VertexElementSemantic.Color0);
                    op.UnwrappedUV = unwrappedUVV;

                    var vertexDeclaration = op.VertexStructure.CreateVertexDeclaration(0);
                    op.VertexBuffers     = new GpuVertexBuffer[] { GpuBufferManager.CreateVertexBuffer(verticesV, vertexDeclaration) };
                    op.VertexStartOffset = 0;
                    op.VertexCount       = vertexCount;

                    if (indicesV != null)
                    {
                        op.IndexBuffer      = GpuBufferManager.CreateIndexBuffer(indicesV);
                        op.IndexStartOffset = 0;
                        op.IndexCount       = indicesV.Length;
                    }

                    //!!!!так?
                    op.Material = materialV;

                    compiledData.MeshData.RenderOperations.Add(op);

                    //!!!!может мержить когда несколько. индексы MeshGeometry в RawVertices
                    if (compiledData.MeshData.Structure == null)
                    {
                        compiledData.MeshData.Structure = structure;
                    }
                }
                //else
                //{
                //	//!!!!!error
                //}
            }
        }
Esempio n. 2
0
 public abstract void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure);
        /////////////////////////////////////////

        protected virtual void OnGetDataOfThisObject(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices,
                                                     ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
        }
Esempio n. 4
0
        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            //!!!!!можно было бы не обновлять если такие же параметры

            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            Vector3F[] positions;
            Vector3F[] normals;
            Vector4F[] tangents;
            Vector2F[] texCoords;
            SimpleMeshGenerator.Face[] faces;

            if (SphereType.Value == SphereTypeEnum.GeoSphere)
            {
                SimpleMeshGenerator.GenerateSphere(Radius, SegmentsHorizontal, SegmentsVertical, InsideOut, out positions, out normals, out tangents, out texCoords, out indices, out faces);
            }
            else
            {
                SimpleMeshGenerator.GenerateIcoSphere(Radius, Subdivisions.Value, InsideOut, out positions, out normals, out tangents, out texCoords, out indices, out faces);
            }

            if (faces != null)
            {
                structure = SimpleMeshGenerator.CreateMeshStructure(faces);
            }

            vertices = new byte[vertexSize * positions.Length];
            unsafe
            {
                fixed(byte *pVertices = vertices)
                {
                    StandardVertex.StaticOneTexCoord *pVertex = (StandardVertex.StaticOneTexCoord *)pVertices;

                    for (int n = 0; n < positions.Length; n++)
                    {
                        pVertex->Position  = positions[n];
                        pVertex->Normal    = normals[n];
                        pVertex->Tangent   = tangents[n];
                        pVertex->Color     = new ColorValue(1, 1, 1, 1);
                        pVertex->TexCoord0 = texCoords[n];

                        pVertex++;
                    }
                }
            }
        }
Esempio n. 5
0
 protected override void OnGetDataOfThisObject(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
 {
     GetProceduralGeneratedData(ref vertexStructure, ref vertices, ref indices, ref material, ref structure);
 }
Esempio n. 6
0
        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            var meshInSpace = Parent?.Parent as Component_MeshInSpace;
            var points      = GetPointPositions();

            if (meshInSpace != null && points.Length >= 3)
            {
                vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
                unsafe
                {
                    if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                    {
                        Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                    }
                }

                SimpleMeshGenerator.GeneratePolygonBasedPolyhedron(points, Clockwise, Height, InsideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out indices, out var faces);
Esempio n. 7
0
        ////InsideOut
        //ReferenceField<bool> _insideOut = false;
        //[DefaultValue( false )]
        //[Serialize]
        //public Reference<bool> InsideOut
        //{
        //	get
        //	{
        //		if( _insideOut.BeginGet() )
        //			InsideOut = _insideOut.Get( this );
        //		return _insideOut.value;
        //	}
        //	set
        //	{
        //		if( _insideOut.BeginSet( ref value ) )
        //		{
        //			try
        //			{
        //				InsideOutChanged?.Invoke( this );
        //				ShouldRecompileMesh();
        //			}
        //			finally { _insideOut.EndSet(); }
        //		}
        //	}
        //}
        //public event Action<Component_MeshGeometry_Plane> InsideOutChanged;

        //!!!!!by tesselation modifier?

        ////SegmentsHorizontal
        //Reference<int> segmentsHorizontal = 32;
        //[Serialize]
        //public virtual Reference<int> SegmentsHorizontal
        //{
        //	get
        //	{
        //		if( !string.IsNullOrEmpty( segmentsHorizontal.GetByReference ) )
        //			SegmentsHorizontal = segmentsHorizontal.GetValue( this );
        //		return segmentsHorizontal;
        //	}
        //	set
        //	{
        //		if( segmentsHorizontal == value ) return;
        //		segmentsHorizontal = value;
        //		SegmentsHorizontalChanged?.Invoke( this );
        //	}
        //}
        //public event Action<Component_MeshData_Parallelepiped> SegmentsHorizontalChanged;


        ////SegmentsVertical
        //Reference<int> segmentsVertical = 32;
        //[Serialize]
        //public virtual Reference<int> SegmentsVertical
        //{
        //	get
        //	{
        //		if( !string.IsNullOrEmpty( segmentsVertical.GetByReference ) )
        //			SegmentsVertical = segmentsVertical.GetValue( this );
        //		return segmentsVertical;
        //	}
        //	set
        //	{
        //		if( segmentsVertical == value ) return;
        //		segmentsVertical = value;
        //		SegmentsVerticalChanged?.Invoke( this );
        //	}
        //}
        //public event Action<Component_MeshData_Parallelepiped> SegmentsVerticalChanged;

        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            var dimensions = Dimensions.Value;

            //if( InsideOut )
            //	dimensions = -dimensions;

            SimpleMeshGenerator.GenerateSegmentedPlane(Axis, dimensions.ToVector2F(), Segments.Value, UVTilesPerUnit.Value.ToVector2F(), UVTilesInTotal.Value.ToVector2F(), out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            SimpleMeshGenerator.GenerateTorus(Axis, Radius, Segments, Circumference, TubeRadius, TubeSegments, TubeCircumference, /*Smooth, */ InsideOut, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
Esempio n. 9
0
        //!!!!!by tesselation modifier?

        ////SegmentsHorizontal
        //Reference<int> segmentsHorizontal = 32;
        //[Serialize]
        //public virtual Reference<int> SegmentsHorizontal
        //{
        //	get
        //	{
        //		if( !string.IsNullOrEmpty( segmentsHorizontal.GetByReference ) )
        //			SegmentsHorizontal = segmentsHorizontal.GetValue( this );
        //		return segmentsHorizontal;
        //	}
        //	set
        //	{
        //		if( segmentsHorizontal == value ) return;
        //		segmentsHorizontal = value;
        //		SegmentsHorizontalChanged?.Invoke( this );
        //	}
        //}
        //public event Action<Component_MeshData_Parallelepiped> SegmentsHorizontalChanged;


        ////SegmentsVertical
        //Reference<int> segmentsVertical = 32;
        //[Serialize]
        //public virtual Reference<int> SegmentsVertical
        //{
        //	get
        //	{
        //		if( !string.IsNullOrEmpty( segmentsVertical.GetByReference ) )
        //			SegmentsVertical = segmentsVertical.GetValue( this );
        //		return segmentsVertical;
        //	}
        //	set
        //	{
        //		if( segmentsVertical == value ) return;
        //		segmentsVertical = value;
        //		SegmentsVerticalChanged?.Invoke( this );
        //	}
        //}
        //public event Action<Component_MeshData_Parallelepiped> SegmentsVerticalChanged;


        //!!!!полусферной
        //!!!!закрытость сферы как Shape volume


        /////////////////////////////////////////

        //[StructLayout( LayoutKind.Sequential )]
        //public struct Vertex
        //{
        //	public Vec3F position;
        //	public Vec3F normal;
        //	public Vec2F texCoord;
        //}

        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            SimpleMeshGenerator.GenerateBox(Dimensions.Value.ToVector3F(), InsideOut, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
        static void ConvertProceduralMeshGeometries(DocumentInstance document, Component_Mesh mesh, UndoMultiAction undoMultiAction, ref bool needUndoForNextActions)
        {
            //needUndoForNextActions = true;

            var meshGeometries = mesh.GetComponents <Component_MeshGeometry>();

            if (meshGeometries.Any(g => g is Component_MeshGeometry_Procedural))
            {
                //!!!!?
                bool hasOrdinary = meshGeometries.Any(g => !(g is Component_MeshGeometry_Procedural));
                if (!hasOrdinary)
                {
                    needUndoForNextActions = false;                     //??? Если были и обычные geometry и procedural? Как правильно needUndoForNextActions? Пока так: undo не нужен только если все procedural
                }
                //!!!!right? !needUndoForNextActions
                if (undoMultiAction != null && !needUndoForNextActions)
                {
                    //add structure update to undo
                    var property = (Metadata.Property)mesh.MetadataGetMemberBySignature("property:" + nameof(Component_Mesh.Structure));
                    undoMultiAction.AddAction(new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item(mesh, property, mesh.Structure?.Clone())));
                }

                for (int i = 0; i < meshGeometries.Length; i++)
                {
                    var meshGeometry = meshGeometries[i];

                    //convert to usual Component_MeshGeometry
                    if (meshGeometry is Component_MeshGeometry_Procedural meshGeometryProcedural)
                    {
                        VertexElement[]               vertexStructure = null;
                        byte[]                        vertices        = null;
                        int[]                         indices         = null;
                        Component_Material            material        = null;
                        Component_Mesh.StructureClass structure       = null;
                        meshGeometryProcedural.GetProceduralGeneratedData(ref vertexStructure, ref vertices, ref indices, ref material, ref structure);

                        var insertIndex = meshGeometryProcedural.Parent.Components.IndexOf(meshGeometryProcedural);

                        var meshGeometryNew = mesh.CreateComponent <Component_MeshGeometry>(insertIndex);
                        meshGeometryNew.Name            = meshGeometry.Name;
                        meshGeometryNew.VertexStructure = vertexStructure;
                        meshGeometryNew.Vertices        = vertices;
                        meshGeometryNew.Indices         = indices;

                        meshGeometryNew.Material = meshGeometryProcedural.Material;

                        //concut structures. If the geometry is procedural it is not in a structure yet.
                        mesh.Structure = Component_Mesh.StructureClass.Concat(mesh.Structure, structure, i);

                        //delete old mesh geometry
                        if (undoMultiAction != null)
                        {
                            undoMultiAction.AddAction(new UndoActionComponentCreateDelete(document, new Component[] { meshGeometry }, create: false));
                        }
                        else
                        {
                            meshGeometry.Dispose();
                        }

                        //add created geometry to undo
                        if (undoMultiAction != null)
                        {
                            undoMultiAction.AddAction(new UndoActionComponentCreateDelete(document, new Component[] { meshGeometryNew }, create: true));
                        }
                    }
                }
            }
        }
        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            var radius = Radius.Value;
            var height = Height.Value;

            if (InsideOut)
            {
                radius = -radius;
                height = -height;
            }
            SimpleMeshGenerator.GenerateCylinder(Axis, (float)radius, (float)height, Segments, true, true, true, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
Esempio n. 12
0
        internal void CompileDataOfThisObject(Component_Mesh.CompiledData compiledData)          // Component_Mesh mesh, Component_Mesh.CompiledData result )
        {
            VertexElement[] vertexStructureV = VertexStructure;
            UnwrappedUVEnum unwrappedUVV     = UnwrappedUV;

            byte[]             verticesV = Vertices;
            int[]              indicesV  = Indices;
            Component_Material materialV = Material;

            Component_Mesh.StructureClass structure = null;

            OnGetDataOfThisObject(ref vertexStructureV, ref verticesV, ref indicesV, ref materialV, ref structure);
            GetDataOfThisObjectEvent?.Invoke(this, ref vertexStructureV, ref verticesV, ref indicesV, ref materialV, ref structure);

            //add to result
            if (vertexStructureV != null && vertexStructureV.Length != 0 && verticesV != null && verticesV.Length != 0 && (indicesV == null || indicesV.Length != 0))
            {
                //!!!!еще чтобы был с позициями?

                vertexStructureV.GetInfo(out var vertexSize, out var holes);
                //if( !holes )
                {
                    int vertexCount = verticesV.Length / vertexSize;

                    var op = new Component_RenderingPipeline.RenderSceneData.MeshDataRenderOperation(this);

                    op.VertexStructure = vertexStructureV;

                    op.VertexStructureContainsColor = op.VertexStructure.Any(e => e.Semantic == VertexElementSemantic.Color0);
                    ////disable if all data equal zero. it is means no data.
                    //if( op.VertexStructureContainsColor )
                    //{
                    //	if( vertexStructureV.GetElementBySemantic( VertexElementSemantic.Color0, out var element ) )
                    //	{
                    //		var size = element.GetSizeInBytes();
                    //		int vertexOffset = element.Offset;
                    //		for( int nVertex = 0; nVertex < vertexCount; nVertex++ )
                    //		{
                    //			for( int n = 0; n < size; n++ )
                    //			{
                    //				if( verticesV[ vertexOffset + n ] != 0 )
                    //				{
                    //					//found non zero
                    //					goto exit;
                    //				}
                    //			}
                    //			vertexOffset += vertexSize;
                    //		}
                    //		op.VertexStructureContainsColor = false;
                    //		exit:;
                    //	}
                    //}

                    op.UnwrappedUV = unwrappedUVV;

                    var vertexDeclaration = op.VertexStructure.CreateVertexDeclaration(0);
                    op.VertexBuffers     = new GpuVertexBuffer[] { GpuBufferManager.CreateVertexBuffer(verticesV, vertexDeclaration) };
                    op.VertexStartOffset = 0;
                    op.VertexCount       = vertexCount;

                    if (indicesV != null)
                    {
                        op.IndexBuffer      = GpuBufferManager.CreateIndexBuffer(indicesV);
                        op.IndexStartOffset = 0;
                        op.IndexCount       = indicesV.Length;
                    }

                    //!!!!так?
                    op.Material = materialV;

                    compiledData.MeshData.RenderOperations.Add(op);

                    //!!!!может мержить когда несколько. индексы MeshGeometry в RawVertices
                    if (compiledData.MeshData.Structure == null)
                    {
                        compiledData.MeshData.Structure = structure;
                    }

                    //var op = new Component_Mesh.CompiledData.RenderOperation();
                    //op.creator = this;

                    //op.vertexStructure = vertexStructureV;
                    //List<GpuVertexBuffer> l = new List<GpuVertexBuffer>();

                    ////!!!!make copy of arrays?

                    //var vertexDeclaration = op.vertexStructure.CreateVertexDeclaration( 0 );

                    //l.Add( GpuBufferManager.CreateVertexBuffer( verticesV, vertexDeclaration, false ) );
                    //op.vertexBuffers = l;
                    //op.vertexStartOffset = 0;
                    //op.vertexCount = vertexCount;

                    //if( indicesV != null )
                    //{
                    //	op.indexBuffer = GpuBufferManager.CreateIndexBuffer( indicesV, false );
                    //	op.indexStartOffset = 0;
                    //	op.indexCount = indicesV.Length;
                    //}

                    ////!!!!так?
                    //op.material = materialV;

                    //var item = new Component_Mesh.CompiledData.RenderOperationItem();
                    //item.operation = op;
                    ////!!!!
                    ////item.transform = TransformOfData;//TransformRelativeToParent;
                    //compiledData.RenderOperations.Add( item );

                    ////op.transform = Transform;
                    ////compiledData.RenderOperations.Add( op );
                }
                //else
                //{
                //	//!!!!!error
                //}
            }
        }
Esempio n. 13
0
        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            SimpleMeshGenerator.GenerateStairs(Axis, Width, Height, Depth, Steps, Curvature, Radius, Sides, InsideOut, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
Esempio n. 14
0
        public static Component_Mesh.StructureClass CreateMeshStructure(Face[] faces)
        {
            var result         = new Component_Mesh.StructureClass();
            int vertexMaxIndex = 0;

            //faces
            result.Faces = new Component_Mesh.StructureClass.Face[faces.Length];
            for (int nFace = 0; nFace < faces.Length; nFace++)
            {
                var face = faces[nFace];

                var triangles2 = new Component_Mesh.StructureClass.FaceVertex[face.Triangles.Length];
                for (int n = 0; n < triangles2.Length; n++)
                {
                    var faceVertex = face.Triangles[n];
                    triangles2[n] = new Component_Mesh.StructureClass.FaceVertex(faceVertex.Vertex, 0, faceVertex.RawVertex);

                    vertexMaxIndex = Math.Max(vertexMaxIndex, faceVertex.Vertex);
                }

                result.Faces[nFace] = new Component_Mesh.StructureClass.Face(triangles2, null, 0);
            }

            //edges
            var edges = new ESet <Vector2I>(vertexMaxIndex * 3);

            for (int nFace = 0; nFace < faces.Length; nFace++)
            {
                var face = faces[nFace];

                var edgeCounts = new Dictionary <Vector2I, int>(face.Triangles.Length);

                for (int nTriangle = 0; nTriangle < face.Triangles.Length / 3; nTriangle++)
                {
                    var faceVertex0 = face.Triangles[nTriangle * 3 + 0];
                    var faceVertex1 = face.Triangles[nTriangle * 3 + 1];
                    var faceVertex2 = face.Triangles[nTriangle * 3 + 2];

                    void AddEdge(int vertex1, int vertex2)
                    {
                        int v1, v2;

                        if (vertex1 > vertex2)
                        {
                            v1 = vertex2;
                            v2 = vertex1;
                        }
                        else
                        {
                            v1 = vertex1;
                            v2 = vertex2;
                        }
                        var key = new Vector2I(v1, v2);

                        edgeCounts.TryGetValue(key, out var count);
                        edgeCounts[key] = count + 1;
                    }

                    AddEdge(faceVertex0.Vertex, faceVertex1.Vertex);
                    AddEdge(faceVertex1.Vertex, faceVertex2.Vertex);
                    AddEdge(faceVertex2.Vertex, faceVertex0.Vertex);
                }

                foreach (var pair in edgeCounts)
                {
                    if (pair.Value == 1)
                    {
                        var edge = pair.Key;
                        edges.AddWithCheckAlreadyContained(new Vector2I(edge.X, edge.Y));
                    }
                }

                //for( int nTriangle = 0; nTriangle < face.Triangles.Length / 3; nTriangle++ )
                //{
                //	var faceVertex0 = face.Triangles[ nTriangle * 3 + 0 ];
                //	var faceVertex1 = face.Triangles[ nTriangle * 3 + 1 ];
                //	var faceVertex2 = face.Triangles[ nTriangle * 3 + 2 ];

                //	void AddEdge( int vertex1, int vertex2 )
                //	{
                //		int v1, v2;
                //		if( vertex1 > vertex2 )
                //		{
                //			v1 = vertex2;
                //			v2 = vertex1;
                //		}
                //		else
                //		{
                //			v1 = vertex1;
                //			v2 = vertex2;
                //		}
                //		edges.AddWithCheckAlreadyContained( new Vector2I( v1, v2 ) );
                //	}

                //	AddEdge( faceVertex0.Vertex, faceVertex1.Vertex );
                //	AddEdge( faceVertex1.Vertex, faceVertex2.Vertex );
                //	AddEdge( faceVertex2.Vertex, faceVertex0.Vertex );
                //}
            }
            result.Edges = edges.Select(e => new Component_Mesh.StructureClass.Edge(e.X, e.Y)).ToArray();

            //vertices
            result.Vertices = new Component_Mesh.StructureClass.Vertex[vertexMaxIndex + 1];

            return(result);
        }