######################
Simple Load and Export
######################

.. sidebar::

   .. contents::
      :local:


Whether you need to convert a CAD file to another format or explore its content using the API, the first step is always the same: loading the file into memory.
This document covers how to load and export CAD files with HOOPS Exchange.

In HOOPS Exchange, a CAD file loaded into memory is called a **model file**.
It can be referenced using the :c:type:`A3DAsmModelFile` type, which represents the **topmost entity** of your file.

.. _load_model_import:

Loading a CAD File
==================

To load a model file from disk, use the :c:func:`A3DAsmModelFileLoadFromFile` function.
It requires:

* a *C-string file path* (``A3DUTF8Char*``),
* a set of load parameters (:c:struct:`A3DRWParamsLoadData`), and
* a location to store the *model file* handle (``A3DAsmModelFile**``).

.. code-block:: c

   A3DAsmModelFile*    model_file  = A3D_NULL_HANDLE;
   A3DRWParamsLoadData read_params = A3D_MAKE_DATA(A3DRWParamsLoadData);

   A3DStatus status = A3DAsmModelFileLoadFromFile("path/to/file", &read_params, &model_file);

The function returns ``A3D_SUCCESS``, or another code in case of failure.
See the reference guide for :c:func:`A3DAsmModelFileLoadFromFile` for the complete list of possible errors.
If the file is properly loaded, ``model_file`` contains a handle to a valid model file entity.

Once your model file is loaded, you can:

- :ref:`Export it to any of our supported formats <load_model_export>`
- :doc:`Traverse and manipulate its content <prc_basics>`
- :ref:`Unload it from memory <load_model_unload>`

Using Custom Import Options
---------------------------

Before loading a file, you can configure import parameters to specify what data to load.
Use the :c:struct:`A3DRWParamsLoadData` structure to enable the features you need, such as solids, surfaces, or PMI.

:c:struct:`A3DRWParamsLoadData` is an extensive structure that contains several sub-structures:

.. csv-table::
   :header-rows: 1

   Field Name, Structure, Description
   ``m_sGeneral``, :c:struct:`A3DRWParamsGeneralData`, General reading parameters
   ``m_sPmi``, :c:struct:`A3DRWParamsPmiData`, Parameters for PMI reading
   ``m_sTessellation``, :c:struct:`A3DRWParamsTessellationData`, Tessellation reading parameters
   ``m_sAssembly``, :c:struct:`A3DRWParamsAssemblyData`, Reading parameters for assembly files
   ``m_sMultiEntries``, :c:struct:`A3DRWParamsMultiEntriesData`, Parameters for reading multiple models
   ``m_sSpecifics``, :c:struct:`A3DRWParamsSpecificLoadData`, Parameters specific to each CAD format
   ``m_sIncremental``, :c:struct:`A3DRWParamsIncrementalLoadData`, Reading parameters for incremental loading

You do not need to set all fields explicitly.
Only set the ones you need, and leave the others default-initialized.

.. code-block:: c

   A3DRWParamsLoadData params = A3D_MAKE_DATA(A3DRWParamsLoadData);

   params.m_sGeneral.m_bReadSolids   = A3D_TRUE;
   params.m_sGeneral.m_bReadSurfaces = A3D_TRUE;
   params.m_sGeneral.m_bReadPmis     = A3D_TRUE;

   A3DAsmModelFile* model_file = A3D_NULL_HANDLE;
   A3DStatus status = A3DAsmModelFileLoadFromFile("model.stp", &params, &model_file);

Here is a more complete example from the :doc:`/examples/import_export`:

.. literalinclude:: /../../../final-package/samples/hello_world/ImportExport/ImportExport.cpp
   :start-after: [import]
   :end-before: [!import]
   :linenos:
   :lineno-match:

The model file handle returned by :c:func:`A3DAsmModelFileLoadFromFile` doesn't contain data directly.
To navigate the CAD hierarchy, retrieve its information using :c:func:`A3DAsmModelFileGet`.
See the :doc:`prc_basics` page for more information.

.. _load_model_unload:

Unloading a Model File
----------------------

When you're done with a model file, free it using :c:func:`A3DAsmModelFileDelete`:

.. code-block:: c

   A3DStatus status = A3DAsmModelFileDelete(model_file);

Incremental Load
----------------

Incremental load allows you to load specific parts into memory without loading the entire model.
Exchange loads the full assembly structure (product occurrences), but only the geometry and tessellation of specified parts.
This reduces memory overhead and improves performance for large CAD models.

Incremental load is available for certain file formats, including SolidWorks, NX (Unigraphics), Creo (Pro/E), JT, and CATIA V5.
Support is indicated on the :doc:`format information pages </start/supported-formats>`.

The workflow consists of two steps:

1. **Load structure only**: Load the assembly tree without geometry
2. **Load specific parts**: Load geometry for selected product occurrences

.. code-block:: c

   // Step 1: Load assembly structure only
   A3DRWParamsLoadData load_params = A3D_MAKE_DATA(A3DRWParamsLoadData);
   load_params.m_sIncremental.m_bLoadStructureOnly = A3D_TRUE;

   A3DAsmModelFile* model_file = A3D_NULL_HANDLE;
   A3DStatus status = A3DAsmModelFileLoadFromFile("assembly.CATProduct", &load_params, &model_file);

   // Traverse the assembly tree to find the parts you need...
   // Store the target part in pLeafProductOccurrence
   // Store its parent in pRootProductOccurrence

   // Step 2: Load geometry for specific parts
   load_params.m_sGeneral.m_eReadGeomTessMode = kA3DReadGeomAndTess;
   load_params.m_sIncremental.m_bLoadStructureOnly = A3D_FALSE;
   load_params.m_sIncremental.m_ppProductOccurrences = &pLeafProductOccurrence;
   load_params.m_sIncremental.m_uiProductOccurrencesSize = 1;
   load_params.m_sIncremental.m_pRootProductOccurrence = pRootProductOccurrence;

   status = A3DAsmModelFileLoadFromFile("assembly.CATProduct", &load_params, &model_file);

.. note::

   - Only leaf nodes (parts with geometry) can be loaded incrementally.
   - Assembly-level geometry, PMI, and views are not supported.
   - Attempting to load an assembly product occurrence returns ``A3D_LOAD_INVALID_PARAMETERS_FOR_INCREMENTAL_LOAD``.
   - Metadata for JT format is not supported in incremental mode.

To unload parts after use, call :c:func:`A3DAsmModelFileUnloadParts`.

A complete example is available in the :ref:`sample_incremental` sample.
You can also evaluate incremental mode in the `HOOPS Demo Viewer <https://developer.techsoft3d.com/hoops/demos/>`_ (see the `HDV documentation <https://docs.techsoft3d.com/hdv/latest/index.html>`_ for instructions).

Loading a PDF Model
-------------------

HOOPS Exchange supports reading PRC and U3D content embedded in PDF files.
This is done by first :c:func:`extracting data streams from a PDF file <A3DGet3DPDFStreams>` and :c:func:`loading those streams <A3DAsmModelFileLoadFromPrcStream>` into a new model file.

For more information, see :ref:`loading_pdf`.

.. _load_model_export:

Exporting a CAD File
====================

Each export format has its own function and parameter structure.
The general pattern is:

1. Create and configure an export parameters structure
2. Call the format-specific export function

.. code-block:: c

   // Example: Export to STEP
   A3DRWParamsExportStepData export_params = A3D_MAKE_DATA(A3DRWParamsExportStepData);
   export_params.m_bSaveFacetedToWireframe = A3D_TRUE;

   A3DStatus status = A3DAsmModelFileExportToStepFile(model_file, &export_params, "output.stp");

The supported export formats are listed in the :doc:`supported formats </start/supported-formats>` page.

Export Functions Reference
--------------------------

The following table lists all available export functions and their parameter structures:

.. csv-table::
   :header-rows: 1

   Format, Function, Parameters Structure
   3MF, :c:func:`A3DAsmModelFileExportTo3mfFile`, :c:struct:`A3DRWParamsExport3mfData`
   ACIS, :c:func:`A3DAsmModelFileExportToAcisFile`, :c:struct:`A3DRWParamsExportAcisData`
   FBX, :c:func:`A3DAsmModelFileExportToFbxFile`, :c:struct:`A3DRWParamsExportFbxData`
   glTF, :c:func:`A3DAsmModelFileExportToGltfFile`, :c:struct:`A3DRWParamsExportGltfData`
   HTML, :c:func:`A3DAsmModelFileExportToHTMLFile`, :c:struct:`A3DRWParamsExportHtmlData`
   IGES, :c:func:`A3DAsmModelFileExportToIgesFile`, :c:struct:`A3DRWParamsExportIgesData`
   JT, :c:func:`A3DAsmModelFileExportToJTFile`, :c:struct:`A3DRWParamsExportJTData`
   OBJ, :c:func:`A3DAsmModelFileExportToObjFile`, :c:struct:`A3DRWParamsExportObjData`
   Parasolid, :c:func:`A3DAsmModelFileExportToParasolidFile`, :c:struct:`A3DRWParamsExportParasolidData`
   PRC, :c:func:`A3DAsmModelFileExportToPrcFile`, :c:struct:`A3DRWParamsExportPrcData`
   SCS, :c:func:`deprecated_A3DAsmModelFileExportToSCSFile`, :c:struct:`deprecated_A3DRWParamsExportScsData`
   STEP, :c:func:`A3DAsmModelFileExportToStepFile`, :c:struct:`A3DRWParamsExportStepData`
   STL, :c:func:`A3DAsmModelFileExportToStlFile`, :c:struct:`A3DRWParamsExportStlData`
   U3D, :c:func:`A3DAsmModelFileExportToU3DFile`, :c:struct:`A3DRWParamsExportU3DData`
   VRML, :c:func:`A3DAsmModelFileExportToVrmlFile`, *(none)*
   XML, :c:func:`A3DAsmModelFileExportToXMLFile`, :c:struct:`A3DRWParamsExportXMLData`

Here is an example exporting to JT with custom options:

.. code-block:: c

   A3DRWParamsExportJTData export_params = A3D_MAKE_DATA(A3DRWParamsExportJTData);
   export_params.m_eWriteGeomTessMode    = kA3DWriteGeomAndTess;
   export_params.m_bWritePMI             = A3D_TRUE;

   A3DStatus status = A3DAsmModelFileExportToJTFile(model_file, &export_params, "output.jt");

Using the C++ Convenience Wrapper
=================================

HOOPS Exchange provides a C++ convenience wrapper called ``HOOPSExchangeLoader`` for simpler file-to-file conversion scenarios.
This wrapper is useful when you don't need to manipulate the model file between import and export.

The wrapper uses ``A3DImport`` and ``A3DExport`` classes to configure options, and the ``Convert()`` method to perform the conversion in a single call.
The export format is determined automatically from the output file extension.

.. code-block:: cpp

   #include <ExchangeToolkit.h>

   HOOPSExchangeLoader loader;

   A3DImport import_options("input.CATProduct");
   A3DExport export_options("output.step");

   A3DStatus status = loader.Convert(import_options, export_options);

You can also customize import and export parameters through the wrapper:

.. code-block:: cpp

   A3DImport import_options("input.CATProduct");
   import_options.m_sLoadData.m_sGeneral.m_bReadPmis = A3D_TRUE;

   A3DExport export_options("output.jt");
   export_options.m_sExportData.m_bWritePMI = A3D_TRUE;

   A3DStatus status = loader.Convert(import_options, export_options);

.. note::

   The ``HOOPSExchangeLoader`` wrapper is best suited for simple conversion workflows.
   For more control over the model file (traversal, modification, multiple exports), use the C API functions directly.

Related Pages
=============

* **Getting Started:** :doc:`/start/supported-formats`
* **Example Code:** :doc:`/examples/import_export`
* **Tutorial:** :doc:`/tutorials/c/file-to-file-translation`
* **Programming Guide:** :doc:`prc_basics`
* **API Reference:** :ref:`group__a3d__publish__modelfile__loadexport`
