Feb 9, 2012

SolidWorks Macro Performance Enhancers

No one likes a slow macro.  What’s worse is to be embarrassed by your peers with lackluster speed resulting in macro envy!  Don’t let your macros suffer from this unnecessary condition.  Add a few of these tweaks to your code to re-invigorate their performance.

SketchManager.AddToDB


If your macro is ever creating sketch geometry, this one is a must!  Try the following VB.NET macro code.  Start by opening a new part and inserting a sketch on any plane.  The macro is supposed to create 5 circles in a very small pattern. 

    Sub main()
        Dim swApp As SldWorks.SldWorks
        Dim Part As ModelDoc2
        Dim skSegment As SketchSegment
        Dim skMgr As SketchManager
 
        swApp = Application.SldWorks
 
        Part = swApp.ActiveDoc
        skMgr = Part.SketchManager
        skMgr.CreateCircleByRadius(0#, 0#, 0#, 0.001)
        skMgr.CreateCircleByRadius(0.0005, 0.0005, 0#, 0.0001)
        skMgr.CreateCircleByRadius(0.0005, -0.0005, 0#, 0.0001)
        skMgr.CreateCircleByRadius(-0.0005, 0.0005, 0#, 0.0001)
        skMgr.CreateCircleByRadius(-0.0005, -0.0005, 0#, 0.0001)
    End Sub

There’s a good chance that when you run the code, there are no circles drawn as a result.  If you zoom in to the origin close enough, it will run. 

Now, try the following.  AddToDB is set to True to cause the sketch geometry to be created and to avoid snapping to other nearby geometry.  AddToDB should be set back to False when you’re done with the sketch.

    Sub main()
        Dim swApp As SldWorks.SldWorks
        Dim Part As ModelDoc2
        Dim skSegment As SketchSegment
        Dim skMgr As SketchManager
 
        swApp = Application.SldWorks
 
        Part = swApp.ActiveDoc
        skMgr = Part.SketchManager
        skMgr.AddToDB = True
        skMgr.CreateCircleByRadius(0#, 0#, 0#, 0.001)
        skMgr.CreateCircleByRadius(0.0005, 0.0005, 0#, 0.0001)
        skMgr.CreateCircleByRadius(0.0005, -0.0005, 0#, 0.0001)
        skMgr.CreateCircleByRadius(-0.0005, 0.0005, 0#, 0.0001)
        skMgr.CreateCircleByRadius(-0.0005, -0.0005, 0#, 0.0001)
        skMgr.AddToDB = False
    End Sub

See the difference?  Now, the enhancement doesn’t come without some side effects which may include missing automatic relationships and occasional headaches for other users who need to work with the sketch.

ModelView.EnableGraphicsUpdate


Sometimes a macro seems to go so fast that it’s over before you were ready.  You never saw anything happen until, whammo, it’s on the screen.  Well, there’s a good chance the programmer used this little magic trick. 

The ModelView is the current viewport for the file in SolidWorks.  If a user regularly splits the viewport into multiple views, you would need to operate on each of them.  Luckily most users don’t.  You can get to the ModelView interface by calling ModelDoc2.ActiveView.

Record yourself a macro of whatever actions you’d like.  But keep it to one model.  The macro below is a subset of me zooming and rotating all over the screen.

    Public Sub main()
        Dim swDoc As ModelDoc2 = Nothing
        Dim swPart As PartDoc = Nothing
        Dim swDrawing As DrawingDoc = Nothing
        Dim swAssembly As AssemblyDoc = Nothing
        Dim boolstatus As Boolean = False
        Dim longstatus As Integer = 0
        Dim longwarnings As Integer = 0
        swDoc = CType(swApp.ActiveDoc, ModelDoc2)
        Dim myModelView As ModelView = Nothing
        myModelView = CType(swDoc.ActiveView, ModelView)
        myModelView.FrameState = _
            swWindowState_e.swWindowMaximized
        myModelView = CType(swDoc.ActiveView, ModelView)
        myModelView.RotateAboutCenter(0.10566, 0)
        myModelView = CType(swDoc.ActiveView, ModelView)
        myModelView.RotateAboutCenter(0.05513, 0)
    .... way too much stuff in between to post ....
        swDoc.ViewZoomtofit2()
        swDoc.HideComponent2()
        swDoc.ClearSelection2(True)
        swDoc.ShowNamedView2("*Top", 5)
    End Sub

Playing back the macro gives you a dizzying display of nearly the exact steps you just recorded.  Now, for the performance boost.  Add the following call to set EnableGraphicsUpdate to False until everything is done.  Then set it back to True to see a final graphics update.

    Public Sub main()
        Dim swDoc As ModelDoc2 = Nothing
        Dim swPart As PartDoc = Nothing
        Dim swDrawing As DrawingDoc = Nothing
        Dim swAssembly As AssemblyDoc = Nothing
        Dim boolstatus As Boolean = False
        Dim longstatus As Integer = 0
        Dim longwarnings As Integer = 0
        swDoc = CType(swApp.ActiveDoc, ModelDoc2)
        Dim myModelView As ModelView = Nothing
        myModelView = CType(swDoc.ActiveView, ModelView)
        myModelView.FrameState = _
            swWindowState_e.swWindowMaximized
        myModelView = CType(swDoc.ActiveView, ModelView)
 
        myModelView.EnableGraphicsUpdate = False
 
        myModelView.RotateAboutCenter(0.10566, 0)
        myModelView = CType(swDoc.ActiveView, ModelView)
        myModelView.RotateAboutCenter(0.055131, 0)
    .... way too much stuff in between to post ....
        swDoc.ViewZoomtofit2()
        swDoc.HideComponent2()
        swDoc.ClearSelection2(True)
 
        myModelView.EnableGraphicsUpdate = True
 
        swDoc.ShowNamedView2("*Top", 5)
    End Sub

Now run the macro again and, presto change-o, all you’ll see is a brief pause and the end result.  Add this to any existing macro that takes time to process and you’ll likely see improvements.  Watch out though.  This one can come with a nasty side effect if you don’t handle and trap errors.  If your code stops before setting EnableGraphicsUpdate to true, your model view is dead in the water until you re-open the file.

SldWorks.DocumentVisible


This one is perfect for those macros that need to open reference models into memory.  Adding views to drawings and inserting components in assemblies are two obvious uses.  The SolidWorks application has the DocumentVisible method that causes any files of a given type to be opened without a display window.  Refreshing the display window is visually distracting as well as a performance drain.

The following VB.NET macro code inserts a part into a new assembly.  Check the path for the sample part to make sure it is correct for your system.

    Public Sub main()
        Dim swDoc As ModelDoc2 = Nothing
        Dim swAssembly As AssemblyDoc = Nothing
        Dim swComp As Component2
        swDoc = swApp.NewAssembly()
        Dim assemName As String
        assemName = swDoc.GetTitle
        swAssembly = swDoc
        Dim FileName As String
        FileName = "C:\Program Files\SolidWorks Corp" _
            & "\SolidWorks\samples\tutorial\" _
            & "advdrawings\base plate.sldprt"
        swDoc = swApp.OpenDoc(FileName, _
            swDocumentTypes_e.swDocPART)
        swApp.ActivateDoc(assemName)
        swComp = swAssembly.AddComponent2(FileName, 0, 0, 0)
        swAssembly.EditRebuild()
    End Sub

Before you can make the call to AddComponent2, you need to have the model open in memory.  But notice the time required to open the base plate part.  And when you’re done, the base plate part is still open with its own window.  Imagine adding dozens or even hundreds of parts into an assembly.  You could throw someone into a seizure with all the blinking! 

Add some smooth speed to the macro by calling DocumentVisible from the SolidWorks application interface.  You need to pass it the document type too. 

    Public Sub main()
        Dim swDoc As ModelDoc2 = Nothing
        Dim swAssembly As AssemblyDoc = Nothing
        Dim swComp As Component2
        swDoc = swApp.NewAssembly()
        Dim assemName As String
        assemName = swDoc.GetTitle
        swAssembly = swDoc
        Dim FileName As String
        FileName = "C:\Program Files\SolidWorks Corp" _
            & "\SolidWorks\samples\tutorial\" _
            & "advdrawings\base plate.sldprt"
        'Open parts invisibly
        swApp.DocumentVisible(False, swDocumentTypes_e.swDocPART)
 
        swDoc = swApp.OpenDoc(FileName, _
            swDocumentTypes_e.swDocPART)
        swApp.ActivateDoc(assemName)
        swComp = swAssembly.AddComponent2(FileName, 0, 0, 0)
        swAssembly.EditRebuild()
 
        'reset part visibility
        swApp.DocumentVisible(True, swDocumentTypes_e.swDocPART)
    End Sub

Much nicer, no?  If you’re adding multiple components, consider using DocumentVisible along with EnableGraphicsUpdate on the assembly ModelView and you’ll have some serious speed!  Side effects include completely destroying a user’s ability to open models with any kind of user interface if you fail to trap errors and reset document visibility at the end of your code.  Once you’ve called DocumentVisible during a SolidWorks session, all files opened of that type will be opened in memory, but will be invisible to the user unless you reset DocumentVisible to True.

3 comments:

  1. I'd love to hear your successes or challenges using any of these performance enhancers! If you have any others you like to use, let me know too.

    ReplyDelete
  2. Thank you Mike.
    These two lines helped me a lot to create a repeatable pattern correctly!

    ReplyDelete
  3. Very helpful. Thanks for sharing these invaluable experiences.

    ReplyDelete

Note: Only a member of this blog may post a comment.