.NET

Reply
Contributor
ken.washburn
Posts: 25
Registered: ‎06-10-2008
Message 1 of 12 (385 Views)
Accepted Solution

Is there a way to create a 3D DWF from a drawing using VB.Net

385 Views, 11 Replies
07-13-2012 07:02 AM

Is there a way to create a 3D DWF from a drawing using VB.Net?  I have a program that processes hundreds of drawings and creates a PDF and DWF of each drawing.  I'd like to also create a 3D DWF file, but haven't find anything on it anywhere.  I'm not sure if this would be a Save As, Export or something else.

 

Thanks,

Ken

Member
adam
Posts: 3
Registered: ‎02-23-2008
Message 2 of 12 (376 Views)

Re: Is there a way to create a 3D DWF from a drawing using VB.Net

07-13-2012 08:07 AM in reply to: ken.washburn

Hi Ken,

 

If it appropriate and you are happy using the command line then use "3DDWF"

 

Adam

Contributor
ken.washburn
Posts: 25
Registered: ‎06-10-2008
Message 3 of 12 (374 Views)

Re: Is there a way to create a 3D DWF from a drawing using VB.Net

07-13-2012 08:22 AM in reply to: adam

Adam,

I thought about that, but the SendStringToExecute doesn't run until everything else has finished in vb.net (which doesn't work when batch processing).  And since moving to the 2013 API, I've found that emulating the vba "ThisDrawing.SendCommand" is spotty at best.  Though, I may have to go this route if there is not a direct way to access it.

 

 

Thanks,
Ken

*Expert Elite*
_gile
Posts: 2,071
Registered: ‎04-29-2006
Message 4 of 12 (354 Views)

Re : Is there a way to create a 3D DWF from a drawing using VB.Net

07-14-2012 04:33 PM in reply to: ken.washburn

Hi,

 

You can P/Invoke acedCmd which is synchronous.

 

Here's another way, in pure .NET. Maybe it isn't the best one but it works fine for me.

It creates a DSD file and publish it.

In this example, all layouts are published to DWF and the Model to 3d DWF

 

using System.IO;
using System.Text;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Publishing;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace Publish3dDwf
{
    public class PublishDwf
    {
        // Private fields
        private string dwgFile, dwfFile, dsdFile, tmpFile, title, outputDir;
        private int numOfSections;
        private Database db = HostApplicationServices.WorkingDatabase;
        private Editor ed = AcAp.DocumentManager.MdiActiveDocument.Editor;
        const string FN_PUBLOG = "publish.log";

        // Constructor
        public PublishDwf()
        {
            dwgFile = db.Filename;
            outputDir = Path.GetDirectoryName(dwgFile);
            if (!Directory.Exists(outputDir))
                Directory.CreateDirectory(outputDir);
            title = Path.GetFileNameWithoutExtension(dwgFile);
            dwfFile = Path.ChangeExtension(dwgFile, "dwf");
            dsdFile = Path.ChangeExtension(dwgFile, "dsd");
            tmpFile = Path.Combine(outputDir, "temp.dsd");
            numOfSections = 0;
        }

        // Publishes all layouts, displays a progress bar
        private void Publish()
        {
            try
            {
                Publisher publisher = AcAp.Publisher;
                PlotProgressDialog plotDlg = new PlotProgressDialog(false, numOfSections, true);
                publisher.PublishDsd(dsdFile, plotDlg);
                plotDlg.Destroy();
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nErreur: {0}\n{1}", ex.Message, ex.StackTrace);
            }
        }

        // Creates a DSD file (template)
        private void CreateDSD()
        {
            using (DsdData dsd = new DsdData())
            using (DsdEntryCollection dsdEntCol = CreateDsdEntryCollection())
            {
                numOfSections = dsdEntCol.Count;

                dsd.SetDsdEntryCollection(dsdEntCol);

                dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
                dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
                dsd.SheetType = SheetType.MultiDwf;
                dsd.NoOfCopies = 1;
                dsd.DestinationName = dwfFile;
                dsd.IsHomogeneous = false;
                dsd.LogFilePath = Path.Combine(outputDir, FN_PUBLOG);

                PostProcessDSD(dsd);
            }
        }

        // Creates an entry collection (one per layout) for the DSD file
        private DsdEntryCollection CreateDsdEntryCollection()
        {
            DsdEntryCollection dsdEntCol = new DsdEntryCollection();

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary layoutDict = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
                foreach (DBDictionaryEntry layoutEntry in layoutDict)
                {
                    Layout layout = (Layout)tr.GetObject(layoutEntry.Value, OpenMode.ForRead);
                    DsdEntry dsdEntry = new DsdEntry();
                    dsdEntry.DwgName = dwgFile;
                    dsdEntry.Layout = layout.LayoutName.ToString();
                    dsdEntry.Title = title + "-" + layout.LayoutName;
                    dsdEntry.Nps = layout.TabOrder.ToString();
                    dsdEntCol.Add(dsdEntry);
                }
            }
            return dsdEntCol;
        }

        // Writes the definitive DSD file from the template and additional infos
        private void PostProcessDSD(DsdData dsd)
        {
            string str, newStr;

            try
            {
                dsd.WriteDsd(tmpFile);
                bool isModel = false;

                using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
                using (StreamWriter writer = new StreamWriter(dsdFile, false, Encoding.Default))
                {
                    while (!reader.EndOfStream)
                    {
                        str = reader.ReadLine();
                        if (str == "Layout=Model")
                        {
                            isModel = true;
                        }
                        if (str.Contains("Has3DDWF"))
                        {
                            newStr = isModel ? "Has3DDWF=1" : "Has3DDWF=0"; // <- 3dDwf if Model layout
                            isModel = false;
                        }
                        else if (str.Contains("OriginalSheetPath"))
                        {
                            newStr = "OriginalSheetPath=" + dwgFile;
                        }
                        else if (str.Contains("Type"))
                        {
                            newStr = "Type=0"; // <- 6 for DwgToPdf
                        }
                        else if (str.Contains("OUT"))
                        {
                            newStr = "OUT=" + outputDir;
                        }
                        else if (str.Contains("IncludeLayer"))
                        {
                            newStr = "IncludeLayer=TRUE";
                        }
                        else if (str.Contains("PromptForDwfName"))
                        {
                            newStr = "PromptForDwfName=FALSE";
                        }
                        else if (str.Contains("LogFilePath"))
                        {
                            newStr = "LogFilePath=" + Path.Combine(outputDir, FN_PUBLOG);
                        }
                        else
                        {
                            newStr = str;
                        }
                        writer.WriteLine(newStr);
                    }
                }
            }
            catch (System.Exception e)
            {
                ed.WriteMessage("\nErreur: {0}\n{1}", e.Message, e.StackTrace);
            }
        }

        // Deletes the DSD files
        private void Cleanup()
        {
            try
            {
                if (File.Exists(dsdFile))
                {
                    File.Delete(dsdFile);
                }

                if (File.Exists(tmpFile))
                {
                    File.Delete(tmpFile);
                }
            }
            catch (System.Exception e)
            {
                ed.WriteMessage("\nErreur: {0}\n{1}", e.Message, e.StackTrace);
            }
        }

        // Command
        [CommandMethod("PublishToDwf")]
        public void PublishToDwf()
        {
            short bgp = (short)AcAp.GetSystemVariable("BACKGROUNDPLOT");
            AcAp.SetSystemVariable("BACKGROUNDPLOT", 0);
            CreateDSD();
            Publish();
            Cleanup();
            AcAp.SetSystemVariable("BACKGROUNDPLOT", bgp);
        }
    }
}

 

Gilles Chanteau
*Expert Elite*
_gile
Posts: 2,071
Registered: ‎04-29-2006
Message 5 of 12 (347 Views)

Re : Is there a way to create a 3D DWF from a drawing using VB.Net

07-15-2012 06:57 AM in reply to: _gile

The upper code is a quick (and dirty) adaptation of the one I used to plot layouts to a PDF file.

 

Publishing a 3d DWF may be a little more simple (removing unsefull lines).

 

Here's a little class you can instanciate to call the Publish() method:

 

Dim plot3d As New PlotTo3dDwf("C:\Temp")
plot3d.Publish()

 C#

using System.IO;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.PlottingServices;

namespace Plottings
{
    public class PlotTo3dDwf
    {
        private string dwgFile, dwfFile, dsdFile, title, outputDir;

        public PlotTo3dDwf()
        {
            outputDir = (string)Application.GetSystemVariable("DWGPREFIX");
            string name = (string)Application.GetSystemVariable("DWGNAME");
            dwgFile = Path.Combine(outputDir, name);
            title = Path.GetFileNameWithoutExtension(name);
            dwfFile = Path.ChangeExtension(dwgFile, "dwf");
            dsdFile = Path.ChangeExtension(dwfFile, ".dsd");
        }

        public PlotTo3dDwf(string outputDir) : this ()
        {
            this.outputDir = outputDir;
        }

        public void Publish()
        {
            short bgPlot = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
            Application.SetSystemVariable("BACKGROUNDPLOT", 0);

            if (!Directory.Exists(outputDir))
                Directory.CreateDirectory(outputDir);

            using (DsdData dsd = new DsdData())
            using (DsdEntryCollection dsdEntries = new DsdEntryCollection())
            {
                // add the Model layout to the entry collection
                DsdEntry dsdEntry = new DsdEntry();
                dsdEntry.DwgName = dwgFile;
                dsdEntry.Layout = "Model";
                dsdEntry.Title = title;
                dsdEntry.Nps = "0";
                dsdEntries.Add(dsdEntry);
                dsd.SetDsdEntryCollection(dsdEntries);

                // set DsdData
                dsd.Dwf3dOptions.PublishWithMaterials = true;
                dsd.Dwf3dOptions.GroupByXrefHierarchy = true;
                dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
                dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
                dsd.SheetType = SheetType.SingleDwf;
                dsd.NoOfCopies = 1;
                dsd.ProjectPath = outputDir;
                dsd.IsHomogeneous = true;

                if (File.Exists(dsdFile)) 
                    File.Delete(dsdFile);

                // write the DsdData file
                dsd.WriteDsd(dsdFile);

                // get the Dsd File contents
                string str;
                using (StreamReader sr = new StreamReader(dsdFile, Encoding.Default))
                {
                    str = sr.ReadToEnd();
                }
                // edit the contents
                str = str.Replace("Has3DDWF=0", "Has3DDWF=1");
                str = str.Replace("PromptForDwfName=TRUE", "PromptForDwfName=FALSE");
                // rewrite the Dsd file
                using (StreamWriter sw = new StreamWriter(dsdFile, false, Encoding.Default))
                {
                    sw.Write(str);
                }

                // import the Dsd file contents in the DsdData
                dsd.ReadDsd(dsdFile);

                File.Delete(dsdFile);

                PlotConfig pc = PlotConfigManager.SetCurrentConfig("DWF6 ePlot.pc3");
                Application.Publisher.PublishExecute(dsd, pc);
                Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot);
            }
        }
    }
}

 VB

Imports System.IO
Imports System.Text
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.PlottingServices

Namespace Plottings
    Public Class PlotTo3dDwf
        Private dwgFile, dwfFile, dsdFile, title, outputDir As String

        Public Sub New()
            outputDir = DirectCast(Application.GetSystemVariable("DWGPREFIX"), String)
            Dim name As String = DirectCast(Application.GetSystemVariable("DWGNAME"), String)
            dwgFile = Path.Combine(outputDir, name)
            title = Path.GetFileNameWithoutExtension(name)
            dwfFile = Path.ChangeExtension(dwgFile, "dwf")
            dsdFile = Path.ChangeExtension(dwfFile, ".dsd")
        End Sub

        Public Sub New(outputDir As String)
            Me.New()
            Me.outputDir = outputDir
        End Sub

        Public Sub Publish()
            Dim bgPlot As Short = CShort(Application.GetSystemVariable("BACKGROUNDPLOT"))
            Application.SetSystemVariable("BACKGROUNDPLOT", 0)

            If Not Directory.Exists(outputDir) Then
                Directory.CreateDirectory(outputDir)
            End If

            Using dsd As New DsdData()
                Using dsdEntries As New DsdEntryCollection()
                    ' add the Model layout to the entry collection
                    Dim dsdEntry As New DsdEntry()
                    dsdEntry.DwgName = dwgFile
                    dsdEntry.Layout = "Model"
                    dsdEntry.Title = title
                    dsdEntry.Nps = "0"
                    dsdEntries.Add(dsdEntry)
                    dsd.SetDsdEntryCollection(dsdEntries)

                    ' set DsdData data
                    dsd.Dwf3dOptions.PublishWithMaterials = True
                    dsd.Dwf3dOptions.GroupByXrefHierarchy = True
                    dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE")
                    dsd.SetUnrecognizedData("PromptForPwd", "FALSE")
                    dsd.SheetType = SheetType.SingleDwf
                    dsd.NoOfCopies = 1
                    dsd.ProjectPath = outputDir
                    dsd.IsHomogeneous = True

                    If File.Exists(dsdFile) Then
                        File.Delete(dsdFile)
                    End If

                    ' write the DsdData file
                    dsd.WriteDsd(dsdFile)

                    ' get the Dsd File contents
                    Dim str As String
                    Using sr As New StreamReader(dsdFile, Encoding.[Default])
                        str = sr.ReadToEnd()
                    End Using
                    ' edit the contents
                    str = str.Replace("Has3DDWF=0", "Has3DDWF=1")
                    str = str.Replace("PromptForDwfName=TRUE", "PromptForDwfName=FALSE")
                    ' rewrite the Dsd file
                    Using sw As New StreamWriter(dsdFile, False, Encoding.[Default])
                        sw.Write(str)
                    End Using

                    ' import the Dsd file new contents in the DsdData
                    dsd.ReadDsd(dsdFile)

                    File.Delete(dsdFile)

                    Dim pc As PlotConfig = PlotConfigManager.SetCurrentConfig("DWF6 ePlot.pc3")
                    Application.Publisher.PublishExecute(dsd, pc)
                    Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot)
                End Using
            End Using
        End Sub
    End Class
End Namespace

 

Gilles Chanteau
Contributor
ken.washburn
Posts: 25
Registered: ‎06-10-2008
Message 6 of 12 (326 Views)

Re : Is there a way to create a 3D DWF from a drawing using VB.Net

07-16-2012 06:54 AM in reply to: _gile

_gile, thanks for the code!  I will try this when I get time later this week.

 

Ken

Contributor
ken.washburn
Posts: 25
Registered: ‎06-10-2008
Message 7 of 12 (318 Views)

Re : Is there a way to create a 3D DWF from a drawing using VB.Net

07-16-2012 09:56 AM in reply to: ken.washburn

_gile, I got a chance to try your second set of code this morning, and it appears to work, as far as creating a dwf file.  However, the dwf file it creates I can't open (see attached) - it hangs up after starting to open.  I'm using Map 3D 2013.  Note that I can create 3DDWF from the command line (so I know that the drivers are there and working - unless this uses something different).

 

Also, I'm not familiar with working with DSD files and have the following questions:

1. I want the 3D DWF file to have a different name than the drawing (as I will already have a 2D DWF file in the folder) - somthing like Drawingname-3D.dwf.  So where would I change that?  I tried changing the "name" variable and the "dwfFile" variable, but neither worked (i.e. it didn't create the file).

 

2. Since the folder that I'm creating the new 3D DWF file in may already have an existing (older) 3D DWF, I want to overwrite the older file.  While I can write something to check for the file and delete it, I was wondering if there was something in your Publish() code section that could force an overwrite and supress any dialog boxes (that ask you if you want to overwrite the file).

 

Thanks again for your help on this.

Ken

 

*Expert Elite*
_gile
Posts: 2,071
Registered: ‎04-29-2006
Message 8 of 12 (315 Views)

Re : Is there a way to create a 3D DWF from a drawing using VB.Net

07-16-2012 12:29 PM in reply to: ken.washburn

I can open your 3d DWF file, but it looks like empty, I can't say why.

 

1. Try this in the constructor :

            dwfFile = Path.Combine(outputDir, title & "-3d.dwf")

 

2. Add this at the begining of the Publish() code:

                If File.Exists(dwfFile) Then
                    File.Delete(dwfFile)
                End If
Gilles Chanteau
Contributor
ken.washburn
Posts: 25
Registered: ‎06-10-2008
Message 9 of 12 (303 Views)

Re: Is there a way to create a 3D DWF from a drawing using VB.Net

07-16-2012 02:36 PM in reply to: ken.washburn

_gile, thanks for the suggestions.  I just tried Publish within Autocad and I get the same results (i.e. the dwf is blank).  However, 3DDWF does work.  I think I had the problem with both Publish and 3DDWF not working when I first installed Map 3D 2013 and got 3DDWF working after re-installing.  I will try a reinstall to see if I can get that piece working.

 

Otherwise, I think your code works fine.

 

 

Thanks again for your help!

 

Ken

Contributor
ken.washburn
Posts: 25
Registered: ‎06-10-2008
Message 10 of 12 (293 Views)

Re: Is there a way to create a 3D DWF from a drawing using VB.Net

07-17-2012 07:56 AM in reply to: ken.washburn

_gile, one more question.  I have everything working (the reinstall worked on the Publish command), except the naming (i.e. to drawingname-3D.dwf).  I don't see where in the Publish sub where it actually uses the dwfFile variable.  I see that it uses the dwgFile variable, but not the dwfFile variable. 

 

Thanks,

Ken

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community