Read and display body from the file using SOLIDWORKS API
This VBA example demonstrates how to read the body geometry data from the external binary file. Load this data into the COM Stream and restore into the temp solid body using SOLIDWORKS API.
Body is displayed to the user and macro execution stops. Body is not present in the Feature Manager Tree and only visible in the graphics area.
Continue the macro execution to destroy the body.
Imports SolidWorks.Interop.sldworks Imports SolidWorks.Interop.swconst Imports System.IO Imports System.Runtime.InteropServices Imports System.Runtime.InteropServices.ComTypes Module Module1 Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As IntPtr, ByVal fDeleteOnRelease As Boolean, ByRef ppstm As IStream) As Long Const FILE_PATH As String = "D:\body.dat" Sub Main() Dim app As ISldWorks = CreateObject("SldWorks.Application") app.Visible = True Dim model As IModelDoc2 model = app.ActiveDoc If Not model Is Nothing Then Dim body As IBody2 = LoadBodyFromFile(app, FILE_PATH) If Not body Is Nothing Then body.Display3(model, RGB(255, 255, 0), swTempBodySelectOptions_e.swTempBodySelectOptionNone) Console.ReadLine() Else Throw New Exception("Failed to restore the body") End If Else Throw New Exception("Please open the model") End If End Sub Function LoadBodyFromFile(app As ISldWorks, filePath As String) As IBody2 Dim stream As IStream = Nothing CreateStreamOnHGlobal(IntPtr.Zero, True, stream) Dim comStream = New ComStream(stream, True, True) Using fileStream = File.OpenRead(filePath) fileStream.CopyTo(comStream) comStream.Seek(0, SeekOrigin.Begin) End Using Dim modeler As IModeler = app.IGetModeler() Return modeler.Restore(stream) End Function End Module Public Class ComStream Inherits Stream Private ReadOnly m_ComStream As IStream Private ReadOnly m_Commit As Boolean Private m_IsWritable As Boolean Public Sub New(ByRef comStream As IStream, writable As Boolean, Optional commit As Boolean = True) If comStream Is Nothing Then Throw New ArgumentNullException(NameOf(comStream)) End If m_ComStream = comStream m_IsWritable = writable m_Commit = commit End Sub Public Overrides ReadOnly Property CanRead() As Boolean Get Return True End Get End Property Public Overrides ReadOnly Property CanSeek() As Boolean Get Return True End Get End Property Public Overrides ReadOnly Property CanWrite() As Boolean Get Return m_IsWritable End Get End Property Public Overrides ReadOnly Property Length As Long Get Const STATSFLAG_NONAME As Integer = 1 Dim stats As ComTypes.STATSTG = Nothing m_ComStream.Stat(stats, STATSFLAG_NONAME) Return stats.cbSize End Get End Property Public Overrides Property Position() As Long Get Return Seek(0, SeekOrigin.Current) End Get Set(ByVal Value As Long) Seek(Value, SeekOrigin.Begin) End Set End Property Public Overrides Sub Flush() If m_Commit Then Const STGC_DEFAULT As Integer = 0 m_ComStream.Commit(STGC_DEFAULT) End If End Sub Public Overrides Sub SetLength(ByVal Value As Long) m_ComStream.SetSize(Value) End Sub Public Overrides Sub Write(buffer() As Byte, offset As Integer, count As Integer) If offset <> 0 Then Dim bufferSize As Integer bufferSize = buffer.Length - offset Dim tmpBuffer(bufferSize) As Byte Array.Copy(buffer, offset, tmpBuffer, 0, bufferSize) m_ComStream.Write(tmpBuffer, bufferSize, Nothing) Else m_ComStream.Write(buffer, count, Nothing) End If End Sub Public Overrides Function Read(buffer() As Byte, offset As Integer, count As Integer) As Integer Dim bytesRead As Integer = 0 Dim boxBytesRead As Object = bytesRead Dim hObject As GCHandle Try hObject = GCHandle.Alloc(boxBytesRead, GCHandleType.Pinned) Dim pBytesRead As IntPtr = hObject.AddrOfPinnedObject() If offset <> 0 Then Dim tmpBuffer(count - 1) As Byte m_ComStream.Read(tmpBuffer, count, pBytesRead) bytesRead = CInt(boxBytesRead) Array.Copy(tmpBuffer, 0, buffer, offset, bytesRead) Else m_ComStream.Read(buffer, count, pBytesRead) bytesRead = CInt(boxBytesRead) End If Finally If hObject.IsAllocated Then hObject.Free() End If End Try Return bytesRead End Function Public Overrides Function Seek(offset As Long, origin As SeekOrigin) As Long Dim curPosition As Long = 0 Dim boxCurPosition As Object = curPosition Dim hObject As GCHandle Try hObject = GCHandle.Alloc(boxCurPosition, GCHandleType.Pinned) Dim pCurPosition As IntPtr = hObject.AddrOfPinnedObject() m_ComStream.Seek(offset, origin, pCurPosition) curPosition = CLng(boxCurPosition) Finally If hObject.IsAllocated Then hObject.Free() End If End Try Return curPosition End Function Protected Overrides Sub Dispose(ByVal disposing As Boolean) Try If disposing Then m_IsWritable = False End If Finally MyBase.Dispose(disposing) End Try End Sub Protected Overrides Sub Finalize() Dispose(False) End Sub End Class