Code:
#PBFORMS CREATED V1.50
'------------------------------------------------------------------------------
' The first line in this file is a PB/Forms metastatement.
' It should ALWAYS be the first line of the file. Other
' PB/Forms metastatements are placed at the beginning and
' end of "Named Blocks" of code that should be edited
' with PBForms only. Do not manually edit or delete these
' metastatements or PB/Forms will not be able to reread
' the file correctly. See the PB/Forms documentation for
' more information.
' Named blocks begin like this: #PBFORMS BEGIN ...
' Named blocks end like this: #PBFORMS END ...
' Other PB/Forms metastatements such as:
' #PBFORMS DECLARATIONS
' are used by PB/Forms to insert additional code.
' Feel free to make changes anywhere else in the file.
'------------------------------------------------------------------------------
#COMPILE EXE "G-Code to DXF"
#DIM ALL
'------------------------------------------------------------------------------
' ** Includes **
'------------------------------------------------------------------------------
#PBFORMS BEGIN INCLUDES
#IF NOT %DEF(%WINAPI)
#INCLUDE "WIN32API.INC"
#ENDIF
#PBFORMS END INCLUDES
'------------------------------------------------------------------------------
#INCLUDE "COMDLG32.INC"
#INCLUDE "C:\QVCS LIB\Workfile\PowerBasic\Common\URL\url.inc" ' Add Urls
'------------------------------------------------------------------------------
' ** Constants **
'------------------------------------------------------------------------------
#PBFORMS BEGIN CONSTANTS
%IDD_DIALOG1 = 101
%IDC_BUTTON1 = 1001
%IDC_BUTTON2 = 1002
%IDC_LABEL1 = 1003
%IDC_LABEL2 = 1004 '*
%IDC_LABEL3 = 1005
%IDC_LABEL4 = 1006
%IDC_BUTTON3 = 1007
%IDC_LABEL5 = 1008
#PBFORMS END CONSTANTS
'------------------------------------------------------------------------------
MACRO Pi = 3.141592653589793##
TYPE TypPoints
X AS SINGLE ' Center of first circle or first point of intersection
Y AS SINGLE
Z AS SINGLE
I AS SINGLE
J AS SINGLE
X1 AS SINGLE ' Center of first circle or first point of intersection
Y1 AS SINGLE
X2 AS SINGLE ' Point on diameter of circle or second point of intersection
Y2 AS SINGLE
R AS SINGLE ' Common Radius
Ang AS SINGLE ' Angle of Radius Point on Circomference.
END TYPE
GLOBAL TypOld AS TypPoints ' Hold Values of Geometry
DECLARE SUB CalcCenters( BYREF Centers AS TypPoints )
DECLARE SUB CalcAngle( BYREF tPoints AS TypPoints )
DECLARE SUB PARSEFILE( hWnd AS LONG,SMYSOURCEFILE AS STRING )
$ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
$DP = "#.0###" ' FORMAT OF XYZ - CODE
'------------------------------------------------------------------------------
' ** Declarations **
'------------------------------------------------------------------------------
DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
#PBFORMS DECLARATIONS
'------------------------------------------------------------------------------
DECLARE FUNCTION ExeName(Op AS LONG) AS STRING
'------------------------------------------------------------------------------
' ** Main Application Entry Point **
'------------------------------------------------------------------------------
FUNCTION PBMAIN()
ShowDIALOG1 %HWND_DESKTOP
END FUNCTION
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
' ** CallBacks **
'------------------------------------------------------------------------------
CALLBACK FUNCTION ShowDIALOG1Proc()
SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
' Initialization handler
CASE %WM_NCACTIVATE
STATIC hWndSaveFocus AS DWORD
IF ISFALSE CBWPARAM THEN
' Save control focus
hWndSaveFocus = GetFocus()
ELSEIF hWndSaveFocus THEN
' Restore control focus
SetFocus(hWndSaveFocus)
hWndSaveFocus = 0
END IF
CASE %WM_COMMAND
' Process control notifications
SELECT CASE AS LONG CBCTL
' /* Inserted by PB/Forms 10-11-2004 00:36:51
CASE %IDC_LABEL5
' */
' /* Inserted by PB/Forms 09-11-2004 15:16:59
CASE %IDC_BUTTON3
IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
DIALOG END CBHNDL 'Exit
END IF
' */
CASE %IDC_BUTTON1
IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
DIM InputFile AS STRING
Inputfile = "*.cnc;*.txt;*.dnc"
IF OpenFileDialog(0, _
"Open PowerBasic Source File", _
InputFile, _
CURDIR$, _
"CNC Files (*.cnc;*.txt;*.dnc)|*.cnc,*.txt,*.dnc", _
"cnc", _
%OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY) THEN
END IF
IF Inputfile = "*.cnc;*.txt;*.dnc" THEN Inputfile = "None"
CONTROL SET TEXT CBHNDL , %IDC_LABEL1, InputFile
END IF
CASE %IDC_BUTTON2
IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
CONTROL GET TEXT CBHNDL , %IDC_LABEL1 TO InputFile
IF Inputfile = "None" THEN EXIT FUNCTION
' Disable system menu's close item
MENU SET STATE GetSystemMenu(CBHNDL, 0), %SC_CLOSE, %MF_GRAYED
' Disable other controls
CONTROL DISABLE CBHNDL, %IDC_BUTTON1
CONTROL DISABLE CBHNDL, %IDC_BUTTON2
CONTROL DISABLE CBHNDL, %IDC_BUTTON3
PARSEFILE(CBHNDL,InputFile)
MSGBOX "Finished"
CONTROL ENABLE CBHNDL, %IDC_BUTTON1
CONTROL ENABLE CBHNDL, %IDC_BUTTON2
CONTROL ENABLE CBHNDL, %IDC_BUTTON3
END IF
CASE %IDC_LABEL1
CASE %IDC_LABEL3
CASE %IDC_LABEL4
END SELECT
END SELECT
END FUNCTION
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
' ** Dialogs **
'------------------------------------------------------------------------------
FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
LOCAL lRslt AS LONG
#PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
LOCAL hDlg AS DWORD
DIALOG NEW hParent, "G-Code to DXF", 73, 156, 274, 94, %WS_POPUP OR _
%WS_BORDER OR %WS_DLGFRAME OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR _
%DS_MODALFRAME OR %DS_CENTER OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
%DS_SETFONT, %WS_EX_WINDOWEDGE OR %WS_EX_CONTROLPARENT OR _
%WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
CONTROL ADD BUTTON, hDlg, %IDC_BUTTON1, "Import G-Code", 5, 10, 65, 15
CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "Convert to DXF", 5, 45, 65, 15
CONTROL ADD LABEL, hDlg, %IDC_LABEL1, "None", 10, 30, 255, 10
CONTROL ADD LABEL, hDlg, %IDC_LABEL3, "Line : ", 80, 50, 25, 10
CONTROL ADD LABEL, hDlg, %IDC_LABEL4, "", 110, 50, 155, 10
CONTROL ADD BUTTON, hDlg, %IDC_BUTTON3, "Exit", 205, 70, 50, 15
#PBFORMS END DIALOG
InitUrlCtrl ' INI for URL's
CONTROL ADD "PBURL32", hDlg, 106, "By Wayne Hill;mailto:[email protected]", _
10, 70, 80, 14, %WS_VISIBLE OR %WS_CHILD
DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
#PBFORMS BEGIN CLEANUP %IDD_DIALOG1
#PBFORMS END CLEANUP
FUNCTION = lRslt
END FUNCTION
'------------------------------------------------------------------------------
FUNCTION ExeName(Op AS LONG) AS STRING
LOCAL TmpAsciiz AS ASCIIZ * 256
GetModuleFileName GetModuleHandle(BYVAL 0&), TmpAsciiz, 255
IF Op = 1 THEN
FUNCTION = TmpAsciiz
ELSE
LOCAL i AS LONG, j AS LONG
DO
j = INSTR(i + 1, TmpAsciiz, "\")
IF j = 0 THEN EXIT DO ELSE i = j
LOOP
IF Op = 2 THEN FUNCTION = LEFT$(TmpAsciiz$, i) ELSE _ ' With final \
FUNCTION = MID$(TmpAsciiz$, i + 1)
END IF
END FUNCTION
SUB PARSEFILE( hWnd AS LONG,SMYSOURCEFILE AS STRING )
DIM TypNew AS TypPoints
DIM MyResults AS TypPoints
DIM lNumberOfLines AS LONG
DIM lNumberofAlpha_Codes AS LONG
DIM lLineCount AS LONG
DIM lAlphaCode_Count AS LONG
DIM lAlphaCodePos AS LONG
DIM lAlphaValue AS LONG
DIM sLine AS STRING
DIM sLineParsed AS STRING
DIM sAlphaCode AS STRING
DIM sGMode AS STRING
LOCAL ArcCenterX AS SINGLE
LOCAL ArcCenterY AS SINGLE
LOCAL SideXs AS SINGLE
LOCAL SideYs AS SINGLE
LOCAL Radius AS SINGLE
LOCAL AngleEnd AS SINGLE
LOCAL AngleStart AS SINGLE
LOCAL LineCounter AS LONG
LineCounter = 48 ' Start at 48 for AutoCAD Line Number Entity
DIM HFILE AS LONG
DIM sBUFFER AS STRING
DIM sTemp AS STRING
TypOld = TypNew ' Clear
HFILE = FREEFILE
OPEN SMYSOURCEFILE FOR INPUT AS HFILE
WHILE ISFALSE EOF( HFILE )
LINE INPUT# HFILE, sTemp
CONTROL SET TEXT hWnd , %IDC_LABEL4, sTemp
sBUFFER = sBUFFER + sTemp + $CRLF
DIALOG DOEVENTS
WEND
CLOSE HFILE
HFILE = FREEFILE
OPEN "Data.DXF" FOR OUTPUT AS HFILE 'DXF FILE.
PRINT #HFILE, " 0"
PRINT #HFILE, "SECTION"
PRINT #HFILE, " 2"
PRINT #HFILE, "ENTITIES"
lNumberOfLines = TALLY( sBUFFER, $CRLF )
FOR lLineCount = 1 TO lNumberOfLines
DIALOG DOEVENTS
CONTROL SET TEXT hWnd , %IDC_LABEL4, STR$(lLineCount)
sLine = PARSE$( sBUFFER, $CRLF, lLineCount )
sLine = PARSE$( sLine, "(", 1 ) ' REMOVE COMMENT LINE
sLine = UCASE$( sLine ) ' CHANGE TO UPPERCASE
sLine = REMOVE$( sLine, " " ) ' REMOVE SPACES
lNumberofAlpha_Codes = TALLY( sLine, ANY $ALPHA )
FOR lAlphaCode_Count = 1 TO lNumberofAlpha_Codes
lAlphaCodePos = INSTR( - 1, sLine, ANY $ALPHA ) ' FIND THE RIGHTMOST LETTER
sLineParsed = MID$( sLine, lAlphaCodePos, LEN( sLine )) ' GET THE CODE AND THE VALUE
sLine = EXTRACT$( sLine, sLineParsed ) ' REMOVE IT FROM THE MAIN STRING
sAlphaCode = LEFT$( sLineParsed, 1 )
SELECT CASE sAlphaCode
CASE "X"
TypNew.X = VAL( FORMAT$( VAL( PARSE$( sLineParsed, ANY $ALPHA, 2 )), $DP ))
CASE "Y"
TypNew.Y = VAL( FORMAT$( VAL( PARSE$( sLineParsed, ANY $ALPHA, 2 )), $DP ))
CASE "Z"
TypNew.Z = VAL( FORMAT$( VAL( PARSE$( sLineParsed, ANY $ALPHA, 2 )), $DP ))
CASE "R"
TypNew.R = VAL( FORMAT$( VAL( PARSE$( sLineParsed, ANY $ALPHA, 2 )), $DP ))
CASE "I"
TypNew.I = VAL( FORMAT$( VAL( PARSE$( sLineParsed, ANY $ALPHA, 2 )), $DP ))
CASE "J"
TypNew.J = VAL( FORMAT$( VAL( PARSE$( sLineParsed, ANY $ALPHA, 2 )), $DP ))
CASE "G"
lAlphaValue = VAL( PARSE$( sLineParsed, ANY $ALPHA, 2 ))
SELECT CASE lAlphaValue
CASE 0
sGMode = "0" ' Group 1 G Codes
CASE 1
sGMode = "1"
CASE 2
sGMode = "2"
CASE 3
sGMode = "3"
END SELECT
END SELECT
NEXT ALPHACODECOUNT
IF sGMode = "3" OR sGMode = "2" THEN
IF TypNew.R <> 0 THEN
MyResults.X1 = TypOld.X
MyResults.Y1 = TypOld.Y
MyResults.X2 = TypNew.X
MyResults.Y2 = TypNew.Y
Radius = TypNew.R
MyResults.R = ABS( Radius )
CalcCenters MyResults
IF ( sGMode = "2" ) AND ( SGN( Radius ) = - 1 ) THEN
ArcCenterX = MyResults.X2
ArcCenterY = MyResults.Y2
END IF
IF ( sGMode = "2" ) AND ( SGN( Radius ) = 1 ) THEN
ArcCenterX = MyResults.X1
ArcCenterY = MyResults.Y1
END IF
IF ( sGMode = "3" ) AND ( SGN( Radius ) = - 1 ) THEN
ArcCenterX = MyResults.X1
ArcCenterY = MyResults.Y1
END IF
IF ( sGMode = "3" ) AND ( SGN( Radius ) = 1 ) THEN
ArcCenterX = MyResults.X2
ArcCenterY = MyResults.Y2
END IF
GOTO PlotPoint
END IF
IF ( TypNew.I <> 0 ) OR ( TypNew.J <> 0 ) THEN
ArcCenterX = TypOld.X + TypNew.I
ArcCenterY = TypOld.Y + TypNew.J
END IF
PlotPoint:
MyResults.X1 = ArcCenterX ' Center of Circle
MyResults.Y1 = ArcCenterY
MyResults.X2 = TypOld.X ' Point in Radius
MyResults.Y2 = TypOld.Y
CalcAngle MyResults
AngleStart = MyResults.ang
MyResults.X1 = ArcCenterX ' Center of Circle
MyResults.Y1 = ArcCenterY
MyResults.X2 = TypNew.X ' Point in Radius
MyResults.Y2 = TypNew.Y
CalcAngle MyResults
AngleEnd = MyResults.ang
TypNew.R = MyResults.r
IF sGMode = "3" THEN
IF AngleStart = > AngleEnd THEN AngleEnd = AngleEnd + 360
END IF
IF sGMode = "2" THEN
IF AngleStart < = AngleEnd THEN AngleEnd = AngleEnd - 360
END IF
PRINT #HFILE, " 0"
PRINT #HFILE, "ARC"
PRINT #HFILE, " 5"
PRINT #HFILE, HEX$( LineCounter )
PRINT #HFILE, "100"
PRINT #HFILE, "AcDbEntity"
PRINT #HFILE, " 8"
PRINT #HFILE, "0"
PRINT #HFILE, " 62" ' Line Color Format
PRINT #HFILE, " " + STR$( 45 ) ' Line Color
PRINT #HFILE, "100"
PRINT #HFILE, "AcDbCircle"
PRINT #HFILE, " 10"
PRINT #HFILE, ArcCenterX
PRINT #HFILE, " 20"
PRINT #HFILE, ArcCenterY
PRINT #HFILE, " 30"
PRINT #HFILE, TypOld.Z
PRINT #HFILE, " 40"
PRINT #HFILE, TypNew.R
PRINT #HFILE, "100"
PRINT #HFILE, "AcDbArc"
PRINT #HFILE, " 50"
IF sGMode = "2" THEN PRINT #HFILE, AngleEnd
IF sGMode = "3" THEN PRINT #HFILE, AngleStart
PRINT #HFILE, " 51"
IF sGMode = "2" THEN PRINT #HFILE, AngleStart
IF sGMode = "3" THEN PRINT #HFILE, AngleEnd
INCR LineCounter
TypOld.X = TypNew.X
TypOld.Y = TypNew.Y
TypOld.Z = TypNew.Z
TypNew.R=0
TypNew.I=0
TypNew.J=0
ITERATE FOR
END IF
PRINT #HFILE, " 0"
PRINT #HFILE, "LINE"
PRINT #HFILE, " 5"
PRINT #HFILE, HEX$( LineCounter )
PRINT #HFILE, "100"
PRINT #HFILE, "AcDbEntity"
PRINT #HFILE, " 8"
PRINT #HFILE, "0"
PRINT #HFILE, " 62" ' Line Color Format
PRINT #HFILE, " " + STR$( 45 ) ' Line Color
PRINT #HFILE, "100"
PRINT #HFILE, "AcDbLine"
PRINT #HFILE, " 10"
PRINT #HFILE, TypOld.X
PRINT #HFILE, " 20"
PRINT #HFILE, TypOld.Y
PRINT #HFILE, " 30"
PRINT #HFILE, TypOld.Z
PRINT #HFILE, " 11"
PRINT #HFILE, TypNew.X
PRINT #HFILE, " 21"
PRINT #HFILE, TypNew.Y
PRINT #HFILE, " 31"
PRINT #HFILE, TypNew.Z
INCR LineCounter
TypOld.X = TypNew.X
TypOld.Y = TypNew.Y
TypOld.Z = TypNew.Z
NEXT lLineCount
PRINT #HFILE, " 0"
PRINT #HFILE, "ENDSEC"
PRINT #HFILE, " 0"
PRINT #HFILE, "EOF"
CLOSE HFILE
END SUB
' ================================================================================
'
' CalcCenters calculates the centers of two circles given their points
' of intersection and common radius.
'
' ================================================================================
'
SUB CalcCenters( BYREF Centers AS TypPoints )
LOCAL c AS TypPoints ' Points of intersection
LOCAL H1!, H2!, K1!, K2!, X!, Y!, D!, D2!
c = Centers
X = c.x1 - c.x2
Y = c.y1 - c.y2
D2 = X^2 + Y^2
D = SQR( D2 )
IF 2 * c.r < D, THEN ' values of H and K are not real
c.x1 = 0! ' and there is no solution.
c.x2 = 0!
c.y1 = 0!
c.y2 = 0!
c.r = 0!
Centers = c
EXIT SUB
END IF
K1 = ( Y + X * SQR( 4 * c.r^2 / D^2 - 1 )) / 2
K2 = ( Y - X * SQR( 4 * c.r^2 / D^2 - 1 )) / 2
H1 = ( X^2 - Y * ( 2 * K1 - Y )) / ( 2 * X )
H2 = ( X^2 - Y * ( 2 * K2 - Y )) / ( 2 * X )
h1 = H1 + c.x2
h2 = H2 + c.x2
k1 = K1 + c.y2
k2 = K2 + c.y2
c.x1 = h1
c.x2 = h2
c.y1 = k1
c.y2 = k2
c.r = c.r
Centers = c
END SUB
'
' ================================================================================
'
' CalcAngle calculates the angle of radius given
' center of circle to point on circomeference.
'
' ================================================================================
'
SUB CalcAngle( BYREF tPoints AS TypPoints )
LOCAL c AS TypPoints ' Radius and Angle of circle
LOCAL X!, Y!, R!
c = tPoints
X = c.x2 - c.x1
Y = c.y2 - c.y1
c.r = SQR( X^2 + Y^2 ) ' Hyp of angle (Radius)
IF c.r = 0 THEN ' values are not real
c.x1 = 0! ' and there is no solution.
c.x2 = 0!
c.y1 = 0!
c.y2 = 0!
c.r = 0!
c.ang = 0!
tPoints = c
EXIT SUB
END IF
' Find quadrant of angle in radians
IF x = 0 THEN
IF y > = 0 THEN
c.ang = PI / 2
ELSE ' Y
c.ang = 3 * PI / 2
END IF 'Y
ELSE ' X
c.ang = ATN( Y / X )
END IF 'X
IF X < 0 THEN
c.ang = c.ang + PI
ELSE
IF ( x > 0 ) AND ( y < 0 ) THEN
c.ang = c.ang + 2 * PI
END IF
END IF
c.ang = c.ang * 180 / pi ' Convert to Decimal Degrees
tPoints = c
END SUB