Пример #1
0
        static unsafe void TransformVertices(byte[] vertices, MeshData.MeshGeometryFormat format, Matrix4 matrix, Quaternion rotation)
        {
            fixed(byte *ptr = vertices)
            {
                int count = vertices.Length / format.vertexSize;

                for (int i = 0; i < count; i++)
                {
                    byte *    vertexStart = ptr + i * format.vertexSize;
                    Vector3F *posPtr      = (Vector3F *)(vertexStart + format.positionOffset);
                    *         posPtr      = (*posPtr * matrix).ToVector3F();

                    Vector3F *normalPtr = (Vector3F *)(vertexStart + format.normalOffset);
                    *         normalPtr = (*normalPtr * rotation).ToVector3F();

                    Vector4F *tangentPtr = (Vector4F *)(vertexStart + format.tangentOffset);
                    *         tangentPtr = new Vector4F(((*tangentPtr).ToVector3F() * rotation).ToVector3F(), (*tangentPtr).W);
                }
            }
        }
Пример #2
0
        //static byte[] ToVertices( Net3dBool.Vector3[] vertices, MeshData.MeshGeometryFormat vs )
        //{
        //	byte[] ret = new byte[ vertices.Length * vs.vertexSize ];
        //	unsafe
        //	{
        //		fixed ( byte* ptr = ret )
        //		{
        //			for( int i = 0; i < vertices.Length; i++ )
        //			{
        //				var v = vertices[ i ];

        //				var pos = (Vector3F*)( ptr + i * vs.vertexSize + vs.positionOffset );
        //				( *pos ) = new Vector3F( (float)v.x, (float)v.y, (float)v.z );
        //			}
        //		}
        //	}

        //	return ret;
        //}


        //The data are extracted from Component_Mesh.ExtractedStructure.
        //Хотя можно взять из MeshGeometry.Vertices,Indices, но там проиндексировано вместе с другими элементами(normals,...).
        static List <(Vector3F[] positions, int[] indices)> GetData(Component_MeshInSpace ms)
        {
            Component_Mesh.ExtractedStructure structure = ms.Mesh.Value.ExtractStructure();

            var ret = new List <(Vector3F[] positions, int[] indices)>();

            //extract old positions
            var oldPositions = new Vector3F[structure.MeshGeometries.Length][];

            for (int geomIndex = 0; geomIndex < structure.MeshGeometries.Length; geomIndex++)
            {
                var vs = new MeshData.MeshGeometryFormat(structure.MeshGeometries[geomIndex].VertexStructure);
                oldPositions[geomIndex] = new Vector3F[structure.MeshGeometries[geomIndex].Vertices.Length / vs.vertexSize];

                unsafe
                {
                    fixed(byte *ptr = structure.MeshGeometries[geomIndex].Vertices)
                    {
                        for (int i = 0; i < oldPositions[geomIndex].Length; i++)
                        {
                            oldPositions[geomIndex][i] = *(Vector3F *)(ptr + i * vs.vertexSize + vs.positionOffset);
                        }
                    }
                }
            }
            //------------

            var geomTriangles = new List <Component_Mesh.StructureClass.FaceVertex> [structure.MeshGeometries.Length];

            for (int i = 0; i < structure.MeshGeometries.Length; i++)
            {
                geomTriangles[i] = new List <Component_Mesh.StructureClass.FaceVertex>();
            }
            for (int faceIndex = 0; faceIndex < structure.Structure.Faces.Length; faceIndex++)
            {
                var face = structure.Structure.Faces[faceIndex];
                for (int i = 0; i < face.Triangles.Length; i++)
                {
                    geomTriangles[face.Triangles[i].RawGeometry].Add(face.Triangles[i]);
                }
            }

            for (int i = 0; i < geomTriangles.Length; i++)
            {
                var   g = geomTriangles[i];
                int[] oldVertexToNewMapping = new int[structure.Structure.Vertices.Length];
                for (int j = 0; j < oldVertexToNewMapping.Length; j++)
                {
                    oldVertexToNewMapping[j] = -1;
                }
                int nextIndex    = 0;
                var newPositions = new List <Vector3F>();
                var newIndices   = new int[g.Count];

                for (int j = 0; j < g.Count; j++)
                {
                    var tv       = g[j];
                    int newIndex = oldVertexToNewMapping[tv.Vertex];
                    if (newIndex == -1)
                    {
                        newIndex = nextIndex++;
                        oldVertexToNewMapping[tv.Vertex] = newIndex;
                        newPositions.Add(oldPositions[tv.RawGeometry][tv.RawVertex]);
                    }
                    newIndices[j] = newIndex;
                }
                ret.Add((newPositions.ToArray(), newIndices));
            }

            return(ret);
        }
Пример #3
0
        //Component_MeshInSpace contains only one Component_Mesh.
        static void MergeGeometries(Component_Mesh mesh, DocumentInstance document, UndoMultiAction undo)
        {
            Component_MeshGeometry[] geometries = mesh.GetComponents <Component_MeshGeometry>();
            if (geometries == null || geometries.Length < 2)
            {
                return;
            }

            Reference <Component_Material> material = geometries[0].Material;
            //for( int i = 1; i < geometries.Length; i++ )
            //{
            //	if( !( material.Value == null && geometries[ i ].Material.Value == null || material.Equals( geometries[ i ].Material ) ) )
            //	{
            //		//??? Если разные Material какой вариант лучше: 1) Брать из первого geometry с вопросом в MessageBox; 2) Disable в меню для Action. 3) Соединять те, которые с одинаковым материалом.
            //		if( EditorMessageBox.ShowQuestion( "Mesh geometries have different materials. Merge them using a material from the first geometry?", MessageBoxButtons.OKCancel ) == DialogResult.Cancel )
            //		{
            //			return;
            //		}
            //	}
            //}

            var extracted = mesh.ExtractStructure();

            var newIndices         = new List <int>();
            var newVertices        = new List <byte>();
            var newVertexStructure = extracted.MeshGeometries[0].VertexStructure;
            var newVertexFormat    = new MeshData.MeshGeometryFormat(newVertexStructure);

            for (int geomIndex = 0; geomIndex < extracted.MeshGeometries.Length; geomIndex++)
            {
                var g = extracted.MeshGeometries[geomIndex];


                if (g.Vertices == null || g.Indices == null)
                {
                    continue;
                }
                int indexOffset = newVertices.Count / newVertexFormat.vertexSize;

                for (int i = 0; i < g.Indices.Length; i++)
                {
                    newIndices.Add(g.Indices[i] + indexOffset);
                }

                if (!CommonFunctions.IsSameVertexStructure(newVertexStructure, g.VertexStructure))
                {
                    g.Vertices = MeshData.ConvertToFormat(new MeshData.MeshGeometryFormat(g.VertexStructure), g.Vertices, newVertexFormat);
                }

                newVertices.AddRange(g.Vertices);

                foreach (var face in extracted.Structure.Faces)
                {
                    for (int i = 0; i < face.Triangles.Length; i++)
                    {
                        if (face.Triangles[i].RawGeometry == geomIndex)
                        {
                            face.Triangles[i].RawGeometry = 0;
                            face.Triangles[i].RawVertex  += indexOffset;
                        }
                    }
                }
            }

            // changes in the mesh

            if (undo != null)
            {
                //add structure update to undo
                var property = (Metadata.Property)mesh.MetadataGetMemberBySignature("property:" + nameof(Component_Mesh.Structure));
                undo.AddAction(new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item(mesh, property, mesh.Structure?.Clone())));
            }

            bool meshWasEnabled = mesh.Enabled;

            mesh.Enabled = false;
            try
            {
                var newGeometry = mesh.CreateComponent <Component_MeshGeometry>();
                newGeometry.Material = material;

                newGeometry.Vertices        = newVertices.ToArray();
                newGeometry.Indices         = newIndices.ToArray();
                newGeometry.VertexStructure = newVertexStructure;

                //add created geometry to undo
                undo?.AddAction(new UndoActionComponentCreateDelete(document, new Component[] { newGeometry }, create: true));

                mesh.Structure = extracted.Structure;

                //delete old mesh geometry
                undo?.AddAction(new UndoActionComponentCreateDelete(document, geometries, create: false));

                newGeometry.Name = CommonFunctions.GetUniqueFriendlyName(newGeometry);
            }
            finally
            {
                mesh.Enabled = meshWasEnabled;
            }
        }