highrise_uk Posted October 16 Posted October 16 Hi LISP dons, Thanks for the help with my last thread, learning a lot and it's very much appreciated! Lots of knowledge on here. I'm sure an automatic layout builder is a very regular request, but I was keen to go through the different parts of what it needs to do and why/how, to help learn (and have something specific for my job haha). I usually use a mixture of DATAEXTRACT, Excel and Scripts to do this task, and it does the job just fine and relatively quickly (especially compared to doing it manually when there are many many layouts!) For example, there's a drawing with 36 layouts, and the viewport block on each as below: The basepoint of every block is bang in the centre. So when I do a DATAEXTRACT for the points, it's the middle and that enables me to write a script to put in all the text, and also automatically build all of the viewports with them in the right location and zoom amount. See below for the Excel/script examples Text: Layouts So this copies the template layout, selects the new layout, goes into the viewport and zooms into the centre of each block in turn. As said, this works perfectly well but is obviously a bit clunky and can be annoying if you have to re-do everything when things have moved in the drawing. I've basically done no real work today as I've been trying to make a smarter LISP setup which would do all of this on a single click of a block. The code below won't run but I've split the process up into all the parts I think are necessary. Some of them are already working but the real complicated stuff is still evading me. The main thing I'm struggling to get my head around is getting a list of each blocks co-ordinate and then having the process run for each of those individually. I've taken a few bits from other LISPS here and there, and tried to put them in the right order. I'm assuming there's ways to list the co-ords of every block, sort them, then run the process for as many blocks as there are in the drawing. I figure some combination of the variant and counter to keep updating a co-ordinate variant is what's needed but can't work out how to set that up. Also would be nice to maintain the 01 02 03 format instead of 1 2 3, but that is beyond me too haha. There are plenty of notes in the code so I probably don't need to explain any more what I want this to do. But I'm happy to clear things up for anyone willing to have a go See attached the DWG with blocks and the LISP/notes as they currently are. This is only my second real go at this so im sure there's loads of clunky nonsense in the file lol Thanks! AutoLayoutTest.dwg DW AUTOLAYOUT.lsp ;;; VIEWPORT UNLOCKER ; working! (setq clay (getvar "CLAYER")) (command "-VPORTS" "L" "OFF" "ALL" "") (setvar "CLAYER" clay) (princ) ) ;;;GET VP BLOCK NAME AND LAYER ; working! (setq blk (entsel "\nSelect viewport block: ") blkname (vla-get-effectivename (vlax-ename->vla-object (car blk))) blklayer (vla-get-layer (vlax-ename->vla-object (car blk))) ) ;;;SELECTION SET - ALL BLOCKS ON VP LAYER ; working! (setq ss_blk (ssget "_X" ;SELECT ALL (list (cons 8 blklayer) ;;LAYER FILTER (cons 2 blkname) ;;BLOCK NAME FILTER ) ) ) (sslength ss_blk) ;;;GET CO-ORDS OF BLOCKS (setq blk-coord (cdr blk)) ;;; shows co-ord of first selected block ;;;LIST CO-ORDS ;;;SORT CO-ORDS X small to big AND THEN Y big to small in list ;;; CHANGE CO-ORD PER CYCLE (setq vp-coord1 (???)) ;;;COUNTER (setq count 1) ;;WHILE (while (< count (sslength ss_blk)) ;do text insert and layout ;;;NUMBER TEXT INSERT ;working ! just need co-ords info from list (setq num-txt (rtos count 2 0)) ;;;counter value for text (command "-TEXT" "J" "M" ;;;TEXT POSITION MIDDLE vp-coord1 ;;; textLOCATION "100" ;TEXT SIZE "90" ;TEXT ANGLE num-txt) ;TEXT CONTENT 1 2 3.... (command "_chprop" "_last" "" "_layer" blklayer "") ;;;text to VP layer ;;; LAYOUT MAKER ;working ! (setq zoom 281) (setq lay0 (getstring "\nType in template layout name...")) (setq laynew (rtos count 2 0)) (command "_-LAYOUT" "C" lay0 laynew "_-LAYOUT" "s" laynew "MSPACE" "ZOOM" "C" vp-coord1 zoom "PSPACE" ) ) ;;; 1:500 ZOOM = 281 (maybe add scale choice as part of LISP) ;;; 1:1000 = 562 ;;; 1:250 = 140.5 ;;;COUNTER +1 (setq count (+ count 1)) ;;;ENDWHILE ;;; LOCK ALL VIEWPORTS ;working! (setq clay (getvar "CLAYER")) (command "-VPORTS" "L" "ON" "ALL" "") (setvar "CLAYER" clay) (princ) ) Quote
highrise_uk Posted October 16 Author Posted October 16 Too late to edit but ignore the Viewport locking bits at the start and finish... they weren't meant to be pasted in and also aren't complete/working. Quote
BIGAL Posted October 16 Posted October 16 (edited) There is lots of make layouts out there based on say a rectang and a scale. This is one of a couple of different ways. It has a enter scale and title block front end. Draw rectangs.mp4 Edited October 16 by BIGAL Quote
highrise_uk Posted October 21 Author Posted October 21 I managed to get this working better now, though im sure it's still kinda janky in many ways haha. DW AUTOLAYOUT reverse.lsp Added lines to ensure all numbers under 10 are represented as 01 02... Added a reverse counter for adding said numbers so that the first made entity is tagged 01 instead of the last number. One thing that I still can't get my head around is how to force the SelSet to order itself based on the co-ords of the objects. Very much enjoying learning this but a little nudge on how to organise the set by x/y position so that blocks inserted anywhere will number correctly left to right would be appreciated. Cheers Quote
BIGAL Posted October 21 Posted October 21 A couple of suggestions as your using a block to define the area of interest yes do a what scale required 1st, then insert the block using a scale. You read the scale so know what scale the mview needs to be, you can use "zoom c Point scale" to set the correct scale of the newly made Viewport. When using copy layout I use Template option so read from another dwg the correct layout size which has a viewport already made see image above. The ssget add (cons 410 "Model") if block is always in Model space. Saves finding the odd one in a layout. "set by x/y position" you can do a double sort on a list of block insertion points. Then number. ; sorts on 1st two items (vl-sort lst '(lambda (a b) (cond ((< (car a) (car b))) ((= (car a) (car b)) (< (cadr a) (cadr b))) ) ) ) Just a final comment I look for something similar it can have any rotation also, and a mix of sheet sizes and /or scales. Layouts are made to suit. 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.