- Home /
Select mesh element
Hi! What is the approach to detect elements inside the mesh? Like, same to functionality that 3Ds Max Has - "select element"? I can think of some ways, but looping all over and looping all over seems more like workaround then solution to me, so before posting any of my pseudo code I'll gladly hear any advices on how to approach that task.
Do you want to check if some object is inside a mesh or select a triangle in the mesh? If selecting a triangle, how do you want to define which triangle you want to select? Clicking it?
What I want to do is store vertex indicies for every element, like:
backpockets [1,8,9,5,6.....] button [3,5,7,7,6]
So I want to think of some good algorithm which will irritate through mesh, detect elements, and store them thsi way
Is someone ever searches this again, here is my solution:
List<$$anonymous$$eshExtrusion.Edge> _borders = $$anonymous$$eshExtrusion.Build$$anonymous$$anifoldEdges(_mm);
Dictionary<int, Color32> _color$$anonymous$$eys = new Dictionary<int, Color32>();
while (_borders.Count > 0)
{
List<$$anonymous$$eshExtrusion.Edge> _takeusaway = new List<$$anonymous$$eshExtrusion.Edge>();
List<int> _candidates = new List<int>();
_candidates.Add(_borders[0].vertexIndex[0]);
List<int> _openNewSearches = new List<int>();
List<int> _searched = new List<int>();
Color32 _startingColor = new Color32((byte)(UnityEngine.Random.value * 255), (byte)(UnityEngine.Random.value * 255), (byte)(UnityEngine.Random.value * 255), 255);
while (_candidates.Count > 0)
{
for (int p = 0; p < _candidates.Count; p++)
{
if (!_searched.Contains(_candidates[p]))
{
for (int s = 0; s < _borders.Count; s++)
{
//_openNewSearches.Add(_candidates[p]);
if (!_openNewSearches.Contains(_borders[s].vertexIndex[1]))
{
if (_borders[s].vertexIndex[0] == _candidates[p])
{
_openNewSearches.Add(_borders[s].vertexIndex[1]);
if (!_color$$anonymous$$eys.Contains$$anonymous$$ey(_borders[s].vertexIndex[1]))
{
_color$$anonymous$$eys.Add(_borders[s].vertexIndex[1], _startingColor);
}
if (!_takeusaway .Contains(_borders[s]))
{
_takeusaway .Add(_borders[s]);
}
}
}
}
_searched.Add(_candidates[p]);
}
}
_candidates = new List<int>();
for (int g = 0; g < _openNewSearches.Count; g++)
{
_candidates.Add(_openNewSearches[g]);
}
_openNewSearches = new List<int>();
}
for (int i = 0; i < _takeusaway .Count; i++)
{
_borders.Remove(_takeusaway [i]);
}
}
Answer by RyuMaster · Feb 25, 2013 at 09:45 PM
List<MeshExtrusion.Edge> _borders = MeshExtrusion.BuildManifoldEdges(_mm);
Dictionary<int, Color32> _colorKeys = new Dictionary<int, Color32>();
while (_borders.Count > 0)
{
List<MeshExtrusion.Edge> _takeusaway = new List<MeshExtrusion.Edge>();
List<int> _candidates = new List<int>();
_candidates.Add(_borders[0].vertexIndex[0]);
List<int> _openNewSearches = new List<int>();
List<int> _searched = new List<int>();
Color32 _startingColor = new Color32((byte)(UnityEngine.Random.value * 255), (byte)(UnityEngine.Random.value * 255), (byte)(UnityEngine.Random.value * 255), 255);
while (_candidates.Count > 0)
{
for (int p = 0; p < _candidates.Count; p++)
{
if (!_searched.Contains(_candidates[p]))
{
for (int s = 0; s < _borders.Count; s++)
{
//_openNewSearches.Add(_candidates[p]);
if (!_openNewSearches.Contains(_borders[s].vertexIndex[1]))
{
if (_borders[s].vertexIndex[0] == _candidates[p])
{
_openNewSearches.Add(_borders[s].vertexIndex[1]);
if (!_colorKeys.ContainsKey(_borders[s].vertexIndex[1]))
{
_colorKeys.Add(_borders[s].vertexIndex[1], _startingColor);
}
if (!_takeusaway .Contains(_borders[s]))
{
_takeusaway .Add(_borders[s]);
}
}
}
}
_searched.Add(_candidates[p]);
}
}
_candidates = new List<int>();
for (int g = 0; g < _openNewSearches.Count; g++)
{
_candidates.Add(_openNewSearches[g]);
}
_openNewSearches = new List<int>();
}
for (int i = 0; i < _takeusaway .Count; i++)
{
_borders.Remove(_takeusaway [i]);
}
}
Awesome! but seems it selects only edges? how to get all indices of element?
Answer by Dante_CyberdeckGames · Mar 28, 2017 at 04:41 AM
I think this is a more straight forward solution, less code without pre-calculating edges. Explanation on my blog: http://dantefalcone.name/finding-linked-faces-elements-within-a-3d-model-mesh-with-unity3d-and-c/
/// <summary>
/// Given two faces, return whether they share any common vertices.
/// </summary>
/// <param name="faceA">Face represented as array of vertex indices.</param>
/// <param name="faceB">Face represented as array of vertex indices.</param>
/// <returns>bool - whether the faces are connected. </returns>
bool IsConnected(int[] faceA, int[] faceB)
{
for (int i = 0; i < faceA.Length; i++)
for (int j = 0; j < faceB.Length; j++)
if (faceA[i] == faceB[j])
return true;
return false;
}
/// <summary>
/// Given a single triangle face of vertex indices,
/// returns a list of all the vertices of all linked faces.
/// </summary>
/// <param name="pickedTriangle">A known triangle to start search.</param>
/// <param name="triangles">Triangle index list of all vertices in mesh.</param>
/// <returns>List<int> - All triangle face indices that represent the surface element.</returns>
public List<int> GetElement(int[] pickedTriangle, List<int> triangles)
{
// Create the return result list,
// starting with the current picked face
List<int> result = new List<int>(pickedTriangle);
// Iterate through the triangle list index buffer
// by triangle (iterations of 3)
for (int i = 0; i < triangles.Count; i += 3)
{
// Select the (i)th triangle in the index buffer
int[] curTriangle = new int[3] {
triangles[i],
triangles[i + 1],
triangles[i + 2] };
// Check if faces are linked
if (IsConnected(curTriangle, pickedTriangle))
{
// Recursively add all the linked faces to the result
result.AddRange(GetElement(curTriangle, triangles));
}
}
return result;
}
Answer by indianalf · Jan 07, 2021 at 11:35 AM
Interesting but unfortunately the recursive call would iterate a billion times on complex objects so the connective test spot faces within a smoothing group only to extend by distances the time get quickly unacceptable ...
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Problem with non convex mesh colliders 4 Answers
Assign/add gameobject to LOD via script 1 Answer
C# Array of OtherArray's Meshes 1 Answer