Author Topic: Project objects from OCS to a Vport in Layout  (Read 593 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Swamp Rat
  • Posts: 774
Project objects from OCS to a Vport in Layout
« on: July 11, 2021, 04:44:16 PM »
Hey guys, I've got stuck at this specific problem -
In the sample drawing I have an attributed block reference which contains 2 attribute definitions and a rectangle.
That same block reference is displayed from a viewport on a certain layout.
The block reference is uniformly scaled and rotated in the modelspace, aswell the viewport orientation.

I'm trying to figure out how to re-entmake/copy/project/extract the contents (or more precisely: the 2 attribute definitions) on in the space of the layout which the viewport resides in.
 - something like vla-Explode method.
Say creating a subfunction, where given two handles: <BlockRefHandle> <ViewportHandle> to "Explode" the block as a projection in that certain layout.
In the sample drawings the handles are "597C" for the blockref, and "5962" for the viewport.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)

ribarm

  • Gator
  • Posts: 2559
  • Marko Ribar, architect
Re: Project objects from OCS to a Vport in Layout
« Reply #1 on: July 11, 2021, 05:23:12 PM »
I don't quite understand what do you exactly want to achieve with attributes in Layout, but I'd try exploding block, seleting attributes, change space (CHSPACE command), do with attributes what had to be done, and finally undo all until before exploding... I don't know if this helps you, but we need more info about copy-re-entmaking and so on... that you plan to do...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

BIGAL

  • Swamp Rat
  • Posts: 868
  • 30 + years of using Autocad
Re: Project objects from OCS to a Vport in Layout
« Reply #2 on: July 11, 2021, 07:48:10 PM »
If you have a object in modelspace and chspace it  will disappear in other viewports. Do you mean to leave it behind ? But replicate/copy it to the layout at correct orientation and position over multiple viewports ? May have some clues how to do.
A man who never made a mistake never made anything

Grrr1337

  • Swamp Rat
  • Posts: 774
Re: Project objects from OCS to a Vport in Layout
« Reply #3 on: July 12, 2021, 02:52:10 PM »
I don't quite understand what do you exactly want to achieve with attributes in Layout

Its a part of a larger program, where I'm creating layouts and viewports and zooming on the same attributed block; and I do need to obtain the exact attribute position
in the layout space, so I could do conditional changes for the TextString property based on the TagString.
My intention is to entmake MTEXTs in the layout space, matching the properties of the projected attribute definitions (position, rotation, size, style).
Unfortunately creating multiple attributed blocks in each layout's space is not a option.


but I'd try exploding block, seleting attributes, change space (CHSPACE command), do with attributes what had to be done, and finally undo all until before exploding... I don't know if this helps you, but we need more info about copy-re-entmaking and so on... that you plan to do...

Sounds like a working idea, although I've got 100+ layouts and each one has multiple viewports zooming on different blocks,
and I'm not sure how much the command call will slow down the whole thing.

My main problem is to figure out on how to perform the point translations from the OCS of the block ref to the PCS of the layout -
so I've thought about implementing the 'refgeom' subfunction by gile but I have no clue how to use it.


If you have a object in modelspace and chspace it  will disappear in other viewports. Do you mean to leave it behind ? But replicate/copy it to the layout at correct orientation and position over multiple viewports ? May have some clues how to do.

I'm just trying to 'explode it on top' of a certaion viewport in a certain layout, hence if I provide these handles <BlockRefHandle> <ViewportHandle> to the subfunction I would know exactly from which block I can extract its geometry to which layout. But by exploding I mean like the method vla-Explode, where the block in modelspace remains untouched.

A possible alternative would be to translate/scale the whole block reference to the layout space as a copy and then explode it.
But that would deviate from the question on how to translate a point from OCS to PCS.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)

BIGAL

  • Swamp Rat
  • Posts: 868
  • 30 + years of using Autocad
Re: Project objects from OCS to a Vport in Layout
« Reply #4 on: July 13, 2021, 12:06:13 AM »
In something I did pick a point in a layout mview in paperspace, convert to a modelspace point using trans, I then found a rounded co-ord this is for grids in paperspace. Returned to paperspace and again trans to convert model space to layout point. eg model 100000,527000 = 100,100 in paperspace.

I had to play with (trans (trans to make it work. pretty sure I allowed for ucs twists.

Try pt in model space is block insert point, you must be in layout, paperspace then run this.

(setq psnewcen (trans (trans pt 1 2) 2 3))

A man who never made a mistake never made anything

ribarm

  • Gator
  • Posts: 2559
  • Marko Ribar, architect
Re: Project objects from OCS to a Vport in Layout
« Reply #5 on: July 13, 2021, 03:15:33 AM »
My main problem is to figure out on how to perform the point translations from the OCS of the block ref to the PCS of the layout -
so I've thought about implementing the 'refgeom' subfunction by gile but I have no clue how to use it.

You actually don't need (refgeom) but (revrefgeom) - I am sure that you can find it if you search www... Authors are Mr. Gilles C. and Mr. Lee M.
That is how you should get coords of nested entity in its parent space...
Then you can (trans) it to PS or whatever space you need...

But that's just for getting correct positions - you need I suppose copy/recreate if I understood correctly, or just (entmake)-ing MTEXT at the same position as attribute - if that's the case, then you should be good to go with (revrefgeom) and (trans) like BIGAL explained...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Grrr1337

  • Swamp Rat
  • Posts: 774
Re: Project objects from OCS to a Vport in Layout
« Reply #6 on: July 20, 2021, 04:45:59 PM »
Thank you guys, upon my further web research I've discovered the existence of WCS2PCS, PCS2WCS and WCS2RCS, RCS2WCS  subfunctions of Gile, which are dealing with the point transformations.
Then I realised that I actually need to perform transformations on the block's attdefs for the vport (instead of just point-translating them) In order to retain the rotation and scale,
so I've checked out several routines in Lee Mac's website which are using RefGeom and RevRefGeom functions. The main programs I needed researching were these:
Modelspace To Paperspace
Extract Nested Block
Add Objects to block

So I've managed to assemble the subfunction I needed, thanks to Gile and Lee Mac :
Code - Auto/Visual Lisp: [Select]
  1. (defun TransformAttDefsFromBlkRefToVport ( handleBlkRef handleVport / TransformToSpace GetAttDefs GetVportMatrix RefGeom )
  2.  
  3.   (defun TransformToSpace ( oL mat space bDel bRegen / acDoc r )
  4.     (foreach o (setq r (vlax-invoke (setq acDoc (vla-get-activedocument (vlax-get-acad-object))) 'CopyObjects oL space))
  5.       (vla-TransformBy o mat)
  6.     )
  7.     (if bDel (foreach o oL (vla-Delete o)))
  8.     (if bRegen (vla-Regen acDoc acAllviewports))
  9.    
  10.     r
  11.   ); defun TransformToSpace
  12.  
  13.   (defun GetAttDefs ( blkref / L )
  14.     (vlax-for o
  15.       (and (eq (vla-get-objectname o) "AcDbAttributeDefinition") (setq L (cons o L)))
  16.     ); vlax-for
  17.     L
  18.   ); defun
  19.  
  20.   ; Used Lee Mac's "modelspace to paperspace" program to create this subfunction - refgeom for a viewport object
  21.   (defun GetVportMatrix ( vport / enx ang nor scl mat )
  22.     (setq
  23.       enx (entget vport)
  24.       ang (cdr (assoc 51 enx))
  25.       nor (cdr (assoc 16 enx))
  26.       scl (/ (cdr (assoc 41 enx)) (cdr (assoc 45 enx)))
  27.       mat ; http://lee-mac.com/ms2ps.html
  28.       (vlax-tmatrix
  29.         (append
  30.           (mapcar '(lambda ( a b ) (append a (list b)))
  31.             (setq mat ;; The following is adapted from gile's WCS2PCS function:
  32.               (mxm
  33.                 (list
  34.                   (list (cos ang) (- (sin ang)) 0.0)
  35.                   (list (sin ang)    (cos ang)  0.0)
  36.                   '(0.0 0.0 1.0)
  37.                 )
  38.                 (mapcar (function (lambda ( v ) (vxs (trans v nor 0 t) scl)))
  39.                   '(
  40.                     (1.0 0.0 0.0)
  41.                     (0.0 1.0 0.0)
  42.                     (0.0 0.0 1.0)
  43.                   )
  44.                 )
  45.               )
  46.             )
  47.             (mapcar '+
  48.               (mxv mat (mapcar '- (cdr (assoc 17 enx))))
  49.               (vxs (cdr (assoc 12 enx)) (- scl))
  50.               (cdr (assoc 10 enx))
  51.             )
  52.           )
  53.           '((0.0 0.0 0.0 1.0))
  54.         )
  55.       ); vlax-tmatrix
  56.     ); setq
  57.    
  58.   ); defun GetVportMatrix
  59.  
  60.  
  61.  
  62.   ;; RefGeom (gile)
  63.   ;; Returns a list which first item is a 3x3 transformation matrix (rotation, scales, normal)
  64.   ;; and second item the object insertion point in its parent (xref, block or space)
  65.   ;; Argument : an ename
  66.   (defun RefGeom ( ent / mxv trp mxm ang ang mat ocs )
  67.    
  68.     ;; Matrix x Vector - Vladimir Nesterovsky
  69.     ;; Args: m - nxn matrix, v - vector in R^n
  70.     (defun mxv ( m v )(mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m) )
  71.    
  72.     ;; Matrix Transpose - Doug Wilson
  73.     ;; Args: m - nxn matrix
  74.     (defun trp ( m ) (apply 'mapcar (cons 'list m)))
  75.    
  76.     ;; Matrix x Matrix - Vladimir Nesterovsky
  77.     ;; Args: m,n - nxn matrices
  78.     (defun mxm ( m n ) ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n)))
  79.    
  80.    
  81.     (setq enx (entget ent)
  82.       ang (cdr (assoc 050 enx))
  83.       ocs (cdr (assoc 210 enx))
  84.     )
  85.     (list
  86.       (setq mat
  87.         (mxm
  88.           (mapcar '(lambda ( v ) (trans v 0 ocs t))
  89.             '(
  90.               (1.0 0.0 0.0)
  91.               (0.0 1.0 0.0)
  92.               (0.0 0.0 1.0)
  93.             )
  94.           )
  95.           (mxm
  96.             (list
  97.               (list (cos ang) (- (sin ang)) 0.0)
  98.               (list (sin ang) (cos ang)     0.0)
  99.               '(0.0 0.0 1.0)
  100.             )
  101.             (list
  102.               (list (cdr (assoc 41 enx)) 0.0 0.0)
  103.               (list 0.0 (cdr (assoc 42 enx)) 0.0)
  104.               (list 0.0 0.0 (cdr (assoc 43 enx)))
  105.             )
  106.           )
  107.         )
  108.       ); setq mat
  109.       (mapcar '- (trans (cdr (assoc 10 enx)) ocs 0)
  110.         (mxv mat (cdr (assoc 10 (tblsearch "block" (cdr (assoc 2 enx))))))
  111.       )
  112.     ); list
  113.   ); defun RefGeom
  114.  
  115.  
  116.   ( ; Main
  117.     (lambda ( handleBlkRef handleVport / acDoc blkref vport mat1 oL mat2 r )
  118.       (mapcar 'set '(blkref vport) (mapcar 'handent (list handleBlkRef handleVport)))
  119.       (and
  120.         (eq -1 (vlax-get (vlax-ename->vla-object blkref) 'HasAttributes))
  121.         (setq mat1
  122.           (apply
  123.             '(lambda ( m v ) (vlax-tmatrix (append (mapcar '(lambda ( x v )(append x (list v))) m v) '((0.0 0.0 0.0 1.0)))))
  124.             (refgeom blkref)  
  125.           ); apply
  126.         ); setq mat1
  127.         (setq oL (TransformToSpace (GetAttDefs blkref) mat1 (vla-get-ModelSpace acDoc) nil nil)) ; transform the entities into MSPACE
  128.         (setq mat2 (GetVportMatrix vport))
  129.         (setq r
  130.           (TransformToSpace oL mat2 ; transform the entities above the VPORT
  131.             (vla-get-Block
  132.               (vla-item (vla-get-Layouts (vla-get-Document (vlax-ename->vla-object vport)))
  133.               (cdr (assoc 410 (entget vport))))
  134.             )
  135.             t t
  136.           )
  137.         ); setq r
  138.       ); and
  139.       r
  140.     ); lambda
  141.     handleBlkRef handleVport
  142.   ); Main
  143.  
  144. ); defun TransformAttDefsFromBlkRefToVport

Now given the handles, the subfunction successfuly projects the attribute definitions from the block reference into the layout's space above the desired viewport.
I would be stuck forever without Lee writing this "refgeom" matrix for a viewport object, which I just used as a subfunction in here.

Thank you all, and sorry for my delayed reply - I'm really busy with other stuff and I'm taking my time to figure out the programming troubles I get into.

(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)