5 Replies Latest reply on Jun 14, 2014 3:33 AM by Artem Taturevych

    Macro for adjusting dimension to keep constant volume?

    J. R.

      Hi all,

       

      Due to SW limitations on dimensioning volumes, I need a macro to do a certain job. However, due to my inexperience, I don't know how to write it.

       

      I'm attaching the model so you can see. Generated in SW2013.

       

      There is a 3D solid body. There is also a plane which intersects the body, and cuts off part of it (Surface Cut command). The plane's position is controlled by 2 dimensions - Angle at which the model is cut (Angle@Cut Angle), and how close the plane is to the center of the body (Depth@Cut Depth).

       

       

      In Equations window, user inputs the Desired Volume, Error Margin and Angle, manually, and as the model is rebuilt, the macro should adjust Depth@Cut Depth by trial and error to set the Volume of the body in 10% Error Margin.

       

       

       

      Again, the macro should:

      1. Run every time model is rebuilt;

      2. Compare Volume to Desired Volume;

      2. Adjust Depth dimension in Cut Depth plane by trial and error until these Volume is within 10% of Desired Volume

      3. End.

       

       

      Can anybody help me out to write this macro? I need not only to write it, but to understand it, because I'll be using it for much more complex model.

        • Re: Macro for adjusting dimension to keep constant volume?
          J. R.

          I went ahead, took some VBA tutorials, and written the code. Tested, it is working on it's own, but now I need to connect it to SolidWorks model - mostly dimensions and global equations.

           

          Here is the code:

           

           

          Dim Volume As Single

          Dim DesiredVolume As Single

          Dim ErrorMargin As Single

          Dim Depth As Single

          Dim Increment As Single

          Dim TooHigh As Integer

           

          Sub main()

              Depth = Depth@CutDepth@part1.sldprt

              DesiredVolume = Desired Volume@part1.sldprt

              ErrorMargin = Error margin@part1.sldprt

              Increment = DesiredVolume * ErrorMargin * 0.05

              TooHigh = -1

           

           

              Do While Abs(Volume - DesiredVolume) > DesiredVolume * ErrorMargin

                  Volume = Volume@part1.sldprt

                      If Volume < DesiredVolume Then

                          TooHigh = 0

                          Depth = Depth + Depth * Increment

                      Else

                          TooHigh = 1

                          Depth = Depth - Depth * Increment

                      End If

                      Set Depth@CutDepth@part1.sldprt = Depth

                      boolstatus = Part.ForceRebuild()

           

                      If Volume < DesiredVolume And TooHigh = 1 Or Volume > DesiredVolume And TooHigh = 0 Then

                      Increment = Increment / 2

                      End If

              Loop

           

              MsgBox Volume

           

          End Sub

           

           

           

           

          As you can guess, now it doesn't recognize Depth@CutDepth@part1.sldprt and similar references. How can I translate this into corresponding dimensions and equations on my model?

            • Re: Macro for adjusting dimension to keep constant volume?
              J. R.

              I managed to do it on my own. The macro does everything I need, but I still neet to find a way to make it run every time part rebuilds. How can I accomplish that?

               

              My code:

               

               

              Dim Volume As Single

              Dim DesiredVolume As Single

              Dim ErrorMargin As Single

              Dim Depth As Single

              Dim Set_Depth As Single

              Dim Increment As Single

              Dim TooHigh As Integer

              Dim Counter As Integer

               

              Dim swApp As SldWorks.SldWorks

                  Dim swModel As SldWorks.ModelDoc2

                      Dim swFeature_Cut_Depth As SldWorks.Feature

                      Dim swSelectionManager As SldWorks.SelectionMgr

                          Dim swDim_Depth As SldWorks.Dimension

                  Dim boolstatus As Boolean

                  Dim errors As Long

                  Dim warnings As Long

               

              Dim swEqnMgr As SldWorks.EquationMgr

               

               

              Sub main()

                  Set swApp = Application.SldWorks

                 

               

                  Set swModel = swApp.ActiveDoc

                  boolstatus = swModel.Extension.SelectByID2("Cut Depth", "PLANE", 0, 0, 0, False, 0, Nothing, 0)

                  Set swSelectionManager = swModel.SelectionManager

                  Set swFeature_Cut_Depth = swSelectionManager.GetSelectedObject6(1, -1)

                  Set swDim_Depth = swFeature_Cut_Depth.Parameter("Depth")

                  Depth = swDim_Depth.SystemValue

                 

                  Set swEqnMgr = swModel.GetEquationMgr

                  Volume = swEqnMgr.Value(0)

                  DesiredVolume = swEqnMgr.Value(1)

                  ErrorMargin = swEqnMgr.Value(2)

                 

                  Increment = DesiredVolume * ErrorMargin * 0.05

                  TooHigh = -1

                  Counter = 0

               

                 

                  Do While Abs(Volume - DesiredVolume) > DesiredVolume * ErrorMargin Or Counter = 20

                     

                          If Volume < DesiredVolume Then

                              TooHigh = 0

                              Depth = Depth + Depth * Increment

                              Counter = Counter + 1

                          Else

                              TooHigh = 1

                              Depth = Depth - Depth * Increment

                              Counter = Counter + 1

                          End If

                          Set_Depth = swDim_Depth.SetSystemValue3(Depth, swSetValue_InThisConfiguration, Empty)

                          swModel.EditRebuild3

                          Volume = swEqnMgr.Value(0)

                      

                          If Volume < DesiredVolume And TooHigh = 1 Or Volume > DesiredVolume And TooHigh = 0 Then

                          Increment = Increment / 2

                          End If

                  Loop

                 

                  If Counter > 19 Then

                  MsgBox "Error"

                  Else

                  MsgBox "Volume: " & Volume & vbCrLf & "Counter: " & Counter

                  End If

                 

              End Sub

               

               

                • Re: Macro for adjusting dimension to keep constant volume?
                  Josh Brady

                  Sorry... you can't.

                   

                  Your code has EditRebuild3. If a rebuild triggers your code, your code will trigger itself. You cannot evaluate volume until after the rebuild completes, but the rebuild will never complete because a new instance of your code will run every time the rebuild happens.  You would run out of stack space and crash to desktop.

                   

                  It may be possible to directly access the modeler and use temporary bodies to analyze volume, but this will not be quite as simple as what you have above.

                   

                  There are two ways to run code on every rebuild.  One is to create a macro feature.  The other is to embed VBA code into a specially crafted equation.  There are posts on this forum on how to do that, but it's pretty tricky.

                   

                  It's interesting stuff!  Happy learning!

                  • Re: Macro for adjusting dimension to keep constant volume?
                    Deepak Gupta

                    Thanks Josh for the clarification, didn't thought of that

                    • Re: Macro for adjusting dimension to keep constant volume?
                      Artem Taturevych

                      Keith has a good article regarding embedding the macros into equations: http://www.cadsharp.com/blog/equation-triggered-macros/

                       

                      In addition to what Josh said even if you can manage to skip the rebuild to avoid the infinite rebuild recursion (it is possible to do with variable which will indicate that the current rebuild is a 'technical' rebuild caused by a macro so the rerun of macro is not required). But even thus it may be unsafe to do rebuild within a rebuild because not all elements may be ready for the operation. You may need to use OnIdle notification fired after the Rebuild to safely do your routine. So I would suggest to go with add-in rather than macro in this case.