概要
Visualizeバージョン23.1以降、VSFXファイルは部分ビューモードでストリーミングされ、ストリーミングベースのソリューションでデスクトップに似た部分表示技術を提供できます。これは、さまざまなケースで使用できます。例えば:
- 線形ストリーミングと比較して、より情報量の多い不完全な最初のフレームを、通常の読み込みと比較して可能な限り高速にレンダリングします。
- RAMの制限により完全にレンダリングできない大きなファイルをレンダリングします。
この技術のもう1つの利点は、サーバーに大きな負荷をかけないことです。オフセットと長さを使用してバイナリファイルの一部を読み取るのに、サーバー上の追加サービスは必要ありません。
部分表示
部分ビューテクノロジーを使用すると、ファイルからサービスオブジェクトのみをロードし、すべてのエンティティとジオメトリをファイル内に保持できます。各 update() 呼び出しは、画面に表示されるエンティティのリストを生成し、これらのエンティティのみがファイルからロードされます。部分ビューをファイルに適用する前に、保存されたデータベースには部分インデックス (実際のエンティティのロードとベクトル化なしで、指定されたビューでどのエンティティが表示されるかを決定する エンティティ識別子 エンティティ範囲> のペアのリスト) が含まれている必要があります。部分ビューは、表示されていたが指定されたビューで非表示になった (画面外になった) エンティティのアンロードもサポートします。部分ビューのもう1つの機能は、指定されたメモリ制限に達した場合にエンティティのロードを防止するリミットマネージャーのサポートです。
リニアストリーミング
通常のファイルロードと部分ファイルロードの両方で、ファイル全体へのアクセスが必要です。しかし、場合によっては、これは不便な制限となります。たとえば、クラウドソリューションでは、ファイル全体をサーバーに送信するのにかかる時間や、限られたメモリを占有するため、ファイル全体をメモリに保持することによってのみアクセスを提供できる場合があります。
VSFXファイルはストリーミングをサポートしており、元のファイルの小さな部分を使用してファイルをロードできます。また、ストリーミングされたファイルを不完全にレンダリングする機能も提供します。VSFXファイルをストリーミングする前に、ストリーミング互換バージョンに変換する必要があります。通常の writeVSFX() メソッドはストリーミング非互換バージョンを作成するためです。ただし、通常の readVSFX() メソッドは、ストリーミング互換バージョンとストリーミング非互換バージョンの両方で機能します。詳細については、「Visualize Streaming の操作」を参照してください。
部分ビュー ストリーミング
部分ビューイングストリーミングは、部分ビューイングとリニアストリーミングの両方の技術を組み合わせたものです。そのため、VSFXファイルには部分インデックスが含まれている必要があり、ストリーミング互換バージョンに変換する必要があります。
主な手順は次のとおりです。
- リニアストリーミングが開始されます。
- すべてのサービスデータが解析されると、リニアストリーミングは停止します。
- 各update()呼び出しは、画面に表示されるエンティティのリストを生成します。
- データベースレシーバーはこのリストを処理し、元のファイルの一部であるオフセットと長さを記述するレコードのリストを生成し、これらのレコードをサーバー側に送信します。
- サーバーはこれらのレコードを処理し、要求されたファイルのパーツをレシーバーに送信します。
- データベースレシーバーはストリーミング技術を使用してこのデータを解析するため、データ(リニアストリーミングモードのファイルと同様)は、バイナリデータ配列全体としてではなく、小さな断片のリストとして処理できます。
OdTvDatabaseReceiverReactor
リニアストリーミングと比較して、部分ビューイングストリーミングは、クライアント側でのOdTvDatabaseReceiverReactorインターフェースの実装を必要とします。
このリアクターインターフェースには、OdTvRequestRecord構造体(データベースレシーバーによって要求されるファイルのパーツを記述する構造体)の定義が含まれています。レシーバーがすべてのサービスセクションを解析すると、次のリアクターメソッドを使用してサーバーに通知します。
virtual bool onServicePartReceived( bool bHasPartialIndex ) = 0;
bHasPartialIndexパラメーターは、データベースが部分インデックスを持っているかどうかを指定します。このコールバックが呼び出された後、通常のOdTvDatabaseReceiver::doReceive呼び出しはデータを解析しません。trueを返し、データベースをkReceiver_RequestMode状態に切り替えます。これは、レシーバーがOdTvDatabaseReceiver::doReceiveResponce()メソッドを使用して要求を生成し、応答を解析することを意味します。
主なリアクターメソッドは次のとおりです。
virtual void onRequest( OdUInt32 requestID, OdUInt32 nRecCount, const OdTvRequestRecord* pRecords ) = 0;
このコールバックは、レシーバーが部分ビューイングリストを処理し、ファイルへの要求が生成されたときに呼び出されます。requestIDパラメーターは要求の識別子を定義し、nRecCountはpRecords配列内の要求レコードの数です。
VSFXファイルは圧縮されたページで構成されているため、各要求レコードはエンティティではなく、単一のページまたはいくつかのファイルページを記述します。複数のエンティティが同じページにある場合があり、それらはすべて単一のレコードによって要求される可能性があります。一方、レシーバーは高速なレコードと要求の組み合わせのみを提供するため(パフォーマンス上の理由から)、レシーバーは同じ要求中に異なるエンティティに対して同じバイナリデータを数回取得することもあります。このため、レコードの長さの合計がファイル自体よりも大きくなることがあり、レコードの数は要求されたエンティティの数に関する情報を提供しません。
コールバックを受信した後、サーバーは要求されたファイルのパーツを読み取り、次のメソッドを使用してレシーバーに送信します。
virtual bool doReceiveResponce( OdUInt32 requestID, const OdUInt8* pData, OdUInt32 nSize, OdTvResult* rc = NULL ) = 0;
ここで:
- requestID - コールバックからの要求の識別子。
- pData - 読み取られたファイルの一部。
- nSize - パーツのサイズ。
注:doReceiveResponce()メソッドはストリーミング技術をサポートしているため、同じrequestIDに対して複数回呼び出すことができ、要求されたデータの一部を線形順序で提供します。
要求が完全に解析されると、レシーバーはdoReceiveResponce()メソッドを呼び出します。
virtual bool doReceiveResponce( OdUInt32 requestID, const OdUInt8* pData, OdUInt32 nSize, OdTvResult* rc = NULL ) = 0;
ただし、リクエストが完全に解析されず、ビュー設定が変更され、新しい update() 呼び出しが発生した場合、レシーバーは新しいリクエストを生成しますが、まずレシーバーは次のコールバックを使用して現在のリクエストをキャンセルする必要があります。
virtual void onRequestAborted( OdUInt32 requestID ) = 0;
ワークフロー
クライアントコードは OdTvDatabaseReceiver クラスのインスタンスを作成する必要があります。
OdTvFactoryId factId = odTvGetFactory();
OdTvDatabaseReceiverPtr pDbReceiver = factId.createDatabaseReceiver();
次に、OdTvDatabaseReceiverReactor インターフェースのクライアント実装を使用して、レシーバーを部分モードに切り替えます。
m_pDbReceiver->enablePartialMode( true, pReactor );
doReceive() が true を返し、レシーバーの状態が kReceiver_RequestMode になるまで、線形ストリーミングが開始されます。
bool bDone = pDbReceiver->doReceive( pData, nDataSize);
OdTvDatabaseReceiver::DatabaseReceivingState state = pDbReceiver->state();
if( bDone && state != OdTvDatabaseReceiver::kReceiver_RequestMode ) throw OD_T(“Internal error” );
if( bDone ) break; //stop linear streaming, start partial-viewing streaming
この場合、OdTvDatabaseReceiverReactor のクライアント実装も onServicePartReceived() 通知を受け取ります。
サーバーは待機し、OdTvDatabaseReceiverReactor::onRequest() が発生すると、サーバーはリクエストに対する応答を送信します。
if( !m_pDbReceiver->doReceiveResponce(requestID, binData.asArrayPtr(), binData.size() ) )
throw OD_T(“Response not parsed” );
追加管理
部分ビューのストリーミングは、OdTvDatabaseReceiverManagementOptions クラスと OdTvDatabaseReceiver メソッドを使用して管理される追加機能をサポートしています。
virtual void setManagementOptions( const OdTvDatabaseReceiverManagementOptions& options ) = 0;
リミットマネージャー
部分ビューのストリーミングにおけるリミットマネージャーは、次の場合に役立ちます。
- 通常の部分ビューと同様に、各要求されたエンティティをロードする前にレシーバーが使用されます。制限に達した場合、レシーバーは後続のエンティティをロードしません。
- レシーバーは、リクエストを生成する際にリミットマネージャーを使用できます。ファイル内のエンティティ長を使用して、エンティティのロードに必要なメモリを推定します。リミットマネージャーが推定値が制限を超えていることを示す場合、レシーバーはこれらのエンティティをリクエストに含めません。この目的のために、レシーバーは OdTvDatabaseReceiverManagementOptions::memoryEstimationMultiplier() メソッドを使用します。ただし、この乗数の実際の値は純粋にヒューリスティックであり、ファイルによって異なる場合があります。このトピックで後述するレシーバー統計は、この値を定義するのに役立ちます。
OdTvLimitManager のインスタンスは、次のファクトリメソッドを使用して指定できます。
void setLimitManager( OdTvLimitManager* pManager );
オブジェクトのアンロード
通常の部分ビューと同様に、部分ビューのストリーミングは、ロードされたが現在画面外にあるオブジェクトのアンロードをサポートしています。デフォルトでは、アンロードが有効になっている場合、すべての画面外オブジェクトはアンロードされます。ただし、この操作はレンダリングパフォーマンスを低下させるため、スケジューラの制限を指定できます。この場合、レシーバーは、各 update() 呼び出し中に、指定された unloadTimeLimit パラメーターを超える時間をアンロードに費やしません。すべてのオブジェクトをアンロードする時間がない場合、残りのオブジェクトは次の update() 呼び出し中にアンロードされます。
オブジェクトのアンロードは、次の OdTvDatabaseReceiverManagementOptions メソッドによって管理されます。
void setObjectsUnloading( bool bUnload, OdUInt32 unloadTimeLimit = 0 );
ここで、
- bUnload — アンロードを有効にするフラグ。
- unloadTimeLimit — アンロードの時間制限 (0 は「制限なし」を意味します)。
統計の生成
統計の生成は、次の OdTvDatabaseReceiverManagementOptions メソッドを使用して管理できます。
void setEnableStatistic( bool bEnable, bool bOnlyRequestedItems = true, bool bCountUnloadObjects = false );
ここで、
- bEnable — 統計の収集を有効にします。
- bOnlyRequestedItems — リクエストの統計のみが収集されることを指定します (線形ストリーミングワークフローからのサービスオブジェクトの統計は収集されません)。
- bCountUnloadObjects — アンロードされたオブジェクトを統計に含めることを指定します。
統計が有効になっている場合、結果は次の OdTvDatabaseReceiver メソッドから OdTvDatabaseReceiver::StatisticTool を使用して取得できます。
virtual const StatisticTool* statisticTool() const = 0;
統計には、解析されたオブジェクトとアンロードされたオブジェクトの数と長さ (生、非圧縮) に関する情報が含まれます。
クライアント側が消費メモリの計算をサポートしている場合、このツールを異なる反復で使用して、OdTvDatabaseReceiverManagementOptions::memoryEstimationMultiplier() のカスタム値を推定できます。