Snap to nearest entity point (VIEWER)

Discuss and ask questions about CAD .NET library.

Moderators: SDS, support, admin

Post Reply
peter.hentrich
Posts: 2
Joined: 26 Jun 2008, 10:21

Snap to nearest entity point (VIEWER)

Post by peter.hentrich » 24 Sep 2008, 09:43

Scope:
"CAD Import .NET" VIEWER demo downloaded from http://www.cadsofttools.com/download/cadimportnet.zip
cadimport.dll version 6.3.2942.31648 or later

Background:
I struggled with getting the coordinates of a snap point for this old version of the viewer demo.
Here are my findings after I successfully implemented this functionality.

Known Issues:
- This code works but selects the nearest entity automatically. Hence, the entity will be dotted and selected

Purpose:
- Gets the snap points when hovering over an entity
- Calculates the distance between two snap points

Important functions:
Me.GetRealPointUsingImagePoint
CADImage.SnapRealPoint
CADImage.RefreshSnapTrace
CADImage.DrawSnapTrace
CADImage.SelectExt
PictureBox.Invalidate

Important properties:
CADImage.SelectionMode
CADImage.EnableSnap

Important Notes:
- Make sure you include Me.cadPictBox.Invalidate() in the cadPictBox_MouseMove() to constantly check for the nearest entity
- Set the CADImage.SelectionMode = CADImport.SelectionEntityMode.Enabled
- Set CADImage.EnableSnap = True

Please see the relevant code below:

Code: Select all

Public Class MainForm
 ...
    Public Shared FCADImage As CADImport.CADImage       ' the CAD drawing
    Dim blnSnapGet2ndPt As Boolean = False
    Dim dPt1, dPt2, dPt3, dPt4, dPt5, ePt1, ePt2 As CADImport.DPoint
 ...
End Class

  '-----------------------------------------------------------------------------------------------------
    ' Name:         cmdSnap_Click
    ' Purpose:      Clear snap point display and toggle enabling of entity selection
    ' In:           sender, e
    ' Out:          
    ' Ext Ref:      FCADImage.ClearSelectCollection, cadPictBox.Invalidate
    ' Usage: 
    ' VER  DATE      AUTH  DESC
    ' 0.0  24/09/08  PMH   Created 
    '-----------------------------------------------------------------------------------------------------

    '' pmh_20080625: enable snap feature
    Private Sub cmdSnap_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSnap.Click
        If (Not FCADImage Is Nothing) Then

            If sender.BackColor = Color.Navy Then
                sender.BackColor = Color.Green
                sender.text = "Turn Snap Off"
                FCADImage.SelectionMode = CADImport.SelectionEntityMode.Enabled
                lblSnapPtVal1.Text = ""
                lblSnapPtVal2.Text = ""
            Else
                sender.BackColor = Color.Navy
                sender.text = "Turn Snap On"
                FCADImage.SelectionMode = CADImport.SelectionEntityMode.Disabled
            End If

            FCADImage.ClearSelectCollection()
            cadPictBox.Invalidate()
        End If

    End Sub
    '-----------------------------------------------------------------------------------------------------
    ' Name:         cadPictBox_MouseMove
    ' Purpose:      As the user moves the mouse, select the nearest entity allowing snap points to be used.
    '               Display the current CAD mouse coords.
    ' In:           sender, e
    ' Out:          
    ' Ext Ref:      FCADImage.DrawSnapTrace, FCADImage.RefreshSnapTrace, 
    ' Usage: GetRealPointUsingImagePoint
    ' VER  DATE      AUTH   DESC
    ' 0.0  19/03/08  PH     Created 
    ' 1.0  19/09/08  PH     Used DrawSnapTrace and RefreshSnapTrace to draw snap rectangles
    ' 1.1  23/09/08  PH     Enable snap point selection points by calling Invalidate and SelectExt functs  
    '-----------------------------------------------------------------------------------------------------
    Public Sub cadPictBox_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles cadPictBox.MouseMove
        Me.cadPictBox.Focus()
        If (Not MainForm.FCADImage Is Nothing) Then

            ' run snap dynamic on-the-fly functionality
            If cmdSnap.BackColor = Color.Green Then
                ' reset pict box to allow selection of entity when hovering over with mouse
                Me.cadPictBox.Invalidate()

                ' simulate click to select entity
                Dim mod1 As CADImport.SelectionEntityMode = FCADImage.SelectionMode
                FCADImage.SelectionMode = CADImport.SelectionEntityMode.Enabled

                ' select the entity near the point
                Dim ent1 As New CADImport.CADEntity
                Try
                    ent1 = FCADImage.SelectExt(e.X, e.Y, True, True)
                Catch ex16 As Exception
                    ent1 = New CADImport.CADEntity
                End Try

                ' draw snap rectangles
                If (Me.cadPictBox.ClientRectangle.Contains(e.X, e.Y)) Then
                    Dim tmpRect As RectangleF = New RectangleF(-1, -3, 995, 608)
                    FCADImage.DrawSnapTrace(e.X, e.Y, Me.cadPictBox, tmpRect)
                Else
                    FCADImage.RefreshSnapTrace(Me.cadPictBox)
                End If
            End If

            ' display curr coords
            ePt1 = Me.GetRealPointUsingImagePoint(CType(e.X, Single), CType(e.Y, Single))
            lblCurrPosVal.Text = ePt1.X.ToString & ", " & ePt1.Y.ToString


            ' if mouse down, then store pos ??
            If (Me.det1 = True) Then
                Me.pos.X = (Me.pos.X - (Me.cX - e.X))
                Me.pos.Y = (Me.pos.Y - (Me.cY - e.Y))
                Me.cX = e.X
                Me.cY = e.Y
                Me.cadPictBox.Invalidate()
            End If
            Me.old_Pos = New PointF(CType(e.X, Single), CType(e.Y, Single))
            
        End If
    End Sub
    '-----------------------------------------------------------------------------------------------------
    ' Name:         CheckSnapError
    ' Purpose:      Calcs the percent error between snap point and real pt
    ' In:           dPtReal - real point
    '               dPtSnap - snap point
    ' Out:          -
    ' Ext Ref:
    ' Usage:        cadPictBox_Click
    ' VER  DATE  AUTH  DESC
    ' 0.0  24/09/08  PMH   Created 
    '-----------------------------------------------------------------------------------------------------
    Private Sub CheckSnapError(ByVal dPtReal As CADImport.DPoint, ByVal dPtSnap As CADImport.DPoint)
        Dim perc_diff_x, perc_diff_y As Double

        perc_diff_x = Math.Abs(dPtSnap.X - dPtReal.X) / Math.Abs(dPtReal.X)
        perc_diff_y = Math.Abs(dPtSnap.Y - dPtReal.Y) / Math.Abs(dPtReal.Y)

        If perc_diff_x > 0.1 Or perc_diff_y > 0.1 Then
            lblSnapStatusVal.Text = "Snap point not found." & vbCrLf & "x-coord error=" & Format(perc_diff_x, "0.00%" & vbCrLf & _
            "y-coord error=" & Format(perc_diff_y, "0.00%"))
        Else
            lblSnapStatusVal.Text = "SUCCESS!"
        End If
    End Sub
    '-----------------------------------------------------------------------------------------------------
    ' Name:         cadPictBox_Click
    ' Purpose:      If the user clicks on the drawing and snap is enabled then get the point properties
    '               Determine if user clicks on 2nd point, then calc the distance between point1 and point2
    ' In:           sender, e
    ' Out:          
    ' Ext Ref:      GetRealPointUsingImagePoint, FCADImage.SnapRealPoint, CheckSnapError
    ' Usage: 
    ' VER  DATE      AUTH  DESC
    ' 0.0  25/06/08  PMH   Created 
    '-----------------------------------------------------------------------------------------------------
    Private Sub cadPictBox_Click(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles cadPictBox.Click

        If FCADImage.EnableSnap = True Then

            ' get the first pt
            If blnSnapGet2ndPt = False Then
                'sender.tooltip = "a"

                ' get real point
                dPt1 = Me.GetRealPointUsingImagePoint(CType(e.X, Single), CType(e.Y, Single))
                lblRealPtVal1.Text = dPt1.X.ToString & ", " & dPt1.Y.ToString

                ' get snap point
                dPt2 = FCADImage.SnapRealPoint()
                lblSnapPtVal1.Text = dPt2.X.ToString & "," & dPt2.Y.ToString

                'check for valid snap point
                CheckSnapError(dPt1, dPt2)

                ' toggle selection of 2nd point now
                blnSnapGet2ndPt = True

            Else ' get the 2nd snap point

                ' toggle back to selection of first point
                blnSnapGet2ndPt = False

                ' get the 2nd point real coords
                dPt3 = Me.GetRealPointUsingImagePoint(CType(e.X, Single), CType(e.Y, Single))
                lblRealPtVal2.Text = dPt3.X.ToString & ", " & dPt3.Y.ToString

                ' get the 2nd point snap coords
                dPt4 = FCADImage.SnapRealPoint()
                lblSnapPtVal2.Text = dPt4.X.ToString & "," & dPt4.Y.ToString

                'check for valid snap point
                CheckSnapError(dPt3, dPt4)

                ' calc the dist between the two real points
                Dim dx, dy, dist As Double
                dx = dPt3.X - dPt1.X
                dy = dPt3.Y - dPt1.Y
                dist = Math.Sqrt(dx * dx + dy * dy)
                lblRealDistVal.Text = dist.ToString

                ' calc the dist between the two snap points
                dx = dPt4.X - dPt2.X
                dy = dPt4.Y - dPt2.Y
                dist = Math.Sqrt(dx * dx + dy * dy)
                lblSnapDistVal.Text = dist.ToString

            End If

        End If

    End Sub
Last edited by peter.hentrich on 14 Oct 2008, 05:43, edited 5 times in total.

support
Posts: 3272
Joined: 30 Mar 2005, 11:36
Contact:

Re: Snap to nearest entity point

Post by support » 26 Sep 2008, 15:42

Hello Peter!

Thank you very mush for the investigations!

Sergey.
Technical Support E-mail: support@cadsofttools.com
Chat support on Skype: cadsofttools.support

Post Reply