Author Topic: .NET Layout,ViewPort,Plot Routines  (Read 25584 times)

0 Members and 1 Guest are viewing this topic.

flyte

  • Newt
  • Posts: 26
Re: .NET Layout,ViewPort,Plot Routines
« Reply #15 on: September 19, 2017, 11:51:31 PM »
Publishing to 3d DWF

<Edit: adding a try/catch block in agreement with the observation of tony>
C#
Code - C#: [Select]
  1. using System.IO;
  2. using System.Text;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.PlottingServices;
  5.  
  6. namespace Plottings
  7. {
  8.     public class PlotTo3dDwf
  9.     {
  10.         private string dwgFile, dwfFile, dsdFile, title, outputDir;
  11.  
  12.         public PlotTo3dDwf()
  13.         {
  14.             outputDir = (string)Application.GetSystemVariable("DWGPREFIX");
  15.             string name = (string)Application.GetSystemVariable("DWGNAME");
  16.             dwgFile = Path.Combine(outputDir, name);
  17.             title = Path.GetFileNameWithoutExtension(name);
  18.             dwfFile = Path.ChangeExtension(dwgFile, "dwf");
  19.             dsdFile = Path.ChangeExtension(dwfFile, ".dsd");
  20.         }
  21.  
  22.         public PlotTo3dDwf(string outputDir)
  23.             : this()
  24.         {
  25.             this.outputDir = outputDir;
  26.         }
  27.  
  28.         public void Publish()
  29.         {
  30.             short bgPlot = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
  31.             Application.SetSystemVariable("BACKGROUNDPLOT", 0);
  32.             try
  33.             {
  34.                 if (!Directory.Exists(outputDir))
  35.                     Directory.CreateDirectory(outputDir);
  36.  
  37.                 using (DsdData dsd = new DsdData())
  38.                 using (DsdEntryCollection dsdEntries = new DsdEntryCollection())
  39.                 {
  40.                     // add the Model layout to the entry collection
  41.                     DsdEntry dsdEntry = new DsdEntry();
  42.                     dsdEntry.DwgName = dwgFile;
  43.                     dsdEntry.Layout = "Model";
  44.                     dsdEntry.Title = title;
  45.                     dsdEntry.Nps = "0";
  46.                     dsdEntries.Add(dsdEntry);
  47.                     dsd.SetDsdEntryCollection(dsdEntries);
  48.  
  49.                     // set DsdData
  50.                     dsd.Dwf3dOptions.PublishWithMaterials = true;
  51.                     dsd.Dwf3dOptions.GroupByXrefHierarchy = true;
  52.                     dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
  53.                     dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
  54.                     dsd.SheetType = SheetType.SingleDwf;
  55.                     dsd.NoOfCopies = 1;
  56.                     dsd.ProjectPath = outputDir;
  57.                     dsd.IsHomogeneous = true;
  58.  
  59.                     if (File.Exists(dsdFile))
  60.                         File.Delete(dsdFile);
  61.  
  62.                     // write the DsdData file
  63.                     dsd.WriteDsd(dsdFile);
  64.  
  65.                     // get the Dsd File contents
  66.                     string str;
  67.                     using (StreamReader sr = new StreamReader(dsdFile, Encoding.Default))
  68.                     {
  69.                         str = sr.ReadToEnd();
  70.                     }
  71.                     // edit the contents
  72.                     str = str.Replace("Has3DDWF=0", "Has3DDWF=1");
  73.                     str = str.Replace("PromptForDwfName=TRUE", "PromptForDwfName=FALSE");
  74.                     // rewrite the Dsd file
  75.                     using (StreamWriter sw = new StreamWriter(dsdFile, false, Encoding.Default))
  76.                     {
  77.                         sw.Write(str);
  78.                     }
  79.  
  80.                     // import the Dsd file new contents in the DsdData
  81.                     dsd.ReadDsd(dsdFile);
  82.  
  83.                     File.Delete(dsdFile);
  84.  
  85.                     PlotConfig pc = PlotConfigManager.SetCurrentConfig("DWF6 ePlot.pc3");
  86.                     Application.Publisher.PublishExecute(dsd, pc);
  87.                 }
  88.             }
  89.             finally
  90.             {
  91.                 Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot);
  92.             }
  93.         }
  94.     }
  95. }
  96.  

Hi gile - excellent post, but for some reason this isn't working for me. I don't have the "DWF6 ePlot.pc3" on my config so I had to change it to:

Code: [Select]
var pc = PlotConfigManager.SetCurrentConfig("Autodesk DWF Writer.pc3");

which should be available to me programatically, here it is in the options:


however when I do this, I get an error dialog:


and the following exception:
Code: [Select]
System.Exception {Autodesk.AutoCAD.Runtime.Exception }
Quote
{"eNullPtr"}

.. not sure what is causing this... any ideas?

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: .NET Layout,ViewPort,Plot Routines
« Reply #16 on: September 20, 2017, 04:00:00 AM »
Hi,

You'd rather use the _PLOTTERMANAGER command to check for installed plotters and look for one which uses the dwfplot1X.hdi driver.
Speaking English as a French Frog

flyte

  • Newt
  • Posts: 26
Re: .NET Layout,ViewPort,Plot Routines
« Reply #17 on: September 20, 2017, 09:59:46 AM »
Hi,

You'd rather use the _PLOTTERMANAGER command to check for installed plotters and look for one which uses the dwfplot1X.hdi driver.

When I issue that command, it simply opens up an Explorer window showing the .pc3's, and indeed Autodesk DWF Writer.pc3 exists.


gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: .NET Layout,ViewPort,Plot Routines
« Reply #18 on: September 20, 2017, 11:48:09 AM »
As far as I know, Autodesk DWF Writer is a plotter to be used with non Autodesk applications.

The PlotTo3dDwf class uses the "publish" mechanism with DSD files which requires the "DWF6 ePlot.pc3" plotter.
Speaking English as a French Frog

flyte

  • Newt
  • Posts: 26
Re: .NET Layout,ViewPort,Plot Routines
« Reply #19 on: January 17, 2018, 12:17:53 AM »
As far as I know, Autodesk DWF Writer is a plotter to be used with non Autodesk applications.

The PlotTo3dDwf class uses the "publish" mechanism with DSD files which requires the "DWF6 ePlot.pc3" plotter.

Hi gile.

Before I run the above code to export to 3ddwf, I want to detach all xrefs and thaw and turn on all layers. I want all that to happen before the export happens, and then "revert" back to the original state when the export is done.

I have seen lsp code do this by setting
Code: [Select]
(acad-push-dbmod) How can I do this in C#?

For reference, I am using the nifty layer routines that were posted in the corresponding threads on this site.. here is an example:

Code: [Select]
[CommandMethod("Thawall")]
public static void ThawAll()
{
Database db = HostApplicationServices.WorkingDatabase;
LayerTableRecord layer;

string curLayer = (string)Application.GetSystemVariable("CLayer");
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
foreach (ObjectId layerId in lt)
{
layer = tr.GetObject
(layerId, OpenMode.ForWrite) as LayerTableRecord;
if (layer.Name != curLayer)
layer.IsFrozen = false;
}
tr.Commit();
Application.DocumentManager.MdiActiveDocument.Editor.Regen();
}
}

I have tried commenting out the commit, but it still appears to react.

Any ideas what I can do?

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: .NET Layout,ViewPort,Plot Routines
« Reply #20 on: January 17, 2018, 02:29:39 AM »
Hi,

You have to store the frozen layers while you thaw them so that you you can freeze them bak when your stuff is done.

EDIT: Added unload/reload xrefs

Code - C#: [Select]
  1.         [CommandMethod("SOMECOMMAND")]
  2.         public void SomeCommand()
  3.         {
  4.             var db = HostApplicationServices.WorkingDatabase;
  5.             using (var tr = db.TransactionManager.StartTransaction())
  6.             {
  7.                 // Thaw and store frozen layers
  8.                 var frozen = new List<LayerTableRecord>();
  9.                 var layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
  10.                 foreach (ObjectId id in layerTable)
  11.                 {
  12.                     var layer = (LayerTableRecord)tr.GetObject(id, OpenMode.ForRead);
  13.                     if (layer.IsFrozen)
  14.                     {
  15.                         frozen.Add(layer);
  16.                         layer.UpgradeOpen();
  17.                         layer.IsFrozen = false;
  18.                     }
  19.                 }
  20.  
  21.                 // Unload and store xrefs
  22.                 var xrefIds = new ObjectIdCollection();
  23.                 var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  24.                 foreach (ObjectId id in bt)
  25.                 {
  26.                     var btr = (BlockTableRecord)tr.GetObject(id, OpenMode.ForRead);
  27.                     if (btr.IsFromExternalReference)
  28.                     {
  29.                         xrefIds.Add(id);
  30.                     }
  31.                 }
  32.                 db.UnloadXrefs(xrefIds);
  33.  
  34.                 // Do some stuff
  35.                 try
  36.                 {
  37.                     // do some stuff here
  38.                 }
  39.  
  40.                 // Freeze back the previously frozen layers and reload xrefs
  41.                 finally
  42.                 {
  43.                     foreach (var layer in frozen)
  44.                     {
  45.                         layer.IsFrozen = true;
  46.                     }
  47.                     db.ReloadXrefs(xrefIds);
  48.                 }
  49.                 tr.Commit();
  50.             }
  51.         }
« Last Edit: January 17, 2018, 03:11:47 AM by gile »
Speaking English as a French Frog

flyte

  • Newt
  • Posts: 26
Re: .NET Layout,ViewPort,Plot Routines
« Reply #21 on: January 17, 2018, 12:45:23 PM »
Hi,

You have to store the frozen layers while you thaw them so that you you can freeze them bak when your stuff is done.

EDIT: Added unload/reload xrefs

Code - C#: [Select]
  1.         [CommandMethod("SOMECOMMAND")]
  2.         public void SomeCommand()
  3.         {
  4.             var db = HostApplicationServices.WorkingDatabase;
  5.             using (var tr = db.TransactionManager.StartTransaction())
  6.             {
  7.                 // Thaw and store frozen layers
  8.                 var frozen = new List<LayerTableRecord>();
  9.                 var layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
  10.                 foreach (ObjectId id in layerTable)
  11.                 {
  12.                     var layer = (LayerTableRecord)tr.GetObject(id, OpenMode.ForRead);
  13.                     if (layer.IsFrozen)
  14.                     {
  15.                         frozen.Add(layer);
  16.                         layer.UpgradeOpen();
  17.                         layer.IsFrozen = false;
  18.                     }
  19.                 }
  20.  
  21.                 // Unload and store xrefs
  22.                 var xrefIds = new ObjectIdCollection();
  23.                 var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  24.                 foreach (ObjectId id in bt)
  25.                 {
  26.                     var btr = (BlockTableRecord)tr.GetObject(id, OpenMode.ForRead);
  27.                     if (btr.IsFromExternalReference)
  28.                     {
  29.                         xrefIds.Add(id);
  30.                     }
  31.                 }
  32.                 db.UnloadXrefs(xrefIds);
  33.  
  34.                 // Do some stuff
  35.                 try
  36.                 {
  37.                     // do some stuff here
  38.                 }
  39.  
  40.                 // Freeze back the previously frozen layers and reload xrefs
  41.                 finally
  42.                 {
  43.                     foreach (var layer in frozen)
  44.                     {
  45.                         layer.IsFrozen = true;
  46.                     }
  47.                     db.ReloadXrefs(xrefIds);
  48.                 }
  49.                 tr.Commit();
  50.             }
  51.         }

Thanks (yet again!) gile for your guidance. Another thread suggested
Code: [Select]
Autodesk.AutoCAD.ApplicationServices.Document.PopDbMod()/PushDbMod() - would that be safe to use and prevent me from having to do all of the book keeping of what was on/thawed ?

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: .NET Layout,ViewPort,Plot Routines
« Reply #22 on: January 17, 2018, 01:48:05 PM »
Not at all.
PushDbMod() and PushDbMod() work the same as the LISP functions acad-push-dbmod and acad-pop-dbmod and are only use to handle the DBMOD system variable.
Please, read the docs for:
acad-push-dbmod LISP function
acad-pop-dbmod LISP function
pushDbmod ARX method (wrapped by the PushDbMod managed method)
popDbmod ARX method (wrapped by the PopDbMod managed method)
Speaking English as a French Frog