Drawing Sketch Project Geometry using API

Drawing Sketch Project Geometry using API

Anonymous
Not applicable
4,436 Views
11 Replies
Message 1 of 12

Drawing Sketch Project Geometry using API

Anonymous
Not applicable

Hello,  I'm developing with VB.Net and Inventor using a standalone exe that grabs or creates inventor app.  I have reached an impass with trying to find the propery way to project entities (AddByProjectingEntity) from an assembly's origin to a sketch created from the base view's sketch collection's add routine.  What I have attempted is below:

 

Dim vSide As DrawingView = shClearance.DrawingViews.AddBaseView(ClearanceModel, pntSideView, CDbl(1 / 40), ViewOrientationTypeEnum.kFrontViewOrientation, DrawingViewStyleEnum.kHiddenLineRemovedDrawingViewStyle, "SIDE VIEW")

Dim wporigin As WorkPoint = SetWorkPointVisibility(vSide, "Center Point", True)

Dim pOrigin As SketchPoint = skSection.AddByProjectingEntity(wporigin)

    Public Function SetWorkPointVisibility(ByRef v As DrawingView, ByRef wpName As String, ByVal visibility As Boolean) As WorkPoint
        Dim doc As Inventor.Document = v.ReferencedDocumentDescriptor.ReferencedDocument
        Dim cd As ComponentDefinition = Nothing
        If doc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
            cd = CType(doc, AssemblyDocument).ComponentDefinition
        ElseIf doc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
            cd = CType(doc, PartDocument).ComponentDefinition
        End If
        Dim wp As WorkPoint = FindWorkPoint(cd, wpName)
        If wp IsNot Nothing Then
            v.SetVisibility(wp, True)
            Return wp
        End If
        Return Nothing
    End Function

    Public Function FindWorkPoint(ByRef cd As ComponentDefinition, ByVal wpName As String) As WorkPoint
        Dim wps As WorkPoints = Nothing
        If cd.Type = ObjectTypeEnum.kAssemblyComponentDefinitionObject Then
            Dim acd As AssemblyComponentDefinition = cd
            wps = acd.WorkPoints
        ElseIf cd.Type = ObjectTypeEnum.kPartComponentDefinitionObject Then
            Dim pcd As PartComponentDefinition = cd
            wps = pcd.WorkPoints
        End If
        If wps IsNot Nothing Then
            For Each wp As WorkPoint In wps
                If wp.Name = wpName Then Return wp
            Next
        End If
        Return Nothing
    End Function

 

I can't find any example, sample or blog with a direct example.  Any guidance would be helpful.  Thanks,

0 Likes
Accepted solutions (2)
4,437 Views
11 Replies
Replies (11)
Message 2 of 12

Jon.Balgley
Alumni
Alumni

I will take a look at your sample, but in the meantime, you might see if the thread below answers your question:

 

https://forums.autodesk.com/t5/inventor-customization/trying-to-use-addbyprojectingentity-with-a-dra...

 

I found that by googling for "addbyprojectingentity" ... there are a few other threads too.

 

 


Jon Balgley
0 Likes
Message 3 of 12

Anonymous
Not applicable

Yea i read that one (and many others), and it seems appropriate IF i wanted something from an occurance.  BUT the item i want is from the referenced document component definition itself, not an occurance within that definition. 

Example:

Assembly-A1 has 1 occurance

     Assembly-B1 with 1 occurance

          Part-C1

 

Drawing-A1 has 1 sheet

    Sheet-1 with 1 view

         View-1 that references document, and the view has a single sketch in its sketches collection

               Assemlby-A1

               Sketch1

I want to project the CenterPoint of Assembly-A1 into Sketch1. 

 

This top level does not have any occurance mechanism or create proxy geometry options to work with.  So the assumption is you don't proxy anything at this top level and place the found object (work point) within the sketch (addbyprojectingentity).  It throws an error Invalid Parameters every time.  So naturally I'm lost.

 

0 Likes
Message 4 of 12

Jon.Balgley
Alumni
Alumni

I can confirm/reproduce the behavior you describe.  I am continuing to investigate.


Jon Balgley
0 Likes
Message 5 of 12

Jon.Balgley
Alumni
Alumni

After some investigation, I learned a few relevant things:

 

1. It appears that workpoints cannot be projected to drawing sketches.  Try to do this interatively in Inventor -- you can't (at least, I can't!).  

1a. Someone mentioned that maybe it only makes sense to do that for sketches that are associated to views, as opposed to sketches that are associated to the sheet.  To do the former, first select the view, then create the sketch.  You'll see the origin centered on the view.

2. It appears that sketch points in a drawing sketch are not visible (at least, normally not) ... so you probably want to use the sketch point for something else (e.g., end point of a line).

3. Some things for drawing sketches only work inside an Edit/ExitEdit pair.

 

But nevertheless, the code below may be useful to you.  It takes two workpoints from the model (a part, in my case), and draws a sketch-line between them in the corresponding view.  I did this in iLogic, in the IDW, so the second line has an iLogic-ism.  The rest is pretty much all pure API code.  

 

Hope this helps.

 

SyntaxEditor Code Snippet

Dim vw As DrawingView
vw = ActiveSheet.View("VIEW1").View

Dim dsk as DrawingSketch
dsk = vw.Sketches.Item(1)

Dim partDef as PartComponentDefinition
partDef = vw.ReferencedDocumentDescriptor.ReferencedDocument.ComponentDefinition

Dim wpa As Workpoint
wpa = partDef.workpoints.item("MyWorkpoint1")

Dim pt3a As Point
pt3a = wpa.Point

Dim pt2a As Point2d
pt2a = vw.ModelToDrawingViewSpace(pt3a)

Dim wpb As Workpoint
wpb = partDef.workpoints.item("MyWorkpoint2")

Dim pt3b As Point
pt3b = wpb.Point

Dim pt2b As Point2d
pt2b = vw.ModelToDrawingViewSpace(pt3b)

Dim tGeo As TransientGeometry
tGeo = ThisApplication.TransientGeometry


dsk.Edit
dsk.SketchLines.AddByTwoPoints(pt2a, pt2b)
'dsk.AddByProjectingEntity(wp)
dsk.ExitEdit

   


Jon Balgley
0 Likes
Message 6 of 12

Anonymous
Not applicable

You can get the work point into a sketch same as work plane you must ‘include’ the geometry before you can project it. Something I do in code a line or two above, but didn’t post. I’ve tried to project a Workplane just the same thru code, and it doesn’t work. But I can do both manually.

So to make it happen manually, you first create the base view, find the origin center point of the assembly in the browser under the view and right-click on it to select include, then highlight the view and press “s” for sketch (creates a sketch linked to the view), then press project geometry, and select the projected work point (center point), and it becomes part of the sketch. As proof you will see a small cross, and be able to dimension to it within the sketch. You would not be able to dimension to it if it were not projected first.

0 Likes
Message 7 of 12

Jon.Balgley
Alumni
Alumni

Oooh, INCLUDE.  OK, I forgot about that.  Yes, I can confirm this workflow, and I can manually project the included workpoints into the sketch.  But -- as you know -- even included workpoints cannot be projected via the API (apparently).  

 

Using ModelToDrawingViewSpace will give you the relevant coordinates.  The "only" thing additional thing you get from an actual projected workpoint is ... associativity.  That is, your sketch will be associative with the workpoints.  Of course, that is usually very important.  But since you're coding this up, maybe you are re-running the code whenever something changes, and don't need that?  Just asking.

 

I will continue to investigate.  It looks like a defect, so far.


Jon Balgley
0 Likes
Message 8 of 12

Anonymous
Not applicable

Thanks for your help.  I will implement your work around as necessary.

Message 9 of 12

Jon.Balgley
Alumni
Alumni
Accepted solution

I got more information from a colleague.   When you include a workpoint, it creates a "Centermark" on the sheet.  The centermark can be projected into the sketch.  This will be better than the "workaround" I suggested earlier.

 

There is also an API to explicitly create a centermark from a workpoint .  Seems to do the same thing as 'include'.  (Centermarks.AddByWorkFeature, not shown here)

 

SyntaxEditor Code Snippet

'iLogic-ism here
Dim sh As Sheet
sh = ActiveSheet.Sheet

Dim vw As DrawingView
vw = ActiveSheet.View("VIEW1").View

' --- the rest should be pure API code

Dim dsk as DrawingSketch
dsk = vw.Sketches.Item(1)

Dim partDef as PartComponentDefinition
partDef = vw.ReferencedDocumentDescriptor.ReferencedDocument.ComponentDefinition

Dim wpa As Workpoint
wpa = partDef.workpoints.item("MyWorkpoint1")
vw.SetIncludeStatus(wpa, True)

Dim wpb As Workpoint
wpb = partDef.workpoints.item("MyWorkpoint2")
vw.SetIncludeStatus(wpb, True)

Dim centerMark1 As CenterMark
Dim centerMark2 As CenterMark

centerMark1 =  sh.CenterMarks.Item(1)
centerMark2 = sh.CenterMarks.Item(2)

dsk.AddByProjectingEntity(centerMark1)
dsk.AddByProjectingEntity(centerMark2)
    

 

 


Jon Balgley
Message 10 of 12

Anonymous
Not applicable

I admire your persistance.  This will definitely expose a new realm of coding.  I only thought that views and sheet sketches contained entities, but now I see sheets do as well.  Meaning that the projected workplanes most likely create centerlines, so now I have solved my other potential unknown for the day, how to get the made visible centerline of the workplane so that I can attach a centerline symbol to it.

 

Thanks,

0 Likes
Message 11 of 12

Anonymous
Not applicable

Diving deeper and deeper, I've successfully created a workpoint/centermark from a top level assembly into its direct drawing sheet space.  I've created work planes/centerlines from the same.  Now I am attempting to add work points from a 4 level down part.  I get the component definition from the sketch, get the component occurence from the definition, get the work point from the component occurance's definition, use the component occurance to convert it to a work point proxy, use either view.SetVisibility(workpointproxy,true) or view.SetIncludeStatus(workpointproxy, true) and they both fail, Invalid Parameter.  Makes me think I'm putting in the wrong data somehow.  I've tried using work point direct and work point proxy (which should be the correct answer).  Setting include status fails the same.  This 4th level work point does not want to come thru.

 

Public Function SetSubOccWorkPointVisibility(ByRef v As DrawingView, ByRef subOccName As String, ByRef wpName As String, ByVal visibility As Boolean) As Centermark
        Try
            Dim doc As Inventor.Document = v.ReferencedDocumentDescriptor.ReferencedDocument
            Dim wp As WorkPoint = Nothing
            Dim cd As ComponentDefinition = Nothing
            If doc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
                cd = CType(doc, AssemblyDocument).ComponentDefinition
            ElseIf doc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
                cd = CType(doc, PartDocument).ComponentDefinition
            End If
            If cd IsNot Nothing Then
                Dim co As ComponentOccurrence = GetSubOccuranceByName(cd, subOccName)
                If co IsNot Nothing Then
                    cd = co.Definition
                    wp = FindWorkPoint(cd, wpName)
                    If wp IsNot Nothing Then
                        Dim wpp As WorkPointProxy = Nothing
                        co.CreateGeometryProxy(wp, wpp)
                        v.SetIncludeStatus(wpp, True)
                        Return v.Parent.Centermarks.AddByWorkFeature(wpp, v)
                        'v.SetVisibility(wpp, True)
                        'Return v.Parent.Centermarks(v.Parent.Centermarks.Count)
                    End If
                End If
            End If
        Catch ex As Exception
            Dim eh As New ErrorHandler(ex)
            eh.HandleIt()
        End Try
        Return Nothing
    End Function

find workpoint:

 

    Public Function FindWorkPoint(ByRef cd As ComponentDefinition, ByVal wpName As String) As WorkPoint
        Dim wps As WorkPoints = Nothing
        If cd.Type = ObjectTypeEnum.kAssemblyComponentDefinitionObject Then
            Dim acd As AssemblyComponentDefinition = cd
            wps = acd.WorkPoints
        ElseIf cd.Type = ObjectTypeEnum.kPartComponentDefinitionObject Then
            Dim pcd As PartComponentDefinition = cd
            wps = pcd.WorkPoints
        End If
        If wps IsNot Nothing Then
            For Each wp As WorkPoint In wps
                If wp.Name = wpName Then Return wp
            Next
        End If
        Return Nothing
    End Function

GetSubOccuranceByName:

 

    Public Function GetSubOccuranceByName(ByRef cdAssembly As AssemblyComponentDefinition, ByVal subOccName As String) As ComponentOccurrence
        For Each co As ComponentOccurrence In cdAssembly.Occurrences
            If co.Name = subOccName Then Return co
            If co.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
                Dim sco As ComponentOccurrence = GetSubOccuranceByName(co.Definition, subOccName)
                If sco IsNot Nothing Then Return sco
            End If
        Next
        Return Nothing
    End Function

example code to request centermark creation:

 

Dim cmTruckCenterStart As Centermark = SetSubOccWorkPointVisibility(vSide, "CAR", "TruckCentersStart", True)

CAR (actual component name - set by code during insertion) is a part file inside of CarMod an assembly inside of GenArr an assembly inside of ClearanceDrawing an assembly displayed by ClearanceDrawing a drawing (idw).  vSide is the base view of what viewcube calls Front as the side view of the car displaying the XY plane normal.

 

 

So question is, if I have verified that I have the correct work point proxy, just before calling the centermark options(2) what else could be going wrong, and how can I fix.

 

BTW my company just applied for the ADN Standard, I'm getting into this hardcore.

 

Thanks,

0 Likes
Message 12 of 12

Anonymous
Not applicable
Accepted solution

This is the solution to your sub component's sub component's sub component's needs:

 

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="cdAssembly">Parent Assembly reference</param>
    ''' <param name="subOccName">Name of Component to find</param>
    ''' <returns>Returns the ComponentOccurance if first level and ComponentOccuranceProxy if lower level.</returns>
    Public Function GetSubOccuranceProxyByName(ByRef cdAssembly As AssemblyComponentDefinition, ByVal subOccName As String) As Object
        Dim cop As ComponentOccurrenceProxy = Nothing
        For Each co As ComponentOccurrence In cdAssembly.Occurrences
            If co.Name = subOccName Then Return co
            If co.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
                Dim sco As ComponentOccurrence = GetSubOccuranceProxyByName(co.Definition, subOccName)
                If sco IsNot Nothing Then
                    co.CreateGeometryProxy(sco, cop)
                    Exit For
                End If
            End If
        Next
        Return cop
    End Function

This self diving loop works if you understand one primary principal, a ComponentOccuranceProxy inherits (is drived from) ComponentOccurance.  So I can run a loop that returns either.  As long as the object that calls this loop is defined as a ComponentOccurance, then it will get one of those back, or nothing.  For the purpose of creating a deeply nested geometry proxy the return object will be capable of calling CreateGeometryProxy either way.  I did some prodding, in Visual Studio watch window, the object will show only as a ComponentProxy, but in the pop up inspector you will see the extra properties such as OccurancePath proving it is a proxy object.  Here is an example (my work point to centermark routine) of it working:

 

 

    Public Function SetSubOccWorkPointVisibility(ByRef v As DrawingView, ByRef subOccName As String, ByRef wpName As String, ByVal visibility As Boolean) As Centermark
        Try
            Dim doc As Inventor.Document = v.ReferencedDocumentDescriptor.ReferencedDocument
            Dim wp As WorkPoint = Nothing
            Dim cd As ComponentDefinition = Nothing
            If doc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
                cd = CType(doc, AssemblyDocument).ComponentDefinition
            ElseIf doc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
                cd = CType(doc, PartDocument).ComponentDefinition
            End If
            If cd IsNot Nothing Then
                Dim co As ComponentOccurrence = GetSubOccuranceProxyByName(cd, subOccName)
                If co IsNot Nothing Then
                    wp = FindWorkPoint(co.Definition, wpName)
                    If wp IsNot Nothing Then
                        Dim wpp As WorkPointProxy = Nothing
                        co.CreateGeometryProxy(wp, wpp)
                        v.SetVisibility(wpp, True)
                        Return v.Parent.Centermarks(v.Parent.Centermarks.Count)
                    End If
                End If
            End If
        Catch ex As Exception
            Dim eh As New ErrorHandler(ex)
            eh.HandleIt()
        End Try
        Return Nothing
    End Function

Hope this helps everybody going there.  (and if I forget here it is documented!)