What I'm working with:
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.
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.
I tried looking into the API for solutions to keep the dimensions in relative position, such as one of these enums
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.
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.