9.2 Exporting


HOOPS Visualize can export a few different types of file formats. Regardless of the file type, a similar pattern is employed. For this example we will talk about HSF files, as they are the native file format for HOOPS Visualize. See the Programming Guide sections on Exchange integration and Parasolid integration for information on exporting via HOOPS Exchange and Parasolid, respectively.

When exporting data, HSFs can be written from any arbitrary segment. This means that the entire scene can be saved by writing from the window segment. Alternatively, a portion of the scene can be written if only a piece of a model needs to be saved. Note that when saving partial scenes, attributes inherited by the branch root are not saved with the HSF. If you wish to save attributes into the HSF, they must be explicitly set within the branch you are exporting.

The basic method for exporting a model to HSF is shown below:

[snippet 9.2.a]
try
{
exportOptionsKit.SetColorCompression(true, 16);
HPS::Stream::File::Export(filename, mySegmentKey, exportOptionsKit).Wait();
}
catch (IOException ioe)
{
// handle exception
throw;
}
try
{
exportOptionsKit.SetColorCompression(true, 16); // color compression ranges from 0 to 72
HPS.Stream.File.Export(filename, mySegmentKey, exportOptionsKit);
}
catch (HPS.IOException ioe)
{
// handle exception
}

The HPS::Stream::ExportOptionsKit has a variety of lossy compression options. Color compression is enabled in the snippet above as an example of how to specify compression.

IMPORTANT: All file exports are done synchronously, except for HSF stream files. Do not try to export on a separate thread while the scene graph can be modified, because the scene graph must be in a write-locked state during the export.

For HSF files, the HPS::Stream export operation will happen on a separate thread. Do not modify the subtree while the export is occurring. When exporting stream files, you should use a HPS::Stream::ExportNotifier to control the export operation. For example, you can call:

  • Status(), to receive the current export status and check the progress.
  • Wait(), to block the current thread until the export operation is finished.
  • Cancel(), to cancel the export operation.

If you cancel a file export, you are responsible for cleaning up the partially exported file on disk.

Exporting to a buffer

In addition to saving to an HSF, the HPS::Stream class supports exporting HSF data to a buffer. This is implemented as an overload to HPS::Stream::File::Export.

[snippet 9.2.b]
HPS::ByteArrayArray buffers;
try
{
// write to a series of buffers
HPS::Stream::ExportNotifier exportNotifier = HPS::Stream::File::Export(mySegmentKey, exportOptionsKit, buffers);
// pauses this thread until the HSF is finished exporting
exportNotifier.Wait();
}
catch (HPS::IOException ioe)
{
// handle exception
throw;
}
byte[][] buffers;
try
{
// write to a series of buffers
HPS.Stream.ExportNotifier exportNotifier = HPS.Stream.File.Export(mySegmentKey, exportOptionsKit, out buffers);
exportNotifier.Wait();
}
catch (HPS.IOException ioe)
{
// handle exception
throw;
}

9.2.1 Export events

When writing an HSF file, Visualize can notify you of its progress through the use of HPS::Stream::SegmentExportEvent and HPS::Stream::GeometryExportEvent. You receive these events by setting an HPS::Stream::ExportEventHandler for the HPS::Stream::ExportEvent type (from HPS::Object::ClassID) on your HPS::Stream::ExportOptionsKit. The HPS::Stream::ExportEventHandler class has a virtual function, Handle, that Visualize will call with the HPS::Stream::ExportEvent data when it is about to write the provided data. You should override the Handle function to inspect the data to suit your needs.

The following code sample defines a custom ExportEventHandler class, which will export some non-db user data if a specific segment-name is encountered in the HSF file:

[snippet 9.2.1.a]
class SpecialExportEvent : public HPS::Stream::ExportEventHandler
{
public:
{
if (e != nullptr)
{
HPS::UTF8 name = seg_event->segment_key.Name();
if (name == "My_Special_Segment")
{
const char * str = "HOOPS! HOOPS!";
seg_event->non_db_user_data.assign(str, str+strlen(str));
}
}
}
};
class SpecialExportEvent : HPS.Stream.ExportEventHandler
{
public override void Handle(HPS.Stream.ExportEvent e)
{
string name = seg_event.segment_key.Name();
if (name == "My_Special_Segment")
{
string str = "HOOPS Visualize!";
seg_event.non_db_user_data = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, seg_event.non_db_user_data, 0, seg_event.non_db_user_data.Length);
}
}
};

We then set the custom handler on the HPS::Stream::ExportOptionsKit for the segment-export event, prior to exporting the HSF File:

[snippet 9.2.1.b]
SpecialExportEvent special_export_event;
export_options.SetEventHandler(special_export_event, HPS::Object::ClassID<HPS::Stream::SegmentExportEvent>());
SpecialExportEvent special_export_event = new SpecialExportEvent();
export_options.SetEventHandler(special_export_event, HPS.Object.ClassID<HPS.Stream.SegmentExportEvent>());

User data

User data can be exported to an HSF file in 2 different ways. One form is user-data that is specified within the database and is associated with a segment or geometry (See User Data), and will be automatically exported along with the database. The second form is user-data that is not associated with the database and can be exported by utilizing the HPS::Stream::ExportEvent.non_db_user_data, where you may copy arbitrary data.