BatchDeleteHoles

Hi,everyone. I have trouble problem in my project. I hope you can give me some suggestion.
In my Model There many hole on the column. and Some hole is wrong, and I know where are the wrong holes in every column. and I must delete this holes, There are hundreds holes that should be deleted. I can stand to delete them one by one using mouse click. I can wite gha, and rhp and all the script. While I find no sdk,no slutions to this. Maybe I need crack the rhcommon_c.dll to see if any functions can be used to this. I also have read the opennurbs C code for how we create a brep. still, I find nothing to solve this. Help me, @dale @stevebaer @DavidRutten @mary
and below is the code I want to try release this by command line. but I failed,Because the script aways stoped after delete the first hole.God help me–

  Protected Overrides Sub RegisterInputParams(ByVal pManager As GH_Component.GH_InputParamManager)
            ' pManager.AddTextParameter("Guid", "Id", "将要被替换的犀牛物件" & vbCrLf & "(RhinoObjects that will be replaced)", GH_ParamAccess.item)
            'Dim guidParam As New Param_Guid
            pManager.AddParameter(New Param_Guid, "Guid", "Id", "要被删除孔的犀牛物件" & vbCrLf & "(RhinoObjects that will be Deleted holes)", GH_ParamAccess.item)
            pManager.AddPointParameter("HolePoint", "P", "孔位置的点" & vbCrLf & "(Point nearby hole)", GH_ParamAccess.list)
            pManager.AddBooleanParameter("Delete", "D", "如果是True则进行删除动作" & vbCrLf & "(If true Perform the Delete)", GH_ParamAccess.item, False)
        End Sub
        Protected Overrides Sub RegisterOutputParams(ByVal pManager As Kernel.GH_Component.GH_OutputParamManager)
            pManager.AddTextParameter("Result", "RG", "结果列表" & vbCrLf & "(Result)", GH_ParamAccess.list)
        End Sub

  Protected Overrides Sub SolveInstance(ByVal DA As Kernel.IGH_DataAccess)
            If Banner.astrict.showmessage Then Return
            Dim Ids As Guid = Guid.Empty
            'Dim Ids As String = String.Empty
            Dim Holept As New List(Of Point3d)
            Dim blDelete As Boolean = False
            If Not DA.GetData(0, Ids) Then Return
            If Not DA.GetDataList(1, Holept) Then Return
            If Not DA.GetData(2, blDelete) Then Return
            If Not blDelete Then
                GoTo line1
                Reslist.Add(Now & "_未替换!(Replace failed!)")
            Else
                Reslist.Clear()
                '  Grasshopper.Instances.ActiveCanvas.ModifiersEnabled = False
            End If
            ' rt.AddRange(docobjlist.Select(Function(geoobj As RhinoObject) GH_Convert.ObjRefToGeometry(New ObjRef(geoobj.Id))))
            'Private Checked(5) As Boolean, Namestr() As String = {"Point", "Curve", "Brep", "Mesh", "TextDot", "TextEntity"}
            Try
                Dim rh As RhinoDoc = Rhino.RhinoDoc.ActiveDoc
                ' Dim rhobj As RhinoObject = rh.Objects.Find(Ids)
                '   Dim rhobj As RhinoObject = rh.Objects.Find(New Guid(Ids))
                ' Dim bobj As BrepObject = CType(rhobj, BrepObject)
                ' RhinoApp.SendKeystrokes("Cancel", True)
                ' RhinoApp.SendKeystrokes("Cancel", True)
                '  bobj.Select(True)
                ' RhinoApp.RunScript("_SolidPtOn", False)
                '  Dim gobjs As GripObject() = bobj.GetGrips
                '   rh.Views.RedrawEnabled = False
                ' RhinoApp.RunScript("-_DeleteHole ", True)

                For Each worldpt As Point3d In Holept
                    Dim rvi As RhinoViewport = rh.Views.ActiveView.ActiveViewport
                    ' Dim cpt As Point2d = rvi.WorldToClient(worldpt)
                    '  Dim spt As Drawing.Point = rvi.ClientToScreen(cpt)
                    'If grpobj.CurrentLocation.DistanceTo(Holept) < tolar Then
                    '    grpobj.Select(True)
                    Dim pln As New Plane(worldpt, Vector3d.XAxis, Vector3d.YAxis)

                    rvi.SetConstructionPlane(pln)
                    '   RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport.SetToPlanView(worldpt, Vector3d.XAxis, Vector3d.YAxis, True)
                    '    Dim tropt As New Point3d(Holept), trtpt As New Point3d(tpt)
                    '    tropt.Transform(Transform.PlaneToPlane(Plane.WorldXY, CurrentPln))
                    '    trtpt.Transform(Transform.PlaneToPlane(Plane.WorldXY, CurrentPln))
                    '   Dim movestr As String = String.Format(" {0},{1},{2}", worldpt.X, worldpt.Y, worldpt.Z)
                    ' RhinoApp.SendKeystrokes("0", True)
                    '  RhinoApp.RunScript("-_DeleteHole 0", True)
                    '    RhinoApp.SendKeystrokes("-_DeleteHole 0 Cancel", True)
                    RhinoApp.SendKeystrokes("-_Untrim 0 Cancel", True)
                    ' Utilityfunction.Pause(5)
                    RhinoApp.SendKeystrokes("Cancel", True)
                    RhinoApp.SendKeystrokes("Cancel", True)
                    RhinoApp.SendKeystrokes("Enter", True)
                    RhinoApp.SendKeystrokes("Enter", True)

                    '  MsgBox("dd")
                    ' RhinoApp.RunScript("Enter", True)
                    '  MsgBox("ddd")

                    ' RhinoApp.RunScript("Cancel", True)
                    '  MsgBox("dddd")

                    ' RhinoApp.RunScript("0", True)
                    ' RhinoApp.RunScript("Cancel", True)
                    ' RhinoApp.SendKeystrokes("Cancel", True)

                    ' RhinoApp.RunScript(movestr, True)
                    '  grpobj.Select(False)
                    ' End If
                Next
                ' RhinoApp.RunScript("Enter", False)
                '   RhinoApp.SendKeystrokes("Cancel", True)

                ''  rh.Views.RedrawEnabled = True
                Reslist.Add(Now & "_替换成功!(Replace Success!)")
            Catch ex As Exception
                Reslist.Add(Now & "_替换失败!(Replace failed!)" & vbCrLf & ex.Message)
            End Try
            '    Grasshopper.Instances.ActiveCanvas.ModifiersEnabled = True

line1: DA.SetDataList(0, Reslist)
End Sub

Perhaps you can post your model and, in it, identify what is correct and what is not?

OK,Thank you for your replay dale,Below is the column model Test attach.
[http://www.grasshopper3d.com/forum/attachment/download?id=2985220%3AUploadedFile%3A13791471]


I really don’t know how to upload zip to this forum–
BatchDeleteHoleTest.zip (2.8 MB)

Just drag and drop into the message field.
(or use the upload button - a horizontal bar with an up-arrow - or use the short-cut Ctrl+G)

OH,Thank you wim script :grin:

@rajaa, it appears that the user is trying to access DeleteHole from Grasshopper. Any suggestions?

1 Like

Hi @huaxiamengqing haux
The is an “All” option in DeleteHole command. It should help you delete all the holes. Is that helpful?

Hi,dear rajaa.The command line doesn’t help. I can’t get the right code to batch delete holes. See my code, When it delete one hole, it stops- -. Can you trouble give some code to realize that? Thank you in advance!
I can’t use the “All” option,Because some right holes must be reserved. I just want to delete the wrong holes. There are many right holes in the same brep face.

@rajaa Not any good solution?

@dale No any solutions dear Dale?

Hi @huaxiamengqing
It was not clear to me from your code which holes you need to delete and what is the criteria to choose the holes.
The DeleteHole command in Rhino goes through individual faces, looks for holes (identify inner loops with all the faces that are connected to it), mark those, then delete and rebuild the brep. The code is a bit involved and is written in C++.
Can you please share your Script files (not just the code)? I’d like to run it at my end and see if I can debug it.

Hi,Dear @rajaa ,I don’t think Scripts is a good solution. It does not run well in gha SolveInstance. Can I use .net SDK to go through individual faces, looks for holes,mark those,delete and rebuild brep? Is there any interface to .net api? If not see the script below, help me to debug it. Thank you !
I Paste the code out, The code is same in attach.

Private Sub RunScript(ByVal Holept As List(Of Point3d), ByVal B As Boolean) 
If Not b Then Return
Dim rh As RhinoDoc = Me.RhinoDocument
For Each worldpt As Point3d In Holept
  Dim rvi As   Rhino.Display.RhinoViewport = rh.Views.ActiveView.ActiveViewport
  '  - ---'I can't figure out the relation of world ucs and the use of user click's Relation
  'So I used a way that build a ucs plane in the point where is the hole. and then we send
  ' (0,0,0) to delete hole command line--,it's not a smart way, Is not it?
  ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  ' Dim cpt As Point2d = rvi.WorldToClient(worldpt)
  '  Dim spt As Drawing.Point = rvi.ClientToScreen(cpt)
  'If grpobj.CurrentLocation.DistanceTo(Holept) < tolar Then
  ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  Dim pln As New Plane(worldpt, Vector3d.XAxis, Vector3d.YAxis)
  rvi.SetConstructionPlane(pln)
  RhinoApp.RunScript("-_DeleteHole 0", True)
  'Though I use so many cancel, It stops after delete one hole and I must use hand to ESC--
  RhinoApp.RunScript("Cancel", True)
  RhinoApp.RunScript("Cancel", True)
  RhinoApp.RunScript("Enter", True)
  RhinoApp.RunScript("Enter", True)


Next

End Sub
There are Two Problem exist.
Problem One: It Stop when the script delete one hole, I must use hand to Press “ESC” key to let the script run.
Problem Two:Some time the rhino can’t judge which point we input for click, It lets you to select to ensure where you click.
And I don’t want this case come out in the process of script running. see picture below if you can’t understand what is this case.

and the attach. Thank you in advance–
DeleteHoleScriptTest].rar (2.0 MB)

@huaxiamengqing can you send your plugin or file compressed as a zip? Feel free to email directly if you prefer.

Sorry,I forget you use ZIP. I can’t use email to send attach to you.I am in China,All the emails with attach are blocked by great wall–

BatchDeleteHoleTest.zip (2.8 MB)

@huaxiamengqing
The following script will work with your logic of marking each hole with a point.

Private Sub RunScript(ByVal Holept As List(Of Point3d), ByVal b As Boolean, ByRef A As Object)

If Not b Then Return

'get current view
Dim rh As RhinoDoc = Me.RhinoDocument
Dim rvi As   Rhino.Display.RhinoViewport = rh.Views.ActiveView.ActiveViewport
'get current construction plane
Dim c_pln = rvi.ConstructionPlane

For Each worldpt As Point3d In Holept
  Dim pln As New Plane(worldpt, Vector3d.XAxis, Vector3d.YAxis)
  rvi.SetConstructionPlane(pln)
  RhinoApp.RunScript("-_DeleteHole 0,0,0 _Pause _Enter", True)
Next

'set the construction plane back to what it was
rvi.SetConstructionPlane(c_pln)

End Sub

Great rajaa. _Pause is the key of this problem.
But the Problem Two in my quesion is not solved. Do you have any good idea?

I am not sure which problem you are referring to. Can you clarify?

OK,I have solved the problem by myslef. Thank for your reply