Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Insert Block along polyline by distance & offset

14 REPLIES 14
Reply
Message 1 of 15
siukai10
4280 Views, 14 Replies

Insert Block along polyline by distance & offset

I had downloaded a lisp file called Put2.lsp from Tee Square Graphic. It help me to insert a defined block along the polyline by distance. I modified it with repeat function which enable me to insert numerous blocks along the polyline continuously. I didn't modify this lsp file properly with error message during ending execution. Should someone fix this ending execution for me once my last block inserted. the file is:

(defun C:PUT (/ os ce bm blk ent obj ppt dst ept ref len ipt par slp ang)
(command "_.undo" "_be")
(setq os (getvar "osmode")
ce (getvar "cmdecho")
bm (getvar "blipmode")
blk ""
);;setq
(if (not bk)(setq bk ""))
(setvar "osmode" 0)
(setvar "cmdecho" 0)
(setvar "blipmode" 0)
(while (not (setq ent (entsel "\nSelect object near reference end: "))))
(while
(and
(not (tblsearch "block" blk))
(not (findfile (strcat blk ".dwg")))
);;and
(setq blk (getstring (strcat "\nBlock to use <" bk ">: ")))
(if (> blk "")(setq bk blk)(setq blk bk))
);;while
(while (setq obj (car ent)
ppt (osnap (cadr ent) "nea")
dst (getdist "\nDistance to Block Insertion: ")
ept (vlax-curve-getEndPoint obj)
ref (vlax-curve-getDistAtPoint obj ppt)
len (vlax-curve-getDistAtPoint obj ept)
);;setq
(if (> ref (/ len 2.0))
(setq dst (- len dst))
);;setq
(setq ipt (vlax-curve-getPointAtDist obj dst)
par (vlax-curve-getParamAtPoint obj ipt)
slp (vlax-curve-getFirstDeriv obj par)
ang (atan (/ (cadr slp)(car slp)))
);;setq
(entmake
(list
'(0 . "INSERT")
(cons 2 blk)
(cons 10 ipt)
(cons 50 ang)
);;list
);;entmake
)
(princ)
)

Ideally, it prefer to insert the block along polyline by distance & offset distance. Should it be possible to modify this routine with offset distance as well. So the block will be in determined distance & offset along the polyline. THK anyone help.
14 REPLIES 14
Message 2 of 15
highflybird
in reply to: siukai10

[code]
......
(while (setq obj (car ent)
ppt (osnap (cadr ent) "nea")
dst (getdist "\nDistance to Block Insertion: ")
ept (vlax-curve-getEndPoint obj)
ref (vlax-curve-getDistAtPoint obj ppt)
len (vlax-curve-getDistAtPoint obj ept)
);;setq
......
[/code]
=> Should be modified like this:
[code]
......
(while (setq obj (car ent)
ppt (osnap (cadr ent) "nea")
ept (vlax-curve-getEndPoint obj)
ref (vlax-curve-getDistAtPoint obj ppt)
len (vlax-curve-getDistAtPoint obj ept)
dst (getdist "\nDistance to Block Insertion: ")
)
......
[/code]
just exchange two code position.
Message 3 of 15
irneb
in reply to: siukai10

Just a thought ... can't you simply offset the polyline first then use measure to place the block, then delete the new polyline?

You could even automate this process through lisp. Something like:
(defun C:Blk2PolyOff ( / pl1 pl2 bname pt1 odist)
(setq bname (getstring "\nType Block name: "))
(setq pl1 (car (entsel "\nSelect polyline: ")))
(setq pt1 (getpoint "\nPick side to offset to: "))
(setq odist (getdist pt1 "\nDistance to offset"))
(command "_offset" odist pl1 pt1 "")
(setq pl2 (entlast))
(command "_measure" pl2 "_b" bname "_y" odist)
;; or if you don't want to rotate the block as well
;; (command "_measure" pl2 "_b" bname "_n" odist)
)

This is quick & dirty - I havn't checked if it works properly, but the idea is sound.
Message 4 of 15
siukai10
in reply to: siukai10

Thanks highflybird
You fixed my lisp error.
Cheers
siukai10
Message 5 of 15
siukai10
in reply to: siukai10

Thanks Irneb
At the moment, I offset the block at distance I wanted and created another temporary block on top of it. Use Put2.lsp to put the temporary blocks in places. Explode them and purge them. Look OK but stupid, isn't it? The suggestion you given is not applied to my application. We work in transportation discipline and locate a lot of roadway signages. There are Hundreds of signages along each side of the road. We normally relies on client 3Dpolyline to identify the roadway curvages and exact locations. The line called 'control line' with distance called 'chainage'. If we offset the control line and then put the block in place, the inserted block location against the original line will be deviated depending the offset distance & curvage.
The lisp routine you proposed is offset the line and used measure command to distribute the same block along the line with equal distance. It doesn't suit my needed.
Thanks Siukai10
Message 6 of 15
tommcgtx
in reply to: siukai10

I came across this post while looking for a lisp routine that would allow me to insert a block at specified distances along a polyline. This works great, but how could it be modified to change scale factor, or maybe even use the block insertion dialog box to pick the block?

Message 7 of 15
Kent1Cooper
in reply to: tommcgtx


@tommcgtx wrote:

I came across this post while looking for a lisp routine that would allow me to insert a block at specified distances along a polyline. This works great, but how could it be modified to change scale factor, or maybe even use the block insertion dialog box to pick the block?


One of the many enhancements of the DIV+ and MEA+ commands in this:

 

http://cadtips.cadalyst.com/2d-operations/divide-and-measure-plus

 

above and beyond what ordinary Divide & Measure will do, is that they let you specify the scale of the Blocks [ordinary Divide & Measure only use 1].  They don't let you use the Block Insertion dialog box, but they do accept Block names that are not already in the drawing [ordinary Divide & Measure won't], provided they're drawings somewhere in the Support File Search Path list in the Files tab in Options.

Kent Cooper, AIA
Message 8 of 15
tommcgtx
in reply to: siukai10

That works great, but I'm looking for something that will let me specify the distance from the end of the pline. For instance, placing manholes along a sewer line at specific stations (0+00, 1+50, 2+65.25, etc.). The original routine I was asking about does this, but it won't allow for scaling. I understand that it is just as easy to go back and scale the blocks afterword, but it would be nice to be able to do it in one step.

Message 9 of 15
Kent1Cooper
in reply to: tommcgtx


@tommcgtx wrote:

....I'm looking for something that will let me specify the distance from the end of the pline. For instance, placing manholes along a sewer line at specific stations (0+00, 1+50, 2+65.25, etc.). The original routine I was asking about does this, but it won't allow for scaling. ....


If by "this" in "This works great" in Message 6 you mean the code in Message 1, and assuming you want the same value for both X and Y scale factors, you should be able to add something like this:

 

(setq scl (getreal "\nScale Factor for Blocks: "))

 

up near the top somewhere, and then add the scale factors to the (entmake) entity data list at the end:

 

  (entmake
    (list
      '(0 . "INSERT")
      (cons 2 blk)
      (cons 10 ipt)

      (cons 41 scl); X scale factor
      (cons 42 scl); Y scale factor
      (cons 50 ang)
    );;list
  );;entmake
 [Add another line with a 43 if you want to designate the Z scale factor.]

Kent Cooper, AIA
Message 10 of 15
tommcgtx
in reply to: siukai10

By "this" I meant the MEA+ and DIV+ from Cadalyst in the post I replied to.

Message 11 of 15
tommcgtx
in reply to: siukai10

Kent1Cooper,

 

I tried to add the lines you suggested, but got a "syntax error". I don't know if I entered them in wrong or what, and I am not experienced enough to figure it out. Thank you.

Message 12 of 15
Kent1Cooper
in reply to: tommcgtx


@tommcgtx wrote:

By "this" I meant the MEA+ and DIV+ from Cadalyst in the post I replied to.


[Actually, those would be referred to by "That works great" in Message 8 -- look back at "This works great" in Message 6, from before I posted the link to DIV+/MEA+.]

 

I just wanted to be sure you were referring to the code in Message 1, not something else on the thread, as a basis for something to add a scaling option to.  I hadn't realized before [not having loaded it up or studied it very deeply] that Message 1 was built to take varying distances, rather than regular spacing -- probably the use of Measure in Message 3 threw me, because I hadn't read Message 5 all the way through to realize that Message 3 isn't operationally equivalent to Message 1.

 

My suggestion in Message 9 would be to add a scale option to the code in Message 1.  It would be considerably more complicated to "fix" DIV+/MEA+ for your purpose, because they are built to enhance the possibilities of ordinary Divide & Measure, but otherwise to be like them.  Consequently, both of them result in regularly-spaced placements.  Altering them to take a sequence of varying distances would be a much bigger re-write than just adding the scale option to Message 1, if it otherwise does what you want.

Kent Cooper, AIA
Message 13 of 15
Kent1Cooper
in reply to: tommcgtx


@tommcgtx wrote:

.... 

I tried to add the lines you suggested, but got a "syntax error". I don't know if I entered them in wrong or what, and I am not experienced enough to figure it out. Thank you.


It could be that you put the scale prompt in some inappropriate place, such as within one of those (while) loops or something.  Post your adjusted version, and it may be apparent.

 

Or it may be that if you include X and Y scale factors in an (entmake) entity-data list, you must also include a Z scale factor -- I haven't tried that.  If that's the problem, this should fix it:

....

      (cons 10 ipt)

      (cons 41 scl); X scale factor
      (cons 42 scl); Y scale factor
      (cons 43 scl); Y scale factor
      (cons 50 ang)

....

Kent Cooper, AIA
Message 14 of 15
tommcgtx
in reply to: Kent1Cooper

Kent1Cooper,

 

Thank you, I pasted the lines with the Z scale factor, and it works! I don't know if I pasted the lines in the wrong place at first, but here is what I ended up with:

 

(defun C:UT (/ os ce bm blk ent obj ppt dst ept ref len ipt par slp ang)
(command "_.undo" "_be")
(setq os (getvar "osmode")
ce (getvar "cmdecho")
bm (getvar "blipmode")
blk ""
);;setq
(if (not bk)(setq bk ""))
(setvar "osmode" 0)
(setvar "cmdecho" 0)
(setvar "blipmode" 0)
(while (not (setq ent (entsel "\nSelect object near reference end: "))))
(while
(and
(not (tblsearch "block" blk))
(not (findfile (strcat blk ".dwg")))
);;and
(setq scl (getreal "\nScale Factor for Blocks: "))
(setq blk (getstring (strcat "\nBlock to use <" bk ">: ")))
(if (> blk "")(setq bk blk)(setq blk bk))
);;while
(while (setq obj (car ent)
ppt (osnap (cadr ent) "nea")
ept (vlax-curve-getEndPoint obj)
ref (vlax-curve-getDistAtPoint obj ppt)
len (vlax-curve-getDistAtPoint obj ept)
dst (getdist "\nDistance to Block Insertion: ")
)
(if (> ref (/ len 2.0))
(setq dst (- len dst))
);;setq
(setq ipt (vlax-curve-getPointAtDist obj dst)
par (vlax-curve-getParamAtPoint obj ipt)
slp (vlax-curve-getFirstDeriv obj par)
ang (atan (/ (cadr slp)(car slp)))
);;setq
(entmake
(list
'(0 . "INSERT")
(cons 2 blk)
(cons 10 ipt)
(cons 41 scl); X scale factor
(cons 42 scl); Y scale factor
(cons 43 scl); Y scale factor
(cons 50 ang)
);;list
);;entmake
)
(princ)
)

Message 15 of 15
Kent1Cooper
in reply to: tommcgtx


@tommcgtx wrote:

.... 

Thank you, I pasted the lines with the Z scale factor, and it works! ....

....

(cons 41 scl); X scale factor
(cons 42 scl); Y scale factor
(cons 43 scl); Y scale factor
....


I'm glad it works, but I see I didn't change the Y to a Z, to go along with changing the 42 to a 43, when I copied the Y scale factor line for the Z scale factor.  It wouldn't affect the working of it, since it's only in a comment, but for looking back at it later, you probably ought to make that correction:

....

(cons 41 scl); X scale factor
(cons 42 scl); Y scale factor
(cons 43 scl); Z scale factor
....

 

And it's interesting to know, in case it's ever needed, that if any scale factors are included in such a list, it appears all three must be.

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost