Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Dimensions flipping sides

1 REPLY 1
Reply
Message 1 of 2
HogueOne
186 Views, 1 Reply

Dimensions flipping sides

What I'm working with:

HogueOne_1-1725382996682.png

 

I have a script that basically looks for this flat pattern view and positions it on the sheet with breaks and buffers the user specifies.

 

HogueOne_0-1725382932897.png

 

The first time its performed works decently enough. after I run it I need to call a different rule I'm using to rearrange the dimensions, but the dimensions only rearrange correctly if they are already on the correct side of the model view, which in this case is the top and the left. If I run the script again, one of the dimensions gets flipped to the other side, depending one which break view is commanded to be performed first.

 

HogueOne_3-1725383790915.png

 

I tried looking into the API for solutions to keep the dimensions in relative position, such as one of these enums

  • kMaintainAllTextAlignment 55555 All dimension text is updated to maintain relative position.
  • kMaintainCenteredTextAlignment 55554 Dimension text is updated to stay centered.
  • kMaintainViewPositionAlignment 55553 Dimension text is fixed relative to the first anchor point.

But I'm not sure how to use them, and I don't even know if they're relevant. so here's the big question:


How do I get dimensions to stay on the side they were before a view update?

or,

How do I get dimensions to keep their relative position after a view update?

 

here's the codes I'm working with:

AddReference "System.Windows.Forms"
AddReference "System.Drawing"

Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports Inventor
Imports Point = System.Drawing.Point
Imports WinForms = System.Windows.Forms
Imports System.Runtime.InteropServices
Public Class ArrangeViews
    Inherits Form

    Private WithEvents keepOnTopTimer As Timer

    <DllImport("user32.dll")>
    Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean
    End Function

    ' Constants for window positioning
    Private Const HWND_TOPMOST As Integer = -1
    Private Const SWP_NOMOVE As Integer = &H2
    Private Const SWP_NOSIZE As Integer = &H1

    ' Constants for attribute names
    Private Const ATTRIBUTE_SET_NAME As String = "ArrangeViewsSettings"
    Private Const WINDOW_LEFT_ATTR As String = "ArrangeViewsWindowLeft"
    Private Const WINDOW_TOP_ATTR As String = "ArrangeViewsWindowTop"
    Private Const WINDOW_WIDTH_ATTR As String = "ArrangeViewsWindowWidth"
    Private Const WINDOW_HEIGHT_ATTR As String = "ArrangeViewsWindowHeight"

    ' Constants for easy adjustment
    Private Const MAX_VERTICAL_GAP As Double = 12.0
    Private Const MAX_HORIZONTAL_GAP As Double = 18.0
    Private Const SLIDER_STEP As Double = 0.25
    Private Const MIN_WINDOW_WIDTH As Integer = 400
    Private Const MIN_WINDOW_HEIGHT As Integer = 420

    ' Individual min and max constants for each slider
    Private Const TOP_GAP_MIN As Double = 1.0
    Private Const TOP_GAP_MAX As Double = 10.0
    Private Const BOTTOM_GAP_MIN As Double = 0.5
    Private Const BOTTOM_GAP_MAX As Double = 5.0
    Private Const LEFT_GAP_MIN As Double = 1.0
    Private Const LEFT_GAP_MAX As Double = 15.0
    Private Const RIGHT_GAP_MIN As Double = 1.0
    Private Const RIGHT_GAP_MAX As Double = 15.0

    ' Default values
    Private Const DEFAULT_TOP_GAP_CM As Double = 3.0
    Private Const DEFAULT_BOTTOM_GAP_CM As Double = 1.5
    Private Const DEFAULT_RIGHT_GAP_CM As Double = 7.0
    Private Const DEFAULT_LEFT_GAP_CM As Double = 10.0

    Private sliders As WinForms.TrackBar()
    Private textBoxes As WinForms.TextBox()
    Private labels As WinForms.Label()
    Private statusStrip As statusStrip
    Private statusLabel As ToolStripStatusLabel
    Private progressBar As ToolStripProgressBar

    Private oApp As Inventor.Application
    Private oDrawDoc As DrawingDocument
    Private oSheet As Sheet
    Private oDrawingView As DrawingView
    Private tg As TransientGeometry

	Public Sub New(app As Inventor.Application)
	    InitializeComponent()
	    oApp = app
	    oDrawDoc = oApp.ActiveDocument
	    oSheet = oDrawDoc.ActiveSheet
	    tg = oApp.TransientGeometry
	    LoadWindowSettings()
	    AddHandler Me.FormClosing, AddressOf ArrangeViews_FormClosing
	    
	    ' Set TopMost property to True
	    Me.TopMost = True
	End Sub

Private Sub InitializeComponent()
    Me.MinimumSize = New Size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
    Me.Size = New Size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
    Me.Text = "Arrange Views"
    Me.StartPosition = FormStartPosition.CenterScreen

    Dim toolStrip As New ToolStrip()
    Dim arrangeButton As New ToolStripButton("Arrange Views")
    AddHandler arrangeButton.Click, AddressOf ArrangeViews_Click
    toolStrip.Items.Add(arrangeButton)

    Dim helpButton As New ToolStripButton("Help")
    AddHandler helpButton.Click, AddressOf HelpButton_Click
    toolStrip.Items.Add(helpButton)

    Dim exitButton As New ToolStripButton("Exit")
    AddHandler exitButton.Click, AddressOf ExitButton_Click
    toolStrip.Items.Add(exitButton)

    Me.Controls.Add(toolStrip)

    sliders = New WinForms.TrackBar(3) {}
    textBoxes = New WinForms.TextBox(3) {}
    labels = New WinForms.Label(3) {}

    Dim sliderTitles() As String = {"Top Gap", "Bottom Gap", "Left Gap", "Right Gap"}
    Dim defaultValues() As Double = {DEFAULT_TOP_GAP_CM, DEFAULT_BOTTOM_GAP_CM, DEFAULT_LEFT_GAP_CM, DEFAULT_RIGHT_GAP_CM}
    Dim minValues() As Double = {TOP_GAP_MIN, BOTTOM_GAP_MIN, LEFT_GAP_MIN, RIGHT_GAP_MIN}
    Dim maxValues() As Double = {TOP_GAP_MAX, BOTTOM_GAP_MAX, LEFT_GAP_MAX, RIGHT_GAP_MAX}

    For i As Integer = 0 To 3
        labels(i) = New WinForms.Label()
        labels(i).Text = sliderTitles(i)
        labels(i).Location = New Point(20, 50 + i * 70 + If(i > 1, 20, 0))
        labels(i).AutoSize = True
        Me.Controls.Add(labels(i))

        sliders(i) = New WinForms.TrackBar()
        sliders(i).Location = New Point(20, 70 + i * 70 + If(i > 1, 20, 0))
        sliders(i).Size = New Size(200, 45)
        sliders(i).Minimum = CInt(minValues(i) * (1 / SLIDER_STEP))
        sliders(i).Maximum = CInt(maxValues(i) * (1 / SLIDER_STEP))
        sliders(i).TickFrequency = 1
        sliders(i).Value = CInt(defaultValues(i) * (1 / SLIDER_STEP))
        AddHandler sliders(i).Scroll, AddressOf Slider_Scroll
        Me.Controls.Add(sliders(i))

        textBoxes(i) = New WinForms.TextBox()
        textBoxes(i).Location = New Point(230, 70 + i * 70 + If(i > 1, 20, 0))
        textBoxes(i).Size = New Size(50, 20)
        textBoxes(i).Text = defaultValues(i).ToString("F2")
        AddHandler textBoxes(i).TextChanged, AddressOf TextBox_TextChanged
        Me.Controls.Add(textBoxes(i))
    Next

    Dim divider As New WinForms.Label()
    divider.AutoSize = False
    divider.Size = New Size(MIN_WINDOW_WIDTH - 40, 2)
    divider.Location = New Point(20, 190)
    divider.BorderStyle = BorderStyle.Fixed3D
    Me.Controls.Add(divider)

    statusStrip = New StatusStrip()
    statusStrip.SizingGrip = False
    
    statusLabel = New ToolStripStatusLabel("Ready")
    statusLabel.Spring = True
    statusLabel.TextAlign = ContentAlignment.MiddleLeft
    statusStrip.Items.Add(statusLabel)

    progressBar = New ToolStripProgressBar()
    progressBar.Width = 100
    statusStrip.Items.Add(progressBar)

    Me.Controls.Add(statusStrip)
End Sub


    Private Sub LoadWindowSettings()
        Dim Left As Integer = GetDocumentAttribute(WINDOW_LEFT_ATTR, Me.Left)
        Dim Top As Integer = GetDocumentAttribute(WINDOW_TOP_ATTR, Me.Top)
        Dim Width As Integer = GetDocumentAttribute(WINDOW_WIDTH_ATTR, Me.Width)
        Dim Height As Integer = GetDocumentAttribute(WINDOW_HEIGHT_ATTR, Me.Height)

        If Left <> 0 Or Top <> 0 Then
            Me.StartPosition = FormStartPosition.Manual
            Me.Left = Left
            Me.Top = Top
            Me.Width = Width
            Me.Height = Height
        End If
    End Sub

    Private Function GetDocumentAttribute(attrName As String, defaultValue As Integer) As Integer
        Dim oAttribSets As AttributeSets = oDrawDoc.AttributeSets

        If oAttribSets.NameIsUsed(ATTRIBUTE_SET_NAME) Then
            Dim oAttribSet As AttributeSet = oAttribSets.Item(ATTRIBUTE_SET_NAME)
            If oAttribSet.NameIsUsed(attrName) Then
                Return CInt(oAttribSet.Item(attrName).Value)
            End If
        End If

        Return defaultValue
    End Function

Private Sub ArrangeViews_FormClosing(sender As Object, E As FormClosingEventArgs)
    SaveWindowSettings()
End Sub

    Private Sub SaveWindowSettings()
        Try
            SetDocumentAttribute(WINDOW_LEFT_ATTR, Me.Left)
            SetDocumentAttribute(WINDOW_TOP_ATTR, Me.Top)
            SetDocumentAttribute(WINDOW_WIDTH_ATTR, Me.Width)
            SetDocumentAttribute(WINDOW_HEIGHT_ATTR, Me.Height)
            oDrawDoc.Save()
        Catch ex As Exception
            MessageBox.Show("Failed to save window settings: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    Private Sub SetDocumentAttribute(attrName As String, value As Integer)
        Dim oAttribSets As AttributeSets = oDrawDoc.AttributeSets
        Dim oAttribSet As AttributeSet

        If Not oAttribSets.NameIsUsed(ATTRIBUTE_SET_NAME) Then
            oAttribSet = oAttribSets.Add(ATTRIBUTE_SET_NAME)
        Else
            oAttribSet = oAttribSets.Item(ATTRIBUTE_SET_NAME)
        End If

        If oAttribSet.NameIsUsed(attrName) Then
            oAttribSet.Item(attrName).Value = value
        Else
            oAttribSet.Add(attrName, ValueTypeEnum.kIntegerType, value)
        End If
    End Sub

    Private Sub Slider_Scroll(sender As Object, e As EventArgs)
        Dim slider As WinForms.TrackBar = DirectCast(sender, WinForms.TrackBar)
        Dim index As Integer = Array.IndexOf(sliders, slider)
        Dim value As Double = slider.Value * SLIDER_STEP
        textBoxes(index).Text = value.ToString("F2")

        If index <= 1 Then
            ApplyVerticalConstraints(index)
        Else
            ApplyHorizontalConstraints(index)
        End If
    End Sub

    Private Sub TextBox_TextChanged(sender As Object, e As EventArgs)
        Dim textBox As WinForms.TextBox = DirectCast(sender, WinForms.TextBox)
        Dim index As Integer = Array.IndexOf(textBoxes, textBox)
        Dim value As Double

        Dim minValue As Double = GetSliderMinValue(index)
        Dim maxValue As Double = GetSliderMaxValue(index)

        If Double.TryParse(textBox.Text, value) AndAlso value >= minValue AndAlso value <= maxValue Then
            sliders(index).Value = CInt(value * (1 / SLIDER_STEP))

            If index <= 1 Then
                ApplyVerticalConstraints(index)
            Else
                ApplyHorizontalConstraints(index)
            End If
        End If
    End Sub

    Private Sub ApplyVerticalConstraints(index As Integer)
        Dim otherIndex As Integer = If(index = 0, 1, 0)
        Dim total As Double = GetSliderValue(index) + GetSliderValue(otherIndex)
        If total > MAX_VERTICAL_GAP Then
            Dim newOtherValue As Double = Math.Max(GetSliderMinValue(otherIndex), MAX_VERTICAL_GAP - GetSliderValue(index))
            SetSliderValue(otherIndex, newOtherValue)
        End If
    End Sub

    Private Sub ApplyHorizontalConstraints(index As Integer)
        Dim otherIndex As Integer = If(index = 2, 3, 2)
        Dim total As Double = GetSliderValue(index) + GetSliderValue(otherIndex)
        If total > MAX_HORIZONTAL_GAP Then
            Dim newOtherValue As Double = Math.Max(GetSliderMinValue(otherIndex), MAX_HORIZONTAL_GAP - GetSliderValue(index))
            SetSliderValue(otherIndex, newOtherValue)
        End If
    End Sub

    Private Function GetSliderValue(index As Integer) As Double
        Return sliders(index).Value * SLIDER_STEP
    End Function

    Private Sub SetSliderValue(index As Integer, value As Double)
        sliders(index).Value = CInt(value * (1 / SLIDER_STEP))
        textBoxes(index).Text = value.ToString("F2")
    End Sub

    Private Function GetSliderMinValue(index As Integer) As Double
        Select Case index
            Case 0 : Return TOP_GAP_MIN
            Case 1 : Return BOTTOM_GAP_MIN
            Case 2 : Return LEFT_GAP_MIN
            Case 3 : Return RIGHT_GAP_MIN
            Case Else : Return 0
        End Select
    End Function

    Private Function GetSliderMaxValue(index As Integer) As Double
        Select Case index
            Case 0 : Return TOP_GAP_MAX
            Case 1 : Return BOTTOM_GAP_MAX
            Case 2 : Return LEFT_GAP_MAX
            Case 3 : Return RIGHT_GAP_MAX
            Case Else : Return 0
        End Select
    End Function

    Private Sub ArrangeViews_Click(sender As Object, E As EventArgs)
        If FindFlatPatternView() Then
            PerformArrangement()
        End If
    End Sub
	
	Private Function FindFlatPatternView() As Boolean
        oDrawingView = Nothing
        For Each oView As DrawingView In oSheet.DrawingViews
            If oView.IsFlatPatternView Then
                oDrawingView = oView
                Exit For
            End If
        Next

        If oDrawingView Is Nothing Then
            MessageBox.Show("No flat pattern view found on the active sheet.", "View Not Found")
            Return False
        End If

        Return True
    End Function
	
    Private Sub PerformArrangement()
        progressBar.Value = 0
        statusLabel.Text = "Arranging views..."

        UpdateProgress(0, "Removing existing breaks...")
        While oDrawingView.BreakOperations.Count > 0
            oDrawingView.BreakOperations.Item(1).Delete()
        End While

        UpdateProgress(25, "Applying vertical break...")
        ApplyBreak(True)

        UpdateProgress(50, "Applying horizontal break...")
        ApplyBreak(False)

        UpdateProgress(75, "Repositioning view...")
        RepositionView()

        UpdateProgress(100, "Views arranged successfully")
    End Sub
			
	Private Sub ApplyBreak(isVertical As Boolean)
        Dim sheetDimension As Double = If(isVertical, oSheet.Height, oSheet.Width)
        Dim viewDimension As Double = If(isVertical, oDrawingView.Height, oDrawingView.Width)
        Dim targetViewDimension As Double = sheetDimension - (GetSliderValue(If(isVertical, 0, 2)) + GetSliderValue(If(isVertical, 1, 3)))
        Dim breakLength As Double = viewDimension - targetViewDimension
            
        If breakLength <= 0 Then
            Dim message As String = String.Format("The view is already {0} than the target {1}. No {2} break needed.", _
                                                  If(isVertical, "shorter", "narrower"), _
                                                  If(isVertical, "height", "width"), _
                                                  If(isVertical, "vertical", "horizontal"))
            MessageBox.Show(message, "Information")
            Exit Sub
        End If

        Dim centerX As Double = oDrawingView.Center.X
        Dim centerY As Double = oDrawingView.Center.Y
        Dim halfBreak As Double = breakLength / 2
        Dim startPoint As Point2d
        Dim endPoint As Point2d

        If isVertical Then
            startPoint = tg.CreatePoint2d(centerX, centerY + halfBreak)
            endPoint = tg.CreatePoint2d(centerX, centerY - halfBreak)
        Else
            startPoint = tg.CreatePoint2d(centerX + halfBreak, centerY)
            endPoint = tg.CreatePoint2d(centerX - halfBreak, centerY)
        End If

        Try
            Dim breakOperation As BreakOperation = oDrawingView.BreakOperations.Add(
                If(isVertical, kVerticalBreakOrientation, kHorizontalBreakOrientation),
                startPoint, endPoint, kStructuralBreakStyle)
            If breakOperation Is Nothing Then
                Throw New Exception(String.Format("Failed to create {0} break operation.", If(isVertical, "vertical", "horizontal")))
            End If
        Catch ex As Exception
            MessageBox.Show(String.Format("Failed to create {0} break. Error: {1}", If(isVertical, "vertical", "horizontal"), ex.Message), "Error")
        End Try
    End Sub
	
	 Private Sub RepositionView()
        Dim viewHeight As Double = oDrawingView.Height
        Dim viewWidth As Double = oDrawingView.Width
        Dim newCenterY As Double = viewHeight / 2 + GetSliderValue(1)
        Dim newCenterX As Double = GetSliderValue(2) + viewWidth / 2
        Dim newCenter As Point2d = tg.CreatePoint2d(newCenterX, newCenterY)
        oDrawingView.Center = newCenter
    End Sub

    Private Sub UpdateProgress(value As Integer, Message As String)
        progressBar.Value = value
        statusLabel.Text = Message
        System.Windows.Forms.Application.DoEvents()
    End Sub

    Private Sub HelpButton_Click(sender As Object, e As EventArgs)
        MessageBox.Show("Help.", "Help")
    End Sub

    Private Sub ExitButton_Click(sender As Object, e As EventArgs)
        Me.Close()
    End Sub
End Class

Sub Main()
    Dim Form As New ArrangeViews(ThisApplication)
    Form.Show()
    iLogicVb.RunRule("Suspend")
End Sub

 

Here's a suspend rule that let's me do other things while the window is open:

Sub Main()
    ' This rule does nothing
    ' It's used to keep the form reference alive in iLogic
End Sub

 

and here's a rule I use to fix dimensions:


Sub Main()
    Dim oDoc As Document = ThisApplication.ActiveDocument
    Dim oTM As TransactionManager = ThisApplication.TransactionManager
    
    If TypeOf oDoc Is DrawingDocument Then
        Dim oDDoc As DrawingDocument = oDoc
        ThisApplication.CommandManager.ControlDefinitions.Item("AppZoomallCmd").Execute
        
        Dim oSheet As Sheet = oDoc.ActiveSheet
        Dim oDrawingDim As DrawingDimension 
        Dim oSelectSet As SelectSet = oDDoc.SelectSet
        oSelectSet.Clear()
        
        Dim newTM As Transaction = oTM.StartTransaction(oDDoc, "CenterAndAlignDimensions")
        
        ' Center dimensions
        For Each oDrawingDim In oSheet.DrawingDimensions
            If TypeOf oDrawingDim Is LinearGeneralDimension Or TypeOf oDrawingDim Is AngularGeneralDimension Then
                Call oDrawingDim.CenterText
            End If
        Next
        
        ' Select dimensions for alignment
        For Each oDrawingDim In oSheet.DrawingDimensions
            If TypeOf oDrawingDim Is LinearGeneralDimension Or TypeOf oDrawingDim Is AngularGeneralDimension Then
                oSelectSet.Select(oDrawingDim)
            End If
        Next
        
        ' Align dimensions
        Call ThisApplication.CommandManager.ControlDefinitions.Item("DrawingArrangeDimensionsCmd").Execute
        
        oSelectSet.Clear()
        newTM.End()
    End If        
End Sub

 

Any help would be greatly appreciated.

Labels (6)
1 REPLY 1
Message 2 of 2
daltonNYAW9
in reply to: HogueOne

Have you tried using "DrawingDimensions.Arrange" instead of the ribbon button?
Haven't tried it, but it gives an option for a point on the sheet.

https://help.autodesk.com/view/INVNTOR/2024/ENU/?guid=DrawingDimensions_Arrange

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report