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.SldWorksDim 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.SldWorksDim 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 = NothingDim 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 = NothingDim 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 = NothingDim 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 = NothingDim 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.
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.
ReplyDeleteThank you Mike.
ReplyDeleteThese two lines helped me a lot to create a repeatable pattern correctly!
Very helpful. Thanks for sharing these invaluable experiences.
ReplyDelete