I am not sure how to proceed in this rule to place some automated leaders in a drawing view. The leaders point to WorkPoints in the assembly file that fit a specific naming convention. It works unless the view is a section view, and the depth of the section view is short enough that some of the workpoints are in the field of view, but should not be included because they are farther away than the section depth.
The specifics of my problem is that I have a large assembly of outdoor equipment that is all mounted on independent concrete foundations. At the early stages of the project, the same part file is used for many of the concrete pieces. In order to identify the concrete foundations, I came up with the idea of adding a named workpoints, ie a workpoint with a specific naming convention. In this case workpoints are named WPFTG-N-0001, WPFTG-N-0002, etc.
I find the assembly file by getting the referenced document for the view. I scan the assembly file and find the workpoints with names that contain the string "WPFTG-N" and add them to a collection. Then on the drawing view, I add a sketch and add text 0001, 0002 etc on the locations where they are.
This worked great in plan view. I then made a version with a section view where I showed the elevation of of the concrete foundations. This time I got the elevation of the workpoint, added it to some reference value and added a leader with the text. This also worked great in elevation view or an isometric view. I check to ensure that it appears within the boundaries of the view on the sheet. I am happy to this point.
Where I am stuck is when I have a larger assembly. Then I need to create a section view that has a section depth to limit what is seen. In my drawing section, this is a large value like 5m, when my assembly could be 30 meters deep.
Here where things do not work as expected. All of the workpoints are included generating lots of unnecessary leaders in the view. I do not know how to determine if a point should be within the volume shown in the section view, or if it is too far and outside the depth of the section view. The DrawingView has a method to find GetIncludeStatus, but my experiment with checking this value show the Include Status as true, and the rule faithfully
So how do I determine if this workpoint or a point in X,Y,Z space should be included in the section view?
I have included the rule that I have and apologize for the length (and maybe the poor style). I have attached a screen shot of the drawing note leaders pointing to a spot in space where something would show if I had the section view depth set to full. And a view of the assembly and the browser.
' show elevation of named workpoints as leadernotes
' select a drawing view on a drawing. Goes to the underlying assembly and finds a named point, in the form
' wpname = "WPFTG-N-001"
' then determines the height of the workpoint, adds a leader with the elevation of the workpoint/foundation
' since adding leaders, now I am working on sheetspace not drawing view space. No sketch required.
Sub main()
If ThisApplication.ActiveDocumentType <> Inventor.DocumentTypeEnum.kDrawingDocumentObject Then
MsgBox("This rule needs to run on the drawing file", , "Wrong file warning")
Exit Sub
End If
Dim selectedDrawingView As Inventor.DrawingView
selectedDrawingView = ThisApplication.CommandManager.Pick(Inventor.SelectionFilterEnum.kDrawingViewFilter, "Select a drawing view that needs elevations added as leader notes")
Dim oTG As TransientGeometry = ThisApplication.TransientGeometry
'Dim ftgSketch As Inventor.Sketch =Nothing
'ftgSketch = selectedDrawingView.Sketches.Add()
'ftgSketch.Edit
' expecting to find workpoint name of the form wpname = "WPFTG-N-001"
Dim wpmatchstring As String = "WPFTG-N-"
Dim foundarray As New ArrayList
Dim foundcount As Integer
foundcount = FindAllTopLevelPointsMatch(selectedDrawingView, wpmatchstring, foundarray)
If foundcount = 0 Then
MsgBox("found nothing, early exit")
Exit Sub
End If
Dim inputtext As String
Dim referenceElevation As Double
inputtext= InputBox("Enter the elevation in meters that cooresponds to the assembly zero elevation", "Enter reference elevation", "0")
referenceElevation = CDblAny(Val(inputtext))
'MsgBox("foundcount =" & foundcount, , "debug")
For Each foundpoint As Inventor.WorkPoint In foundarray
'MsgBox("found this point X= " & foundpoint.Point.X & "Y= " & foundpoint.Point.Y)
' convert from model to drawing view coordinate in 2D. Not the same as sheet space coordinates.
Dim PointOnDrawingView As Point2d = selectedDrawingView.ModelToDrawingViewSpace(foundpoint.Point)
' need to check if within the current view boundaries.
If checkwithinview(selectedDrawingView, PointOnDrawingView) Then
Dim nametxt As String
nametxt = foundpoint.Name
numtext = nametxt.Remove(0, wpmatchstring.Length)
Dim elevstr As String
Dim elev As Double
elev = referenceElevation + foundpoint.Point.Z / 100.0 ' convert from centimeters to meters
elev = Round(elev, 3)
elevstr = elev.ToString("F")
'numtext = "Ftg:" & numtext & vbLf & "Elev:" & elevstr
numtext = "EL " & elevstr
'ftgSketch.TextBoxes.AddFitted(oShtPt1, numtext)
CreateElevationLeader( ActiveSheet.Sheet, selectedDrawingView, oTG , foundpoint, elevstr )
' we can add a text style to the function here as an option
End If
Next
End Sub
' this needs the drawing view, and a string that will match the names of workpoints. It is passed an array that will be modified.
Private Function FindAllTopLevelPointsMatch(selectedDrawingView As Inventor.DrawingView, wpname As String, ByRef foundarray As ArrayList )
Dim oAssyDoc As AssemblyDocument = selectedDrawingView.ReferencedDocumentDescriptor.ReferencedDocument
Dim somethingFound As Boolean = False
' find workpoints that are in the top level of the assembly
For Each oWorkPoint As WorkPoint In oAssyDoc.ComponentDefinition.WorkPoints
If oWorkPoint.Name.Contains(wpname) Then
foundworkpoint = oWorkPoint
foundarray.Add(oWorkPoint)
somethingFound = True
End If
Next
' still to do, change this to traverse occurrences because will still miss subassemblies.
' return size of arraylist
Dim numberOfWorkPoints As Integer
numberOfWorkPoints = foundarray.Count
Return numberOfWorkPoints
End Function
Private Function CheckWithinView(selectedDrawingView As Inventor.DrawingView, checkthis2Dpoint As Inventor.Point2d)
Dim PointOnSheet As Inventor.Point2d = selectedDrawingView.DrawingViewToSheetSpace(checkthis2Dpoint)
If PointOnSheet.X > selectedDrawingView.Left And PointOnSheet.X< (selectedDrawingView.Left + 2 * (selectedDrawingView.Center.X - selectedDrawingView.Left)) Then
' x is ok
If PointOnSheet.Y < selectedDrawingView.Top And PointOnSheet.Y>(selectedDrawingView.Top - 2 * (selectedDrawingView.Top - selectedDrawingView.Center.Y)) Then
'y is ok too
Return True
End If
End If
Return False
End Function
Public Function CreateElevationLeader(oActiveSheet As Sheet, oDrawingView As DrawingView, oTG As TransientGeometry, targetpoint As Inventor.WorkPoint, elevstr As String)
Dim oLeaderPoints As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
' place a centermark on the workpoint to tie it to the model location
Dim mypointcenter As Inventor.Centermark = oActiveSheet.Centermarks.AddByWorkFeature(targetpoint, oDrawingView)
mypointcenter.Visible=False ' can set to invisible if it bothers you
Dim mypointonsheet As Point2d = oDrawingView.ModelToSheetSpace(targetpoint.Point)
oLeaderPoints.Add(oTG.CreatePoint2d(mypointonsheet.X+1, mypointonsheet.Y+1))
'*** Must be the LAST point added to the array. This is the Balloon Leader attachment point.
Dim geoIntent As Inventor.GeometryIntent = oActiveSheet.CreateGeometryIntent(mypointcenter)
oLeaderPoints.Add(geoIntent)
'*** Create the leader
Dim myLeader As Inventor.LeaderNote
myLeader = oActiveSheet.DrawingNotes.LeaderNotes.Add(oLeaderPoints,elevstr)
End Function