Author Topic: Save/restore xref layer states only  (Read 7833 times)

0 Members and 1 Guest are viewing this topic.

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Save/restore xref layer states only
« on: November 10, 2008, 02:35:50 PM »
Anyone have anything that will save/restore layer states for xrefs ONLY?
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

pkohut

  • Guest
Re: Save/restore xref layer states only
« Reply #1 on: November 10, 2008, 02:47:40 PM »
Code or application?

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Save/restore xref layer states only
« Reply #2 on: November 10, 2008, 02:51:06 PM »
I don't have one, but one could be written pretty easily I would assume. Just store the information in a dictionary within the drawing, and then you can call it when you opening it fresh again.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: Save/restore xref layer states only
« Reply #3 on: November 10, 2008, 02:51:18 PM »
Code or application?


Code preferably... Not too keen on running something that I don't know what it'll _really_ do.  No offense.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: Save/restore xref layer states only
« Reply #4 on: November 10, 2008, 02:52:05 PM »
I don't have one, but one could be written pretty easily I would assume. Just store the information in a dictionary within the drawing, and then you can call it when you opening it fresh again.

This would just be like a one time thing.  It doesn't need to be run every time the drawing is opened.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Save/restore xref layer states only
« Reply #5 on: November 10, 2008, 02:56:51 PM »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Save/restore xref layer states only
« Reply #6 on: November 10, 2008, 02:58:39 PM »
I don't have one, but one could be written pretty easily I would assume. Just store the information in a dictionary within the drawing, and then you can call it when you opening it fresh again.

This would just be like a one time thing.  It doesn't need to be run every time the drawing is opened.
How do you know which layers are supposed to be on/off frozen/thawed?  The information could be stored in a global variable, and then just called by a program to restore/save.

How are you visioning it working?
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

pkohut

  • Guest
Re: Save/restore xref layer states only
« Reply #7 on: November 10, 2008, 03:06:59 PM »
I don't remember fully but don't layer names with $ or | in them represent
attached or overlay xrefs?  Otherwise you just get the layer info through
normal means, with the addition that you need to check group code 70
bit 5 to see if the layer is dependent on an attached xref.

Paul

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: Save/restore xref layer states only
« Reply #8 on: November 10, 2008, 03:12:28 PM »
What I'd like to do is basically match another drawing's layer states for selected xrefs.  The more I think about it, the more I realize I'm not sure how to approach this.  I could do some sort of DBX thang that loops through layers checking them against the good drawing's xref layers?  Or maybe save an external file and restore......whenever??  I dunno.  I guess I'm open for suggestions.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Save/restore xref layer states only
« Reply #9 on: November 10, 2008, 03:28:26 PM »
If you just want to copy from one drawing to the current, than that shouldn't be too hard, as long as the xrefs are named the same.  If not, then some mapping will come into play.  This could be done with VBA ( stated because I know you can code in it ).  If that is what you are after it wouldn't be too hard to come up with something.  Do you want to code it in VBA ( I can't really help, but give some ideas that I would use with Lisp and ActiveX )?  Or do you want to do it in Lisp?
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: Save/restore xref layer states only
« Reply #10 on: November 10, 2008, 03:34:47 PM »
Hmmm.... vba... now that you mention it, I did something with layers and saving/restoring (I think) a few years back.  I'll have to scour my CDs and see if I still have a copy of it.  If not, I might take a whack at it with VBA or maybe OpenDCL.  Wheeeeee!!!

I'm still open for ideas if you want to share.   :roll:
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Save/restore xref layer states only
« Reply #11 on: November 10, 2008, 03:36:44 PM »
What I'd like to do is basically match another drawing's layer states for selected xrefs.  The more I think about it, the more I realize I'm not sure how to approach this.  I could do some sort of DBX thang that loops through layers checking them against the good drawing's xref layers?  Or maybe save an external file and restore......whenever??  I dunno.  I guess I'm open for suggestions.
Are you just doing for one drawing one time?   (If am I reading you correctly)
IN that case creat and then export a layer "filter" from the "to be match" drawing and then import that filter into the file to the matching.  But I am probaly all wet. 

I will go back to drooling this :-D
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: Save/restore xref layer states only
« Reply #12 on: November 10, 2008, 03:38:39 PM »
What I'd like to do is basically match another drawing's layer states for selected xrefs.  The more I think about it, the more I realize I'm not sure how to approach this.  I could do some sort of DBX thang that loops through layers checking them against the good drawing's xref layers?  Or maybe save an external file and restore......whenever??  I dunno.  I guess I'm open for suggestions.
Are you just doing for one drawing one time?   (If am I reading you correctly)
IN that case creat and then export a layer "filter" from the "to be match" drawing and then import that filter into the file to the matching.  But I am probaly all wet. 

I will go back to drooling this :-D

That would give me EVERY layer... I just want the xref layers.
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

jbuzbee

  • Swamp Rat
  • Posts: 851
Re: Save/restore xref layer states only
« Reply #13 on: November 10, 2008, 03:42:29 PM »
Have a look at the following:

The following code opens and closes a DBX document

Code: [Select]
;;; Open a dbxDoc ;
;;; use (setq dbxDocument(kb:OpenDbxDocument dwgname)) ;
(defun kb:OpenDbxDocument (DwgName / app doc dbxopen dbxDoc)
  (setq app (vlax-get-acad-object)
        doc (vla-get-ActiveDocument app)
        )
  (if (/= dwgname (vla-get-fullname doc))
    (progn (cond ((= (substr (getvar "ACADVER") 1 5) "15.06")
                  (setq dbxDoc  (vla-GetInterfaceObject app "ObjectDBX.AxDbDocument")
                        dbxopen (vl-catch-all-apply 'vla-open (list dbxDoc DwgName))
                        )
                  )
                 (t
                  (setq dbxDoc  (vla-GetInterfaceObject
                                  app
                                  (strcat "ObjectDBX.AxDbDocument." (substr (getvar "acadver") 1 2))
                                  )
                        dbxopen (vl-catch-all-apply 'vla-open (list dbxDoc DwgName))
                        )
                  )
                 )
           (if (vl-catch-all-error-p dbxopen)
             (setq dbxDoc nil)
             )
           )
    )
  dbxDoc
  )

;;; Close dbxDoc
;;; (kb:CloseDbxDocument dbxDocument)
(defun kb:CloseDbxDocument (dbxdoc)
  (if (= (type dbxDoc) 'VLA-OBJECT)
    (progn (vlax-release-object dbxDoc) (setq dbxDoc nil))
    )
  )

This code will return a list of layer names to change.
arguments: xref; "*" returns ALL layers
                       nil returns the active doc layers only
                       "xr" returns ALL xref layers (filters "|")
                       "xrefname" returns only the layers of a single xref (filters "xrefname|")

Code: [Select]
(defun kb:GetLayerList (xref / layers ret)
  (setq layers (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
  (cond ((= xref "*") ;gets all layers
(vlax-for x layers (setq ret (append ret (list (vla-get-name x)))))
)
((= xref nil) ;gets only active doc layers
(vlax-for
x
layers
   (if (not (vl-string-search "|" (vla-get-name x)))
     (setq ret (append ret (list (vla-get-name x))))
     )
   )
)
((= xref "xr") ;gets all xref layers
(vlax-for
x
layers
   (if (vl-string-search "|" (vla-get-name x))
     (setq ret (append ret (list (vla-get-name x))))
     )
   )
)
(t ;gets a specific xref's layers
(vlax-for
x
layers
   (if (vl-string-search (strcat xref "|") (vla-get-name x))
     (setq ret (append ret (list (vla-get-name x))))
     )
   )
)
)
  ret
  )

This code will match the layer in the active drawing, local and / or xrefs, with the states of the layers in the dbx document.

arguments:
lstatename - the Layer State to use
dwgname - the drawing to be referenced (dbx doc)
layerList - which layers to change: see above.

Code: [Select]
(defun kb:LayerStateEngine (lstatename   dwgname layerlist     /
    dbxdoc   dbxdict dict       dbxplotstyles
    dbxlayernames dbxlinetypes
    )
  (setvar "clayer" "0")
  (princ "\nSetting the current layer to 0")
  (princ)
  (setq dbxdoc (kb:OpenDbxDocument DwgName))
  (if dbxdoc
    (progn (setq lstateobj (vla-GetInterfaceObject(vlax-get-acad-object)(strcat"AutoCAD.AcadLayerStateManager."(substr (getvar "ACADVER") 1 2))))
   (if lstateobj
     (progn (vla-setdatabase lstateobj (vla-get-database dbxdoc))
    (vlax-invoke lstateobj 'restore lstatename)
    (setq dbxlayers (vla-get-layers dbxdoc)
  layers    (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
  )
    ;get a list of layers in the dbxdoc - because there's no "has" method!
    (vlax-for
   x
    (vla-get-layers dbxdoc)
      (setq dbxlayernames
     (append dbxlayernames (list (strcase (vla-get-name x))))
    )
      )
    ;(setq n "X_Base43|A-Wall-Patt")
    ;(setq n(nth 3 layerlist))
    (foreach
   n
    layerlist
      (if (and (not (= n "0"))
       (member (strcase (kb:striplayername n)) dbxlayernames)
       )
(progn (setq lobj    (vla-item layers n)
     lobjdbx (vla-item dbxlayers (kb:striplayername n))
     )
       (foreach
      property
      (list "Freeze"   "LayerOn" "Lineweight"
    "Lock"   "Plottable" "color"
    )
(vlax-put lobj property (vlax-get lobjdbx property))
)
    ;set plotstyle
       (setq ps (vlax-get lobjdbx "PlotStyleName"))
       (kb:load-plotstyle dbxdoc ps)
       (vlax-put lobj "PlotStyleName" ps)
    ;set linetype
       (setq ln (vlax-get lobjdbx "Linetype"))
       (if (not (tblsearch "ltype" ln))
(setq newln
(vl-catch-all-apply
  'vla-CopyObjects
  (list dbxDoc
(vlax-safearray-fill
  (vlax-make-safearray vlax-vbObject '(0 . 0))
  (list (vla-item (vla-get-linetypes dbxDoc) ln))
  )
(vla-get-linetypes (vla-get-activedocument (vlax-get-acad-object)))
)
  )
       )
)
       (if (tblsearch "ltype" ln)
(vlax-put lobj "Linetype" ln)
)
       )
)
      )
    )
     )
   (kb:CloseDbxDocument dbxdoc)
   (vlax-release-object lstateobj)
   )
    )
  (vla-regen
    (vla-get-activedocument (vlax-get-acad-object))
    acActiveViewport
    )
  )

jb
James Buzbee
Windows 8

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: Save/restore xref layer states only
« Reply #14 on: November 10, 2008, 03:43:29 PM »
Hmmm.... vba... now that you mention it, I did something with layers and saving/restoring (I think) a few years back.  I'll have to scour my CDs and see if I still have a copy of it.  If not, I might take a whack at it with VBA or maybe OpenDCL.  Wheeeeee!!!

I'm still open for ideas if you want to share.   :roll:

Oooohhh..... I actually found it.  From October 2004.  It's not pretty, but it worked!  I just have to make it work for what I want to do now.


Code: [Select]
Option Explicit

Public Const strErrPath = "S:\CADDStds\Error_Logs\"


Public Sub SaveLayerState()
    Dim oXrec As AcadXRecord
    Dim oDict As AcadDictionary
    Dim oLayer As AcadLayer
    Dim vType() As Integer
    Dim vData() As Variant
    Dim i As Integer
   
    On Error GoTo ErrMsg
   
    ReDim Preserve vData(0 To i)
    ReDim Preserve vType(0 To i)
   
    Set oDict = ThisDrawing.Dictionaries.Add("MY_LAYERS")
    For Each oLayer In ThisDrawing.Layers
        vType(i) = 1
        ' Layer name
        ' Truecolor
        ' Linetype
        ' Plottable?
        ' Locked?
        ' On?
        ' Frozen
        vData(i) = oLayer.Name & "~!~" & oLayer.TrueColor.ColorIndex & "~!~" & oLayer.Linetype & "~!~" & oLayer.Plottable & "~!~" & oLayer.Lock & "~!~" & oLayer.LayerOn & "~!~" & oLayer.Freeze
        Set oXrec = oDict.AddXRecord("MY_LAYER_STATES")
        oXrec.SetXRecordData vType, vData
        i = i + 1
        ReDim Preserve vData(0 To i)
        ReDim Preserve vType(0 To i)
    Next
   
    Set oXrec = Nothing
    Exit Sub
   
ErrMsg:
    WriteError Err.Number, Err.Description, "Layer_State.dvb :: modMain.Main :: SaveLayerState", Now, ""
End Sub

Public Sub RestoreLayerState()
    Dim oLayer As AcadLayer
    Dim color As AcadAcCmColor
    Dim varResult As Variant
    Dim myDict As AcadDictionary
    Dim i As Integer
    Dim myXRec As AcadXRecord
    Dim dxfCode, dxfData
    Dim iLayer As Integer
   
    On Error GoTo ErrMsg
   
    Set myDict = ThisDrawing.Dictionaries.Item("MY_LAYERS")
    Set myXRec = myDict.Item("MY_LAYER_STATES")
    myXRec.GetXRecordData dxfCode, dxfData
   
    ThisDrawing.SetVariable "regenmode", 0
   
    On Error Resume Next
    For Each oLayer In ThisDrawing.Layers
        oLayer.Freeze = True
        oLayer.LayerOn = False
    Next oLayer
   
    For i = LBound(dxfData) To UBound(dxfData)
        varResult = Split(dxfData(i), "~!~", , vbTextCompare)
'''        Debug.Print varResult(0) ' Layer name
'''        Debug.Print varResult(1) ' Truecolor
'''        Debug.Print varResult(2) ' Linetype
'''        Debug.Print varResult(3) ' Plottable
'''        Debug.Print varResult(4) ' Locked
'''        Debug.Print varResult(5) ' On
'''        Debug.Print varResult(6) ' Frozen
        Set color = New AcadAcCmColor
        With color
            .ColorMethod = acColorMethodByACI
            .ColorIndex = varResult(1)
        End With
        Set oLayer = ThisDrawing.Layers(varResult(0))
        With oLayer
            .TrueColor = color
            .Linetype = varResult(2)
            .Plottable = varResult(3)
            .Lock = varResult(4)
            .LayerOn = varResult(5)
            .Freeze = varResult(6)
        End With
    Next i
    ThisDrawing.SetVariable "regenmode", 1
    ThisDrawing.Regen acAllViewports
    Exit Sub
   
ErrMsg:
    WriteError Err.Number, Err.Description, "Layer_State.dvb :: modMain.Main :: RestoreLayerState", Now, ""
    Resume Next
End Sub

Public Sub WriteError(iErrNum As Integer, sDesc As String, sSource As String, sDate As String, sOptionalInfo As String)
    '// Writes all errors to err.log
    Dim F As Integer
    F = FreeFile
    Open strErrPath & Format(Now, "mm-dd-yy__hh.mm.ss") & ".log" For Output As #F
    Print #F, "Error Number: " & iErrNum
    Print #F, "Description: " & sDesc
    Print #F, "Source: " & sSource
    Print #F, "Date: " & sDate
    Print #F, "More Info: " & sOptionalInfo
    Print #F, ""
    Close #F
End Sub
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io