• This forum is the machine-generated translation of www.cad3d.it/forum1 - the Italian design community. Several terms are not translated correctly.

coordinate viewport in lisp

  • Thread starter Thread starter Cristallo
  • Start date Start date

Cristallo

Guest
in a drawing I have several layouts
I get the list by (setq layouts (layoutlist))
I order them by (setq layouts (acad_strlsort layouts))

then for each I try to get the info of the viewport (I have only 1 for each layout) - we say I look for the viewport of the layout 1002
(setq p (ssget "x" (cons 0 "viewport") (cons 410 "1002"))))
(setq view0 (entget (sname p 0)))

I get the viewport entity list on that particular layout and try to figure out what the extremes of the view, but I can't. I know that group 10 is the center of viewport, but I need angles (the display box to understand), to be able to select the entities of viewport in the model.
Can some gurus tell me?
 
uno tra i metodi se la finestra è rettangolare :

selezionare the window nel layout
(setq flay (vlax-ename->vla-object))

trovare il bounding box della finestra (p1 e p2)
(vla-getboundingbox flay 'p1* 'p2*')
(setq p1 (vlax-safearray->list p1*))
(setq p2 (vlax-safearray->list p2*))
(setq p1 (list (car p1) (cadr p1))
(setq p2 (list (car p2) (cadr p2))

trasforma le coordinate da layout a modello
(setq p1 (trans p1 3 2)
(setq p2 (trans p2 3 2))
 
oppure
(vlax-get-property vlaobj "center") punto central
(vlax-get-property vlaobj "width") larghezza
(vlax-get-property vlaobj "height") altezza
 
or
if ent is the list of viewport entities
(cdr (assoc 10 ent) central point
(cdr (assoc 40 ent) width
(cdr (assoc 41 ent) height
 
first tests:
with the method of rpor, through belly, width and height I arrive at the same identical coordinates of the bounding box of gp, but I have to do 3-4 steps to get there, so I prefer the solution of gp much more immediate.

The big problem I'm finding is on the trans
1) returns a value only if the current display is on the layout. if they are in the model returns nil.
2) there is a translation between the points out from trans and those that instead would be correct. It is a pure translation because if I draw a line (in the model) between the two points of the bounding box, the line perfectly covers the size of the window but translating a tot (which I don't understand what is tied to).

I attach both the fragment of the two codics (gp solution - rpor solution), and an extract of the dwg file so that I can verify my difficulties.
Code:
  (setq layouts (layoutlist))
  (setq layouts (acad_strlsort layouts))
  (setq ad (getvar "dwgprefix"))
  (setq layfol (strcat ad "layouts"))
  (vl-mkdir layfol)
 
  (setq layoutnumber (length layouts))
  (setq count 0)
    (setq layout (nth 0 layouts))
    (setq vp (ssget "x" (list (cons 0 "viewport")(cons 410 layout))))
;;;;*********inizio codice gp***********
       (setq flay (vlax-ename->vla-object (ssname vp 0)))
        (vla-getboundingbox flay 'p1* 'p2*)
        (setq p1 (vlax-safearray->list p1*))
        (setq p2 (vlax-safearray->list p2*))
        (setq p3 (list (car p1) (cadr p1)))
        (setq p4 (list (car p2) (cadr p2)))
        (setq p5 (trans p3 3 2))
        (setq p6 (trans p4 3 2))
;;;;;*********fine codice gp*************
    (setq oldosmode (getvar "osmode"))
    (setvar "osmode" 0)
    (command "_line" p5 p6 "")
Code:
;;***codice rpor*************
 (setq centro (vlax-safearray->list (vlax-variant-value (vlax-get-property flay "center"))))
 (setq larghezza (vlax-get-property flay "width"))
 (setq altezza (vlax-get-property flay "height"))
 (setq p01x (- (nth 0 centro)(/ larghezza 2)))
 (setq p01y (- (nth 1 centro)(/ altezza 2)))
 (setq p01 (list p01x p01y (nth 2 centro)))
;;;****codice rpor*****************
 

Attachments

Code:
 (setq layouts (layoutlist))
  (setq layouts (acad_strlsort layouts))
  (setq ad (getvar "dwgprefix"))
  (setq layfol (strcat ad "layouts"))
  (vl-mkdir layfol)
 
  (setq layoutnumber (length layouts))
  (setq count 0)
    (setq layout (nth 0 layouts))
    (setq vp (ssget "x" (list (cons 0 "viewport")(cons 410 layout))))
    (setvar "clayout" layout) ;<====== rendi corrente il layout
;;;;*********inizio codice gp***********
       (setq flay (vlax-ename->vla-object (ssname vp 0)))
        (vla-getboundingbox flay 'p1* 'p2*)
        (setq p1 (vlax-safearray->list p1*))
        (setq p2 (vlax-safearray->list p2*))
        (setq p3 (list (car p1) (cadr p1)))
        (setq p4 (list (car p2) (cadr p2)))
        (setq p5 (trans p3 3 2))
        (setq p6 (trans p4 3 2))
;;;;;*********fine codice gp*************
    (setvar "clayout" "model") ;<===== rendi corrente model
    (setq oldosmode (getvar "osmode"))
    (setvar "osmode" 0)
    (command "_line" p5 p6 "")
 
Last edited by a moderator:
The big problem I'm finding is on the trans
1) returns a value only if the current display is on the layout. if they are in the model returns nil.
because code 3 refers to the dcs of the paper space, if you are not in the layout you cannot calculate the coordinates.
 
because code 3 refers to the dcs of the paper space, if you are not in the layout you cannot calculate the coordinates.
I understood this, but when I make him trans from paper space, he returns me values that are not the exact ones. There is a 950 translation unit (of both points, identically), as if there was something I can't identify.
the exact gap is this:
delta x = 920.4609, delta y = -258.0204, delta z = 0.0000
 
Last edited:
in the viewport list there is the sublist (17 920.46 -258.024 30.4836) which is your scaffolding, do not ask me why, I never happened, sum the values to the calculated coordinates and fix everything.
making copy/paste of your dwg the problem recreates, creating a new dwg, pasting your (only model) and inserting the viewport, the problem disappears.
I'll investigate.
bye
 
sublist 17 is the equivalent of the .target property of the viewport object.
x y z sum values regardless of p5 and p6 points.
 
sublist 17 is the equivalent of the .target property of the viewport object.
x y z sum values regardless of p5 and p6 points.
perfect rpor.
group 17 is the value of the target variable of autocad. variable read-only, zero only by means of
Code:
(fun c:reset_target () (command "_.dview" "" "_po" '(0 0 0) '(0 0 1) "_x")
in all cases your method works by adding coordinates.
the method to sum regardless of the coordinates works anyway, because even when the target value is not set, the group seems to be always present in the viewport list.
 
I don't know if I can help, because I refer to a code I wrote a long time ago, it's not lisp, but I know that I solved my pointing problems in the dxf parser by looking at the group code 71.
If you don't find it, or I don't remember it well, it's zero, the view is not perspective, so I just have the wp and tp on the extension of the object.
Code:
    while s1$<>"endtab"
     s$=dxff.readline:s1$=dxff.readline
     if int(val(s$))=16 then wpx=val(s1$)
     if int(val(s$))=26 then wpy=val(s1$)
     if int(val(s$))=36 then wpz=val(s1$)
     if int(val(s$))=17 then tpx=val(s1$)
     if int(val(s$))=27 then tpy=val(s1$)
     if int(val(s$))=37 then tpz=val(s1$)
     if int(val(s$))=71 then orto=val(s1$)
    wend
 
You know, guys, I'll show you about evolution.
by habit/comfort work in a single file with many tables (the last one had 46), creating a layout for each table.
This is because when asked, I mould all the drawings by publishing, very quickly and because if I make a change somewhere it is much easier to update all the dependent tables.
since some customers do not want a file with 46 tables, but 46 files from 1 table, I needed to export the file of its constituent layouts.
layoutexport, export the layout, but only in the model space (you lose the layout) and especially export it with the display set in the layout (if you set up in the layout "representing print styles" you will find the black and white model.
and above all it does for single layout.
I tried other lisp (type lxa) which is a layoutexport multiple, but suffers from the same problems of exportlayout (obviously)
I tried layoutstodwgs but it does a case, I replicate the whole model, so a 13mbyte file became me 46 13mbyte files

and then I wrote it, with the help of gp (big master) and rpor66 (other beast of the lisp).
It's a little rough, little error control, but do what you need
export each layout to a separate file, keeping the only entities contained in the layout window and the layout itself, including the relevant entities in the paper space.

Code:
(defun reset_var()
  (setq layouts nil ad nil layfol nil oldrgnmode nil layoutnumber nil count nil)
  (setq  vp nil flay nil p1 nil p2 nil p3 nil p4 nil p5 nil p6 nil p7 nil p8 nil)
  (setq target_vp nil oldosmode nil todel nil count1 nil layname nil file_name nil)
   (setq pspace_ent nil oldmaxvp nil old_thumb nil)
 )


;;;   export all layouts in separate files  in a subfolder "layouts"
;;;  for each file retain model entity and layout (with relative paper space entity)
;;;  layout must have one single vieport, if layout have multiple viewport, probram break.
;;; tanks to gp and rpor66 of cad3d.it to solve my dealock

(defun c:layexport9 ()

  (vl-load-com)
 

(setq oldmaxvp (getvar "maxactvp"))
(setq old_thumb (getvar "updatethumbnail"))
(setvar "clayout" "model")


  (setq layouts (layoutlist))
  (setq layouts (acad_strlsort layouts))
  (setq ad (getvar "dwgprefix"))
  (setq layfol (strcat ad "layouts"))

  (if (findfile layfol)
    (progn
      (alert "\n la directory di output e' gia' esistente
      \nla procedura potrebbe sovrascrivere file giã  esistenti
      e produrre risultati inaspettati.
      \nil programma sara' terminato e tutte le variabili saranno azzerate")
      (reset_var)
      (quit)
    )
   )



  (vl-mkdir layfol)
  (setq oldrgnmode (getvar "regenmode"))
  (setvar "regenmode" 0)
 
(setq layoutnumber (length layouts))
(setq count 0)
(setq pspace_ent (ssget "x" '((67 . 1))))

 

  (foreach layout layouts
    (setvar "maxactvp" 2)
    (setvar "updatethumbnail" 0)
    (setq layout (nth count layouts))
    (setq vp (ssget "x" (list (cons 0 "viewport")(cons 410 layout))))

      (if (> (sslength vp) 2)
    (progn
      (setq vpnumerr (strcat "nel layou " layout " ci sono piu' di una viewport
      \nil programma potrebbe fornire risultati inaspettati e sara' terminato.
           \nricordarsi di eliminare la directory giã  creata altrimenti la procedura fallirã  nuovamente."))
      (alert vpnumerr)
           (reset_var)
            (quit)
         )
    )

       (setvar "clayout" layout);;<----- cambia il layout rendendo corrente quello in esame
    ;;;;*********inizio codice gp***********
       (setq flay (vlax-ename->vla-object (ssname vp 0)))
         (vla-getboundingbox flay 'p1* 'p2*)
           (setq p1 (vlax-safearray->list p1*))
           (setq p2 (vlax-safearray->list p2*))
           (setq p3 (list (car p1) (cadr p1)))
           (setq p4 (list (car p2) (cadr p2)))
           (setq p5 (trans p1 3 2))
           (setq p6 (trans p2 3 2))

;;<------- inizio suggerimento rpor
;;;; somma il valore di target alle coordinate viewport
    (if (assoc '17 (entget (ssname vp 0)))
       ;;se esiste il valore di target
      (progn
    (setq target_vp (cdr (assoc '17 (entget (ssname vp 0)))))
        (setq p7 (list (+ (nth 0 p5)(nth 0 target_vp)) (+ (nth 1 p5)(nth 1 target_vp)) 0.00 ))
        (setq p8 (list (+ (nth 0 p6)(nth 0 target_vp)) (+ (nth 1 p6)(nth 1 target_vp)) 0.00 ))
      );;<--------chiusura progn
    );;<--------se esiste gruppo 17 nell'entita viewport
 
        (setvar "clayout" "model")
;;;;;*********fine codice gp*************
    (setq oldosmode (getvar "osmode"))
    (setvar "osmode" 0)

    (command "_.select" "_crossing" p7 p8 "")

  (command "._undo" "_begin") 
    (command "_erase" "_all" "_remove" "_previous" "_remove" pspace_ent "")

(setq count1 -1)
 
(repeat layoutnumber

(setq count1 (+ count1 1))
  (setq layname (nth count1 layouts))
  (if (/= layname layout) (command "_layout" "_delete" layname));;<chiusura if
  
 
);;<-- chiusura repeat

(command "._undo" "_end")

    (setq file_name (strcat layfol "\\" layout))
    (command "-purge" "_all" "" "_no")
    (command "-purge" "_all" "" "_no")
    (setvar "maxactvp" oldmaxvp)
    (setvar "updatethumbnail" old_thumb)

(command "_saveas" "" file_name)
    (command "_undo" "_back" "_y")

(setvar "clayout" "model")

(command "_erase" "_crossing" p7 p8 "")
    (command "-purge" "_all" "" "_no")

    (setq count (+ count 1))
    
);;;;<------------------ chiusura foreach layout

  (setvar "regenmode" oldrgnmode)

  );;<-------chiusura defun

(alert "\n estrae tutti i layout di un dwg in file separati in una sottocartella layouts del dwg.
\nfunziona con layout che abbiano una sola viewport, ed esporta, per ogni layout, sia la parte modello che il relativo layout con le entita' appartenenti al paper space di quel layout.
\n\nusare layexport9 per lanciare")
the only part I still have to solve is to physically copy external references (xrif and images) from the folder where they reside at the new subfolder "layouts", so that when opening the files of the individual layout does not give the missing reference notice.

I can get the xref dwg list by:
Code:
;;; codice to close the xref blocchi

(setq *acad-object* (vlax-get-acad-object))
(setq *active-doc* (vla-get-activedocument *acad-object*))
(setq *blocks* (vla-get-blocks *active-doc*)))
(vlax-for n *blocks*
(if (eq (vla-get-isxref n) :vlax-true)
(progn)
(setq pippo (vla-get-path n))
(setq pippo (findfile pippo))
)
)
)

;;; codice to close the xref blocchi
and image file names by:
Code:
;;; codice to squeeze the xref immagini
(defun imgfile ( / acad_image_dict )

(vl-catch-all-apply
lambda ( )
(setq acad_image_dict
(vla-item
(vla-get-dictionaries
(vla-get-activedocument
(vlax-get-acad-object)
)
)
"acad_image_dict"
)
)
)
)
(setq lista (list))
(if acad_image_dict
(vlax-for entry acad_image_dict
(setq img
(vl-princ-to-string
(cdr)
(assoc 1
(entget)
(vlax-vla-object->ename entry)
)
)
)
)
)
)
But I got stuck on autocad shell operations. I haven't used them for 20 years.

another thrust of the masters? :
 
Meanwhile, take this file that allows the use of the synchronous/asynchronous shell, you can also edit it to use the xcopy command only the parameters filedacopy dirdestination so as to manage the program "clean".
If you have problems, I'm here.
bye
 

Attachments

Forum statistics

Threads
44,997
Messages
339,767
Members
4
Latest member
ibt

Members online

No members online now.
Back
Top