- Home /
Fast way to find vertex of spezific color
Hi,
i have a big mesh with colored vertices. The mesh is so big that unity split it into submeshes. Now i want to find vertices to a given color. My first try was to iterate over the whole color array of one submesh, and this for all submeshes. It works but it takes a loooooooooooooooooong to complete. Is there some sort of function which can find the vertices for a given color ?
My Code so far:
// at start, check for filter of the parent node
void Awake () {
checkMeshForFilter(transform);
}
// just check for the mesh filter. if there is no -> check the children
// if mesh filter is found -> check for color of the mesh
private void checkMeshForFilter(Transform obj){
MeshFilter filter = obj.GetComponent<MeshFilter>();
if (filter == null)
for (int i=0; i < obj.transform.childCount; i++)
checkMeshForFilter(transform.GetChild(i));
else
{
checkMeshForColor(new Color32(255, 0, 0, 0));
}
}
// iterate over all color of the mesh and compare it with the given color
private void checkMeshForColor(Color32 color, MeshFilter filter){
Mesh mesh = filter.mesh;
for (int i=0; i < mesh.colors32.Length; i++)
if (mesh.colors32[i].Equals(color))
Debug.Log("FOUND");
}
Also here is my hierarchy of the mesh
MESH (no filter)
->SUB_MESH_1 (with filter & mesh)
->SUB_MESH_2 (with filter & mesh)
->SUB_MESH_3 (with filter & mesh)
Best dimerk
Answer by Bunny83 · Nov 20, 2014 at 02:22 PM
There is no faster way and it shouldn't take that long. In your code above the only thing that might cause a severe delay is your Debug.Log. That is slow like hell ;)
Try this instead:
string str = "";
Color32[] colors = mesh.colors32;
for (int i=0; i < colors.Length; i++)
if (colors[i].Equals(color))
str += i+", ";
Debug.Log("FOUND: " + str);
If there are a lot vertices with that color this will be way much faster, even though "str +=" is also quite slow and inefficient (and a StringBuilder would be better) it s still 1000 times faster then seperate Debug.Logs.
edit
Forgot to mention that you should cache the array as you actually create two new arrays each iteration. The colors or colors32 property creates a temporary array with the color values and returns it every time you read the property. So in your original code you get a copy just to check the array length (in the for-loop-condition) and again inside the for loop body. If the array is large (which it probably is when you already have to split the mesh into submeshes) this will create a huge amount of garbage. One array with 64k elements requires around 260KB. Since you create 2 arrays for each array element it's 64k * 260KB = ~ 16.3 GB ^^
Awesome.Thank you for the solution and thank you for writing the reason what's the problem is!! Runtime now is about 1 $$anonymous$$ute. Was 5 $$anonymous$$utes or more.
1 $$anonymous$$ute? That's impossible. Even when you have 10 meshes with all 64k vertices this should be a matter of seconds (or even fractions of a second). Is that your whole code?
It's also not necessary to iterate manually to all children. There is GetComponentsInChildren which you can use to get all $$anonymous$$eshFilters on that gameobject and on all child objects.
Yes, i had some heavy stuff running (Loading some dll and when missing some hardware it slows down the start of the whole program). When i disable this, it's instant. Thanks again :)