Jump to content

Need better multiline


Vigilante

Recommended Posts

Hi all, I'm sure this is out there, if someone could point me in the right direction.

 

We have acad 2002 and used to use 2000.

In 2002 we have the mline command which is pretty simple. But in 2000 we had the doubleline command which was much more powerful.

 

Basically, I draw a lot of double lines which step down in size and make turns.

So, for example, I'll start a double line at 20", draw horizontal for a bit and step down to 16". Then I might make a 45 or 90 degree turn, and continue on, possibly step down some more.

It would also be really cool, if when making a turn, it automatically arcs the corners appropriately.

 

So in 2002, I have to draw a 20" double line, stop it, cap the end, start a new double line at 16", go on and turn, stop, cap it. Then I have to go back and manually arc the corners and erase the square ends. I cap off the mline so I can start the new mline on center, plus it's needed later.

 

So, it would be special to be able to continuously draw a double line, step it down, make turns that auto-arc, without having to stop the command at each point.

 

This would save tremendous time.

 

How do I? Thanks.

Link to comment
Share on other sites

I think you draw Polyline with _pline command with specifing width of segments. It seems as doubleline when system variable FILLMODE=0.

In 2002 it available.

Link to comment
Share on other sites

Hey I downloaded the Dline lisp and it works just great, that's the one I was talking about.

 

The only thing is, I wonder if there is a version where the corners are rounded instead of square. That would just be peachy!

 

Thanks

Link to comment
Share on other sites

Hey I downloaded the Dline lisp and it works just great, that's the one I was talking about.

 

The only thing is, I wonder if there is a version where the corners are rounded instead of square. That would just be peachy!

 

Thanks

 

I wrote one for myself some time ago. See if it can help.

 

; Draws continuous pipe (or duct) of any size 
; with user defined inner bend radius (default = 0.0)

(defun c:bd (/ d1 d p1 p2 p3 rd1 rd2 lu1 lu2 u1	u2 u3 u5 erd elu erd2
     elu2 ofr)
 (setq oerr *error*)
 (defun *error* (msg)
   (setvar "filletrad" ofr)
   (setvar "osmode" osn)
   (princ
     "Function cancelled by user, or radius is too large  "
   )
   (setq *error* oerr)
   (command)
   (princ)
 )
 (setq osn (getvar "osmode"))
 (setq ofr (getvar "filletrad"))
 (setvar "cmdecho" 0)
 (if (= d2 nil)
   (setq d2 1.0)
 )
 (princ "\n Pipe diameter / duct width < ")
 (princ d2)
 (princ " >?:")
 (setq d1 (getdist))
 (if (= d1 nil)
   (setq d1 d2)
 )
 (setq d2 d1)
 (if (= r1 nil)
   (setq r1 0.0)
 )
 (princ "\n Inner bend radius < ")
 (princ r1)
 (princ " >?:")
 (setq r (getdist))
 (if (= r nil)
   (setq r r1)
 )
 (setq r1 r)
 (setq d (/ d1 2))
 (setq p1 (getpoint "\n Start point: "))
 (setq p2 (getpoint p1 "\n Next point: "))
 (setq u1 (angle p1 p2))

 (setq rd1 (polar p1 (- u1 (* pi 0.5)) d)) ; rd = right
 (setq rd2 (polar rd1 u1 (distance p1 p2)))
 (setq lu1 (polar p1 (+ u1 (* pi 0.5)) d)) ; lu = left
 (setq lu2 (polar lu1 u1 (distance p1 p2)))
 (setvar "osmode" 0)
 (command "line" rd1 rd2 "")
 (setq erd (entlast))
 (command "line" lu1 lu2 "")
 (setq elu (entlast))
 (setvar "osmode" osn)
 (setq p3 (getpoint p2 "\n Next"))
 (setvar "osmode" 0)
 (setq u2 (angle p2 p3))

 (setq u5 (+ (- pi u1) u2))
 (if (> u5 (* pi 2))
   (setq u5 (- u5 (* pi 2)))
 )
 (if (< u5 0)
   (setq u5 (+ (* pi 2) u5))
 )

 (while p3
   (setq p1 p2)
   (setq p2 p3)
   (setq u1 (angle p1 p2))

   (setq rd1 (polar p1 (- u1 (* pi 0.5)) d)) ; rd = right/down
   (setq rd2 (polar rd1 u1 (distance p1 p2)))
   (setq lu1 (polar p1 (+ u1 (* pi 0.5)) d)) ; lu = left/up
   (setq lu2 (polar lu1 u1 (distance p1 p2)))
   (command "line" rd1 rd2 "")
   (setq erd2 (entlast))
   (command "line" lu1 lu2 "")
   (setq elu2 (entlast))

   (if	(< u5 pi)
     (progn
(setvar "filletrad" r)
(command "fillet" erd erd2)
(setvar "filletrad" (+ d1 r))
(command "fillet" elu elu2)
     )
   )
   (if	(> u5 pi)
     (progn
(setvar "filletrad" (+ d1 r))
(command "fillet" erd erd2)
(setvar "filletrad" r)
(command "fillet" elu elu2)
     )
   )

   (setq erd erd2)
   (setq elu elu2)
   (setvar "osmode" osn)
   (setq p3 (getpoint p2 "\n Next:"))
   (setvar "osmode" 0)
   (if	(= p3 nil)
     ()
     (setq u2 (angle p2 p3))
   )

   (setq u5 (+ (- pi u1) u2))
   (if	(> u5 (* pi 2))
     (setq u5 (- u5 (* pi 2)))
   )
   (if	(< u5 0)
     (setq u5 (+ (* pi 2) u5))
   )


 )
 (setvar "osmode" osn)
 (setvar "filletrad" ofr)
 (princ)
)

Link to comment
Share on other sites

Nice, I played around with it a little, it's alright. Only thing I would change, for my own purposes, are these:

 

1) I'd like to see the lines as their drawn, rather then a dashed line, because I have to size things as I draw.

 

2) I'd like justification, like mline, for alignment.

 

3) It would be ok for the radius to be calculated as a quarter of the line spacing. So if the line spacing is 6", the radius can just be 1.5". That would save a step.

 

4) Lastly, and most important, I want to be able to change widths while still in the command. So if I start drawing at 6", I want to change width to 4" without stopping the command. The double line should be capped where the larger width stops and the shorter width begins. And the shorter width is still centered on the larger. And if I change width, or course the radius would have to change with it.

 

5) Lastly, on any curve, the double lines should be capped where each arc begins and ends.

 

 

I attached a picture of the type of thing I'd like to draw with a single command, all in one motion. Mline can't change width mid-way. The Dline can but arcing corners is impossible to me and it has to many options. Your BD script does the corners but doesn't have those things mentioned.

 

Refere to the picture, can anybody help tweak a script or know where I can do this drawing with one command?

 

Thanks, the suggestions thus far already save many steps in creating this drawing.

dline.JPG

Link to comment
Share on other sites

Believe me, I want to. I'm begining my studies. But this particular problem is to advanced for a beginner.

 

I did, however, take two sepparate LISP programs and merge them together into a single command for my purposes. That's gotta be something :)

Link to comment
Share on other sites

Nice, I played around with it a little, it's alright. Only thing I would change, for my own purposes, are these:

 

1) I'd like to see the lines as their drawn, rather then a dashed line, because I have to size things as I draw.

 

2) I'd like justification, like mline, for alignment.

 

3) It would be ok for the radius to be calculated as a quarter of the line spacing. So if the line spacing is 6", the radius can just be 1.5". That would save a step.

 

4) Lastly, and most important, I want to be able to change widths while still in the command. So if I start drawing at 6", I want to change width to 4" without stopping the command. The double line should be capped where the larger width stops and the shorter width begins. And the shorter width is still centered on the larger. And if I change width, or course the radius would have to change with it.

 

5) Lastly, on any curve, the double lines should be capped where each arc begins and ends.

 

 

I attached a picture of the type of thing I'd like to draw with a single command, all in one motion. Mline can't change width mid-way. The Dline can but arcing corners is impossible to me and it has to many options. Your BD script does the corners but doesn't have those things mentioned.

 

Refere to the picture, can anybody help tweak a script or know where I can do this drawing with one command?

 

Thanks, the suggestions thus far already save many steps in creating this drawing.

 

Well, I am trying to imagine the user input for the figure like the one on the picture.

Every segment, the routine would have to ask if there is any change in size for the next segment.

The same goes for “justification”. If it is other than symmetrical, there would have to be some more questions answered before program could continue after each change in size.

Does the next segment always continue in the same direction following the change in size?

Do you always want to start from the large size and decrease it during the program execution, the other way around, or should it be possible to draw it either way?

You know the variations you want to be able to draw. Try to imagine all possible scenarios and the user input for each case and post it here.

 

I didn't quite get your comment #1. I can't see any dashed lines when I use the routine. Do you? Every segment is visible as soon as you enter the next point, isn't it?

Link to comment
Share on other sites

Well, I am trying to imagine the user input for the figure like the one on the picture.

Every segment, the routine would have to ask if there is any change in size for the next segment.

The same goes for “justification”. If it is other than symmetrical, there would have to be some more questions answered before program could continue after each change in size.

Does the next segment always continue in the same direction following the change in size?

Do you always want to start from the large size and decrease it during the program execution, the other way around, or should it be possible to draw it either way?

You know the variations you want to be able to draw. Try to imagine all possible scenarios and the user input for each case and post it here.

 

I didn't quite get your comment #1. I can't see any dashed lines when I use the routine. Do you? Every segment is visible as soon as you enter the next point, isn't it?

 

Hello! Thanks for your willingness to help. In answer to the issues you raised:

 

You are correct, each time you "click" to stop a segment, you should be able to put in a new width. This is how the mline command does it. Without interrupting the command.

 

Justification does NOT have to change mid shift. That is just an option when you first start a new multiline. And if you don't put it in at all I won't complain. KISS.

 

Yes the segment always goes in the same direction after a size change. So basically on every possible turn or corner, both sides are the same size. Size changes are usually before or after a turn. Rarely I will have to change sizes at a corner, but I don't need a single command for this. I'll just stop the command and start a new one. Because such corners are not rounded, and have other special features.

 

And I do only go from larger to smaller sizes. For my specific purpose, I would not have to go smaller to larger. But it seems like that wouldn't be hard to add, so both would be good, but not necessary at all.

 

As for the dashed line, yes the segment is visible AFTER I click to end the segment. I'd like to see the two lines AS I draw them, rather then only after I click. Refer to how mline works. There is the dotted line, but you can also see where the two lines will end up, before clicking to end the segment.

 

Here is a theoretical command chain that would work for this:

 

I type the command "xyz"

Options available "justification (bottom/center/top), size"

'Click point to start...'

Options available "size"

6 ">

<....continue clicking to end segments changing sizes....>

 

 

So basically, I only to end a segment. I shouldn't have to click after changing size. And remember the ratio is a quarter of size. And that segment ends are capped. And capped at corners as well.

 

Thanks again if you actually work on this, that would be cool!

Link to comment
Share on other sites

hell, paul that lisp is great. i think it's gonna go in my Startup Suite, haha. i'll use that a lot. one thing would have been nice, is to have an endcap when completing the line. but hey, no complaints here. lol 8)

Link to comment
Share on other sites

hell, paul that lisp is great. i think it's gonna go in my Startup Suite, haha. i'll use that a lot. one thing would have been nice, is to have an endcap when completing the line. but hey, no complaints here. lol 8)

 

Like this?

; Draws continuous pipe (or duct) of any size 
; with user defined inner bend radius (default = 0.0)

(defun c:bd (/ d1 d p1 p2 p3 rd1 rd2 lu1 lu2 u1	u2 u3 u5 erd elu erd2
     elu2 ofr)
 (setq oerr *error*)
 (defun *error* (msg)
   (setvar "filletrad" ofr)
   (setvar "osmode" osn)
   (princ
     "Function cancelled by user, or radius is too large  "
   )
   (setq *error* oerr)
   (command)
   (princ)
 )
 (setq osn (getvar "osmode"))
 (setq ofr (getvar "filletrad"))
 (setvar "cmdecho" 0)
 (if (= d2 nil)
   (setq d2 1.0)
 )
 (princ "\n Pipe diameter / duct width < ")
 (princ d2)
 (princ " >?:")
 (setq d1 (getdist))
 (if (= d1 nil)
   (setq d1 d2)
 )
 (setq d2 d1)
 (if (= r1 nil)
   (setq r1 0.0)
 )
 (princ "\n Inner bend radius < ")
 (princ r1)
 (princ " >?:")
 (setq r (getdist))
 (if (= r nil)
   (setq r r1)
 )
 (setq r1 r)
 (setq d (/ d1 2))
 (setq p1 (getpoint "\n Start point: "))
 (setq p2 (getpoint p1 "\n Next point: "))
 (setq u1 (angle p1 p2))

 (setq rd1 (polar p1 (- u1 (* pi 0.5)) d)) ; rd = right
 (setq rd2 (polar rd1 u1 (distance p1 p2)))
 (setq lu1 (polar p1 (+ u1 (* pi 0.5)) d)) ; lu = left
 (setq lu2 (polar lu1 u1 (distance p1 p2)))
 (setvar "osmode" 0)
 (command "line" rd1 lu1 "")
 (command "line" rd1 rd2 "")
 (setq erd (entlast))
 (command "line" lu1 lu2 "")
 (setq elu (entlast))
 (setvar "osmode" osn)
 (setq p3 (getpoint p2 "\n Next"))
 (setvar "osmode" 0)
 (setq u2 (angle p2 p3))

 (setq u5 (+ (- pi u1) u2))
 (if (> u5 (* pi 2))
   (setq u5 (- u5 (* pi 2)))
 )
 (if (< u5 0)
   (setq u5 (+ (* pi 2) u5))
 )

 (while p3
   (setq p1 p2)
   (setq p2 p3)
   (setq u1 (angle p1 p2))

   (setq rd1 (polar p1 (- u1 (* pi 0.5)) d)) ; rd = right/down
   (setq rd2 (polar rd1 u1 (distance p1 p2)))
   (setq lu1 (polar p1 (+ u1 (* pi 0.5)) d)) ; lu = left/up
   (setq lu2 (polar lu1 u1 (distance p1 p2)))
   (command "line" rd1 rd2 "")
   (setq erd2 (entlast))
   (command "line" lu1 lu2 "")
   (setq elu2 (entlast))

   (if	(< u5 pi)
     (progn
(setvar "filletrad" r)
(command "fillet" erd erd2)
(setvar "filletrad" (+ d1 r))
(command "fillet" elu elu2)
     )
   )
   (if	(> u5 pi)
     (progn
(setvar "filletrad" (+ d1 r))
(command "fillet" erd erd2)
(setvar "filletrad" r)
(command "fillet" elu elu2)
     )
   )

   (setq erd erd2)
   (setq elu elu2)
   (setvar "osmode" osn)
   (setq p3 (getpoint p2 "\n Next:"))
   (setvar "osmode" 0)
   (if	(= p3 nil)
     ()
     (setq u2 (angle p2 p3))
   )

   (setq u5 (+ (- pi u1) u2))
   (if	(> u5 (* pi 2))
     (setq u5 (- u5 (* pi 2)))
   )
   (if	(< u5 0)
     (setq u5 (+ (* pi 2) u5))
   )


 )
 
 (command "line" rd2 lu2 "")
 (setvar "osmode" osn)
 (setvar "filletrad" ofr)
 (princ)
)

Link to comment
Share on other sites

PERFECT!!!! wow man thanks, you didn't have to do that, but seriously, this is one of my new programs of choice now. i do Ductwork, and i use the MLINE for my rectanular duct with vained 90's, but with this new lisp now i can use it for my radius 90's. man thanks a million, seriously.... 8)

Link to comment
Share on other sites

Another one:

 

(defun c:duct(/ oldWd oldFil oldEch lEnt pl1 
            pl2 vLst1 vLst2 *error*)
 (vl-load-com)

 (defun GetPlineVer(plObj)
   (mapcar 'cdr
    (vl-remove-if-not
     '(lambda(x)(=(car x)10))
     (entget plObj)))
   ); end of GetPLineVer

 (defun *error*(msg)
   (setvar "CMDECHO" oldEch)
   (setvar "FILLMODE" oldFil)
   (princ)
   ); end of *error*
 
 (if(not duct:pWd)(setq duct:pWd 1.0))
 (setq oldWd duct:pWd
duct:pWd(getdist
     (strcat "\nSpecify pipe diameter <" (rtos duct:pWd) ">: "))
oldFil(getvar "FILLMODE")
oldEch(getvar "CMDECHO")
); end setq
 (if(null duct:pWd)(setq duct:pWd oldWd))
 (mapcar 'setvar
  '("CMDECHO" "FILLMODE") '(0 0))
 (if(entlast)(setq lEnt(entlast)))
 (princ "\nSpesify start point: ")
 (command "_.pline" pause)
 (command "_w" duct:pWd duct:pWd)
 (while(= 1(getvar "CMDACTIVE"))
   (command pause)
   (princ "\nSpecify next point: ")
   ); end while
 (if
   (not
     (equal lEnt(entlast)))
(progn
  (setq lEnt(entlast))
  (command "_.fillet" "_r" duct:pWd)
  (command "_.fillet" "_p" lEnt)
  (setq lEnt
	 (vlax-ename->vla-object lEnt)
	pl1(car(vlax-safearray->list
	     (vlax-variant-value
	       (vla-Offset lEnt (/ duct:pWd 2)))))
	pl2(car(vlax-safearray->list
	     (vlax-variant-value
	       (vla-Offset lEnt (-(/ duct:pWd 2))))))
	vLst1(GetPlineVer
	       (vlax-vla-object->ename pl1))
	vLst2(GetPlineVer
	       (vlax-vla-object->ename pl2))
	); end setq
  (vla-put-ConstantWidth pl1 0.0)
  (vla-put-ConstantWidth pl2 0.0)
  (vla-Delete lEnt)
  (foreach itm vLst1
    (command "._line" itm (car vLst2) "")
    (setq vLst2(cdr vLst2))
    ); end foreach
  ); end progn
   ); end if
 (setvar "CMDECHO" oldEch)
 (setvar "FILLMODE" oldFil)
 (princ)
 ); end of c:duct

Duct.gif

Link to comment
Share on other sites

wow, that even takes it a step further, AND it creates a polyline which is handy when offsetting for the duct liner. man this is great stuff.... paul and asmi, you guys are definitely my new best friend right now. lol 8)

 

EDIT: and to further note, i almost feel like i should be cutting you guys a check or something... haha. i mean, this SERIOUSLY just upped my drawing time.

Link to comment
Share on other sites

Never mind, here everyone help each other and you with that too. :) I have made some additions concerning errors at attempt of drawing on the locked layers. It does not affect process of drawing. Thank you.

 

(defun c:duct(/ oldWd oldFil oldEch lEnt pl1
      pl2 vLst1 vLst2 stLst *error*)
 
 (vl-load-com)

 (defun GetPlineVer(plObj)
   (mapcar 'cdr
    (vl-remove-if-not
     '(lambda(x)(=(car x)10))
     (entget plObj)))
   ); end of GetPLineVer

 (defun asmi-LayersUnlock(/ restLst)
 (setq restLst '())
 (vlax-for lay
    (vla-get-Layers
            (vla-get-ActiveDocument
              (vlax-get-acad-object)))
   (setq restLst
    (append restLst
      (list
        (list
         lay
          (vla-get-Lock lay)
   (vla-get-Freeze lay)
         ); end list
        ); end list
      ); end append
   ); end setq
   (vla-put-Lock lay :vlax-false)
   (if
     (vl-catch-all-error-p
(vl-catch-all-apply
  'vla-put-Freeze(list lay :vlax-false)))
     t)
   ); end vlax-for
 restLst
 ); end of asmi-LayersUnlock

 (defun asmi-LayersStateRestore(StateList)
 (foreach lay StateList
   (vla-put-Lock(car lay)(cadr lay))
    (if
     (vl-catch-all-error-p
(vl-catch-all-apply
  'vla-put-Freeze(list(car lay)(nth 2 lay))))
     t)
   ); end foreach
 (princ)
    ); end of asmi-LayersStateRestore

 (defun *error*(msg)
   (if(and oldEch oldFil)
     (progn
   (setvar "CMDECHO" oldEch)
   (setvar "FILLMODE" oldFil)
     ); end progn
    ); end if
   (princ)
   ); end of *error*
 
 (if(not duct:pWd)(setq duct:pWd 1.0))
 (setq oldWd duct:pWd
duct:pWd(getdist
     (strcat "\nSpecify pipe diameter <" (rtos duct:pWd) ">: "))
oldFil(getvar "FILLMODE")
oldEch(getvar "CMDECHO")
); end setq
 (if(null duct:pWd)(setq duct:pWd oldWd))
 (mapcar 'setvar
  '("CMDECHO" "FILLMODE") '(0 0))
 (if(entlast)(setq lEnt(entlast)))
 (princ "\nSpesify start point: ")
 (command "_.pline" pause)
 (command "_w" duct:pWd duct:pWd)
 (while(= 1(getvar "CMDACTIVE"))
   (command pause)
   (princ "\nSpecify next point: ")
   ); end while
 (if
   (not
     (equal lEnt(entlast)))
(progn
  (setq lEnt(entlast))
  (setq stLst(asmi-LayersUnlock))
  (command "_.fillet" "_r" duct:pWd)
  (command "_.fillet" "_p" lEnt)
  (setq lEnt
	 (vlax-ename->vla-object lEnt)
	pl1(car(vlax-safearray->list
	     (vlax-variant-value
	       (vla-Offset lEnt (/ duct:pWd 2)))))
	pl2(car(vlax-safearray->list
	     (vlax-variant-value
	       (vla-Offset lEnt (-(/ duct:pWd 2))))))
	vLst1(GetPlineVer
	       (vlax-vla-object->ename pl1))
	vLst2(GetPlineVer
	       (vlax-vla-object->ename pl2))
	); end setq
  (vla-put-ConstantWidth pl1 0.0)
  (vla-put-ConstantWidth pl2 0.0)
  (vla-Delete lEnt)
  (asmi-LayersStateRestore stLst)
  (foreach itm vLst1
    (command "._line" itm (car vLst2) "")
    (setq vLst2(cdr vLst2))
    ); end foreach
  ); end progn
   ); end if
 (setvar "CMDECHO" oldEch)
 (setvar "FILLMODE" oldFil)
 (princ)
 ); end of c:duct

Link to comment
Share on other sites

It seems good idea to me has come. It is possible to transform existing polylines to pipes.

 

(defun c:plp(/ lSet plLst pl pl1 pl2 oldOsm
      actDoc vLst1 vLst2 stLst *error*)
 
 (vl-load-com)

 (defun GetPlineVer(plObj)
   (mapcar 'cdr
    (vl-remove-if-not
     '(lambda(x)(=(car x)10))
     (entget plObj)))
   ); end of GetPLineVer

 (defun asmi-LayersUnlock(/ restLst)
 (setq restLst '())
 (vlax-for lay
    (vla-get-Layers
            (vla-get-ActiveDocument
              (vlax-get-acad-object)))
   (setq restLst
    (append restLst
      (list
        (list
         lay
          (vla-get-Lock lay)
   (vla-get-Freeze lay)
         ); end list
        ); end list
      ); end append
   ); end setq
   (vla-put-Lock lay :vlax-false)
   (if
     (vl-catch-all-error-p
(vl-catch-all-apply
  'vla-put-Freeze(list lay :vlax-false)))
     t)
   ); end vlax-for
 restLst
 ); end of asmi-LayersUnlock

 (defun asmi-LayersStateRestore(StateList)
 (foreach lay StateList
   (vla-put-Lock(car lay)(cadr lay))
    (if
     (vl-catch-all-error-p
(vl-catch-all-apply
  'vla-put-Freeze(list(car lay)(nth 2 lay))))
     t)
   ); end foreach
 (princ)
    ); end of asmi-LayersStateRestore

 (if(not duct:pWd)(setq duct:pWd 1.0))
 (setq oldWd duct:pWd
duct:pWd(getdist
     (strcat "\nSpecify pipes diameter <" (rtos duct:pWd) ">: "))
); end setq
 (if(null duct:pWd)(setq duct:pWd oldWd))
(princ "\n>>> Select polylines <<< ")
 (if
   (setq lSet
   (ssget '((0 . "LWPOLYLINE"))))
(progn
  (setq stLst(asmi-LayersUnlock)
	plLst(mapcar 'vlax-ename->vla-object
	       (vl-remove-if 'listp 
                        (mapcar 'cadr(ssnamex lSet))))
	); end setq
  (vla-StartUndoMark
    (setq actDoc
	   (vla-get-ActiveDocument
		  (vlax-get-acad-object))))
  (foreach pl plLst
  (command "_.fillet" "_r" duct:pWd)
  (command "_.fillet" "_p"
	   (vlax-vla-object->ename pl))
  (setq pl1(car(vlax-safearray->list
	     (vlax-variant-value
	       (vla-Offset pl (/ duct:pWd 2)))))
	pl2(car(vlax-safearray->list
	     (vlax-variant-value
	       (vla-Offset pl (-(/ duct:pWd 2))))))
	vLst1(GetPlineVer
	       (vlax-vla-object->ename pl1))
	vLst2(GetPlineVer
	       (vlax-vla-object->ename pl2))
	); end setq
  (vla-put-ConstantWidth pl1 0.0)
  (vla-put-ConstantWidth pl2 0.0)
  (vla-Delete pl)
  (foreach itm vLst1
    (setq oldOsm(getvar "OSMODE"))
    (setvar "OSMODE" 0)
    (command "._line" itm (car vLst2) "")
    (setvar "OSMODE" oldOsm)
    (setq vLst2(cdr vLst2))
    ); end foreach
    (asmi-LayersStateRestore stLst)
   ); end foreach
  (vla-EndUndoMark actDoc)
  ); end progn
   ); end if
 (princ)
 ); end of c:plp

plp.gif

  • Like 1
Link to comment
Share on other sites

One more modification for one step Undo, [Length/Undo] in command line and restoring default polyline width:

 

(defun c:duct(/ oldWd oldFil oldEch lEnt pl1 actDoc
      pl2 vLst1 vLst2 stLst *error* oldWid)
 
 (vl-load-com)

 (defun GetPlineVer(plObj)
   (mapcar 'cdr
    (vl-remove-if-not
     '(lambda(x)(=(car x)10))
     (entget plObj)))
   ); end of GetPLineVer

 (defun asmi-LayersUnlock(/ restLst)
 (setq restLst '())
 (vlax-for lay
    (vla-get-Layers
            (vla-get-ActiveDocument
              (vlax-get-acad-object)))
   (setq restLst
    (append restLst
      (list
        (list
         lay
          (vla-get-Lock lay)
   (vla-get-Freeze lay)
         ); end list
        ); end list
      ); end append
   ); end setq
   (vla-put-Lock lay :vlax-false)
   (if
     (vl-catch-all-error-p
(vl-catch-all-apply
  'vla-put-Freeze(list lay :vlax-false)))
     t)
   ); end vlax-for
 restLst
 ); end of asmi-LayersUnlock

 (defun asmi-LayersStateRestore(StateList)
 (foreach lay StateList
   (vla-put-Lock(car lay)(cadr lay))
    (if
     (vl-catch-all-error-p
(vl-catch-all-apply
  'vla-put-Freeze(list(car lay)(nth 2 lay))))
     t)
   ); end foreach
 (princ)
    ); end of asmi-LayersStateRestore

 (defun *error*(msg)
   (if(and oldEch oldFil)
     (progn
   (setvar "CMDECHO" oldEch)
   (setvar "FILLMODE" oldFil)
   (setvar "PLINEWID" oldWid)
     ); end progn
    ); end if
    (if actDoc
     (vla-EndUndoMark actDoc)
     ); end if
   (princ)
   ); end of *error*
 
 (if(not duct:pWd)(setq duct:pWd 1.0))
 (setq oldWd duct:pWd
duct:pWd(getdist
     (strcat "\nSpecify pipe diameter <" (rtos duct:pWd) ">: "))
oldFil(getvar "FILLMODE")
oldEch(getvar "CMDECHO")
oldWid(getvar "PLINEWID")
); end setq
 (if(null duct:pWd)(setq duct:pWd oldWd))
 (mapcar 'setvar
  '("CMDECHO" "FILLMODE") '(0 0))
 (if(entlast)(setq lEnt(entlast)))
 (vla-StartUndoMark
    (setq actDoc
	   (vla-get-ActiveDocument
		  (vlax-get-acad-object))))
 (princ "\nSpecify start point: ")
 (command "_.pline" pause)
 (command "_w" duct:pWd duct:pWd)
 (while(= 1(getvar "CMDACTIVE"))
   (command pause)
   (princ "\nSpecify next point or [Length/Undo]: ")
   ); end while
 (if
   (not
     (equal lEnt(entlast)))
(progn
  (setq lEnt(entlast)
        stLst(asmi-LayersUnlock))
  (command "_.fillet" "_r" duct:pWd)
  (command "_.fillet" "_p" lEnt)
  (setq lEnt
	 (vlax-ename->vla-object lEnt)
	pl1(car(vlax-safearray->list
	     (vlax-variant-value
	       (vla-Offset lEnt (/ duct:pWd 2)))))
	pl2(car(vlax-safearray->list
	     (vlax-variant-value
	       (vla-Offset lEnt (-(/ duct:pWd 2))))))
	vLst1(GetPlineVer
	       (vlax-vla-object->ename pl1))
	vLst2(GetPlineVer
	       (vlax-vla-object->ename pl2))
	); end setq
  (vla-put-ConstantWidth pl1 0.0)
  (vla-put-ConstantWidth pl2 0.0)
  (vla-Delete lEnt)
  (asmi-LayersStateRestore stLst)
  (foreach itm vLst1
    (command "._line" itm (car vLst2) "")
    (setq vLst2(cdr vLst2))
    ); end foreach
  ); end progn
   ); end if
 (vla-EndUndoMark actDoc)
 (setvar "CMDECHO" oldEch)
 (setvar "FILLMODE" oldFil)
 (setvar "PLINEWID" oldWid)
 (princ)
 ); end of c:duct 

  • Like 1
Link to comment
Share on other sites

Looking good guys!

 

Now if only we could blend the two scripts so that all segments are capped, and I can see both lines as I draw, to know where they'll be. And, or course, be able to change widths within the command.

 

AMSI's script shows both lines, and caps all the segments, and I like the undo thing.

I like how Paul's script rounds the corners as you draw, rather then at the end of the command.

 

These scripts are so close to doing what I need!

 

I'm not sure if it's better to have polylines or not. When I use mline I normally end up having to explode so I can edit the lines.

However, it would be good if the entire duct, or everything created by a single command, is all one selection/object/line, whatever. Like mline.

In other words, imagine I create a string of duct and maybe 2 or 3 corners. But then I have to move all the duct 3" down. If all the duct drawn was a single line or block, I could just grab it and move. But if not, I have to try to select all the duct line by line and then move it.

 

I don't want to sound picky! It's just that the scripts are so close I'm kind of excited! But without being able to change sizes midway, it's just the same as mline except for rounded corners.

And whatever calc ASMI uses for radius should be added to yours, Paul. Unless naming a specific radius is needed. It's not, in my case, the radius can be calculated automatically like ASMI's. The idea is to remove as many clicks and commands as possible, to draw this duct like shown on page one.

 

Blast, I wish I knew LISP! Got any good beginner tutorials around here? I'm not a stranger to programming, I know Visual Basic, some Java, C concepts, PHP, so I should be able to jump right in.

 

Thanks again, good stuff! If you create this script so that the drawing in page 1 could be drawn in one command, there is only one more thing to add to make it complete! You have no idea how much time and effort this will save!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...