Add Image Viewport

Add Image Viewport

adaptacad
Advocate Advocate
1,754 Views
5 Replies
Message 1 of 6

Add Image Viewport

adaptacad
Advocate
Advocate

Hello guys, can anyone give me a hand?

How do I edit the program to add a new viewport and crop and insert into the viewport the AutoCAD geolocation image.
Image example!
I tried to make some modifications to the code, but due to the little knowledge, I was unsuccessful!
any help is good life.
And thank you in advance !!

image.PNG

 

;;LINK
;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/looking-for-a-lisp-routine-to-create-automulti-layouts-and/td-p/8539246
(defun GridsToLayouts
       
       (
	
	UseUndoMarks
	
	/	
	GridLayer
	GridAttribute
	SourceLayout
	TitleBlockHeight
	KeyZoomFactor	
	TitleBlockName
	TitleBlockSheetNumberAttribute
	TitleBlockTotalSheetsAttribute
	vl-GetAttributeValue
	ss
	i
	enam
	edata
	grids
	grid
	id
	previd
	ssvp1
	vp1
	vpno1
	ssvp2
	vp2
	vbno2
	ptmin
	ptmax
	
	)

  ;;;*SOME SETTINGS THAT CAN BE CUSTOMIZED
  (setq GridLayer                        "Layer1")
  (setq GridAttribute                    "number")
  (setq SourceLayout                     "001")
  (setq TitleBlockHeight                 80)
  (setq KeyZoomFactor                    0.33)
  ;(setq TitleBlockName                   "XXX_2")
  ;(setq TitleBlockSheetNumberAttribute   "SHEET_NO")
  ;(setq TitleBlockTotalSheetsAttribute   "NO_OF_SHEETS")

  (defun vl-GetAttributeValue ( blk tag )
    (setq tag (strcase tag))
    (vl-some '(lambda ( att ) (if (= tag (strcase (vla-get-tagstring att))) (vla-get-textstring att)))
        (vlax-invoke blk 'getattributes)
    )
  )
 
  (cond
   ((not (setq ss (ssget "x" (list (cons 0 "INSERT") (cons 8 GridLayer)))))
    (princ (strcat "\nNo grid blocks on layer '" GridLayer "' found."))
   )
   ((not (member SourceLayout (layoutlist)))
    (princ (strcat "\nSource layout '" SourceLayout "' not found."))
   )
   ((> (length (layoutlist)) 1)
    (princ (strcat "\nOnly layouts 'Model' and '" SourceLayout "' should exist."))
   )
   (T
    (Vl-cmdf "_.IsolateObjects" ss "")
    (setq i 0)
    (while (< i (sslength ss))
	  (setq edata (entget (setq enam (ssname ss i))))
      (if (and
            (= (cdr (assoc 0 edata)) "INSERT")
            (setq attval (vl-GetAttributeValue (vlax-ename->vla-object (cdr (assoc -1 edata))) GridAttribute))
          )
        (setq grids (cons (cons attval enam) grids))
      )
      (setq i (1+ i))
    )
    (setq grids (vl-sort grids (function (lambda (e1 e2) (< (car e1) (car e2))))))

    
    (if UseUndoMarks (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object))))
    (if grids
      (princ "\nCreating layouts...")
      (princ "\nNo grids found...")
    )
    (foreach grid grids
      (if grids
        (progn
          (setq id (car grid) enam (cdr grid))
          (princ (strcat "\n layout '" id "'... "))
          (if (not (member id (layoutlist)))
            (command "._layout" "c" previd id)
          )
          (command "._layout" "s" id "._pspace")
          (if (and
                (setq ssvp1 (ssget "x" (list (cons 0 "VIEWPORT") (cons -4 "*,>,*") (list 10 0 TitleBlockHeight 0))))
                (setq ssvp2 (ssget "x" (list (cons 0 "VIEWPORT") (cons -4 "*,<,*") (list 10 0 TitleBlockHeight 0))))
		
		
		
		(setq ssvp3 (ssget "x" (list (cons 0 "VIEWPORT") (cons -4 "*,<,*") (list 10 0 TitleBlockHeight 0)))) ;;;; I edited here
		
              )
            (progn
              (vla-getboundingbox (vlax-ename->vla-object enam) 'ptmin 'ptmax)
              (setq vpno1 (cdr (assoc 69 (entget (setq vp1 (ssname ssvp1 0))))))
              (setq vpno2 (cdr (assoc 69 (entget (setq vp2 (ssname ssvp2 0))))))
	      
	      (setq vpno3 (cdr (assoc 69 (entget (setq vp3 (ssname ssvp3 0))))));;;; I edited here
	      
              (command "._mspace")
              (setvar "CVPORT" vpno1)
              (vla-zoomwindow (vlax-get-acad-object) ptmin ptmax)
              (setvar "CVPORT" vpno2)
              (vla-zoomwindow (vlax-get-acad-object) ptmin ptmax)
	      
	      (setvar "CVPORT" vpno3) ;;;; I edited here
              (vla-zoomwindow (vlax-get-acad-object) ptmin ptmax);;;; I edited here
	      (vl-cmdf "_.geomapimage" ptmin ptmax);;;; I edited here
	      
	      
              (vla-zoomscaled (vlax-get-acad-object) KeyZoomFactor acZoomScaledRelative)
              (command "._pspace")
              (vla-zoomextents (vlax-get-acad-object))
            )
            (princ (strcat "\nUnable to find the two vieports needed for layout " id))
          )
          (setq previd id)
          (if (= (length (layoutlist)) 255)
            (progn
              (princ "\nMaximum number of layouts met.")
              (setq grids nil)
            )
          )
          (vla-eval (vlax-get-acad-object) "DoEvents")
        )       
      )
    )
    (princ "\... GridsToLayouts finished.")
    (if UseUndoMarks (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object))))
    (vl-cmdf "_.UnIsolateObjects")
   )

  )
)

(defun C:GridsToLayouts nil (GridsToLayouts T) (princ))
;;;;(C:GridsToLayouts)

 

0 Likes
Accepted solutions (2)
1,755 Views
5 Replies
Replies (5)
Message 2 of 6

CodeDing
Advisor
Advisor
Accepted solution

@adaptacad ,

 

You have a good amount of work left to finish this, but here's a start..

- Your "GridAttribute" is incorrect for the drawing you provided

- In the dwg you provided, not all blocks are on the same layer...

- you must UNLOCK (not included in code) the lower-right VP to scale its zoom level

- You will need to adjust your GEOMAP Image layer, and any necessary VPFreeze layers otherwise the maps will appear in every VP...

 

NOTE: The ONLY way to edit GepMap Image properties, is if you acquire the entity name via (entlast)... There is no other way with AutoLISP.

 

Here's the updated, slightly cleaner code:

;;LINK
;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/looking-for-a-lisp-routine-to-create-automulti-layouts-and/td-p/8539246
(defun GridsToLayouts (UseUndoMarks
		       /	
		       GridLayer GridAttribute SourceLayout
		       TitleBlockHeight KeyZoomFactor TitleBlockName
		       TitleBlockSheetNumberAttribute TitleBlockTotalSheetsAttribute
		       vl-GetAttributeValue ss i enam edata
		       grids grid id previd
		       ssvp1 vp1 vpno1 ssvp2 vp2 vpno2 ssvp3 vp3 vpno3 vpMapEnt
		       ptmin ptmax
		      )
;;;CUSTOM SETTINGS
(setq GridLayer "Layer1"
      GridAttribute "NUMERO_PRANCHA")
(setq SourceLayout "001"
      TitleBlockHeight 80
      KeyZoomFactor 0.33)
;(setq TitleBlockName "XXX_2"
;      TitleBlockSheetNumberAttribute "SHEET_NO"
;      TitleBlockTotalSheetsAttribute "NO_OF_SHEETS")
;;;HELPER FUNCTION(S)
  (defun vl-GetAttributeValue ( blk tag )
    (setq tag (strcase tag))
    (vl-some '(lambda ( att ) (if (= tag (strcase (vla-get-tagstring att))) (vla-get-textstring att)))
        (vlax-invoke blk 'getattributes)
    );vl-some
  );defun
;;;INITIAL TESTS / WORK
(cond
  ((not (setq ss (ssget "x" (list (cons 0 "INSERT") (cons 8 GridLayer)))))
    (princ (strcat "\nNo grid blocks on layer '" GridLayer "' found."))
  );cond 1
  ((not (member SourceLayout (layoutlist)))
    (princ (strcat "\nSource layout '" SourceLayout "' not found."))
  );cond 2
  ((> (length (layoutlist)) 1)
    (princ (strcat "\nOnly layouts 'Model' and '" SourceLayout "' should exist."))
  );cond 3
  (T
    ;isolate grids, then save with grid #s, sort grids
    (Vl-cmdf "_.IsolateObjects" ss "")
    (repeat (setq i (sslength ss))
	  (setq edata (entget (setq enam (ssname ss (setq i (1- i))))))
      (if (and (= (cdr (assoc 0 edata)) "INSERT")
	       (setq attval (vl-GetAttributeValue (vlax-ename->vla-object (cdr (assoc -1 edata))) GridAttribute))
          );and
        (setq grids (cons (cons attval enam) grids))
      );if
    );repeat
    (setq grids (vl-sort grids (function (lambda (e1 e2) (< (car e1) (car e2))))))
    ;set undo if relevant, update user
    (if UseUndoMarks (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object))))
    (if grids
      (princ "\nCreating layouts...")
      (princ "\nNo grids found...")
    );if
    ;create layouts
    (foreach grid grids
      (setq id (car grid) enam (cdr grid))
      (princ (strcat "\n layout '" id "'... "))
      ;copy layout if necessary
      (if (not (member id (layoutlist)))
        (command "._layout" "c" previd id)
      );if
      (command "._layout" "s" id "._pspace")
      ;get all 3 VPs in layout
;This section MAY cause trouble in the future, since it No Longer uses the 'TitleBlockHeight' variable. (if (and (setq ssvp1 (ssget "x" (list (cons 0 "VIEWPORT") (cons -4 "<,>,*") (list 10 600 0 0)))) (setq ssvp2 (ssget "x" (list (cons 0 "VIEWPORT") (cons -4 ">,<,*") (list 10 600 250 0)))) (setq ssvp3 (ssget "x" (list (cons 0 "VIEWPORT") (cons -4 ">,>,*") (list 10 600 250 0)))) );and (progn ;zoom to appropriate areas & set items for VPs (vla-getboundingbox (vlax-ename->vla-object enam) 'ptmin 'ptmax) (setq vpno1 (cdr (assoc 69 (entget (setq vp1 (ssname ssvp1 0)))))) (setq vpno2 (cdr (assoc 69 (entget (setq vp2 (ssname ssvp2 0)))))) (setq vpno3 (cdr (assoc 69 (entget (setq vp3 (ssname ssvp3 0)))))) (command "._mspace") (setvar "CVPORT" vpno1) (vla-zoomwindow (vlax-get-acad-object) ptmin ptmax) (setvar "CVPORT" vpno2) (vla-zoomwindow (vlax-get-acad-object) ptmin ptmax) (vla-zoomscaled (vlax-get-acad-object) KeyZoomFactor acZoomScaledRelative) (setvar "CVPORT" vpno3) (vla-zoomwindow (vlax-get-acad-object) ptmin ptmax) (vl-cmdf "_.geomap" "a" "_.geomapimage" "v" "_.geomap" "o") (setq vpMapEnt (entlast));<<---this is the ONLY way to acquire a GEOMAP Image entity name (by using entlast) (use 'setpropertyvalue')
;Dump: (dumpallproperties vpMapEnt)
;Example: (setpropertyvalue vpMapEnt "Resolution" 2) (command "._pspace") (vla-zoomextents (vlax-get-acad-object)) );progn ;else (princ (strcat "\nUnable to find the two vieports needed for layout " id)) );if (setq previd id) (if (= (length (layoutlist)) 255) (setq grids (princ "\nMaximum number of layouts met.")) );if (vla-eval (vlax-get-acad-object) "DoEvents") );foreach );cond T );cond (princ "\... GridsToLayouts finished.") (if UseUndoMarks (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))) (vl-cmdf "_.UnIsolateObjects") );defun (defun C:GridsToLayouts nil (GridsToLayouts T) (princ)) ;;;;(C:GridsToLayouts)

Best,

~DD

0 Likes
Message 3 of 6

adaptacad
Advocate
Advocate

Thanks for the feedback!!
Almost, but not working!
Everything is in just one layout and is working in just a few.

 

Cap.JPG

0 Likes
Message 4 of 6

CodeDing
Advisor
Advisor
Accepted solution

@adaptacad ,

 

The Main reason why your test is not creating more than one layout.. is because your block in model space with the attribute "001" is not included in your selection set...

You can set all blocks in Model Space to the same layer, "Layer1", and that will solve your current problem..

But you should also include a way to incorporate this check into your code..

There are so many unknown variables for me to correct your entire code...

 

I will never know if every map will have these same blocks.. what layers will change.. if they will be on separate layers.. what the attribute number will always begin with/end with.. if the map is always Geo-Located.. whether the blocks will always fall within the extents of the geolocation map... etc.. etc...

 

There are just so many questions that unless I know your entire purpose, I cannot code it correctly for you. You will need to learn how to TROUBLESHOOT and fix these things as they arise for you.

 

So for your current issue.. to troubleshoot.. since your one layout was not being copied.. We need to ask WHY it wasn't being copied? Well, there's only one place in our code that copies a layout:

      ;copy layout if necessary
      (if (not (member id (layoutlist)))
        (command "._layout" "c" previd id)
      );if
      (command "._layout" "s" id "._pspace")

...So it looks like we need to know what "id" is being checked as a member of the layoutlist.

...Since NONE of your IDs will ever be "001" (since that block is currently not on "Layer1"), the code will CONTINUOUSLY check for "previd" to copy from.. Well, since "previd" has not been declared anywhere in our code up to this first check, we can include a fail-safe declaration before we run our check..

      ;copy layout if necessary
      (if (not previd) (setq previd "001"))
      (if (not (member id (layoutlist)))
        (command "._layout" "c" previd id)
      );if
      (command "._layout" "s" id "._pspace")

...Now, this will solve our copy issue, but it creates another... Since our FIRST id is Not "001", but we already have a "001" layout named, what will happen with our "001" layout? ...Nothing.. Absolutely nothing.

...So now you must determine if the "001" layout is even necessary? OR if including the "001" attributed block is necessary? And you will need to make necessary adjustments to your code... and so-on and so-forth...

 

In conclusion, you must learn to troubleshoot your problems and you must understand how your code works. Because if you just grab a "working" piece of code for somebody else, and try to make it work for you without understanding WHY or HOW it was made, then you will be creating a lot of headache for yourself.. And that is where the community can come in handy to help you fix your Troubleshooting problems.. But we cannot solve ALL of your problems as we may never fully understand the context of your code or your desired outcome...

 

Whew, ok I'm done. I will be here for your questions, but please be sure you are doing most of your own troubleshooting and not relying solely on the community to resolve this program for you.

 

Best,

~DD

 

Message 5 of 6

adaptacad
Advocate
Advocate
Angry!!! you are very good !! I understood your line of reasoning well. Perfect thank you !!
 
Any suggestions on how to best handle this?
0 Likes
Message 6 of 6

CodeDing
Advisor
Advisor

@adaptacad ,

 

Sorry, I'm not angry. But it can be a bit frustrating when users ask for fix after fix after fix without any troubleshooting on their own. This is why I wanted to make it clear that If You put in effort, then I will also. The community is not intended to serve a one-way relationship for users who only want to benefit without any work of their own.

 

I am not trying to say that you are not doing work on your won, but it is evident that you have taken on a task that is probably too much for you at your current level. We have all been there before.

 

What I recommend for you is that you maybe don't take on such a large task all at once.. Break this task down into pieces then complete those pieces one at a time. This will help you work toward a goal and learn things along the way.

 

Best,

~DD

0 Likes