Issue with TopologyEdgeList method 'SplitEdge'

Hello,

I was wondering if I could find some help with an issue I have found with the SplitEdge method of MeshTopologyEdgeList. I have written the attached script to speed up the splitting of naked mesh edges of very large meshes, as is common at my job. Everything works correctly out of EditPythonScript and RunPythonScript, but fails when I install the scripts as plugins.

The I have debugged the issue to the specific line where I split edge:

flag = meshTopologyEdgeList.SplitEdge(edgeTopoIndex, splitPercentage)

When run from RunPythonScript, this correctly splits the edge, the meshTopologyEdgeList.Count increases by 2, as expected, and the flag returns True. However, when it is run directly from the command line as an installed plug in, the method returns True, but nothing has been changed with the meshTopologyEdgeList, and the mesh is not successfully split.

To make getting help more complicated, we run Rhino on computers not connected to internet, so I have had to manually retype the entire code here. Assuming no typos, it should all be here, but I have not been able to verify if it is identical yet. But I was hoping that someone could take a look and determine if I am missing something or if I have found a bug.

My version of Rhino is 8.9.24194.18121

Thanks,
Isaac

mesh_rhino_script.py (3.5 KB)
split_command.rhi (1.5 KB)

@eirannejad - is this something you can help with?

@Isaac_Murrin There was loads of typos in the script and I managed to fix a few. Not sure what meshTopologyEdges is on line 99 meshTopologyEdgeList = meshTopologyEdges:

See my changes here

import rhinoscriptsyntax as rs
import Rhino as rhino
import scriptcontext as sc

__commandname__ = "SplitMeshLarge"


def RunCommand(is_interactive):
    curr_doc = sc.doc

    filter = rhino.DocObjects.ObjectType.Mesh
    rc, objrefs = rhino.Input.RhinoGet.GetMultipleObjects(
        "Select Meshs to split", False, filter
    )

    for objref in objrefs:
        mesh = objref.Mesh()
        if mesh.IsClosed:
            print("Your Mesh is already closed")
            return
        mesh.DuplicateMesh()
        mesh.Vertices.CombineIdentical(True, True)
        curr_doc.Objects.Replace(objref, mesh)

        meshTopologyEdgeList = mesh.TopologyEdges
        meshTopologyVertexList = mesh.TopologyVertices
        verticesNakedDict = mesh.GetNakedEdgePointStatus()
        nakedEdges = []
        nakedEdgePoints = []
        nakedEdgeLengths = []

        for i in range(meshTopologyEdgeList.Count):
            pairVertices = meshTopologyEdgeList.GetTopologyVertices(i)
            index1 = pairVertices[0]
            index2 = pairVertices[1]
            if verticesNakedDict[index1] and verticesNakedDict[index2]:
                pt1 = mesh.Vertices[index1]
                pt2 = mesh.Vertices[index2]
                nakedEdgePoints.append([pt1, pt2])
                nakedEdges.append(i)
                line = rhino.Geometry.Line(pt1, pt2)
                nakedEdgeLengths.append(line.Length)
        ignoreVar, nakedEdges = zip(
            *sorted(zip(nakedEdgeLengths, nakedEdges), reverse=True)
        )
        ignoreVar, nakedEdgePoints = zip(
            *sorted(zip(nakedEdgeLengths, nakedEdgePoints), reverse=True)
        )
        for i in range(len(nakedEdges)):
            pairVertices = meshTopologyEdgeList.GetTopologyVertices(nakedEdges[i])
            testpt = nakedEdgePoints[i][0]
            for counter, vertex in enumerate(mesh.Vertices):
                if vertex == nakedEdgePoints[i][0]:
                    index1 = counter
                elif vertex == nakedEdgePoints[i][1]:
                    index2 = counter
        line = rhino.Geometry.Line(mesh.Vertices[index1], mesh.Vertices[index2])
        bb = line.BoundingBox
        rs.ZoomBoundingBox(bb)
        line_GUID = curr_doc.Objects.AddLine(line)
        rs.SelectObject(line_GUID)
        curr_doc.Views.Redraw()

        gi = rhino.Input.Custom.GetInteger()
        gi.SetCommandPrompt("How many times should we split this edge")
        gi.SetCommandPromptDefault("0")
        gi.SetDefaultInteger(0)
        gi.AddOption("Exit")
        gi.SetLowerLimit(0, False)
        gi.SetUpperLimit(9, False)
        get_gi = gi.Get()
        if gi.CommandResult() != rhino.Commands.Result.Success:
            curr_doc.Objects.Delete(line_GUID, True)
            return
        if get_gi == rhino.Input.GetResult.Number:
            curr_doc.Objects.Delete(line_GUID, True)
            numSplits = gi.Number()
        elif get_gi == rhino.Input.GetResult.Option:
            curr_doc.Objects.Delete(line_GUID, True)
            print("User exited")
            return

        if numSplits == 0:
            continue

        edgeTopoIndex = meshTopologyEdgeList.GetEdgeIndex(index1, index2)
        for j in range(numSplits):
            splitPercentage = (j + 1) / (numSplits + 1)
            edgeTopoIndex = meshTopologyEdgeList.GetEdgeIndex(index1, index2)
            print(meshTopologyEdgeList.Count)
            flag = meshTopologyEdgeList.SplitEdge(
                edgeTopoIndex, splitPercentage
            )  # THE ISSUE IS HERE!!
            print(meshTopologyEdgeList.Count)
            print(flag)
            curr_doc.Objects.Replace(objref, mesh)
            curr_doc.Views.Redraw()
            if flag != False:
                meshTopologyEdgeList = meshTopologyEdges
                old_index1 = index1
                index1 = mesh.Vertices.Count - 1
                verticesNakedDict = mesh.GetNakedEdgePointStatus()
                edgeTopoIndex = meshTopologyEdgeList.GetEdgeIndex(index1, index2)
            else:
                print("Script error")
                return
    curr_doc.Objects.Replace(objref, mesh)
    curr_doc.Views.Redraw()
    print("All done with naked Edges")


RunCommand(True)
2 Likes

Thank you for looking at it. that line should be

meshTopologyEdgeList = mesh.TopologyEdges

Also, after reviewing, I found that I misspelled Multiple in line 11.
The updated files should be here:

mesh_rhino_script.py (3.5 KB)
split_command.rhi (1.5 KB)