DISP_E_MEMBERNOTFOUND with Inventor.Point

DISP_E_MEMBERNOTFOUND with Inventor.Point

JamieVJohnson2
Collaborator Collaborator
921 Views
6 Replies
Message 1 of 7

DISP_E_MEMBERNOTFOUND with Inventor.Point

JamieVJohnson2
Collaborator
Collaborator

Platform: Visual Studio Professional 2017 (build just released today), Windows 10 16299 based (updated), Inventor 2018 latest release build.  Autodesk Inventor.Interop (ver 22.2.0.0)

 

I'm getting a total twilight zone moment here.  here is some code that runs fine, but when I set the value of the function to an empty variable (regardless of object type being "object" or "Inventor.Point" I get this error.  "Member not found" 

stack trace:

   at Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateSet(Object o, Type& objType, String name, Object[] args, String[] paramnames, Boolean OptimisticSet, CallType UseCallType)
   at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateSet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean OptimisticSet, Boolean RValueBase, CallType CallType)
   at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateSetComplex(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean OptimisticSet, Boolean RValueBase)
   at TTSInventorTools.BatchDrawing.CreatePartDrawing() in C:\Code\Inventor\TTS Inventor Tools\TTSInventorTools\TTSInventorTools\BatchDrawing.vb:line 485

 

What is at line 485:

Dim pntCameraTarget As Object = FindMidPoint3D(Model.InvDoc.ComponentDefinition.RangeBox.MinPoint, Model.InvDoc.ComponentDefinition.RangeBox.MaxPoint)

 

What is FindMidPoint3D:

    Public Function FindMidPoint3D(ByRef p1 As Point, ByRef p2 As Point) As Inventor.Point
        Dim x As Double = FindMid(p1.X, p2.X)
        Dim y As Double = FindMid(p1.Y, p2.Y)
        Dim z As Double = FindMid(p1.Z, p2.Z)
        Dim p As Inventor.Point = invApp.TransientGeometry.CreatePoint(x, y, z)
        Return p
    End Function

 

I followed this code all the way to return P, and everything is fine, and the point is created and it has an x,y,z values that are acceptable.

Then after it attempts to assign this "p" from FindMidPoint3D to pntCameraTarget (as Object or as Inventor.Point), I get the same error. 

Please help me resolve this.

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
922 Views
6 Replies
Replies (6)
Message 2 of 7

chandra.shekar.g
Autodesk Support
Autodesk Support

Hello @JamieVJohnson2,

 

 

Both declaration of Object and Inventor.Point for pntCameraTarget is working fine on returning P. A sample application is developed using Visual Studio 2017, Windows 10 and autodesk.Inventor.Interop (22.2.0.0) and attached with this post.

 

For more details, refer the below image which depicts return of Point P.

 

Retuning Point.png

 

Please feel free to contact if there is any queries.

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 3 of 7

JamieVJohnson2
Collaborator
Collaborator

I acknowledge your test project, and verify its proper functionality.  However my twilight zone episode persists, and the system.exception displayed in capture.png is captured at the moment FindPoint3D passes its data back to pntCameraTarget.

 

Inconceivable!  There has to be some other underlying circumstance that works in harmony with this call to create the problem.  The fundamental call should be harmless.  (invApp is acquired in advance, and stored as a global variable).

 

So any reasons why?

 

Here is the ENTIRE sub:

 Public Function CreatePartDrawing() As Inventor.DrawingDocument
        Dim drawDoc As Inventor.DrawingDocument = Nothing
        Try
            Dim invSilent As Boolean = invApp.SilentOperation
            invApp.SilentOperation = True
            drawDoc = invApp.Documents.Add(DocumentTypeEnum.kDrawingDocumentObject, BatchDrawings.Instance.DrawingTemplate)
            Dim strFileName As String = Model.InvDoc.FullFileName.Replace(".ipt", ".idw")
            Try
                drawDoc.SaveAs(strFileName, False)
            Catch
                MsgBox("Can not save file with this name it is probably already open as a different document." & vbCrLf & strFileName)
                Me.Errors += "[Can not save file]"
            End Try
            invApp.SilentOperation = invSilent
            'check for parameters in the description, and use the place view.
            Dim strDescription As String = String.Empty
            Dim descDims As List(Of DimensionConstraint) = GetDimensionsFromDescription(Model.InvDoc, strDescription, Me)
            Dim sktNormal As UnitVector = tg.CreateUnitVector(0, 1, 0)
            If strDescription.Length > 1 Then
                If strDescription.Substring(0, 2) = "=P" AndAlso strDescription.Contains("PIPE") = False Then
                    sktNormal = tg.CreateUnitVector(0, 0, 1)
                    If descDims.Count > 0 Then
                        For Each dc As DimensionConstraint In descDims
                            If dc.Parameter.Name.ToUpper = "LONG" Then
                                Dim skt As Sketch = dc.Parent
                                If skt.Type = ObjectTypeEnum.kPlanarSketchObject Then
                                    'get the normal of this sketch
                                    sktNormal = CType(skt, PlanarSketch).PlanarEntityGeometry.Normal
                                    'use this normal to place the view
                                End If
                            End If
                        Next
                    End If
                End If
            End If
            'choose base view face direction (take from dimensions "Long", and "Short" and "Thick" to allow orientation to match)
            'determine if part is complex or simple
            'If IsComplex(partDoc) Then
            '    Dim shCarMod As Sheet = CreateSheetFromSheetFormat(drawDoc, "TTS - Arch D")
            'End If
            Dim strSheetName As String = "TTS Part - Eng B"
            Dim shPart As Sheet
            Select Case PageSize
                Case PageSizeEnum.B_Size
                'default size nothing to do.
                Case PageSizeEnum.C_Size
                    'get sheet from sheet format
                    strSheetName = "TTS Part - Arch C"
                    shPart = CreateSheetFromSheetFormat(drawDoc, strSheetName)
                Case PageSizeEnum.D_Size
                    strSheetName = "TTS Part - Arch D"
                    shPart = CreateSheetFromSheetFormat(drawDoc, strSheetName)
                Case PageSizeEnum.E_Size
                    strSheetName = "TTS Part - Arch E1"
                    shPart = CreateSheetFromSheetFormat(drawDoc, strSheetName)
            End Select
            Dim sheet1 As Sheet = drawDoc.Sheets(1)
            Dim pViewPosition As Point2d = tg.CreatePoint2d(sheet1.Width * 2 / 5, sheet1.Height * 3 / 5)
            'choose base view rotation
            Dim viewOrientation As ViewOrientationTypeEnum = ViewOrientationTypeEnum.kArbitraryViewOrientation
            'pick a view orientation from the normal vector???
            Dim viewCamera As Camera = invApp.TransientObjects.CreateCamera()
            viewCamera.SceneObject = Model.InvDoc.ComponentDefinition
            ' viewCamera.ViewOrientationType = ViewOrientationTypeEnum.kFrontViewOrientation
            Dim pntCameraTarget As Inventor.Point = FindMidPoint3D(Model.InvDoc.ComponentDefinition.RangeBox.MinPoint, Model.InvDoc.ComponentDefinition.RangeBox.MaxPoint)
            viewCamera.Target = pntCameraTarget
            Dim pEye As Point = viewCamera.Target
            pEye.TranslateBy(sktNormal.AsVector)
            viewCamera.Eye = pEye
            'viewCamera.UpVector = sktNormal
            viewCamera.Apply()
            Dim viewStyle As DrawingViewStyleEnum = DrawingViewStyleEnum.kHiddenLineDrawingViewStyle
            If HiddenLines = False Then
                viewStyle = DrawingViewStyleEnum.kHiddenLineRemovedDrawingViewStyle
            End If
            'scale base view to fit drawing 75%
            Dim viewWidthLimitInches As Double = 16 * 0.75
            Dim viewHeightLimitInches As Double = 5.5
            'insert base view
            Dim vBase As DrawingView = InsertAndScaleBaseView(drawDoc, Model.InvDoc, sheet1, "", pViewPosition, viewOrientation, viewStyle, False, 1.0, "1""=1""", viewWidthLimitInches, viewHeightLimitInches, viewCamera, , True)
            If EndView = True Then
                'project side view (to show "Thick")
                pViewPosition = tg.CreatePoint2d(sheet1.Width * 4 / 5, vBase.Position.Y)
                Dim vProjected As DrawingView = sheet1.DrawingViews.AddProjectedView(vBase, pViewPosition, viewStyle)
            End If
            If TopView = True Then
                'project top view (to show "Top")
                pViewPosition = tg.CreatePoint2d(vBase.Position.X, sheet1.Height * 4 / 5)
                Dim vProjected As DrawingView = sheet1.DrawingViews.AddProjectedView(vBase, pViewPosition, viewStyle)
            End If
            If IsoMetricView = True Then
                pViewPosition = tg.CreatePoint2d(sheet1.Width * 4 / 5, sheet1.Height * 4 / 5)
                Dim vProjected As DrawingView = sheet1.DrawingViews.AddProjectedView(vBase, pViewPosition, viewStyle)
            End If
            If AutomaticCenterlines Then
                Dim acls As AutomatedCenterlineSettings = Nothing
                vBase.GetAutomatedCenterlineSettings(acls)
                Tools.GlobalAutomaticCenterlineSettings.CopyTo(acls)
                vBase.SetAutomatedCenterlineSettings()
            End If
            drawDoc.Save2(True)
        Catch ex As Exception
            Dim eh As New ErrorHandler(ex)
            eh.HandleIt()
        End Try
        Return drawDoc
    End Function
Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
Message 4 of 7

JamieVJohnson2
Collaborator
Collaborator

While still trying to figure this out, I moved everything, changed reference, all with no effect.  Then I decided to move the guts of FindMidPoint3D() into the main routine to 'skip' the function.  Code processed without error.  Yet ran the function with error (repeatable behavior).  Focusing on the term "Late Binding" from the error, I decided to change the function input point variables from byref to byval.  This made the function work.  (Work around established).

 

Only confusing part is, your example function was also by ref, and worked just fine.  So I know more specifically what the issue is, but I can't 'fix it'. 

 

Byref is used when you want to modify the original in a sub/function, and byval when you want NOT to modify the original.  ByRef uses the same memory address, ByVal copies the object, using more memory.  ByRef is the new default in .Net (ByVal used to be), because it is faster.  All that discussed, still doesn't explain why your example works and mine does not using the EXACT SAME CODE.

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
Message 5 of 7

chandra.shekar.g
Autodesk Support
Autodesk Support

@JamieVJohnson2,

 

invApp is acquired in advance, and stored as a global variable - regular routine coding practice that we follow.


@JamieVJohnson2 wrote:

While still trying to figure this out, I moved everything, changed reference, all with no effect.  Then I decided to move the guts of FindMidPoint3D() into the main routine to 'skip' the function.  Code processed without error.  Yet ran the function with error (repeatable behavior).  Focusing on the term "Late Binding" from the error, I decided to change the function input point variables from byref to byval.  This made the function work.  (Work around established).

 

Only confusing part is, your example function was also by ref, and worked just fine.  So I know more specifically what the issue is, but I can't 'fix it'. 

 

Byref is used when you want to modify the original in a sub/function, and byval when you want NOT to modify the original.  ByRef uses the same memory address, ByVal copies the object, using more memory.  ByRef is the new default in .Net (ByVal used to be), because it is faster.  All that discussed, still doesn't explain why your example works and mine does not using the EXACT SAME CODE.


Usually, passing the parameters as "ByVal" is good practice. By doing this, only value would passed to called function. In pass by "ByRef", there are chances that value might be changed in called function.

 

Thanks and regards,

 


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 6 of 7

JamieVJohnson2
Collaborator
Collaborator

"Usually, passing the parameters as "ByVal" is good practice. By doing this, only value would passed to called function. In pass by "ByRef", there are chances that value might be changed in called function."

 

Generally your statement would be a good blanket response to beginner programmers.  However, over the past 20 years, I've done some experimentation, and used some more advanced techniques where I got a good handle on ByVal vs ByRef.  And since this thread has turned into a discussion of the two (as do many other threads), I'm going to reiterate a brief summary for those who want to know the difference.  So bear with me Chandra until the end.

 

ByVal - copies your object "in the background" and sends the COPIED VALUEs into your sub method.  A value that is sent ByVal does consume more memory and processing power as it copies your object.  The advantage is your sub method CANNOT modify the original object's original values, because it only knows only about the copy.  However this is generally negligible and tends to be ignored by the end user, BUT, if you use this in a process that runs many, many, many cycles, or on a very large object the extra processing does become noticeable.  There are other happenings you must be aware of if your object is a list of objects, that gets tricky, where ByVal copies the list collector's pointer, but not the collection, look into it if your confused.

 

ByRef - creates a pointer to the original object in memory, and sends the pointer into your sub method.  A value that is sent ByRef consumes way less memory and processing power as it IS your original object.  The advantage is your sub method CAN modify the original object's values, because it has direct reference (pointer) to the original object.  This is used when somebody needs to construct a sub method that can modify multiple values from the calling thread, and give them all back as modified (unlike a function that only returns a single object/value).   The down side is also its advantage, since your sub method CAN modify the original object's values, you have to be careful to NOT allow any changes to the passed pointer's target object (original object), unless you intend too.

 

How does all this come into play with my original question?  Well, I constructed a sub function to read some values from two Point2D(s) and return a different Point2D that has the calculated mid point.  This sub function passed in the two original points as ByRef, meaning if I wanted too, I could change the original two point's values in the sub function.  My code did NOT modify any of the original values, as it created new objects to store the new data, and returned a new point back to the original thread.  Yet Inventor still threw an error.  This error DISP_E_MEMBERNOTFOUND is typically raised when a line of code is attempting to run a function or method by name that does not exist, and only an IDE (aka Visual Studio) that has option strict turned off, would allow such a thing knowingly.  However, option strict was turned on, and the IDE found nothing wrong with the code, because nothing was being asked to be done that wasn't properly structured.  That I knew of...  

 

Experimenting with the process, led to the discovery that changing the code to ByVal eliminated the problem.  Since I haven't written any code to change the underlying object, there must be a hidden process (aka built into the Inventor API or .Net framework at the next lower level) that was performing actions on the original two points when the sub method finished, because they were set to ByRef, such as attempting to copy the values (that were not modified) back to the object, using a method member that was not found.  So while changing the call to ByVal stopped the issue (by bypassing the hidden code), it didn't fix it.  The source of the error, aka the code that is calling the missing member, has not been found.  This can be a problem if I wanted to actually modify a(or some) 2D Point(s) using the ByRef method, as it will likely fail just the same (when it shouldn't).

 

Thank you,

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
Message 7 of 7

chandra.shekar.g
Autodesk Support
Autodesk Support

@JamieVJohnson2,

 

Thanks for useful information on ByVal and ByRef.

 

In my sample application, both ByVal and ByRef are working fine.

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes