通过SOLIDWORKS API从CSV文件导入点云到草图
该宏使用SOLIDWORKS API将从指定的CSV(逗号分隔值)文件中读取的点云导入到活动的草图中。支持2D和3D草图。
配置
宏有几个配置选项,可以通过更改宏开头的常量的值来修改。
Const USE_SYSTEM_UNITS As Boolean = True
Const FIRST_ROW_HEADER As Boolean = True
- FIRST_ROW_HEADER 指定CSV文件的第一行是否被视为标题并应被忽略。如果CSV文件不包含标题,请将该常量的值设置为False。
- USE_SYSTEM_UNITS 指示CSV文件中的坐标值是否以系统单位(米)表示。如果将此选项设置为False,宏将使用当前文档单位。
输入的CSV文件可以包含3个坐标(X、Y、Z)或2个坐标(X、Y)。
示例文件
如何运行宏
- 打开模型并创建2D或3D草图(或编辑现有草图)。
- (可选)预先选择坐标系,如果需要将点导入到该坐标系的相对位置。
- 运行宏。在显示的文件浏览对话框中指定CSV文件的完整路径。
- 单击“确定”。点将在活动草图中创建。
Const USE_SYSTEM_UNITS As Boolean = True
Const FIRST_ROW_HEADER As Boolean = True
Dim swApp As SldWorks.SldWorks
Sub main()
try_:
On Error GoTo catch_
Set swApp = Application.SldWorks
Dim swModel As SldWorks.ModelDoc2
Set swModel = swApp.ActiveDoc
If Not swModel Is Nothing Then
Dim swSketch As SldWorks.Sketch
Set swSketch = swModel.SketchManager.ActiveSketch
If Not swSketch Is Nothing Then
Dim vPoints As Variant
Dim inputFile As String
inputFile = swApp.GetOpenFileName("在显示的文件浏览对话框中指定CSV文件的完整路径", "", "CSV文件 (*.csv)|*.csv|文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*|", -1, "", "")
If inputFile <> "" Then
vPoints = ReadCsvFile(inputFile, FIRST_ROW_HEADER)
vPoints = ConvertPointsLocations(vPoints, swModel, USE_SYSTEM_UNITS, GetSelectedCoordinateSystemTransform(swModel))
DrawPoints swModel, vPoints
End If
Else
Err.Raise vbError, "", "请打开2D或3D草图"
End If
Else
Err.Raise vbError, "", "请打开模型"
End If
GoTo finally_
catch_:
swApp.SendMsgToUser2 Err.Description, swMessageBoxIcon_e.swMbStop, swMessageBoxBtn_e.swMbOk
finally_:
End Sub
Function GetSelectedCoordinateSystemTransform(model As SldWorks.ModelDoc2) As SldWorks.mathTransform
Dim swSelMgr As SldWorks.SelectionMgr
Set swSelMgr = model.SelectionManager
If swSelMgr.GetSelectedObjectType3(1, -1) = swSelectType_e.swSelCOORDSYS Then
Dim swCoordSysFeat As SldWorks.Feature
Set swCoordSysFeat = swSelMgr.GetSelectedObject6(1, -1)
Set GetSelectedCoordinateSystemTransform = model.Extension.GetCoordinateSystemTransformByName(swCoordSysFeat.Name)
Else
Set GetSelectedCoordinateSystemTransform = Nothing
End If
End Function
Sub DrawPoints(model As SldWorks.ModelDoc2, vPoints As Variant)
model.SketchManager.AddToDB = True
Dim i As Integer
For i = 0 To UBound(vPoints)
Dim swSkPt As SldWorks.SketchPoint
Dim vPt As Variant
vPt = vPoints(i)
Dim x As Double
Dim y As Double
Dim z As Double
x = CDbl(vPt(0))
y = CDbl(vPt(1))
z = CDbl(vPt(2))
Set swSkPt = model.SketchManager.CreatePoint(x, y, z)
If swSkPt Is Nothing Then
Err.Raise vbError, "", "在位置:" & x & "; " & y & "; " & z & " 处创建点失败"
End If
Next
model.SketchManager.AddToDB = False
End Sub
Function ConvertPointsLocations(points As Variant, model As SldWorks.ModelDoc2, useSystemUnits As Boolean, mathTransform As SldWorks.mathTransform) As Variant
Dim swMathUtils As SldWorks.MathUtility
Set swMathUtils = swApp.GetMathUtility
Dim convFact As Double
convFact = 1
If Not useSystemUnits Then
Dim swUserUnit As SldWorks.UserUnit
Set swUserUnit = model.GetUserUnit(swUserUnitsType_e.swLengthUnit)
convFact = 1 / swUserUnit.GetConversionFactor()
End If
Dim i As Integer
For i = 0 To UBound(points)
Dim vPt As Variant
vPt = points(i)
Dim dPt(2) As Double
If UBound(vPt) >= 0 Then
dPt(0) = CDbl(vPt(0)) * convFact
Else
dPt(0) = 0
End If
If UBound(vPt) >= 1 Then
dPt(1) = CDbl(vPt(1)) * convFact
Else
dPt(1) = 0
End If
If UBound(vPt) >= 2 Then
dPt(2) = CDbl(vPt(2)) * convFact
Else
dPt(2) = 0
End If
If Not mathTransform Is Nothing Then
Dim swMathPt As SldWorks.MathPoint
Set swMathPt = swMathUtils.CreatePoint(dPt)
Set swMathPt = swMathPt.MultiplyTransform(mathTransform)
vPt = swMathPt.ArrayData
Else
vPt = dPt
End If
points(i) = vPt
Next
ConvertPointsLocations = points
End Function
Function ReadCsvFile(filePath As String, firstRowHeader As Boolean) As Variant
'rows x columns
Dim vTable() As Variant
Dim fileName As String
Dim tableRow As String
Dim fileNo As Integer
fileNo = FreeFile
Open filePath For Input As #fileNo
Dim isFirstRow As Boolean
Dim isTableInit As Boolean
isFirstRow = True
isTableInit = False
Do While Not EOF(fileNo)
Line Input #fileNo, tableRow
If Not isFirstRow Or Not firstRowHeader Then
Dim vCells As Variant
vCells = Split(tableRow, ",")
Dim i As Integer
Dim dCells() As Double
ReDim dCells(UBound(vCells))
For i = 0 To UBound(vCells)
dCells(i) = CDbl(vCells(i))
Next
Dim lastRowIndex As Integer
If Not isTableInit Then
lastRowIndex = 0
isTableInit = True
ReDim Preserve vTable(lastRowIndex)
Else
lastRowIndex = UBound(vTable, 1) + 1
ReDim Preserve vTable(lastRowIndex)
End If
vTable(lastRowIndex) = dCells
End If
If isFirstRow Then
isFirstRow = False
End If
Loop
Close #fileNo
ReadCsvFile = vTable
End Function