TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: gile on April 02, 2008, 08:06:09 AM

Title: Thaw a layer in a viewport
Post by: gile on April 02, 2008, 08:06:09 AM
Hi,

I can freeze a layer in a viewport by changing the viewport XDatas.

Code: [Select]
;; VPFREEZE
;; Freeze the layer in the viewport
;;
;; Arguments
;; vp : viewport (vla-object)
;; lay : layer name (string)

(defun vpfreeze (vp lay / typ val)
  (vla-getXdata vp "ACAD" 'typ 'val)
  (setq typ (reverse
      (cons 1002
    (cons 1002
  (cons 1003 (cddr (reverse (vlax-safearray->list typ))))
    )
      )
    )
val (reverse
      (cons (vlax-make-variant "}")
    (cons (vlax-make-variant "}")
  (cons (vlax-make-variant lay)
(cddr (reverse (vlax-safearray->list val)))
  )
    )
      )
    )
  )
  (vla-setXData
    vp
    (vlax-safearray-fill
      (vlax-make-safearray
vlax-vbInteger
(cons 0 (1- (length typ)))
      )
      typ
    )
    (vlax-safearray-fill
      (vlax-make-safearray
vlax-vbVariant
(cons 0 (1- (length val)))
      )
      val
    )
  )
  ;; this is needed to display the change
  (vla-display vp :vlax-false)
  (vla-display vp :vlax-true)
)

But how can I thaw a frozen layer in a viewport ?
I tried this, but it doesn't work.

Code: [Select]
(defun vpfreeze (vp lay / typ val)
  (vla-getXdata vp "ACAD" 'typ 'val)
  (setq typ (reverse
      (cons 1002
    (cons 1002
  (cons 1003 (cddr (reverse (vlax-safearray->list typ))))
    )
      )
    )
val (reverse
      (cons (vlax-make-variant "}")
    (cons (vlax-make-variant "}")
  (cons (vlax-make-variant lay)
(cddr (reverse (vlax-safearray->list val)))
  )
    )
      )
    )
  )
  (vla-setXData
    vp
    (vlax-safearray-fill
      (vlax-make-safearray
vlax-vbInteger
(cons 0 (1- (length typ)))
      )
      typ
    )
    (vlax-safearray-fill
      (vlax-make-safearray
vlax-vbVariant
(cons 0 (1- (length val)))
      )
      val
    )
  )
  (vla-display vp :vlax-false)
  (vla-display vp :vlax-true)
)
Title: Re: Thaw a layer in a viewport
Post by: CAB on April 02, 2008, 08:30:07 AM
As I recall, MP tried to get that to work back in the year 2005 or 2006 and could not so I ended up using
(command ".vplayer"

I'll see if I can find the thread for some clues.
Title: Re: Thaw a layer in a viewport
Post by: CAB on April 02, 2008, 09:35:05 AM
gile,
Haven't visited this subject in a long time.
Looking at the DXF data for a viewport, the entity name of the frozen layer in in the main entity list.
In ACAD 2000 it is in DXF 341 and in ACAD2004 it is in DXF 331. The xdata remains the same.
Is the DXF 341 or 331 being updated?

This may be what we missed back in 2005 when we tried to freeze/thaw the VP layers.


I found several threads from that time period but not the one I was looking for.
I'd do some testing but I am short of time today.
Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on June 27, 2008, 06:15:25 PM
Hi

I back a topic, but I have the same problem.
Unable to frozen a layer in a viewport using xdatas.  :x
If you have found.  :-)

@+
Title: Re: Thaw a layer in a viewport
Post by: VovKa on June 28, 2008, 07:13:04 AM
the bad thing is that one cannot use the entmod function to modify a viewport entity, making it imposible to remove a 331 group
Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on June 29, 2008, 07:27:25 AM
Yoy can't modify viewport with entmod, but you can with visual.

@+
Title: Re: Thaw a layer in a viewport
Post by: CAB on June 29, 2008, 04:39:14 PM
Patrick,
Gile's code will FREEZE a layer in a viewport.
But no method found to THAW a layer in a viewport.

Here is my attempt and it doesn't work.  :-(

Code: [Select]
(defun vpthaw (vp      ; vpObject
               laylist ; list of layer names
               / typ val TypeList ValueList cFlag pos newlen newtyp newval LayVar
              )
  (vl-load-com)
  ;;  CAB 12/27/2006
  ;;  (RemoveNth 3 '(0 1 2 3 4 5))
  ;;  (0 1 2 4 5)
  (defun removeNth (i lst)
    (setq i (1+ i))
    (vl-remove-if '(lambda (x) (zerop (setq i (1- i)))) lst)
  )


  (vla-getXdata vp "ACAD" 'typ 'val) ; get the xData
  ;;  make xData into 2 lists
  (setq TypeList  (vlax-safearray->list typ)
        ValueList (vlax-safearray->list val)

  )

  ;;  remove the layer names & type data in the list.
  (foreach Layname layList
    (if (setq pos (vl-position
                    (setq LayVar (vlax-make-variant layname 8)) valuelist)
        )
      (setq valuelist (vl-remove LayVar valuelist)
            TypeList  (removeNth pos TypeList)
            cFlag     t
      )
    )
  )

  (if cFlag ; need to update xData
    (progn
      (setq newlen (1- (length TypeList))
            ;;  create new arrays with the new length
            newtyp (vlax-make-safearray vlax-vbinteger (cons 0 newlen))
            newval (vlax-make-safearray vlax-vbvariant (cons 0 newlen))
      )

      ;; fill up the new array with new data
      (vlax-safearray-fill newtyp TypeList)
      (vlax-safearray-fill newval ValueList)

      ;; update the xdata  <----<<<   NOT working
      (vlax-invoke-method vp 'SetXData NewTyp NewVal)

      (vla-display vp :vlax-false)
      (vla-display vp :vlax-true)

    )
  )
)
Title: Re: Thaw a layer in a viewport
Post by: VovKa on June 29, 2008, 06:08:19 PM
it seems to me that thawing a layer has nothing to do with xdata

i use a simple method, save a drawing (with frozen layer) in DXF format, then thaw layer and save it again as DXF (with new name). then run some file comparison program, i use standart fc. we'll see than the only difference is presence/absence of 331 group, xdata ramains intact
Title: Re: Thaw a layer in a viewport
Post by: CAB on June 29, 2008, 07:45:49 PM
When I freeze a layer the ename is added to the elst 331 and the string name is added to the xData.
When I thaw a layer the ename is removed from the elst 331 and the string name is removed from the xData.
You can use Gile's code to Freeze a layer which alters the xData and ACAD reactors (I assume) updates the DXF 331.
One may conclude that you should be able to reverse the process but it has proven to be incorrect so far.
Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on June 30, 2008, 02:47:08 AM
Thank you for your reply CAB
I arrived at the same result that you, namely that the setxdata does not work, despite a safearray correct.
I asked to see if someone had not found a trick and circumvented the problem.
Apparently not :-(
It is still surprising that we can add, but not delete.
The only method is dond use _.vplayer, but when the viewport is not active layout, I do not see how

@+
Title: Re: Thaw a layer in a viewport
Post by: FengK on June 30, 2008, 04:08:25 AM
I remember trying hard on this one as well and in the end also took the (command ".vplayer"...) route. A few years ago, when I was using AutoCAD 2002/2004, I tried Mr. TT's AcadX and I recall it has function(s) to thaw layers in viewport. But AcadX has been discontinued.
Title: Re: Thaw a layer in a viewport
Post by: It's Alive! on June 30, 2008, 04:27:20 AM
This is a tough one for ARX as well
http://www.theswamp.org/index.php?topic=21875.msg264784#msg264784
Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on June 30, 2008, 07:32:00 AM
Hi

I try your arx and it's work to freeze a layout
Code: [Select]
(crpvpfreeze (getvar "clayer") (list (getvar "ctab")))but don't to thaw
Code: [Select]
(crpvpthaw (getvar "clayer") (list (getvar "ctab")))I have this error
ERREUR INTERNE: !laymgr.cpp@987: eWasopenForRead

I load "CrpARX16.arx" in my A2006 (R16.2)

@+
Title: Re: Thaw a layer in a viewport
Post by: It's Alive! on June 30, 2008, 08:11:40 AM
Doh! I will try to fix it.

Did you try it with a layer that’s not the current layer?
Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on June 30, 2008, 08:50:37 AM
It's the same thing with a layer different from current layer.

That would be great, it would indicate the viewport rather than the layout, because you may want to freeze/thaw that the layer on one or several viewports a layout but not necessarily all of a viewports layout.
And top tops a list of layers rather than one by one. :-)

@+
Title: Re: Thaw a layer in a viewport
Post by: It's Alive! on June 30, 2008, 09:08:35 AM
Thanks for testing this. I will fix it
Title: Re: Thaw a layer in a viewport
Post by: It's Alive! on July 15, 2008, 01:01:24 PM
I finally got around fixing my routine (I hope), if anyone wants to try it out for me. The signature would now be
(doit   viewport (ename)  (list of layers)   i.e

Code: [Select]
;(doit vpEname (list of layers))
(doit (car (entsel)) (list "Layer1" "Layer2" "Layer3" "Layer4" "Layer5"));freeze
(undoit (car (entsel)) (list "Layer1" "Layer2" "Layer3" "Layer4" "Layer5"));thaw

If all is ok I will post the updated code in this thread
http://www.theswamp.org/index.php?topic=21875.msg264784#msg264784

your system variable LAYOUTREGENCTL must be set to 0 for you to see the changes

Use the attached ARX


Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on July 16, 2008, 05:43:06 AM
Great !!!

I even tested on a viewport that is not in the active layout, it's work fine  :-)

Thanks
Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on July 16, 2008, 07:33:09 AM
I adapted my lisp with your arx.
Title: Re: Thaw a layer in a viewport
Post by: It's Alive! on July 16, 2008, 08:34:27 AM
Very Nice!
before you get too far along, I was planning on changing those function names to something more appropriate.
I’ll probably use crpvpfreeze and crpvpthaw.

Dan
Title: Re: Thaw a layer in a viewport
Post by: It's Alive! on July 16, 2008, 09:53:56 AM
Ok I updated the Arx files and I uploaded the source code
http://www.theswamp.org/index.php?topic=21875.msg264050#msg264050
Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on July 16, 2008, 10:46:13 AM
Thanks

I updated the lisp

@+
Title: Re: Thaw a layer in a viewport
Post by: It's Alive! on July 16, 2008, 11:00:59 AM
Very fine work!  8-)
Title: Re: Thaw a layer in a viewport
Post by: Patrick_35 on July 16, 2008, 11:57:33 AM
Thanks

Just a clarification, you can work on several viewport.

@+
Title: Re: Thaw a layer in a viewport
Post by: FengK on July 16, 2008, 12:22:47 PM
Ok I updated the Arx files and I uploaded the source code
http://www.theswamp.org/index.php?topic=21875.msg264050#msg264050


Very nice Daniel! I know I requested this one. Thank you!