8 Replies Latest reply on Jun 1, 2017 2:40 PM by Greg James

    GetObjectByPersistReference3 fails for ref I just got (in Assembly)

    Greg James

      The following code throws my exception when run from an Assembly.

      Why does the ModelDoc2 not accept a persistreference3 that it just handed me?

       

              const int PERSIST_REF_OBJ_OK = (int)swPersistReferencedObjectStates_e.swPersistReferencedObject_Ok;

       

              public List<object> SegmentsToPersistRefs(List<SketchSegment> segments)

              {

                  Debug.Print("SegmentsToPersistRefs called for list of " + segments.Count);

                  List<object> refs = new List<object>();

                  foreach (SketchSegment seg in segments)

                  {

                      object pid = mDoc.Extension.GetPersistReference3(seg);

                      if (pid == null)

                      {

                          throw new ApplicationException("SketchSegment GetPersistReference3 is null");

                      }

       

                      int errorCode;

                      object obj = mDoc.Extension.GetObjectByPersistReference3(pid, out errorCode);

                      if (errorCode != PERSIST_REF_OBJ_OK)

                      {

                          // *** ENDS UP HERE with errorCode = 1 == INVALID ***

                          throw new ApplicationException("Cannot get object from PersistRef3 we just got");

                      }

                      refs.Add(pid);

                  }

                  return refs;

              }

        • Re: GetObjectByPersistReference3 fails for ref I just got (in Assembly)
          Josh Brady

          I don't play with C stuff... But is your type correct for pid?  Looks like you're saying it's an object.  pid will be an array of bytes I think (per the help file).  This is a bit over my head, but since you are using C don't you need to use the second argument of GetPersistReference3 in order to know how many elements are in the byte array that's returned?  I think you don't need that in the VBA example due to the VBA version going to a Variant.

          • Re: GetObjectByPersistReference3 fails for ref I just got (in Assembly)
            Josh Brady

            You said it throws the exception in an assembly... Does this mean it works in parts?

             

            In VBA land I can't get this to not work:

             

            Dim swApp As SldWorks.SldWorks

            Dim swDoc As SldWorks.ModelDoc2

            Dim swExt As SldWorks.ModelDocExtension

            Dim swSelMgr As SldWorks.SelectionMgr

            Dim oObj As Object

            Dim vRef As Variant

            Dim i As Long

            Dim j As Long

            Dim sRef As String

            Dim failCode As Long

            Dim theType As swSelectType_e

             

             

             

             

            Sub main()

             

             

            Set swApp = Application.SldWorks

            Set swDoc = swApp.ActiveDoc

            Set swExt = swDoc.Extension

            Set swSelMgr = swDoc.SelectionManager

             

             

            For i = 1 To swSelMgr.GetSelectedObjectCount2(-1)

                vRef = swExt.GetPersistReference3(swSelMgr.GetSelectedObject6(i, -1))

                theType = swSelMgr.GetSelectedObjectType3(i, -1)

                sRef = ""

                Debug.Print "Object type: " & theType & "  ID length: " & UBound(vRef)

                For j = 0 To UBound(vRef)

                    sRef = sRef & " " & vRef(j)

                Next j

                Debug.Print sRef

                Set oObj = Nothing

                Set oObj = swExt.GetObjectByPersistReference3(vRef, failCode)

                Debug.Print "Object is Nothing? " & (oObj Is Nothing) & " Fail code: " & failCode

            Next i

               

             

             

            End Sub

              • Re: GetObjectByPersistReference3 fails for ref I just got (in Assembly)
                Greg James

                Thanks Josh - They work great in Parts docs using 'object'.  That's what the SolidWorks C# API deals with, so I don't have to poke in to the bytes.  All C# class instances can be passed around as that ultimate base 'object'.  I use them to track SketchSegments during and between invocations of my PropertyManagerPage.  They survive edits and rebuilds, and they tell me if the thing they reference has been deleted.  It's great.... when working with a Part.

                 

                Now I'm trying something similar in an Assembly doc, and it's all gone sideways.  At first, I thought it might be related to the difference between the Assembly 'top-level' ModelDoc2  vs. the ModelDoc2 instances I can get from the Assembly Components.  Doesn't seem to be.  I've tried all combinations of Get/Set with the ModelDoc2 instances that I get in various ways.  For example, from an Attribute:

                 

                //  Attribute attr.  Below is edited for brevity.  The instances are valid., and calls to them do the right thing.

                object entObj = attr.GetEntity2();

                Entity ent = (Entity)entObj;

                Component2 comp2 = ent.IGetComponent2();

                ModelDoc2 compDoc = (ModelDoc2)comp2.GetModelDoc2();

                // My other way to a ModelDoc2 is the SwApp ActiveDoc

                 

                I'll try to get examples of the bytes after this meeting I'm supposed to be in =/

                  • Re: GetObjectByPersistReference3 fails for ref I just got (in Assembly)
                    Josh Brady

                    Did you also edit your original code for brevity?  Are you using the same ModelDoc2 to obtain the reference that you are using to select by that reference?  Once you get to an assembly, the persistent reference for the sketch segments changes.  If you get the segments PID in the context of the assembly's ModelDoc2 and then try to select them in the part's ModelDoc2 it won't work.

                     

                    Dim swApp As SldWorks.SldWorks
                    Dim swDoc As SldWorks.ModelDoc2
                    Dim swExt As SldWorks.ModelDocExtension
                    Dim swSelMgr As SldWorks.SelectionMgr
                    Dim swSelComp As SldWorks.Component2
                    Dim swSelDoc As SldWorks.ModelDoc2
                    Dim oObj As Object
                    Dim vRef As Variant
                    Dim i As Long
                    Dim j As Long
                    Dim sRef As String
                    Dim failCode As Long
                    Dim theType As swSelectType_e
                    
                    Sub main()
                    
                    Set swApp = Application.SldWorks
                    Set swDoc = swApp.ActiveDoc
                    Set swExt = swDoc.Extension
                    Set swSelMgr = swDoc.SelectionManager
                    
                    For i = 1 To swSelMgr.GetSelectedObjectCount2(-1)
                        vRef = swExt.GetPersistReference3(swSelMgr.GetSelectedObject6(i, -1))
                        Set swSelComp = swSelMgr.GetSelectedObjectsComponent4(i, -1)
                        Set swSelDoc = swSelComp.GetModelDoc2
                        theType = swSelMgr.GetSelectedObjectType3(i, -1)
                        sRef = ""
                        Debug.Print "Object type: " & theType & "  ID length: " & UBound(vRef)
                        For j = 0 To UBound(vRef)
                            sRef = sRef & " " & vRef(j)
                        Next j
                        Debug.Print sRef
                        Set oObj = Nothing
                        Set oObj = swExt.GetObjectByPersistReference3(vRef, failCode)
                        Debug.Print "Object is Nothing in Active doc? " & (oObj Is Nothing) & " Fail code: " & failCode
                        Set oObj = Nothing
                        Set oObj = swSelDoc.Extension.GetObjectByPersistReference3(vRef, failCode)
                        Debug.Print "Object is Nothing in Component's doc? " & (oObj Is Nothing) & " Fail code: " & failCode & vbCrLf
                    Next i
                    
                    
                    End Sub
                    
                      • Re: GetObjectByPersistReference3 fails for ref I just got (in Assembly)
                        Greg James

                        >Did you also edit your original code for brevity? 

                        Nope.  Original code is as is. 

                         

                        > Are you using the same ModelDoc2 to obtain the reference that you are using to select by that reference?

                        Yes, using the same ModelDoc2, as in the code above.  I've called that func with all the ModelDoc2 that I can find, in various ways.  All have the same issue.  I've also tried querying one ModelDoc2 with refs from another ModelDoc2, just in case, and have tried all the combinations of getting from one and querying from another.

                         

                        > If you get the segments PID in the context of the assembly's ModelDoc2 and then try to select them in the part's ModelDoc2 it won't work

                        Seems reasonable to expect that to fail, but I'm not trying that.  I'm seeing this problem completely within the context of an Assembly.  I never open a Part separately or get PersistRefs from a Part and then try them in an assembly.  I'm in the assembly the whole time.  I trigger the code by hitting a button in my PropertyManagerPage.

                         

                        If I relaunch SolidWorks and trigger that same code from a Part, everything works fine.

                        My SubmitABug finger is tingling

                         

                          • Re: GetObjectByPersistReference3 fails for ref I just got (in Assembly)
                            Josh Brady

                            Can you examine the value of PID?  Can you compare those values to the ones reported by my VBA macro?

                             

                            Where is the list of sketch segments coming from?  Again, not a C guy, but it looks like you're passing in a list from somewhere to this function.  How is the list created?  Can you create a similar function to mine that just gets PIDs from the current selection set?  If you are pulling the list out of a selection box that SolidWorks populates, the list of objects themselves may be in part context rather than assembly.

                             

                            Dim swApp As SldWorks.SldWorks
                            Dim swDoc As SldWorks.ModelDoc2
                            Dim swExt As SldWorks.ModelDocExtension
                            Dim swSelMgr As SldWorks.SelectionMgr
                            Dim swSelComp As SldWorks.Component2
                            Dim swSelDoc As SldWorks.ModelDoc2
                            Dim oObj As Object
                            Dim vRef As Variant
                            Dim bRef() As Byte
                            Dim theLen As Long
                            Dim i As Long
                            Dim j As Long
                            Dim sRef As String
                            Dim failCode As Long
                            Dim theType As swSelectType_e
                            
                            Sub main()
                            
                            Set swApp = Application.SldWorks
                            Set swDoc = swApp.ActiveDoc
                            Set swExt = swDoc.Extension
                            Set swSelMgr = swDoc.SelectionManager
                            
                            For i = 1 To swSelMgr.GetSelectedObjectCount2(-1)
                                vRef = swExt.GetPersistReference3(swSelMgr.GetSelectedObject6(i, -1))
                                theLen = swExt.GetPersistReferenceCount3(swSelMgr.GetSelectedObject6(i, -1))
                                ReDim bRef(theLen)
                                bRef = swExt.GetPersistReference3(swSelMgr.GetSelectedObject6(i, -1))
                                Set swSelComp = swSelMgr.GetSelectedObjectsComponent4(i, -1)
                                Set swSelDoc = swSelComp.GetModelDoc2
                                theType = swSelMgr.GetSelectedObjectType3(i, -1)
                                sRef = ""
                                Debug.Print "Object type: " & theType & "  Array length: " & UBound(vRef) + 1 & " Reported length: " & theLen
                                For j = 0 To UBound(vRef)
                                    If vRef(j) <> bRef(j) Then
                                        sRef = sRef & "!!!"
                                    End If
                                    sRef = sRef & " " & vRef(j)
                                Next j
                                Debug.Print sRef
                                Set oObj = Nothing
                                Set oObj = swExt.GetObjectByPersistReference3(vRef, failCode)
                                Debug.Print "Object is Nothing in Active doc? " & (oObj Is Nothing) & " Fail code: " & failCode
                                'Set oObj = Nothing
                                'Set oObj = swSelDoc.Extension.GetObjectByPersistReference3(vRef, failCode)
                                'Debug.Print "Object is Nothing in Component's doc? " & (oObj Is Nothing) & " Fail code: " & failCode & vbCrLf
                                Set oObj = swSelDoc.Extension.GetCorresponding(oObj)
                                Debug.Print "Got object in part context? " & Not (oObj Is Nothing)
                                vRef = swSelDoc.Extension.GetPersistReference3(oObj)
                                sRef = ""
                                For j = 0 To UBound(vRef)
                                    sRef = sRef & " " & vRef(j)
                                Next j
                                Debug.Print sRef
                                Set oObj = swSelComp.GetCorresponding(oObj)
                                Debug.Print "Got object back in assembly context? " & Not (oObj Is Nothing)
                                vRef = swExt.GetPersistReference3(oObj)
                                sRef = ""
                                For j = 0 To UBound(vRef)
                                    sRef = sRef & " " & vRef(j)
                                Next j
                                Debug.Print sRef
                            Next i
                            
                    • Re: GetObjectByPersistReference3 fails for ref I just got (in Assembly)
                      Greg James

                      Found the problem.  I was using a part's ModelDoc2, which came from looking from a sketch up to its parent document.  If I switch to the ModelDoc2 for the .SLDASM, the GetObjectByPersistReference3() works. 

                       

                      After opening my .SLDASM doc, there are three ModelDoc2 that can be found from SwApp.GetFirstDocument() and ModelDoc2.GetNext().

                      // ModelDoc2 GetPathName(): sled_01.SLDPRT

                      //     next  GetPathName(): test_part_03.SLDPRT

                      //     next  GetPathName(): sled_and_part.SLDASM

                       

                      If I use the ModelDoc2 for the .SLDASM, everything works.