Coin3d ライブラリ (OpenInventor と同じコード ベースに基づく) を使用して大規模なデータ セットを視覚化するアプリケーションを作成しています。私はしばらくこの問題に取り組んできましたが、満足のいく解決策を見つけられませんでした。
データは可変数の「ストリップ」でSoEngine
提供されます。視覚化するデータを収集し、それを多数の出力に送信し、SoQuadMesh
レンダリングのために各ストリップに接続する を作成しました。
ここでエンジンを使用している理由は、データがデータ ソースからフェッチされ、ユーザーがナビゲートすると視覚化が更新されるためです。つまり、ユーザーがズームインおよびズームアウトすると、画像の解像度が変更されます (Google マップによる)。データはバックグラウンド スレッドで取得され (1 ~ 2 秒かかります)、エンジン出力の更新に使用されます。
問題は、任意の数の を作成する方法がないように見えることです。SoEngineOutput
それらはすべて、SO_ENGINE_ADD_OUTPUT
マクロを使用してエンジンに追加する前に、クラス定義で宣言する必要があります。
Coin のソース コードを分析することで、マクロの背後にあるコードをSO_ENGINE_ADD_OUTPUT
わずかに変更した形式で実装することで、これを回避しようとしましたが、最終的には失敗しました (または神経を失いSoEngine::outputdata
ました)。内部の実装全体の詳細を知らずに、再初期化の結果を危険にさらしたくありませんでした。
私が現在取り組んでいる解決策は、ヘッダーのように、すべての出力を可能な最大値まで宣言することです。
class Engine : public SoEngine
{
SO_ENGINE_HEADER(Engine);
public:
// The output: vector of points, edges, colours and indices
// A set of these is needed for each strip in the visualisation
SoEngineOutputList dataPoints;
SoEngineOutputList edgePoints;
SoEngineOutputList dataColours;
SoEngineOutputList edgeColours;
SoEngineOutputList numSamples;
SoEngineOutputList numDepths;
// Macro to simplify and shorten the code for adding multiple engine outputs
#define ENGINE_DECLARE_OUTPUTS(N) \
SoEngineOutput dataPoints_##N; /*SoMFVec3f*/ \
SoEngineOutput edgePoints_##N; /*SoMFVec3f*/ \
SoEngineOutput dataColours_##N; /*SoMFColor*/ \
SoEngineOutput edgeColours_##N; /*SoMFColor*/ \
SoEngineOutput numSamples_##N; /*SoSFInt32 */ \
SoEngineOutput numDepths_##N; /*SoSFInt32 */
// Declare all the outputs from the engine. Note that they have to be added
// individually because it uses the macro above.
ENGINE_DECLARE_OUTPUTS(0);
ENGINE_DECLARE_OUTPUTS(1);
ENGINE_DECLARE_OUTPUTS(2);
ENGINE_DECLARE_OUTPUTS(3);
// etc. all the way to a constant MAX_NUM_SAMPLE_SETS
次に、Engine コンストラクターで、各出力をエンジンの出力リストに追加します。
#define ENGINE_ADD_OUTPUTS(N) \
SO_ENGINE_ADD_OUTPUT(dataPoints_##N, SoMFVec3f); \
SO_ENGINE_ADD_OUTPUT(edgePoints_##N, SoMFVec3f); \
SO_ENGINE_ADD_OUTPUT(dataColours_##N, SoMFColor); \
SO_ENGINE_ADD_OUTPUT(edgeColours_##N, SoMFColor); \
SO_ENGINE_ADD_OUTPUT(numSamples_##N, SoSFInt32); \
SO_ENGINE_ADD_OUTPUT(numDepths_##N, SoSFInt32); \
dataPoints.append(&dataPoints_##N); \
edgePoints.append(&edgePoints_##N); \
dataColours.append(&dataColours_##N); \
edgeColours.append(&edgeColours_##N); \
numSamples.append(&numSamples_##N); \
numDepths.append(&numDepths_##N);
// Add all the outputs from the engine. Note that they have to be added
// individually because it uses the macro above. The number added should match
// the number defined in MAX_NUM_SAMPLE_SETS
ENGINE_ADD_OUTPUTS(0);
ENGINE_ADD_OUTPUTS(1);
ENGINE_ADD_OUTPUTS(2);
ENGINE_ADD_OUTPUTS(3);
// etc. all the way to a constant MAX_NUM_SAMPLE_SETS
これは機能しますが、 Engine クラスが 100 に設定されている場合、約 20 秒インスタンス化されるとパフォーマンスが低下します。MAX_NUM_SAMPLE_SETS
これは 600 の宣言を意味しSoEngineOutputs
ます。MAX_NUM_SAMPLE_SETS = 100
は可能な限り最大です - ほとんどの視覚化ではこれよりもはるかに少ない (10 未満) 必要があるため、実行時に出力の数を決定できるようにしたいと考えています。
だから私の質問は:
SoEngineOutput
実行時に Coin3d に任意の数の s を追加する方法はありますか?- `SoEngineOutput の宣言の数がこれほど多いのはなぜですか? (これは、別の質問を作成する一般的な C++ の質問であるか、Coin3d の問題である可能性があります)
- これに対する解決策を実装するためのより良い方法はありますか?