Jump to content

Add to the code the ability to create layouts for non-standard formats


Recommended Posts

Posted (edited)

Hello everyone! There is a wonderful lisp AddLay.LSP. I've been using it for a few years now. 
It creates layouts standard A1, A2, and A3 formats...

Can anyone add to this code the ability to create layouts for non-standard formats (A4x3, A4x4, A3x3, A3x4, A2x3, A2x4...). 
So far, no one has been able to implement this. I would be very grateful. 
The code creates viewports for non-standard formats, but the formats need to be set manually.

The code works with polyline frames and dynamic frame blocks.
In the file dwg shows that a viewport is being created for a non-standard format, but the format is not being set.

List of non-standard formats:

  _A4x3_(297.00_x_630.00_MM)
  _A4x4_(297.00_x_841.00_MM)
  _A4x5_(297.00_x_1051.00_MM)

  _A3x3_(420.00_x_891.00_MM)
  _A3x4_(420.00_x_1189.00_MM)
  _A3x5_(420.00_x_1486.00_MM)

  _A2x3_(594.00_x_1261.00_MM)
  _A2x4_(594.00_x_1682.00_MM)
  _A2x5_(594.00_x_2102.00_MM)

 

;;; AddLayEn / Original AddLay Author: Andrey_13 / 08.2015 /
;;; Translation to English: 03.2025
;;; Creation of Layouts and Viewports based on frames in Model Space

(defun C:AL (/
		 ActiveDocument
		 Application
		 Display
		 DeleteLayouts
		 FirstSheet
		 Flag
		 Formats
		 i
		 j
		 Layout
		 Layouts
		 Layer
		 ModelSpace
		 NumberFormats
		 PaperSpace
		 Points
		 MatchSheet
		 MinPoint
		 MaxPoint
		 NoMatchSheet
		 Object
		 Point1
		 Point2
		 Point1x
		 Point1y
		 Point2x
		 Point2y
		 Scale
		 Square
		 ViewportHeight
		 ViewportWidth
		 Viewport
		 X
		 Y
		 )
  (vl-load-com) ; Load ActiveX functions
  (setvar "CTAB" "Model") ; Switch to Model tab
  (initget 6) 
  (setq Application (vlax-get-acad-object) ; Application object
	ActiveDocument (vla-get-ActiveDocument Application) ; Active document object
	ModelSpace (vla-get-ModelSpace ActiveDocument) ; Model space pointer
	Layouts (vla-get-Layouts ActiveDocument) ; Layouts collection
	Display (vla-get-Display (vla-get-Preferences Application)) ; Display preferences
	)

  ;;; Prompt for the layer containing frames by selecting an object
  (while (null Object)
    (setq Object (car (entsel "
Select an object to define the frames layer: ")))
    )
  (setq Layer (cdr (assoc 8 (entget Object))) ; Determine layer name
	Formats (ssget (list (cons 8 Layer))) ; Select all objects on that layer
	NumberFormats (sslength Formats) ; Count number of frames
	Scale (getreal "
Enter scale 1:<1>: ") ; Request scale
	i 0
	Points ()
	)
  (if (not Scale) (setq Scale 1))

  (repeat NumberFormats
    (setq Format (vlax-ename->vla-object (ssname Formats i)))
    (if
      (and (= (vla-get-ObjectName Format) "AcDbBlockReference") (= (vla-get-IsDynamicBlock Format) :vlax-true)) ; Check if dynamic block
      (progn
	(setq Points (append Points (list (GetBoundingBox_dynblock (vlax-vla-object->ename Format))))) ; Get points for dynamic block
	(setq i (1+ i))
	)
      (progn
	(vla-GetBoundingBox Format 'MinPoint 'MaxPoint) ; Get points for regular object
	(setq
	  Points (append Points (list (list (vlax-safearray->list MinPoint) (vlax-safearray->list MaxPoint))))
	  i (1+ i)
	  )
	)
      )
    )

  ;;; Determine sorting order for the points
  (setq i 0)
  (repeat (length Points) ; Build lists of X and Y coordinates
    (setq X (append X (list (caar (nth i Points)))))
    (setq Y (append Y (list (cadar (nth i Points)))))
    (setq i (1+ i))
    )
  (if
    (> (- (MaxElement X) (MinElement X)) (- (MaxElement Y) (MinElement Y))) ; Decide sorting axis
    (setq Points (vl-sort Points (function (lambda (P1 P2) (< (caar P1) (caar P2)))))) ; Sort by X
    (setq Points (vl-sort Points (function (lambda (P1 P2) (> (cadar P1) (cadar P2)))))) ; Sort by Y
    )

  ;;; Disable automatic viewport creation on new layouts
  (if
    (= (vla-get-LayoutCreateViewport Display) :vlax-true)
    (progn
      (vla-put-LayoutCreateViewport Display :vlax-false)
      (setq Flag T)
      )
    )

  ;;; Layout management
  (initget 1 "Yes No")
  (setq DeleteLayouts (getkword "
Delete existing layouts? [Yes/No]: "))
  (cond
    (
     (= DeleteLayouts "Yes")
     ;;; Delete all layouts except Model
     (vlax-for Layout Layouts
       (if
	 (/= (vla-get-Name Layout) "Model")
	 (vla-delete Layout)
	 )
       )
     (initget 6)
     (setq FirstSheet (getint "
Starting sheet number: "))
     (vla-put-Name (vla-Item Layouts 1) (itoa FirstSheet)) ; Rename the default remaining layout
     )    
    ;;; Handle existing layouts if not deleting
    (
     (= DeleteLayouts "No")
     (while (= NoMatchSheet nil)
       (progn
	 (initget 6)
	 (setq
	   i 0
	   FirstSheet (getint "
Starting sheet number: ")
	   MatchSheet nil
	   )
	 (repeat NumberFormats
	   (if
	     (not (null (member (itoa (+ FirstSheet i)) (layoutlist))))
	     (setq MatchSheet T)
	     )
	   (setq i (1+ i))
	   )
	 (if
	   (= MatchSheet T)
	   (alert "Error: Layout names already exist!")
	   (setq NoMatchSheet T)
	   )
	 )
       )
     )
    )

  ;;; Insert new layouts and create viewports
  (setq i 0 j 0)
  (repeat NumberFormats
    (cond
      ;;; Workflow if layouts were deleted
      (
       (= DeleteLayouts "Yes")
       (if
	 (= i 0)
	 (progn
	   (setq Layout (vla-item Layouts 0))
	   (setvar "CTAB" (itoa FirstSheet))
	   )
	 (progn
	   (setq Layout (vla-Add Layouts (itoa (+ FirstSheet i))))
	   (setvar "CTAB" (itoa (+ FirstSheet i)))
	   )
	 )
       )
      ;;; Workflow if adding to existing layouts
      (
       (= DeleteLayouts "No")
       (progn
	 (setq Layout (vla-Add Layouts (itoa (+ FirstSheet i))))
	 (setvar "CTAB" (itoa (+ FirstSheet i)))
	 )
       )
      )

    ;;; Viewport creation logic
    (setq Point1 (car (nth j Points))
	  Point2 (cadr (nth j Points))
	  PaperSpace (vla-get-paperspace ActiveDocument)
	  Point1x (car Point1)
	  Point1y (cadr Point1)
	  Point2x (car Point2)
	  Point2y (cadr Point2)
	  ViewportHeight (/ (abs (- Point1y Point2y)) Scale)
	  ViewportWidth (/ (abs (- Point1x Point2x)) Scale)
	  Viewport (vla-AddPViewport PaperSpace (vlax-3d-point (list (/ ViewportWidth 2) (/ ViewportHeight 2))) ViewportWidth ViewportHeight))
    
    (vla-display Viewport :vlax-true)
    (vla-put-mspace ActiveDocument :vlax-true) ; Activate model space inside viewport
    (vla-zoomcenter Application (vlax-3d-point (list (/ (+ Point1x Point2x) 2) (/ (+ Point1y Point2y) 2))) 1.0)
    (vla-put-mspace ActiveDocument :vlax-false) ; Deactivate model space
    (vla-put-standardscale Viewport acVpCustomScale)
    (vla-put-CustomScale Viewport (/ 1.0 Scale))
    (vla-put-DisplayLocked Viewport :vlax-true) ; Lock viewport

    ;;; Page Setup
    (vla-put-StyleSheet Layout "monochrome.ctb")
    (vla-put-PlotType Layout 5) ; Set plot area to "Layout"

    ;;; Determine Paper Size based on viewport area (Square)
    (setq Square (* ViewportHeight ViewportWidth))
    (cond
      ((and (> Square 59251) (< Square 65488)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_A4_(297.00_x_210.00_MM)"))
      ((and (> Square 118503) (< Square 130977)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_A3_(420.00_x_297.00_MM)"))
      ((and (> Square 237006) (< Square 261954)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_A2_(594.00_x_420.00_MM)"))
      ((and (> Square 474012) (< Square 523908)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_A1_(841.00_x_594.00_MM)"))
      ((and (> Square 948024) (< Square 1047816)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_A0_(841.00_x_1189.00_MM)"))
      (T (vla-put-ConfigName Layout "None")) ; Default to No plotter for non-standard sizes
      )
    
    (if (> ViewportHeight ViewportWidth) (vla-put-PlotRotation Layout 1) (vla-put-PlotRotation Layout 0)) ; Orientation
    (command "_Zoom" "_All")
    (setq i (1+ i) j (1+ j))
    )

  ;;; Restore "Automatic Viewport Creation" setting if it was originally ON
  (if (= Flag T) (vla-put-LayoutCreateViewport Display :vlax-true))
  (setvar "CTAB" "Model") ; Return to Model tab
  (princ "
Creation of layouts completed.")
  (princ)
  )

;;; Find minimum element in list
(defun MinElement (X /) (car (vl-sort X '<)))

;;; Find maximum element in list
(defun MaxElement (X /) (car (vl-sort X '>)))

;;; Get correct Bounding Box for Dynamic Blocks
(defun GetBoundingBox_dynblock (ent / lst ins_pt min_point max_point 3d_polarp)
  (if
    (and (or ent
	     (= (type (setq ent (vl-catch-all-apply (function (lambda () (car (entsel "
Select Dynamic Block: "))))))) 'ename)
	     )
	 (setq ent (vlax-ename->vla-object ent))
	 (vlax-property-available-p ent 'isdynamicblock)
	 (equal (vla-get-isdynamicblock ent) :vlax-true)
	 )
    (progn
      (vlax-for item
		(vla-item
		  (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
		  (vla-get-name ent)
		  )
		(if (equal (vla-get-visible item) :vlax-true)
		  (setq lst (cons item lst))
		  )
		)
      (setq
	ins_pt (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint ent)))
	lst (vl-remove nil
		       (mapcar
			 '(lambda (x / minp maxp)
			    (if (not (vl-catch-all-error-p (vl-catch-all-apply (function (lambda () (vla-getboundingbox x 'minp 'maxp))))))
			      (list (cons "min" (vlax-safearray->list minp)) (cons "max" (vlax-safearray->list maxp)))
			      )
			    )
			 lst
			 )
		       )
	lst (mapcar
	      '(lambda (mins)
		 (mapcar
		   '(lambda (fun)
		      (apply (read mins)
			     (mapcar (function fun)
				     (mapcar '(lambda (pts) (cdr (assoc mins pts))) lst)
				     )
			     )
		      )
		   (list car cadr caddr)
		   )
		 )
	      (list "min" "max")
	      )
	lst (mapcar
	      '(lambda (ept)
		 (mapcar
		   '(lambda (coord_pt coord_line coord_ins)
		      (+ (* coord_pt ((eval (read (strcat "vla-get-" coord_line "EffectiveScaleFactor"))) ent)) coord_ins)
		      )
		   ept
		   '("X" "Y" "Z")
		   ins_pt
		   )
		 )
	      lst
	      )
	)
      )
    )
  )

 

AL.dwg     WP.png

Edited by Nikon
Posted

@Nikon

 

While I don't know this routine, and don't recognize the Paper Sizes you have specified. The change would have to do with this section I think (see below). I added a couple condition lines for standard layouts "ISO full bleed 2A0" and "ISO full bleed 4A0" that are in my standard "DWG to PDF.PC3" file. I don't know what determines the area of the viewports though, (it seems that it is an object you select), so I am guessing at the area range of the viewport sizes.

 

(cond
   ((and (> Square 59251)   (< Square   65488)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout    "ISO_full_bleed_A4_(297.00_x_210.00_MM)"))
   ((and (> Square 118503)  (< Square  130977)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout    "ISO_full_bleed_A3_(420.00_x_297.00_MM)"))
   ((and (> Square 237006)  (< Square  261954)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout    "ISO_full_bleed_A2_(594.00_x_420.00_MM)"))
   ((and (> Square 474012)  (< Square  523908)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout    "ISO_full_bleed_A1_(841.00_x_594.00_MM)"))
   ((and (> Square 948024)  (< Square 1047816)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout   "ISO_full_bleed_A0_(841.00_x_1189.00_MM)"))
   ((and (> Square 1949898) (< Square 2049898)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_2A0_(1189.00_x_1682.00_MM)"))
   ((and (> Square 3949796) (< Square 4049796)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_4A0_(1682.00_x_2378.00_MM)"))
   (T (vla-put-ConfigName Layout "None")) ; Default to No plotter for non-standard sizes
)

 

  • Thanks 1
Posted (edited)
1 hour ago, pkenewell said:
((and (> Square 1949898) (< Square 2049898)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_2A0_(1189.00_x_1682.00_MM)"))
   ((and (> Square 3949796) (< Square 4049796)) (vla-put-ConfigName Layout "DWG To PDF.pc3") (vla-put-CanonicalMediaName Layout "ISO_full_bleed_4A0_(1682.00_x_2378.00_MM)"))

I don't use such formats:
"ISO_full_bleed_2A0_(1189.00_x_1682.00_MM)"
"ISO_full_bleed_4A0_(1682.00_x_2378.00_MM)"

The sizes of the formats are listed in the list
"List of non-standard formats".

I don't understand how to get these numbers:

 (> Square 59251)   (< Square   65488
 (> Square 118503)  (< Square  130977)

and how will they help you create a non-standard layout?

 

Edited by Nikon
Posted (edited)
39 minutes ago, Nikon said:

and how will they help you create a non-standard layout?

 

The condition lines I added were just examples of how to add more sizes. As long as you know the areas and the name of the paper size, you should be able to add them.

The "Square" variable as i understand it, is the min and max AREA of the frame you select (Length x Width), for the condition to select the paper size. This depends on what you are selecting for the frame to define the paper size. How would I know, if I don't have an example of what you are selecting?

Edited by pkenewell
  • Thanks 1
Posted
5 minutes ago, pkenewell said:

How would I know, if I don't have an example of what you are selecting?

I have attached a dwg example.

Posted (edited)
10 hours ago, Nikon said:

List of non-standard formats:

  _A4x3_(297.00_x_630.00_MM)
  _A4x4_(297.00_x_841.00_MM)
  _A4x5_(297.00_x_1051.00_MM)

  _A3x3_(420.00_x_891.00_MM)
  _A3x4_(420.00_x_1189.00_MM)
  _A3x5_(420.00_x_1486.00_MM)

  _A2x3_(594.00_x_1261.00_MM)
  _A2x4_(594.00_x_1682.00_MM)
  _A2x5_(594.00_x_2102.00_MM)

Are these the actual names of the Paper sizes in the pc3 file?

 

The squares in your example file are just the paper sizes. You need to know the Frame layer, and the size range of the Frames that create your viewports. In any case - you should have all the information you need to do it yourself. as I said in the above to lay it out more clearly:

 

1) You need a range of AREA to be within on the frames. For example, on your "A4x3", (297 x 630) = 187110. Your range for the "square" variable should be a min and max with this value in the middle, such as 187110 - 10000 = 177110 "(> Square 177110)" and 187110 + 10000 = 197110 "(< Square 197110)"

 

2) each added condition should have the exact name of the Custom paper size:

((and (> Square 177110) (< Square 197110))(vla-put-ConfigName Layout "DWG To PDF.pc3")(vla-put-CanonicalMediaName Layout "_A4x3_(297.00_x_630.00_MM)"))

 

ALSO:

3) You must have a unique Layer for the Frame polylines or blocks, something like "MyPaperSizeFrameLayer", or anything, as long as it is unique to the frames.

Edited by pkenewell
  • Thanks 1
Posted
18 minutes ago, pkenewell said:

3) You must have a unique Layer for the Frame polylines or blocks, something like "MyPaperSizeFrameLayer", or anything, as long as it is unique to the frames.

It is enough that the frames are just on one layer.

I will try to add squares and formats to the code, but it seems to me that a different approach 
is needed for non-standard formats.
 

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