FOREACH

FOREACH

vishshreevT578L
Advocate Advocate
1,689 Views
12 Replies
Message 1 of 13

FOREACH

vishshreevT578L
Advocate
Advocate

(DEFUN C:EXTRPOINTS ()
(SETQ POLYENT (ENTGET (CAR (ENTSEL "\nSelect a polyline: "))))

 

CAN I MAKE A LIST OF ALL THE COORDINATES OF A POLYLINE USING "FOREACH" HERE, IF I CAN ....HOW?

Shreev
0 Likes
Accepted solutions (2)
1,690 Views
12 Replies
Replies (12)
Message 2 of 13

Kent1Cooper
Consultant
Consultant
Accepted solution

@vishshreevT578L wrote:

(DEFUN C:EXTRPOINTS ()
(SETQ POLYENT (ENTGET (CAR (ENTSEL "\nSelect a polyline: "))))

 

CAN I MAKE A LIST OF ALL THE COORDINATES OF A POLYLINE USING "FOREACH" HERE, IF I CAN ....HOW?


If you mean the vertices, you could, but if it's a lightweight Polyline, it's perhaps easier to do it by leaving out all entity data entries that don't start with a 10 [the vertices]:

(setq VertexList

  (mapcar 'cdr ; take the 10's off the beginning of each

    (vl-remove-if-not

      '(lambda (x) (= (car x) 10)); a vertex entry

      POLYENT

    ); vl-remove...

  ); mapcar

); setq

 

[If you really mean just the raw coordinates, not differentiated into point lists, check out the 'Coordinates VLA Property, which you can get from either a lightweight or a heavy Polyline.]

 

But yes, there is a way to do it with (foreach):

 

(foreach entry POLYENT

  (if (= (car entry) 10); it's a vertex entry

    (setq VertexList (cons (cdr entry) VertexList)); then -- add point list [without the 10] to collective list

  ); if

); foreach

 

Use (reverse) on the result if you need them in the Polyline's drawn order, or use (reverse) on POLYENT at the beginning so it will build the list the other way.

Kent Cooper, AIA
Message 3 of 13

vishshreevT578L
Advocate
Advocate
I WANTED TO THIS USING FOREACH FUNCTION BUT NOW I CAME TO KNOW I CANNOT..
THANKS SIR
Shreev
0 Likes
Message 4 of 13

devitg
Advisor
Advisor

Why you can not ??

 

 

 

0 Likes
Message 5 of 13

vishshreevT578L
Advocate
Advocate
Can you give an example
Shreev
0 Likes
Message 6 of 13

devitg
Advisor
Advisor
Accepted solution

See  solution by Kent Cooper

 

 

(setq polyent (entget(car(entsel ¨select the poly¨))))
(setq VertexList ())

(foreach entry POLYENT
(if (= (car entry) 10); it's a vertex entry
(setq VertexList (cons (cdr entry) VertexList)); then -- add point list [without the 10] to collective list
); if
); foreach

(setq VertexList (reverse VertexList))

 it return 

 

 

 

((-5323.34 21.1449) (-3529.54 2470.28) (-1255.43 2440.89) (2636.05 1902.08) (3371.21 -801.765) (3135.96 -2643.52) (-10.5496 -1898.98))

 

 

 

0 Likes
Message 7 of 13

devitg
Advisor
Advisor

Other sample using Foreach 

 

 

(DEFUN MASSOC  (KEY ENTDATA / X NLIST)
  (FOREACH X  ENTDATA
    (IF (EQ KEY (CAR X))
      (SETQ NLIST (CONS (CDR X) NLIST))
      ) ;_ end of if 
    ) ;_ end of foreach 
  (REVERSE NLIST)
  )

Whre key , shall be 10 , and entdata   (entget )enty))

 

 

Grab the books, they dont bite .

 

 

 

 

 

 

0 Likes
Message 8 of 13

john.uhden
Mentor
Mentor
Massoc is by Tony Tanzillo c. 1999.
I wonder which is faster, (vl-remove-if-not) or (massoc).

John F. Uhden

0 Likes
Message 9 of 13

devitg
Advisor
Advisor

Unknow author

(DEFUN MASSOC-VL (CODE ENTDATA) (MAPCAR 'CDR (VL-REMOVE-IF-NOT '(LAMBDA (X) (= CODE (CAR X))) ENTDATA)) )

Massoc-vl ,Is twice fast than  masso for a 336019  vertex lwpolyline , 

 

;;Massoc is by Tony Tanzillo c. 1999
(DEFUN MASSOC  (KEY ENTDATA / X NLIST)
  (FOREACH X  ENTDATA
    (IF (EQ KEY (CAR X))
      (SETQ NLIST (CONS (CDR X) NLIST))
      ) ;_ end of if 
    ) ;_ end of foreach 
  (REVERSE NLIST)
  )

For 5 repeat 

 

0.905 for massoc
0.453 for massoc-vl 

 

Find attached the DWG and the lisp 

 

 

 

0 Likes
Message 10 of 13

john.uhden
Mentor
Mentor
How about for 100,000 simpler polylines?

Could you also post your time test function?

John F. Uhden

0 Likes
Message 11 of 13

devitg
Advisor
Advisor

Unzip the attached , or 

 

;;************************************************************************************************************
;;Massoc is by Tony Tanzillo c. 1999
(DEFUN MASSOC  (KEY ENTDATA / X NLIST)
  (FOREACH X  ENTDATA
    (IF (EQ KEY (CAR X))
      (SETQ NLIST (CONS (CDR X) NLIST))
      ) ;_ end of if 
    ) ;_ end of foreach 
  (REVERSE NLIST)
  )

;;************************************************************************************************************
(DEFUN MASSOC-VL  (CODE ENTDATA)
  (MAPCAR 'CDR (VL-REMOVE-IF-NOT '(LAMBDA (X) (= CODE (CAR X))) ENTDATA))
  )

;;;(massoc-vl 5 elst) NOT KNOW THE AUTHOR , BUT IT IS NOT MINE 
(DEFUN MIL-INI  ()
  (SETQ INI@ (GETVAR "millisecs"))
  )

(DEFUN MIL-FIN  ()
  (SETQ FIN@ (GETVAR "millisecs"))
  (SETQ MIL-IN-FIN (/ (- FIN@ INI@) 1000.0))
  )



(setq ent-data(entget (car(entsel))))
(setq data-qty (LENGTH ent-data))

(defun c:mas ()

(setq n-list ())
(setq   cmdecho (getvar 'cmdecho))

(setvar 'cmdecho 0)
(MIL-INI)

(repeat 5

  (massoc 10 ent-data)

  )



  
(mil-fin)
(setvar 'userr1 MIL-IN-FIN)

)



(defun c:mas-vl ()

(setq n-list ())
(setq   cmdecho (getvar 'cmdecho))

(setvar 'cmdecho 0)
(MIL-INI)

(repeat 5

  (MASSOC-VL 10 ent-data)

  )



  
(mil-fin)
(setvar 'userr2 MIL-IN-FIN)

)


(getvar 'userr1 ) 
(getvar 'userr2 )
0 Likes
Message 12 of 13

john.uhden
Mentor
Mentor
Bummer. 2002 doesn't have "mllisecs."

John F. Uhden

0 Likes
Message 13 of 13

john.uhden
Mentor
Mentor

Here's a timer function I dug out of my stuff from 2001:

 

(defun timer (fun n / start stop)
  (setq start (getvar "date"))
  (repeat n (eval fun))
  (setq stop (getvar "date"))
  (princ (strcat "Elapsed time for " (itoa n) " iterations: " (rtos (* 86400.0 (- stop start)) 2 2) " secs.\n"))
  (eval fun)
)

So I tried it on 1 14± vertex LWPOLYLINE...

 

Command: (setq ent (entget (car (entsel))))

Select object: ((-1 . <Entity name: 40082d88>) (0 . "LWPOLYLINE") (330 . 
<Entity name: 40082cf8>) (5 . "31") (100 . "AcDbEntity") (67 . 0) (410 . 
"Model") (8 . "0") (100 . "AcDbPolyline") (90 . 14) (70 . 128) (43 . 0.0) (38 . 
0.0) (39 . 0.0) (10 4.97271 1.65594) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 
5.3741 2.68069) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 6.05794 2.63614) (40 . 
0.0) (41 . 0.0) (42 . 0.0) (10 6.3404 2.88861) (40 . 0.0) (41 . 0.0) (42 . 0.0) 
(10 6.80124 2.23515) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 7.36616 2.72525) (40 
. 0.0) (41 . 0.0) (42 . 0.0) (10 7.75268 1.80446) (40 . 0.0) (41 . 0.0) (42 . 
0.0) (10 8.24326 2.11634) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 8.78546 1.26347) 
(40 . 0.0) (41 . 0.0) (42 . 0.0) (10 9.145 1.49204) (40 . 0.0) (41 . 0.0) (42 . 
0.0) (10 9.50688 1.18069) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 10.1164 1.35891) 
(40 . 0.0) (41 . 0.0) (42 . 0.0) (10 10.3988 1.09158) (40 . 0.0) (41 . 0.0) (42 
. 0.0) (10 10.9786 1.2698) (40 . 0.0) (41 . 0.0) (42 . 0.0) (210 0.0 0.0 1.0))

Command: (timer '(massoc 10 ent) 100000)
Elapsed time for 100000 iterations: 12.97 secs.

Command: (timer '(massoc-vl 10 ent) 100000)
Elapsed time for 100000 iterations: 16.62 secs.

Don't consider the time values as absolute.  I am running ACAD 2002 vanilla on a 2010 Dell I-7 laptop with many problems, the worst of which is that it just turns itself off every 15 minutes or so, I think depending on the level of graphic activity.  Any clues?

John F. Uhden

0 Likes