grouch19 Posted March 6, 2017 Posted March 6, 2017 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 Manhole.dwg BlockSample.dwg Quote
BIGAL Posted March 6, 2017 Posted March 6, 2017 (edited) 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")) (SETQ ANGDIRR (GETVAR "ANGDIR")) (SETQ AUNITSS (GETVAR "AUNITS")) (SETVAR "ANGDIR" 0) (SETVAR "AUNITS" 3) (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) (princ) (command "mirror" "L" "" pt1 pt2 "Y") ) (setvar "osmode" osmodes) ) (SETVAR "ANGDIR" ANGDIRR) (SETVAR "AUNITS" AUNITSS) (setvar "osmode" osmodes) ) Edited March 8, 2017 by BIGAL aunits was wrong Quote
grouch19 Posted March 6, 2017 Author Posted March 6, 2017 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. Cheers Quote
BIGAL Posted March 7, 2017 Posted March 7, 2017 I should set the angles to radians and anti clockwise then set back to what you had before. Try above code revised. Worked ok for me. Quote
grouch19 Posted March 7, 2017 Author Posted March 7, 2017 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. CheersDrawing-blocktest.dwg Quote
eldon Posted March 7, 2017 Posted March 7, 2017 Do you need to insert a block? Perhaps you could try Lee Mac's 3-Point Rectangle, which would draw the rectangle /square. Quote
SLW210 Posted March 7, 2017 Posted March 7, 2017 Since you seem to be requesting a LISP I moved your thread to the AutoLISP, Visual LISP & DCL Forum. Quote
grouch19 Posted March 7, 2017 Author Posted March 7, 2017 Hi eldon, Thanks for the suggestion. For this particular job I do need to insert a block. Cheers Quote
BIGAL Posted March 8, 2017 Posted March 8, 2017 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. Quote
BIGAL Posted March 8, 2017 Posted March 8, 2017 (edited) 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 March 8, 2017 by BIGAL Quote
grouch19 Posted March 9, 2017 Author Posted March 9, 2017 Hi BIGAL, 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. Cheers Quote
BIGAL Posted March 9, 2017 Posted March 9, 2017 Not sure whats going on this is your sample dwg posted did all of them 1 after another. Anbody else out there what might be wrong Quote
grouch19 Posted March 9, 2017 Author Posted March 9, 2017 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. Cheers Quote
BIGAL Posted March 9, 2017 Posted March 9, 2017 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. Quote
grouch19 Posted March 9, 2017 Author Posted March 9, 2017 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! Quote
BIGAL Posted March 10, 2017 Posted March 10, 2017 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-safearray->list (vlax-variant-value (vlax-get-property (vlax-ename->vla-object ent) "Coordinates" ) ) ) ) (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 Quote
grouch19 Posted March 10, 2017 Author Posted March 10, 2017 Thanks BIGAL I'll take a look when back in the office on Monday. Cheers Quote
Lee Mac Posted March 11, 2017 Posted March 11, 2017 (edited) Based on your sample drawing, here is my attempt: (defun c:insblk ( / blk cmd dwg ent enx idx lst scl sel ) (setq blk "Manhole") ;; Block Name (cond ( (not (or (tblsearch "block" blk) (and (setq dwg (findfile (strcat blk ".dwg"))) (progn (setq cmd (getvar 'cmdecho)) (setvar 'cmdecho 0) (command "_.-insert" dwg nil) (setvar 'cmdecho cmd) (tblsearch "block" blk) ) ) ) ) (princ (strcat "\nBlock \"" blk "\" not found or could not be defined.")) ) ( (setq sel (ssget "_:L" '((0 . "POLYLINE") (-4 . "&=") (70 . 8) (-4 . "<NOT") (-4 . "&=") (70 . 1) (-4 . "NOT>")))) (repeat (setq idx (sslength sel)) (setq ent (entnext (ssname sel (setq idx (1- idx)))) enx (entget ent) lst nil ) (while (= "VERTEX" (cdr (assoc 0 enx))) (setq lst (cons (cdr (assoc 10 enx)) lst) ent (entnext ent) enx (entget ent) ) ) (if (= 3 (length lst)) (progn (if (apply '< (setq scl (mapcar 'distance lst (cdr lst)))) (setq lst (reverse lst) scl (reverse scl) ) ) (if (minusp (sin (- (angle (car lst) (caddr lst)) (angle (car lst) (cadr lst))))) (setq lst (vl-list* (cadr lst) (car lst) (cddr lst))) ) (if (entmake (list '(000 . "INSERT") (cons 002 blk) (cons 010 (car lst)) (cons 041 (car scl)) (cons 042 (cadr scl)) (cons 050 (angle (car lst) (cadr lst))) ) ) (entdel (ssname sel idx)) ) ) ) ) ) ) (princ) ) Demo: Edited June 9 by Lee Mac Quote
Grrr Posted March 12, 2017 Posted March 12, 2017 Based on your sample drawing, here is my attempt: I think you mean here is the solution. Quote
Recommended Posts
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.