Jump to content

Insert a block at multiple points or lines and scale


Recommended Posts

G'day all


I'm working on and editing a mapping project from photogrammetry.


I have a block which indicates a square manhole cover. (File is attached to this post)


My project area has hundreds of these manholes and my client needs each of them scaled and rotated to fit the exact size of the manhole. I had been manually doing this with the help of an ECW image in the background. But the process is rather tedious and not all that accurate.


My operators can pick up a three point string showing the height and length of the manhole. Some manholes are square and some are rectangular.


I have a few lisp routines that get the block in there. The block insertion point comes in at the first plotted point as required. Is there any similar LISP that will insert the attached block dwg file at the first point collected and scale it based on the 2nd and third point whilst keeping the elevation heights?


I've attached two dwg files... One is the block itself and one is a diagram with a better explanation.


I've also added a screen shot of what is required.


Any help would be appreciated


Cheers guys






Link to comment
Share on other sites

  • Replies 22
  • Created
  • Last Reply

Top Posters In This Topic

  • grouch19




  • Lee Mac


  • eldon


Top Posters In This Topic

Posted Images

Try this need a block called Sq or what ever you want to name it draw it 1x1 square.


(defun c:inssq ( / pt1 pt2 pt3 dist ang scx scy lr)

(setq osmodes (getvar "osmode"))


(while (setq pt1 (getpoint "pick pt1 <Cr> to exit"))
(setq pt2 (getpoint "pick pt2"))
(setq pt3 (getpoint "pick pt3"))

(setq ang (angle pt1 pt2))

(setq ax (car pt1))
(setq ay (cadr pt1))
(setq bx (car pt2))
(setq by (cadr pt2))
(setq x (car pt3))
(setq y (cadr pt3))
(setq lr (- (*(- Bx  Ax)  (- Y  Ay)) (*(- By  Ay) (- X  Ax)))) ; left right test

(setq scx (distance pt1 pt2))
(setq scy (distance pt3 pt2))
(setvar "osmode" 0)

(command "-insert" "sq" pt1 scx scy ang)

(if (> lr 0.0) 
(command "mirror" "L" "" pt1 pt2 "Y")
(setvar "osmode" osmodes)
(setvar "osmode" osmodes)

Edited by BIGAL
aunits was wrong
Link to comment
Share on other sites

Drawing4.dwgHi BIGAL

Thank you for the reply


I have tested this routine. The block does come in but the scale and rotation seem off.

I've attached a DWG of what happens. This DWG file has the original 3 point line still there to show the results.


My block is 1m x 1m so that should be fine.

It does appear to be using the first point as its insertion point which is great. Just not sure why it is making the block so huge and not at the right size/scale.



Link to comment
Share on other sites

Thanks BIGAL


Unfortunately it is still playing up.


I did make a stupid mistake yesterday though. In the test files I was using i had the units set to Inches. I have tried using both your routines with the units set to meters and got some mixed results.


If my 3 pt string has pt1 to pt2 at 90 degrees and pt2 to pt3 at 0/360 degrees it works perfectly. However as these lines are collected via photogrammetry and the manholes are all at random angles and spacings the 90 degree angle isn't really going to happen.


I tested the routines with pt1 to p2 running at an approx 20 degree angle and the block won't come in at that angle. It seems to rotate it slightly upwards but nowhere near the original pt1 to pt2 distance. It's almost as though once the angle is less than 90 degrees it fails.


The attached dwg file shows some of the results. Note I have shifted the red original 3 point line(s) to the left to illustrate the issue.


Really appreciate your time mate.



Link to comment
Share on other sites

I have another routine that draws pits and uses similar ideas and I know it works so will have another play but your right I need to check direction of p1-p3. Not sure why the shallow angles do not work.

Link to comment
Share on other sites

I fixed one mistake aunits should have been 3 in code above, I have to add the Mirror last to get clockwise anti clock wise.


Found a simple answer for left right, code updated. Tested on your sample dwg did them all in one go. It is feasible to rotate the block rather than mirror version 2.

Edited by BIGAL
Link to comment
Share on other sites



I'm afraid I am still getting the same results as yesterday.

Seems strange how the 90 and 360 degree lines seem to work but once the 3pt string is of those angles the block sits off.

I've attached a screen shot of my results. I've got my units menu open also to show you my setup.


The red line is the original 3pt string.


The insertion point is perfect as are the distances from pt1 to pt2 and from pt2 to pt3. It appears the issue is all around the rotation area.


I'm not that great at the LSP stuff so really appreciate your help mate.





Link to comment
Share on other sites

It works!!!


Not sure what was going on. I did a manual restart of AutoCAD and upon restart it works perfectly!


Sincerely appreciate all your help BIGAL!

Now I'm off to scale and rotate a few hundred manholes "automatically!"


Thanks again mate.



Link to comment
Share on other sites

No worries only hiccup is if block has text, you can use Mirrtext to control. A bit more long winded is to rotate the block around the centre point.


If you want it automatic make sure they are plines, just get the 3 points of the pline and it will auto do by using co-ords via a selection set.


I just cut out the need to draw the pline just pick 3pts it works now, could add a perp option. Its up to you.

Link to comment
Share on other sites

The current LSP works very well by selecting the 3 points.


But it would be super awesome to just select all the lines and have it go off and insert/scale/rotate the block without having to select the 3 points.


I'm happy to do it the current way but if there was an automatic way I'm all ears!

Link to comment
Share on other sites

Need to add version 2 must be plines not 2 lines, its very simple select all, use a get-coords of pline this is 3 pts and use what already coded. Over the weekend.


; pline get co-ords example
; By Alan H
(defun getcoords (ent)
   (vlax-ename->vla-object ent)

(defun co-ords2xy ()
; convert now to a list of xy as co-ords are x y x y x y if 3d x y z x y z
(setq len (length co-ords))
(setq numb (/ len 2)) ; even and odd check required
(setq I 0)
(repeat numb
(setq xy (list (nth i co-ords)(nth (+ I 1) co-ords) ))
; odd (setq xy (list (nth i co-ords)(nth (+ I 1) co-ords)(nth (+ I 2) co-ords) ))
(setq co-ordsxy (cons xy co-ordsxy))
(setq I (+ I 2))
; program starts here
(setq co-ords (getcoords (car (entsel "\nplease pick pline")))) 
(co-ords2xy) ; list of 2d points making pline

Link to comment
Share on other sites

Based on your sample drawing, here is my attempt:

([color=BLUE]defun[/color] c:insblk ( [color=BLUE]/[/color] blk cmd dwg ent enx idx lst scl sel )

   ([color=BLUE]setq[/color] blk [color=MAROON]"Manhole"[/color]) [color=GREEN];; Block Name[/color]

       (   ([color=BLUE]not[/color]
               ([color=BLUE]or[/color] ([color=BLUE]tblsearch[/color] [color=MAROON]"block"[/color] blk)
                   ([color=BLUE]and[/color] ([color=BLUE]setq[/color] dwg ([color=BLUE]findfile[/color] ([color=BLUE]strcat[/color] blk [color=MAROON]".dwg"[/color])))
                           ([color=BLUE]setq[/color] cmd ([color=BLUE]getvar[/color] 'cmdecho))
                           ([color=BLUE]setvar[/color] 'cmdecho 0)
                           ([color=BLUE]command[/color] [color=MAROON]"_.-insert"[/color] dwg [color=BLUE]nil[/color])
                           ([color=BLUE]setvar[/color] 'cmdecho cmd)
                           ([color=BLUE]tblsearch[/color] [color=MAROON]"block"[/color] blk)
           ([color=BLUE]princ[/color] ([color=BLUE]strcat[/color] [color=MAROON]"\nBlock \""[/color] blk [color=MAROON]"\" not found or could not be defined."[/color]))
       (   ([color=BLUE]setq[/color] sel ([color=BLUE]ssget[/color] [color=MAROON]"_:L"[/color] '((0 . [color=MAROON]"POLYLINE"[/color]) (-4 . [color=MAROON]"&="[/color]) (70 .  (-4 . [color=MAROON]"<NOT"[/color]) (-4 . [color=MAROON]"&="[/color]) (70 . 1) (-4 . [color=MAROON]"NOT>"[/color]))))
           ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] idx ([color=BLUE]sslength[/color] sel))
               ([color=BLUE]setq[/color] ent ([color=BLUE]entnext[/color] ([color=BLUE]ssname[/color] sel ([color=BLUE]setq[/color] idx ([color=BLUE]1-[/color] idx))))
                     enx ([color=BLUE]entget[/color] ent)
                     lst [color=BLUE]nil[/color]
               ([color=BLUE]while[/color] ([color=BLUE]=[/color] [color=MAROON]"VERTEX"[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 0 enx)))
                   ([color=BLUE]setq[/color] lst ([color=BLUE]cons[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 10 enx)) lst)
                         ent ([color=BLUE]entnext[/color] ent)
                         enx ([color=BLUE]entget[/color]  ent)
               ([color=BLUE]if[/color] ([color=BLUE]=[/color] 3 ([color=BLUE]length[/color] lst))
                       ([color=BLUE]if[/color] ([color=BLUE]apply[/color] '[color=BLUE]<[/color] ([color=BLUE]setq[/color] scl ([color=BLUE]mapcar[/color] '[color=BLUE]distance[/color] lst ([color=BLUE]cdr[/color] lst))))
                           ([color=BLUE]setq[/color] lst ([color=BLUE]reverse[/color] lst)
                                 scl ([color=BLUE]reverse[/color] scl)
                       ([color=BLUE]if[/color] ([color=BLUE]minusp[/color] ([color=BLUE]sin[/color] ([color=BLUE]-[/color] ([color=BLUE]angle[/color] ([color=BLUE]car[/color] lst) ([color=BLUE]caddr[/color] lst)) ([color=BLUE]angle[/color] ([color=BLUE]car[/color] lst) ([color=BLUE]cadr[/color] lst)))))
                           ([color=BLUE]setq[/color] lst ([color=BLUE]vl-list*[/color] ([color=BLUE]cadr[/color] lst) ([color=BLUE]car[/color] lst) ([color=BLUE]cddr[/color] lst)))
                       ([color=BLUE]if[/color] ([color=BLUE]entmake[/color]
                                  '(000 . [color=MAROON]"INSERT"[/color])
                                   ([color=BLUE]cons[/color] 002 blk)
                                   ([color=BLUE]cons[/color] 010 ([color=BLUE]car[/color]  lst))
                                   ([color=BLUE]cons[/color] 041 ([color=BLUE]car[/color]  scl))
                                   ([color=BLUE]cons[/color] 042 ([color=BLUE]cadr[/color] scl))
                                   ([color=BLUE]cons[/color] 050 ([color=BLUE]angle[/color] ([color=BLUE]car[/color] lst) ([color=BLUE]cadr[/color] lst)))
                           ([color=BLUE]entdel[/color] ([color=BLUE]ssname[/color] sel idx))




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.

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...