0

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 未満) 必要があるため、実行時に出力の数を決定できるようにしたいと考えています。

だから私の質問は:

  1. SoEngineOutput実行時に Coin3d に任意の数の s を追加する方法はありますか?
  2. `SoEngineOutput の宣言の数がこれほど多いのはなぜですか? (これは、別の質問を作成する一般的な C++ の質問であるか、Coin3d の問題である可能性があります)
  3. これに対する解決策を実装するためのより良い方法はありますか?
4

1 に答える 1

1

私がコメントできる50の評判があれば、なぜSoEngineこれに を使いたいのか尋ねます. sの目的はSoEngine、シーン グラフ内のさまざまな要素間の計算を可能にし、依存関係を構築することです。これらの要素は、走査中にアクティブにする必要があります。つまり、動的に、.ivファイルに書き込むことができます。

プレゼンテーションの前にデータをロードするときに、一度行う必要があるという印象を受けます。その場合、シーン グラフを作成し、データ セットに基づいてノードを直接埋めることができますSoEngine

実行時に視覚化を動的に更新する必要があるデータ ストリームがある場合でも、使用中にノードを削除または追加しないように注意すれば、使用中にシーン グラフを自由に変更できることに注意してください。横断した。これを達成するにはさまざまな方法がありますが、それはおそらく別の問題です。

編集:別の質問:なぜ、データをストリップで取得した場合、そもそもそれを変換するのではSoIndexedFaceSetなくSoTriangleStripSet、に変換するのですか?

于 2016-06-23T14:13:53.140 に答える