December 2014

Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      










« Autodesk University customization sessions | Main | Loading the right version of an ObjectARX module into 32- or 64-bit AutoCAD »

April 18, 2007

Taking a snapshot of the AutoCAD model (take 2)

In this previous post, we looked at some code to do a programmatic snapshot of AutoCAD's modelspace, saving the results to an image file.

From the discussion that followed, I realised that the code had an undesired (and unnecessary) side-effect of creating a new 3D GS View and leaving the modelspace with that view active. GS Views in AutoCAD 2007 have grey backgrounds by default, and so this change can be quite disturbing for users. The only reason we created the GS View in the first place (if one didn't already exist), was to use it to query the view position/target/up vector/field width and height and apply it to our new view. Thankfully it seems this can also be determined directly from the viewport.

So rather than calling GetGSView() and using the returned view to get that information, we now simply call SetViewFromViewport() specifying the viewport number held in CVPORT, and the graphics system manager for that document handles the rest.

Here's the updated C# code, which appears to achieve the same goals without the side-effect. Check line 124 for the new code, a few extraneous lines around it having been removed:

    1 using Autodesk.AutoCAD.ApplicationServices;

    2 using Autodesk.AutoCAD.DatabaseServices;

    3 using Autodesk.AutoCAD.EditorInput;

    4 using Autodesk.AutoCAD.GraphicsInterface;

    5 using Autodesk.AutoCAD.GraphicsSystem;

    6 using Autodesk.AutoCAD.Runtime;

    7 using Autodesk.AutoCAD.Interop;

    8 using System.Drawing;

    9

   10 namespace OffscreenImageCreation

   11 {

   12   public class Commands

   13   {

   14     [CommandMethod("OSS")]

   15     static public void OffscreenSnapshot()

   16     {

   17       CreateSphere();

   18       SnapshotToFile(

   19         "c:\\sphere-Wireframe2D.png",

   20         VisualStyleType.Wireframe2D

   21       );

   22       SnapshotToFile(

   23         "c:\\sphere-Hidden.png",

   24         VisualStyleType.Hidden

   25       );

   26       SnapshotToFile(

   27         "c:\\sphere-Basic.png",

   28         VisualStyleType.Basic

   29       );

   30       SnapshotToFile(

   31         "c:\\sphere-ColorChange.png",

   32         VisualStyleType.ColorChange

   33       );

   34       SnapshotToFile(

   35         "c:\\sphere-Conceptual.png",

   36         VisualStyleType.Conceptual

   37       );

   38       SnapshotToFile(

   39         "c:\\sphere-Flat.png",

   40         VisualStyleType.Flat

   41       );

   42       SnapshotToFile(

   43         "c:\\sphere-Gouraud.png",

   44         VisualStyleType.Gouraud

   45       );

   46       SnapshotToFile(

   47         "c:\\sphere-Realistic.png",

   48         VisualStyleType.Realistic

   49       );

   50     }

   51

   52     static public void CreateSphere()

   53     {

   54       Document doc =

   55         Application.DocumentManager.MdiActiveDocument;

   56       Database db = doc.Database;

   57       Editor ed = doc.Editor;

   58

   59       Transaction tr =

   60         doc.TransactionManager.StartTransaction();

   61       using (tr)

   62       {

   63         BlockTable bt =

   64           (BlockTable)tr.GetObject(

   65             db.BlockTableId,

   66             OpenMode.ForRead

   67           );

   68         BlockTableRecord btr =

   69           (BlockTableRecord)tr.GetObject(

   70             bt[BlockTableRecord.ModelSpace],

   71             OpenMode.ForWrite

   72           );

   73         Solid3d sol = new Solid3d();

   74         sol.CreateSphere(10.0);

   75

   76         const string matname =

   77           "Sitework.Paving - Surfacing.Riverstone.Mortared";

   78         DBDictionary matdict =

   79           (DBDictionary)tr.GetObject(

   80             db.MaterialDictionaryId,

   81             OpenMode.ForRead

   82           );

   83         if (matdict.Contains(matname))

   84         {

   85           sol.Material = matname;

   86         }

   87         else

   88         {

   89           ed.WriteMessage(

   90             "\nMaterial (" + matname + ") not found" +

   91             " - sphere will be rendered without it.",

   92             matname

   93           );

   94         }

   95         btr.AppendEntity(sol);

   96

   97         tr.AddNewlyCreatedDBObject(sol, true);

   98         tr.Commit();

   99       }

  100       AcadApplication acadApp =

  101         (AcadApplication)Application.AcadApplication;

  102       acadApp.ZoomExtents();

  103     }

  104

  105     static public void SnapshotToFile(

  106       string filename,

  107       VisualStyleType vst

  108     )

  109     {

  110       Document doc =

  111         Application.DocumentManager.MdiActiveDocument;

  112       Editor ed = doc.Editor;

  113       Database db = doc.Database;

  114       Manager gsm = doc.GraphicsManager;

  115

  116       // Get some AutoCAD system variables

  117       int vpn =

  118         System.Convert.ToInt32(

  119           Application.GetSystemVariable("CVPORT")

  120         );

  121

  122       using (View view = new View())

  123       {

  124         gsm.SetViewFromViewport(view, vpn);

  125

  126         // Set the visual style to the one passed in

  127         view.VisualStyle = new VisualStyle(vst);

  128

  129         Device dev =

  130           gsm.CreateAutoCADOffScreenDevice();

  131         using (dev)

  132         {

  133           dev.OnSize(gsm.DisplaySize);

  134

  135           // Set the render type and the background color

  136           dev.DeviceRenderType = RendererType.Default;

  137           dev.BackgroundColor = Color.White;

  138

  139           // Add the view to the device and update it

  140           dev.Add(view);

  141           dev.Update();

  142

  143           using (Model model = gsm.CreateAutoCADModel())

  144           {

  145             Transaction tr =

  146               db.TransactionManager.StartTransaction();

  147             using (tr)

  148             {

  149               // Add the modelspace to the view

  150               // It's a container but also a drawable

  151               BlockTable bt =

  152                 (BlockTable)tr.GetObject(

  153                   db.BlockTableId,

  154                   OpenMode.ForRead

  155                 );

  156               BlockTableRecord btr =

  157                 (BlockTableRecord)tr.GetObject(

  158                   bt[BlockTableRecord.ModelSpace],

  159                   OpenMode.ForRead

  160                 );

  161               view.Add(btr, model);

  162               tr.Commit();

  163             }

  164             // Take the snapshot

  165             Rectangle rect = view.Viewport;

  166             using (Bitmap bitmap = view.GetSnapshot(rect))

  167             {

  168               bitmap.Save(filename);

  169               ed.WriteMessage(

  170                 "\nSnapshot image saved to: " +

  171                 filename

  172               );

  173               // Clean up

  174               view.EraseAll();

  175               dev.Erase(view);

  176             }

  177           }

  178         }

  179       }

  180     }

  181   }

  182 }

You can also download the .cs file from here.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83452464869e200d8357830af69e2

Listed below are links to weblogs that reference Taking a snapshot of the AutoCAD model (take 2):

blog comments powered by Disqus

Feed/Share

10 Random Posts