14 Replies Latest reply on Jun 21, 2017 4:54 AM by Peter Brinkhuis

    Selected lines/points coordinates into array

    Viktor Ács

      Hi,

      Im new to APIs. Im struggling with a concept, because i cant get the type of arrays and selected items right. My idea is basicly: save the selected lines and points coordinates in oder into an array, then read it in a loop, so i can insert a spline to the coordinates and make it tangent with the lines. I know very few codes in API but im familiar with other languages. I can come up with a pseudo code, but i have no idea what am i doing:).

       

      Dim swApp As SldWorks.SldWorks

      Dim swModel As SldWorks.ModelDoc2

      Dim boolstatus As Boolean

       

      Sub main()

      Set SelMgr = swModel.SelectionManager

      Dim numsel As Long

      If (SelMgr.GetSelectedObjectCount = 0) Then

      swApp.SendMsgToUser ("Select points.")

      Else

       

      Dim Points() As Double

      Dim Lines() As Double

      Dim j As Integer

       

      'there could be an if to check if the selected items are points

       

      ReDim Points(numsel)

      For j = 0 To numsel

      'this is probably wrong, i dont get it how can i get the coordinates of selected object

      Set Points(j) = SelMgr.GetSelectedObjectsComponent6(j, -1)

      Next j

       

      'there could be an if to check if the selected items are lines

       

      For j = 0 To numsel

      Set Lines(j) = SelMgr.GetSelectedObjectsComponent6(j, -1)

      Next j

      For j=0 to numsel

       

      Dim pointArray As Variant

      Dim skSegment As Object

      'i just copied a recorded macro, i can probably paste the variables from the array in this, but any help i accept

      Set pointArray = Points(j), Points(j+1)

      Set skSegment = Part.SketchManager.CreateSpline((pointArray))

      boolstatus = Part.Extension.SelectByID2("Spline1", "SKETCHSEGMENT", 0, 1.81015384357535E-02, 2.09337519325041E-02, False, 0, Nothing, 0)

      boolstatus = Part.Extension.SelectByID2("Line1", "SKETCHSEGMENT", 0, 4.71625117067592E-02, 1.10825745525022E-02, True, 0, Nothing, 1)

      Part.SketchAddConstraints "sgTANGENT"

       

      Part.ClearSelection2 True

      boolstatus = Part.Extension.SelectByID2("Spline1", "SKETCHSEGMENT", 0, -3.97741286717577E-02, 7.28987126120142E-02, False, 0, Nothing, 0)

      boolstatus = Part.Extension.SelectByID2("Line2", "SKETCHSEGMENT", 0, -4.44534379272586E-02, 0.10146712701402, True, 0, Nothing, 1)

      Part.SketchAddConstraints "sgTANGENT"

      ' it has to jump to every second j, but i dont know neither how to do it

      j++

      Next j

       

      Debug.Print numsel

      End If

      End Sub

       

      I would be happy for any scratch of information, and again to be clear, im lack of the basic knowledge of macros, i can only barely understand other people's macros, so i work from those with copy/paste, i only understand the basic programming stuff like loops and codestructure. thx for any help

        • Re: Selected lines/points coordinates into array
          Viktor Ács

          Ok, im tried to study and leanr step by step, here is what i got so far:

           

          Dim swApp As Object

           

          Dim Part As Object

          Dim boolstatus As Boolean

          Dim longstatus As Long, longwarnings As Long

          Dim Points() As Vertex

          Dim Lines() As Edge

          Dim numsel As Long

          Dim i As Integer

          Dim nLines As Integer

          Dim nPoints As Integer

           

          Sub main()

           

          Set swApp = Application.SldWorks

          Set Part = swApp.ActiveDoc

          Set SelMgr = Part.SelectionManager

           

          numsel = SelMgr.GetSelectedObjectCount

          nPoints = 0

          nLines = 0

          ReDim Preserve Points(nPoints)

          ReDim Preserve Lines(nLines)

           

          If (numsel = 0) Then

              swApp.SendMsgToUser ("Válassz ki valamit.")

          Else

           

          Debug.Print numsel

           

          For i = 0 To numsel - 1

              If SelMgr.GetSelectedObjectType3(i, -1) = 3 Then

                    nPoints = nPoints + 1

                    Set Points(nPoints) = SelMgr.GetSelectedObjects6(i, -1).GetPoint

                    Debug.Print Points(nPoints)

              End If

          Next i

           

          For i = 0 To numsel - 1

              If SelMgr.GetSelectedObjectType3(i, -1) = 1 Then

                    nLines = nLines + 1

                    Set Lines(nLines) = SelMgr.GetSelectedObjects6(i, -1).GetPoint

                    Debug.Print Lines(nLines)

              End If

          Next i

           

          Part.SketchManager.Insert3DSketch True

          Dim skSegment As Object

          For i = 0 To nPoints

           

          Set skSegment = Part.SketchManager.CreateSpline(0, 0, 0, 1, 1, 1)

          i = i + 1

          Next i

           

          Debug.Print nLines

          Debug.Print nPoints

           

          End If

          End Sub

           

          Obviusly it doesnt work, i think it bleeds from several wounds. I just posted to show how much i dont understand this stuff, but i dont give up.

          Debugs shows the number of selected items, but it give me zero for lines and points. I know i basicly ask u to make this macro instead of me, but im happy for any advice or given example. Thanks again for any reply.

            • Re: Selected lines/points coordinates into array
              Viktor Ács

              I really dont want to spam my own post, but here is my latest non-working badly wounded pseudo code:

               

              Dim swApp As Object

               

              Dim Part As Object

              Dim boolstatus As Boolean

              Dim longstatus As Long, longwarnings As Long

              Dim Points() As SketchPoint

              Dim Lines() As SketchLine

              Dim numsel As Long

              Dim i As Integer

              Dim nLines As Integer

              Dim nPoints As Integer

               

              Sub main()

               

              Set swApp = Application.SldWorks

              Set Part = swApp.ActiveDoc

              Set SelMgr = Part.SelectionManager

               

              numsel = SelMgr.GetSelectedObjectCount

              nPoints = 0

              nLines = 0

               

              If (numsel = 0) Then

                  swApp.SendMsgToUser ("Select points and lines.")

              Else

               

              For i = 0 To numsel

                  If SelMgr.GetSelectedObjectType3(i, -1) = 25 Then

                        nPoints = nPoints + 1

                        ReDim Preserve Points(nPoints)

                        Set Points(nPoints) = SelMgr.GetSelectedObjects6(i, -1).GetPoints

                  End If

              Next i

               

              For i = 0 To numsel

                  If SelMgr.GetSelectedObjectType3(i, -1) = 24 Then

                        nLines = nLines + 1

                        ReDim Preserve Lines(nLines)

                        Set Lines(nLines) = SelMgr.GetSelectedObjects6(i, -1)

                  End If

              Next i

               

              Part.ClearSelection2 True

              Part.SketchManager.Insert3DSketch True

               

              For i = 0 To nLines

                      boolstatus = Lines(i)

                      boolstatus = Part.SketchManager.SketchUseEdge3(False, False)

                      Part.ClearSelection2 True

              Next i

               

              Dim skSegment As Object

               

              For i = 0 To nPoints

                  Set skSegment = Part.SketchManager.CreateSpline(Points(i), Points(i + 1))

                  i = i + 1

                  Part.ClearSelection2 True

                  boolstatus = Part.Extension.SelectByID2("Spline" & i, "SKETCHSEGMENT", 0, 0, 0, False, 0, Nothing, 0)

                  boolstatus = Part.Extension.SelectByID2("Line" & i, "SKETCHSEGMENT", 0, 0, 0, True, 0, Nothing, 1)

                  Part.SketchAddConstraints "sgTANGENT"

                  Part.ClearSelection2 True

                  boolstatus = Part.Extension.SelectByID2("Spline" & i, "SKETCHSEGMENT", 0, 0, 0, False, 0, Nothing, 0)

                  boolstatus = Part.Extension.SelectByID2("Line" & i + 1, "SKETCHSEGMENT", 0, 0, 0, True, 0, Nothing, 1)

                  Part.SketchAddConstraints "sgTANGENT"

                  Part.ClearSelection2 True

              Next i

               

              End If

              End Sub

               

              I do understand, that there are huge problems with the array, and probably there are more problems with the code, but if anyone can help me with the arrays, to set up right, maybe i can progress and solve the rest myself. Also i dont understand how do i create a spline with this line:

              Set skSegment = Part.SketchManager.CreateSpline(Points(i), Points(i + 1))

              it gives me an error, even if i change the nonworking points() to something that makes sense, but i just copied from a recorded macro.

                • Re: Selected lines/points coordinates into array
                  Peter Brinkhuis

                  I got started with your code, added some functions to clean it up. I changed the loop lower value for i from 0 to 1 because the selection manager starts at one. I renamed Part to swModel as is the tradition here. I didn't get the chance to run it yet, sorry

                  I got to the bold section, that code is now in the bottom function. What are you trying to do there? The line boolstatus = Lines(i) doesn't really make sense and wouldn't work. Are you trying to select all lines? Do you need them all in one selection set or do you need to select them individually? If you have their names, you can use swModel.SelectByID, but it would be better to use their Persistent ID. Look it up

                   

                  I'll get back to you when you need some more help.

                   

                  Option Explicit

                   

                  Dim swApp As SldWorks.SldWorks

                  Dim swModel As ModelDoc2

                  Dim selMgr As SelectionMgr

                   

                  Sub main()

                      Dim boolstatus As Boolean

                      Dim longstatus As Long, longwarnings As Long

                      Dim Points() As SketchPoint

                      Dim Lines() As SketchLine

                     

                      Set swApp = Application.SldWorks

                      Set swModel = swApp.ActiveDoc

                      Set selMgr = swModel.SelectionManager

                      

                      If selMgr.GetSelectedObjectCount = 0 Then

                          swApp.SendMsgToUser ("Please select a few points and lines first.")

                      Else

                          

                          FindSelectedPoints Points

                          FindSelectedLines Lines

                         

                          swModel.ClearSelection2 True

                          swModel.SketchManager.Insert3DSketch True

                          

                          UseSketchEdges Lines

                   

                          Dim skSegment As Object

                          

                          For i = 0 To nPoints

                              Set skSegment = swModel.SketchManager.CreateSpline(Points(i), Points(i + 1))

                              i = i + 1

                              swModel.ClearSelection2 True

                              boolstatus = swModel.Extension.SelectByID2("Spline" & i, "SKETCHSEGMENT", 0, 0, 0, False, 0, Nothing, 0)

                              boolstatus = swModel.Extension.SelectByID2("Line" & i, "SKETCHSEGMENT", 0, 0, 0, True, 0, Nothing, 1)

                              swModel.SketchAddConstraints "sgTANGENT"

                              swModel.ClearSelection2 True

                              boolstatus = swModel.Extension.SelectByID2("Spline" & i, "SKETCHSEGMENT", 0, 0, 0, False, 0, Nothing, 0)

                              boolstatus = swModel.Extension.SelectByID2("Line" & i + 1, "SKETCHSEGMENT", 0, 0, 0, True, 0, Nothing, 1)

                              swModel.SketchAddConstraints "sgTANGENT"

                              swModel.ClearSelection2 True

                          Next i

                      End If

                  End Sub

                   

                  Function FindSelectedPoints(ByRef Points() As SketchPoint)

                      Dim i As Integer

                      For i = 1 To selMgr.GetSelectedObjectCount

                          If selMgr.GetSelectedObjectType3(i, -1) = 25 Then

                              ReDim Preserve Points(UBound(Points) + 1)

                              Set Points(UBound(Points)) = selMgr.GetSelectedObjects6(i, -1).GetPoints

                          End If

                      Next i

                  End Function

                   

                  Function FindSelectedLines(ByRef Lines() As SketchLine)

                      Dim i As Integer

                     

                      For i = 1 To selMgr.GetSelectedObjectCount

                          If selMgr.GetSelectedObjectType3(i, -1) = 24 Then

                              ReDim Preserve Points(UBound(Lines) + 1)

                              Set Lines(UBound(Lines)) = selMgr.GetSelectedObjects6(i, -1)

                          End If

                      Next i

                  End Function

                   

                  Function UseSketchEdges(Lines() As SketchLine)

                      Dim i As Integer

                      For i = 0 To UBound(Lines)

                          boolstatus = Lines(i)

                          swModel.SketchManager.SketchUseEdge3 False, False

                          swModel.ClearSelection2 True

                      Next i

                  End Function

                    • Re: Selected lines/points coordinates into array
                      Viktor Ács

                      Thanks for the answer i will study your code, i like it very much thanks again. I'll look up persistent id, to be fair, i dont even know what i wanted to do there, i guess i can select all lines then convert, it doesnt have to be individually.

                      • Re: Selected lines/points coordinates into array
                        Viktor Ács

                        Your code looks very promising. but i'm afraid there are still problems with creating the array, at this line:

                        ReDim Preserve Points(UBound(Lines) + 1)

                        and

                        ReDim Preserve Lines(UBound(Lines) + 1)

                        it give me the error: runtime error 9 subscript out of range, i have managed to fix this by making the array 3x larger and save x y z as individual in the array but at the ReDim Lines it still gives me the runtime error 438 Object doesn't support this property or method.

                        • Re: Selected lines/points coordinates into array
                          Viktor Ács

                          I eliminated most of the errors and it turns out, that the Selectedobject6() gives me the 438 Object Doesn't Support This Property or Method error, even if i select a point and run this simple macro which i got from apihelp examples:

                          Dim swApp As SldWorks.SldWorks

                          Dim swModel As ModelDoc2

                          Dim selMgr As SelectionMgr

                          Dim debugtest As SketchPoint

                           

                          Set swApp = Application.SldWorks

                          Set swModel = swApp.ActiveDoc

                          Set selMgr = swModel.SelectionManager

                           

                          Debug.Print selMgr.GetSelectedObjectCount

                          Set debugtest = selMgr.GetSelectedObjects6(1, 0)

                          Debug.Print debugtest.X

                          i tried with debugtest.Name and debugtest.GetPoint. Nothing works. I have no idea what am i doing wrong, i really do need your help.

                            • Re: Selected lines/points coordinates into array
                              John Alexander

                              Just to be clear, when you are testing this macro, are you selecting a sketch point or are you selecting a vertex?

                               

                              Sketch Point - drawn by the user

                               

                              Vertex - generated from model geometry

                               

                              GetSelectedObject returns several types depending on what you have selected. This is why the pattern usually involves looping over all selected entities, checking their type with GetSelectedObjectType, and then assigning to the appropriate object. There are several examples of that in this thread.

                               

                              In the sample code, they took a lazy shortcut and assumed that the first selection in the list is a sketch point. Those examples often demonstrate how to use a certain function but neglect to do it in a way that is robust.

                                • Re: Selected lines/points coordinates into array
                                  Viktor Ács

                                  I wanted to use sketchpoints, and i have managed to make a half working macro, but then i realised, maybe skecthpoints doesnt work for me neither. I want a macro for selecting points and lines in an assembly, then create splines to the points and make them tangents with the lines in selection order, just like autorouting.

                                  Set Points(nPoints) = selMgr.GetSelectedObject6(i, -1)

                                  I save the points in the array then make another array for the spline like this:

                                  Dim pointArray As Variant

                                  Dim pointss() As Double

                                  ReDim pointss(0 To 5) As Double

                                  pointss(0) = Points(2 * i).X

                                  pointss(1) = Points(2 * i).Y

                                  pointss(2) = Points(2 * i).Z

                                  pointss(3) = Points(2 * i + 1).X

                                  pointss(4) = Points(2 * i + 1).Y

                                  pointss(5) = Points(2 * i + 1).Z

                                  pointArray = pointss

                                  Set skSegment = swModel.SketchManager.CreateSpline(pointArray)

                                  I know its a really dumb way to do it but i couldnt make to work otherwise. The problem is if i make a 3d sketch, and select 2 point, it creates the spline perfectly, but when i make a 2d sketch, the splines change their xyz axis and is perpendicular to the skecth plane, and in the assembly it doesnt create the spline in the coordinates of the selected points in the assembly, instead it inserts in the coordinates of the selected points in their parts. I dont know how to fix this, sorry for my bad english i hope i was clear.

                                    • Re: Selected lines/points coordinates into array
                                      John Alexander

                                      So you are looping over all selections, collecting valid sketch points, and reformatting the coordinates as [x1,y1,z1,x2,y2,z2]. Now, the sketch points that you are selecting, what sketch do they belong to? Are they in the same sketch that the spline is being created in?

                                       

                                      When you are calling CreateSpline, are you activating a particular sketch or just letting it generate a new sketch for you? I would recommend creating the sketch programmatically so you are less dependent on the user's behavior.

                                       

                                      2012 SOLIDWORKS API Help - CreateSpline Method (ISketchManager)

                                      Remarks

                                      This method creates a spline in the active 2D sketch. If a sketch is not active, then a new sketch is created. Use ISketchManager::ActiveSketch to check if the sketch active.

                                      The PointData array is a set of, at least, two X, Y, Z values. The X value for the start point of the spline is PointData[0], the Y value for the start point is PointData[1], and the Z value for the start point is PointData[2]. The X value for the next point is PointData[3], and so on.

                                      This method does not work with ISketchManager::AddToDB or ISketchManager::DisplayWhenAdded. It always adds the spline directly to the database (as if ISketchManager::AddToDB(True) was in effect), and you must redraw your document window to see the entities that you added (as if ISketchManager::DisplayWhenAdded(False) was in effect).

                                      In 2D sketches, SolidWorks ignores the Z value in PointData.

                                      Can you post a screenshot of the before and after for 3D and 2D sketch points? My guess is that you are using sketch points selected from one sketch to draw the spline in another sketch. The problem with this is that you need to transform the points from one sketch's coordinate system to the other.

                                       

                                      To do that, check out ModelToSketchTransform and read about how to manipulate Solidworks MathPoints with MathTransforms.

                          • Re: Selected lines/points coordinates into array
                            John Alexander

                            I had to draw splines for a macro a little bit ago. I wrote this function to draw splines on a particular layer.

                             

                            It takes a drawing document, an array of math points, and a layer on which to draw the spline.

                             

                            Public Function drawSpline(swModel As SldWorks.ModelDoc2, swMathPoints() As SldWorks.MathPoint, swLayer As SldWorks.Layer)

                                Dim swSketchSegment     As SldWorks.SketchSegment

                                Dim pointData()         As Double

                               

                                Dim bRet    As Boolean

                                Dim i       As Integer

                               

                               

                                swModel.SketchManager.InferenceMode = False

                                swModel.SketchManager.AddToDB = True

                                ReDim pointData(3 * (UBound(swMathPoints) + 2) - 1)

                                For i = 0 To (UBound(swMathPoints))

                                    pointData(3 * i) = swMathPoints(i).ArrayData(0)

                                    pointData(3 * i + 1) = swMathPoints(i).ArrayData(1)

                                    pointData(3 * i + 2) = 0#

                                Next i

                               

                                pointData(3 * i) = swMathPoints(0).ArrayData(0)

                                pointData(3 * i + 1) = swMathPoints(0).ArrayData(1)

                                pointData(3 * i + 2) = 0#

                               

                                Set swSketchSegment = swModel.SketchManager.CreateSpline2(pointData, True)

                                swSketchSegment.Layer = swLayer.Name

                                swModel.SketchManager.InferenceMode = True

                                swModel.SketchManager.AddToDB = False

                               

                                swModel.Rebuild swRebuildOptions_e.swCurrentSheetDisp

                            End Function

                            I think in your code, you are trying to pass sketch points instead of mathpoints. Mathpoints are just a helpful container for coordinate data. Some functions in the Solidworks API use them while others don't.

                            • Re: Selected lines/points coordinates into array
                              Viktor Ács

                              Thx all the answers, i can learn alot from this, but u missed my bane=( creating array with the coordiantes of the points. Can anyone help me with that?