Im trying to edit the texture of a mesh, adding different color around sharp edges. To do this, I figure that I have to check the edges and if the angle between the faces attached to an edge is above some threshold value, I color the texture along that edge.
So far im just coloring all edges to see how this works, but I got some strange results.
The cube works, but apparently the outer edges only have one face attached to them, so I have to find the pairs somehow and check the angle.
However, when I run the code on a cylinder, it goes haywire.

MeshInstance3D meshInstance = GetNode<MeshInstance3D>("../barrel");
		Mesh droneMesh = meshInstance.Mesh;
		MeshDataTool meshDataTool = new MeshDataTool();
		var arrMesh = new ArrayMesh();
		arrMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, droneMesh.SurfaceGetArrays(0));
		meshDataTool.CreateFromSurface(arrMesh, 0);
		Image image = Image.Create(500, 500, false, Image.Format.Rgb8);
		for(int edgeCounter = 0; edgeCounter < meshDataTool.GetEdgeCount(); edgeCounter++){
			for (int y = 0; y < image.GetHeight(); y++) {
				for (int x = 0; x < image.GetWidth(); x++) {
					int[] faceIds = meshDataTool.GetEdgeFaces(edgeCounter);
					if(faceIds.Length == 1 && x%3==0){
						//calculate distance from edge to point x,y
						Vector2 uv = meshDataTool.GetVertexUV(meshDataTool.GetEdgeVertex(edgeCounter, 0));
						Vector2 uv2 = meshDataTool.GetVertexUV(meshDataTool.GetEdgeVertex(edgeCounter, 1));
						float a = (uv-uv2).Length();
						float b = (uv - new Vector2((float)x/500f,(float)y/500f)).Length();
						float c = (uv2 - new Vector2((float)x/500f,(float)y/500f)).Length();
						float s = (a + b + c)/2;
						float distance = 2 * (float) Math.Sqrt(s * (s-a) * (s-b) * (s-c)) / a;
						if(distance < lineWidth){
							image.SetPixel(x, y, new Color(1.0f, 1.0f, 1.0f));
						}	
					}
					if(faceIds.Length == 2 && x%3==1 && meshDataTool.GetFaceNormal(faceIds[0]) != meshDataTool.GetFaceNormal(faceIds[1])){
						//calculate distance from edge to point x,y
						Vector2 uv = meshDataTool.GetVertexUV(meshDataTool.GetEdgeVertex(edgeCounter, 0));
						Vector2 uv2 = meshDataTool.GetVertexUV(meshDataTool.GetEdgeVertex(edgeCounter, 1));
						float a = (uv-uv2).Length();
						float b = (uv - new Vector2((float)x/500f,(float)y/500f)).Length();
						float c = (uv2 - new Vector2((float)x/500f,(float)y/500f)).Length();
						float s = (a + b + c)/2;
						float distance = 2 * (float) Math.Sqrt(s * (s-a) * (s-b) * (s-c)) / a;
						if(distance < lineWidth){
							image.SetPixel(x, y, new Color(1.0f, 0.0f, 0.0f));
						}	
					}	
					if(faceIds.Length == 2 && x%3==2 && meshDataTool.GetFaceNormal(faceIds[0]) == meshDataTool.GetFaceNormal(faceIds[1])){
						//calculate distance from edge to point x,y
						Vector2 uv = meshDataTool.GetVertexUV(meshDataTool.GetEdgeVertex(edgeCounter, 0));
						Vector2 uv2 = meshDataTool.GetVertexUV(meshDataTool.GetEdgeVertex(edgeCounter, 1));
						float a = (uv-uv2).Length();
						float b = (uv - new Vector2((float)x/500f,(float)y/500f)).Length();
						float c = (uv2 - new Vector2((float)x/500f,(float)y/500f)).Length();
						float s = (a + b + c)/2;
						float distance = 2 * (float) Math.Sqrt(s * (s-a) * (s-b) * (s-c)) / a;
						if(distance < lineWidth){
							image.SetPixel(x, y, new Color(0.0f, 1.0f, 0.0f));
						}	
					}			
				}
			}
		}
  • xyz replied to this.

    Gamero Format the code properly using ``` tags.

    It took some fiddling with the editor to get the format right.
    Yes, that is the godot cylinder, and the godot boxmesh.

    • xyz replied to this.

      Gamero Try making a simpler version first, the one that renders all edges without discrimination, to see if your edge distance calculations are correct. I'd also use Geometry2D::GetClosestPointToSegment() to calculate the distance instead of this complicated way via Heron's formula.