Mesh.Unweld alternative for Rhino3dmIO?


#1

Good morning all,

I have been working on an application that uses Rhino3dmIO to read/write some mesh objects in 3dm files. I’ve reached a point now when importing a mesh and I am seeing some flipped/incorrect vertices on the mesh which cause some shade/display issues when viewing the model later. Normally in RhinoCommon, or in Rhino alone I would use the Unweld command, or Mesh.Unweld to resolve this; however, I see that this method doesn’t exist in Rhino IO. Is there an alternative routine in Rhino3dmIO to achieve the same corrective result?

I appreciate any suggestions in advance, thanks.


(Dale Fugier) #2

Hi @AndrewZ,

If you want to unweld a mesh manually, then just run through each of the faces, make a copy of each face vertex, and set the face.vi to the new vertex index. Then, use Mesh.Compact when it’s done to get rid of the no longer referenced vertexes. Finally recompute the vertex normals and face normals.

– Dale


#3

Hey Dale,

I appreciate the suggestion, and I apologize if this question is trivial; I feel like I’ve followed you here, but still seeing the same results as before. Is there something I am missing in the code below? Should I be computing/comparing against a given angle tolerance at some point, as you would supply when running the Unweld command?

   private Mesh UnweldMesh(Mesh inputmesh)
    {
        var facelist = inputmesh.Faces;

        for (int i = 0; i < facelist.Count; i++)
        {
            MeshFace fcopy = facelist[i];
            var a = fcopy.A;
            var b = fcopy.B;
            var c = fcopy.C;
            facelist[i].Set(a, b, c);
        }

        inputmesh.Compact();                        //dump unref'd verts
        inputmesh.Normals.ComputeNormals();         //recompute vert norms
        inputmesh.FaceNormals.ComputeFaceNormals(); // recompute face norms

        return inputmesh;

    }

(Dale Fugier) #4

Hi @AndrewZ,

I was thinking of something more like this:

public static Mesh UnweldMesh(Mesh src)
{
  if (null == src) throw new ArgumentNullException(nameof(src));

  var mesh = src.DuplicateMesh();
  for (var i = 0; i < mesh.Faces.Count; i++)
  {
    var face = mesh.Faces[i];
    var a = mesh.Vertices.Add(mesh.Vertices[face.A]);
    var b = mesh.Vertices.Add(mesh.Vertices[face.B]);
    var c = mesh.Vertices.Add(mesh.Vertices[face.C]);
    var d = face.IsQuad ? mesh.Vertices.Add(mesh.Vertices[face.D]) : c;
    mesh.Faces.SetFace(i, a, b, c, d);
  }

  mesh.Compact();
  mesh.Normals.ComputeNormals();
  mesh.FaceNormals.ComputeFaceNormals();

  return mesh;
}

I think this will work. :wink:

– Dale


#5

You’re the man @dale. I still have a lot to learn, but that did the trick. Thanks!