Rule to Set Origin indicator on Drawing View

Rule to Set Origin indicator on Drawing View

Mac_W
Contributor Contributor
1,803 Views
20 Replies
Message 1 of 21

Rule to Set Origin indicator on Drawing View

Mac_W
Contributor
Contributor

I am trying to set the origin indicator on a drawing view in an IDW file. The rule i wrote below works if the two lines actually intersect. The issue is when the lines come to a radius instead of a vertex. Is there a way to get the theoretical intersection? Alternatively could I get the x value of one line, the y value of the other, and combine them to a point that I can set the origin to? Any advice or help would be greatly appreciated, also open to any suggestions if there is a better way to set the origin indicator from the drawing view. 

 

 

Sub Main()

	'Get the active sheet
	Dim oSheet As Sheet = ThisApplication.ActiveDocument.ActiveSheet

	'Get the curves for intersection point
	Dim oCurve1 As DrawingCurve = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Pick first intersection curve").Parent
	Dim oCurve2 As DrawingCurve = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Pick second intersection curve").Parent
	
	'Create GeometryIntent for intersection
	Dim oIntersectionIntent As GeometryIntent = oSheet.CreateGeometryIntent(oCurve1, oCurve2)

	Dim oDrawingView As DrawingView = oCurve1.Parent
	
	'If origin indicator has Not been already created, create it first.
	If Not oDrawingView.HasOriginIndicator Then
	    MsgBox("no origin indicator")
	    oDrawingView.CreateOriginIndicator(oIntersectionIntent)
	Else
		 MsgBox("has origin indicator")
		oDrawingView.OriginIndicator.Intent = oIntersectionIntent
	End If

End Sub

 

0 Likes
Accepted solutions (1)
1,804 Views
20 Replies
Replies (20)
Message 2 of 21

Michael.Navara
Advisor
Advisor
Accepted solution

You need to create origin indicator somewhere on existing drawing curve, but you can move them relative from this position. Here si modified code

 

Sub Main()

    'Get active drawing document
    Dim drawing As DrawingDocument = ThisDoc.Document
    'Get the active sheet
    Dim oSheet As Sheet = drawing.ActiveSheet

    'Get the curves for intersection point
    Dim oCurve1 As DrawingCurve = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Pick first intersection curve").Parent
    Dim oCurve2 As DrawingCurve = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Pick second intersection curve").Parent

    'Create GeometryIntent for intersection
    Dim oIntersectionIntent As GeometryIntent = oSheet.CreateGeometryIntent(oCurve1, PointIntentEnum.kMidPointIntent)
    Dim intentPointOnSheet As Point2d = oIntersectionIntent.PointOnSheet

    'Get theoretical intersection point
    Dim lineSegment1 As LineSegment2d = oCurve1.Segments(1).Geometry
    Dim lineSegment2 As LineSegment2d = oCurve2.Segments(1).Geometry

    Dim line1 = ThisApplication.TransientGeometry.CreateLine2d(lineSegment1.StartPoint, lineSegment1.Direction)
    Dim line2 = ThisApplication.TransientGeometry.CreateLine2d(lineSegment2.StartPoint, lineSegment2.Direction)

    Dim intersectionPoint2d As Point2d = line1.IntersectWithCurve(line2)(1)
    Dim vectorToIntersection As Vector2d = intentPointOnSheet.VectorTo(intersectionPoint2d)


    'If origin indicator has Not been already created, create it first.
    Dim oDrawingView As DrawingView = oCurve1.Parent
    If Not oDrawingView.HasOriginIndicator Then
        MsgBox("no origin indicator")
        oDrawingView.CreateOriginIndicator(oIntersectionIntent)
    Else
        MsgBox("has origin indicator")
        oDrawingView.OriginIndicator.Intent = oIntersectionIntent
    End If

    'Move origin indicator to intersection point location
    oDrawingView.OriginIndicator.RelativeX = vectorToIntersection.X/oDrawingView.Scale
    oDrawingView.OriginIndicator.RelativeY = vectorToIntersection.Y/oDrawingView.Scale

End Sub

 

EDIT:

@Mac_W's update added to the code sample

 

Message 3 of 21

Mac_W
Contributor
Contributor

@Michael.Navara This works great, thank you! I changed lines 38 and 39 to work for drawing views of any scale. 

    oDrawingView.OriginIndicator.RelativeX = vectorToIntersection.X/oDrawingView.Scale
    oDrawingView.OriginIndicator.RelativeY = vectorToIntersection.Y/oDrawingView.Scale

 

Message 4 of 21

romu51
Advocate
Advocate

Hi, 

I've tried this rule and the origin symbol does not snap on the intersection. 

2 different parts and drawings return the same, ratio of 0.375 along the first picked line. 

romu51_0-1692258314281.png

romu51_1-1692258349791.png

 

0 Likes
Message 5 of 21

Mac_W
Contributor
Contributor

@romu51 did you add this to the end of line 38 and 39?

/oDrawingView.Scale

 What scale are the drawing views you tried?

Also what unit of measurement is your part model and drawing set to? If it's not a scaling issue then it might be possible there is a unit conversion issue, I think ilogic uses cm by default.

Message 6 of 21

romu51
Advocate
Advocate

ahhhhh it works now! Thanks. 

yes, scale was 1:4 for both views. 

unit is mm but it looks like the units would not affect the rule. 

nice rule! 

Message 7 of 21

ralfmja
Advocate
Advocate

Hi @Michael.Navara , 

 

I have question for this topic - maybe you can help me 🙂 

 

I have a view where I want to add an origin indicator without pointing to anything. I think you need to approach it in the following way:

 

Intersection.png

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

To find point A and B, we could use this rule,which finds the "left point" in the X and Y directions. (@JelteDeJong)

Could you show me the path and how to proceed to determine point C in ilogic ?

 

Thanks in advance,

Regards,

ralfmj

0 Likes
Message 8 of 21

WCrihfield
Mentor
Mentor

Hi @ralfmja.  That might be nearly impossible in some situations.  What if the view was of a round part (circle is outer edge of part)?  No amount of checking the X & Y positions of CenterPoint, StartPoint, EndPoint type points on DrawingCurves will give you an accurate minimum X, and minimum Y value you need for that lower left point.  The simplest, and quickest way (which is most likely also the least accurate) is to use the DrawingView.Left property to get the minumum X value.  Then use (DrawingView.Top - DrawingView.Height) to get the minimum Y value of the view.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 9 of 21

WCrihfield
Mentor
Mentor

Hi @ralfmja.  Here is an iLogic code example that should get the location for you (a Point2d), but there does not appear to be any good way to then create the GeometryIntent needed to create the origin indicator after that point.  A GeometryIntent needs something stable as its basis, not just transient geometry (math only).  And keep in mind that the coordinate values it writes to the iLogic Log window at the end are in 'database units', instead of 'document units', so you may need to convert them to whatever units you usually use.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then Exit Sub
	Dim oDDoc As DrawingDocument = ThisDoc.Document
	Dim oSheet As Inventor.Sheet = oDDoc.ActiveSheet
	Dim oView As DrawingView = Nothing
	Try : oView = oSheet.DrawingViews.Item(1) : Catch : End Try
	If oView Is Nothing Then Exit Sub
	Dim oMinPoint As Point2d = GetViewMinPoint(oView)
	If oMinPoint Is Nothing Then Exit Sub
	Logger.Info("oMinPoint.X = " & oMinPoint.X & vbCrLf & "oMinPoint.Y = " & oMinPoint.Y)
	'Dim oGI As GeometryIntent = oSheet.CreateGeometryIntent()
	'oView.CreateOriginIndicator(oGI)
End Sub

Function GetViewMinPoint(oView As DrawingView) As Point2d
	If oView Is Nothing Then Return Nothing
	Dim oDCE As DrawingCurvesEnumerator = Nothing
	Try : oDCE = oView.DrawingCurves : Catch : End Try
	If oDCE Is Nothing OrElse oDCE.Count = 0 Then Return Nothing
	Dim dMinPointX As Double = oView.Left + oView.Width
	Dim dMinPointY As Double = oView.Top
	For Each oDC As DrawingCurve In oDCE
		Dim dMinParam, dMaxParam As Double
		oDC.Evaluator2D.GetParamExtents(dMinParam, dMaxParam)
		Dim oParams() As Double = {dMinParam, dMaxParam}
		Dim oPointCoords() As Double = {}
		oDC.Evaluator2D.GetPointAtParam(oParams, oPointCoords)
		If oPointCoords(0) < dMinPointX Then dMinPointX = oPointCoords(0)
		If oPointCoords(1) < dMinPointY Then dMinPointY = oPointCoords(1)
	Next
	Dim oMinPoint As Point2d = ThisApplication.TransientGeometry.CreatePoint2d(dMinPointX, dMinPointY)
	Return oMinPoint
End Function

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 21

Mac_W
Contributor
Contributor

Hi @WCrihfield, I think in order to get the origin to the desired location you could get the intersection point of points A and B in @ralfmja's example which would be point C. Then get the vector from A or B to C. Then create your origin indicator on A or B, whichever you used to get the vector. Finally, set the relativeX and relativeY of the originIndicator to the vector / view.Scale. 

 

The code below is what I use now for finding profile dimensions. It doesn't set an origin but it does find profile points of curves and could maybe be modified to set the origin of parts with curved profiles. 

 

Public Class ThisRule
	Private _doc As DrawingDocument
    Private _sheet As Sheet
	Private _views As DrawingViews
    Private _intents As List(Of GeometryIntent) = New List(Of GeometryIntent)()

    Sub Main()
        _doc = ThisApplication.ActiveDocument
        _sheet = _doc.ActiveSheet
		_views = _sheet.DrawingViews
		
		For Each _view As DrawingView In _views
		
		_intents.Clear
        CreateIntentList(_view)
		
		Dim orderedIntentsX = _intents.OrderByDescending(Function(s) s.PointOnSheet.X)

		Dim pointLeft = orderedIntentsX.Last.PointOnSheet.x
        Dim pointRight = orderedIntentsX.First.PointOnSheet.x
		
		Dim orderedIntentsY = _intents.OrderByDescending(Function(s) s.PointOnSheet.Y)

		Dim pointBot = orderedIntentsY.Last.PointOnSheet.y
        Dim pointTop = orderedIntentsY.First.PointOnSheet.y
		
		Dim xDim As Double = Round(((pointRight - pointLeft)/_view.Scale)/2.54, 3)
		Dim yDim As Double = Round(((pointTop - pointBot)/_view.Scale)/2.54, 3)
		
		
		MsgBox("pointLeft: " & pointLeft & vbCrLf _
		& "pointRight: " & pointRight & vbCrLf _
		& "pointBot: " & pointBot & vbCrLf _
		& "pointTop: " & pointTop)
		
		MsgBox("X: " & xDim & vbCrLf _
		& "Y: " & yDim)
		Next
    End Sub
	
	Private Sub addIntent(Geometry As DrawingCurve, IntentPlace As Object, onLineCheck As Boolean)

        Dim intent As GeometryIntent = _sheet.CreateGeometryIntent(Geometry, IntentPlace)
        If intent.PointOnSheet Is Nothing Then Return

        If onLineCheck Then
            If (IntentIsOnCurve(intent)) Then
                _intents.Add(intent)
            End If
        Else
            _intents.Add(intent)
        End If
    End Sub

	Private Function IntentIsOnCurve(intent As GeometryIntent) As Boolean

	        Dim Geometry As DrawingCurve = intent.Geometry
	        Dim sp = intent.PointOnSheet

	        Dim pts(1) As Double
	        Dim gp() As Double = {}
	        Dim md() As Double = {}
	        Dim pm() As Double = {}
	        Dim st() As SolutionNatureEnum = {}
	        pts(0) = sp.X
	        pts(1) = sp.Y

	        Try
	            Geometry.Evaluator2D.GetParamAtPoint(pts, gp, md, pm, st)
	        Catch ex As Exception
	            Return False
	        End Try
	        Return True
	    End Function

	Private Sub CreateIntentList(_view As DrawingView)

	        For Each oDrawingCurve As DrawingCurve In _view.DrawingCurves
	            Select Case oDrawingCurve.ProjectedCurveType
	                Case _
	                        Curve2dTypeEnum.kCircleCurve2d,
	                        Curve2dTypeEnum.kCircularArcCurve2d,
	                        Curve2dTypeEnum.kEllipseFullCurve2d,
	                        Curve2dTypeEnum.kEllipticalArcCurve2d

	                    addIntent(oDrawingCurve, PointIntentEnum.kCircularTopPointIntent, True)
	                    addIntent(oDrawingCurve, PointIntentEnum.kCircularBottomPointIntent, True)
	                    addIntent(oDrawingCurve, PointIntentEnum.kCircularLeftPointIntent, True)
	                    addIntent(oDrawingCurve, PointIntentEnum.kCircularRightPointIntent, True)

	                    addIntent(oDrawingCurve, PointIntentEnum.kEndPointIntent, False)
	                    addIntent(oDrawingCurve, PointIntentEnum.kStartPointIntent, False)

	                Case _
	                        Curve2dTypeEnum.kLineCurve2d,
	                        Curve2dTypeEnum.kLineSegmentCurve2d

	                    addIntent(oDrawingCurve, PointIntentEnum.kEndPointIntent, False)
	                    addIntent(oDrawingCurve, PointIntentEnum.kStartPointIntent, False)

	                Case _
	                    Curve2dTypeEnum.kPolylineCurve2d,
	                    Curve2dTypeEnum.kBSplineCurve2d,
	                    Curve2dTypeEnum.kUnknownCurve2d

	                    ' Unhandled curves types
	                Case Else
	            End Select
	        Next

	    End Sub
End Class

 

 

0 Likes
Message 11 of 21

ralfmja
Advocate
Advocate

Hi @WCrihfield ,

 

If I understood correctly - you determined the X coordinate of point B and the Y coordinate of point A from my sketch?

However, you think that even if you were to determine a line parallel to the Y direction passing through point A and a line parallel to the X direction passing through point B.

In the next step, intersect them as the point of inserting the C indicator - this will not be possible because we do not have simple "physical" ones, only "mathematical" calculations??

 

@Mac_W  

 

If I understood correctly, your code is a variation of the code I pasted from @JelteDeJong, which is currently used to determine the coordinates of points A and B in my sketch. However, if I understand correctly, the problem is not about determining the intersection point described in the sketch as C, but about its physical representation (no insertion point) ??

 

@WCrihfield , @Mac_W 

What would you say to such an idea:

determining the coordinates of point C and then adding a sketch in the view and adding a point with the coordinates of point C and then inserting the origin pointer at the point in the sketch ??

 

thank you for your help and I am asking for more 😉 (especially when it comes to the code)

 

Regards,

ralfmja

0 Likes
Message 12 of 21

Mac_W
Contributor
Contributor

@ralfmja@WCrihfield 

 

I modified the code i previously posted to set the origin. I had very limited time to test it but it did seem to work on my re-creation of @ralfmja's example.

 

 

 

Public Class ThisRule
	Private _doc As DrawingDocument
    Private _sheet As Sheet
	Private _view As DrawingView
    Private _intents As List(Of GeometryIntent) = New List(Of GeometryIntent)()

    Sub Main()
        _doc = ThisApplication.ActiveDocument
        _sheet = _doc.ActiveSheet

		Dim _view As DrawingView = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingViewFilter, "Pick DrawingView")
		_intents.Clear
        CreateIntentList(_view)
		
		Dim orderedIntentsX = _intents.OrderByDescending(Function(s) s.PointOnSheet.X)

		Dim pointLeft = orderedIntentsX.Last.PointOnSheet.x
        Dim pointRight = orderedIntentsX.First.PointOnSheet.x
		
		Dim orderedIntentsY = _intents.OrderByDescending(Function(s) s.PointOnSheet.Y)

		Dim pointBot = orderedIntentsY.Last.PointOnSheet.y
        Dim pointTop = orderedIntentsY.First.PointOnSheet.y
		
		
		
		
		
		
		
		
		'Create GeometryIntent for intersection
    	Dim oIntersectionIntent As GeometryIntent = orderedIntentsY.Last
		
		Dim distToGo As Double = orderedIntentsY.Last.PointOnSheet.x - orderedIntentsX.Last.PointOnSheet.x
		
		
		
		'If origin indicator has Not been already created, create it first.
	    If Not _view.HasOriginIndicator Then
	        MsgBox("no origin indicator")
	        _view.CreateOriginIndicator(oIntersectionIntent)
	    Else
	        MsgBox("has origin indicator")
	        _view.OriginIndicator.Intent = oIntersectionIntent
	    End If
		
		
		
		'set relative x of origin
		_view.OriginIndicator.RelativeX = ((distToGo)*(-1))/_view.Scale
		
		
		
		
		
		
		
		Dim xDim As Double = Round(((pointRight - pointLeft)/_view.Scale)/2.54, 3)
		Dim yDim As Double = Round(((pointTop - pointBot)/_view.Scale)/2.54, 3)
		
		
		MsgBox("pointLeft: " & pointLeft & vbCrLf _
		& "pointRight: " & pointRight & vbCrLf _
		& "pointBot: " & pointBot & vbCrLf _
		& "pointTop: " & pointTop)
		
		MsgBox("X: " & xDim & vbCrLf _
		& "Y: " & yDim)

    End Sub
	
	Private Sub addIntent(Geometry As DrawingCurve, IntentPlace As Object, onLineCheck As Boolean)

        Dim intent As GeometryIntent = _sheet.CreateGeometryIntent(Geometry, IntentPlace)
        If intent.PointOnSheet Is Nothing Then Return

        If onLineCheck Then
            If (IntentIsOnCurve(intent)) Then
                _intents.Add(intent)
            End If
        Else
            _intents.Add(intent)
        End If
    End Sub

	Private Function IntentIsOnCurve(intent As GeometryIntent) As Boolean

	        Dim Geometry As DrawingCurve = intent.Geometry
	        Dim sp = intent.PointOnSheet

	        Dim pts(1) As Double
	        Dim gp() As Double = {}
	        Dim md() As Double = {}
	        Dim pm() As Double = {}
	        Dim st() As SolutionNatureEnum = {}
	        pts(0) = sp.X
	        pts(1) = sp.Y

	        Try
	            Geometry.Evaluator2D.GetParamAtPoint(pts, gp, md, pm, st)
	        Catch ex As Exception
	            Return False
	        End Try
	        Return True
	    End Function

	Private Sub CreateIntentList(_view As DrawingView)

	        For Each oDrawingCurve As DrawingCurve In _view.DrawingCurves
	            Select Case oDrawingCurve.ProjectedCurveType
	                Case _
	                        Curve2dTypeEnum.kCircleCurve2d,
	                        Curve2dTypeEnum.kCircularArcCurve2d,
	                        Curve2dTypeEnum.kEllipseFullCurve2d,
	                        Curve2dTypeEnum.kEllipticalArcCurve2d

	                    addIntent(oDrawingCurve, PointIntentEnum.kCircularTopPointIntent, True)
	                    addIntent(oDrawingCurve, PointIntentEnum.kCircularBottomPointIntent, True)
	                    addIntent(oDrawingCurve, PointIntentEnum.kCircularLeftPointIntent, True)
	                    addIntent(oDrawingCurve, PointIntentEnum.kCircularRightPointIntent, True)

	                    addIntent(oDrawingCurve, PointIntentEnum.kEndPointIntent, False)
	                    addIntent(oDrawingCurve, PointIntentEnum.kStartPointIntent, False)

	                Case _
	                        Curve2dTypeEnum.kLineCurve2d,
	                        Curve2dTypeEnum.kLineSegmentCurve2d

	                    addIntent(oDrawingCurve, PointIntentEnum.kEndPointIntent, False)
	                    addIntent(oDrawingCurve, PointIntentEnum.kStartPointIntent, False)

	                Case _
	                    Curve2dTypeEnum.kPolylineCurve2d,
	                    Curve2dTypeEnum.kBSplineCurve2d,
	                    Curve2dTypeEnum.kUnknownCurve2d

	                    ' Unhandled curves types
	                Case Else
	            End Select
	        Next

	    End Sub
End Class




 

 

Message 13 of 21

ralfmja
Advocate
Advocate

Hi @Mac_W,

 

Thanks - it works 🙂

 

Regards

ralfmja 

0 Likes
Message 14 of 21

WCrihfield
Mentor
Mentor

After dealing with a lot of other projects, I decided to take another look at this challenge, just to see if it could be done any easier, or more efficiently.  I realized that since we have the ability to specify OriginIndicator.RelativeX and OriginIndicator.RelativeY, then it really does not matter which GeometryIntent you associate the OriginIndicator with, because you can simply use the mathematical position difference between the two locations to offset it.  With that fact in mind, I adapted my earlier code for finding the geometric lower left point of the views geometry, then simply used the 'first' GeometryIntent, from the 'first' DrawingCurve of the view to create the OriginIndicator on.  Then applied the mathematical offsets to it, and it seems to work just fine for this task.

 

When getting the GeometryIntent of that first DrawingCurve, I specified the second input as being either its 'mid point', or its 'center point', because we need a point intent, and pretty much every type of DrawingCurve will have one or the other.

Here is the revised code, just for the extra reference, and another option.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then Exit Sub
	Dim oDDoc As DrawingDocument = ThisDoc.Document
	Dim oSheet As Inventor.Sheet = oDDoc.ActiveSheet
	If oSheet.DrawingViews.Count = 0 Then Exit Sub
	Dim oView As DrawingView = oSheet.DrawingViews.Item(1)
	Dim oMinPoint As Point2d = GetViewMinPoint(oView)
	If oMinPoint Is Nothing Then Exit Sub
	Logger.Info("oMinPoint.X = " & oMinPoint.X & vbCrLf & "oMinPoint.Y = " & oMinPoint.Y)
	Dim oGI As GeometryIntent = Nothing
	Try
		oGI = oSheet.CreateGeometryIntent(oView.DrawingCurves.Item(1), PointIntentEnum.kMidPointIntent)
	Catch
		oGI = oSheet.CreateGeometryIntent(oView.DrawingCurves.Item(1), PointIntentEnum.kCenterPointIntent)
	Catch
		Logger.Debug("Could not get GeometryIntent from first DrawingCurve in view.")
	End Try
	If oGI Is Nothing Then Exit Sub
	If oView.HasOriginIndicator Then
		oView.OriginIndicator.Intent = oGI
	Else
		oView.CreateOriginIndicator(oGI)
	End If
	Dim dXOffset As Double = (oGI.PointOnSheet.X - oMinPoint.X) * (-1) / oView.Scale
	Dim dYOffset As Double = (oGI.PointOnSheet.Y - oMinPoint.Y) * (-1) / oView.Scale
	oView.OriginIndicator.RelativeX = dXOffset
	oView.OriginIndicator.RelativeY = dYOffset
End Sub

Function GetViewMinPoint(oView As DrawingView) As Point2d
	If oView Is Nothing Then Return Nothing
	Dim oDCE As DrawingCurvesEnumerator = Nothing
	Try : oDCE = oView.DrawingCurves : Catch : End Try
	If oDCE Is Nothing OrElse oDCE.Count = 0 Then Return Nothing
	Dim dMinPointX As Double = oView.Left + oView.Width
	Dim dMinPointY As Double = oView.Top
	For Each oDC As DrawingCurve In oDCE
		Dim dMinParam, dMaxParam As Double
		oDC.Evaluator2D.GetParamExtents(dMinParam, dMaxParam)
		Dim oParams() As Double = {dMinParam, dMaxParam}
		Dim oPointCoords() As Double = {}
		oDC.Evaluator2D.GetPointAtParam(oParams, oPointCoords)
		If oPointCoords(0) < dMinPointX Then dMinPointX = oPointCoords(0)
		If oPointCoords(1) < dMinPointY Then dMinPointY = oPointCoords(1)
	Next
	Dim oMinPoint As Point2d = ThisApplication.TransientGeometry.CreatePoint2d(dMinPointX, dMinPointY)
	Return oMinPoint
End Function

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 15 of 21

ralfmja
Advocate
Advocate

Hi @WCrihfield ,

 

Yeah - thats works great too 🙂 

 

@WCrihfield , @Mac_W 

thanks guys - i can't mark your posts as solution but your help were invaluable 🙂

 

Regards,

ralfmja

Message 16 of 21

ralfmja
Advocate
Advocate

Hi @WCrihfield@Mac_W 

 

The next topic related to this issue 🙂 I would like to dimension the holes using a ordinary dimension set, where 0 will be in the extreme left point of the sketch (as in the previous case).

 

I'm getting something like this:

ODS1.png

I would like to achieve something like this:

 

ods2.png

 

I have a problem as shown in the video below, i.e., specifying the geometry intent by providing our origin indicator - I am unable to provide coordinates shifted by the offset vector value 🙂

 

 

Is there a possibility to change the coordinates of the origin indicator by the offset value and use it as the first object in the "CenterPointCollection" set??

 

Is there any other option that could achieve what I want??

 

My current code is below:

Sub Main()
	
Dim oView As DrawingView = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingViewFilter, "Select the drawing view")
Dim oSheet As Sheet = oView.Parent
Dim oDoc As DrawingDocument = oSheet.Parent

Dim oTO As TransientObjects = ThisApplication.TransientObjects
Dim oTG As TransientGeometry = ThisApplication.TransientGeometry

Dim oMinPoint As Point2d = GetViewMinPoint(oView)
Dim oGI As GeometryIntent = Nothing
	Try
		oGI = oSheet.CreateGeometryIntent(oView.DrawingCurves.Item(1), PointIntentEnum.kMidPointIntent)
	Catch
		oGI = oSheet.CreateGeometryIntent(oView.DrawingCurves.Item(1), PointIntentEnum.kCenterPointIntent)
	Catch
		Logger.Debug("Could not get GeometryIntent from first DrawingCurve in view.")
	End Try
	If oGI Is Nothing Then Exit Sub
	If oView.HasOriginIndicator Then
		oView.OriginIndicator.Intent = oGI
	Else
		oView.CreateOriginIndicator(oGI)
	End If
	Dim dXOffset As Double = (oGI.PointOnSheet.X - oMinPoint.X) * (-1) / oView.Scale
	Dim dYOffset As Double = (oGI.PointOnSheet.Y - oMinPoint.Y) * (-1) / oView.Scale
	oView.OriginIndicator.RelativeX = dXOffset
	oView.OriginIndicator.RelativeY = dYOffset
	
Dim CenterPointCollection As ObjectCollection = oTO.CreateObjectCollection
CenterPointCollection.Add(oView.OriginIndicator.Intent)

'Iterate through every drawing curve in the view
For Each oCurve As DrawingCurve In oView.DrawingCurves()
	'Check if curve is a circle
	If oCurve.ProjectedCurveType = Curve2dTypeEnum.kCircleCurve2d Then
		'Make geometry intent point at that point
		Dim CenterPointIntent As GeometryIntent = oSheet.CreateGeometryIntent(oCurve, PointIntentEnum.kCenterPointIntent)
		'Add the geometry intent point to the CenterPointCollection
		CenterPointCollection.Add(CenterPointIntent)
	End If
Next

'Point to place Dimensions
Dim TopofView As Point2d = oTG.CreatePoint2d(oView.Center.X, oView.Top + 3)

oSheet.DrawingDimensions.OrdinateDimensionSets.Add(CenterPointCollection, TopofView, DimensionTypeEnum.kHorizontalDimensionType)
End Sub
Function GetViewMinPoint(oView As DrawingView) As Point2d
	If oView Is Nothing Then Return Nothing
	Dim oDCE As DrawingCurvesEnumerator = Nothing
	Try : oDCE = oView.DrawingCurves : Catch : End Try
	If oDCE Is Nothing OrElse oDCE.Count = 0 Then Return Nothing
	Dim dMinPointX As Double = oView.Left + oView.Width
	Dim dMinPointY As Double = oView.Top
	For Each oDC As DrawingCurve In oDCE
		Dim dMinParam, dMaxParam As Double
		oDC.Evaluator2D.GetParamExtents(dMinParam, dMaxParam)
		Dim oParams() As Double = {dMinParam, dMaxParam}
		Dim oPointCoords() As Double = {}
		oDC.Evaluator2D.GetPointAtParam(oParams, oPointCoords)
		If oPointCoords(0) < dMinPointX Then dMinPointX = oPointCoords(0)
		If oPointCoords(1) < dMinPointY Then dMinPointY = oPointCoords(1)
	Next
	Dim oMinPoint As Point2d = ThisApplication.TransientGeometry.CreatePoint2d(dMinPointX, dMinPointY)
	Return oMinPoint
End Function

 

Thanks in advance,

ralfmja

0 Likes
Message 17 of 21

WCrihfield
Mentor
Mentor

Hi @ralfmja.  Since this is now getting into dimensioning, it may be getting to the point where it may need its own forum post.  If your OrdinateDimensionSet is not recognizing the 'shifted' location of the OriginIndicator, that means that you will need to place your OriginIndicator directly on the left most GeometryIntent of your view's geometry, and not shift its position, and use that as the origin of your dimension set.  Unfortunately, as you have already observed, the left most point of a view's geometry may not always be the lowest (down in Y direction) point of a view's geometry.  You will simply have to plan ahead for that situation when designing stuff that you know will need to be dimensioned that way on a drawing later.  Below is another variation of code, which is mostly using the same strategies as @Mac_W's codes above.  It gets a List of GeometryIntent objects from the view that are on view geometry, then finds the one who's PointOnSheet is the farthest left (min X), and uses that for the view's OriginIndicator.  I have not tested it yet though.   And I probably should not have included center point in the intent types to process, but I left it in there anyways.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then Exit Sub
	Dim oDDoc As DrawingDocument = ThisDoc.Document
	Dim oView As DrawingView = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingViewFilter, "Select a Drawing View.")
	If oView Is Nothing Then Exit Sub
	Dim oViewIntents As List(Of Inventor.GeometryIntent) = GetViewIntentsOnGeometry(oView)
	If oViewIntents IsNot Nothing AndAlso oViewIntents.Count > 0 Then
		'determine which Intent point is furthest left (min x)
		Dim oLeftIntent As GeometryIntent = Nothing
		Dim dX As Double = oView.Left + oView.Width
		For Each oVI In oViewIntents
			If oVI.PointOnSheet.X < dX Then
				dX = oVI.PointOnSheet.X
				oLeftIntent = oVI
			End If
		Next
		If oView.HasOriginIndicator Then
			oView.OriginIndicator.Intent = oLeftIntent
		Else
			oView.CreateOriginIndicator(oLeftIntent)
		End If
	End If
	oView.Parent.Update
	oDDoc.Update2(True)
End Sub

Function GetViewIntentsOnGeometry(oView As DrawingView) As List(Of Inventor.GeometryIntent)
	If oView Is Nothing Then Return Nothing
	Dim oDCs As DrawingCurvesEnumerator = Nothing
	Try : oDCs = oView.DrawingCurves : Catch : End Try
	If oDCs Is Nothing OrElse oDCs.Count = 0 Then Return Nothing
	Dim oGIs As New List(Of Inventor.GeometryIntent)
	Dim oSheet As Inventor.Sheet = oView.Parent
	Dim oPIs() As PointIntentEnum = {PointIntentEnum.kCenterPointIntent, PointIntentEnum.kCircularBottomPointIntent,
	PointIntentEnum.kCircularLeftPointIntent, PointIntentEnum.kCircularRightPointIntent, PointIntentEnum.kCircularTopPointIntent,
	PointIntentEnum.kEndPointIntent, PointIntentEnum.kMidPointIntent, PointIntentEnum.kStartPointIntent}
	For Each oDC As DrawingCurve In oDCs
		For Each oPI In oPIs
			Dim oGI As GeometryIntent = Nothing
			Try : oGI = oSheet.CreateGeometryIntent(oDC, oPI) : Catch : End Try
			If oGI IsNot Nothing Then 'check if Intent point is on oDC
				Dim oPOS As Point2d = oGI.PointOnSheet
				If oPOS Is Nothing Then Continue For
				Dim oPoints() As Double = {oPOS.X, oPOS.Y }
				Dim oGuessParams() As Double = {}
				Dim oMaxDeviations() As Double = {}
				Dim oParams() As Double = {}
				Dim oSolTypes() As SolutionNatureEnum = {}
				Try
					oDC.Evaluator2D.GetParamAtPoint(oPoints, oGuessParams, oMaxDeviations, oParams, oSolTypes)
				Catch : Continue For : End Try
				If oSolTypes(1) = SolutionNatureEnum.kNoSolution Then
				Else : oGIs.Add(oGI) : End If
			End If
		Next 'oPI
	Next 'oDC
End Function

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 18 of 21

ralfmja
Advocate
Advocate

Hi @WCrihfield ,

 

Currently, I have an error as shown in the screenshot : 

 

ralfmja_0-1695220207756.png

In english it will be :"Index was outside the bounds of the array"

 

I think the position of the origin indicator is not important in the Y direction for horizontal dimensions :)I even think that it would be desirable to hide the origin indicator on the dimensioned view after placing it (we only need it to anchor the 0).

 

Of course, the rule would also need to do the same for vertical dimensions, but then we would have a situation where we are not concerned about the X direction (only minimum Y). So, if it was possible to achieve this for what I've shown, the same approach could be used to achieve dimensions in Y.

 

Thanks for your time,

 

Regards,

ralfmja

 

 

0 Likes
Message 19 of 21

WCrihfield
Mentor
Mentor

My mistake.  Change oSolTypes(1) to oSolTypes(0), or oSolTypes.First .  I temporarily forgot that Array's are zero based, so their first entry is at zero, not 1.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 20 of 21

ralfmja
Advocate
Advocate

Yes, that was it 🙂 but  after running the rule, nothing happens, i.e., the origin indicator is not created, but there are no errors either.

0 Likes