Author Topic: Strange Behaviour upon calling a Function  (Read 1035 times)

0 Members and 1 Guest are viewing this topic.

S.Langhammer

  • Guest
Strange Behaviour upon calling a Function
« on: January 29, 2013, 02:39:23 AM »
Greetings,
I'm currently working on a Lisp script that's supposed to read all the information from entities within the model space of BricsCAD and write it to a file.
With a lot of help from tutorials and very kind helpers in different forums i came pretty far, but now I've reached the point of cleaning up my code and a certain function I call in the script, which is pretty essential began to behave strange.

It's the function to get the information i want from an insert:
When copy it to a test environment, which only calls this one get info function it works clean: takes the list of entities checks every single entity in the list, if its an insert and if it is the function reads out things like Insertion Point, layer, handle, list of sub-entities and so on. The idea of it is, that it doesn't write the list of subentities to  the file directly but to call all the get info functions (including the get insert function) so it can read down level by level.

Now in the actual script i don't call every single get info function but a function that calls them all one after another, passing on an input list.

The general algorithm Looks about like this:

- make a list of all entities within the model space  (modSpList)
- call (getInfo modSpList)
- inform the user that the script is finished via command line

- end

The getInfo algorithm (assuming we take modSpList as input):

- inform the user that the script beginns to read lines via command line
- call (getLineData modSpList)
- inform the user that the script finished to read lines via command line

- inform the user that the script beginns to read arcs via command line
- call (getArcData modSpList)
- inform the user that the script finished to read arcs via command line

[walk through all types of entities that way]

- inform the user that the script beginns to read inserts via command line
- call (getInsertData modSpList)
- inform the user that the script finished to read inserts via command line

- end

And finally the getInsert algorithm (assuming we take modSpList as input):

- check through all entities in the input list (this case modSpList)
- only handle entities that are inserts
- read out all necessary Information (name, handle, insertion point and so on)
- write those to a file
- create a list of all existing sub-entities (lets call it subEntList)
- call (getInfo subEntList)

- end

See it SHOULD do a clean recursive call but all i get in the generated file is a lot of empty space (line Feeds).
Did I make a misstake in the algorithm from not knowing Lisp to well yet or does it look functioning and the error is within the code?

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Strange Behaviour upon calling a Function
« Reply #1 on: January 29, 2013, 03:07:31 AM »
Could you post your code? What exactly are you attempting? There could be various reasons why something might work in one file, but not another. The most obvious one would be using non-localized variables - but by no means is this an exclusive reason.

Do you want to group all the data of each entity into lists of entity types? If so your method seems a bit inefficient, since you're looping through the entire model for each entity type. Perhaps just loop though it once and add to the relevant list depending on the current entity's type.

Edit: Example
Code - Auto/Visual Lisp: [Select]
  1. (defun GroupEntities (/ ss n data Result found)
  2.   (if (setq ss (ssget "_X" '((410 . "Model"))))
  3.     (repeat (setq n (sslength ss))
  4.       (setq data (entget (ssname ss (setq n (1- n)))))
  5.       (if (setq found (assoc (cdr (assoc 0 data)) Result))
  6.         (setq Result (subst (reverse (cons data (reverse found))) found Result))
  7.         (setq Result (cons (list (cdr (assoc 0 data)) data) Result)))))
  8.   Result)

To list it to the text screen by entity type:
Code: [Select]
(mapcar 'print (GroupEntities))
« Last Edit: January 29, 2013, 03:16:24 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

S.Langhammer

  • Guest
Re: Strange Behaviour upon calling a Function
« Reply #2 on: January 29, 2013, 03:33:03 AM »
Ok sure

Main Function:

Code - Auto/Visual Lisp: [Select]
  1. (defun C:C2F()                                                         
  2.         (princ "CAD 2 File aufgerufen\n")
  3.         (setq spcr ",")                 ;;; sets the seperator char
  4.         (getMSpList)                    ;;; calls for the list of entities in the model space
  5.         (getinfo mSpList)                       ;;; calls for the get Information function
  6.         (princ "!!!DXF-Daten exportiert!!!\n")
  7.         (princ)                               ;;; unterdrückt das Kommandozeilenecho
  8. )
  9.  

get information summary:

Code - Auto/Visual Lisp: [Select]
  1. (defun getInfo(checkList  / )  
  2.        
  3.         (princ "getInfo aufgerufen\n")
  4.        
  5.         (princ "Punkte Begin\n")
  6.         (getPoiData checkList)
  7.         (princ "Punkte ausgelesen\n")
  8.        
  9.         (princ "Linien Begin\n")
  10.         (getLinData checkList)
  11.         (princ "Linien ausgelesen\n")
  12.        
  13.         (princ "XLinien Begin\n")
  14.         (getXliData checkList)
  15.         (princ "XLinien ausgelesen\n")
  16.        
  17.         (princ "MLinien Begin\n")
  18.         (getMliData checkList)
  19.         (princ "MLinien ausgelesen\n")
  20.        
  21.         (princ "Lightweight Polylinien Begin\n")
  22.         (getLwpData checkList)
  23.         (princ "Lightweight Polylinien ausgelesen\n")
  24.        
  25.         (princ "Bögen Begin\n")
  26.         (getArcData checkList)
  27.         (princ "Bögen ausgelesen\n")
  28.        
  29.         (princ "Ellipsen Begin\n")
  30.         (getELLData checkList)
  31.         (princ "Ellipsen ausgelesen\n")
  32.        
  33.         (princ "Kreise Begin\n")
  34.         (getCirData checkList)
  35.         (princ "Kreise ausgelesen\n")
  36.        
  37.         (princ "Texte Begin\n")
  38.         (getTxtData checkList)
  39.         (princ "Texte ausgelesen\n")
  40.        
  41.         (princ "Inserts Begin\n")
  42.         (getInsData checkList)
  43.         (princ "Inserts ausgelesen\n")
  44.        
  45.         (princ)
  46. )
  47. ;;;
  48.  

the insert data:

Code - Auto/Visual Lisp: [Select]
  1. (defun getInsData( inputList /  en enlist hdrStr dataList entName entPoint entX entY entZ entTyp entLay entRot dStr entHan step)
  2.         (princ "getInsData aufgerufen\n")
  3.         (setq dataList(list))                                                                                                                                                                   ;;; ausgabeliste leer angelegt
  4.         (foreach step inputList
  5.                 (progn
  6.                         (princ "getInsData -> foreach aufgerufen\n")
  7.                         (if(= (cdr(assoc 0 step)) "INSERT")
  8.                                 (progn
  9.                                         (princ "getInsData -> foeach -> if aufgerufen\n")
  10.  
  11.                                         ;;;(setq entTyp(cdr(assoc 0 enlist)))                                                                                                   ;;; Entitätentyp läuft noch nicht richtig??? Umgangen, wird statisch eingefügt (siehe build a data string)
  12.  
  13.                                         (setq en(cdr(assoc -1 step)))   ;;; entity name
  14.                                         (princ "\n") (princ en) (princ "\n")
  15.                                         (setq enlist(entget en))          ;;; dxf groupcode
  16.                                         (princ "\n") (princ enlist) (princ "\n")
  17.    
  18.                                         (setq entName(cdr(assoc 2 enlist)))     ;;; Blockname
  19.                                         (princ "\n") (princ entName) (princ "\n")
  20.                                         (setq entHan(cdr(assoc 5 enlist)))         ;;; Handle
  21.                                         (princ "\n") (princ entHan) (princ "\n")
  22.                                         (setq entPoint(cdr(assoc 10 enlist)))   ;;; Insertionpoint
  23.                                         (princ "\n") (princ entPoi) (princ "\n")
  24.                                         (setq entX (rtos (car   entPoint) 2 4)) ;;; X to string
  25.                                         (princ "\n") (princ entX) (princ "\n")
  26.                                         (setq entY (rtos (cadr  entPoint) 2 4)) ;;; Y to string
  27.                                         (princ "\n") (princ entY) (princ "\n")
  28.                                         (setq entZ (rtos (caddr entPoint) 2 4)) ;;; Z to string
  29.                                         (princ "\n") (princ entZ) (princ "\n")
  30.                                         (setq entLay(cdr(assoc 8 enlist)))      ;;; Layer
  31.                                         (if(assoc 50 enlist)                    ;;; Rotation
  32.                                                 (setq entRot(angtos(cdr(assoc 50 enlist))0 4))
  33.                                                 (setq entRot "0.0000")
  34.                                         )
  35.                                         (princ "\n") (princ entRot) (princ "\n")
  36.                                         ;(setq subList (append (Block_EnameListNested (cdr (assoc 2 enlist))) enlist ) )        ;;; make the sub-entity list
  37.                                         ;(princ "\n") (princ subList) (princ "\n")
  38.                                        
  39.                                         (setq dStr "")
  40.                                         (setq dStr (strcat dStr "INSERT" spcr))
  41.                                         (setq dStr (strcat dStr entHan spcr))
  42.                                         (setq dStr (strcat dStr entLay spcr))
  43.                                         (setq dStr (strcat dStr entName spcr))
  44.                                         (setq dStr (strcat dStr entX spcr entY spcr entZ spcr))
  45.                                         (setq dStr (strcat dStr entRot spcr))                           ;;; make a data string
  46.                                         (setq dataList(append dataList(list (strcat "\n" dStr))))               ;;; to list
  47.                                         ;(setq dataList(append dataList(list subList))) ;;; add it to the list
  48.                                        
  49.                                         ;(filewrite)
  50.                                        
  51.                                         (setq subList (append (Block_EnameListNested (cdr (assoc 2 enlist))) enlist ) ) ;;; make the sub-entity list
  52.                                         (princ "\n") (princ subList) (princ "\n")
  53.                                         (getinfo subList) ;;;
  54.                
  55.                                         (setq dataList(append dataList(list (strcat "\nEnd of '" entHan "' \n"))))              ;;; mark the end of the insert
  56.                                 )       ;;; ende if-progn
  57.                         )       ;;; ende if
  58.                 )       ;;; ende foreach-progn
  59.         )       ;;; ende foreach
  60.         (filewrite dataList)
  61.         (princ)
  62. )       ;;; ende getInsData
  63.  

get the list of sub-entities (received that as it is from another Forum):

Code - Auto/Visual Lisp: [Select]
  1. (defun Block_EnameListNested (blockName / ename ret) ; Return value: List of enames of block nested entities from Block Definition
  2.         (princ "Block_EnameListNested aufgerufen\n")
  3.   (setq ename (tblobjname "block" blockName)
  4.         ret   (entget ename)
  5.         )
  6.    (if ename
  7.      
  8.        (while (setq ename (entnext ename))
  9.          (setq ret (append ret (entget ename) ))
  10.        )
  11.      
  12.    )
  13.  )
  14. ;;;
  15.  

And just in case the file write:

Code - Auto/Visual Lisp: [Select]
  1. (defun fileWrite( inlist / a)
  2.         (princ "fileWrite aufgerufen\n")
  3.     ;;;--- Open the file to write
  4.         (if(setq fil(open "C:/temp/entitytext.txt" "a"))
  5.                 (progn
  6.                         (foreach a inlist(princ a fil))
  7.                        
  8.                 )
  9.                 (alert "Error - Could not open File. \nMake sure the file is not opened by another application.")
  10.         )
  11.         (princ "\n" fil)
  12.         (close fil)
  13. )
  14. ;;;
  15.  

Sorry if this looks like a total hackjob to you. Its my second week of learning and using Lisp. All so I excuse if my English is pretty bad sometimes, I guess you can see where I'm from.

snddd2000

  • Guest
Re: Strange Behaviour upon calling a Function
« Reply #3 on: January 29, 2013, 07:51:11 PM »
need function getMSpList and var mSpList

S.Langhammer

  • Guest
Re: Strange Behaviour upon calling a Function
« Reply #4 on: January 30, 2013, 01:56:34 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun getMSpList (/ en enlist eset cntr)
  2.         (princ "getMSpList aufgerufen \n")
  3.        
  4.         (setq mSpList(list))
  5.         (setq eset (ssget "X"))
  6.         (if (/= eset nil)
  7.                 (progn
  8.                         (setq cntr 0)
  9.                         (setq en (ssname eset cntr))
  10.                         (setq enlist(entget en))
  11.  
  12.                         (while (< cntr (sslength eset) )
  13.                                 (setq enlist(entget en))
  14.                                 (if (/= (entnext en) nil)
  15.                                         (progn
  16.                                                 (setq en (entnext en))
  17.                                                 (setq mSpList(append mSpList(list enlist)))
  18.                                         )
  19.                                 )
  20.                                 (setq cntr (+ cntr 1))
  21.                         )
  22.                 )
  23.                 (princ "!!!KEINE ENTITÄTEN IN DER ZEICHNUNG!!!\n") ; eng: !!!no entities in the drawing!!!
  24.         )
  25.         mSpList
  26. )
  27.  

mSpList contains the list of all entities within the drawing. The thing now is, that I had to change how getInsData works. I've took it out of getInfo. Now its supposed to get its Information NOT from the blocks possible within the drawing BUT from all blocks contained within the file. Yet I'm not entirely sure how I can grab a list of all Inserts/Blocks from the block table. I first thought this function would help:

Code - Auto/Visual Lisp: [Select]
  1. (defun blockEntityList(/ f t1)
  2.         (princ "blockEntityList aufgerufen \n")
  3.         (setq blkEntList(list))
  4.  
  5.         (setq f 1) ;set pointer
  6.  
  7.         (while ;start while loop
  8.           (setq t1 (tblnext "block" f)) ;get the next block
  9.           (setq f nil) ;reset pointer
  10.           (setq b (cdr (assoc -2 t1))) ;get the inserts/blocks name
  11.             (if (/= b nil) ;if entity name is not equal to nil
  12.                (setq blkEntList (append blkEntList (list b))) ;Add the blocks entity name to the list
  13.             );if
  14.         );while
  15.         blkEntList
  16. )
  17.  

It's pretty much based on a code example I found on afralisp, Into the Database Page III to be exact.  But for some reason it doesn't  give me the entity names of blocks/inserts in my test example, but the names of the first entity contained within the block (at least it looks like that to me). I must admit, that i don't completely understand the tblnext function yet. But I'm working on that issue.

Edit: I'll better open a new thread or my currnent problem to keep the topics seperated.
« Last Edit: January 30, 2013, 03:05:35 AM by S.Langhammer »