I asked this question before, but didnt get any answer so I hope the second try will be successful. I want to export/print layouts automatically (in a loop) to PDFs. With Dale's help I am exploring CRhinoPageView class in order to create the layouts, and that is going fine, but I still dont know how to print them.
My best guesses involve using CRhino(Ui)Dib (somehow) and CRhinoPrintInfo to set the parameters for printing to PDF…but those are just guesses and I don`t know how to combine them…any suggestions?
but can you give me couple of more hints…like what functions are used to set PDF as output and what to actually print? I know RhinoDib has WriteToFile or DrawToDC…what is the proper function here? DrawWithGDI?
Once you have a CDC, you would call UpdateFromPrinterDC to get the print info page sizes all structured correctly. Then you would call DrawWithGDI if you want vector output to the PDF. Otherwise you would draw to a bitmap (CRhinoDib) and then dump that bitmap into a PDF.
Unfortunately this requires quite a bit of code to get set up correctly and I don’t have any samples immediately on hand. An alternate approach could be to use the dashed version of the print command.
How about if I set all the options manually and prepare them for my “batch printing” by printing a test PDF? I guess that information is saved? Then if I called DrawWithGDI() the CDisplayPipelineAttributes should already be set?
P.S. I know that it is out of the Rhino scope, but I cannot find the easiest way to get a CDC for a PDF printer…if you have any tips on how to get that I would appreciate it…is there a way to use one of the Rhino Dialog classes to open some dialog and select the printer, hence getting a CDC?
I am sorry, but I have to ask again because I want to explore all the possibilities I have, and the one in which I get the printer CDC by calling the PrintDlg looks like the most promising one. So, the question is if you maybe know why doesn`t anything happen after calling PrintDlg (the code is above)? Is the dialog somehow blocked? Like when RunScript cannot be called from a CRhinoCommand derived command? (I tried deriving the command from CRhinoScriptCommand but PrintDlg still does nothing.)
The other possibility was calling EnumPrinters function to find the name of the printer and then CreateDC…but not sure how to do that either, cause EnumPrinters function is not recognized…
The answer “we don`t know”, or “it is too complicated to explain” is also totally acceptable, so I know I have to continue to search on my own…but any hint would help.
So I got the CDC with PrintDlg(&pd), and I called StartDoc - EndDoc functions around the DrawWithGDI. The result is that I managed to print automatically to the chosen device, BUT it prints only a white A4 paper. At what point am I missing to pass the actual layout (or any CRhinoView) to DrawWithGDI? Because I am obviously not doing it anywhere and I have to give CRhinoPrintInfo somehow the information on what to print. (The DOCINFO part must be wrong…) The code:
Since I am getting no answer I will try to ask more concisely:
When we draw with DrawToDC or RenderToDC we easily tell Rhino what to draw with the use of CRhinoObjectIterator. When I use CRhinoPrintInfo::DrawWithGDI how am I telling Rhino what to draw? I am only giving it the context device. If the answer is that the whole display pipeline gets drawn, then we are back to the old question:
Once I surround my UpdateFromPrinter and DrawWithGDI functions with StartDoc, StartPage, EndPage, EndDoc, they just get ignored. An empty document is generated by the 4 Start/End functions, as if two CRhinoPrintInfo functions don`t exist. And it makes sense that the paper is empty, because (in my bad example above) those functions get only the device context as an input, and for what to print, they get the empty DOCINFO document.
How do I connect the 4 Start/End functions and DrawWithGDI so that it works? I feel that i am only one tip away from solving this…
I have to apologize, but I will not give up until I manage to to this That being said…
First problem is that I am not sure how to get the CRhinoViewport needed for CRhinoPrintInfo::SetViewport (?) (all examples show only how to get CRhinoView, but not CRhinoViewport - what is their relation?),
Second (main) problem is that CRhinoPrintInfo::DrawWithGDI does nothing…it does not evoke any action. You said to surround it with StartDoc-EndDoc functions. When I do, they (logically) work totally independently of CRhinoPrintInfo and print an empty page, defined by DOCINFO. The main question is how do I connect those two?
I could print with DrawWithGDI and ignore Start/End functions - but this does not work.
I can print with Start/End functions but I am missing a link to my CPrintInfoClass. How do I connect them? How do I pass CRhinoPrintInfo details to DOCINFO or to Start/End functions?
I cannot find the basic information online or in RhinoDocs that can help me understand how this works. You basically only have to tell me what Rhino does after the the user presses “Print” in the Print Setup dialog. Does it call DrawWithGDI? Does it call Start/End functions?
A CRhinoView is the top level window itself. For standard modeling views, a CRhinoView will contain a single CRhinoViewport which covers the entire CRhinoView’s child window area. For layouts, a CRhinoView can contain a single “MainViewport” and multiple CRhinoViewports that represent each detail on the layout. Just use the MainViewport function on a CRhinoView to get the viewport that you want to use.
You absolutely need to tell the CRhinoPrintInfo which CRhinoViewport to print. This is probably why you are getting blank output.
Unfortunately, that is a massive amount of code that spreads across several files. I would have just posted the code if it were easy to do.
thanks…I`ll try to solve it… just tell me how do I access RhinoView-RhinoViewport, because whenever I call MainViewport, ActiveViewport, or try accessing m_vp directly it tells me it is inaccessible…even though, as I see, these classes are friends. ?
you were right. It actually worked. I will try to continue on my own now as much as I can…I know I am slowly becoming very boring but i might have couple of additional questions along the way. For example, I want to set the printing options now (page layout, etc…) I see two ways of doing this:
The easiest way would be to set everything manually, print something and somehow evoke those last settings for every new printing job. Is this possible? At the moment this doesn`t work… The things I print with DrawWithGDI always have some of their own (default?) settings.
If this is not possible, I have to set everything manually…by setting CRhinoPrintInfo members…in this case the most important question is where the page layout setting is? (Landscape/Portrait, Paper size…)