Hi,
i'm trying to create a routine, where i can select multiple windows in modelspace, and the plot a multisheet pdf.
but I'm having trouble to create multiple pages, it only generates 1 page
I have modified sourcecode from Kean Walmsley:
http://through-the-interface.typepad.com/through_the_interface/2007/09/driving-a-multi.html
- this routine creates a single-page pdf with only the last selected window.
- the pc3-file I use is able to create multisheets because the original routine with paperspace works fine
- I think it has maybe something to do with the pi.Layout = lo.Id ?
any ideas?
kind regards, Wouter de Haan
the netherlands
<CommandMethod("mplot2")> Public Sub MultiSheetPlot2() Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim ed As Autodesk.AutoCAD.EditorInput.Editor = doc.Editor Dim db As Database = doc.Database Dim tr As Transaction = db.TransactionManager.StartTransaction() Using tr Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) Dim pi As New PlotInfo() Dim piv As New PlotInfoValidator() piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled ' A PlotEngine does the actual plotting ' (can also create one for Preview) If PlotFactory.ProcessPlotState = Autodesk.AutoCAD.PlottingServices.ProcessPlotState.NotPlotting Then Dim pe As PlotEngine = PlotFactory.CreatePublishEngine() Using pe ' Create a Progress Dialog to provide info ' and allow the user to cancel Dim ppd As New PlotProgressDialog(False, 1, True) Using ppd 'Dim layoutsToPlot As New ObjectIdCollection() 'For Each btrId As ObjectId In bt ' Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord) ' If btr.IsLayout AndAlso btr.Name.ToUpper() <> BlockTableRecord.ModelSpace.ToUpper() Then ' layoutsToPlot.Add(btrId) ' End If 'Next 'For Each btrId As ObjectId In layoutsToPlot Dim AcLayoutMgr As LayoutManager AcLayoutMgr = LayoutManager.Current For I As Integer = 1 To 3 'Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord) 'Dim lo As Layout = DirectCast(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout) Dim lo As Layout lo = tr.GetObject(AcLayoutMgr.GetLayoutId(AcLayoutMgr.CurrentLayout), OpenMode.ForRead) ' We need a PlotSettings object ' based on the layout settings ' which we then customize Dim ps As New PlotSettings(lo.ModelType) ps.CopyFrom(lo) ' The PlotSettingsValidator helps ' create a valid PlotSettings object Dim psv As PlotSettingsValidator = PlotSettingsValidator.Current ' We'll plot the extents, centered and ' scaled to fit If 1 = 1 Then Dim WindowLO As XYData Dim WindowRB As XYData SelecteerPunt("Geef 1e punt", WindowLO.X, WindowLO.Y) SelecteerWindow("Geef 2e punt", WindowLO.X, WindowLO.Y, WindowRB.X, WindowRB.Y) Dim PlotBound As New Extents2d(WindowLO.X, WindowLO.Y, WindowRB.X, WindowRB.Y) psv.SetPlotWindowArea(ps, PlotBound) psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window) Else psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents) End If psv.SetUseStandardScale(ps, True) psv.SetStdScaleType(ps, StdScaleType.ScaleToFit) psv.SetPlotCentered(ps, True) ' We'll use the standard DWFx PC3, as ' this supports multiple sheets psv.SetPlotConfigurationName(ps, "PDFCreator.pc3", "A4") ' We need a PlotInfo object ' linked to the layout
'---??? is this correct?
pi.Layout = lo.Id
' Make the layout we're plotting current LayoutManager.Current.CurrentLayout = lo.LayoutName ' We need to link the PlotInfo to the ' PlotSettings and then validate it pi.OverrideSettings = ps piv.Validate(pi) If I = 1 Then ppd.PlotMsgString(PlotMessageIndex.DialogTitle) = "Custom Plot Progress" ppd.PlotMsgString(PlotMessageIndex.CancelJobButtonMessage) = "Cancel Job" ppd.PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage) = "Cancel Sheet" ppd.PlotMsgString(PlotMessageIndex.SheetSetProgressCaption) = "Sheet Set Progress" ppd.PlotMsgString(PlotMessageIndex.SheetProgressCaption) = "Sheet Progress" ppd.LowerPlotProgressRange = 0 ppd.UpperPlotProgressRange = 100 ppd.PlotProgressPos = 0 ' Let's start the plot, at last ppd.OnBeginPlot() ppd.IsVisible = True pe.BeginPlot(ppd, Nothing) ' We'll be plotting a single document ' Let's plot to file pe.BeginDocument(pi, doc.Name, Nothing, 1, False, "c:\test-multi-sheet") End If ' Which may contain multiple sheets ppd.StatusMsgString = "Plotting " & doc.Name.Substring(doc.Name.LastIndexOf("\") + 1) & " - sheet " & I.ToString() & " of " & "3" ppd.OnBeginSheet() ppd.LowerSheetProgressRange = 0 ppd.UpperSheetProgressRange = 100 ppd.SheetProgressPos = 0 Dim ppi As New PlotPageInfo() pe.BeginPage(ppi, pi, I = 3, Nothing) pe.BeginGenerateGraphics(Nothing) ppd.SheetProgressPos = 50 pe.EndGenerateGraphics(Nothing) ' Finish the sheet pe.EndPage(Nothing) ppd.SheetProgressPos = 100 ppd.OnEndSheet() Next ' Finish the document pe.EndDocument(Nothing) ' And finish the plot ppd.PlotProgressPos = 100 ppd.OnEndPlot() pe.EndPlot(Nothing) End Using End Using Else ed.WriteMessage(vbLf & "Another plot is in progress.") End If End Using End Sub
Hi Wouter,
I am not sure if your code can work to create a single multi-sheet PDF since the parameter to the "SetPlotType" is only used to define the extents of the layout to be plotted. When the same layout is used for plotting again,the last one get overwritten. Typically such plotting is used to create multi-sheet plots of the layouts in the drawing.
A way to create a multi-sheet DWF / PDF based for different portions of your model space is to use the "PublishExecute" method. I created a blog post to explain this :
If you create named views for different portions of your drawing, a named page setup can be created for it and used with the DSD file to create a single sheet DWF/PDF.
Regards,
Dear Balaji,
thank you for your reply, it explains why I only got the last page printed,
but in order to read the link you sent, do I have to sign up with this typepad? I cannot read the blog-section you have sent, is it possible to post it here?
kind regards,
Wouter de Haan
Hi Wouter,
Not at all. I think I posted the incorrect link. Sorry for that.
You can read it here :
http://adndevblog.typepad.com/autocad/
Regards,
Hi Balaji,
the code I converted to vb.net, but I get an error at line:
psv.SetPlotConfigurationName(plotSettings, "DWF6 ePlot.pc3", "ANSI_A_(8.50_x_11.00_Inches)")
also, the sample.dwg, i cannot open, because I'm working with AutoCad2010, due to the VBA/vb.net conversion.. Is it possible to save it as an AutoCad 2010 file? And when it works I can also save it as a multisheet PDF file?
Hope You can help, thanks in advance,
kind regards Wouter
Imports Autodesk.AutoCAD Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.PlottingServices Imports Autodesk.AutoCAD.Publishing Imports System.Collections.Specialized Imports System.Text Public Module PDF <CommandMethod("Pub2")> Public Sub PublishViews2MultiSheet() Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim viewsToPlot As StringCollection = New StringCollection viewsToPlot.Add("Test1") viewsToPlot.Add("Test2") ' Create page setup based on the views Dim Tx As Transaction = db.TransactionManager.StartTransaction Dim layoutId As ObjectId = LayoutManager.Current.GetLayoutId(LayoutManager.Current.CurrentLayout) Dim layout As Layout = CType(Tx.GetObject(layoutId, OpenMode.ForWrite), Layout) For Each viewName As String In viewsToPlot Dim plotSettings As PlotSettings = New PlotSettings(layout.ModelType) plotSettings.CopyFrom(layout) Dim psv As PlotSettingsValidator = PlotSettingsValidator.Current psv.SetPlotConfigurationName(plotSettings, "DWF6 ePlot.pc3", "ANSI_A_(8.50_x_11.00_Inches)") psv.RefreshLists(plotSettings) psv.SetPlotViewName(plotSettings, viewName) psv.SetPlotType(plotSettings, DatabaseServices.PlotType.View) psv.SetUseStandardScale(plotSettings, True) psv.SetStdScaleType(plotSettings, StdScaleType.ScaleToFit) psv.SetPlotCentered(plotSettings, True) psv.SetPlotRotation(plotSettings, PlotRotation.Degrees000) psv.SetPlotPaperUnits(plotSettings, PlotPaperUnit.Inches) plotSettings.PlotSettingsName = String.Format("{0}{1}", viewName, "PS") plotSettings.PrintLineweights = True plotSettings.AddToPlotSettingsDictionary(db) Tx.AddNewlyCreatedDBObject(plotSettings, True) psv.RefreshLists(plotSettings) layout.CopyFrom(plotSettings) Next Tx.Commit() 'put the plot in foreground Dim bgPlot As Short = CType(Application.GetSystemVariable("BACKGROUNDPLOT"), Short) Application.SetSystemVariable("BACKGROUNDPLOT", 0) Dim dwgFileName As String = CType(Application.GetSystemVariable("DWGNAME"), String) Dim dwgPath As String = CType(Application.GetSystemVariable("DWGPREFIX"), String) Tx = db.TransactionManager.StartTransaction Dim collection As DsdEntryCollection = New DsdEntryCollection Dim activeLayoutId As ObjectId = LayoutManager.Current.GetLayoutId(LayoutManager.Current.CurrentLayout) For Each viewName As String In viewsToPlot Dim layout1 As Layout = CType(Tx.GetObject(activeLayoutId, OpenMode.ForRead), Layout) Dim entry As DsdEntry = New DsdEntry entry.DwgName = (dwgPath + dwgFileName) entry.Layout = layout1.LayoutName entry.Title = viewName entry.NpsSourceDwg = entry.DwgName entry.Nps = String.Format("{0}{1}", viewName, "PS") collection.Add(entry) Next ' remove the ".dwg" extension dwgFileName = dwgFileName.Substring(0, (dwgFileName.Length - 4)) Dim dsdData As DsdData = New DsdData dsdData.SheetType = SheetType.MultiDwf dsdData.ProjectPath = dwgPath dsdData.DestinationName = (dsdData.ProjectPath _ + (dwgFileName + ".dwf")) If System.IO.File.Exists(dsdData.DestinationName) Then System.IO.File.Delete(dsdData.DestinationName) End If dsdData.SetDsdEntryCollection(collection) Dim dsdFile As String = (dsdData.ProjectPath _ + (dwgFileName + ".dsd")) 'Workaround to avoid promp for pdf file name 'set PromptForDwfName=FALSE in dsdData using StreamReader/StreamWriter dsdData.WriteDsd(dsdFile) Dim sr As System.IO.StreamReader = New System.IO.StreamReader(dsdFile) Dim str As String = sr.ReadToEnd sr.Close() ' Replace PromptForDwfName str = str.Replace("PromptForDwfName=TRUE", "PromptForDwfName=FALSE") ' Workaround to have the page setup names included in the DSD file ' Replace Setup names based on the created page setups ' May not be required if Nps is output to the DSD Dim occ As Integer = 0 Dim index As Integer = str.IndexOf("Setup=") Dim startIndex As Integer = 0 Dim dsdText As StringBuilder = New StringBuilder While (index <> -1) ' 6 for length of "Setup=" Dim str1 As String = str.Substring(startIndex, (index + (6 - startIndex))) dsdText.Append(str1) dsdText.Append(String.Format("{0}{1}", viewsToPlot(occ), "PS")) startIndex = (index + 6) index = str.IndexOf("Setup=", (index + 6)) If (index = -1) Then dsdText.Append(str.Substring(startIndex, (str.Length - startIndex))) End If occ = (occ + 1) End While ' Write the DSD Dim sw As System.IO.StreamWriter = New System.IO.StreamWriter(dsdFile) sw.Write(dsdText.ToString) sw.Close() ' Read the updated DSD file dsdData.ReadDsd(dsdFile) ' Erase DSD as it is no longer needed System.IO.File.Delete(dsdFile) Dim plotConfig As PlotConfig = PlotConfigManager.SetCurrentConfig("DWF6 ePlot.pc3") Dim publisher As Publisher = Application.Publisher ' Publish it publisher.PublishExecute(dsdData, plotConfig) Tx.Commit() 'reset the background plot value Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot) End Sub End Module
Hi Wouter,
I am having problem with my Visual Studio installation in my system. So I am having trouble testing it right away.
I will test the VB.Net code and let you know after I get my system in order.
Here is the drawing saved as a 2010 format dwg.
Regards,
Hi Wouter,
Sorry for the delay.
Yes, the same code with a few changes should generate a multi-sheet PDF.
I have tested the VB.Net code with AutoCAD 2010 and it worked ok.
I have attached the sample project, the test drawing and the pdf generated.
Regards,
Hey,
I'm trying the example project as i am trying to accomplish the same thing, i got single sheet pdf working but not a multisheet pdf, its just giving me errors, the problem is with your example project here that its giving me the error that it doesnt have a page set up, i have try'd sevelar things only still its giving me the error that there is no page setup. I have added the publish plot details as picture
I'm working with AutoCAD 2011
Beste regards,
Sean Berger
Got it working now, changed entry.nps string to a existing page setup and now its working.
Thank you for your time anyways.
Best regards,
Sean Berger
Can't find what you're looking for? Ask the community or share your knowledge.