How to plot OLE objects in a side database?

luckyboy82292
Enthusiast
Enthusiast

How to plot OLE objects in a side database?

luckyboy82292
Enthusiast
Enthusiast

Hey there!

In the CAD file, there are certain OLE objects. But when I use my application to plot the file into a PDF, these OLE objects don't show up in the final output. It's important for these objects to appear in the plot accurately. I'm reaching out for help to fix this issue and ensure that the plotted PDF reflects all elements from the original CAD file.

0 Likes
Reply
Accepted solutions (1)
535 Views
7 Replies
Replies (7)

luckyboy82292
Enthusiast
Enthusiast

Please, could someone shed some light on this issue? Thank you!

0 Likes

luckyboy82292
Enthusiast
Enthusiast
Please, could someone shed some light on this issue? Thank you!
0 Likes

ed57gmc
Mentor
Mentor

I haven't tried plotting OLE because I stay away from it as much as possible. But if you tried a normal plot and it doesn't work, then how about trying to plot using AcCoreConsole rather than a side database? When you ask a question, it's best if you post the code you have.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes

luckyboy82292
Enthusiast
Enthusiast

This is the code:

 

using Autodesk.AutoCAD.Runtime;
using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.PlottingServices;
using System;
using System.IO;
using System.Windows.Forms;

namespace PlotMultiDrawingsToPdf
{
    public class PlotMultipleDWGFilesToPDF : IExtensionApplication
    {
        #region
        public void Initialize()
        {
            
        }
        public void Terminate()
        {

        }
        #endregion

        [CommandMethod("OO")]

        public void ProcessFilesSelection()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var openFileDialog = new Autodesk.AutoCAD.Windows.OpenFileDialog
                ("Select Drawing Files",
                "",
                "dwg",
                "",
                Autodesk.AutoCAD.Windows.OpenFileDialog.OpenFileDialogFlags.AllowMultiple
                );

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                var layerName = string.Empty;
                while (string.IsNullOrEmpty(layerName))
                {
                    var layResult = ed.GetString("\nSpecify the layer name: ");
                    if (layResult.Status != PromptStatus.OK)
                    {
                        MessageBox.Show($"\nOperation has been canceled by the User. ");
                        return;
                    }
                    layerName = layResult.StringResult.Trim();
                    if (string.IsNullOrEmpty(layerName))
                    {
                        ed.WriteMessage("\nThe layer name wasn't specified. Please enter a valid layer name. ");
                    }
                }
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
                    var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead, false) as BlockTableRecord;
                    var lo = tr.GetObject(btr.LayoutId, OpenMode.ForRead, false) as Layout;
                    
                    foreach (var file in openFileDialog.GetFilenames())
                    {
                        PlotToPDF(file, layerName, lo);
                    }

                    tr.Commit();
                }
            }
            else
            {
                MessageBox.Show("\nAt least one file must be selected to continue. ");
                return;
            }
        }
        static void PlotToPDF(string fileName, string layerName, Layout curLay)
        {
            var ed = Application.DocumentManager.MdiActiveDocument.Editor;

            var path = Path.GetDirectoryName(fileName) + "\\PDF Sections\\";
            var fName = Path.GetFileNameWithoutExtension(fileName);
            var bgPlot = Application.GetSystemVariable("Backgroundplot");
            Application.SetSystemVariable("Backgroundplot", 0);

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);

            }

            try
            {
                Unnamed.ProcessDwg(fileName, db =>
                {
                    var point0 = new Point2d();
                    var point2 = new Point2d();
                    using (var tr = db.TransactionManager.StartTransaction())
                    {
                        var lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead, false);
                        if (lt.Has(layerName))
                        {
                            layerName = layerName.Trim();
                        }
                        else
                        {
                            MessageBox.Show($"\nThe layer \"{layerName}\" does not exist in the selected drawing file: {Path.GetFileNameWithoutExtension(fileName)}.");
                            return;
                        }

                        var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false);
                        var btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead, false);

                        foreach (ObjectId objId in btr)
                        {
                            Polyline obj = tr.GetObject(objId, OpenMode.ForRead, false) as Polyline;
                            if (obj != null && obj is Polyline polyline && polyline.NumberOfVertices == 4 && string.Equals(polyline.Layer, layerName, StringComparison.OrdinalIgnoreCase))
                            {
                                point0 = polyline.GetPoint2dAt(0);
                                point2 = polyline.GetPoint2dAt(2);
                                break;
                            }
                        }
                        Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead, false);
                        PlotToPDF(lo, curLay, point0, point2, path, fName);
                    }
                    Application.SetSystemVariable("Backgroundplot", bgPlot);
                });
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage($"\nError1: {ex.Message}\n{ex.StackTrace}");
            }
        }
        static void PlotToPDF(Layout lo, Layout curLay, Point2d point0, Point2d point2, string path, string fileName)
        {
            var pw = new Extents2d(point0, point2);

            try
            {
                using (PlotInfo pi = new PlotInfo())
                {
                    pi.Layout = lo.ObjectId;
                    using (PlotSettings ps = new PlotSettings(lo.ModelType))
                    {
                        ps.CopyFrom(curLay);
                        PlotSettingsValidator psv = PlotSettingsValidator.Current;
                        psv.SetPlotWindowArea(ps, pw);
                        psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
                        psv.SetUseStandardScale(ps, true);
                        psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
                        psv.SetPlotCentered(ps, true);
                        pi.OverrideSettings = ps;
                        using (PlotInfoValidator piv = new PlotInfoValidator())
                        {
                            piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
                            piv.Validate(pi);
                            if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
                            {
                                using (PlotEngine pe = PlotFactory.CreatePublishEngine())
                                {
                                    // Track the plot progress with a Progress dialog
                                    using (PlotProgressDialog pd = new PlotProgressDialog(false, 1, true))
                                    {
                                        using (pd)
                                        {
                                            // Define the status messages to display 
                                            // when plotting starts
                                            pd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "Plot Progress");
                                            pd.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "Cancel Job");
                                            pd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "Cancel Sheet");
                                            pd.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "Sheet Set Progress");
                                            pd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "Sheet Progress");

                                            // Set the plot progress range
                                            pd.LowerPlotProgressRange = 0;
                                            pd.UpperPlotProgressRange = 100;
                                            pd.PlotProgressPos = 0;

                                            // Display the Progress dialog
                                            pd.OnBeginPlot();
                                            pd.IsVisible = true;

                                            // Start to plot the layout
                                            pe.BeginPlot(pd, null);

                                            // Define the plot output
                                            pe.BeginDocument(pi, fileName, null, 1, true, path + fileName + ".pdf");

                                            // Display information about the current plot
                                            pd.set_PlotMsgString(PlotMessageIndex.SheetName, "Plotting: " + fileName + " - " + lo.LayoutName);

                                            // Set the sheet progress range
                                            pd.OnBeginSheet();
                                            pd.LowerSheetProgressRange = 0;
                                            pd.UpperSheetProgressRange = 100;
                                            pd.SheetProgressPos = 0;

                                            // Plot the first sheet/layout
                                            using (PlotPageInfo acPlPageInfo = new PlotPageInfo())
                                            {
                                                pe.BeginPage(acPlPageInfo, pi, true, null);
                                            }

                                            pe.BeginGenerateGraphics(null);
                                            pe.EndGenerateGraphics(null);

                                            // Finish plotting the sheet/layout
                                            pe.EndPage(null);
                                            pd.SheetProgressPos = 100;
                                            pd.OnEndSheet();

                                            // Finish plotting the document
                                            pe.EndDocument(null);

                                            // Finish the plot
                                            pd.PlotProgressPos = 100;
                                            pd.OnEndPlot();
                                            pe.EndPlot(null);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                var ed = Application.DocumentManager.MdiActiveDocument.Editor;
                ed.WriteMessage($"\nError: {ex.Message}\n{ex.StackTrace}");
            }
        }

    }

    public static class Unnamed
    {
        public static void ProcessDwg(string fileName, Action<Database> action)
        {
            try
            {
                using (var db = new Database(false, true))
                {
                    db.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, false, null);
                    using (new WorkingDatabase(db))
                    {
                        action(db);
                    }
                }
            }
            catch (System.Exception ex)
            {
                var ed = Application.DocumentManager.MdiActiveDocument.Editor;
                ed.WriteMessage($"\nError with '{fileName}': {ex.Message}");
            }
        }
    }

    public class WorkingDatabase : IDisposable
    {
        Database previous;

        public WorkingDatabase(Database newWorkingDb)
        {
            if (newWorkingDb == null)
                throw new ArgumentNullException(nameof(newWorkingDb));
            Database current = HostApplicationServices.WorkingDatabase;
            if (newWorkingDb != current)
            {
                previous = current;
                HostApplicationServices.WorkingDatabase = newWorkingDb;
            }
        }

        public void Dispose()
        {
            if (previous != null)
            {
                HostApplicationServices.WorkingDatabase = previous;
                previous = null;
            }
        }
    }
}

 

0 Likes

ed57gmc
Mentor
Mentor

A couple of questions

1. If you use the same plot settings with an open dwg, does the OLE plot?

2. Is the correct window plotting, just not the OLE? The reason I ask is because of the following lines:

foreach (ObjectId objId in btr)
                        {
                            Polyline obj = tr.GetObject(objId, OpenMode.ForRead, false) as Polyline;
                            if (obj != null && obj is Polyline polyline && polyline.NumberOfVertices == 4 && string.Equals(polyline.Layer, layerName, StringComparison.OrdinalIgnoreCase))
                            {
                                point0 = polyline.GetPoint2dAt(0);
                                point2 = polyline.GetPoint2dAt(2);
                                break;
                            }
                        }

It seems that you are trying to get the extents of all plines. However, this will only store the results of the last pline examined in the loop. Thus, the OLE may be out of view.

 

Also, in the following line, Application is a type belonging to both System.Windows and Autodesk.AutoCAD.ApplicationServices, thus using it would be ambiguous. You should avoid naming variables the same as a type. Typically, we use something like "acApp".

using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;

 

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes

luckyboy82292
Enthusiast
Enthusiast
Accepted solution

I have changed my mind & and used AcCoreConsole for batch plot. And worked for me. But works little bit slow.

using Autodesk.AutoCAD.Runtime;
using acApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
using Autodesk.AutoCAD.DatabaseServices;
using System.Windows.Forms;
using Autodesk.AutoCAD.EditorInput;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;

public class PlotMultipleDWGFilesToPDF : IExtensionApplication
{
    #region
    public void Initialize()
    {

    }
    public void Terminate()
    {

    }
    #endregion

    [CommandMethod("OO")]

    public void ProcessFilesSelection()
    {
        var docs = acApp.DocumentManager;
        var acDoc = docs.MdiActiveDocument;
        var ed = acDoc.Editor;
        string ver = GetInstalledAutoCADVersion();
        string cadPath = GetInstalledAutoCADPath();
        string accoreconsole = Path.Combine(cadPath, "accoreconsole.exe");
        AutoCADVersionChecker checker = new AutoCADVersionChecker();
        if (!(ver != null) || !checker.IsVersionEqualOrGreater(ver, "R20"))
        {
            MessageBox.Show($"\nThe application only works with AutoCAD 2020 or later ");
            return;
        }
        using (var db = acDoc.Database)
        {
            try
            {
                var openFileDialog = new Autodesk.AutoCAD.Windows.OpenFileDialog
                    ("Select Drawing Files",
                    "",
                    "dwg",
                    "",
                    Autodesk.AutoCAD.Windows.OpenFileDialog.OpenFileDialogFlags.AllowMultiple
                    );

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    var layerName = string.Empty;
                    while (string.IsNullOrEmpty(layerName))
                    {
                        var layResult = ed.GetString("\nSpecify the layer name: ");
                        if (layResult.Status != PromptStatus.OK)
                        {
                            MessageBox.Show($"\nOperation has been canceled by the User. ");
                            return;
                        }
                        layerName = layResult.StringResult.Trim();
                        if (string.IsNullOrEmpty(layerName))
                        {
                            ed.WriteMessage("\nThe layer name wasn't specified. Please enter a valid layer name. ");
                        }
                    }
                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
                        var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead, false) as BlockTableRecord;
                        var lo = tr.GetObject(btr.LayoutId, OpenMode.ForRead, false) as Layout;
                        var plotter = lo.PlotConfigurationName;
                        var pageSize = lo.CanonicalMediaName.Replace("_", " ");
                        var plotStyle = lo.CurrentStyleSheet;
                        var dir = Path.GetDirectoryName(openFileDialog.GetFilenames()[0]);
                        var path = Path.Combine(dir + "\\PDF\\");
                        var repPath = path.Replace($"\\", $"\\\\");
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }

                        foreach (string file in openFileDialog.GetFilenames())
                        {

                            var scriptFile = CreateScriptFile(layerName, plotter, pageSize, plotStyle, repPath + Path.GetFileNameWithoutExtension(file));
                            ProcessScripts(accoreconsole, file, scriptFile);

                        }

                        tr.Commit();
                    }
                }
                else
                {
                    MessageBox.Show("\nAt least one file must be selected to continue. ");
                    return;
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage($"\nError: {ex.Message}\n{ex.StackTrace}");
            }
        }
    }
    public string GetInstalledAutoCADPath()
    {
        string path = "";
        try
        {
            string autoCADVersionKey = GetInstalledAutoCADVersion();
            if (!string.IsNullOrEmpty(autoCADVersionKey))
            {
                string keyPath = @"SOFTWARE\Autodesk\AutoCAD\" + autoCADVersionKey;
                path = SearchSubKeysForKey(keyPath, "InstallDir");
                if (string.IsNullOrEmpty(path))
                {
                    path = SearchSubKeysForKey(keyPath, "AcadLocation");
                }
            }
        }
        catch (System.Exception ex)
        {
            path = "Error: " + ex.Message;
        }
        return path;
    }

    private string SearchSubKeysForKey(string keyPath, string valueName)
    {
        string result = "";
        using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyPath))
        {
            if (key != null)
            {
                foreach (string subKeyName in key.GetSubKeyNames())
                {
                    using (RegistryKey subKey = key.OpenSubKey(subKeyName))
                    {
                        if (subKey != null)
                        {
                            object value = subKey.GetValue(valueName);
                            if (value != null)
                            {
                                result = value.ToString();
                                break;
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

    public string GetInstalledAutoCADVersion()
    {
        string version = "";
        try
        {
            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Autodesk\AutoCAD"))
            {
                if (key != null)
                {
                    string[] subKeyNames = key.GetSubKeyNames();
                    foreach (string subKeyName in subKeyNames)
                    {
                        if (subKeyName.StartsWith("R"))
                        {
                            version = subKeyName;
                            break;
                        }
                    }
                }
            }
        }
        catch (System.Exception ex)
        {
            version = "Error: " + ex.Message;
        }
        return version;
    }

    private static string CreateScriptFile(string layerName, string plotter, string size, string style, string path)
    {
        string tempFolder = Path.GetTempPath();
        string scriptFolder = Path.Combine(tempFolder, "AutoCAD_Scripts");
        string scriptFile = Path.Combine(scriptFolder, "AutoCAD_Script.scr");

        if (!Directory.Exists(scriptFolder))
        {
            try
            {
                Directory.CreateDirectory(scriptFolder);
                Console.WriteLine($"Script folder created at: {scriptFolder}");
            }
            catch (System.Exception ex)
            {
                Console.WriteLine($"Error creating script folder: {ex.Message}");
            }
        }

        string[] scriptContent = {
            $"(setvar \"cmdecho\" 0)",
            $"(setvar \"filedia\" 0)",
            $"(setq vertices nil)",
            $"(setq layFilter (list (cons 8 \"{layerName}\")))",
            $"(setq ss (ssget \"X\" layFilter))",
            $"(if ss",
            $"(progn",
            $"(setq sslen (sslength ss))",
            $"(setq i 0)",
            $"(repeat sslen",
            $"(setq ent (ssname ss i))",
            $"(if (and (= (cdr (assoc 0 (entget ent))) \"LWPOLYLINE\") (= 4 (cdr (assoc 90 (entget ent)))))",
            $"(progn",
            $"(foreach d (entget ent)",
            $"(if (= 10 (car d))",
            $"(progn",
            $"(setq vertex (cdr d))",
            $"(setq vertices (append (list vertex) vertices)))))))",
            $"(setq i (1+ i)))",
            $"(setq minListX (vl-sort vertices '(lambda (a b) (< (car a) (car b)))))",
            $"(setq minListY (vl-sort vertices '(lambda (a b) (< (cadr a) (cadr b)))))",
            $"(setq minPoint (list (car (car minListX)) (cadr (car minListY))))",
            $"(setq maxListX (vl-sort vertices '(lambda (a b) (> (car a) (car b)))))",
            $"(setq maxListY (vl-sort vertices '(lambda (a b) (> (cadr a) (cadr b)))))",
            $"(setq maxPoint (list (car (car maxListX)) (cadr (car maxListY))))))",
            //$"(command \"Zoom\" \"w\" minPoint maxPoint)",
            $"(command \"-Plot\" \"y\" \"\" \"{plotter}\" \"{size}\" \"\" \"\" \"\" \"w\" minPoint maxPoint \"f\" \"c\" \"y\" \"{style}\" \"\" \"\" \"{path}\" \"y\" \"y\")",
            //$"(command \"qsave\")",
            $"(setvar \"filedia\" 1)",
            $"(setvar \"cmdecho\" 1)",
            $"quit",
            $"y"
        };

        try
        {
            File.WriteAllLines(scriptFile, scriptContent);
            Console.WriteLine($"Script file created at: {scriptFile}");
        }
        catch (System.Exception ex)
        {
            Console.WriteLine($"Error creating script file: {ex.Message}");
        }
        return scriptFile;
    }

    private static void ProcessScripts(string AcCoreConsolePath, string fileName, string scriptFile)
    {
        ProcessStartInfo psi = new ProcessStartInfo(AcCoreConsolePath)
        {
            Arguments = $"/i \"{fileName}\" /s \"{scriptFile}\" /l en-us",
            UseShellExecute = false,
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            CreateNoWindow = true
        };

        using (Process process = new Process())
        {
            process.StartInfo = psi;
            process.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data);
            process.ErrorDataReceived += (sender, e) => Console.WriteLine(e.Data);

            process.Start();
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();

            Console.WriteLine("Process finished.");
        }
    }

}
public class AutoCADVersionChecker
{
    public bool IsVersionEqualOrGreater(string versionToCheck, string targetVersion)
    {
        // Extract version numbers after "R"
        int versionNumberToCheck = ExtractVersionNumber(versionToCheck);
        int targetVersionNumber = ExtractVersionNumber(targetVersion);

        // Compare versions
        return versionNumberToCheck >= targetVersionNumber;
    }

    private int ExtractVersionNumber(string version)
    {
        // Extract version number after "R" using regular expression
        Match match = Regex.Match(version, @"R(\d+)");
        if (match.Success && match.Groups.Count > 1)
        {
            return int.Parse(match.Groups[1].Value);
        }
        throw new ArgumentException("Invalid version format");
    }
}
0 Likes

luckyboy82292
Enthusiast
Enthusiast

Actually the problem was here.

using (var db = new Database(false, true))

I changed the second parameter to false and it worked. Now my application is plotting the OLE objects. However, another problem persists. When I plot with the acad.ctb style, it generates black and white plots.

0 Likes