cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Create a class to handle unexpected dimension text placement.

Create a class to handle unexpected dimension text placement.

When I want to automate my drawings (and create dimensions using iLogic) I run into 3 issues:

  • With some default Inventor settings on, the x value of my placement point is ignored. They are always in the center of the dimension. (Which is something that I sometimes want...)
  • With some dimension style settings my dimension text will not be on the same height. Even if I use the same height in my text placement points! 
  • If my code throws an exception with in the block created by the Drawing.BeginManage() and Drawing.EndManage() then the Drawing.EndManage() is never executed.

I don't want my dimensions to look like this. 

JelteDeJong_0-1700737990167.png

I need quite some extra code generate dimensions to look like this.

JelteDeJong_1-1700738032499.png

 

I would like to propose a new class that solve all of these issues and save me some extra code. This class should have a property/method that will the appropriate inventor settings so I can choose if I want my dimension texts to be centered. It should set the styles settings in such a way that dimension text are vertically aligned. And last but not least it MUST return all settings back to default even if the rule crashes. Therefore the class should implement the IDisposable interface. That way we can use the "Using" functionality of .Net and a try/catch/finally Block will be implemented automatically. Then this class could also replace the Drawing.BeginManage() and Drawing.EndManage() because we can be sure that the Drawing.EndManage() is called if it's the implemented in the dispose() method.

 

This is how I implemented this class. (Maybe another name for the class might be better but you will get the idea.)

Public Class DrawingComponentManager
    Implements IDisposable

    Private _drawing As IManagedDrawing
    Private _inventor As Inventor.InventorServer
    Private _style As DimensionStyle

    Private _center As Boolean
    Private _horizontalOrientation As DimensionTextOrientationEnum
    Private _alignedOrientation As DimensionTextOrientationEnum
    Private _verticalOrientation As DimensionTextOrientationEnum

    Public Sub New(drawing As IManagedDrawing)
        _drawing = drawing
        _inventor = drawing.NativeEntity.Parent
        _style = drawing.Document.StylesManager.ActiveStandardStyle.ActiveObjectDefaults.LinearDimensionStyle

        _center = _inventor.DrawingOptions.CenterDimensionText
        _horizontalOrientation = _style.HorizontalDimensionTextOrientation
        _alignedOrientation = _style.AlignedDimensionTextOrientation
        _verticalOrientation = _style.VerticalDimensionTextOrientation

        _drawing.BeginManage()
        _style.HorizontalDimensionTextOrientation = DimensionTextOrientationEnum.kInlineHorizontalDimensionText
        _style.AlignedDimensionTextOrientation = DimensionTextOrientationEnum.kInlineAlignedDimensionText
        _style.VerticalDimensionTextOrientation = DimensionTextOrientationEnum.kInlineHorizontalDimensionText
    End Sub

    Public WriteOnly Property CenterDimensionText() As Boolean
        Set(ByVal value As Boolean)
            _inventor.DrawingOptions.CenterDimensionText = value
        End Set
    End Property

    Public Sub Dispose() Implements IDisposable.Dispose
        _drawing.EndManage()
        _inventor.DrawingOptions.CenterDimensionText = _center
        _style.HorizontalDimensionTextOrientation = _horizontalOrientation
        _style.AlignedDimensionTextOrientation = _alignedOrientation
        _style.VerticalDimensionTextOrientation = _verticalOrientation
    End Sub
End Class

This is a follow up on this post: Unexpected dimension text place

5 Comments
JelteDeJong
Mentor

This is an example on how the new class could be used.

 

Public Sub Main()
	Dim Sheet_1 = ThisDrawing.Sheets.ItemByName("Sheet:1")
	Dim VIEW1 = Sheet_1.DrawingViews.ItemByName("VIEW1")
	Dim dimensions = Sheet_1.DrawingDimensions.GeneralDimensions

	' Get all intents
	Dim legIntent1 = VIEW1.GetIntent("LegMount1", PointIntentEnum.kMidPointIntent)
	Dim legIntent2 = VIEW1.GetIntent("LegMount2", PointIntentEnum.kMidPointIntent)
	Dim legIntent3 = VIEW1.GetIntent("LegMount3", PointIntentEnum.kMidPointIntent)
	Dim sideIntent1 = VIEW1.GetIntent("side1", Nothing)
	Dim sideIntent2 = VIEW1.GetIntent("side2", Nothing)
	
	' Setup default values
	Dim y1 = -0.3
	Dim horizontalDimType = DimensionTypeEnum.kHorizontalDimensionType
	
	Using manager As New DrawingComponentManager(ThisDrawing)
		' Placement logic
		manager.CenterDimensionText = False
		dimensions.AddLinear("Mounting point1", VIEW1.SheetPoint(-0.07, y1), sideIntent1, legIntent1)
		dimensions.AddLinear("Mounting point2", VIEW1.SheetPoint(1.07, y1), legIntent3, sideIntent2)
		
		manager.CenterDimensionText = True
		dimensions.AddLinear("LegMountDim1", VIEW1.SheetPoint(0.5, y1), legIntent1, legIntent2, horizontalDimType)	
		dimensions.AddLinear("LegMountDim2", VIEW1.SheetPoint(0.5, y1), legIntent2, legIntent3, horizontalDimType)
	End Using
End Sub

 

Yijiang.Cai
Autodesk
Status changed to: Future Consideration

Many thanks for posting the idea to us, and tracked as [INVGEN-76412] for future consideration.

MjDeck
Autodesk

@JelteDeJong , we chose not to call EndManage when the rule ends with an error. (Even though the EndManage statement in the rule will not be hit in this case, we could have added logic to call it after the rule exits.) But we didn't do it because we expect users to resolve the error and run the rule again. We don't want to delete managed entities when we know that the rule has not completed.

Can you provide some details about why you want to call EndManage when the rule ends with an error?

JelteDeJong
Mentor

The main reason for this class is to solve the issue of "unexpected dimension text placement". When I finished the class I ended up writing rules like this:

 

ThisDrawing.BeginManage()
Using manager As New DrawingComponentManager(ThisDrawing)
	
	' Placement logic
	
End Using
ThisDrawing.EndManage()

 

Not very elegant in my opinion to repeat the same (in different iLogic rules). Especially if both the DrawingComponentManager and the ThisDrawing.BeginManage() are managing dimensions.  So I did put them together. So the management part of the class is secondary. To be honest I did not think about your scenario. And I would like to call 'EndManage ' in the Dispose method pure for convenience.

But now thinking about: For me it would be fine if my managed entities were deleted because of an exception (that is still shown in an exception window and should be resolved). After fixing the rule my entities would get recreated anyway.

If Autodesk/you do not agree I would suggest keeping the 'BeginManage' in the constructor. But removing the 'EndManage' from the 'Dispose' method, and instead adding its own method in the DrawingComponentManager. Something like this (see line 51...53):

 

Public Class ThisRule
	Public Sub main()

        Using manager As New DrawingComponentManager(ThisDrawing)

            ' Placement logic

            Throw New Exception("Some exception")

            ' This will never run!
            manager.EndManage()
        End Using
    End Sub

End Class

Public Class DrawingComponentManager
    Implements IDisposable

    Private _drawing As IManagedDrawing
    Private _inventor As Inventor.Application
    Private _style As DimensionStyle

    Private _center As Boolean
    Private _horizontalOrientation As DimensionTextOrientationEnum
    Private _alignedOrientation As DimensionTextOrientationEnum
    Private _verticalOrientation As DimensionTextOrientationEnum

    Public Sub New(drawing As IManagedDrawing)
        _drawing = drawing
        _inventor = drawing.NativeEntity.Parent
        _style = drawing.Document.StylesManager.ActiveStandardStyle.ActiveObjectDefaults.LinearDimensionStyle

        _center = _inventor.DrawingOptions.CenterDimensionText
        _horizontalOrientation = _style.HorizontalDimensionTextOrientation
        _alignedOrientation = _style.AlignedDimensionTextOrientation
        _verticalOrientation = _style.VerticalDimensionTextOrientation

        _drawing.BeginManage()
        _style.HorizontalDimensionTextOrientation = DimensionTextOrientationEnum.kInlineHorizontalDimensionText
        _style.AlignedDimensionTextOrientation = DimensionTextOrientationEnum.kInlineAlignedDimensionText
        _style.VerticalDimensionTextOrientation = DimensionTextOrientationEnum.kInlineHorizontalDimensionText
    End Sub

    Public WriteOnly Property CenterDimensionText() As Boolean
        Set(ByVal value As Boolean)
            _inventor.DrawingOptions.CenterDimensionText = value
        End Set
    End Property

	Public Sub EndManage()
		_drawing.EndManage()
	End Sub
    Public Sub Dispose() Implements IDisposable.Dispose
        _inventor.DrawingOptions.CenterDimensionText = _center
        _style.HorizontalDimensionTextOrientation = _horizontalOrientation
        _style.AlignedDimensionTextOrientation = _alignedOrientation
        _style.VerticalDimensionTextOrientation = _verticalOrientation
    End Sub
End Class

 

This will prevent calling the EndManage if a rule ends with an error but keep all the components managing in 1 neat class.

Although I prefer not having to call theEndManage so I can't forget it and it saves me 1 more line of code. At the ver low cost of 'deleted entities' if a rule ends with errors. If I get an error I have to fix it anyway.

MjDeck
Autodesk

Thanks. I think we can put EndManage in the Dispose() function.

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

Submit Idea