Skip to content

Commit 4fe16dd

Browse files
Merge pull request #1353 from Balint-H:fix/unity-mesh-import
PiperOrigin-RevId: 602391543 Change-Id: I6d93c2beb672e8de7d5c9d17e77b4185dd137cb3
2 parents e143b3d + 64b0423 commit 4fe16dd

File tree

1 file changed

+45
-20
lines changed

1 file changed

+45
-20
lines changed

unity/Editor/Importer/StlMeshParser.cs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
using System;
1615
using System.Collections.Generic;
1716
using System.IO;
1817
using System.Linq;
1918
using UnityEngine;
19+
using UnityEngine.Rendering;
2020

2121
namespace Mujoco {
2222

@@ -27,6 +27,17 @@ public static Vector3 ReadVector3(this BinaryReader reader) {
2727
var z = reader.ReadSingle();
2828
return new Vector3(x, y, z);
2929
}
30+
31+
public static int GetOrCreateVertexIndex(Dictionary<Vector3, int> vertexIndexMap, List<Vector3> vertices, List<Vector3>normals, Vector3 vertex, Vector3 normal) {
32+
if (vertexIndexMap.TryGetValue(vertex, out int existingIndex)) {
33+
return existingIndex;
34+
}
35+
int newIndex = vertexIndexMap.Count;
36+
vertexIndexMap.Add(vertex, newIndex);
37+
vertices.Add(vertex);
38+
normals.Add(normal);
39+
return newIndex;
40+
}
3041
}
3142

3243
public static class BinaryWriterExtensions {
@@ -50,7 +61,7 @@ public class StlMeshParser {
5061
// The binary STL format is described here: https://en.wikipedia.org/wiki/STL_(file_format)
5162
public static Mesh ParseBinary(byte[] stlFileContents, Vector3 scale) {
5263
var fileTypeId = System.Text.Encoding.UTF8.GetString(
53-
stlFileContents.Take(_asciiFileTypeId.Length).ToArray());
64+
stlFileContents.Take(_asciiFileTypeId.Length).ToArray());
5465
if (fileTypeId == _asciiFileTypeId) {
5566
throw new IOException("Ascii STL file format is not supported.");
5667
}
@@ -59,27 +70,39 @@ public static Mesh ParseBinary(byte[] stlFileContents, Vector3 scale) {
5970
using (var reader = new BinaryReader(stream)) {
6071
reader.ReadBytes(_headerLength);
6172
var numTriangles = reader.ReadUInt32();
62-
var numVertices = numTriangles * _verticesPerTriangle;
63-
if (numVertices > _unityLimitNumVerticesPerMesh) {
64-
throw new IndexOutOfRangeException(
65-
"The mesh exceeds the number of vertices per mesh allowed by Unity. " +
66-
$"({numVertices} > {_unityLimitNumVerticesPerMesh})");
67-
}
68-
var triangleIndices = new List<int>(capacity: (int)numVertices);
69-
var vertices = new List<Vector3>(capacity: (int)numVertices);
70-
var normals = new List<Vector3>(capacity: (int)numVertices);
71-
for (var i = 0; i < numVertices; i += _verticesPerTriangle) {
73+
var maxNumVertices = numTriangles * _verticesPerTriangle;
74+
75+
Dictionary<Vector3, int> vertexIndexMap = new Dictionary<Vector3, int>();
76+
var triangleIndices = new int[(int)numTriangles * _verticesPerTriangle];
77+
var vertices = new List<Vector3>(capacity: (int)maxNumVertices);
78+
var normals = new List<Vector3>(capacity: (int)maxNumVertices);
79+
for (var i = 0; i < numTriangles; i++) {
7280
var triangleNormal = ToXZY(reader.ReadVector3());
73-
normals.AddRange(new[] { triangleNormal, triangleNormal, triangleNormal });
74-
vertices.AddRange(new[] {
75-
ToXZY(reader.ReadVector3()),
76-
ToXZY(reader.ReadVector3()),
77-
ToXZY(reader.ReadVector3()) });
78-
triangleIndices.AddRange(new[] {i, i + 2, i + 1});
79-
reader.ReadInt16(); // Read the unused attribute indices field.
81+
var verts = new[]
82+
{
83+
ToXZY(reader.ReadVector3()),
84+
ToXZY(reader.ReadVector3()),
85+
ToXZY(reader.ReadVector3())
86+
};
87+
var indices = new[] { verts[0], verts[2], verts[1] }.Select(v =>
88+
BinaryReaderExtensions.GetOrCreateVertexIndex(vertexIndexMap,
89+
vertices,
90+
normals,
91+
v,
92+
triangleNormal)).ToArray();
93+
for (int j = 0; j < 3; j++) {
94+
triangleIndices[i * 3 + j] = indices[j];
95+
}
96+
reader.ReadInt16(); // Read the unused attribute indices field.
8097
}
8198

8299
var mesh = new Mesh();
100+
var numVertices = vertexIndexMap.Count;
101+
102+
if (numVertices > _unityLimitNumVerticesPerMesh) {
103+
mesh.indexFormat = IndexFormat.UInt32;
104+
}
105+
83106
mesh.vertices = vertices.ToArray();
84107
mesh.normals = normals.ToArray();
85108
mesh.triangles = triangleIndices.ToArray();
@@ -88,6 +111,7 @@ public static Mesh ParseBinary(byte[] stlFileContents, Vector3 scale) {
88111
mesh.RecalculateNormals();
89112
mesh.RecalculateTangents();
90113
mesh.RecalculateBounds();
114+
91115
return mesh;
92116
}
93117
}
@@ -126,7 +150,8 @@ public static byte[] SerializeBinary(Mesh mesh) {
126150

127151
writer.Write((short)0);
128152
}
129-
return stream.GetBuffer();
153+
154+
return stream.ToArray();
130155
}
131156
}
132157
}

0 commit comments

Comments
 (0)