Restore Layer State in Viewport

Restore Layer State in Viewport

olivier.eckmann
Advocate Advocate
1,064 Views
5 Replies
Message 1 of 6

Restore Layer State in Viewport

olivier.eckmann
Advocate
Advocate

Hi,

 

I would like to restore existing LayerStates in viewport on all may layout.

I've read and used sample found in .Net help but Second argument is the Id of Viewport and in all sample, this arg is always ObjectId.Null.

I've tried to use Id of my viewport, but Layerstate is always restored in the current Layout, not in my viewport. It seems the 2nd arg is never used or has never been implemented. It always used the default base viewport of the current layout.

 

(How) is it possible to restore à LayerState in choosen Viewport, in choosen layouts?

 

Thanks

 

Olivier 

0 Likes
1,065 Views
5 Replies
Replies (5)
Message 2 of 6

norman.yuan
Mentor
Mentor

When you saying you "would like to restore layer state...", does that imply that you have layer state(s) saved previously by your code? Or do not mean you want to restore to the layer states you somehow know exist in the drawing, probably created by user manually?

 

Let me assume that you use code to save a layerstate at some point of your code execution, and let user or your code to something that could change layes' properties (on/off, color, linetype...). And eventually, you want your code to restore the layerstate to the saved state.

 

So, things should start when you save the layerstate: the LayerStateManager.SaveLayerState() also take an argument of ObjectId, which is the viewport whose VPLAYER setting is to captured. if ObjectId.Null is used, then the layer state saved will not have VPLAYER setting captured. That is, SaveLayerState() and RestoreLayerState() should be passed into the same viewport Id, if you want to svae and restore layerstate with viewport layer state.

 

Here is the quote from ObjectARX document on SaveLayerState() method:

 

<QUOTE>

Saves the current state of the layer table to the layer state specified by name. This function also captures the VPLAYER settings for the viewport specified. Specify Null for the id argument to capture a layer state without VPLAYER settings.

</QUOTE>

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 6

olivier.eckmann
Advocate
Advocate

Hi Norman,

 

thanks for your answer. I'll try to expose my problem more precise.

In our drawing (road conception) I've between 5 and 10 saved Paperspace layerstate (created manually by AutoCAD interface or import form .LAS) : "road design", "pipe design", "landscape design"... and because length of road I've between 1 and 10 (or more) grid (road division in length which could be plot on 1.5m paper length), so I could have until 100 or more layouts. Before publishing, I go on each layout, enter in my viewport and restore "manually" my layerstate => OK.

During the study I add layers, so I update my layerstates, and I need to switch in each layout, enter in my viewport and restore my  good Layerstate. Because file is heavy, switching in each layout and restore my layerstate can take 10 to 30 minutes for all my layouts before publishing to be sure my plot are correct.

The goal is to write an plug-gin with a grid. I associate a layerstate and an viewport Id to each layout, and the plugin restore the good layerstate to the good viewport in the good layout with only 1 button just before publishing, I hope more rapidly than maunal swithing to each layout.

 

As said, Layerstate are created manually, or import from .LAS or define in my template, and not from .Net code.

 

I hope my description of problem could be useful to find a solution.

 

Thanks

 

Olivier

 

0 Likes
Message 4 of 6

kerry_w_brown
Advisor
Advisor

Perhaps you should include a sample version of the drawing.

... and the code you ae trying to use.


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 5 of 6

olivier.eckmann
Advocate
Advocate

Hi,

 

After lots of tests I've found where is the bug in the API and how I (you) can reproduce it.

I join a DWG file which contains:

3 layers named : Calque1 color Red and Calque2 color Green and FMULT (contaning viewports)

2 layouts names : TEST1 and TEST2

2 layer states named : TEST1, TEST2

1 rectangle in Calque1 and 1 rectangle in Calque2.

The goal is to restore layerstate TEST1 in layout TEST1 in viewport in layer FMULT and  layerstate TEST2 in layout TEST2 in viewport in layer FMULT with this code (some comments are in french, if it's a problem I can translate):

    [CommandMethod("PgxTest2")]
    public void PgxTest2()
    {
      Document _acCurDoc = AcAp.DocumentManager.MdiActiveDocument;
      Database _acCurDb = _acCurDoc.Database;
      Editor ed = _acCurDoc.Editor;
      Dictionary<ObjectId, string> _dictLyrState = new Dictionary<ObjectId, string>();

      // Start a transaction
      using (Transaction tr = _acCurDb.TransactionManager.StartTransaction())
      {

        // Lit les infos des présentations
        DBDictionary acDbDict = tr.GetObject(_acCurDb.LayoutDictionaryId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead) as DBDictionary;

        foreach (DBDictionaryEntry acDbDictEnt in acDbDict)
        {
          Layout layout = tr.GetObject(acDbDictEnt.Value, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead) as Layout;
          if (layout.LayoutName.ToUpper() == "MODEL") continue;
          // Sélectionne la viewport
          TypedValue[] tvArray = new TypedValue[] { 
            new TypedValue((int)DxfCode.Start, "VIEWPORT"),
            new TypedValue((int)DxfCode.LayerName, "FMULT"),
            new TypedValue((int)DxfCode.LayoutName, layout.LayoutName)
          };
          SelectionFilter ssFilter = new SelectionFilter(tvArray);
          PromptSelectionResult psr = _acCurDoc.Editor.SelectAll(ssFilter);
          // If selection actually contains nothing or more than 1 viewport
          if ((psr.Status != PromptStatus.OK)
              || psr.Value.Count != 1)
            continue;
          _dictLyrState.Add(psr.Value[0].ObjectId, layout.LayoutName);
        }

        // Dispose of the transaction
      }

      foreach (ObjectId id in _dictLyrState.Keys)
      {
        // Restore les états de calque
        LayerStateManager acLyrStMan = _acCurDb.LayerStateManager;
        string sLyrStName = _dictLyrState[id];
        if (acLyrStMan.HasLayerState(sLyrStName) == true)
        {
          acLyrStMan.RestoreLayerState(sLyrStName, id, 4,
            LayerStateMasks.Color | LayerStateMasks.LineType | LayerStateMasks.CurrentViewport);
        }
      }
    }

 So to reproduce the bug : 

1st test

Open the DWG (layout TEST1 is current) launch the code => It's OK

2nd test

Close and re-open the DWG, switch to Model tab launch the code => It's bad because red square diseappear, it's the bug : when Model tab is current and you restore a Layerstate which contains no replacement in color or linetype but only Frozen in current viewport, the last layerstate restored is ALSO restored in the Model tab.

3rd test

To verify, close and re-open the DWG, switch to Model tab, go to LayerstateManager select TEST1 button Modify change color of Calque1 to Red (instead the same color by re-specify it), do the same think in layerstate TEST2.  launch the code => It's OK

 

So the bug appears when you are in Model tab and when minimum one layerstate restored contains only Frozen in CurrentViewport modification.

 

I've reproduced this bug in MAP 3D 2008, 2010, 2012 and 2015. I haven't tested in vanilla AutoCAD but i think it's the same behaviour.

 

Olivier

 

 

 

0 Likes
Message 6 of 6

moogalm
Autodesk Support
Autodesk Support

Hi there,

 

Thanks for letting us know , I don't see a possible reason why your code fails, I have communicated the behaviour to our development team.

 

Regards,

Madhu.

0 Likes