How to access a variable array through CAPI?

Is it possible to access the data in a variable array in a similar way to accessing an external array (by getting a pointer and length)? Would I need to use something like getData()?




  • craouettecraouette Posts: 113

    As far as I know, than answer is no, getData is working on external arrays.
    You have to use something like (to create):

    FabricCore::RTVal arrayVal = RTVal::ConstructVariableArray(a3dSpliceDFG.client, "Vec3");
    FabricCore::RTVal numVals =  RTVal::ConstructUInt32(a3dSpliceDFG.client, (uint32_t) numElems);
    arrayVal.callMethod("", "resize", 1, &numVals);
    for(uint32_t i = 0; i < numElems; ++i)
      FabricCore::RTVal elem = RTVal::Construct(a3dSpliceDFG.client, 
                                                "Vec3", 0, 0);
      elem.setMember("x", RTVal::ConstructFloat32(a3dSpliceDFG.client, value->x));
      elem.setMember("y", RTVal::ConstructFloat32(a3dSpliceDFG.client, value->y));
      elem.setMember("z", RTVal::ConstructFloat32(a3dSpliceDFG.client, value->z));
      arrayVal.setArrayElement(i, elem);

    and use

    uint32_t getArraySize()
    RTVal getArrayElement( uint32_t index ) const

    to read the array.

  • josh3lightjosh3light Posts: 8

    I see, I'll have to see what the performance overhead is for having each member as a separate RTVal, boxing and unboxing. It might be nice to have an optimized convenience function provided by the Fabric Core capi to convert a variable array to an external array. Does that sound feasible?

  • craouettecraouette Posts: 113

    in fact, most of time, the external array is only used temporarily...
    For example, here is the code for setting points of a polygonMesh from an external array:

    /// \internal
    operator PolygonMesh_getPointsAsExternalArrayTask(Index index, io Float32 values<>, Size components, io PolygonMesh mesh) {
      Index offset = index * components;
      Vec3 pos = mesh.getPointPosition(index);  
      values[offset++] = pos.x;
      values[offset++] = pos.y;
      values[offset++] = pos.z;
      if(components > 3)
        values[offset] = 1.0;
    /// Gets the point positions as a Float32 array.
    /// Values are ordered by polygon points (Poly0Point0, Poly0Point1, Poly0Point2, ..., Poly1Point0, Poly1Point1... ).
    /// \param components indicates the number of Float32 to be returned for each point, and should be 3 or 4. If 4, a 1.0 will pad the 4th component.
    /// \category ImportExportHelpers
    function PolygonMesh.getPointsAsExternalArray(io Float32 values<>, Size components) {
      PolygonMesh foo = this;
      if(values.size() / components >= this.pointCount()) {
        if(this.pointCount() >= PolygonMesh_ExecuteParallel_Count) {
          PolygonMesh_getPointsAsExternalArrayTask<<<this.pointCount()>>>(values, components, foo);
        } else {
          for(Size i=0;i<this.pointCount();i++) {
            PolygonMesh_getPointsAsExternalArrayTask(i, values, components, foo);
  • josh3lightjosh3light Posts: 8

    @craouette Thanks, that may be useful for me in the future. Currently I'm still searching for an optimal solution for:
    (processing data in canvas) -> (dynamically allocated array of an arbitrary size easily accessible in c++ after the graph is processed)
    If I know the array size beforehand, I'll use an external array.

Sign In or Register to comment.