.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

11 REPLIES 11
SOLVED
Reply
Message 1 of 12
ken.washburn
1353 Views, 11 Replies

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

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

11 REPLIES 11
Message 2 of 12
adam
in reply to: ken.washburn

Hi Ken,

 

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

 

Adam

Message 3 of 12
ken.washburn
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

Message 4 of 12
_gile
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
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 12
_gile
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
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 12
ken.washburn
in reply to: _gile

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

 

Ken

Message 7 of 12
ken.washburn
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

 

Message 8 of 12
_gile
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
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 12
ken.washburn
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

Message 10 of 12
ken.washburn
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

Message 11 of 12
_gile
in reply to: ken.washburn

Oopss !...

i removed a DsdData setting I shouldn't: DsdData.DestinationName. This isn't required while DsdData.SheetType = SheetType.SingleDwf (this forces the output file name to be the same as the input dwg).

 

Here's a VB code which seems to work as you expect:

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.Combine(outputDir, title & "-3d.dwf") ' <- add the "-3d" suffix to the file name
            dsdFile = Path.ChangeExtension(dwfFile, ".dsd")
        End Sub

        Public Sub New(outputDir As String)
            Me.New()
            Me.outputDir = outputDir
            dwfFile = Path.Combine(outputDir, title & "-3d.dwf")
        End Sub

        Public Sub Publish()
            Dim bgPlot As Short = CShort(Application.GetSystemVariable("BACKGROUNDPLOT"))
            Application.SetSystemVariable("BACKGROUNDPLOT", 0)
            Try
                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.MultiDwf
                        dsd.NoOfCopies = 1
                        dsd.ProjectPath = outputDir
                        dsd.DestinationName = dwfFile
                        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)
                    End Using
                End Using
            Finally
                Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot)
            End Try
        End Sub
    End Class
End Namespace

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 12 of 12
ken.washburn
in reply to: _gile

_gile, Thanks for the update!  I'm still having issues, but I'm thinking it is something with my drawings or system.  I ran it on four drawings yesterday and it created dwf files for two of them, but not the other two.  Of the two it created, one was blank and one was ok.  So I'll research this more on my end, but I think your code is working correctly.

 

Thanks again!

Ken

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost