Problem accessing CadModel.CADProjectPoint from Basic Script

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem accessing CadModel.CADProjectPoint from Basic Script

    Trying to access the my Cad model in the Graphics Display Window using a PC-DMIS basic script. Getting a "Missing parameter(s)" error message. Here's what I have with the error being generated on the last line seen below;

    '==================
    Sub GetProjectPointData()
    '==================
    Dim App As Object
    Dim Part As Object
    Dim Cmds As Object
    Dim GWindow As Object
    Dim CadWin As Object
    Set App = CreateObject("PCDLRN.Application")
    Set Part = App.ActivePartProgram
    Set Cmds = Part.Commands
    Set GWindow = Part.CadWindows
    Set CadWin = GWindow.Item(1)
    Dim CADMod As CadModel
    Set CADMod = Part.CadModel
    '
    '
    Dim RetVal As Boolean
    Dim XT, YT, ZT, DIRX, DIRY, DIRZ, PX, PY, PZ, PDIRX, PDIRY, PDIRZ As Double
    Dim FeatureName, FID As String
    '
    CadWin.Visible = True

    XT=NetData(7,1)
    YT=NetData(7,2)
    ZT=NetData(7,3)
    CADMod.CADProjectPoint(XT, YT, ZT,7,0,0, PX, PY, PZ, PDIRX, PDIRY, PDIRZ,2)



    The Function info in the help menus has 13 parameters, (as do I). Haven't tried accessing the Graphics display window from a script before and not sure if i have everything right here, but it does compile without errors, so...

    If anyone that has basic script/Pcdmis knowledge about this topic, it would be much appreciated if you could take a peek at this and steer me in the right direction if there are blaring issues seen at first glance.



  • #2
    What is NetData?
    PC-DMIS CAD++ 2o19 R1 SP2

    Comment


    • #3
      I've never tried that function, but note that it is a function and you are calling it as a subroutine. I would start by adding a "Result =" at the beginning of the line and declare Result as a suitable type (32 bit unsigned integer?).

      Looking at the function definition in the type library, it agrees on the 13 arguments,

      Code:
          function CADProjectPoint(pointX: Double; pointY: Double; pointZ: Double;
                                   geometryFilterFlags: ENUM_CAD_GEOMETRY_FILTER_FLAGS;
                                   vectorOption: ENUM_CAD_VECTOR_OPTION;
                                   surfaceBoundaryOption: ENUM_CAD_SURFACE_BOUNDARY_OPTION;
                                   out pProjectPointX: Double; out pProjectPointY: Double;
                                   out pProjectPointZ: Double; out pProjectVectorI: Double;
                                   out pProjectVectorJ: Double; out pProjectVectorK: Double;
                                   out pCadHandle: ICadHandle): ENUM_CAD_RESULT; dispid 7;
      but your last one - 2 - is almost certainly wrong, as it is an OUT parameter - it must be a variable!
      Last edited by AndersI; 05-15-2019, 10:13 AM. Reason: Reading TLB closer
      AndersI
      SW support - Hexagon Metrology Nordic AB

      Comment


      • #4
        Response #2: NetData is a String Array I have set up as a global variable at the top of my program. The code in my example is just the code from a sub routine I created to call to from sub Main.

        Response #2: Agreed. Added this, and received a "Type Mismatch" error.

        Dim Result, CH As Integer
        Result = CADMod.CADProjectPoint(XT, YT, ZT,7,0,0, PX, PY, PZ, PDIRX, PDIRY, PDIRZ, CH)


        This function should be returning values for all of these variables: " PX, PY, PZ, PDIRX, PDIRY, PDIRZ, CH " in the call to CADProjectPoint. Passing in my XT, YT, ZT coordinates to have them projected onto model in Graphics display window, with returns representing model point values and vector relative to cad model.

        Thank for helping, but still compiles and producing error above during runtime. Is it that I need to define a "point" variable of sorts that would hold all the return values? Hmm.

        Comment


        • #5
          Could it be you need variables for … 7, 0, 0, … too?
          AndersI
          SW support - Hexagon Metrology Nordic AB

          Comment


          • #6
            Responce #5:
            AndersI, first off, thanks for all you do for everyone on the boards here. I see your posts throughout issues I look up all the time and appreciate your contributions!

            Just did a test to check and see if "value" works versus enumeration "member" in a field that holds this type of information. Code below works both ways. First line under loop is commented out (which I've been using in my script). The second line where "DmisCmd.Feature = 4" is the enumeration value for F_LINE in the commented line.

            Code:
            For Each DmisCmd In Cmds
            '        If DmisCmd.isFeature And DmisCmd.Feature = F_LINE  Then
                    If DmisCmd.isFeature And DmisCmd.Feature = 4 Then
            .
            .
            .
            History of why I want to write this script:
            The script I'm writing to try and access the Graphics Display Window where my cad model resides pertains to me wanting to "OverRide Nominals" of points I measured using our Laser Tracker. After measuring net pads (we take 5 hits (vector_points) on each pad) on our tooling here at Fiat-Chrysler Automobiles, we have to go back and bump each point measured against the cad mode in the Graphics Display Window to aquire the proper nominal value for each point.

            Having anywhere from 6 to 30 net pads on any given piece of tooling out on the body shop floor, this means right-clicking on each vector point in the Edit Window (Summary Mode) and then selecting "Feature/OverRide Nominals", then clicking on the appropriate surface in the Graphics Display Window, check the surface highlighted surface in the "OverRide Nominals" window, and then click on the "Drop Point" values and click the OverRide Button. Not too hard to do, but time consuming.

            Script Benefits:
            The benefit for having a script that accesses the cad model in the Graphics Display Window could be used for all Tracker users and possibly even those that use PC-DMIS Scanning software. I've seen a lot of post on the boards pertaining to users trying to acquire nominal from Graphics Display Window after producing measured scans. I myself do not use PC-DMIS Scanning software and may never in the future, but never say never, ha.

            Current Script Conditions:
            Prior to looking into the CadModel.CADProjectPoint object, I was poking around trying to find a way to reproduce the override nominal values seen in the OverRide Nominals Window. What I came up with was this;

            *Read in the nominal and measured data from 2 net pad measurements (5 points on each net pad) and load it into the NetData(1 To 400,1 To 11) array. (Sub routine GetNetData).
            Col 1-3 will eventually represent the nominal value of the measured hit projected onto the cad model (x, y, and z, OverRide Nominal values).
            Col 4-6 represents the measured x, y, and z values of each hit on the net pad
            Col 7-9 represents the measured i,j, and k values of each hit on the net pad. (relative to tracker alignment at time of tool shoot).
            Col 10 represents the feature ID of each measured hit. (Hit name must have the word "NET" in it).
            Col 11 not used.

            *Load a LINE feature with the xyz measured values and ijk measured values from a net pad hit into "both" the Theoretical and Actuals xyz and ijk fields of the line. (Sub routine LoadLine). More about this line feature later!

            *Next, I construct a drop_point from the net pad hit (REF1) and the loaded LINE (REF2). (Sub routine CreateDrop). I write these drop_point theoretical values back out into spots 1-3 of the NetData array.

            This construction produces a point that has nominals very close to what is seen in the OverRide Nominals Window. They are slightly different because the ijk vector values of the measured hit (and subsequently the loaded line) are picked up and created from the tracker alignment which is not the same as the Cad Model alignment which is theoretically perfect and in car body position.

            Not wanting to be sloppy, (and always striving for perfection (OCD)), I kept searching for other possibilities to achieve perfect data. Below is the script and subroutines;

            Comment


            • #7
              Code:
              Attribute VB_Name = "OverRideNominals"
              '-----------------------
              'Global VARIABLE Declarations
              '-----------------------
              Dim NetData(1 To 400,1 To 11) As String
              Dim I As Long
              Dim CurrentNetFeature, TotalNetFeatures As Long
              Dim FID As String
              '
              '-----------------------
              'INITIALIZATION of Global Variable(s)
              '-----------------------
              CurrentNetFeatures = 1
              TotalNetFeatures = 0
              FID = " " 'Feature ID
              '
              '==================
              Sub GetNetData()
              '==================
              Dim App As Object
              Dim Part As Object
              Dim Cmds As Object
              Set App = CreateObject("PCDLRN.Application")
              Set Part = App.ActivePartProgram
              Set Cmds = Part.Commands
              Dim Cmd As Object
              Dim I As Long
              '
              I = 1
                  For Each Cmd In Cmds
                      If Cmd.isFeature And Cmd.Feature = F_POINT  Then
                          FID = Cmd.ID
                          If InStr(1, FID,"NET") <> 0 Then
                              NetData(I,1) = Cmd.GetText(THEO_X,0)
                              NetData(I,2) = Cmd.GetText(THEO_Y,0)
                              NetData(I,3) = Cmd.GetText(THEO_Z,0)
                              NetData(I,4) = Cmd.GetText(MEAS_X,0)
                              NetData(I,5) = Cmd.GetText(MEAS_Y,0)
                              NetData(I,6) = Cmd.GetText(MEAS_Z,0)
                              NetData(I,7) = Cmd.GetText(MEAS_I,0)
                              NetData(I,8) = Cmd.GetText(MEAS_J,0)
                              NetData(I,9) = Cmd.GetText(MEAS_K,0)
                              NetData(I,10) = FID
                              TotalNetFeatures = I
                              I = I + 1
                          End If
                      End If
                  Next Cmd
              End Sub
              '
              '==================
              Sub LoadLine()
              '==================
              Dim App As Object
              Dim Part As Object
              Dim Cmds As Object
              Dim LastCmd As Object
              '
              Set App = CreateObject("PCDLRN.Application")
              Set Part = App.ActivePartProgram
              Set Cmds = Part.Commands
              '
              Dim Cmd As Object
              Dim RetVal As Boolean
              Dim RefId1, Refld2, XT, YT, ZT, DIRX, DIRY, DIRZ As String
              Dim FeatureName As String
              '
              Dim CommandCount As Long
              '
                  CommandCount = Cmds.count
                  XT = NetData(1,4)
                  YT = NetData(1,5)
                  ZT = NetData(1,6)
                  DIRX = NetData(1,7)
                  DIRY = NetData(1,8)
                  DIRZ = NetData(1,9)
                  FeatureName = "LIN1"
                  For Each Cmd In Cmds
                      If Cmd.isFeature And Cmd.Feature = F_LINE Then
                          Cmd.Marked = True
                          RetVal = Cmd.SetToggleString(1, COORD_TYPE, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,4), THEO_SX, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,5), THEO_SY, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,6), THEO_SZ, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,4), THEO_EX, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,5), THEO_EY, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,6), THEO_EZ, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,7), THEO_I, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,8), THEO_J, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,9), THEO_K, 0)
                          RetVal = Cmd.PutText("0", THEO_LENGTH, 0)
                          RetVal = Cmd.PutText("0", SURFVEC_I, 0)
                          RetVal = Cmd.PutText("0", SURFVEC_J, 0)
                          RetVal = Cmd.PutText("1", SURFVEC_K, 0)
              
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,4), MEAS_SX, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,5), MEAS_SY, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,6), MEAS_SZ, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,4), MEAS_EX, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,5), MEAS_EY, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,6), MEAS_EZ, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,7), MEAS_I, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,8), MEAS_J, 0)
                          RetVal = Cmd.PutText(NetData(CurrentNetFeature,9), MEAS_K, 0)
                          RetVal = Cmd.PutText("0", MEAS_LENGTH, 0)
                          RetVal = Cmd.PutText("0", SURFVEC_MEAS_I, 0)
                          RetVal = Cmd.PutText("0", SURFVEC_MEAS_J, 0)
                          RetVal = Cmd.PutText("1", SURFVEC_MEAS_K, 0)
                          RetVal = Cmd.PutText(FeatureName, ID, 0)
                      End If
                  Next Cmd
              '
              End Sub
              '
              '==================
              Sub CreateDrop()
              '==================
                  Dim App As Object
                  Dim Part As Object
                  Dim Cmds As Object
                  Dim DmisCmd As Object
              '
                  Set App = CreateObject("PCDLRN.Application")
                  Set Part = App.ActivePartProgram
                  Set Cmds = Part.Commands
              '
                  Dim RetVal As Boolean
                  Dim RefId1, Refld2, XT, YT, ZT As String
                  Dim DropFeatureName, FID As String
                  Dim CommandCount As Long
              '
                  CommandCount = Cmds.count
                  Set DmisCmd = Cmds.Item(CommandCount)
              '
                  For Each DmisCmd In Cmds
              '        If DmisCmd.isFeature And DmisCmd.Feature = F_LINE  Then
                      If DmisCmd.isFeature And DmisCmd.Feature = 4 Then
                          RefId1 = NetData(CurrentNetFeature,10)
                          RefId2 = "LIN1"
                          DropFeatureName = "CDROP" + NetData(CurrentNetFeature,10)
                          Cmds.InsertionPointAfter DmisCmd
                          Set DmisCmd= Cmds.Add(CONST_DROP_POINT, True)
                          DmisCmd.Marked = True
                          RetVal = DmisCmd.PutText(DropFeatureName, ID, 0)
                          RetVal = DmisCmd.PutText(RefId1, REF_ID, 1)
                          RetVal = DmisCmd.PutText(RefId2, REF_ID, 2)
                          RetVal = DmisCmd.SetToggleString(1, COORD_TYPE, 0)
              '            XT = DmisCmd.GetText(THEO_X, 0)
                          NetData(CurrentNetFeature,1) = DmisCmd.GetText(THEO_X, 0)
              '            YT = DmisCmd.GetText(THEO_Y, 0)
                          NetData(CurrentNetFeature,2) = DmisCmd.GetText(THEO_Y, 0)
              '            ZT = DmisCmd.GetText(THEO_Z, 0)
                          NetData(CurrentNetFeature,3) = DmisCmd.GetText(THEO_Z, 0)
                      End If
                  Next DmisCmd
              End Sub
              '
              '==================
              Sub WriteNominals()
              '==================
              Dim App As Object
              Dim Part As Object
              Dim Cmds As Object
              Dim LastCmd As Object
              '
              Set App = CreateObject("PCDLRN.Application")
              Set Part = App.ActivePartProgram
              Set Cmds = Part.Commands
              '
              Dim PrgLineCmd As Object
              Dim RetVal As Boolean
              Dim RefId1, Refld2, XT, YT, ZT, DIRX, DIRY, DIRZ As String
              Dim FeatureName As String
              '
                  For Each PrgLineCmd In Cmds
                      If PrgLineCmd.isFeature Then
                          FID = PrgLineCmd.ID
                          If FID = NetData(CurrentNetFeature,10) Then
                              PrgLineCmd.Marked = True
                              RetVal = PrgLineCmd.PutText(NetData(CurrentNetFeature,1), THEO_X, 0)
                              RetVal = PrgLineCmd.PutText(NetData(CurrentNetFeature,2), THEO_Y, 0)
                              RetVal = PrgLineCmd.PutText(NetData(CurrentNetFeature,3), THEO_Z, 0)
                          End If
                      End If
                  Next PrgLineCmd
              End Sub
              '
              '==================
              Sub GetProjectPointData()
              '==================
              Dim App As Object
              Dim Part As Object
              Dim Cmds As Object
              '
              Set App = CreateObject("PCDLRN.Application")
              Set Part = App.ActivePartProgram
              Set Cmds = Part.Commands
              '
              Dim GWindow As Object
              Dim CadWin As Object
              Set GWindow = Part.CadWindows
              Set CadWin = GWindow.Item(1)
              CadWin.Visible = True
              '
              Dim CADMod As CadModel
              Set CADMod = Part.CadModel
              Dim XM, YM, ZM, DIRX, DIRY, DIRZ, PX, PY, PZ, PDIRX, PDIRY, PDIRZ As Double
              Dim FeatureName As String
              Dim RetVal As Boolean
              RetVal = CadWin.Visible
              '
              XM=NetData(6,1)
              YM=NetData(6,2)
              ZM=NetData(6,3)
              Dim CH As Integer
              Dim CadResult As Integer
              '
              ' 7 All Cad Features
              ' 4 Cad Surfaces Only
              '
                    CadResult = CADMod.CADProjectPoint(XT, YT, ZT,4,0,0, PX, PY, PZ, PDIRX, PDIRY, PDIRZ, CH)
              '
              ' -1  Invalid Object handle, Or operation Not enabled; no value returned.
              '  0  No value returned; geometry doesn't make sense, failed geometry (i.e. parallel lines), Or Not yet implemented.
              '  2  Logic produced a hit, value returned (all is well).
              '  1  Logic produced a miss, closest point returned Or ambiguous point returned.
              '
              End Sub
              '
              '==================
              Sub Main()
              '==================
              Dim App As Object
              Dim Part As Object
              Dim Cmds As Objec
              '
              Set App = CreateObject("PCDLRN.Application")
              Set Part = App.ActivePartProgram
              Set Cmds = Part.Commands
              '
              Dim RepWin As Object
              Set RepWin = Part.ReportWindow
              Dim EditWin As Object
              Set EditWin = Part.EditWindow
              EditWin.Visible = True
              '
                  GetNetData
                  For CurrentNetFeature = 1 To TotalNetFeatures
                      LoadLine
                      CreateDrop
                      WriteNominals
                  Next CurrentNetFeature
                  GetProjectPointData
              '
              Part.Activate
              EditWin.Visible = True
              End Sub

              Comment


              • #8
                Finding Other Possibilities:
                Upon further investigation I came across the "View Menu/Cad Verify" option in PC-DMIS. Looking at this, I plugged in my drop_point constructed nominals from my script and the Cad Verify menu produced the exact nominals seen in the "OverRide Nominals" window when a point is bumped. It actually shows both nominals and vector from the point projected onto the Cad Model. Looking further, I found that the object CadModel.CADProjectPoint is the object that will produce the same results as the Cad Verify menu produces.

                Current Script Condition:
                As of now, I am unable to get CadModel.CADProjectPoint to work. This function has type ENUM_CAD_RESULT. Clicking on this in the help menus show that the values are -1, 0, 2, and 1. This would suggest that the function should be assigned to an Integer value (as seen in the script).

                Other questions I have pertain to the last returned value "CadHandle". CadHandle is an object that, as far as I can tell, seems to represent an instance of the Cad Model in the Graphics Dislpay Window (could be wrong about this) and somehow must be defined prior to using CadModel.CADProjectPoint. The members are CadSequence, Collection, PartInstanceID, and SubCadId. Funny there is no description for CadHandle and not much in the way of showing how it is used.

                Also seeing a ENUM_CAD_COLLECTION. Each of these members starts with HCAD_. Because I am dealing with projecting points onto cad surfaces, HCAD_SURFACE (value = 1) may be my best bet when defining CadHandle.collection.

                Notes on LoadLine:
                I am currently importing the line feature I use to load each measured feature's value in to it. Tried creating it in the script but I must be missing something because the script created line does not produce the drop_point values seen when I import/dmis line. Here's the .dmi file I import below my net pad hits (10 total);

                Code:
                 DMISMN/LIN1.dmi
                 FILNAM/LIN1.dmi
                F(LIN1)=FEAT/MEAS_LINE,UNBND,CART,722.23,760.92,1593.72,0.9999999,0.0002614,$
                  -0.0002259,0,0,1
                MEAS/LINE,F(LIN1),2
                    PTMEAS/CART,0,0,0,0,0,1,RMS=N/A,
                    PTMEAS/CART,0,0,0,0,0,1,RMS=N/A,
                ENDMES
                ENDFIL
                Any further thought would be appreciated pertaining to the script set-up procedure for accessing the cad model in the Graphics Display Window or the use of object CadModel.CADProjectPoint.

                ​​​​​​​​​​​​​​

                Comment


                • #9
                  Nice job Dennis Paul especially on a rare use of multidimensional array! Love that you have to allocate memory to them
                  Appreciate you sharing with the community.
                  Last edited by Kp61dude!; 05-16-2019, 03:01 PM.
                  PcDmis 2015.1 SP10 CAD++
                  Global 7-10-7 DC800S

                  Comment


                  • #10
                    Originally posted by Dennis Paul View Post
                    The script I'm writing to try and access the Graphics Display Window where my cad model resides pertains to me wanting to "OverRide Nominals" of points I measured using our Laser Tracker. After measuring net pads (we take 5 hits (vector_points) on each pad) on our tooling here at Fiat-Chrysler Automobiles, we have to go back and bump each point measured against the cad mode in the Graphics Display Window to aquire the proper nominal value for each point.
                    I may be misunderstanding something, but isn't that what "Find Nominals during Execution" does? F5, General, ~2 pages down through the check boxes.

                    AndersI
                    SW support - Hexagon Metrology Nordic AB

                    Comment


                    • #11
                      Response #10:
                      AndersI, I did a test and no luck. We are in manual mode, learning each point into the program as we measure manually on the tooling. After learning 5 hit points on a net pad, I re-executed the points and re-measured them individually. The THEO's picked up in the measured hit does not match the THEO seen in the OverRide Nominals Window when I bump the point to CAD model in Graphics Display Window.

                      Could it be possible that the "Find Nominal on Execution" is for Scanning? I'm not sure myself seeing as I have not done any scanning to see how this works with scans. It doesn't appear to work (pick up nominals from cad model) using our Tracker Software.

                      I guess my real issue is still 'Trying to access the CAD model in the Graphics Display Window' using a basic script. I can access the Edit Window features and even refresh the Report Window through commands in my script, but haven't figured out how to access the GDWindow.

                      The CadModel Object description is:

                      "The CadModel object allows you to work with the imported CAD model in PC-DMIS' Graphic Display Window".

                      I haven't seen anywhere (Internet, pcdmis forum, etc...) where someone has the basic script calls to access the GDWindow. I have been in contact with Hexagon here in Michigan. Will give them a call back today and see if they can push this to a higher level to see if someone knows how to do this through a script. Not sure if the type declarations are correct in these CadModel Methods are correct and certainly not sure about the CadHandle Object and how that intertwines into all of this.

                      Still in Limbo here at FCA,

                      Comment


                      • #12
                        I assume you have FIND NOMS selected in the auto vector point dialog? And have done an alignment?
                        AndersI
                        SW support - Hexagon Metrology Nordic AB

                        Comment


                        • #13
                          No and Yes. Had F5 Setting in General box 'Find Nominals' checked and 'Find Nominals on Execution' checked. Looked at auto vector_point feature and was set to 'Nominal'. Will perform test again and get back with results.

                          Comment


                          • #14
                            Well that works. Not sure what is faster.

                            Currently we measure all the net pad hits, then right-click on each feature to access OverRide Nominals Window, pick the surface to bump point onto, select the drop point from menu and click override button.

                            With this new method, we would measure 5 hits on net pad. Edit each hit to activate "Find Nominals", re-execute hits and re-measure again by pressing A button on T-probe and then B button to end.

                            6 of one, half a dozen of the other as far as saving time I think. Thank for your help AnderdI. I'll still play with accessing cad model in graphics window and update this thread if I come up with anything.

                            X DEA employee (13 year), current FCA employee (24 years).

                            Comment


                            • Kp61dude!
                              Kp61dude! commented
                              Editing a comment
                              "X DEA employee" it all makes sense now...

                          • #15
                            Response 14.1

                            Yeah, I guess that shows my age and being a little old school (using memory sucking, multi-dimensional arrays and all, KEK).

                            So Kp61dude!, any thoughts on how to access my cad model in the Graphics Display Window using the basic script editor?
                            Or using the CadHandle object, or the CadModel.CADProjectPoint in a script?

                            Comment

                            Related Topics

                            Collapse

                            Working...
                            X