1
$\begingroup$

Is it possible to ( how do you ) export a series of points along a spline. A spline has been created in 3d from various segments. I would like to export a table of 3d points along the spline starting at one end and every mm or so along the spline.

The result would be a file with Z,Y,Z points that are every mm along the spline.
I want to end up with lots of little line segments that approximate the spine.

I have seen a few tutorials on how to export intersection points but that in not what I am looking for.

Thanks

$\endgroup$
3
  • $\begingroup$ eng-tips.com/viewthread.cfm?qid=371022 $\endgroup$ Feb 17, 2019 at 20:24
  • $\begingroup$ @Biswajit Banerjee can you post this as an answer so I may mark it as such. $\endgroup$
    – Burtski
    Feb 25, 2019 at 21:00
  • $\begingroup$ You could post the solution that worked for you as an answer and accept that. I haven't tested the proposed approach and can't vouch for its accuracy. $\endgroup$ Feb 25, 2019 at 21:15

1 Answer 1

0
$\begingroup$

Answering my own question in hopes others will stumble upon it. I did not find an acceptable way to directly export points off a spline.
Attached is my two part solution.
I was able to export the parameters that define the spline from Solidworks and then process that data with a small python script.

Here is the VBA script to run in Solidworks that will export the data for a spline.
In my particular application it is looking for two 3d sketches (centerLineFull and rackPosFull), each of these sketches has exactly 1 spline.
The parameters of the spline are then output to a file that is formated to look like a python dictionary.
You will need to modify all of this for your needs.. but you get the idea..
[A lot of this was lifted from various Solidworks API help files. There are a lot of goof search terms in here that will lead to the correct places in the API help files ]

    Attribute VB_Name = "Macro21"
Option Explicit
    Dim swApp As SldWorks.SldWorks
    Dim Part As SldWorks.ModelDoc2
    Dim swSelectMgr As SldWorks.SelectionMgr
    Dim swFeature As Feature
    Dim swSketch As Sketch

    Dim swSketchSeg As SldWorks.SketchSegment
    Dim swCurveIn As SldWorks.Curve
    Dim varSplineParams As Variant
    Dim success As Boolean
    Dim swActiveSketch As Sketch

    Dim SketchSegments As Variant
    Dim SketchSegment As Variant
    Dim swSketchSegment As SketchSegment

    Dim FilePath As String
    Dim FileName As String



Dim boolstatus As Boolean
Dim longstatus As Long, longwarnings As Long
Dim myModelView As Object




' Extract two integer values out of a single
' double value, assuming that a C int has 4 bytes
Type DoubleRec
    dValue As Double
End Type
Type Int2Rec
    iLower As Long
    iUpper As Long
End Type

' Extract two integer values out of a single
' double value, by assigning a DoubleRec to the
' double value then copying the value over an
' Int2Rec and extracting the integer values
Function ExtractFields(dValue As Double, iLower As Integer, iUpper As Integer)
    Dim dr As DoubleRec
    Dim i2r As Int2Rec
    ' Set the double value
    dr.dValue = dValue
    ' Copy the values
    LSet i2r = dr
    ' Extract the values
    iLower = i2r.iLower
    iUpper = i2r.iUpper
End Function
Sub SplineDump(varSplineParams As Variant)
    Dim dTmpValue As Double
    Dim iNumKnots As Integer
    Dim iNumCtrlPts As Integer
    Dim iDimension As Integer
    Dim iOrder As Integer
    Dim iPeriodicity As Integer
    Dim iSplineArraySize As Integer
    Dim iSplineIndex As Integer
    Dim iVarIndex As Integer
    Dim i As Integer
    dTmpValue = varSplineParams(0)
    ExtractFields dTmpValue, iDimension, iOrder
    dTmpValue = varSplineParams(1)
    ExtractFields dTmpValue, iNumCtrlPts, iPeriodicity
    'Debug.Print "Dimension "; iDimension, " Order"; iOrder, " NumCtrlsPts"; iNumCtrlPts, "Periodicity "; iPeriodicity
    Print #1, "'Dimension':"; iDimension; ","
    Print #1, "'Order':"; iOrder; ","
    Print #1, "'NumberOfControlPoints':"; iNumCtrlPts; ","
    Print #1, "'Periodicity':", iPeriodicity; ","
    Print #1, "'KnotPoints':["
    iNumKnots = iOrder + iNumCtrlPts
    iVarIndex = 2

    For i = 0 To (iNumKnots - 1)
    Print #1, varSplineParams(iVarIndex); ","
    iVarIndex = iVarIndex + 1
    Next i
    Print #1, "],"
    Print #1, "#End of Knot Points"
    Print #1, ""
    Print #1, "#Control Points..."
    Print #1, "'ControlPoints':["
    For i = 0 To (iNumCtrlPts - 1)
    Dim j As Long
    Dim X, Y, Z As Double
    X = varSplineParams(iVarIndex) * 1000#
    Y = varSplineParams(iVarIndex + 1) * 1000
    Z = varSplineParams(iVarIndex + 2) * 1000
    'Debug.Print X, Y, Z
    Print #1, "[";
    Write #1, X, Y, Z;
    Print #1, "],"
    iVarIndex = iVarIndex + 3
    Next i
    Print #1, "],"
    Print #1, "#End of Control Points"
End Sub
Sub SelectStartFeature()
    Dim SketchArcs As Variant
    Dim SketchArc As Variant
    Dim SketchPoints As Variant
    Dim SketchPoint As Variant
    Dim swSketchPoint As SketchPoint
    Dim swArcType As SketchArc
    Dim Point(2) As Double
    Dim PointVariant As Variant
    Dim swXForm As MathTransform
    Dim swMathUtil As MathUtility
    Dim swMathPt As MathPoint
    Dim status As Boolean
    Dim work As String
    Dim i As Integer


    Print #1, "#Start Features"
    status = Part.Extension.SelectByID2("start", "SKETCH", 0, 0, 0, False, 0, Nothing, 0)
    Debug.Print "Selected Shetch 'start' is ", status
    Set swFeature = swSelectMgr.GetSelectedObject6(1, 0)
    Set swSketch = swFeature.GetSpecificFeature2
    Set swXForm = swSketch.ModelToSketchTransform
    Set swXForm = swXForm.Inverse
    Set swMathUtil = swApp.GetMathUtility

    Debug.Print "Sketch is in 3d:"; swSketch.Is3D

    Debug.Print "Number of arcs ", swSketch.GetArcCount
    Print #1, "'NumberArcsFound':", swSketch.GetArcCount; ","
    SketchArcs = swSketch.GetArcs2
    Debug.Print "Arc Center on Sketch", SketchArcs(12) * 1000, SketchArcs(13) * 1000, SketchArcs(14) * 1000
    'Create a Temporary point to use to transform from Sketch coor to model
    Point(0) = SketchArcs(12)
    Point(1) = SketchArcs(13)
    Point(2) = SketchArcs(14)
    PointVariant = Point
    Set swMathPt = swMathUtil.CreatePoint(PointVariant)
    Set swMathPt = swMathPt.MultiplyTransform(swXForm)
    Debug.Print "Arc Center in Model", swMathPt.ArrayData(0) * 1000, swMathPt.ArrayData(1) * 1000, swMathPt.ArrayData(2) * 1000
    Print #1, "'ArcCenter':[";
    Write #1, swMathPt.ArrayData(0) * 1000, swMathPt.ArrayData(1) * 1000, swMathPt.ArrayData(2) * 1000;
    Print #1, "],"
    Print #1, "'NumberPointsFound':", swSketch.GetSketchPointsCount2; ","
    Print #1, ""
    Debug.Print "Number of points", swSketch.GetSketchPointsCount2
    i = 0
    SketchPoints = swSketch.GetSketchPoints2
    For Each SketchPoint In SketchPoints
    work = "'Point" + CStr(i) + "':"
    i = i + 1
    Set swSketchPoint = SketchPoint
    'Debug.Print swSketchPoint.Type, swSketchPoint.X, swSketchPoint.Y, swSketchPoint.Z
    If swSketch.Is3D Then
        Debug.Print swSketchPoint.Type, swSketchPoint.X, swSketchPoint.Y, swSketchPoint.Z
    Else
        Point(0) = swSketchPoint.X
        Point(1) = swSketchPoint.Y
        Point(2) = swSketchPoint.Z
        PointVariant = Point

        Set swXForm = swSketch.ModelToSketchTransform
        Set swXForm = swXForm.Inverse
        Set swMathUtil = swApp.GetMathUtility
        Set swMathPt = swMathUtil.CreatePoint((PointVariant))
        Set swMathPt = swMathPt.MultiplyTransform(swXForm)
        Debug.Print "Point Model", swMathPt.ArrayData(0) * 1000, swMathPt.ArrayData(1) * 1000, swMathPt.ArrayData(2) * 1000
        Debug.Print "Point shetch", swSketchPoint.X * 1000, swSketchPoint.Y * 1000, swSketchPoint.Z * 1000
        Print #1, work;
        Print #1, "[";
        Write #1, swMathPt.ArrayData(0) * 1000, swMathPt.ArrayData(1) * 1000, swMathPt.ArrayData(2) * 1000;
        Print #1, "],"

    End If

    Next
    Print #1, ""


    'Part.ClearSelection2 True

End Sub


Sub main()

    Set swApp = CreateObject("SldWorks.Application")
    Set Part = swApp.ActiveDoc
    Set swSelectMgr = Part.SelectionManager




    FilePath = CurDir$
    FilePath = Left(Part.GetPathName, InStrRev(Part.GetPathName, ".") - 1)
    Debug.Print FilePath
    FileName = FilePath + "_Table.txt"
    Debug.Print FileName
    Open FileName For Output As #1
    Print #1, "#Spline data"
    Print #1, "{"
    Print #1, "'FileName':' "; Part.GetPathName; "',"
    Print #1, "'Date':'"; Now(); "',"
    Print #1, ""


    SelectStartFeature

    Print #1, "#Begin Center Line Spline"
    Print #1, "'CenterLineSpline': {"
    Part.ClearSelection2 (True)
    success = Part.Extension.SelectByID2("centerLineFull", "SKETCH", 0, 0, 0, False, 0, Nothing, 0)
    Part.SketchManager.Insert3DSketch (False)
    Set swActiveSketch = Part.GetActiveSketch2
    SketchSegments = swActiveSketch.GetSketchSegments
    For Each SketchSegment In SketchSegments
    Set swSketchSegment = SketchSegment
    Debug.Print swSketchSegment.GetName
    Debug.Print swSketchSegment.GetType
    If swSketchSegment.GetType = 3 Then
        Debug.Print "This is type 3"
        Exit For
    End If
    Next
    Set swCurveIn = swSketchSegment.GetCurve
    Print #1, "'Spline Name':' "; swSketchSegment.GetName; "',"
    Print #1, "'Length':"; swSketchSegment.GetLength * 1000#; ","

    ' False - do not want a cubic spline
    varSplineParams = swCurveIn.GetBCurveParams(False)
    SplineDump (varSplineParams)
    Part.SketchManager.Insert3DSketch (True)
    Print #1, "},"
    Print #1, ""
    Print #1, "#End Center Line Spline"
    Print #1, ""


    Print #1, "#Begin Rack Spline Data"
    Print #1, "'RackSpline': {"
    Set swActiveSketch = Nothing
    Set swSketchSegment = Nothing
    Set SketchSegments = Nothing
    Set swCurveIn = Nothing
    Part.ClearSelection2 (False)
    success = Part.Extension.SelectByID2("rackPosFull", "SKETCH", 0, 0, 0, False, 0, Nothing, 0)

    Part.SketchManager.Insert3DSketch (False)
    Set swActiveSketch = Part.GetActiveSketch2
    Set swSketchSegment = Nothing
    SketchSegments = swActiveSketch.GetSketchSegments
    For Each SketchSegment In SketchSegments
    Set swSketchSegment = SketchSegment
    Debug.Print "in rack", swSketchSegment.GetName
    Debug.Print swSketchSegment.GetType
    If swSketchSegment.GetType = 3 Then
        Debug.Print "This is type 3"
        Exit For
    End If
    Next
    Print #1, "'Spline Name':'"; swSketchSegment.GetName; "',"
    Print #1, "'Length':"; swSketchSegment.GetLength * 1000#; ","
    Set swCurveIn = swSketchSegment.GetCurve
    Set varSplineParams = Nothing
    varSplineParams = swCurveIn.GetBCurveParams(False)
    SplineDump (varSplineParams)

    Part.SketchManager.Insert3DSketch (True)
    Print #1, "}"
    Print #1, "#End Rack Spline Data"
    Print #1, "} #End of everything"

    Close #1



End Sub

Below is a python script that will read the output of above and give you as many points as you want along that spline.

    import scipy
from geomdl import BSpline
import math
#import easygui
from math import *
import numpy as np
import math
from functools import partial
np.seterr(divide='ignore', invalid='ignore')


filename = 'my_splines_Table.txt'
filehandle = open(filename,"r")
infile = filehandle.read()
filehandle.close()
spd=eval(infile)

CenterCurve = BSpline.Curve()
CenterCurve.rawdata = spd['CenterLineSpline']
CenterCurve.degree = spd['CenterLineSpline']['Dimension']
CenterCurve.ctrlpts = spd['CenterLineSpline']['ControlPoints']
CenterCurve.knotvector = spd['CenterLineSpline']['KnotPoints']
NumPoints = 250
for i in range(NumPoints+1): #Rember to generate the last point so you really get Numpoints + 1
    position = i  / 250
    point = CenterCurve.evaluate_single(position)
    print(" Point ",point)

All of this is specific to my application. You will need to modify accordingly.
There in no error checking or sanity checking.
One thing to note is that when the part is rebuilt, the direction of the spline data may reverse. That is the start and end swap. All the data is correct but the python code my process it from end to start. For my application I have another reference point that is near the beginning of the spline. I check the start and end of the spline data to see which end is closer to the reference point. (That is what some of the extra bits are in the VBA script.)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.