I want to Get multi region on dwg to pdf files in different pages,so I try code below.
totalflatimage = "";
if (Directory.Exists(directory))
Directory.Delete(directory, true);
Directory.CreateDirectory(directory);
List<string> imagelist = new List<string>();
List<FrameAttributeExtend> entitylist = GetFrameEntity(title);
Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
Transaction acTrans = acCurDb.TransactionManager.StartTransaction();
object iSysp = AcadApplication.GetSystemVariable("PUBLISHCOLLATE");
try
{
object iSys = AcadApplication.GetSystemVariable("BACKGROUNDPLOT");
using (acTrans)
{
int flag = 1;
PlotInfoValidator piv = new PlotInfoValidator();
piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
AcadApplication.SetSystemVariable("PUBLISHCOLLATE", 1);
if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
{
PlotEngine pe = PlotFactory.CreatePublishEngine();
using (pe)
{
PlotProgressDialog ppd = new PlotProgressDialog(false, entitylist.Count, true);
using (ppd)
{
foreach (var frame in entitylist)
{
LayoutManager acLayoutMgr = LayoutManager.Current;
Layout acLayout = (Layout)acTrans.GetObject(acLayoutMgr.GetLayoutId(acLayoutMgr.CurrentLayout), OpenMode.ForRead);
PlotInfo pi = new PlotInfo() { Layout = acLayout.ObjectId };
PlotSettings ps = new PlotSettings(acLayout.ModelType);
ps.CopyFrom(acLayout);
PlotSettingsValidator psv = PlotSettingsValidator.Current;
psv.SetPlotType(ps, PlotType.Extents);
psv.SetUseStandardScale(ps, true);
psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
psv.SetPlotCentered(ps, true);
System.Collections.Specialized.StringCollection sc = psv.GetPlotStyleSheetList();
psv.SetCurrentStyleSheet(ps, "demoplotstyle.ctb");
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
string entityscale = frame.Scale;
string vertial = frame.IsVertial;
string picindex = frame.ImageIndex;
string imagename = "";
if (frame.ImageType == 0)
{
imagename = string.Format("1-{0}-{1}-{2}.pdf", entityscale, vertial, picindex);
totalflatimage = directory + imagename;
}
else
{
imagename = string.Format("2-{0}-{1}-{2}.pdf", entityscale, vertial, picindex);
imagelist.Add(directory + imagename);
}
if (vertial == "0")
{
psv.SetPlotConfigurationName(ps, "DWG To PDF.pc3", "ISO_expand_A4_(297.00_x_210.00_mm)");
psv.SetPlotRotation(ps, PlotRotation.Degrees000);
}
else
{
psv.SetPlotConfigurationName(ps, "DWG To PDF.pc3", "ISO_expand_A4_(210.00_x_297.00_mm)");
psv.SetPlotRotation(ps, PlotRotation.Degrees000);
}
ps.ShowPlotStyles = true;
Extents3d extents3d = frame.Extent;
double h = double.Parse(entityscale) * 6;
double x = extents3d.MinPoint.X + unit * 2;
double y = extents3d.MaxPoint.Y + h + unit;
if (unit == 1)
{
x = extents3d.MinPoint.X + unit * 1;
y = extents3d.MaxPoint.Y + double.Parse(entityscale) / 250 + unit * 2;
}
Extents2d E2d = new Extents2d(x, extents3d.MinPoint.Y, extents3d.MaxPoint.X, y);
psv.SetPlotWindowArea(ps, E2d);
psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
pi.OverrideSettings = ps;
piv.Validate(pi);
if (flag == 1)
{
ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "pdf export");
ppd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "cancel");
ppd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "progress");
ppd.LowerPlotProgressRange = 0;
ppd.UpperPlotProgressRange = 100;
ppd.PlotProgressPos = 0;
ppd.OnBeginPlot();
ppd.IsVisible = true;
pe.BeginPlot(ppd, null);
pe.BeginDocument(pi, acDoc.Name, null, 1, true, directory + imagename);
//pe.BeginDocument(pi, acDoc.Name, null, 1, true, directory + imagename);
}
//pe.BeginDocument(pi, acDoc.Name, null, 1, true, directory + imagename);
ppd.set_PlotMsgString(PlotMessageIndex.Status, string.Format("Now the page of{0}", flag));
ppd.OnBeginSheet();
ppd.LowerSheetProgressRange = 0;
ppd.UpperSheetProgressRange = 100;
ppd.SheetProgressPos = 0;
PlotPageInfo ppi = new PlotPageInfo();
pe.BeginPage(ppi, pi, flag == entitylist.Count, null);
pe.BeginGenerateGraphics(null);
ppd.SheetProgressPos = 50;
pe.EndGenerateGraphics(null);
pe.EndPage(null);
ppd.SheetProgressPos = 100;
ppd.OnEndSheet();
flag++;
}
pe.EndDocument(null);
ppd.PlotProgressPos = 100;
ppd.OnEndPlot();
pe.EndPlot(null);
}
}
}
}
while (PlotFactory.ProcessPlotState != ProcessPlotState.NotPlotting)
continue;
MessageBox.Show("The Plot Is Complated!");
return imagelist;
}
catch (Exception ex)
{
return null;
}
finally
{
AcadApplication.SetSystemVariable("PUBLISHCOLLATE", iSysp);
acTrans.Dispose();
}
And finally I got a pdf file, but only one page.
In my test, I use about 4 region in total.
Explanation:
The FrameAttributeExtend contains the region info in dwg files.
Wish to Get help from you guys!
Thank you!
Solved! Go to Solution.
If code is inserted into the post in a good format (using "{ i }" icon on the message composing window), it would have been much easier to get more poeple in interest reading through it :smileysad 😞
Anyway, I saw the code saved system variable "BACKGROUNDPLOT" value. I guess you are intended to set its value to 0 for your plotting process and then restore it afterwards. However, in your code you did not set it to 0 anywhere before your plotting starts. So, firstly try to set "BACKGROUNDPLOT" to 0, this is critical to your programmtic plotting.
Also, in order to plot to multiple page PDF with "DWG to PDF.pc3", all the output layout/window must be plotted to the same paper size. In your case, you used 2 paper sizes in spite the phsical sizes of the 2 papers are the same. While I am not very sure on this particular situation, it could be a problem. In one of mt plotting app, becase of the plotting paper sizes could be different in the same multiple PDF, I chose to plot each sheet into separate PDF file and then stitch them together into one PDF (using itextshar.dll, which is also used by AutoCAD itself). Or you can look into PUBLISH api.
Norman Yuan
Hi,
Maybe you can get some inspiration from this reply:
https://www.theswamp.org/index.php?topic=31897.msg494504#msg494504
Hi, your links is useful
But I got some problem when I tried to get multi Layout from current Layout.
Wolud you please tell me how I can create a new Layout from current dwg file between two points((0,0) and (1000,1000) for example)?
I wanna to export different region of the dwg files to pdf files so I can get them together to a report.
And I tried below code
LayoutManager acLayoutMgr = LayoutManager.Current;
Layout acLayout = (Layout)acTrans.GetObject(acLayoutMgr.GetLayoutId(acLayoutMgr.CurrentLayout), OpenMode.ForRead);
string layoutname = "testpdf";
ObjectId id = LayoutManager.Current.CreateLayout(layoutname );
Layout newlay = acTrans.GetObject(id, OpenMode.ForWrite) as Layout;
newlay.CopyFrom(acLayout);
I always get a error,Autodesk.AutoCAD.Runtime.Exception: eWrongObjectType
if you want to plot different parts of the same drawing, I wouldn't use a new layout... you would also need a viewport and you'll also need to clean up after.
Why don't you use PlotsettingValidator functions? Something like this:
psv.SetPlotOrigin(ps, new Point2d(xMin, yMin)); psv.SetPlotWindowArea(ps, new Extents2d(xMin, yMin, xMax, yMax)); psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
where psv is a PlotSettingsValidator objest and ps is a PlotSettings object, that you can use to initialize different pages...
Well don't see why you need to initialize PlotEngine more than once...
Here a simplified code that works for multipage PDF and multiple layouts. I believe you can adapt it for your needings.
int numSheet = 0; // Initialize plot progress dialog PlotProgressDialog ppd = new PlotProgressDialog(false, layoutsToPlot.Count, true); using (ppd) { // localize messages (if needed) //ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "Avanzamento stampa..."); ppd.OnBeginPlot(); ppd.IsVisible = true; // init Engine (once) PlotEngine pe = PlotFactory.CreatePublishEngine(); pe.BeginPlot(ppd, null); ppd.StatusMsgString = "Plotting..."; // add name of document, if you need it ppd.OnBeginSheet(); ppd.LowerSheetProgressRange = 0; ppd.UpperSheetProgressRange = 100; ppd.SheetProgressPos = 0; // this is a multipage sample for multiple layouts, but if // you have multiple windows of the current layout of even ModelSpace // just make your changes...
foreach (ObjectId btrId in layoutsToPlot) { numSheet++; ppd.SheetProgressPos = numSheet * 100 / layoutsToPlot.Count; // get layout and its extents BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead); Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead); pMin = lo.Extents.MinPoint; pMax = lo.Extents.MaxPoint; // make it current LayoutManager.Current.CurrentLayout = lo.LayoutName; // Every layout may need different plot settings, media, scale, rotation, etc.. PlotSettings ps = new PlotSettings(lo.ModelType); ps.CopyFrom(lo); // ... and a new PlotInfo as well PlotInfo pi = new PlotInfo(); pi.Layout = btr.LayoutId; // The PlotSettingsValidator helps create a valid PlotSettings object PlotSettingsValidator psv = PlotSettingsValidator.Current; // you may need to assign a specific plot style (.ctb or .stb) if (szStyle.Length > 0) { System.Collections.Specialized.StringCollection sc = psv.GetPlotStyleSheetList(); foreach (String szStyleFullName in sc) { if (System.IO.Path.GetFileName(szStyleFullName) == szStyle) { psv.SetCurrentStyleSheet(ps, szStyleFullName); break; } } } ps.ScaleLineweights = false; // here we want a centered plot of the layout extents, // but you can set a Window plot as well... psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents); psv.SetUseStandardScale(ps, true); psv.SetStdScaleType(ps, eScale); psv.SetPlotCentered(ps, bCentrapagina); //psv.SetPlotPaperUnits(ps, PlotPaperUnit.Millimeters); //psv.SetPlotOrigin(ps, new Point2d(xMin, yMin)); //psv.SetPlotWindowArea(ps, new Extents2d(xMin, yMin, xMax, yMax)); //psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window); // here we need to choose the best orientation bool bPaperIsLandscape; bool bAreaIsLandscape; if (lo.ModelType) bAreaIsLandscape = (dwg.Extmax.X - dwg.Extmin.X) > (dwg.Extmax.Y - dwg.Extmin.Y) ? true : false; else bAreaIsLandscape = (lo.Extents.MaxPoint.X - lo.Extents.MinPoint.X) > (lo.Extents.MaxPoint.Y - lo.Extents.MinPoint.Y) ? true : false; // choose the right media, if media not specified, choose the best one szMedia = _PlotSetMedia(szPlotterName, szMedia, lo, ps, psv); // set orientation based on paper and windows to be plot bPaperIsLandscape = (ps.PlotPaperSize.X > ps.PlotPaperSize.Y) ? true : false; if (bPaperIsLandscape != bAreaIsLandscape) psv.SetPlotRotation(ps, PlotRotation.Degrees270); pi.OverrideSettings = ps; // parameters validation required PlotInfoValidator piv = new PlotInfoValidator(); piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled; piv.Validate(pi); if (numSheet == 1) // first page? initialize document { pe.BeginDocument(pi, szDocName, null, 1, true, szOutFile); } // init current page PlotPageInfo ppi = new PlotPageInfo(); pe.BeginPage(ppi, pi, (numSheet == layoutsToPlot.Count), null); pe.BeginGenerateGraphics(null); ppd.SheetProgressPos = 50; pe.EndGenerateGraphics(null); // End page PreviewEndPlotInfo pepi = new PreviewEndPlotInfo(); pe.EndPage(pepi); result = pepi.Status; ppd.SheetProgressPos = 100; ppd.OnEndSheet(); // keep system responsive System.Windows.Forms.Application.DoEvents(); } // End document pe.EndDocument(null); // End plot ppd.PlotProgressPos = 100; ppd.OnEndPlot(); pe.EndPlot(null); pe.Dispose(); } private static String _PlotSetMedia(String szPlotterName, String szMedia, Layout lo, PlotSettings ps, PlotSettingsValidator psv) { if (szMedia.Length > 0) // user specified a preferred media { // set current plotter device psv.SetPlotConfigurationName(ps, szPlotterName, null); psv.RefreshLists(ps); // load canonical names, probably choosen previously from the same list System.Collections.Specialized.StringCollection v = psv.GetCanonicalMediaNameList(ps); String szCanonicalName = "", szTmp; foreach (String s in v) { if (s == szMedia) { // canonical name found as specified by user szCanonicalName = szMedia; break; } else { // otherwise check for a descriptive name szTmp = psv.GetLocaleMediaName(ps, s); if (szTmp == szMedia) { // ok, found! szCanonicalName = s; break; } } } psv.SetPlotConfigurationName(ps, szPlotterName, szCanonicalName); // stampante e formato pagina psv.SetPlotRotation(ps, PlotRotation.Degrees000); } else { // media not specified, choose the best if (lo.ModelType) szMedia = FindBestFormat(ps, psv, szPlotterName, lo.Database.Extmin, lo.Database.Extmax); else szMedia = FindBestFormat(ps, psv, szPlotterName, lo.Extents.MinPoint, lo.Extents.MaxPoint); } return szMedia; }
Hi, Thank you for the reply,and it's really do me some help
I changed your code like below
//get print info //contains the target window area List<FrameAttributeExtend> entitylist = GetFrameEntity(title); Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Transaction acTrans = acCurDb.TransactionManager.StartTransaction(); object iSys = AcadApplication.GetSystemVariable("BACKGROUNDPLOT"); try { using (acTrans) { int flag = 1; //AcadApplication.SetSystemVariable("BACKGROUNDPLOT", 1); AcadApplication.SetSystemVariable("BACKGROUNDPLOT", 0); if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting) { PlotProgressDialog ppd = new PlotProgressDialog(false, entitylist.Count, true); using (ppd) { ppd.OnBeginPlot(); PlotEngine pe = PlotFactory.CreatePublishEngine(); pe.BeginPlot(ppd, null); ppd.StatusMsgString = "Plotting..."; // add name of document, if you need it ppd.LowerSheetProgressRange = 0; ppd.UpperSheetProgressRange = 100; ppd.SheetProgressPos = 0; ppd.OnBeginSheet(); foreach (var frame in entitylist) { //get cur layoutmanager LayoutManager acLayoutMgr = LayoutManager.Current; //get current layout Layout acLayout = (Layout)acTrans.GetObject(acLayoutMgr.GetLayoutId(acLayoutMgr.CurrentLayout), OpenMode.ForRead); //Get print layout info PlotInfo pi = new PlotInfo() { Layout = acLayout.ObjectId }; PlotSettings ps = new PlotSettings(acLayout.ModelType); ps.CopyFrom(acLayout); PlotSettingsValidator psv = PlotSettingsValidator.Current; //set the plot style System.Collections.Specialized.StringCollection sc = psv.GetPlotStyleSheetList(); psv.SetCurrentStyleSheet(ps, "TestStyle.ctb"); psv.SetPlotType(ps, PlotType.Extents); psv.SetUseStandardScale(ps, true); psv.SetStdScaleType(ps, StdScaleType.ScaleToFit); psv.SetPlotCentered(ps, true); if (!Directory.Exists(directory)) Directory.CreateDirectory(directory); //scale string entityscale = frame.Scale; //orientation string vertial = frame.IsVertial; //index string picindex = frame.ImageIndex; string imagename = ""; if (frame.ImageType == 0) { imagename = string.Format("1-{0}-{1}-{2}.pdf", entityscale, vertial, picindex); totalflatimage = directory + imagename; } else { imagename = string.Format("2-{0}-{1}-{2}.pdf", entityscale, vertial, picindex); imagelist.Add(directory + imagename); } ps.ShowPlotStyles = true; //set print extends Extents3d extents3d = frame.Extent; double h = double.Parse(entityscale) * 6; double x = extents3d.MinPoint.X + unit * 2; double y = extents3d.MaxPoint.Y + h + unit; if (unit == 1) { x = extents3d.MinPoint.X + unit * 1; y = extents3d.MaxPoint.Y + double.Parse(entityscale) / 250 + unit * 2; } Extents2d E2d = new Extents2d(x, extents3d.MinPoint.Y, extents3d.MaxPoint.X, y); psv.SetPlotPaperUnits(ps, PlotPaperUnit.Millimeters); //psv.SetPlotOrigin(ps, new Point2d(extents3d.MinPoint.X, extents3d.MinPoint.Y)); psv.SetPlotWindowArea(ps, E2d); //psv.SetPlotOrigin(ps, E2d.MinPoint); psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window); psv.SetPlotConfigurationName(ps, "DWG To PDF.pc3", "ISO_expand_A4_(210.00_x_297.00_mm)"); psv.SetPlotRotation(ps, PlotRotation.Degrees000); PlotInfoValidator piv = new PlotInfoValidator(); piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled; pi.OverrideSettings = ps; piv.Validate(pi); ppd.IsVisible = true; if (flag == 1) { pe.BeginDocument(pi, acDoc.Name, null, 1, true, directory + imagename); } ppd.LowerSheetProgressRange = 0; ppd.UpperSheetProgressRange = 100; ppd.SheetProgressPos = 0; PlotPageInfo ppi = new PlotPageInfo(); pe.BeginPage(ppi, pi, flag == entitylist.Count, null); pe.BeginGenerateGraphics(null); ppd.SheetProgressPos = 50; pe.EndGenerateGraphics(null); pe.EndPage(null); ppd.SheetProgressPos = 100; ppd.OnEndSheet(); ppd.PlotProgressPos = (100 / entitylist.Count) * flag; flag++; } pe.EndDocument(null); ppd.PlotProgressPos = 100; ppd.OnEndPlot(); pe.EndPlot(null); pe.Dispose(); } } } //verify the plot state while (PlotFactory.ProcessPlotState != ProcessPlotState.NotPlotting) continue; MessageBox.Show("The Plot Is Complated!"); } catch (Exception ex) { return null; } finally { AcadApplication.SetSystemVariable("BACKGROUNDPLOT", iSys); acTrans.Dispose(); } }
but there is still some problems,and wished to get your help.
1.if I do't call psv.SetPlotOrigin function,I get a really fast pdf file with multy pages, but the content is not correct,actually,it's blank
2.I tried not to call psv.SetPlotOrigin function,and I get the multi pages files i want, but the problem is it takes ablout 20minutes to generate the file
3.when i set the system variable "BACKGROUNDPLOT" to 1 using the code in 2,I got only one page pdf file
my current problem is it takes too much time to do this,and i don't know how to solve currently,
wolud you give me some help?~
thank you very much.
Besides:FrameAttributeExtend class contains some infos for the target i want to plot
Hi, everyone, I found the problem.And it's really really strange,and I found it in a coincidence.
The code mcicognani really do me a great help.
I always debug in visual studio and I start the autocad in Visual Studio so I wouldn't able to do it correctly,and I don't know why.
At last, I netload the dll and start autocad without visual studio, I get what I want and the speed is much faster than the visual stuio way.
And more strange.
I start AutoCad with Autocad and do not netload my debug dll,I use cad printer to print a drawing to pdf ,and it takes a much long time as I usually do.But when I start autocad directlly and I user the same drawing the same printer config as before,It would take only about less than 3 seconds to get the pdf.
And for sure, the BackgroundPlot is set to 0 in both situation.
And I solve my problem this way
sorry I do not know why.
Can't find what you're looking for? Ask the community or share your knowledge.