Cancel
Showing results for 
Search instead for 
Did you mean: 

Exporting Solid Edge Assembly to Matlab 's Simscape multibody

Experimenter
Experimenter

We are switching from SolidWorks to Solid Edge and one thing we use to do is to create  an assembly (robot) in Solidworks then use the provided ADDIN to export the assembly into Matlab's Simscape multibody diagrams for analysis and control.

 

Mathworks put out a detailed VBA macro for Solidworks and says that the code can be changed for another CAD such Solid Edge using the right API.

 

Any info on the availability of such an API is appreciated.

 

https://www.mathworks.com/matlabcentral/fileexchange/47070-cad-to-matlab-to-simscape-multibody

 

 

The linking (SW to MATLAB) procedure is given below:

 

https://www.mathworks.com/help/physmod/smlink/ug/installing-and-linking-simmechanics-link-software.h...

 

 

6 REPLIES 6

Re: Exporting Solid Edge Assembly to Matlab 's Simscape multibody

Gears Phenom Gears Phenom
Gears Phenom

@sdarenfed wrote:

 

Mathworks put out a detailed VBA macro for Solidworks and says that the code can be changed for another CAD such Solid Edge using the right API.

 

Any info on the availability of such an API is appreciated.

 

 


Probably it is just a matter to change few rows in the VBA macro, from what I seen the geometry is exported in STL format.

 

Is that VBA Macro available to have a look at the code ?

Re: Exporting Solid Edge Assembly to Matlab 's Simscape multibody

Experimenter
Experimenter
'=================================================
' This macro (VBA script) is an example to show how to extract instances and constraints information
' from opened model and produce a .m struct format file.
' We wrote this script based on SolidWorks API.
' If you would like to use this as a reference, you should use the API from you software provider
'
'=================================================

Option Explicit

'Global Variables
Dim instanceNum As Integer
Dim assemblyNum As Integer
Dim partAntiReduplicated() As String
Dim assemblyAntiReduplicated() As String
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim filePath As String
Dim globalLengthUnit As Integer


'-------------------------------------------------
' This is the main function, you may edit the output file directory and name here.
'-------------------------------------------------
Sub main()

Dim swConf As SldWorks.Configuration
Dim swRootComp As SldWorks.Component2
Dim bRet As Boolean

setGlobalVariables
saveAsFile
Set swConf = swModel.GetActiveConfiguration
Set swRootComp = swConf.GetRootComponent
getAssembliesInfo swRootComp
getInstanceTree swRootComp
getConstraints swModel.FirstFeature
getAssemblies swRootComp
getParts swRootComp
resetAttributes
Close #1

End Sub

Sub saveAsFile()

Dim fileName As Variant
fileName = Split(swModel.GetPathName, "\")
fileName = Split(fileName(UBound(fileName)), ".")
Dim outputName As String
outputName = fileName(0) + "_fromCAD2MATLAB_SolidWorks.m"


'**********************************
'PLEASE specify the out put directory here
'Do not forget the "\" in the end of the directory

filePath = "C:\fromCAD2MATLAB_SolidWorks\"

'**********************************

outputName = filePath + outputName
Open outputName For Output As #1

End Sub



'SolidWorks uses integer number to define unit types
'This function returns the String format unit type which corresponds to the number
Function getUnitText(unitNum As Integer) As String

Select Case unitNum
Case 0
getUnitText = "millimeter"
Case 1
getUnitText = "centimeter"
Case 2
getUnitText = "meter"
Case 3
getUnitText = "inch"
Case 4
getUnitText = "foot"
Case 8
getUnitText = "micrometer"
Case Else
getUnitText = "Other type"
End Select

End Function

'SolidWorks uses integer number to define geometry types
'This function returns the String format geometry type which corresponds to the number
Function getGeometryText(geometryNum As Integer) As String

Select Case geometryNum
Case 0
getGeometryText = "point"
Case 1
getGeometryText = "line"
Case 2
getGeometryText = "circle"
Case 3
getGeometryText = "plane"
Case 4
getGeometryText = "cylinder"
Case 5
getGeometryText = "sphere"
Case 6
getGeometryText = "set"
Case 7
getGeometryText = "cone"
Case Else
getGeometryText = "other type"
End Select

End Function

'SolidWorks uses integer number to define constraints types
'This function returns the String format constraints type which corresponds to the number
Function getConstraintText(constraintNum As Integer) As String

Select Case constraintNum
Case 0
getConstraintText = "Coincident"
Case 1
getConstraintText = "Concentric"
Case 2
getConstraintText = "Perpendicular"
Case 3
getConstraintText = "Parallel"
Case 4
getConstraintText = "Tangent"
Case 5
getConstraintText = "Distance"
Case 6
getConstraintText = "Angle"
Case 7
getConstraintText = "Unknown"
Case 8
getConstraintText = "Symmetric"
Case 9
getConstraintText = "Camfollower"
Case 10
getConstraintText = "Gear"
Case Else
getConstraintText = "Error type"
End Select

End Function


'-------------------------------------------------
' This function gets parts information from the activated file
' In this procedure, each part file will be activated and closed.
' I suggest that do not use other windows when export STL files in case of export error
' You may see how we generate the .m struct format for part
'-------------------------------------------------
Function getParts(swRootComp As SldWorks.Component2, Optional offset As Integer = 0) As Integer

Dim swChildComp As SldWorks.Component2
Dim swCompModel As SldWorks.ModelDoc2
Dim swCompBody As SldWorks.Body2
Dim swPart As SldWorks.PartDoc
Dim vMaterialPro As Variant
Dim vMassProps As Variant
Dim nDensity As Double
Dim vChild As Variant
Dim temp As Variant
Dim childNum As Integer
Dim fullName As String
Dim antiRedupFlag As Integer
Dim partCount As Integer

partCount = offset
vChild = swRootComp.GetChildren
childNum = UBound(vChild)

Dim i As Integer
For i = 0 To childNum

Set swChildComp = vChild(i)
Set swCompModel = swChildComp.GetModelDoc
Set swCompBody = swChildComp.GetBody

Dim docType As Integer
docType = swCompModel.GetType

'Document type = 1 means it is a part, while type = 2 means it is an assembly
If docType = 1 Then


'------------------------------------------------
'Get name in proper format
'Just like we get from (exclude <> sign)
Dim flag As Integer
'flag is the position for the specify sign "/"
flag = InStr(1, swChildComp.Name2, "/")
'Found /
If flag <> 0 Then
temp = Split(swChildComp.Name2, "/")
fullName = temp(UBound(temp))
temp = Split(fullName, "-")
'Not found /
Else
fullName = swChildComp.Name2
temp = Split(swChildComp.Name2, "-")
End If


'As multiple instances can based on same part, Num(instances) >= Num(Parts)
'We need to avoid reduplicate parts
'We use antiRedupFlag and partAntiReduplicated() to avoid reduplication
antiRedupFlag = 0
'Search the record (partAntiReduplicated) to see if the current part is already here
Dim k As Integer
For k = 0 To partCount
If temp(0) = partAntiReduplicated(k) Then
antiRedupFlag = 1
Exit For
End If
Next k

'Here means the current part is a new part which we should process and store it
If antiRedupFlag = 0 Then

partAntiReduplicated(partCount) = temp(0)

Dim partFilePath As String
partFilePath = swCompModel.GetPathName()

Dim partObj As Object
Set partObj = swApp.ActivateDoc2(partFilePath, True, Empty)

Dim bSet As Boolean
Dim fileName As String

'If you want to export to STEP file, you should use .STEP instead.
fileName = filePath + temp(0) + "_" + swChildComp.ReferencedConfiguration + "_sldprt.STL"
swApp.SetUserPreferenceIntegerValue swExportStlUnits, swCompModel.LengthUnit
bSet = swCompModel.SaveAs(fileName)
swApp.CloseDoc (partFilePath)

Dim unitType As String
unitType = getUnitText(swCompModel.LengthUnit)

Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").Name = '" & temp(0) & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").Uid = '" & temp(0) & "*:*" & swChildComp.ReferencedConfiguration & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").Version = '" & swCompModel.GetUpdateStamp & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").ModelUnits.Mass ='kilogram';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").ModelUnits.Length = '" + unitType + "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").PartFile.Name = '" & temp(0) & ".SLDPRT';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").PartFile.Type = 'SolidWorks Part';"

'Get mass properties
nDensity = swCompModel.GetUserPreferenceDoubleValue(swMaterialPropertyDensity)
vMassProps = swCompBody.GetMassProperties(nDensity)
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").MassProperties.Mass = '" & vMassProps(5) & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").MassProperties.CenterOfMass = '" & vMassProps(0) & " " & vMassProps(1) & " " & vMassProps(2) & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").MassProperties.Inertia = '" & vMassProps(6) & " " & vMassProps(7) & " " & vMassProps(8) & " " & vMassProps(9) & " " & vMassProps(10) & " " & vMassProps(11) & "';"

'Write geometry file information
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").GeometryFile.Name = '" & temp(0) & "_" & swChildComp.ReferencedConfiguration & "_sldprt.STL';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").GeometryFile.Type = 'STL';"

'Get material (visualization) properties
Set swPart = swCompModel
vMaterialPro = swPart.MaterialPropertyValues

If IsEmpty(vMaterialPro) Then
Debug.Print " No color information,"
Else

Dim dR As Double
Dim dG As Double
Dim dB As Double
Dim dA As Double
Dim ambient As Double
Dim diffuse As Double
Dim specular As Double
Dim shininess As Double
Dim emissive As Double

dR = vMaterialPro(0)
dG = vMaterialPro(1)
dB = vMaterialPro(2)

ambient = vMaterialPro(3)
diffuse = vMaterialPro(4)
specular = vMaterialPro(5)
shininess = vMaterialPro(6)
emissive = vMaterialPro(8)

'Transparency
dA = 1 - vMaterialPro(7)

'In SimMechanics, Ambient, Diffuse, Specular and Emissive are described as [R, G, B, A]
'However, SolidWorks uses double number to store those properties.
'Thus, here we are using [R*ambient, G*ambient, B*ambient, A] in order to convert to SimMechanics representation.
'Please adjust appropriately according to your CAD API.
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").VisualProperties.Ambient = '" & dR * ambient & " " & dG * ambient & " " & dB * ambient & " " & dA & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").VisualProperties.Diffuse = '" & dR * diffuse & " " & dG * diffuse & " " & dB * diffuse & " " & dA & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").VisualProperties.Specular = '" & dR * specular & " " & dG * specular & " " & dB * specular & " " & dA & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").VisualProperties.Emissive = '" & dR * emissive & " " & dG * emissive & " " & dB * emissive & " " & dA & "';"
Print #1, "smiModel.Part(" & CStr(partCount + 1) & ").VisualProperties.Shininess = '" & shininess & "';"

End If

Print #1, ""
partCount = partCount + 1

End If
Else
Dim subChildNum As Integer
subChildNum = UBound(swChildComp.GetChildren)

'If it has zero children, subChlidNum will be -1
'If it is not a part, it should be has child(ren).
If subChildNum > -1 Then
partCount = getParts(swChildComp, partCount)
Else
Debug.Print "Error!"
End If
End If
Next i
getParts = partCount
End Function




' For models with hierarchy, there will be an additional constraints field which called AssemblyConstraints
' This sub will export these constraints only if the model has hierarchy.
' This sub is quite similar to getConstraints. More comments are in getConstraints
' This sub is called by the function getAssemblies
Sub getAssemblyConstraints(swFeat As SldWorks.Feature, preXform As SldWorks.MathTransform, assemblyCount As Integer, uidControlRef As String)

Dim swMateFeat As SldWorks.Feature
Dim swSubFeat As SldWorks.Feature
Dim swMate As SldWorks.Mate2
Dim swComp As SldWorks.Component2
Dim swMateEnt(2) As SldWorks.MateEntity2
Dim constraintType As String
Dim geometryType As String
Dim pOcc2Owner As SldWorks.MathTransform
Dim pOwner2Occ As SldWorks.MathTransform
Dim pMathUtility As SldWorks.MathUtility
Dim pPoint As SldWorks.MathPoint
Dim pVector As SldWorks.MathVector
Dim flag As Integer
Dim count As Integer

count = 1

Do While Not swFeat Is Nothing
'In solidWorks, constraints are labeled as MateGroup.
'You may find what is the label for constraints in your software.
If "MateGroup" = swFeat.GetTypeName Then

Set swMateFeat = swFeat
Exit Do
End If
Set swFeat = swFeat.GetNextFeature
Loop

Set swSubFeat = swMateFeat.GetFirstSubFeature

Do While Not swSubFeat Is Nothing
Set swMate = swSubFeat.GetSpecificFeature2
If swSubFeat.IsSuppressed = "False" Then
If Not swMate Is Nothing Then

constraintType = getConstraintText(swMate.Type)

Print #1, "smiModel.Assembly(" + CStr(assemblyCount) + ").Constraint(" + CStr(count) + ").Name = '" + swSubFeat.Name + "';"
Print #1, "smiModel.Assembly(" + CStr(assemblyCount) + ").Constraint(" + CStr(count) + ").Type = '" + constraintType + "';"

Dim i As Integer
For i = 0 To 1

Set swMateEnt(i) = swMate.MateEntity(i)

Set swComp = swMateEnt(i).ReferenceComponent
Set pOcc2Owner = swComp.Transform2
Set pOwner2Occ = pOcc2Owner.Inverse
Set pMathUtility = swApp.IGetMathUtility

Dim adPosition(2) As Double
adPosition(0) = swMateEnt(i).EntityParams(0)
adPosition(1) = swMateEnt(i).EntityParams(1)
adPosition(2) = swMateEnt(i).EntityParams(2)

Set pPoint = pMathUtility.CreatePoint(adPosition)
Set pPoint = pPoint.MultiplyTransform(preXform)
Set pPoint = pPoint.MultiplyTransform(pOwner2Occ)


Dim adAxis(2) As Double
adAxis(0) = swMateEnt(i).EntityParams(3)
adAxis(1) = swMateEnt(i).EntityParams(4)
adAxis(2) = swMateEnt(i).EntityParams(5)

Set pVector = pMathUtility.CreateVector(adAxis)
Set pVector = pVector.MultiplyTransform(preXform)
Set pVector = pVector.MultiplyTransform(pOwner2Occ)

geometryType = getGeometryText(swMateEnt(i).ReferenceType)


Print #1, "smiModel.Assembly(" + CStr(assemblyCount) + ").Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Type = '" + geometryType + "';"

Dim uidList As Variant
uidList = Split(swComp.Name2, "/")

Dim uidNum As Integer
uidNum = UBound(uidList)
Dim t As Integer
Dim p As Integer
Dim starter As Integer


For p = 0 To uidNum
Dim uidControl As Variant
uidControl = Split(uidList(p), "-")
If uidControlRef = uidControl(0) Then
starter = p + 1
Exit For
Else
starter = uidNum
End If
Next p


For t = starter To uidNum
Print #1, "smiModel.Assembly(" + CStr(assemblyCount) + ").Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Uid(" + CStr(t - starter + 1) + ").Name = '" + uidList(t) + "';"
Next t


Print #1, "smiModel.Assembly(" + CStr(assemblyCount) + ").Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Position = '" + CStr(pPoint.ArrayData(0)) + " " + CStr(pPoint.ArrayData(1)) + " " + CStr(pPoint.ArrayData(2)) + "';"
Print #1, "smiModel.Assembly(" + CStr(assemblyCount) + ").Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Axis = '" + CStr(pVector.ArrayData(0)) + " " + CStr(pVector.ArrayData(1)) + " " + CStr(pVector.ArrayData(2)) + "';"
Print #1, ""
Next i

count = count + 1

End If
End If
'Get the next mate in MateGroup
Set swSubFeat = swSubFeat.GetNextSubFeature
Loop
End Sub



'-------------------------------------------------
' This function gets Assemblies information
' The major task for this function is recursively call the sub getAssemblyConstraints
'-------------------------------------------------
Function getAssemblies(swRootComp As SldWorks.Component2, Optional offset As Integer = 0) As Integer

Dim swChildComp As SldWorks.Component2
Dim vChild As Variant
Dim childNum As Integer
Dim temp As Variant
Dim preXform As SldWorks.MathTransform
Dim antiRedupFlag As Integer
Dim assemblyCount As Integer
Dim swCompModel As SldWorks.ModelDoc2

assemblyCount = offset

vChild = swRootComp.GetChildren
childNum = UBound(vChild)

Dim i As Integer
For i = 0 To childNum

Set swChildComp = vChild(i)

Dim subChildNum As Integer
subChildNum = UBound(swChildComp.GetChildren)

If subChildNum > -1 Then

'Call getAssemblies(swChildComp)

Dim flag As Integer
Dim fullName As String

flag = InStr(1, swChildComp.Name2, "/")
If flag <> 0 Then

temp = Split(swChildComp.Name2, "/")
fullName = temp(UBound(temp))
temp = Split(fullName, "-")

Else

fullName = swChildComp.Name2
temp = Split(swChildComp.Name2, "-")

End If

'Similar as parts, we also need to make sure each assembly is unique
'So we need to avoid deplicated assemblies

antiRedupFlag = 0

Dim k As Integer
For k = 0 To assemblyCount - 1
If temp(0) = assemblyAntiReduplicated(k) Then
antiRedupFlag = 1
Exit For
End If
Next k

If antiRedupFlag = 0 Then

assemblyAntiReduplicated(assemblyCount) = temp(0)

Set swCompModel = swChildComp.GetModelDoc

Print #1, "smiModel.Assembly(" + CStr(assemblyCount + 1) + ").Name = '" + temp(0) + "';"
Print #1, "smiModel.Assembly(" + CStr(assemblyCount + 1) + ").Uid = '" + temp(0) + "';"
Print #1, "smiModel.Assembly(" + CStr(assemblyCount + 1) + ").Version = '" & swCompModel.GetUpdateStamp & "';"
Print #1, "smiModel.Assembly(" + CStr(assemblyCount + 1) + ").ModelUnits.Mass = 'kilogram';"

Dim unitType As String
unitType = getUnitText(swCompModel.LengthUnit)

Print #1, "smiModel.Assembly(" + CStr(assemblyCount + 1) + ").ModelUnits.Length = '" + unitType + "';"
Print #1, "smiModel.Assembly(" + CStr(assemblyCount + 1) + ").AssemblyFile.Name = '" + temp(0) + ".SLDASM';"
Print #1, "smiModel.Assembly(" + CStr(assemblyCount + 1) + ").AssemblyFile.Type = 'SolidWorks Assembly';"
Print #1, ""

Set preXform = swChildComp.Transform2

assemblyCount = assemblyCount + 1
Dim uidControlRef As String
uidControlRef = temp(0)
getAssemblyConstraints swChildComp.FirstFeature, preXform, assemblyCount, uidControlRef
assemblyCount = getAssemblies(swChildComp, assemblyCount)

End If
End If
Next i
getAssemblies = assemblyCount
End Function



'-------------------------------------------------
' This function gets constraints information from the activated file
' You may see how we generate the .m struct format for constraints
'-------------------------------------------------
Sub getConstraints(swFeat As SldWorks.Feature)

Dim swMateFeat As SldWorks.Feature
Dim swSubFeat As SldWorks.Feature
Dim swMate As SldWorks.Mate2
Dim swComp As SldWorks.Component2
Dim swMateEnt(2) As SldWorks.MateEntity2
Dim constraintType As String
Dim geometryType As String
Dim pOcc2Owner As SldWorks.MathTransform
Dim pOwner2Occ As SldWorks.MathTransform
Dim pMathUtility As SldWorks.MathUtility
Dim pPoint As SldWorks.MathPoint
'Dim pPointLocal As SldWorks.MathPoint
Dim pVector As SldWorks.MathVector
'Dim pVectorLocal As SldWorks.MathVector

Dim flag As Integer
Dim count As Integer

'flag is used for avoiding duplicate output for constraint name
flag = 1

'count is used for count the constraint in order to generate index
count = 1

Do While Not swFeat Is Nothing

'In solidWorks, constraints are labelled as MateGroup.
'You may find what is the label for constraints in your software.
If "MateGroup" = swFeat.GetTypeName Then
Set swMateFeat = swFeat
Exit Do
End If
Set swFeat = swFeat.GetNextFeature
Loop

Set swSubFeat = swMateFeat.GetFirstSubFeature
Do While Not swSubFeat Is Nothing
Set swMate = swSubFeat.GetSpecificFeature2

'We should only export the unsuppressed constraints
If swSubFeat.IsSuppressed = "False" Then
If Not swMate Is Nothing Then

constraintType = getConstraintText(swMate.Type)

Print #1, "smiModel.Constraint(" + CStr(count) + ").Name = '" + swSubFeat.Name + "';"
Print #1, "smiModel.Constraint(" + CStr(count) + ").Type = '" + constraintType + "';"


'Each constraint contains two sets of geometry infos
Dim i As Integer
For i = 0 To 1
Set swMateEnt(i) = swMate.MateEntity(i)

geometryType = getGeometryText(swMateEnt(i).ReferenceType)

Print #1, "smiModel.Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Type = '" + geometryType + "';"

Set pMathUtility = swApp.IGetMathUtility

Dim adPosition(2) As Double
adPosition(0) = swMateEnt(i).EntityParams(0)
adPosition(1) = swMateEnt(i).EntityParams(1)
adPosition(2) = swMateEnt(i).EntityParams(2)
Set pPoint = pMathUtility.CreatePoint(adPosition)

Dim adAxis(2) As Double
adAxis(0) = swMateEnt(i).EntityParams(3)
adAxis(1) = swMateEnt(i).EntityParams(4)
adAxis(2) = swMateEnt(i).EntityParams(5)
Set pVector = pMathUtility.CreateVector(adAxis)

'SimMechanic uses local coordinates for each instance while SolidWorks uses global coordinates
'We need to convert them to local coordinates system
'T * Local = Global
'T(-1) * T * Local = T(-1) * Global => Local = T(-1) * Global

Set swComp = Nothing
Set pOcc2Owner = Nothing
Set pOwner2Occ = Nothing

Set swComp = swMateEnt(i).ReferenceComponent
If Not swComp Is Nothing Then

Set pOcc2Owner = swComp.Transform2

If pOcc2Owner Is Nothing Then
Dim fileName As Variant
fileName = Split(swModel.GetPathName, "\")
fileName = Split(fileName(UBound(fileName)), ".")
Print #1, "smiModel.Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Uid(1).Name = '" + fileName(0) + "';"
Else
Set pOwner2Occ = pOcc2Owner.Inverse
Set pPoint = pPoint.MultiplyTransform(pOwner2Occ)
Set pVector = pVector.MultiplyTransform(pOwner2Occ)

'If the model has sub-assemblies (higher level hierarchy), there might be multiple uid.
'In SolidWorks, they are divided by "/"
Dim uidList As Variant
uidList = Split(swComp.Name2, "/")
Dim uidNum As Integer
uidNum = UBound(uidList)
Dim t As Integer
For t = 0 To uidNum
Print #1, "smiModel.Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Uid(" + CStr(t + 1) + ").Name = '" + uidList(t) + "';"
Next t
End If
End If
Print #1, "smiModel.Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Position = '" + CStr(pPoint.ArrayData(0)) + " " + CStr(pPoint.ArrayData(1)) + " " + CStr(pPoint.ArrayData(2)) + "';"
Print #1, "smiModel.Constraint(" + CStr(count) + ")." + "Geometry(" + CStr(i + 1) + ").Axis = '" + CStr(pVector.ArrayData(0)) + " " + CStr(pVector.ArrayData(1)) + " " + CStr(pVector.ArrayData(2)) + "';"
Print #1, ""
Next i

count = count + 1
End If
End If
'Get the next mate in MateGroup
Set swSubFeat = swSubFeat.GetNextSubFeature
Loop
End Sub


'-------------------------------------------------
' This function gets instance tree information from the activated file
' Find the API methods will be the challenge to write your own converter
'-------------------------------------------------
Sub getInstanceTree(swRootComp As SldWorks.Component2, Optional prefix As String = "")

Dim swChildComp As SldWorks.Component2
Dim vChild As Variant
Dim temp As Variant
Dim swCompXform As SldWorks.MathTransform
Dim vXform As Variant
Dim childNum As Integer
Dim fullName As String
Dim preXform As SldWorks.MathTransform


vChild = swRootComp.GetChildren
childNum = UBound(vChild)
instanceNum = instanceNum + childNum + 1
ReDim partAntiReduplicated(0 To instanceNum)

Dim i As Integer
For i = 0 To childNum

Set swChildComp = vChild(i)
Dim subChildNum As Integer

subChildNum = UBound(swChildComp.GetChildren)

Dim flag As Integer
flag = InStr(1, swChildComp.Name2, "/")
If flag <> 0 Then
temp = Split(swChildComp.Name2, "/")
fullName = temp(UBound(temp))
temp = Split(fullName, "-")
Else
fullName = swChildComp.Name2
temp = Split(swChildComp.Name2, "-")
End If

Print #1, "smiModel." + prefix + "Instance(" + CStr(i + 1) + ").Name = '" + fullName + "';"
Print #1, "smiModel." + prefix + "Instance(" + CStr(i + 1) + ").Uid = '" + fullName + "';"

'This macro cannot deal with grounded well except the root level. For further level, right now we just set False(default value) to it.
If prefix = "" Then
Print #1, "smiModel." + prefix + "Instance(" & CStr(i + 1) & ").Grounded = " & "'" & swChildComp.IsFixed & "';"
Else
Print #1, "smiModel." + prefix + "Instance(" & CStr(i + 1) & ").Grounded = " & "'False';"
End If

'Output the Rigid attribute
If swChildComp.Solving <> 1 Then
Print #1, "smiModel." + prefix + "Instance(" & CStr(i + 1) & ").Rigid = 'True';"
Else
Print #1, "smiModel." + prefix + "Instance(" & CStr(i + 1) & ").Rigid = 'False';"
End If

'For the instances which have sub-instance, the EntityUid will be in different format
If subChildNum > -1 Then
Print #1, "smiModel." + prefix + "Instance(" + CStr(i + 1) + ").EntityUid = " + "'" + temp(0) + "';"
Else
Print #1, "smiModel." + prefix + "Instance(" + CStr(i + 1) + ").EntityUid = " + "'" + temp(0) + "*:*" & swChildComp.ReferencedConfiguration & "';"
End If

Set swCompXform = swChildComp.Transform2

'<> means not equal in VB.
'prefix is not empty means this instance is not in root level. So we apply the inversed transform of the upper level to this instance.
If prefix <> "" Then
Set preXform = swRootComp.Transform2
Set preXform = preXform.Inverse
Set swCompXform = swCompXform.Multiply(preXform)
End If

vXform = swCompXform.ArrayData
Print #1, "smiModel." + prefix + "Instance(" + CStr(i + 1) + ").Transform.Rotation = '" + CStr(vXform(0)) + " " + CStr(vXform(3)) + " " + CStr(vXform(6)) + " " + CStr(vXform(1)) + " " + CStr(vXform(4)) + " " + CStr(vXform(7)) + " " + CStr(vXform(2)) + " " + CStr(vXform(5)) + " " + CStr(vXform(8)) + "';"
Print #1, "smiModel." + prefix + "Instance(" + CStr(i + 1) + ").Transform.Translation = '" + CStr(vXform(9)) + " " + CStr(vXform(10)) + " " + CStr(vXform(11)) + "';"
Print #1, ""

If subChildNum > -1 Then
'Whenever there has hierarchy, there should be a assembly (ignore duplication here)
'So the size(Maximum size, because here we do not consider deplication) of the assemblyAntiReduplicated array will be added by 1
ReDim assemblyAntiReduplicated(0 To assemblyNum)
assemblyNum = assemblyNum + 1
Dim tempPrefix As String
tempPrefix = prefix + "Instance(" + CStr(i + 1) + ")."
Call getInstanceTree(swChildComp, tempPrefix)
End If
Next i
End Sub

'-------------------------------------------------
' This function gets some rootassembly information from the activated file
' These information is required by the schema
'-------------------------------------------------
Sub getAssembliesInfo(swRootComp As SldWorks.Component2)

Dim temp As Variant
temp = Split(swModel.GetTitle, ".")
Print #1, "smiModel.CreatedInfo.By = '';"
Print #1, "smiModel.CreatedInfo.From = 'SolidWorks 20.3.0';"
Print #1, "smiModel.CreatedInfo.Using = 'SimMechanics Link Version 4.2';"

Dim unitType As String
unitType = getUnitText(swModel.LengthUnit)

Print #1, "smiModel.ModelUnits.Mass = 'kilogram';"
Print #1, "smiModel.ModelUnits.Length = '" + unitType + "';"
Print #1, "smiModel.DataUnits.Mass = 'kilogram';"
Print #1, "smiModel.DataUnits.Length = 'meter';"
Print #1, ""
Print #1, "smiModel.RootAssembly.Name = '" + temp(0) + "';"
Print #1, "smiModel.RootAssembly.Uid = '" + temp(0) + "';"
Print #1, "smiModel.RootAssembly.Version = '" & swModel.GetUpdateStamp & "';"
Print #1, "smiModel.RootAssembly.AssemblyFile.Name = '" + swModel.GetTitle + "';"
Print #1, "smiModel.RootAssembly.AssemblyFile.Type = 'SolidWorks Assembly';"
Print #1, ""

End Sub

'-------------------------------------------------
' This function reset some attributes which edited by this macro in order to avoid change previous setting
'-------------------------------------------------
Sub resetAttributes()

instanceNum = 0
ReDim partAntiReduplicated(0 To 0)
swApp.SetUserPreferenceToggle swSTLDontTranslateToPositive, False
swApp.SetUserPreferenceIntegerValue swExportStlUnits, globalLengthUnit

End Sub

'-------------------------------------------------
' This function set some global variables which will be used in subs/functions
'-------------------------------------------------
Sub setGlobalVariables()

'Set object type. As it is an example for SolidWorks, here we use SldWorks.Application
Set swApp = CreateObject("SldWorks.Application")
Set swModel = swApp.ActiveDoc

swApp.SetUserPreferenceToggle swSTLBinaryFormat, False
swApp.SetUserPreferenceToggle swSTLDontTranslateToPositive, True
swApp.SetUserPreferenceToggle swSTLComponentsIntoOneFile, False
globalLengthUnit = swModel.LengthUnit
assemblyNum = 0

End Sub

Re: Exporting Solid Edge Assembly to Matlab 's Simscape multibody

Gears Phenom Gears Phenom
Gears Phenom

Ok they are not just few rows, I would say more than translate for Solid Edge it is adapt for Solid Edge, probably some function works different so it is important to know what is required by Simscape.

 

For example this lines:

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2

Set swApp = CreateObject("SldWorks.Application") Set swModel = swApp.ActiveDoc

 

must be changed like: 

Dim seApp As SolidEdgeFramework.Application
Dim seModel As SolidEdgeDocument

Set seApp = CreateObject("SolidEdge.Application") Set seModel = seApp.ActiveDocument

 

Re: Exporting Solid Edge Assembly to Matlab 's Simscape multibody

Experimenter
Experimenter

Thanks Fiorini.  Where is the documentation and references on solid edge API  (VBA) ?

 

Re: Exporting Solid Edge Assembly to Matlab 's Simscape multibody

Gears Honored Contributor Gears Honored Contributor
Gears Honored Contributor

Reading the specs and guidelines for the XML that the VBA macro is supposed to create and then subsequently read by Matlab for rebuilding the assembly, most of the data tags are optional, except the assembly component transformations which involve matrix calculations, and this could be the tricky part, since this is not extensively documented and needs to be researched and figured out.

  

The Solid Ege API help is vast and exhaustive, and can be found under the SDK folder where Solid Edge is installed:

 

sdkloc09.png

Re: Exporting Solid Edge Assembly to Matlab 's Simscape multibody

Gears Phenom Gears Phenom
Gears Phenom

@darenfs wrote:

Thanks Fiorini.  Where is the documentation and references on solid edge API  (VBA) ?

 


https://docs.plm.automation.siemens.com/docs/se/110/api/webframe.html