11 Replies Latest reply on Sep 2, 2016 4:43 AM by roberto gennari

    Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify

    Jacob Corder

      I am in need of getting the closest possible location on a PRESELECTED planar face for this example. I am using DPartEents_UserSelectionPreNotify to capture the preselected object, then using DMouseEvents_MouseMoveNotify which gives me the X and Y Location in Pixels on the monitor. See Code Below. this gives me the appearance of having the location but is quite far away in model space. I Need it relative to the face that is preselected. I Know what one of the XYZ Values are from the face. i need to take that known value along with i am assuming the rotation of the model and

       

      Public Function GetXYZFromModelViewXY(ByVal ModDoc As ModelDoc2, ByVal ModViewX As Double, ByVal ModViewY As Double, ByVal ReferenceFace As Face2, ByVal SetToFace As Boolean) As Double()

              GetXYZFromModelViewXY = Nothing

              Dim ModViewLocation() As Double = Nothing

              Dim ModelViewPoint As MathPoint = Nothing

              If IsNothing(ModDoc) = False And IsNothing(ReferenceFace) = False Then ModelViewPoint = iSwApp.IGetMathUtility.CreatePoint(New Double(2) {ModViewX, ModViewY, 0})

              If IsNothing(ModDoc.IActiveView) = False And IsNothing(ModelViewPoint) = False Then

                  Dim ModelSpacePoint As MathPoint = ModelViewPoint.IMultiplyTransform(ModDoc.IActiveView.Transform.Inverse)

                  If IsNothing(ModelSpacePoint) = False Then

                      ReDim ModViewLocation(2)

                      For i = 0 To 2

                          ModViewLocation(i) = ModelSpacePoint.ArrayData(i)

                      Next

                  End If

                  ModelSpacePoint = Nothing

              End If

              ModelViewPoint = Nothing

              Return ModViewLocation

          End Function

       

      this will return the location that i use to create a temporary body as a preview of what will happen if a user selects the face. The temporary body is not selectable so i do not have any issues with that.

       

      This second image shows the issue as the preview is supposed to be flat to the face as the feature above it is. if i move the mouse to the right it completely disappears into the block. this is all relative to the rotation angle of the model.

       

      i am assuming i need to take my x y and z values that i  am recieving from this function and triangulate the distances so the value that would put it on the face is correct.

       

      for example i am recieving in meters

       

      x = 0.0374432120

      Y = 0.0037049424

      Z = -0.0212748091

       

      in this case Y should equal 0.0

      attached is also the model view orientation transformation matrix. i might not need to use it but i am assuming it is what determines my rotational angle.

       

      Sorry if this is confusing. post any comments that could help or help me better understand how to use transforms.

        • Re: Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify
          Artem Taturevych

          Have you tried the SelectionMgr::GetSelectionPoint2 method?

          ____________________________________________________

          Regards,

          Artem Taturevych, Application Engineer at Intercad (Australia)

           

          translationXpert – add-in to translate SolidWorks models

          myIntercad an integrated tool for SolidWorks Professionals

          LinkedIn SolidWorks API Education Group

          • Re: Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify
            Jacob Corder

            Alright. I Was able to figure out how to do this. This is not the best way to do this but it does work.

             

            Limitations are as follows

             

            It only works on a planar face

            The Face Must have a normal value of 1 or -1  so (0,1,0) or (-1,0,0) ect

            You must know the XY Values returned from mouse events

             

            The only thing needed to find is the Z Value that goes into the point that is transformed by the modelview.Transform.Inverse. This Z Value is treated as depth to screen into Model Space.

             

            First thing needed is getting the point with a z value of 0, and a z value of 1 i was able to determine the depth change in pixels to that face. by running the transformation 3 times it is able to get within a very small distance to that face, then use Face2.getclosestpointOn and the location is projected exactly on that face.

             

             

             

             

                Public Function PreSelectionPoint(ByVal ModDoc As ModelDoc2, ByVal ModViewX As Double, ByVal ModViewY As Double, ByRef RefFace As Face2) As Double()

             

                    Dim ModViewLocation(2) As Double

                    If IsNothing(ModDoc) = False And IsNothing(RefFace) = False Then

                        Dim ModView As ModelView = ModDoc.IActiveView

                        If IsNothing(ModView) = False Then

                            Dim MathUtil As MathUtility = iSwApp.IGetMathUtility

                            Dim KnownDimMultiplier As Double = 1

                            Dim ModViewTransform As MathTransform = ModView.Transform

                            Dim KnownFaceCoord As Integer = KnownFaceCoordinate(RefFace)

                            Dim CompareVals(1, 2) As Double

                            'Dim LastVals(2) As Double

                            'Dim ThisVals(2) As Double

                            Dim Distances(1) As Double

                            Dim KnownVal As Double = 0

                            Dim ClosestPointOnFace As Object = Nothing

             

                            'get a point in the model that is projected from the X,Y Coordinates that are retrieved from MouseEvents

             

                            Dim ModelViewPoint As MathPoint = MathUtil.CreatePoint(New Double(2) {ModViewX, ModViewY, 0})

                            Dim ModelSpacePoint As MathPoint = ModelViewPoint.IMultiplyTransform(ModViewTransform.Inverse)

                              If IsNothing(ModelSpacePoint) = False Then

                                For i = 0 To 2

                                    CompareVals(0, i) = ModelSpacePoint.ArrayData(i)

                                Next

                            End If

                           'Get the known value on the face

                            ClosestPointOnFace = RefFace.GetClosestPointOn(ModelViewPoint.ArrayData(0), ModelViewPoint.ArrayData(1),                          ModelViewPoint.ArrayData(2))

                            KnownVal = ClosestPointOnFace(KnownFaceCoord)

             

                            'Increase the Z Value by 1 giving a difference between the previous point and this point, this gives us depth change per pixel.                 

                            ModelViewPoint = MathUtil.CreatePoint(New Double(2) {ModViewX, ModViewY, 1})

                            ModelSpacePoint = ModelViewPoint.IMultiplyTransform(ModViewTransform.Inverse)

                            If IsNothing(ModelSpacePoint) = False Then

                                For i = 0 To 2

                                    CompareVals(1, i) = ModelSpacePoint.ArrayData(i)

                                Next

                            End If

                            For i = 0 To 1

                                Distances(i) = KnownVal - CompareVals(i, KnownFaceCoord)

                            Next

                            Dim ChangePerPixel = Distances(0) - Distances(1)

                            Dim ModViewZ As Double = (Distances(0) / ChangePerPixel)

                            ModelViewPoint = MathUtil.CreatePoint(New Double(2) {ModViewX, ModViewY, ModViewZ})

                            ModelSpacePoint = ModelViewPoint.IMultiplyTransform(ModViewTransform.Inverse)

                            If IsNothing(ModelSpacePoint) = False Then

                                For i = 0 To 2

                                    ModViewLocation(i) = ModelSpacePoint.ArrayData(i)

                                Next

                            End If

                            Dim DistanceToFace As Double = Math.Abs(ModViewLocation(KnownFaceCoord)) - Math.Abs(KnownVal)

                            Debug.Print("Distance to Known Val on Face = " & DistanceToFace)

                            Select Case DistanceToFace

                                Case -0.00254 To 0.00254

                                    ClosestPointOnFace = RefFace.GetClosestPointOn(ModViewLocation(0), ModViewLocation(1), ModViewLocation(2))

                                    For i = 0 To 2

                                        ModViewLocation(i) = ClosestPointOnFace(i)

                                    Next

                                    Debug.Print("within .1 Inches")

                              End Select

                            End If

                    End If

                    Return ModViewLocation

                End Function

             

            Public Function KnownFaceCoordinate(ByVal RefFace As Face2) As Integer

                    Dim KnownCoord As Integer = -1

                    If IsNothing(RefFace) = False Then

                        Dim Facenorm() As Double = JEMFaces.FaceNormal(RefFace, True)

                        If IsNothing(Facenorm) = False Then

                            For i = LBound(Facenorm) To UBound(Facenorm)

                                If Facenorm(i) <> 0 Then

                                    If KnownCoord = -1 And Facenorm(i) <> 0 Then

                                        KnownCoord = i

                                    Else

                                        Debug.Print("there are 2 normals that are not 0 at KnownFaceCoordinate")

                                    End If

                                End If

                            Next

                        End If

                    End If

                    Return KnownCoord

                End Function

              • Re: Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify
                roberto gennari

                Hallo,

                I'm trying to annex the code to understand it better, but I do not understand what it refers to the line "JEMFaces":

                 

                Public Function KnownFaceCoordinate(ByVal RefFace As Face2) As Integer

                        Dim KnownCoord As Integer = -1

                        If IsNothing(RefFace) = False Then

                            Dim Facenorm() As Double = JEMFaces.FaceNormal(RefFace, True)

                            If IsNothing(Facenorm) = False Then

                                For i = LBound(Facenorm) To UBound(Facenorm)

                                    If Facenorm(i) <> 0 Then

                                        If KnownCoord = -1 And Facenorm(i) <> 0 Then

                                            KnownCoord = i

                                        Else

                                            Debug.Print("there are 2 normals that are not 0 at KnownFaceCoordinate")

                                        End If

                                    End If

                                Next

                            End If

                        End If

                        Return KnownCoord

                    End Function

                 

                The "RefFace" is the face reference of the sketch in the planar face, but I don't undestand what's  JEMFaces object.

                 

                Thanks

                 

                Roberto

                  • Re: Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify
                    Jacob Corder

                    JEMFaces is a class i have in my API Code. just Use RefFace.Normal or insert this function call and change JEMFaces.FaceNormal() to FaceNormal()

                     

                    Public Function FaceNormal(ByVal SelFace As Face2, Optional ByVal RndToTenPlaces As Boolean = True) As Double()

                            FaceNormal = Nothing

                            Dim FaceNorm() As Double = Nothing

                            If IsNothing(SelFace) = False Then

                                Dim FNorm As Object = SelFace.Normal

                                If IsNothing(FNorm) = False Then

                                    If UBound(FNorm) >= 2 Then

                                        ReDim FaceNorm(2)

                                        For i = 0 To 2

                                            FaceNorm(i) = FNorm(i)

                                        Next

                                        For i = 0 To 2

                                            If Math.Round(FaceNorm(i), 10) = 0 Then

                                                FaceNorm(i) = 0

                                            Else

                                                If RndToTenPlaces = True Then

                                                    FaceNorm(i) = Math.Round(CDbl(FaceNorm(i)), 10)

                                                Else

                                                    FaceNorm(i) = CDbl(FaceNorm(i))

                                                End If

                                            End If

                                        Next

                                    End If

                                End If

                            End If

                            Return FaceNorm

                        End Function

                     

                    This function just removes additional values that Solidworks passes. Solidworks works at 10 decimal places, but will often return much greater than 10. this function will trim those values. 

                      • Re: Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify
                        roberto gennari

                        Hallo Jacob,

                        i Tried the new code, but I have a probelm in the call

                         

                        KnownFaceCoord As Integer = FaceNormal(RefFace)

                         

                        My preconditions are a part open and with a edit 2D sketch, the RefFace is the face when the 2D sketch is.

                         

                         

                        this is my code, can you try it, please?

                         

                        In the Form code I have:

                        '

                         

                        Dim pSketch As Sketch

                        Dim MyFeature As Sketch

                         

                         

                        MyFeature = swModel.GetActiveSketch2

                         

                         

                         

                        pSketch = MyFeature.GetSpecificFeature2

                         

                        pEntity = pSketch.GetReferenceEntity(nEntType)

                         

                         

                        If nEntType = 2 Then 'se lo schizzo è appoggiato in una una faccia

                        Debug.Print("Face Selected!")

                         

                        Debug.Print("  Normal   = (" + Str(vNormal(0)) + "," + Str(vNormal(1)) + "," + Str(vNormal(2)) + ")")

                         

                        End If

                         

                         

                        In the MouseMoveNotify I have this code:

                         

                         

                        Public Function TheMouse_MouseMoveNotify(ByVal X As Long, ByVal Y As Long, ByVal WParam As Long) As Long

                        Debug.Print(X & "  " & Y)

                         

                        Debug.Print("wParam= " & WParam)

                         

                        Dim ModViewX As Double = CDbl(X)

                         

                        Dim ModViewY As Double = CDbl(Y)

                        '

                         

                        PreSelectionPoint(swModel, ModViewX, ModViewY, RefFace)

                        '

                         

                        End Function

                         

                         

                         

                        Function PreSelectionPoint(ByVal ModDoc As ModelDoc2, ByVal ModViewX As Double, ByVal ModViewY As Double, ByRef RefFace As Face2) As Double()

                         

                        Dim ModViewLocation(2) As Double


                        If IsNothing(ModDoc) = False And IsNothing(RefFace) = False Then


                        Dim ModView As ModelView = ModDoc.IActiveView

                         

                        If IsNothing(ModView) = False Then


                        Dim MathUtil As MathUtility = swApp.IGetMathUtility

                         

                        Dim KnownDimMultiplier As Double = 1

                         

                        Dim ModViewTransform As MathTransform = ModView.Transform

                         

                        Dim KnownFaceCoord As Integer = FaceNormal(RefFace)                          <---- HIRE A HAVE THE PROBLEM

                         

                        Dim CompareVals(1, 2) As Double


                        'Dim LastVals(2) As Double


                        'Dim ThisVals(2) As Double


                        Dim Distances(1) As Double


                        Dim KnownVal As Double = 0

                         

                        Dim ClosestPointOnFace As Object = Nothing

                         

                         

                         

                        ''''

                        ''''

                        ''''

                         

                         

                         

                        Return ModViewLocation

                         

                        End Function

                         

                         

                         

                         

                         

                        Public Function FaceNormal(ByVal SelFace As Face2, Optional ByVal RndToTenPlaces As Boolean = True) As Double()

                         

                         

                        '''' Like your exsample

                        ''''

                        ''''

                         

                        End Function

                         

                         

                        Thanks and have you a nice day

                         

                         

                          • Re: Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify
                            Jacob Corder

                            Add This Function

                            'This will only work on Front, Top, Left, Right, Back, and Bottom Faces. the return for face Normal must be in any order 0,0,1 or 0,0,-1.

                            otherwise the function is not set up to handle non Ortho Faces.

                             

                            Public Function KnownFaceCoordinate(ByVal RefFace As Face2) As Integer

                                    Dim KnownCoord As Integer = -1

                                    If IsNothing(RefFace) = False Then

                                        Dim Facenorm() As Double = FaceNormal(RefFace, True)

                                        If IsNothing(Facenorm) = False Then

                                            For i = LBound(Facenorm) To UBound(Facenorm)

                                                If Facenorm(i) <> 0 Then

                                                    If KnownCoord = -1 And Facenorm(i) <> 0 Then

                                                        KnownCoord = i

                                                    Else

                                                        Debug.Print("there are 2 normals that are not 0 at KnownFaceCoordinate")

                                                    End If

                                                End If

                                            Next

                                        End If

                                    End If

                                    Return KnownCoord

                                End Function

                              • Re: Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify
                                roberto gennari

                                Hallo,

                                I talk again in this thread because I wanted to implement the code also working on faces that havn't face Normal in any order 0,0,1 or 0,0,-1.

                                How should I proceed to do it that works on different normal faces ? Could someone help me in the code steps?

                                 

                                Thanks to every body

                                Roberto

                                • Re: Get XYZ coordinates for Preselected objects using DMouseEvents_MouseMoveNotify
                                  roberto gennari

                                  Hallo,

                                  I'm sorry, but after so many attempts have failed to find a solution to make this beautiful code on sloped faces (only planar).

                                  Someone would be able to help me, I'd be very grateful.

                                   

                                  Thanks to everibody

                                  Roberto

                                   

                                  Public Function KnownFaceCoordinate(ByVal RefFace As Face2) As Integer

                                          Dim KnownCoord As Integer = -1

                                          If IsNothing(RefFace) = False Then

                                              Dim Facenorm() As Double = FaceNormal(RefFace, True)

                                              If IsNothing(Facenorm) = False Then

                                                  For i = LBound(Facenorm) To UBound(Facenorm)

                                                      If Facenorm(i) <> 0 Then

                                                          If KnownCoord = -1 And Facenorm(i) <> 0 Then

                                                              KnownCoord = i

                                                          Else

                                                              Debug.Print("there are 2 normals that are not 0 at KnownFaceCoordinate")

                                                          End If

                                                      End If

                                                  Next

                                              End If

                                          End If

                                          Return KnownCoord

                                      End Function