//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; } }