Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 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
1
Question by Chris12345 · Aug 01, 2015 at 02:07 AM · c#

Get Outer/Edge Vertices C#

Good Afternoon, I am trying to get all the outer/edge vertices from my mesh. I know I can get the y and x array but am having troubles just getting the outer vertices.

 using UnityEngine;
 using System.Collections;
 
 public class Shape : MonoBehaviour {
 
 public Vector3[] Vertices;
 public Vector3[] Outer;
 
 void Start(){
 // Set Vertices //
 
 
 // Get Vertices //
 for(int i = 0; i < Vertices.Length; i++)
 Outer = Vertices[i].x;
 }
 
 }

 
Comment
Add comment · Show 2
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 Bunny83 · Aug 01, 2015 at 03:32 AM 0
Share

What kind of mesh do we talk about? A 3d mesh or a 2d mesh? So do you want to find the projected silhouette of a 3d mesh (like you would when calculating a shadow volume) or about a flat 2d mesh which consists of several coplanar trianges and you just want to find the bounding edges?

Do you have a screenshot / drawing of your mesh?

avatar image Chris12345 · Aug 01, 2015 at 01:52 PM 0
Share

Thanks for the reply, The mesh is 2d and am in need to find the bounding edges. I would show an image but the mesh is dynamic and constantly changing.

1 Reply

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

Answer by Bunny83 · Aug 01, 2015 at 02:08 PM

Ok, even it's 2d there are several approaches. First of all it depends on if the mesh actually uses shared vertices or not. If the vertices in the inside are not shared the mesh is technically not closed.

If all inside vertices are shared you can simply create pairs of shared edges. All edges which don't have a shared edge have to be a boundary edge. This method would work also with concave meshes.

The next method only works with convex meshes but the mesh don't need to have shared vertices. You simply test each edge and see if all vertices are on one side of the edge. If there are no vertices on the outside it's a boundary edge.

If the mesh doesn't have shared edges / vertices and is concave it's getting difficult. You would have to match vertices based on their local position to determine if they are actually the same. Once all split vertices have been logically merged you can use the first approach.

ps: The first method actually don't need the vertices array at all. You only work with indices. In the second and third case of course you have to use the vertices array.

edit
Here are some methods that will work on shared edges:

 public static class EdgeHelpers
 {
     public struct Edge
     {
         public int v1;
         public int v2;
         public int triangleIndex;
         public Edge(int aV1, int aV2, int aIndex)
         {
             v1 = aV1;
             v2 = aV2;
             triangleIndex = aIndex;
         }
     }
 
     public static List<Edge> GetEdges(int[] aIndices)
     {
         List<Edge> result = new List<Edge>();
         for (int i = 0; i < aIndices.Length; i += 3)
         {
             int v1 = aIndices[i];
             int v2 = aIndices[i + 1];
             int v3 = aIndices[i + 2];
             result.Add(new Edge(v1, v2, i));
             result.Add(new Edge(v2, v3, i));
             result.Add(new Edge(v3, v1, i));
         }
         return result;
     }
 
     public static List<Edge> FindBoundary(this List<Edge> aEdges)
     {
         List<Edge> result = new List<Edge>(aEdges);
         for (int i = result.Count-1; i > 0; i--)
         {
             for (int n = i - 1; n >= 0; n--)
             {
                 if (result[i].v1 == result[n].v2 && result[i].v2 == result[n].v1)
                 {
                     // shared edge so remove both
                     result.RemoveAt(i);
                     result.RemoveAt(n);
                     i--;
                     break;
                 }
             }
         }
         return result;
     }
     public static List<Edge> SortEdges(this List<Edge> aEdges)
     {
         List<Edge> result = new List<Edge>(aEdges);
         for (int i = 0; i < result.Count-2; i++)
         {
             Edge E = result[i];
             for(int n = i+1; n < result.Count; n++)
             {
                 Edge a = result[n];
                 if (E.v2 == a.v1)
                 {
                     // in this case they are already in order so just continoue with the next one
                     if (n == i+1)
                         break;
                     // if we found a match, swap them with the next one after "i"
                     result[n] = result[i + 1];
                     result[i + 1] = a;
                     break;
                 }
             }
         }
         return result;
     }
 }


You can simply use it like that:

 var boundary = EdgeHelpers.GetEdges(mesh.triangles).FindBoundary();

Now you have all boundary edges in a list.

edit
They are probably not sorted in any way. To get a a continuous path you just have to match "v2" of an edge with "v1" of another edge. I just added the "SortEdges" extension method. So you can simply do:

 var boundaryPath = EdgeHelpers.GetEdges(mesh.triangles).FindBoundary().SortEdges();

To get the actual vertices you have to iterate through the edges and just use v1 value of each edge as index into the vertices array.

If you need to support a mesh without shared edges you could simply "preprocess" the mesh to create a indices list with only shared indices. Which vertices are shared has to be determined by looking at the vertex positions.

Comment
Add comment · Show 14 · 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 Chris12345 · Aug 01, 2015 at 03:41 PM 0
Share

Thanks, but i am getting a error: I had to add System.Collections.Generic to the edge helpers script to allow the list class but now in my other script using var boundaryPath = EdgeHelpers.GetEdges(mesh.triangles).FindBoundary().SortEdges(); i am getting this error.

 error CS1061: Type `System.Collections.Generic.List<EdgeHelpers.Edge>' does not contain a definition for `FindBoundary' and no extension method `FindBoundary' of type `System.Collections.Generic.List<EdgeHelpers.Edge>' could be found (are you missing a using directive or an assembly reference?)
avatar image Chris12345 · Aug 01, 2015 at 03:46 PM 0
Share

semed to fix the error by adding:

 public static List<Edge> FindBoundary(this List<Edge> aEdges)
 
 ins$$anonymous$$d of:
 
 public static List<Edge> FindBoundary(List<Edge> aEdges)
avatar image Chris12345 · Aug 01, 2015 at 03:53 PM 0
Share

Could you please explain more about "To get the actual vertices you have to iterate through the edges and just use v1 value of each edge as index into the vertices array.", Thanks for all your help i really appreciate it.

avatar image Bunny83 · Aug 01, 2015 at 05:38 PM 0
Share

@Chris12345: Hmm, that's strange ^^ i thought i have just copy&pasted the whole class from my project and i have the "this" in my code ^^. I've edited the answer.

Well, the indices from the triangle array define which vertices are used to create a triangle. An "Edge" represents always 2 vertices. To get the position of a vertex you just have to use "v1" as index into the vertices array:

 Vector3[] vertices = mesh.vertices;
 List<Edge> boundaryPath = EdgeHelpers.GetEdges(mesh.triangles).FindBoundary().SortEdges();
 for(int i = 0; i < boundaryPath.Count; i++)
 {
     Vector3 pos = vertices[ boundaryPath[i].v1 ];
     // do something with pos
 }

Since the resulting edges should form a closed path we can ignore "v2" (the second point of each edge) since the second point of the first edge is the first point of the second edge. The second point of the second edge is the first point of the third edge and so on. The last edge should connect back to the first one since it's a closed path.

avatar image Chris12345 · Aug 01, 2015 at 06:29 PM 0
Share

Thanks for all the help, but i had to fix

 List<Edge> boundaryPath EdgeHelpers.GetEdges(mesh.triangles).FindBoundary().SortEdges();
 

Change to:

 var boundaryPath EdgeHelpers.GetEdges(mesh.triangles).FindBoundary().SortEdges();
 

Also I am getting a error, my code requires a vector3[] and am getting the following:

 error CS0029: Cannot implicitly convert type `UnityEngine.Vector3' to `UnityEngine.Vector3[]

 Line: Vector3[] pos = vertices[boundaryPath[i].v1];
 

It will not let me set pos to a vector3[]

Show more comments

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

30 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 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

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Illuminating a 3D object's edges OnMouseOver (script in c#)? 1 Answer

Flip over an object (smooth transition) 3 Answers

Making a bubble level (not a game but work tool) 1 Answer


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