Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
*Expert Elite*
hmsilva
Posts: 2,648
Registered: ‎12-17-2004
Message 11 of 54 (326 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 01:50 AM in reply to: l.l.oldescholtenhuis
Ok, understood.
I'm in the middle of a project, later, I'll see what I can do...
One more question, all lines always have the same z, it is possible to have different z's

Henrique
Contributor
l.l.oldescholtenhuis
Posts: 16
Registered: ‎05-03-2011
Message 12 of 54 (325 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 01:56 AM in reply to: hmsilva

Hi Henrique, 

 

I don't expect you do to that, but of course it would be great! I'll just check out the forum later. Have to do some stuff as well :-)

 

Lines on all drawings have the same z-coordinate (x,y,0). Currently, practitioners are not using any 3D-features at all. 

 

 

Best

Léon

*Expert Elite*
hmsilva
Posts: 2,648
Registered: ‎12-17-2004
Message 13 of 54 (312 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 04:37 AM in reply to: l.l.oldescholtenhuis

Léon,
the following code is just a demo, and aims to demonstrate a possible way to achieve what you need...
At the beginning of the code, there are two lists, the first "layrl" contains the layer names, and the second "elevl" contains the respective elevations, you need to fill those lists with your layer names [in uppercase], and the elevations, remember that to the first element from "layrl" will correspond the first element from "layrl"  to the second, the other second, and so on...

 

(vl-load-com)
(defun c:test (/ cir diam1 elev elevl ent filter hnd itm lay layrl num ss);; ensure that the number of elements on both lists are equal...
  (setq	layrl '("WATER" "GAS");; list with the layer names
	elevl '(-3.0 -2.5);; list with the elevation
  );; setq
  (if (= (length layrl) (length elevl));; tests if the number of elements in both lists is equal
    (progn
      (if (= diam nil)
	(setq diam 0.25);; change the 0.25 to the diameter you use most
      );; if
      (setq
	diam1
	 (getreal
	   (strcat "\Enter the tube diameter < " (rtos diam 2 4) " >: ")
	 )
      )
      (if (= diam1 nil)
	(setq diam1 diam)
	(setq diam diam1)
      );; if
      (setq filter "")
      (foreach x layrl
	(setq filter (strcat filter (vl-princ-to-string x) ","))
      );; foreach
      (setq filter (vl-string-right-trim "," filter))
      (prompt "\nSelect the sweep paths: ")
      (if (setq	ss
		 (ssget
		   (list '(0 . "LINE,*POLYLINE,3dpoly") (cons 8 (strcat filter)))
		 )
	  )
	(progn
	  (setq	itm 0
		num (sslength ss)
	  )
	  (while (< itm num)
	    (setq hnd  (ssname ss itm)
		  ent  (entget hnd)
		  lay  (strcase (cdr (assoc 8 ent)))
		  elev (nth (vl-position lay layrl) elevl)
	    )
	    (setvar "clayer" lay)
	    (entmakex (list (cons 0 "Circle")
			    (cons 10 '(0.0 0.0 0.0))
			    (cons 40 (/ diam 2))
		      )
	    )
	    (setq cir (entlast))
	    (command "sweep" cir "" hnd)
	    (vl-cmdf "._move" "_L" "" "0,0,0" (strcat "0,0," (rtos (+ elev (/ diam 2)) 2 2)))
	    (setq itm (1+ itm))
	  );; while
	);; progn
      );; if
    );; progn  
    (prompt "\nLists don't have same elements number!!!")
  );; if
  (princ)
);; test

EDIT: add "strcase"  

hope that helps
Henrique

Contributor
l.l.oldescholtenhuis
Posts: 16
Registered: ‎05-03-2011
Message 14 of 54 (306 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 05:29 AM in reply to: l.l.oldescholtenhuis
Hi Henrique,

It looks great! Thanks a lot. Unfortunately, I cannot try it out this week anymore. I will get back to you next Monday!
Have a great weekend!

Best,
L?on
Universiteit Twente |Faculty of Engineering Technology
Dept. of Construction Management and Engineering
e: l.l.oldescholtenhuis@utwente.nl
t: +31(0)53 489 6857
m: +31(0)6 234 340 67
*Expert Elite*
Kent1Cooper
Posts: 5,242
Registered: ‎09-13-2004
Message 15 of 54 (301 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 06:26 AM in reply to: l.l.oldescholtenhuis

l.l.oldescholtenhuis wrote:

....

Another remark on Kents proposed solution: as I get many drawings containing 2D-lines from drafters and engineers, I need to find a function to convert them in 3D. So I'm not sure whether your solution will work for me. 

....


As far as I know, all Lines in AutoCAD are already 3D, that is, there's no difference between a Line that lies with its ends at the same Z-coordinate value and one with its ends at different Z-coordinate values, except the different numbers in those (assoc 10) and (assoc 11) entity-data entries.  I'm not aware of any need for conversion, nor what a conversion would do.  If you just mean moving them to different elevations, or moving an end to a different elevation, the routine won't care.  They're not like Polylines, for which there is a distinct entity type for the 3D variety.  The routine I posted works on all of those entity types listed in the (ssget) filter, 2D or 3D, except that I find it doesn't like 3D Splines, so if they are possible, you could omit Spline from the filter, or any Splines could be checked for being planar before having tubes built on them.

Kent Cooper
*Expert Elite*
hmsilva
Posts: 2,648
Registered: ‎12-17-2004
Message 16 of 54 (297 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 06:31 AM in reply to: l.l.oldescholtenhuis
You're welcome, Léon
Have a great weekend too!

Henrique
*Expert Elite*
Kent1Cooper
Posts: 5,242
Registered: ‎09-13-2004
Message 17 of 54 (294 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 06:48 AM in reply to: hmsilva

hmsilva wrote:

.... 

....
(foreach x layrl (setq filter (strcat filter (vl-princ-to-string x) ",")) );; foreach (setq filter (vl-string-right-trim "," filter)) ....
(ssget (list '(0 . "LINE,*POLYLINE,3dpoly") (cons 8 (strcat filter))) ....

....


Just for your information, you don't need to remove the comma from the end of the Layer-names list -- it will work with the comma at the end.

 

But I'm also thinking that if the list of Layers is hard-coded into the routine at the beginning, then it may as well be hard-coded into the (ssget) filter, too.  You could eliminate that (foreach) that strings the Layer names together [as well as the expendable end-comma-removal], and just do this:

....

  (ssget
    '((0 . "LINE,*POLYLINE,3dpoly") (8 . "WATER,GAS"))

....

 

Of course, you wouldn't want to do that if you built it as a function with the Layer-name list as an argument that might be different every time you run it.

 

EDIT:  Also, it looks like the routine does the Sweeping and then moves the result to the desired elevation.  I think the sequence should be different, if I'm interpreting Messages 8 and 10 correctly -- the Line/Polyline should be moved to the desired elevation first, then Sweep should be applied.

 

[EDIT 2:  fixed the dotted-pair with the 8]

Kent Cooper
*Expert Elite*
hmsilva
Posts: 2,648
Registered: ‎12-17-2004
Message 18 of 54 (287 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 07:04 AM in reply to: Kent1Cooper

Just for your information, you don't need to remove the comma from the end of the Layer-names list -- it will work with the comma at the end.

 


Kent,
thanks for that information, I thought it would give an error...

 

As to the filter list, I created it this way to avoid too much intervention from the OP, just filling out the two initial lists ...

 

Thank you very much!
Cheers
Henrique

*Expert Elite*
Kent1Cooper
Posts: 5,242
Registered: ‎09-13-2004
Message 19 of 54 (283 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 07:34 AM in reply to: l.l.oldescholtenhuis

l.l.oldescholtenhuis wrote:

.... I would like to be able to let AutoCAD identify various layers based on their name (e.g. Electricity, Water, Gas, etc). Subsequently, I want Autocad to move the various layer to predefined z-coordinates. Then, we can apply the sweep-multiple to create 3D-solids. For example: identify water layer, move all plines in water layer to z-coordinate -3, sweep plines. Repeat process for gas (z-coordinate -2,5) etc. 

 

and...

 

Lines on all drawings have the same z-coordinate (x,y,0). Currently, practitioners are not using any 3D-features


This seems to do that, in limited testing.  It picks up on another current thread about finding the item in a list that follows a specified item, and thereby contains the Layer names and their associated elevations in one list.  Again, it uses Extrude rather than Sweep [since I can't test the latter], and it may work with more entity types than you need, and it doesn't yet have an error handler, but see what you think.

 

(defun C:TUBE (/ cmde osm elevs ss ent)
  (initget (if *tubedia 6 7)); no 0, no negative, no Enter on first use
  (setq
    *tubedia
      (cond
        ((getdist
            (strcat
              "\nDiameter of Tubular Cross-Section(s)"
              (if *tubedia (strcat " <" (rtos *tubedia) ">") ""); offer default only on subsequent use
              ": "
            ); strcat
          ); getdist
        ); User-gives-distance condition
        (*tubedia); Enter for default on subsequent use
      ); cond & *tubedia
    cmde (getvar 'cmdecho)
    osm (getvar 'osmode)
    clay (getvar 'clayer)
    elevs '("ELECTRICITY" 1 "WATER" -3 "GAS" -2.5); edit numbers as appropriate
  ); setq
  (setvar 'cmdecho 0)
  (setvar 'osmode 0)
  (prompt "\nTo put paths at Layer-based elevations and make tubular extrusions along them,")
  (if
    (setq ss (ssget '((0 . "*POLYLINE,LINE,ARC,CIRCLE,ELLIPSE,SPLINE") (8 . "ELECTRICITY,WATER,GAS"))))
    (repeat (sslength ss)
      (setq ent (ssname ss 0))
      (command
        "_.move" ent ""
        (list 0 0 (cadr (member (strcase (setvar 'clayer (cdr (assoc 8 (entget ent))))) elevs)))
          ; gets elevation value as item following Layer name in elevs list,
          ; setting that Layer current in the process
        "" ; 'point' given was displacement -- finish Move
        "_.ucs" "_ZA"
          (vlax-curve-getStartPoint ent)
          (mapcar '+
            (vlax-curve-getStartPoint ent)
            (vlax-curve-getFirstDeriv ent (vlax-curve-getStartParam ent))
          ); mapcar & UCS
        "_.circle" "0,0" (/ *tubedia 2)
        "_.ucs" "_previous"
        "_.extrude" (entlast) "" "_path" ent
      ); command
      (ssdel (ssname ss 0) ss)
    ); repeat
  ); if
  (setvar 'cmdecho cmde)
  (setvar 'osmode osm)
  (setvar 'clayer clay)
  (princ)
); defun

 

Kent Cooper
*Expert Elite*
Kent1Cooper
Posts: 5,242
Registered: ‎09-13-2004
Message 20 of 54 (278 Views)

Re: sweep multple polylines at once. Code does not work *yet*

04-26-2013 08:13 AM in reply to: Kent1Cooper

Kent1Cooper wrote:
....

This seems to do that, in limited testing.  ....


Oh, and I should also mention that it does depend on the second thing I quoted from the OP, that everything is starting out at 0 elevation.  If anything might not be, or if you try to run it again and catch any of the objects that were moved before, then adjustments could be made to force things to an absolute elevation, regardless of their initial elevation.

Kent Cooper

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community