Incorrect DWG to PDF export

1
Mikhael
3/27/2019 10:24 AM

Hello,

It seems, that I cannot export DWG file worksheets to PDF correctly. The drawing on output PDF file page looks very small.
Please look the source DWG file, output PDF and screenshot image file on:
http://download.print-driver.com/ex/mb/cadlib/files.rar

Please let me know if you need any additional info to reproduce and fix this issue.

Mikhael

Wout
3/28/2019 3:49 PM

Not sure if I fixed the problem what is causing your issue, since I can't see what you mean exactly. But there was a problem with MTEXT layout, which is now improved. Please download the latest version from Your resources in your user profile if your license is still valid.

- Wout

Mikhael
3/28/2019 5:00 PM

Thank you, Wout!

Wout
3/28/2019 5:26 PM

Ok, I see the scaling problem too now, overlooked the included PDF.

You have to change the following for exporting paper space layouts to PDF:

C# Code:
                    double scaleFactor = layout.StandardScaleFactor;
                    if (scaleFactor == 0d) {
                        scaleFactor = 1d;
                    }
                    bounds.Update((Point3D)(Vector3D)((Vector2D)plotAreaBounds.Min / scaleFactor));
                    bounds.Update((Point3D)(Vector3D)((Vector2D)plotAreaBounds.Max / scaleFactor));

Here's the complete PDF export example that I used:

C# Code:
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;

using WW.Cad.Base;
using WW.Cad.Drawing;
using WW.Cad.IO;
using WW.Cad.Model;
using WW.Cad.Model.Objects;
using WW.Cad.Model.Tables;
using WW.Math;
using WW.Math.Geometry;

namespace WW.Cad.Test.Examples {
    // This class demonstrates how to export an AutoCAD file to PDF (both model space and paper space layouts).
    public class PdfExporterExample {
        // Exports an AutoCAD file to PDF. For each layout a page in the PDF file is created.
        public static void ExportToPdf(string filename) {
            DxfModel model = CadReader.Read(filename, true);
            ExportToPdf(model);
        }

        // Exports an AutoCAD file to PDF. For each layout a page in the PDF file is created.
        public static void ExportToPdf(DxfModel model) {
            string filename = Path.GetFileName(model.Filename);
            string dir = Path.GetDirectoryName(model.Filename);
            string filenameNoExt = Path.GetFileNameWithoutExtension(filename);
            // as PDF
            using (FileStream stream = File.Create(Path.Combine(dir, filenameNoExt + ".pdf"))) {
                PdfExporter pdfExporter = new PdfExporter(stream);
                pdfExporter.EmbedFonts = true;

                GraphicsConfig config = (GraphicsConfig)GraphicsConfig.AcadLikeWithWhiteBackground.Clone();
                config.DisplayLineTypeElementShapes = true;
                config.TryDrawingTextAsText = true;

                foreach (DxfLayout layout in model.OrderedLayouts) {
                    AddLayoutToPdfExporter(pdfExporter, config, model, null, layout);
                }
                pdfExporter.EndDocument();
            }
        }

        // Exports the specified layout of an AutoCAD file to PDF.
        public static void ExportToPdf(DxfModel model, DxfLayout layout) {
            string filename = Path.GetFileName(model.Filename);
            string dir = Path.GetDirectoryName(model.Filename);
            string filenameNoExt = Path.GetFileNameWithoutExtension(filename);
            // as PDF
            using (FileStream stream = File.Create(Path.Combine(dir, filenameNoExt + "-" + layout.Name + ".pdf"))) {
                PdfExporter pdfExporter = new PdfExporter(stream);
                pdfExporter.EmbedFonts = true;

                GraphicsConfig config = (GraphicsConfig)GraphicsConfig.WhiteBackgroundCorrectForBackColor.Clone();
                config.DisplayLineTypeElementShapes = true;
                config.TryDrawingTextAsText = true;

                AddLayoutToPdfExporter(pdfExporter, config, model, null, layout);

                pdfExporter.EndDocument();
            }
        }

        // For each layout, add a page to the PDF file.
        // Optionally specify a modelView (for model space only).
        // Optionally specify a layout.
        public static void AddLayoutToPdfExporter(
            PdfExporter pdfExporter, GraphicsConfig config, DxfModel model, DxfView modelView, DxfLayout layout
        ) {
            Bounds3D bounds;
            const float defaultMargin = 0.5f;
            float margin = 0f;
            PaperSize paperSize = null;
            bool useModelView = false;
            bool emptyLayout = false;
            if (layout == null || !layout.PaperSpace) {
                // Model space.
                BoundsCalculator boundsCalculator = new BoundsCalculator();
                boundsCalculator.GetBounds(model);
                bounds = boundsCalculator.Bounds;
                if (bounds.Initialized) {
                    if (bounds.Delta.X > bounds.Delta.Y) {
                        paperSize = PaperSizes.GetPaperSize(PaperKind.A4Rotated);
                    } else {
                        paperSize = PaperSizes.GetPaperSize(PaperKind.A4);
                    }
                } else {
                    emptyLayout = true;
                }
                margin = defaultMargin;
                useModelView = modelView != null;
            } else {
                // Paper space layout.
                Bounds2D plotAreaBounds = layout.GetPlotAreaBounds(DxfLayout.DefaultGetEffectivePlotArea);
                bounds = new Bounds3D();
                emptyLayout = !plotAreaBounds.Initialized;
                if (plotAreaBounds.Initialized) {
                    double scaleFactor = layout.StandardScaleFactor;
                    if (scaleFactor == 0d) {
                        scaleFactor = 1d;
                    }
                    bounds.Update((Point3D)(Vector3D)((Vector2D)plotAreaBounds.Min / scaleFactor));
                    bounds.Update((Point3D)(Vector3D)((Vector2D)plotAreaBounds.Max / scaleFactor));

                    if (layout.PlotArea == PlotArea.LayoutInformation) {
                        switch (layout.PlotPaperUnits) {
                            case PlotPaperUnits.Millimeters:
                                paperSize = new PaperSize(Guid.NewGuid().ToString(), (int) (plotAreaBounds.Delta.X * 100d / 25.4d), (int) (plotAreaBounds.Delta.Y * 100d / 25.4d));
                                break;
                            case PlotPaperUnits.Inches:
                                paperSize = new PaperSize(Guid.NewGuid().ToString(), (int) (plotAreaBounds.Delta.X * 100d), (int) (plotAreaBounds.Delta.Y * 100d));
                                break;
                            case PlotPaperUnits.Pixels:
                                // No physical paper units. Fall back to fitting layout into a known paper size.
                                break;
                        }
                    }

                    if (paperSize == null) {
                        if (bounds.Delta.X > bounds.Delta.Y) {
                            paperSize = PaperSizes.GetPaperSize(PaperKind.A4Rotated);
                        } else {
                            paperSize = PaperSizes.GetPaperSize(PaperKind.A4);
                        }
                        margin = defaultMargin;
                    }
                }
            }

            if (!emptyLayout) {
                // Lengths in inches.
                float pageWidthInInches = paperSize.Width / 100f;
                float pageHeightInInches = paperSize.Height / 100f;

                double scaleFactor;
                Matrix4D to2DTransform;
                if (useModelView) {
                    to2DTransform = modelView.GetMappingTransform(
                        new Rectangle2D(
                            margin * PdfExporter.InchToPixel,
                            margin * PdfExporter.InchToPixel,
                            (pageWidthInInches - margin) * PdfExporter.InchToPixel,
                            (pageHeightInInches - margin) * PdfExporter.InchToPixel),
                        false);
                    scaleFactor = double.NaN; // Not needed for model space.
                } else {
                    to2DTransform = DxfUtil.GetScaleTransform(
                        bounds.Corner1,
                        bounds.Corner2,
                        new Point3D(bounds.Center.X, bounds.Corner2.Y, 0d),
                        new Point3D(new Vector3D(margin, margin, 0d) * PdfExporter.InchToPixel),
                        new Point3D(new Vector3D(pageWidthInInches - margin, pageHeightInInches - margin, 0d) * PdfExporter.InchToPixel),
                        new Point3D(new Vector3D(pageWidthInInches / 2d, pageHeightInInches - margin, 0d) * PdfExporter.InchToPixel),
                        out scaleFactor
                        );
                }
                if (layout == null || !layout.PaperSpace) {
                    pdfExporter.DrawPage(model, config, to2DTransform, paperSize, ReportProgress);
                } else {
                    pdfExporter.DrawPage(model, config, to2DTransform, scaleFactor, layout, null, paperSize, ReportProgress);
                }
            }
        }

        private static void ReportProgress(object sender, ProgressEventArgs e) {
            Console.WriteLine("{0}%", (int)System.Math.Round(e.Progress * 100d));
        }
    }
}

Not sure if this scale factor is applied in all scenarios, we'll see.

- Wout

Mikhael
3/29/2019 10:52 AM

Hello Wout,

I tested new CADLib binaries and your C# code and see, that I'm unable to export part of layouts of few DWG files I have in my collection.

As example, if I try convert "C21000PL1.dwg" to PDF, I see, that "PL1" layout exported as empty page in PDF file.

The same result I see if I try convert "20180118_Chinchilla_Final Design_based 38769_DET_Comb.dwg" to PDF. Only "Model" worksheet is exported correctly. Both layouts this file contains looks like empty pages in output PDF file.

Please follow link below to download DWG files I used for this test and let me know if you have any idea how to force CADLib to export them to correct PDF files.
http://download.print-driver.com/ex/mb/cadlib/cadlib-dwg.rar

Mikhael

Mikhael
3/29/2019 12:07 PM

Additionally, if I try convert "AR11_A1_01.DWG" I attached to PDF, 2-nd page of this PDF looks incorrectly. Drawing on this page is not centered and cropped.

Mikhael

Wout
3/29/2019 2:48 PM

Hi,

I've made some changes again, the scaling was still incorrect, it should be this instead:

C# Code:
                    double customScaleFactor = 1d;
                    if ((layout.PlotLayoutFlags & PlotLayoutFlags.UseStandardScale) == 0 && (layout.CustomPrintScaleNumerator != 0d && layout.CustomPrintScaleDenominator != 0d)) {
                        customScaleFactor = layout.CustomPrintScaleNumerator / layout.CustomPrintScaleDenominator;
                    }
                    bounds.Update((Point3D)(Vector3D)((Vector2D)plotAreaBounds.Min / customScaleFactor));
                    bounds.Update((Point3D)(Vector3D)((Vector2D)plotAreaBounds.Max / customScaleFactor));

Also you need to download the latest CadLib version.

- Wout

Mikhael
3/29/2019 3:51 PM

Hi Wout,

Works better now. But pages 2 and 3 are still empty if I try convert file "20180118_Chinchilla_Final Design_based 38769_DET_Comb.dwg" to PDF:
http://download.print-driver.com/ex/mb/cadlib/20180118-Chinchilla.rar

Mikhael

Wout
4/4/2019 12:01 AM

Hi,

Try this one, there seems to be a very specific condition when the custom print scale is used, not sure if this is correct, but it works on the drawings you provided:

C# Code:
                    double customScaleFactor = 1d;
                    if (
                        (layout.PlotLayoutFlags & PlotLayoutFlags.UseStandardScale) == 0 && 
                        (layout.PlotArea == PlotArea.LayoutInformation) && 
                        (layout.CustomPrintScaleNumerator != 0d && layout.CustomPrintScaleDenominator != 0d)
                    ) {
                        customScaleFactor = layout.CustomPrintScaleNumerator / layout.CustomPrintScaleDenominator;
                    }
                    bounds.Update((Point3D)(Vector3D)((Vector2D)plotAreaBounds.Min / customScaleFactor));
                    bounds.Update((Point3D)(Vector3D)((Vector2D)plotAreaBounds.Max / customScaleFactor));

- Wout

Mikhael
4/5/2019 11:52 AM

Hi Wout,

Works better now. Thank you!

Mikhael

1