Hey Everyone,
I'm working on a research degree and have ran into some problems. I'm a newb to autocad lisp code and I'm looking for a little assitance. I've gone through the vlips tutorials that ship with autocad, however they have only provided a crude understanding of the vlips environment and I really don't have the time to fully learn vlisp code. Additionally, I have searched all over user forums trying to find a solution to this problem.
My problem:
I have a collection of data (X Y Rotation) separated by spaces in a txt format. Next I'm wanting to import this data into autocad utilizing Import XYZ. However, instead of the XYZ, I basically want to do XYRotation. This will allow me to insert a basic block and rotate it to the proper Rotational value.
Questions:
- Is it very difficult to make this change?
- How do I go about making this change?
Code:
;;;--- IMPORTXYZ.lsp - Import coords from a file. ;;; ;;; ;;;--- Copyright 2005 by JefferyPSanders.com ;;; All rights reserved. ;;; ;;;--- Revisions ;;; ;;; 3/2/06 - Solved problem with blank Excel lines.
(defun C:IMPORTXYZ()
(setq exitMessage "\n IMPORTXYZ.lsp Complete. \n ")
;;;--- Function to put the values of a range of cells in a list ;;; ;;;--- Parameters: ;;; ;;; stRow = starting row number as integer ;;; stCol = starting column number as integer ;;; LsRow = last row number as integer ;;; LsCol = last column number as integer
(defun GetRangeCells(stRow stCol LsRow LsCol / cellList copyCol)
;;;--- Make a copy of the first column (setq copyCol stCol)
;;;--- Build an empty list to hold the cell's addresses and values (setq cellList(list))
;;;--- Save the column (setq tmpCol stCol)
;;;--- Set up a cell counter and a flag (setq cellCnt 0 oldstRow nil)
;;;--- Loop while we are inside the range (while ( (length dataList) 0) (progn
;;;--- Remove all rows with nil in them (setq tmpData(list)) (foreach a dataList (if(not(member nil a)) (setq tmpData(append tmpData(list a))) ) ) (setq dataList tmpData tmpData nil)
;;;--- Check to see if we have more data in the list than x y & z, a note perhaps (if(> (length (car dataList)) 3) (setq moreData T) )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;;--- Use the first 500 items to find the longest integer to display ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;--- Set the longest integer variable up (setq longestInt 0)
;;;--- Set up a counter so we don't exceed 500 values [ time issue ] (setq cnt 0)
;;;--- While we do not exceed the 500th item... (while(< cnt 500)
;;;--- And there are items left in the dataList (if(> (length dataList) cnt) (progn
;;;--- Get the nth item from the dataList (setq a(nth cnt dataList))
(if moreData (progn ;;;--- Get the integer part of the x y and z coords as a string (setq x(itoa(fix(nth 1 a)))) (setq y(itoa(fix(nth 2 a)))) (setq z(itoa(fix(nth 3 a)))) ) (progn ;;;--- Get the integer part of the x y and z coords as a string (setq x(itoa(fix(nth 0 a)))) (setq y(itoa(fix(nth 1 a)))) (setq z(itoa(fix(nth 2 a)))) ) )
;;;--- Check the "integer" string lengths for a longer one (if(> (strlen x) longestInt)(setq longestInt(strlen x))) (if(> (strlen y) longestInt)(setq longestInt(strlen y))) (if(> (strlen z) longestInt)(setq longestInt(strlen z))) ) )
;;;--- Increment the counter to get the next item (setq cnt(+ cnt 1)) )
;;;--- Set up a string to display as a header in the dialog list box (setq x "X" y "Y" z "Z") (while(< (strlen x) (+ longestInt 2 decPlaces))(setq x(strcat x " "))) (while(< (strlen y) (+ longestInt 2 decPlaces))(setq y(strcat y " "))) (while(< (strlen z) (+ longestInt 2 decPlaces))(setq z(strcat z " ")))
;;;--- Add the header to the dialog list box (start_list "xyz") (add_list (strcat X Y Z)) (end_list)
;;;--- Start the routine to add the first 50 xyz coords to the list box (start_list "xyz" 2)
;;;--- Set up a counter to make sure we do not display more than 50 [time issue] (setq cnt 0)
;;;--- While there are items to display and we have not exceeded 50 (while(and (> (length dataList) cnt)(< cnt 50))
;;;--- Get the nth item from the data list (setq a(nth cnt dataList))
(if moreData (progn (setq x(rtos (nth 1 a) 2 decPlaces)) (setq y(rtos (nth 2 a) 2 decPlaces)) (setq z(rtos (nth 3 a) 2 decPlaces)) ) (progn ;;;--- Get the xy and z coords as strings (setq x(rtos (nth 0 a) 2 decPlaces)) (setq y(rtos (nth 1 a) 2 decPlaces)) (setq z(rtos (nth 2 a) 2 decPlaces)) ) )
;;;--- Pad the xy & z if necessary for display purposes (while(< (strlen x) (+ longestInt 1 decPlaces))(setq x(strcat " " x))) (while(< (strlen y) (+ longestInt 1 decPlaces))(setq y(strcat " " y))) (while(< (strlen z) (+ longestInt 1 decPlaces))(setq z(strcat " " z)))
;;;--- Add the xyz coord to the dialog list box (add_list (strcat x " " y " " z))
;;;--- Increment the counter to get the next point (setq cnt(+ cnt 1)) )
;;;--- Finalize the list box (end_list)
;;;--- Enable tiles (mode_tile "dnode" 0) (mode_tile "dcirc" 0) (mode_tile "dline" 0) (mode_tile "dbloc" 0) (mode_tile "dattr" 0) (mode_tile "dnote" 0) (mode_tile "layers" 0) (mode_tile "blocks" 1) (mode_tile "getblkname" 1) (mode_tile "cdia" 1) (mode_tile "xtag" 1) (mode_tile "ytag" 1) (mode_tile "ztag" 1) ) ) (princ " Done.") )
;;;---------------------------------------------------------------------------------------
;;;--- Functions to enable and disable tiles as necessary
(defun modeDnode() (mode_tile "layers" 0) (mode_tile "cdia" 1) (mode_tile "blocks" 1) (mode_tile "getblkname" 1) (mode_tile "xtag" 1) (mode_tile "ytag" 1) (mode_tile "ztag" 1) )
(defun modeDcirc() (mode_tile "layers" 0) (mode_tile "cdia" 0) (mode_tile "blocks" 1) (mode_tile "getblkname" 1) (mode_tile "xtag" 1) (mode_tile "ytag" 1) (mode_tile "ztag" 1) )
(defun modeDline() (mode_tile "layers" 0) (mode_tile "cdia" 1) (mode_tile "blocks" 1) (mode_tile "getblkname" 1) (mode_tile "xtag" 1) (mode_tile "ytag" 1) (mode_tile "ztag" 1) )
(defun modeDbloc() (mode_tile "layers" 1) (mode_tile "cdia" 1) (mode_tile "blocks" 0) (mode_tile "getblkname" 0) (mode_tile "xtag" 1) (mode_tile "ytag" 1) (mode_tile "ztag" 1) )
(defun modeDattr() (mode_tile "layers" 1) (mode_tile "cdia" 1) (mode_tile "blocks" 0) (mode_tile "getblkname" 0) (mode_tile "xtag" 0) (mode_tile "ytag" 0) (mode_tile "ztag" 0) )
(defun modeDnote() (mode_tile "layers" 0) (mode_tile "cdia" 1) (mode_tile "blocks" 1) (mode_tile "getblkname" 1) (mode_tile "xtag" 1) (mode_tile "ytag" 1) (mode_tile "ztag" 1) )
;;;---------------------------------------------------------------------------------------
;;;--- Function to update the progress bar ;;; ;;; Parameter a = percentage complete [ a = 0.50 = Fifty percent complete ]
(defun upDateProgressBar(a) (setq width (dimx_tile "progbar") height (dimy_tile "progbar")) (start_image "progbar") (fill_image 0 0 width height 250) ;background color = 250 = black (setq x (fix(* width a))) ;fill the used area [ width * percentage used ] (fill_image 0 0 x height 1) ;foreground color = 1 = red (end_image) )
;;;---------------------------------------------------------------------------------------
(defun getAttTags(en)
;;;--- Set up a list to hold the tag names (setq attList(list))
;;;--- Get the DXF group codes of the entity (setq enlist(entget en))
;;;--- Get the name of the block (setq blkName(cdr(assoc 2 enlist)))
;;;--- Check to see if the block's attribute flag is there (if(cdr(assoc 66 enlist)) (progn
;;;--- Get the entity name (setq en(entnext en))
;;;--- Get the entity dxf group codes (setq enlist(entget en))
;;;--- Get the type of block (setq blkType (cdr(assoc 0 enlist)))
;;;--- If group 66 then there are attributes nested inside this block (setq group66(cdr(assoc 66 enlist)))
;;;--- Loop while the type is an attribute or a nested attribute exist (while(or (= blkType "ATTRIB")(= group66 1))
;;;--- Get the block type (setq blkType (cdr(assoc 0 enlist)))
;;;--- Get the block name (setq entName (cdr(assoc 2 enlist)))
;;;--- Check to see if this is the first attribute (if(= blkType "ATTRIB") (progn
;;;--- Get the attribute tag (setq attTag(cdr(assoc 2 enlist)))
;;;--- Add the tag to the tag list (setq attList(append attList (list attTag)))
) ) ;;;--- Get the next sub-entity or nested entity as you will (setq en(entnext en))
;;;--- Get the dxf group codes of the next sub-entity (setq enlist(entget en))
;;;--- Get the block type of the next sub-entity (setq blkType (cdr(assoc 0 enlist)))
;;;--- See if the dxf group code 66 exist. if so, there are more nested attributes (setq group66(cdr(assoc 66 enlist)))
) ) )
;;;--- Return the tag list attList )
;;;---------------------------------------------------------------------------------------
;;;--- Function to get a block name from file and it's attribute tags
(defun getBlkFromFile()
;;;--- If the user selects a block... (if(setq blk(getfiled "Select Block" "" "dwg" 16)) (progn
;;;--- See if the block name already exist (if(not(member (vl-filename-base blk) blkList)) (progn
;;;--- Add the block name to the block list (setq blkList(append blkList (list blk)))
;;;--- Add the block name to the block popup list in the dialog box (start_list "blocks") (mapcar 'add_list blkList) (end_list)
;;;--- Set the currently selected block to the item added (set_tile "blocks" (itoa (- (length blkList) 1)))
);;;--- Else the block exist so, select it in the dialog block popup list (progn
(setq a(member (vl-filename-base blk) blkList)) (setq blkIndex (- (length blkList) (length a))) (set_tile "blocks" (itoa blkIndex))
) ) ) ) )
;;;---------------------------------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; 888 888 888 8888888 8888 888 ;;; ;;; 8888 8888 88888 888 88888 888 ;;; ;;; 88888 88888 888 888 888 888888 888 ;;; ;;; 888888 888888 888 888 888 888 888888 ;;; ;;; 888 88888 888 88888888888 888 888 88888 ;;; ;;; 888 888 888 888 888 8888888 888 8888 ;;; ;;; ;;; ;;; ;;; ;;; 888 888888888 888888888 ;;; ;;; 88888 888 888 888 888 ;;; ;;; 888 888 888 888 888 888 ;;; ;;; 888 888 888888888 888888888 ;;; ;;; 88888888888 888 888 ;;; ;;; 888 888 888 888 ;;; ;;; ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;--- Turn the command echo off (setvar "cmdecho" 0)
;;;--- Set the main list to nil (setq dataList (list))
;;;--- Build match patterns for delimiter checking (setq pat1(list 4 "*`,*`,*")) (setq pat2(list 3 "*`,*")) (setq pat3(list 2 "* * *")) (setq pat4(list 1 "* *")) (setq pat5(list 6 "*\t*\t*")) (setq pat6(list 5 "*\t*"))
;;;--- Turn the note flag to off [ no notes attached to data ] (setq moreData nil)
;;;--- Build a list to hold the layer names (setq layerList(list))
;;;--- Get the first layer name in the drawing (if(setq layN(tblnext "LAYER" T)) (progn
;;;--- Save the layer name in the list (setq layerList(append layerList (list (cdr (assoc 2 layN)))))
;;;--- Loop through all of the remaining layers (while(setq layN(tblnext "LAYER")) (setq layerList(append layerList (list (cdr(assoc 2 layN))))) ) ) )
;;;--- Build a list to hold the block names (setq blkList(list))
;;;--- Get the first block name in the drawing (if(setq blkN(tblnext "BLOCK" T)) (progn
;;;--- Save the block name in the list (setq blkList(append blkList (list (cdr (assoc 2 blkN)))))
;;;--- Loop through all of the remaining blocks (while(setq blkN(tblnext "BLOCK")) (setq blkList(append blkList (list (cdr(assoc 2 blkN))))) ) ) )
;;;--- Build a list of valid decimal places (setq decList(list "0" "1" "2" "3" "4" "5" "6" "7" "8"))
;;;--- Load the dialog box file (setq dcl_id (load_dialog "IMPORTXYZ.dcl"))
;;;--- See if the definition is already loaded (if (not (new_dialog "IMPORTXYZ" dcl_id)) (progn (alert "The IMPORTXYZ.dcl file could not be found.") (exit) ) )
;;;--- Add the layer list to the dialog box drop down list (start_list "layers") (mapcar 'add_list layerList) (end_list)
;;;--- Add the block list to the dialog box drop down list (start_list "blocks") (mapcar 'add_list blkList) (end_list)
;;;--- Add the decimal places list to the dialog box drop down list (start_list "decplaces") (mapcar 'add_list decList) (end_list)
(setq width (dimx_tile "progbar") height (dimy_tile "progbar")) (start_image "progbar") (fill_image 0 0 width height 250) ;250 = AutoCAD black (end_image)
;;;--- Disable tiles (mode_tile "dnode" 1) (mode_tile "dcirc" 1) (mode_tile "dline" 1) (mode_tile "dbloc" 1) (mode_tile "dattr" 1) (mode_tile "dnote" 1) (mode_tile "layers" 1) (mode_tile "cdia" 1) (mode_tile "blocks" 1) (mode_tile "getblkname" 1) (mode_tile "xtag" 1) (mode_tile "ytag" 1) (mode_tile "ztag" 1)
;;;--- If an action event occurs, do this function (action_tile "help" "(xyz_help)") (action_tile "dnode" "(modeDnode)") (action_tile "dcirc" "(modeDcirc)") (action_tile "dline" "(modeDline)") (action_tile "dbloc" "(modeDbloc)") (action_tile "dattr" "(modeDattr)") (action_tile "dnote" "(modeDnote)") (action_tile "getblkname" "(getBlkFromFile)") (action_tile "getfile" "(getFileName)") (action_tile "getdata" "(getData)") (action_tile "decplaces" "(displayXYZ)") (action_tile "cancel" "(setq ddiag 1)(done_dialog)") (action_tile "accept" "(setq ddiag 2)(saveVars)(done_dialog)")
;;;--- Display the dialog box (start_dialog)
;;;--- Unload the dialog box from memory, it is not need any longer (unload_dialog dcl_id)
;;;--- If the cancel button was pressed - display message (if (= ddiag 1) (setq exitMessage "\n IMPORTXYZ Cancelled. \n ") )
;;;--- If the "Create" button was pressed (if (= ddiag 2) (progn
;;;--- Save the current snap settings (setq oldSnap(getvar "osmode"))
;;;--- Turn the osnaps off (setvar "osmode" 0)
;;;--- Save the current layer (setq oldLay(getvar "clayer"))
;;;--- Set the layer (setvar "clayer" layerName)
;;;--- Run a series of test based on the item chosen in the dialog box (cond
;;;--- If the user wanted to draw a node on each point ( (= dNode "1") (progn
;;;--- Display a message on the command line (princ "\n Placing nodes...")
;;;--- Cycle through each point in the list (foreach a dataList
;;;--- If the point is prefixed with a note (if moreData
;;;--- Draw a node on the point (command "point" (cdr a))
;;;--- Else, draw a node on the point (command "point" a) ) )
(princ " Done.")
) )
;;;--- If the user wanted to draw a circle on each point ( (= dCirc "1") (progn
;;;--- Display a message on the command line (princ "\n Placing circles...")
;;;--- Cycle through each point in the list
(foreach a dataList
;;;--- If the point is prefixed with a note (if moreData
;;;--- Draw a node on the point (command "circle" (cdr a) "D" cDia)
;;;--- Else, draw the circle (command "circle" a "D" cDia) ) )
(princ " Done.")
) )
;;;--- If the user wanted to draw lines to each point ( (= dLine "1") (progn
;;;--- Display a message on the command line (princ "\n Drawing lines...")
;;;--- If the point is prefixed with a note (if moreData
;;;--- Start the line command on the first point (command "line" (cdr(car dataList)))
;;;--- Else, start the line command on the first point like this (command "line" (car dataList)) )
;;;--- Cycle through each point in the list except the first [ already used ] (foreach a (cdr dataList)
;;;--- If the point is prefixed with a note (if moreData
;;;--- Send the point to the line command (command (cdr a))
;;;--- Else, send the point to the line command like this (command a) ) )
;;;--- End the line command (command)
(princ " Done.")
) )
;;;--- If the user wanted to insert a block on each point ( (= dBloc "1") (progn
;;;--- Set up a counter to keep the user informed (setq cnt 0)
;;;--- Cycle through each point in the list (foreach a dataList
;;;--- Increment the counter (setq cnt(+ cnt 1))
;;;--- Inform the user of progress (princ "\n Inserting block # ")(princ cnt)
;;;--- If the point is prefixed with a note (if moreData
;;;--- Insert the block using the dimscale and rotation of zero (command "-insert" blkName (cdr a) (getvar "dimscale") "" 0)
;;;--- Else, insert the block using the dimscale and rotation of zero (command "-insert" blkName a (getvar "dimscale") "" 0) ) )
(princ "\n Finished inserting ")(princ cnt)(princ " blocks.")
) )
;;;--- If the user wanted to insert a block on each point and upate attributes in the block ( (= dAttr "1") (progn
;;;--- Save the current state of the attribute request system variable (setq oldAttReq(getvar "attreq"))
;;;--- Turn the attribute request off (setvar "attreq" 0)
;;;--- Set up a counter to keep the user informed (setq cnt 0)
;;;--- Cycle through each point in the list (foreach a dataList
;;;--- Increment the counter (setq cnt(+ cnt 1))
;;;--- Inform the user of progress (princ "\n Inserting block # ")(princ cnt)
;;;--- If the point is prefixed with a note (if moreData
;;;--- Insert the block using the dimscale and rotation of zero (command "-insert" blkName (cdr a) (getvar "dimscale") "" 0)
;;;--- Else, insert the block using the dimscale and rotation of zero (command "-insert" blkName a (getvar "dimscale") "" 0) )
;;;--- Get the entity name of the last inserted block (setq en(entlast))
;;;--- If the point is prefixed with a note (if moreData (progn
;;;--- Replace the x y and z tags of the attribute (repAttVal en xTag (rtos(nth 1 a))) (repAttVal en yTag (rtos(nth 2 a))) (repAttVal en zTag (rtos(nth 3 a))) )
;;;--- Else, (progn
;;;--- Replace the x y and z tags of the attribute (repAttVal en xTag (rtos(nth 0 a))) (repAttVal en yTag (rtos(nth 1 a))) (repAttVal en zTag (rtos(nth 2 a))) ) ) )
(princ "\n Finished inserting ")(princ cnt)(princ " blocks and updating their attributes.")
;;;--- Reset the attribute request to previous state (setvar "attreq" oldAttReq) ) )
;;;--- If the user wanted to insert a note from excel on each point ( (= dNote "1") (progn
;;;--- Display a message on the command line (princ "\n Placing notes...")
;;;--- Cycle through each point in the list (foreach a dataList
;;;--- If the point is prefixed with a note (if moreData
;;;--- Draw a node on the point (command "dim1" "Lea" (cdr a) (polar (cdr a) (* pi
0.25) (* 4.0(getvar "textsize"))) "" (car a));;;--- Else, draw a node on the point (command "point" a) ) )
(princ " Done.") ) )
);;;--- Reset the osnaps to previous state (setvar "osmode" oldSnap)
;;;--- Reset the current layer to previous state (setvar "clayer" oldLay) ) )
;;;--- Reset the command echo (setvar "cmdecho" 1)
;;;--- Display a message (princ exitMessage)
;;;--- Suppress the last echo for a clean exit (princ) )