首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Coin3d/OpenInventor添加任意数量的引擎输出

如何使用Coin3d/OpenInventor添加任意数量的引擎输出
EN

Stack Overflow用户
提问于 2016-06-23 10:33:54
回答 1查看 107关注 0票数 0

我正在编写一个应用程序,它使用Coin3d库(它基于与OpenInventor相同的代码库)可视化一个大型数据集。我与这个问题斗争了一段时间,但一直没有找到令人满意的解决办法。

数据以可变数量的“条带”出现,我创建了一个SoEngine来收集数据以供可视化,并将其发送到多个输出,然后将每个条带连接到一个SoQuadMesh进行渲染。

我之所以在这里使用引擎,是因为数据是从数据源获取的,并且可视化是在用户围绕它导航时更新的。也就是说,当用户缩放图像时,图像的分辨率就会发生变化(如google地图所示)。数据在后台线程中检索(需要一两秒钟),然后用于更新引擎输出。

问题是,似乎没有一种方法可以创建任意数量的SoEngineOutput--它们都必须在类定义中声明,然后再使用SO_ENGINE_ADD_OUTPUT宏添加到引擎中。

通过分析Coin源代码,我尝试用稍微修改过的形式实现SO_ENGINE_ADD_OUTPUT宏后面的代码,但最终我失败了(或者失去了勇气),因为SoEngine::outputdata是一个静态字段,应该只创建一次;我不想冒重新初始化它的后果的风险,而不知道整个实现的细节。

我现在使用的解决方案是将所有输出声明到一个可能的最大值,如标题中所示:

代码语言:javascript
复制
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

然后在引擎构造函数中,将每个输出添加到引擎输出列表中:

代码语言:javascript
复制
#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

这是可行的,但是当MAX_NUM_SAMPLE_SETS设置为100时,实例化的Engine类大约为20秒,这意味着声明600 SoEngineOutputs时,性能会受到影响。MAX_NUM_SAMPLE_SETS = 100是最大的--大多数可视化要求比这个(小于10)少得多,所以我希望能够在运行时确定输出的数量。

所以我的问题是:

  1. 是否有方法在运行时在SoEngineOutput中添加任意数量的Coin3d?
  2. 为什么这么多的“`SoEngineOutput”声明会对性能造成影响?(这可能是一个一般性的C++问题,我将为此创建一个单独的问题,或者这是Coin3d的一个问题)
  3. 是否有更好的方法来实现这方面的解决方案?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-23 14:13:53

如果我有50的声誉,可以让我发表评论,我会问你为什么要使用一个SoEngineSoEngine的目的是启用场景图中各种元素之间的计算和构造依赖关系,这些元素在遍历过程中必须是活动的,即动态的,并且可以写入.iv文件。

我的印象是,当您在演示之前加载数据时,您所做的事情需要完成一次。在这种情况下,您可以构建场景图,并直接基于数据集填充节点,而无需通过SoEngine路由。

请注意,即使您在运行时有一个数据流,必须对其进行动态更新,您仍然可以在使用场景图时随意更改它,如果您在遍历场景图时注意不删除或添加节点的话。实现这一点有多种方法,但这可能是另一个问题。

编辑:另一个问题:为什么,如果你一条条地得到数据,你会把它转换成一个SoIndexedFaceSet,而不是SoTriangleStripSet

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37989139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档