Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Kiloblargh · Nov 13, 2013 at 11:00 PM · meshverticestriangles

Rebuilding mesh.triangles after removing vertices

I am assembling meshes together and any vertices that were in the same place (actually a lot, because there are a lot of small cylindrical segments) , I wanted to remove them and update the triangles. I naively thought I could do it like this:

 var oldVertsA : Vector3[] = myMF.mesh.vertices;
 var oldTrianglesA :int[]  = myMF.mesh.triangles;
 var dupVertsA : List.<int> = new List.<int>();
 var uniqueVertsA : List.<Vector3> = oldVertsA.Distinct().ToList();    
 var tempTrisA : List.<int> = new List.<int>();
 
 for (var q : int = 0; q < oldVertsA.Length; q++)
     {
     if (!uniqueVertsA.Contains (oldVertsA [q]) )
         {
         dupVertsA.Add (q);
         }
     }
 for (var p : int = 0; p < oldVertsA.Length; p++)
     {
     if (dupVertsA.Contains (p) )
         {
         tempTrisA.Add (uniqueVertsA.IndexOf (oldVertsA [p] ) );
         }
     else
         {
         tempTrisA.Add (p);
         }    
     }
 myMF.mesh.vertices = uniqueVertsA.ToArray();
 myMF.mesh.triangles = tempTrisA.ToArray();
 
 myT.gameObject.SetActive (true);

but it takes a long time, slows the editor to a crawl, messes up the model, and throws "Mesh.triangles is too small" and "Failed setting triangles" errors. So I'm probably doing more than one thing wrong.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by aldonaletto · Nov 14, 2013 at 12:09 PM

That's not so easy: there are several other attributes associated to each vertex, and you can only reduce vertices when all attributes are equal. In Unity, the most popular vertex attributes are uv and normal (almost all shaders need them) - you should thus compare at least the elements of three arrays: vertices, uv and normals. You should also compare them with Unity equality operators: Vector3 an Vector2 comparisons are made by squared distance, what solves the problematic float comparison.

The idea is: iterate through the triangle list and, for each entry, check whether the vertex list already contains a compatible vertex; if so, get its index; if not, add it to the list and get its index; anyway, assign this index to the triangle entry. The code could be something like this (untested!):

 // cache the mesh:
 var mesh = myMF.mesh;
 // get its arrays:
 var tris = mesh.triangles;
 var verts = mesh.vertices;
 var uvs = mesh.uv;
 var normals = mesh.normals;
 // create the lists:
 var newVerts = new List.<Vector3>();
 var newUvs = new List.<Vector2>();
 var newNormals = new List.<Vector3>();
 // iterate through all triangle entries:
 for (var i=0; i<tris.Length; i++){
   // for each triangle entry...
   var t = tris[i];
   // get its vertex, uv and normal
   var vert = verts[t];
   var normal = normals[t];
   var uv = uvs[t];
   // vertexFound is the compatible vertex index, if any:
   var vertexFound = -1; 
   // check if the vertex is already in the list:
   for (var j=0; j<nVert; j++){
     // if compatible vertex already in the new list...
     if (vert == newVerts[j] && normal == newNormals[j] && uv == newUvs[j]){
       vertexFound = j; // get its index...
       break; // and stop the loop
     }
   }
   if (vertexFound < 0){ // if no compatible vertex in the list...
     // get the index of the next new element...
     vertexFound = newVerts.Count; 
     // then add the vertex and attributes to the list
     newVerts.Add(vert); // add new vertex...
     newUvs.Add(uv); // and attributes to the list
     newNormal.Add(normal); 
   }
   tris[i] = vertexFound; // anyway, update triangle entry...
 }
 mesh.vertices = newVerts.ToArray();
 mesh.uv = newUvs.ToArray();
 mesh.normals = newNormals.ToArray();

Notice that there's no need to create a new triangle list: the vertex indexes replace the original ones.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jpierre88 · Aug 28, 2014 at 12:49 PM 0
Share

@aldonaletto Can you update script, please? I get this message: $$anonymous$$ identifier: 'nVert'.

avatar image tkoknordic · Apr 08, 2015 at 08:30 AM 0
Share

List function ToArray takes huge GC alloc if list is long. Is there better way in the terms of GC allocation size?

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

17 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Problem drawing a mesh with Graphics.DrawMeshNow 1 Answer

Mesh extrusion overlapping triangles problem 0 Answers

Holes in procedural mesh 0 Answers

Highmap on a cube. 0 Answers

How to make sure two meshes have the same vertex count 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges