概要
Visualize SDKファイル形式VSFXには、ストリーミングサポートが組み込まれています。これは、VSFXファイルがバイナリ配列のセットとして提供できる場合、Visualize SDKがこれらの配列を一貫して処理し、これらの配列のコンテンツを使用してVisualizeデータベースを生成できることを意味します。また、「十分な」配列を提供することで、不完全なデータベースでもレンダリングできます。Visualize SDKは解析されたデータをメモリに保持しないため、不完全なデータベースはソースデータの未解析部分のみをメモリに保持します。ただし、いくつかの制限があるため、通常のVSFXファイルは効率的にストリーミングされる前に前処理する必要があります。この記事では、前処理フェーズとデータベースデータの収集プロセスについて説明します。
VSFXの前処理
ストリーミング互換性
VSFXファイルは、セクションのセットとして表現できます。すべてのセクションは、オブジェクトセクション(Visualizeオブジェクトデータ:エンティティ、ジオメトリ、デバイスなどを含む)とサービスセクション(オブジェクトセクションの解析方法を記述する)の2つのグループに分けられます。
サービスセクションはオブジェクトセクションに依存するため、VSFXファイルを生成すると、サービスセクションはオブジェクトセクションの後に配置されます。このようなファイルのストリーミングは完全に非効率的です。ファイル全体のコンテンツがストリーミングされた後にのみ、Visualize SDKはそれを読み取ることができます。このようなファイルはストリーミング非互換と呼ばれます。
OdTvDatabaseReceiverには、VSFXファイルがストリーミング互換であるかどうかをチェックできる静的メソッドと、ストリーミング非互換のVSFXファイルをストリーミング互換ファイルに変換できるメソッドがあります。
static bool isStreamingCompatible( const OdString& fileName, OdTvResult* pRes = NULL );
static bool isStreamingCompatible( OdStreamBuf* pBuffer, OdTvResult* pRes = NULL );
static OdTvResult makeStreamingCompatible( const OdString& input, const OdString& output );
static OdTvResult makeStreamingCompatible( OdStreamBuf* pInput, OdStreamBuf* pOutput );
Visualize SDKはVSFXファイルのセクションをその内容を解析せずに交換するだけなので、ストリーミング互換ファイルへの変換は十分に高速なプロセスです。
また、一般的なVisualize SDKのVSFXファイル読み込みメソッドは、ストリーミング互換ケースとストリーミング非互換ケースの両方で同様に効果的です。
以下の画像は、ストリーミング互換ケースとストリーミング非互換ケースにおけるセクション位置の違いを示しています。
ストリーミング対応ファイル
VSFXストリーミングの主な目的は、VSFXファイルの一部のみが解析されたときにVisualizeデータベースをレンダリングすることです。しかし、レンダリング可能なオブジェクト(エンティティ、ジオメトリ、挿入物)に加えて、オブジェクトセクションにはレンダリングに必要なオブジェクト(デバイス、ビュー、線種など)も含まれています。したがって、必要なすべてのオブジェクトを受信していない不完全なデータベースをレンダリングすることは不可能であるか(デバイスやビューが解析されていないため)、または完全なデータベースをレンダリングした場合と著しく異なる結果(誤った色、線種など)をもたらす可能性があります。
ストリーミング対応のVSFXファイルでは、オブジェクトセクションは、レンダリングに必要なすべてのオブジェクトがレンダリング可能なオブジェクトの前に配置されるように構成されています。これらのファイルは、必要なすべてのオブジェクトが解析された後に正しくレンダリングできます。
ストリーミング非対応のVSFXファイルでも、不完全なデータベースをレンダリングできますが、この場合、クライアントアプリケーションは、データベースがすでに必要なすべてのオブジェクトを解析していることを確認する必要があります。例えば、デバイスおよびビューのイテレータ、線種のイテレータなどを確認できます。
一般的なVSFXファイル書き込みメソッドは、常にストリーミング対応のコンテンツを生成します。ただし、データベースの部分的なオブジェクトのアンロード(低メモリインポートなど)は、ストリーミング非対応のファイルを生成する可能性があります。
isStreamingFriendlySource()メソッドは、データ解析がストリーミング対応であるかどうかをチェックし、trueを返した場合、isDatabaseRenderable()メソッドはデータベースがレンダリング可能であることを通知します。
オブジェクトセクションに、デバイス、レイヤー、エンティティ、ジオメトリの4種類のデータが含まれているとします。デバイスとレイヤーのデータはレンダリングに必要です。したがって、一部のレイヤーに色がある場合、「レイヤーごとの色」が割り当てられたレイヤー上のエンティティは、そのようなエンティティがレンダリングされる前にこれらのレイヤーがロードされていないと、誤ってレンダリングされます(この場合、デフォルトのレイヤーが使用されるため)。残りのデータ(エンティティとジオメトリ)はレンダリング可能なデータです。レンダリング可能なオブジェクトがロードされると、レンダリングシーンはより詳細な情報を受け取りますが、これらのオブジェクトの一部が欠落している場合、それらは描画されず、以前に描画されたオブジェクトには影響しません。
次の画像は、説明した例におけるストリーミング対応とストリーミング非対応のケースの違いを示しています。
クライアントアプリケーションでのデータベースの収集
クライアント側でデータベースを収集するには:
- OdTvFactory インスタンスを使用して OdTvDatabaseReceiver のインスタンスを作成します。
OdTvFactoryId factId = odTvGetFactory(); OdTvDatabaseReceiverPtr pDbReceiver = factId.createDatabaseReceiver(); - レシーバーは各入力データ配列を処理する必要があります。
/*Input: const OdUint8* pData; //part of .VSFX file OdUInt32 nDataSize; //length of pData array */ bool bDone = pDbReceiver->doReceive( pData, nDataSize); - doReceive メソッドは、データベースが完全に受信された場合に true を返します。この場合、データ受信プロセスを停止できます。それ以外の場合、アプリケーションは不完全なデータベースがレンダリング可能かどうかを判断する必要があります。まず、DatabaseReceivingState 列挙値で表される受信ステータスを確認します。
ステータスは次のいずれかです。OdTvDatabaseReceiver::DatabaseReceivingState state = pDbReceiver->state();- OdTvDatabaseReceiver::kReceiver_Nothing — 何も受信されていません。データベースは空です。
- OdTvDatabaseReceiver::kReceiver_AwaitingServiceData — データ解析は開始されていますが、現在サービスセクションも完了していないため、データベースはまだ空です。
- OdTvDatabaseReceiver::kReceiver_AwaitingObjectsData — データ解析が開始され、すべてのサービスセクションが受信されました。この状態から、アプリケーションはデータベースにアクセスし、そのコンテンツをレンダリングしようとすることができます。
- OdTvDatabaseReceiver::kReceiver_Complete — データベースは完全に受信され、制限なくさらなる処理を行う準備ができています。
ステータスが OdTvDatabaseReceiver::kReceiver_AwaitingObjectsData より低い場合、アプリケーションはデータベース処理なしでデータの受信を続行する必要があります。ステータスが OdTvDatabaseReceiver::kReceiver_AwaitingObjectsData より高い場合、データベースは完全に受信されています。
ステータスが OdTvDatabaseReceiver::kReceiver_AwaitingObjectsData の場合 (ほとんどのケースで VSFX ファイルの大部分がオブジェクトセクションを含んでいるため)、アプリケーションは VSFX ソースがストリーミングフレンドリーであるかどうかを確認し、もしそうであれば、isDatabaseRenderable() メソッドを使用してデータベースをレンダリングできるかどうかを確認できます。
if( state == OdTvDatabaseReceiver::kReceiver_AwaitingObjectsData ) { if( pDbReceiver->isStreamingFriendlySource() ) return pDbReceiver->isDatabaseRenderable(); } - OdTvDatabaseReceiver::kReceiver_Nothing — 何も受信されていません。データベースは空です。
- OdTvDatabaseReceiver::kReceiver_AwaitingServiceData — データ解析は開始されていますが、現在サービスセクションも完了していないため、データベースはまだ空です。
- OdTvDatabaseReceiver::kReceiver_AwaitingObjectsData — データ解析が開始され、すべてのサービスセクションが受信されました。この状態から、アプリケーションはデータベースにアクセスし、そのコンテンツをレンダリングしようとすることができます。
- OdTvDatabaseReceiver::kReceiver_Complete — データベースは完全に受信され、制限なくさらなる処理を行う準備ができています。
- VSFXソースファイルがストリーミングに適していない場合、アプリケーションはレンダリングに必要なすべてのオブジェクトを開けるかどうかを手動で確認する必要があります。たとえば、次のコードは、データベースに最初のデバイスと少なくとも1つのビューが含まれているかどうかをチェックします。
OdTvDatabaseId dbID = pDbReceiver->database(); OdTvDatabasePtr pDb = dbID.openObject( OdTv::kForRead ); if( pDb.isNull() ) return false; OdTvDevicesIteratorPtr pDevIt = pDb->getDevicesIterator(); if( pDevIt.isNull() ) return false; OdTvGsDeviceId devId = pDevIt->getDevice(); if( devId.isNull() ) return false; OdTvGsDevicePtr pDevice = devId.openObject( OdTv::kForRead ); bool anyView = false; OdTvResult tvRes = tvOk; int nViews = pDevice->numViews( &tvRes ); if( tvRes != tvOk || nViews == 0 ) return false; for( int i = 0; i < nViews; ++i ) { if( !pDevice->viewAt( i ).isNull() ) anyView = true; } return anyView;
例
OdVisualizeFirstAppサンプルアプリケーションには、ストリーミングツールが実装されています。これはネットワークアプリケーションではないため、VSFXファイルからバイナリデータチャンクを読み取ることでストリーミングをエミュレートします。また、入力VSFXファイルのストリーミング互換性チェックと変換機能も備えており、これらは通常サーバー側で実装されるべきです。
OdVisualizeFirstAppアプリケーションでストリーミングツールを有効にするには、CommonApplications/Visualize/Examples/win/OdVisualizeFirstApp/resource.h内のOD_VISUALIZE_APP_ENABLE_STREAMING定義のコメントを解除する必要があります。サンプルコードの場所:OdVisualizeAppStreaming.hおよびOdVisualizeAppStreaming.cpp。