=========================
HOOPS Publish integration
=========================

Using the HOOPS Publish HIO component
=====================================

The HOOPS Publish HIO component (HIO Publish) supports exporting the HOOPS/3DGS scene-graph to the 3D PDF format. It utilizes the HOOPS Publish API to achieve this. Before using this component, developers should become familiar with `HOOPS Publish <http://www.techsoft3d.com/products/hoops-toolkits/hoops-publish/>`_, as well as the general HIO architecture and capabilities covered in :doc:`this section </prog_guide/mvo/04_hio_manager>` of the HOOPS/MVO Programming Guide. HOOPS Publish requires the SSSE3 instruction set to be supported by the execution environment.

The HIO Publish component is delivered in the form of a *.hio* file, which gets dynamically loaded by HOOPS Visualize at runtime. To ensure your application can access the HIO Publish component, perform the following:

#. Create a hio_plugins directory in your application's working directory.
#. Copy the *hiopublish<version>.hio* file found in *<hoops>/bin/<platform>/hio_plugins/hio_publish* to the hio_plugins directory created in the previous step.
#. Ensure that the HOOPS Publish DLLs are in your application's path.
#. Run your application

During startup, when HOOPS/MVO finds the HIO Publish component and HOOPS Publish DLLs, it will perform the following steps:

#. Create the appropriate 3D-PDF output handler.
#. Register this handler and the associated file extension with the HIO Manager.

Once the HIO Publish component is successfully loaded, your application will be able to  export the HOOPS/3DGS scene-graph to 3D PDF files.


Exporting use cases
-------------------

The hio_publish module supports the following export cases, with each approach detailed down below:

* Basic export: This involves exporting to a simple 3D-PDF document of fixed size, and with no customizations made to the PDF document. 
* Export via a Template:  This involves specifying an existing PDF template, which will serve as the basis for the exported 3D-PDF document.
* Advanced export using HOOPS Publish: This involves exporting to a PRC model (which represents the 3D data in a 3D-PDF document), and then using the HOOPS Publish APIs to embed the PRC model into a  3D-PDF document that can be fully customized. This approach is appropriate if you require full control over the  PDF document properties.


Basic export
============

Basic export involves:

* Setting up the ``HOutputHandlerOptions`` structure with a valid HOOPS Publish license key
* Obtaining the HOutputHandler for the 'pdf3d' file type
* Setting the ``HOutputHandlerOptions::m_pPDFResourceDirectory`` field to the absolute path of the HOOPS Publish resource directory. Not specifying this path will result in a failed export. By default, the resources directory is located at *<HOOPS_PUBLISH>/bin/resources*.
* Customizing the layout of the '3D Annotation' within the PDF document
* Calling the ``HOutputHandler::FileOutputByKey`` method

Example::

	#include "HIOManager.h"
		
	HFileOutputResult result = OutputFail;
	HOutputHandlerOptions output_options;

	// setup the output options with a HOOPS Publish license key
	// NOTE:  if the license key has alrady been included via an initial call to HC_Define_System_Options at startup, it does not need to be included here
	output_options.m_license = const char* licensekey = "<license_key_string>"; 

	output_options.m_pPDFResourceDirectory = "publish_install_dir/bin/resources";

	// let's have the 3D Annotation automatically activate when the containing PDF page is opened
	output_options.m_bActivateOnPageOpen = true;

	// change the size of the 3D Annotation
	output_options.m_fAnnotLeft = 3.0;
	output_options.m_fAnnotRight = 3.0;
	output_options.m_fAnnotBottom = 2.0;
	output_options.m_fAnnotTop = 2.0;

	output_options.m_pHBaseView = myBaseView;

	// If we simply exported a 'foo.pdf' file, HOOPS/MVO would by default export a '2d pdf' using it's built in 2D-PDF export support.  
	// Since we want to export a 3D-PDF, we must obtain the output handler for the 'pdf3d' file type and utilize it. 
	HOutputHandler * handler = HDB::GetHIOManager()->GetOutputHandler("pdf3d");
	if (handler)
		result = handler->FileOutputByKey("c:\\temp\\my_3D_PDF_File.pdf", myBaseView->GetModelKey(), &output_options);

.. only:: standard

	You could additionally specify the handle to an existing PRC model, which is what makes up the 3D part of 3D PDF. Specifying the PRC handle tells the HIO Publish module to directly utilize the existing PRC data and embed it in a 3D-PDF document, rather than traversing the HOOPS scene-graph information. This may be desirable if you are using HOOPS Exchange to bring in native CAD files (After a CAD file is imported witih HOOPS Exchange, you have access to a PRC handle). This approach is achieved by setting the ``HOutputHandlerOptions::m_pPRCAsmModelFile`` attribute to the PRC model handle, prior to calling FileOutputByKey:

.. only:: spatial

	You could additionally specify the handle to an existing PRC model, which is what makes up the 3D part of 3D-PDF.  Specifying the PRC handle tells the HIO Publish module to directly utilize the existing PRC data and embed it in a 3D-PDF document, rather than traversing the HOOPS scene-graph information.

Example::

	// Let's assume that m_pPRCAsmModelFile is a pointer to our PRC data.
	output_options.m_pPRCAsmModelFile = m_pPRCAsmModelFile;


Using Unicode character strings in the model tree
-------------------------------------------------

Beginning with HOOPS Visualize 20.31, you are able to use Unicode character strings in the model tree when exporting a 3D PDF document. This functionality depends on two fields, ``m_bPrcUseNameUserData`` and ``m_iPrcNameUserDataIndex``.

If ``m_bPrcUseNameUserData`` is ``true``, then, when building the PRC from a scene graph, we will check for user data with the index specified by ``m_iPrcNameUserDataIndex``. If we find user data at that index, we expect it to be UTF8-encoded text, and we will use that text as the name for the corresponding PRC entity. If there is no user data at that index, we will use the traditional behavior for setting the name. Generally, for segments this means we will use the segment name (if present) or the hex representation of the ``HC_KEY`` (if no name is present).

The ``m_bPrcUseNameUserData`` field defaults to ``false``. The ``m_iPrcNameUserDataIndex`` defaults to 0, but that field is only referenced if ``m_bPrcUseNameUserData`` field is ``true``, and it would need to be set to whatever index the user wanted to use for storing name data.

**Using Unicode characters in 2D PDF:** Exporting non-ASCII characters to 2D PDF is supported. However, non-ASCII characters are exported as shells. The resulting "text" is not selectable and can't be copy-pasted, but otherwise appears normally.


Fuse threshold
--------------

The 3D PDF exporter can make use of a special field called ``HOutputHandlerOptions::m_lineFuseThreshold``. This field is useful if your model contains segments with a large number of lines. If the exporter detects the number of lines in a segment is equal to or greater than this value, the exporter will combine them into a single line representation. This can decrease the export time and increase the performance of the PDF. However, this option will make those lines unselectable in your PDF model, so you should set it to a very high level if line selectability is an issue::

	// setting the line fuse threshold
	output_options.m_lineFuseThreshold = 100;


Export with a template
======================

HOOPS Publish provides the ability to create a PDF based on an existing PDF 'template' that contains  named fields which can be modified/populated via ``HPDFLayoutManager`` methods. HOOPS Publish includes a handful of templates, and they can be viewed/edited using Acrobat Professional.  You can also create your own template. 

Exporting a file based on a template involves:

* obtaining the HIOUtilityPublish handler
* calling HIOUtilityPublish::BuildPRCModel to obtain a pointer to the PRC model information
* using the HPDFLayoutManager object to select an existing PDF template and setup its fields
* exporting the PDF by calling the HIOUtilityPublish::WritePDFFromTemplate

Example::

	// Requires the hio_publish directory to be part of the include path
	#include "HIOUtilityPublish.h"       

	// obtain a pointer to the HIOUtilityPublish output handler
	HIOUtilityPublish * handler = (HIOUtilityPublish *)HDB::GetHIOManager()->GetOutputHandler("pdf3d");

	if (handler)
	{
		HOutputHandlerOptions output_options;

		// setup the output options with a HOOPS Publish license key
		output_options.m_license = const char* licensekey = "<license_key_string>"; 
		
		// specify the HBaseView object
		output_options.View(m_pHView);

		// this method parses the HOOPS Visualize database and returns a pointer to a PRC model
		void *prcmodel = handler->BuildPRCModel(&output_options, m_pHView->GetModelKey());   

		// obtain a layoutManager object
		HPDFLayoutManager layoutManager;
		
		// instruct the layout manager to use a pre-existing PDF template
		layoutManager.SetTemplateName("<my_hoops_publish install_dir>\publish110\\pdf_templates\\Templates\\MultiViews\\MultiViews_A4.pdf"); 
										
		// Set the name of the PDF field that will serve as the canvas for the 3D view  
		layoutManager.Set3DFieldName("My3DWindow");                    
			  
		// HPDFLayoutManager::AddTextModification method changes the associated text of an existing PDF text field
		layoutManager.AddTextModification("SummaryText", "This is a test");                                            
		
		// HPDFLayoutManager::AddImageModifcation method changes the associated image of an existing PDF image field 
		layoutManager.AddImageModification("Button1", "c:\\temp\\apex.jpg", HJPG, 40, 40);          
		
		// HPDFLayoutManager::AddMiscModification attached Javascript and/or changes visibility of an existing PDF field
		layoutManager.AddMiscModification("DocumentSubHead", 0 ,HInvisible);   
			
		// We now export the PDF using the HIOUtilityPublish::WritePDFFromTemplate method    
		handler->WritePDFFromTemplate("c:\\tempfiles\\test.pdf", prcmodel, &output_options, &layoutManager, 0);
	}


Advanced export using HOOPS Publish
===================================

This requires first exporting the scene-graph to a PRC model, which has already been covered above. It involves getting the ``HIOUtilityPublish`` handler, and calling ``HIOUtilityPublish::BuildPRCModel`` to obtain a pointer to the PRC model information::

	// Requires the hio_publish directory to be part of the include path
	#include "HIOUtilityPublish.h"       

	// obtain a pointer to the HIOUtilityPublish output handler
	HIOUtilityPublish * handler = (HIOUtilityPublish *)HDB::GetHIOManager()->GetOutputHandler("pdf3d");

	if (handler)
	{
		HOutputHandlerOptions output_options;

		// setup the output options with a HOOPS Publish license key
		output_options.m_license = const char* licensekey = "<license_key_string>"; 
		
		// specify the HBaseView object
		output_options.View(m_pHView);

		// this method parses the HOOPS Visualize database and returns a pointer to a PRC model
		void *prcmodel = handler->BuildPRCModel(&output_options, m_pHView->GetModelKey());   
	}

You would now access HOOPS Publish APIs to create a custom PDF document, and then embed the PRC model inside.


Reducing file size
==================

Implicit HOOPS/3DGS primitives
------------------------------

Certain types of models may contain large amounts of implicit primitives, which can in turn result in large amounts of tesselation information during export. This can cause large 3D-PDF (and PRC) files, an increase in memory usage, and excessive export-time. If you have a scene with a large amount of HOOPS/3DGS cylinders and/or spheres, the following steps can greatly improve export performance and reduce file size:

#. Call ``HC_Set_Rendering_Options("tessellation=(cylinder=3,sphere=4)")``, in the model segment before exporting to 3D-PDF. (The provided values are sample/suggested values.)
#. When exporting to 3D PDF, you will need to set the new option ``HOutputHandlerOptions::m_bPrcCompressTessellation`` to ``TRUE``


B-rep information
-----------------

.. only:: standard

	The ``HOutputHandlerOptions::m_ePrcBrepCompression`` setting can reduce 3D-PDF file size when exporting PRC BRep data. (Typically this is data that came from a CAD file imported via HOOPS Exchange.) This setting will have no effect if there is only HOOPS/3DGS tessellation data being exported to 3D PDF or PRC.

.. only:: spatial

	The ``HOutputHandlerOptions::m_ePrcBrepCompression`` setting can reduce 3D-PDF file size when exporting PRC BRep data. This setting will have no effect if there is only HOOPS/3DGS tessellation data being exported to 3D PDF or PRC.


Notes about supported data
==========================

In general, most HOOPS/3DGS scene graph information is exported to 3D-PDF. Special cases are noted below:

.. csv-table::
	:header: "Visualize entity", "Notes"
	
	"Animation", "A subset of the animations types supported by HOOPS/MVO HBhvAnimation will be exported, including object rotation/translation, camera movement, visibility, and segment-switching."
	
	"PMI", "Items in the HOOPS/3DGS scene-graph that were inserted as MVO PMI elements will be exported. These PMI elements could have been programmatically defined by the developer, or may have been created during CAD file import logic."
	
	"CAD views", "Any CAD 'views' information that was previously imported using HOOPS Exchange and resides in the PRC model will be exported to 3D PDF, provided that ``HOutputHandlerOptions::m_pPRCAsmModelFile`` was set to the PRC file handle. For more information about CAD 'views', please read the :doc:`HIO Exchange </prog_guide/hio/HIO_Exchange>` and `HOOPS Exchange documentation <http://docs.techsoft3d.com/exchange/latest/>`_ documentation."

	"Text encoding", "'ISO Latin One', 'utf8', 'utf16', 'utf32', 'wcs', and 'mbs' are supported. All others are not supported."

	"Text font settings", "Supported: name (some limitations), size (some limitations), bold, italic, overline, strikethrough, underline, width scale, transforms, line spacing. Unsupported: extra space, exterior, greeking limit, greeking mode, preference, renderer, rotation (though 'follow path' *is* supported if a text path is given), size tolerance, slant."

	"Font names", "Any built in fonts (like 'stroked') will become the default font when the PDF is loaded. Additionally, any font requests put in the PDF will display as some default font if the PDF is loaded on a system that doesn't have the requested font."

	"Font sizes", "Transformable text in a PDF will always be scalable - sizes like points, pixels, sru, or wru will not have the same behavior as in Visualize. Additionally, screen-facing text will always be a fixed size. Thus, sizes like sru or wru will not have the same behavior as in Visualize."
	
	"Text paths", "Text paths are supported, but text will always appear as if 'rotation = follow path' is set."
	
	"Text regions", "Text regions (``HC_Set_Text_Region``), text spacing (``HC_Set_Text_Spacing``) and per-character attributes (``HC_MSet_Character_Attributes``) are not supported."
	
	"Textures", "Only diffuse and environment textures are supported. Multitexturing is not supported. If you require multitexturing, we recommend you composite the textures into a single texture."

**NOTE:** Text will always come through as markup in the PDF (since that is the only option in PRC). Additionally, some information is lost in the translation from Visualize to PRC. For instance, the text insertion point for PRC is always the lower left, so any alignments are translated into moving the insertion point. PRC doesn't have multiline text strings, so these must be split into multiple lines (though still in a single markup), and things like line spacing are implicitly defined by the position information for multiple text strings in a markup.


.. only:: standard

	HTML export using HOOPS Publish and HOOPS Exchange
	==================================================

	In Visualize, there are two ways to export to HTML, either through the :doc:`HIO HTML </prog_guide/hio/HIO_HTML>` or through the ``HIO_Publish``. With ``HIO_Publish``, it's possible to import a CAD model from ``HIO_Exchange`` - this offers a potential performance benefit because the model data can be read directly from the PRC created in Exchange without incurring the overhead needed for data conversion.

	Please note, the ``HIO_Publish`` HTML export feature is only available for 64-bit versions of the Visualize API, and a HOOPS Exchange license is necessary to import files with ``HIO_Exchange``.

	To export your CAD model to HTML, first import it via HIO Exchange using the ``\ref HBaseModel::Read() "Read()"`` method::

		HFileInputResult result = InputOK;
		HInputHandlerOptions input_options;
		input_options.m_pHBaseView = m_pHView;
		
		result = m_pHView->GetModel()->Read("path_to_my_cad_file", m_pHView, true, &input_options);
		
		// passing the "html_with_prc" file type will return the HOOPS Publish output handler
		HOutputHandler * outputHandler = HDB::GetHIOManager()->GetOutputHandler("html_with_prc");
		
		HOutputHandlerOptions output_options;
		
		// use the path to the Communicator template included in the Visualize package
		const char* templateFile = "c:\\HOOPS_3DF_2210\\Dev_Tools\\hoops_hio\\hio_templates\\HOOPSCommunicatorTemplate.html";
		output_options.m_pHTMLTemplateFile = templateFile;
		output_options.m_pHBaseView = m_pHView;
		output_options.m_pExtendedData = input_options.m_pPRCAsmModelFile;
		result = outputHandler->FileOutputByKey("c:\\temp\\export_sample.html", m_pHView->GetModelKey(), &output_options);

	Once the import has completed, create an output handler for HOOPS Publish, passing "html_with_prc" as the "file type." In order for the export to be successful, the ``\ref HOutputHandlerOptions::m_pExtendedData "m_pExtendedData"`` property must be set to the ``\ref HInputHandlerOptions::m_pPRCAsmModelFile "m_pPRCAsmModelFile"``, which is populated during the import process.

	Then call ``\ref HOutputHandler::FileOutputByKey(const char * filename, HC_KEY key, HOutputHandlerOptions * options) "FileOutputByKey()"`` with your output path, model key, and output options.

	For your convenience, there are two template files in the Visualize package, *HOOPSCommunicatorTemplate.html* and *HOOPSCommunicatorMinimalTemplate.html*. The standard template includes advanced UI features, whereas the minimal template only includes the basic functionality for viewing a model.

	For more information on modifying an HTML template file, please see :ref:`Creating your own custom HTML template <prog_guide/hio/HIO_HTML:Creating a custom template file>`.
