1212// See the License for the specific language governing permissions and 
1313// limitations under the License. 
1414
15- using  System ; 
1615using  System . Collections . Generic ; 
1716using  System . IO ; 
1817using  System . Linq ; 
1918using  UnityEngine ; 
19+ using  UnityEngine . Rendering ; 
2020
2121namespace  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
3243public  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