Breaking Drawing View-Based on the distance between holes

Breaking Drawing View-Based on the distance between holes

865966724
Contributor Contributor
705 Views
6 Replies
Message 1 of 7

Breaking Drawing View-Based on the distance between holes

865966724
Contributor
Contributor

Hi

I encountered a problem on how to identify hole positions and add break lines between holes,I am not proficient in code and I hope someone can help me.I tried to find the answer, but it seemed more complicated than I had imagined,The attachment is my question

 

the example like this.

20231219190856.jpg

0 Likes
Accepted solutions (1)
706 Views
6 Replies
Replies (6)
Message 2 of 7

J-Camper
Advisor
Advisor
Accepted solution

@865966724,

 

There are a lot of factors to account for, like:

  • is it a vertical or horizontal array
  • were the centermarks added in order/at random
  • are there centermarks to avoid

Just to name a few.  I wrote something that works for the test case you provided:

Sub Main
	
	Dim dDoc As DrawingDocument = TryCast(ThisApplication.ActiveDocument, DrawingDocument)
	If IsNothing(dDoc) Then Logger.Debug("Not Run In Drawing Document") : Exit Sub
UserPicks:	
	Dim PickView As DrawingView = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingViewFilter, "Select a view to break")
	If IsNothing(PickView) Then Exit Sub ' If nothing gets selected then we're done
	
	If PickView.BreakOperations.Count > 0
		If MessageBox.Show("The selected view already has break operations.  Would you still like to attempt to break this view?", "Verify Breaks", MessageBoxButtons.YesNo) <> vbYes Then Exit Sub
	End If
	
	AddBreaksToViewBetweenCentermarks(PickView)
	
	GoTo UserPicks
	
End Sub

Sub AddBreaksToViewBetweenCentermarks(dView As DrawingView)
	
	Dim cmCollection As New List(Of Centermark)
	For Each cm As Centermark In dView.Parent.Centermarks
		If Not cm.Attached Then Continue For
		If Not cm.AttachedEntity.Geometry.Parent Is dView Then Continue For
		cmCollection.Add(cm)
	Next
	
	If cmCollection.Count < 1 Then Logger.Debug("No Centermarks collected") : Exit Sub
	
	Logger.Trace(cmCollection.Count & " Centermarks were selected")
	
	Dim BreakCount As Integer = 0
	
	While BreakCount < cmCollection.Count-1
		
		Call BreakBetweenCentermarks(dView, cmCollection.Item(BreakCount), cmCollection.Item(BreakCount+1))
		
		BreakCount += 1
	End While
	
End Sub

Sub BreakBetweenCentermarks(dView As DrawingView, cm1 As Centermark, cm2 As Centermark)
	
	Dim StartPoint, EndPoint As Point2d
	StartPoint = cm1.Position.Copy
	EndPoint = cm2.Position.Copy
	
	Dim breakoffset1, breakoffset2 As Double
	breakoffset1 = cm1.AttachedEntity.Geometry.Segments.Item(1).Geometry.Radius * 2
	breakoffset2 = cm2.AttachedEntity.Geometry.Segments.Item(1).Geometry.Radius * 2
		
	Dim offsetVector1, offsetVector2 As Vector2d
	offsetVector1 = StartPoint.VectorTo(EndPoint).AsUnitVector.AsVector
	offsetVector2 = EndPoint.VectorTo(StartPoint).AsUnitVector.AsVector
	offsetVector1.ScaleBy(breakoffset1)
	offsetVector2.ScaleBy(breakoffset2)
	
	StartPoint.TranslateBy(offsetVector1)
	EndPoint.TranslateBy(offsetVector2)
	
	Dim Gap As Double = .6 'cm
	Dim PropegateToParentView As Boolean = False
	
	dView.BreakOperations.Add(BreakOrientationEnum.kHorizontalBreakOrientation, StartPoint, EndPoint, BreakStyleEnum.kStructuralBreakStyle, , Gap, , PropegateToParentView)
	
End Sub

 

It is not going to work for all scenarios, but it should serve as a good starting point for you.  Let me know if you have any questions.

0 Likes
Message 3 of 7

865966724
Contributor
Contributor

Thank you very much for your help. With your help, I successfully completed the code using ChatGPT. Although this has met my requirements, I still have a question: how should I remove the steps of human-computer interaction until all the holes have added fracture lines between them. Simply put, what I mean is to add a break line between all the holes. Looking forward to your reply.

Imports System.Runtime.InteropServices
Sub Main
    ' Attempt to cast the active document to a drawing document object
    Dim dDoc As DrawingDocument = TryCast(ThisApplication.ActiveDocument, DrawingDocument)
    ' If the active document is not a drawing document, log debug info and exit the subroutine
    If IsNothing(dDoc) Then Logger.Debug("Not Run In Drawing Document") : Exit Sub

    ' Prompt the user to select a drawing view, exit the subroutine if none is selected
    Dim PickView As DrawingView = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingViewFilter, "Select a view to break")
    If IsNothing(PickView) Then Exit Sub

    ' If the selected view already has break operations, ask the user if they wish to continue
    If PickView.BreakOperations.Count > 0
        If MessageBox.Show("The selected view already has break operations. Would you still like to attempt to break this view?", "Verify Breaks", MessageBoxButtons.YesNo) <> vbYes Then Exit Sub
    End If

    ' Loop to add breaks until the user decides to stop
    Dim ContinueAdding As Boolean = True
    Do While ContinueAdding
        AddBreaksToViewBetweenCentermarks(PickView)

        ' Prompt the user if they want to continue
        ContinueAdding = MessageBox.Show("Do you want to continue adding breaks to the same view?", "Continue?", MessageBoxButtons.YesNo) = vbYes
    Loop
End Sub

Sub AddBreaksToViewBetweenCentermarks(dView As DrawingView)
    Dim cmCollection As New List(Of Centermark)
    For Each cm As Centermark In dView.Parent.Centermarks
        ' Ensure the centermark is attached to an entity
        If Not cm.Attached Then Continue For

        Try
            ' Check if the centermark's attached entity is part of the view we are dealing with
            If Not IsNothing(cm.AttachedEntity) AndAlso Not IsNothing(cm.AttachedEntity.Geometry) AndAlso Not IsNothing(cm.AttachedEntity.Geometry.Parent) AndAlso cm.AttachedEntity.Geometry.Parent Is dView Then
                cmCollection.Add(cm)
            End If
        Catch ex As COMException
            Logger.Error("COMException occurred: " & ex.Message)
            Continue For
        End Try
    Next

    ' Sort the collected centermarks by their X-axis coordinates
    cmCollection.Sort(Function(a, b) a.Position.X.CompareTo(b.Position.X))

    ' If less than two centermarks are collected, we cannot add breaks
    If cmCollection.Count < 2 Then
        Logger.Debug("Not enough Centermarks collected for breaking the view.")
        Exit Sub
    End If

    ' Log the number of centermarks collected
    Logger.Trace(cmCollection.Count & " Centermarks were collected after sorting.")

    ' Start adding breaks
    Dim BreakCount As Integer = 0
    ' Loop until the second to last centermark in the list
    While BreakCount < cmCollection.Count - 1
        ' Call the method to add a break between two centermarks
        BreakBetweenCentermarks(dView, cmCollection.Item(BreakCount), cmCollection.Item(BreakCount + 1))
        ' Move to the next pair of centermarks
        BreakCount += 1
    End While
End Sub
Sub BreakBetweenCentermarks(dView As DrawingView, cm1 As Centermark, cm2 As Centermark)
    Try
        ' Ensure incoming objects are not null
        If IsNothing(dView) OrElse IsNothing(cm1) OrElse IsNothing(cm2) Then
            Logger.Debug("dView, cm1, or cm2 is Nothing")
            Exit Sub
        End If

        ' Check if cm1 and cm2's AttachedEntity and Geometry are valid
        If IsNothing(cm1.AttachedEntity) OrElse IsNothing(cm1.AttachedEntity.Geometry) OrElse IsNothing(cm2.AttachedEntity) OrElse IsNothing(cm2.AttachedEntity.Geometry) Then
            Logger.Debug("One of the centermarks' attached entities or geometries is Nothing")
            Exit Sub
        End If

        ' Check if there are enough elements in the Segments collection
        If cm1.AttachedEntity.Geometry.Segments.Count < 1 OrElse cm2.AttachedEntity.Geometry.Segments.Count < 1 Then
            Logger.Debug("One of the geometries does not have enough segments")
            Exit Sub
        End If

        Dim StartPoint, EndPoint As Point2d
        StartPoint = cm1.Position.Copy
        EndPoint = cm2.Position.Copy

        ' Assuming the first item in Segment exists and has a Radius property
        Dim breakoffset1, breakoffset2 As Double
        breakoffset1 = cm1.AttachedEntity.Geometry.Segments.Item(1).Geometry.Radius * 10
        breakoffset2 = cm2.AttachedEntity.Geometry.Segments.Item(1).Geometry.Radius * 10

        Dim offsetVector1, offsetVector2 As Vector2d
        offsetVector1 = StartPoint.VectorTo(EndPoint).AsUnitVector.AsVector
        offsetVector2 = EndPoint.VectorTo(StartPoint).AsUnitVector.AsVector
        offsetVector1.ScaleBy(breakoffset1)
        offsetVector2.ScaleBy(breakoffset2)

        StartPoint.TranslateBy(offsetVector1)
        EndPoint.TranslateBy(offsetVector2)

        Dim Gap As Double = .1 'cm
        Dim PropegateToParentView As Boolean = False

        dView.BreakOperations.Add(BreakOrientationEnum.kHorizontalBreakOrientation, StartPoint, EndPoint, BreakStyleEnum.kStructuralBreakStyle, , Gap, , PropegateToParentView)

    Catch ex As Exception
        Logger.Error("Error in BreakBetweenCentermarks: " & ex.Message)
    End Try
End Sub

 

0 Likes
Message 4 of 7

J-Camper
Advisor
Advisor

@865966724,

 

I'm not really sure what you are asking.  Can you explain what part of the workflow you want to change?  From what I see this is what happens:

  1. You select a view to add breaks
  2. Then you call for breaks to be added inside a while loop
    1. I think this while loop should not be here.  In my original code I use a GoTo jump back up to User Selecting a view.  The way it is written now it will add all the breaks to a single view and then ask if you want to add more breaks to that same view, but that would cause errors.  You while block would need to include the user picking a different view to add breaks to.
  3. The rest of the rule operates the same as the code I posted with the exceptions of more error catch blocks and a sorting function for the centermarks list.  This means all the centermarks will get a break line between them until the collection is empty.
  4. At this point it returns back to the main sub inside the while loop and asks the user if they want to add more break lines to the currently selected view. [I already explained why this is not what you want to do]

 

I'm not sure if my thoughts above will help you or not, but I will try to help further if I can understand the questions asked.

0 Likes
Message 5 of 7

865966724
Contributor
Contributor

I think I understand now. Let me provide an overview of the entire process. After you answered this question, I tried using the code you provided and it reported this error. I think this is what I wanted from the beginning. It's just that this code is reporting an error.You don't need to pay attention to the code I sent, and then thank you again

 

System.Runtime.InteropServices.COMException (0x80004005): Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))
   at Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
   at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
   at ThisRule.BreakBetweenCentermarks(DrawingView dView, Centermark cm1, Centermark cm2)
   at ThisRule.AddBreaksToViewBetweenCentermarks(DrawingView dView)
   at ThisRule.Main()
   at Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
   at iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

 

0 Likes
Message 6 of 7

cadEY2BL
Explorer
Explorer

Hello Guys,

 

Is it possible to provide the last working code? With me it's not working when i click a view. 

 

0 Likes
Message 7 of 7

865966724
Contributor
Contributor

hi, This code needs to add the centerline to the hole and then run the code.

0 Likes