Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations waross on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Trace Tree network

Status
Not open for further replies.

elev8848

Civil/Environmental
Jul 24, 2004
42
0
0
US
I use tree network (representing sewer pipes) drawn with line entities in AutoCAD 2006.

With my recursive autolisp routine, I click one line. Then, anything connected from upstream is selected automatically. But, AutoLISP is slow (5 minutes for 100 branches) and is limiting in size.

Has anyone got VBA to do this? or any other method? I am tired of searching.
 
Replies continue below

Recommended for you

Maybe the problem is with the routine's logic, not Lisp vs VBA. How does the routine find the "attched" line - look in a small area at the next endpoint, or look through every entity in the drawing? 5 minutes does seem very slow for this.
 
Thanks, CarlB!

Logic I used:
Find starting point P1 of the any first line user selects.
Using selection set filter, select all other lines whose end point is same as P1.
Do this recursively for all the new lines thus discovered.

You end up selecting with the whole tree upstream of that First Line selected by the user.

I will post my inefficient code later (when I get home).
 
Code:
;COMMAND: SALMON1
;DEVELOPED 2:43 AM 7/1/2007
;
;PURPOSE: TO SELECT ALL UPSTREAM LINES
;COPYRIGHT 
;COMMERCIAL USE NOT ALLOWED WITHOUT PERMISSION
;Email: elev8848@lycos.com

;SHORT INSTRUCTION:
;DRAW NETWORK WITH LINE ENTITIES IN AUTOCAD
;TYPE SALMON1 AT COMMAND LINE
;FOLLOW INSTRUCTION THEREAFTER
;GOOD LUCK

(defun c:salmon1( / ss1 ssGrip)
	;find up stream lines
	(setq ss1 (ssget s:)) ;starting size
	(setq ssGrip ss1) ;INITIALIZE

	(up ss1) ;MAIN RECURSIVE FUNCTION

	(sssetfirst ssGrip ssGrip) ;grip and select
	(alert (strcat (rtos (sslength ssGrip) 2 0) " OBJECTS SELECTED."))	;REPORT SIZE

)

 

(defun stPt(en1 / )
	;RETURNS starting point of a line
	(cdr (assoc 10 (entget en1)))
)

(defun endPt(en2 / )
	;RETURNS ending point of a line
	(cdr (assoc 11 (entget en2)))
)


;RETURN SS OF UPSTREAM LINES
(defun UP(ssIn / elist ename upNod filt ename len ct ssOut ssTmp ssOut2)
	(if ssIn
	
	(progn
	(setq ssOUt (ssadd))
	(setq ct 0)
	(setq len (sslength ssIn))
	 (while (< ct len)
		(progn
		(setq ssTmp nil) ;initialize
		(setq ename (ssname ssIn ct))
		(setq upNod (stPt ename))
		(setq filt (list (cons 11 upnod)))
		(setq ssTmp (ssget "x" filt))

		;add these items to ssout
		(ssjoin ssout ssTmp)
		(ssjoin ssGrip ssTmp) ;adding to ss to be gripped

		(up ssout) ;RECURSION

		(setq ct (+ ct 1))
		(princ)
		
		)
	 )
	)
	(princ)
	)
	
	(setq ssOut2 ssOut)
	

)
 

;Union of two ss
(defun SSjoin(sel1 sel2 / ct len)
(if (/= sel2 nil)
(progn
	(setq ct 0)
	;set counter to zero

	(repeat (sslength sel2)
	;get the number of items in selection set 2
	;and loop that number of times

	(ssadd (ssname sel2 ct) sel1)
	;get the name of the entity from selection set 2
	;by using the counter index number and add it to
	;selection set 1

	(setq ct (1+ ct))
	;increment the counter by 1
	
	);end repeat
	(princ)
))
;else
(princ)

)
 
elev8848,
Well, here is an iterative version of your salmon1 program. I have never had so much trouble with what should have been a fairly simple algorithm. From the user's point of view, I think it works the same way your program does and it is considerably faster. I hope this works for you.

; etree.lsp - traverse tree, show grips and select all connected line segments
; (end point to start point) upstream from the selection point.
; 8-03-07 working etree development code.

(defun etree_error (msg)
(princ)
)

(defun rcl (inlist loca / cn)
(setq cn (+ loca 1))
(setq post nil)
(while (/= cn (length inlist))
(setq post (cons (nth cn inlist) post))
(setq cn (+ cn 1))
)
(setq cn 0)
(setq ante nil)
(while (< cn loca)
(setq ante (cons (nth cn inlist) ante))
(setq cn (+ cn 1))
)
(setq inlist (append post ante))
(setq inlist (reverse inlist))
)

(defun accbranch (/ altname sublista sublistb)
(setq n 0)
(while (/= n (length en_points))
(if (equal srcpt (nth n en_points) thresh)
(progn
(setq altname (nth n namelist))
(if altname
(progn
(setq altlist (cons altname altlist))
(setq sublista (member (nth (+ n 1) namelist) namelist))
(setq namelist (reverse namelist))
(setq sublistb (member (nth (- (length namelist) n) namelist) namelist))
(setq sublistb (reverse sublistb))
(setq namelist (append sublistb sublista))
(setq en_points (rcl en_points n))
(setq n (- n 1))
)
)
)
)
(setq n (+ n 1))
)
(princ)
)

(defun c:etree (/ ckvar firstline sl_ed sl_en sl_ln flname sname
ssl gripset branchlist c cbranch brec )

(setq syserror *error*)
(setq *error* etree_error)
(setq thresh 0.00005) ; USER ADJUSTMENT - set general linear tolerance here
(setq griplist nil)
(setq branchlist nil)
(setq altlist nil)
(setq namelist nil)
(setq en_points nil)
(setq sl_ln nil)

; GET FIRST LINE AND NAME
(setq firstline (ssget)) ; select root entity
(setq flname (ssname firstline 0))

; GET SET OF ALL LINES
(setq ssl (ssget "X" '((0 . "LINE"))))
(if ssl (setq sl_ln (sslength ssl))
)

(if sl_ln
(progn
(setq ssl (ssdel flname ssl))
(setq altlist (cons flname altlist))
(setq sl_ln (- sl_ln 1))
(setq n 0)
(repeat sl_ln
(setq sname (ssname ssl n))
(setq namelist (cons sname namelist))
(setq n (+ n 1))
)
(setq namelist (cons flname namelist))
(setq ssl (ssadd flname ssl))

; EXTRACT END POINTS TO LIST
(setq sl_ln (+ sl_ln 1))
(setq n 0)
(if ssl ; not nil
(repeat sl_ln
(setq sl_en (ssname ssl n))
(setq sl_ed (entget sl_en))
(setq en_points (cons (cdr (assoc 11 sl_ed)) en_points))
(setq n (+ n 1))
)
)

(setq cbranch (car altlist))
(setq brec (entget cbranch))
(setq srcpt (cdr (assoc 10 brec)))

; MAIN LOOP

(while altlist ; is not empty (nil)
(accbranch)
(setq branchlist (cons (car altlist) branchlist))
(setq cbranch (car altlist))
(setq brec (entget cbranch))
(setq srcpt (cdr (assoc 10 brec)))
(setq altlist (cdr altlist))
)

) ; end progn
) ; end if (sl_ln)

(setq gripset (ssadd))
(foreach ckvar branchlist
(setq gripset (ssadd ckvar gripset))
)
(sssetfirst gripset gripset) ; grip and select
(setq ssl nil)
(setq firstline nil)
(setq gripset nil)
(setq *error* syserror)
(princ)
) ; end etree main




 
CADMILES:
Wow, that is much much faster. I knew there was somebody out there taking the challenge. Thanks a lot for sharing. I am not a programmer at all; was just trying to make my work easier. Did it take quite an effort? I spent many nights.

 
elev8848,
For someone who is not programmer, you have written an elegant program. It is a good example of how recursion can pack a lot of processing into a few lines of code. Unfortunately, elegance doesn't always mean fast execution. Iterative programs usually outperform the recursive ones, but take more code. Because the loops in an iterative program are explicit, they are usually easier to understand. Nevertheless, I had a hell of a time with my program. I had to re-write it three times. I hope my experience doesn't discourage anyone else from programming in Autolisp. When you write your own CAD tools, you can save a huge amount of time and effort in your CAD work. I have my intellectual limitations, but I am persistent, and I am very happy with my collection of custom built tools. Keep on programming!
 
Status
Not open for further replies.
Back
Top