void FieldContainer::dumpFieldInfo(void) const
{
    const TypeObject &oType = this->getType();

    fprintf(stderr, "Dump Container (%s) Field Info\n",
            oType.getCName());

    for(UInt32 i = 1; i <= oType.getNumFieldDescs(); ++i)
    {
        FieldDescriptionBase *pDesc = oType.getFieldDesc(i);

        if(pDesc != NULL)
        {
            UInt32 uiTmp  = (_bvChanged & pDesc->getFieldMask()) != 0x0000;
            UInt32 uiTmp1 = 0x0000;

            fprintf(stderr, WS30"                                  ch : %x\r", 
                    uiTmp);


            uiTmp  = (pDesc->getFlags() & Field::FClusterLocal) != 0x0000;
            uiTmp1 = (_pFieldFlags->_bClusterLocalFlags & 
                       pDesc      ->getFieldMask()       ) == 0x0000;

            fprintf(stderr, WS30"                     cl : %x | %x\r",
                    uiTmp,
                    uiTmp1);


            uiTmp  = (pDesc->getFlags() & Field::FThreadLocal) != 0x0000;
            uiTmp1 = (_pFieldFlags->_bThreadLocalFlags & 
                       pDesc      ->getFieldMask()     ) == 0x0000;

            fprintf(stderr, WS30"        tl : %x | %x\r",
                    uiTmp,
                    uiTmp1);


            fprintf(stderr, "(%d) : %s :\r", 
                    i, 
                    pDesc->getCName());


            fprintf(stderr, "\n");

#if 0
            fprintf(stderr, "0x%016"PRIx64" 0x%016"PRIx64"\n",
                    _pFieldFlags->_bClusterLocalFlags,
                    pDesc      ->getFieldMask());
#endif
        }
        else
        {
            fprintf(stderr, "(%d) : NULL\n", i);
        }
    }
}
Beispiel #2
0
Int32 OSGLoader::mapExtIntFieldType(const Char8 *szFieldname,
                                    const Int32  iFieldTypeId)
{
    Int32 returnValue = Inherited::mapExtIntFieldType(szFieldname,
                                                      iFieldTypeId);

    if(returnValue < 0 && szFieldname != NULL && _pCurrentFC != NULL)
    {
        FieldDescriptionBase *pFieldDesc = 
            _pCurrentFC->getFieldDescription(szFieldname);

        if(pFieldDesc != NULL)
        {
            const FieldType &oFieldType = pFieldDesc->getFieldType();

            PINFO << "FieldTypeId invalid, trying to fix. " << std::endl;
            PINFO << oFieldType.getContentType().getCName()
                  << " comparing with "
                  << FieldTraits<FieldContainer *>::getType().getCName()
                  << std::endl;


            if(oFieldType.getContentType().isDerivedFrom(
                   FieldTraits<FieldContainer *>::getType()) == true)
            {
                PINFO << "FieldContainer * or derived class, "
                      << "parsing as Node"
                      << std::endl;

                if(oFieldType.getCardinality() == FieldType::SingleField)
                {
                    returnValue = ScanParseSkel::OSGsfNode;
                }
                else
                {
                    returnValue = ScanParseSkel::OSGmfNode;
                }
            }
        }
    }

    return returnValue;
}
void FieldContainerType::unmarkFieldsClusterLocal(const BitVector bvFieldMasks)
{
    if(_pPrototype != NULL)
    {
        BitVector bCurrent = 0x0002;

        for(UInt32 i = 1; i <= this->getNumFieldDescs(); ++i)
        {
            FieldDescriptionBase *pDesc = this->getFieldDesc(i);

            if(0x0000 != (bCurrent & bvFieldMasks) && pDesc != NULL)
            {
                pDesc->setFlags(pDesc->getFlags() & ~Field::FClusterLocal);

                _pPrototype->_pFieldFlags->_bClusterLocalFlags |=
                    pDesc->getFieldMask();
            }

            bCurrent <<= 1;
        }
    }
}
Beispiel #4
0
UInt32 OSGLoader::getFieldType(const Char8 *szFieldname)
{
    UInt32                returnValue = 0;
    FieldDescriptionBase *pFieldDesc  = NULL;

    if(szFieldname == NULL)
        return returnValue;

    if(_pCurrentFC != NULL)
    {
        pFieldDesc = _pCurrentFC->getFieldDescription(szFieldname);

        PINFO << "GF : " << szFieldname << " " << pFieldDesc << std::endl;

        if(pFieldDesc != NULL)
        {
            returnValue = pFieldDesc->getFieldType().getScanTypeId();
        }
    }

    return returnValue;
}
/*         one or more fields failed to be exposed to Python.          */
bool PyFieldAccessHandler::exposeAllFieldsToPython()
{
    for(UInt32 idx = 1; idx <= _pPythonScript->getType().getNumFieldDescs(); ++idx)
    {
        FieldDescriptionBase *desc = _pPythonScript->getType().getFieldDesc(idx);
        assert(desc);

#ifdef OSGPY_DEBUG_CODEGENERATION
        std::string tmp = (desc->isDynamic()) ? "dynamic. Analyzing..." : "static. Skip...";
        std::cout << "Processing field '" << desc->getName() << "' | "
                  << tmp << std::endl;
#endif

        if(desc->isDynamic() == true)
        {
            if(exposeFieldToPython(desc->getName(), desc->getFieldId()) == true)
            {
#ifdef OSGPY_DEBUG_CODEGENERATION
                std::cout << "Successfully exposed field '" << desc->getName()
                          << "'" << std::endl << std::endl;
#endif
            }
            else
            {
                std::cerr << "Error exposing field " << desc->getName()
                          << std::endl;

                _pPyInterpreter->activate();
                _pPyInterpreter->dumpError();
                _pPyInterpreter->clearError();
                _pPyInterpreter->deactivate();

                std::cerr << "The field will not be accessible in Python!"
                          << std::endl << std::endl;
            }
        }
    }

    return true;
}
/*!
    Tries to write the image object to the given output stream.
    Returns true on success.
*/
bool EXRImageFileType::write(const Image        *image, 
                                   std::ostream &os, 
                             const std::string  &mimetype)
{
#ifdef OSG_WITH_IMF
    if (!os.good())
        return false;

    if(image->getDataType() != Image::OSG_FLOAT16_IMAGEDATA)
    {
        FWARNING(("EXRImageFileType::write: Image has non float data type!\n"));
        return false;
    }
    if(image->getComponents() != 4)
    {
        FWARNING(("EXRImageFileType::write: Image has != 4 components!\n"));
        return false;
    }
    if (image->getSideCount() == 6)
    {
        FWARNING(("EXRImageFileType::write: NYI for cubemaps\n"));  //TODO
        return false;
    }

    try
    {
        Int32 width  = image->getWidth();
        Int32 height = image->getHeight();

        const char *dummy = "";
        StdOStream file(os, dummy);
        Imf::Header header(width, height);

#if 0
        // now add custom attributes
        ImageGenericAtt *att = dynamic_cast<ImageGenericAtt *>(
            image->findAttachment(
                ImageGenericAtt::getClassType().getGroupId()));

        if(att != NULL)
        {
            FieldContainerType  &fcType = att->getType();
            Int32 count = att->getType().getNumFieldDescs();

            for(Int32 i = 1; i <= count; ++i)
            {
                FieldDescriptionBase *fDesc = fcType.getFieldDesc(i);
                Field                *field = att->getField(i);

                if(fDesc != NULL && field != NULL)
                {
                    SFString *strField = dynamic_cast<SFString*>(field);

                    if(strField != NULL)
                    {
                        Imf::StringAttribute imfAttr(
                            strField->getValue().c_str());

                        header.insert(fDesc->getCName(), imfAttr);
                    }
                }
            }
        }
#endif

        // we write each side as 4 channels out
        // side 0 RGBA
        // side 1 R1G1B1A1
        // ...
        for(Int32 side=0;side<image->getSideCount();++side)
        {
            char cn[20];
            sprintf(cn, "%d", side);

            char name[20];
            sprintf(name, "R%s", side == 0 ? "" : cn);
            header.channels().insert(name, Imf::Channel(Imf::HALF));
            sprintf(name, "G%s", side == 0 ? "" : cn);
            header.channels().insert(name, Imf::Channel(Imf::HALF));
            sprintf(name, "B%s", side == 0 ? "" : cn);
            header.channels().insert(name, Imf::Channel(Imf::HALF));
            sprintf(name, "A%s", side == 0 ? "" : cn);
            header.channels().insert(name, Imf::Channel(Imf::HALF));
        }

        Imf::OutputFile stream(file, header);
        Imf::FrameBuffer frame_buffer;

        // we need to do a vertical flip so we write single scan lines out.
        for(int i=height-1;i>=0;--i)
        {
            for(Int32 side=0;side<image->getSideCount();++side)
            {
                const char *data = (reinterpret_cast<const char *>(image->getData(0, 0, side))) + i * (sizeof(Real16) * 4 * width);

                // writePixels() adds the current scan line index as an offset to the
                // base address we need to eliminate this!
                data -= stream.currentScanLine() * (sizeof(Real16) * 4 * width);

                char cn[20];
                sprintf(cn, "%d", side);
                char name[20];
                sprintf(name, "R%s", side == 0 ? "" : cn);
                frame_buffer.insert(name, Imf::Slice(Imf::HALF, 
                                                     const_cast<char *>(data), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                sprintf(name, "G%s", side == 0 ? "" : cn);
                frame_buffer.insert(name, Imf::Slice(Imf::HALF, 
                                                     const_cast<char *>(data) + 1 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                sprintf(name, "B%s", side == 0 ? "" : cn);
                frame_buffer.insert(name, Imf::Slice(Imf::HALF, 
                                                     const_cast<char *>(data) + 2 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                sprintf(name, "A%s", side == 0 ? "" : cn);
                frame_buffer.insert(name, Imf::Slice(Imf::HALF, 
                                                     const_cast<char *>(data) + 3 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
            }
            stream.setFrameBuffer(frame_buffer);
            stream.writePixels(1);
        }

        return true;
    }
    catch(std::exception &e)
    {
        FFATAL(( "Error while trying to write OpenEXR Image from stream: %s\n",
                  e.what() ));
        return false;
    }

#else
    SWARNING << getMimeType()
             << " write is not compiled into the current binary "
             << std::endl;
    return false;
#endif
}
/*-------------------------------------------------------------------------*\
 -  private                                                                 -
\*-------------------------------------------------------------------------*/
void GenericFieldContainerEditor::updateFieldsPanel(FieldContainer* fc)
{
    _FieldsContainer->clearChildren();

    UInt32 NumFields(fc->getType().getNumFieldDescs());
    FieldDescriptionBase* Desc;
    FieldEditorComponentUnrecPtr TheEditor;
    LabelUnrecPtr TheLabel;
    ComponentRecPtr TheToolTip;
    GridBagLayoutConstraintsRefPtr LayoutConstraints;
    PanelRefPtr FieldPanel;
    UInt32 NumRows(0),NumRowsForField(1);

    BorderLayoutRefPtr TheBorderLayout = BorderLayout::create();
    BorderLayoutConstraintsRefPtr WestConstraint = BorderLayoutConstraints::create();
    WestConstraint->setRegion(BorderLayoutConstraints::BORDER_WEST);
    BorderLayoutConstraintsRefPtr CenterConstraint = BorderLayoutConstraints::create();
    CenterConstraint->setRegion(BorderLayoutConstraints::BORDER_CENTER);

    //Backgrounds
    ColorLayerRefPtr HeaderBgLayer = ColorLayer::create();
    HeaderBgLayer->setColor(Color4f(0.7f,0.7f,0.7f,1.0f));

    ColorLayerRefPtr LightBgLayer = ColorLayer::create();
    LightBgLayer->setColor(Color4f(0.9f,0.9f,0.9f,1.0f));
    ColorLayerRefPtr DarkBgLayer = ColorLayer::create();
    DarkBgLayer->setColor(Color4f(0.8f,0.8f,0.8f,1.0f));

    LayoutConstraints = GridBagLayoutConstraints::create();
    LayoutConstraints->setGridX(0);
    LayoutConstraints->setGridY(NumRows);
    LayoutConstraints->setGridHeight(1);
    LayoutConstraints->setGridWidth(2);
    LayoutConstraints->setFill(GridBagLayoutConstraints::FILL_BOTH);

    LabelRecPtr FieldsLabel = Label::create();
    FieldsLabel->setAlignment(Vec2f(0.5f,0.5f));
    FieldsLabel->setText("Fields");
    FieldsLabel->setBackgrounds(HeaderBgLayer);
    FieldsLabel->setConstraints(LayoutConstraints);
    FieldsLabel->setFont(_BoldFont);

    _FieldsContainer->pushToChildren(FieldsLabel);
    ++NumRows;

    if(_GenericNameAttachmentEditor->isTypeEditable(fc->getType()))
    {
        //Create the Label
        TheLabel = Label::create();
        TheLabel->setText("Name");
        TheLabel->setBackgrounds(NULL);
        TheLabel->setConstraints(WestConstraint);
        TheLabel->setPreferredSize(Vec2f(160.0f,22.0f));

        //Attach the Generic Name Editor
        _GenericNameAttachmentEditor->setCommandManager(_CmdManager);
        _GenericNameAttachmentEditor->attachContainer(fc);
        _GenericNameAttachmentEditor->setConstraints(CenterConstraint);

        //Create the Panel
        LayoutConstraints = GridBagLayoutConstraints::create();
        LayoutConstraints->setGridX(0);
        LayoutConstraints->setGridY(NumRows);
        LayoutConstraints->setGridHeight(1);
        LayoutConstraints->setGridWidth(1);
        LayoutConstraints->setFill(GridBagLayoutConstraints::FILL_BOTH);

        FieldPanel = Panel::createEmpty();
        FieldPanel->setInset(Vec4f(1.0f,1.0f,1.0f,1.0f));
        FieldPanel->pushToChildren(TheLabel);
        FieldPanel->pushToChildren(_GenericNameAttachmentEditor);
        FieldPanel->setLayout(TheBorderLayout);
        FieldPanel->setConstraints(LayoutConstraints);
        FieldPanel->setBackgrounds(LightBgLayer);

        _FieldsContainer->pushToChildren(FieldPanel);
        ++NumRows;
    }

    UInt32 UsedFieldCount(0);
    for(UInt32 i(1) ; i<=NumFields ; ++i)
    {
        Desc = fc->getFieldDescription(i);
        if(Desc != NULL &&
           !Desc->isInternal() &&
           Desc->getFieldType().getClass() != FieldType::ParentPtrField &&
           //HACK: Stop the pixel field from being editable on Images
           !(fc->getType().isDerivedFrom(Image::getClassType()) &&
             Desc->getFieldId() == Image::PixelFieldId))
        {
            //Create the Editor
            TheEditor = FieldEditorFactory::the()->createDefaultEditor(fc, Desc->getFieldId(), _CmdManager);
            if(TheEditor != NULL)
            {
                NumRowsForField = TheEditor->getNumRequestedRows();
                pushToEditors(TheEditor);
                TheEditor->setConstraints(CenterConstraint);

                //Create the Label
                TheLabel = Label::create();
                TheLabel->setText(Desc->getCName());
                TheLabel->setBackgrounds(NULL);
                TheLabel->setConstraints(WestConstraint);
                TheLabel->setPreferredSize(Vec2f(160.0f,22.0f));
                TheToolTip = createFieldToolTip(Desc);
                TheLabel->setToolTip(TheToolTip);

                //Create the Panel
                LayoutConstraints = GridBagLayoutConstraints::create();
                LayoutConstraints->setGridX(0);
                LayoutConstraints->setGridY(NumRows);
                LayoutConstraints->setGridHeight(NumRowsForField);
                LayoutConstraints->setGridWidth(1);
                LayoutConstraints->setFill(GridBagLayoutConstraints::FILL_BOTH);


                FieldPanel = Panel::createEmpty();
                FieldPanel->setInset(Vec4f(1.0f,1.0f,1.0f,1.0f));
                FieldPanel->pushToChildren(TheLabel);
                FieldPanel->pushToChildren(TheEditor);
                FieldPanel->setLayout(TheBorderLayout);
                FieldPanel->setConstraints(LayoutConstraints);
                if((UsedFieldCount%2) == 0)
                {
                    FieldPanel->setBackgrounds(DarkBgLayer);
                }
                else
                {
                    FieldPanel->setBackgrounds(LightBgLayer);
                }

                _FieldsContainer->pushToChildren(FieldPanel);
                NumRows += NumRowsForField;
                TheEditor->setPreferredSize(Vec2f(50.0f,22.0f * NumRowsForField));
                ++UsedFieldCount;
            }
        }
    }

    //Set the number of rows for the grid layout
    dynamic_cast<GridBagLayout*>(_FieldsContainer->getLayout())->setRows(NumRows);
    _FieldsContainer->setPreferredSize(Vec2f(400.0f, NumRows*24.0f));
}
void
OSBGeometryElement::postReadV100(void)
{
    OSG_OSB_LOG(("OSBGeometryElement::postReadV100\n"));

    OSBRootElement  *root             = editRoot();
    Geometry        *geo              =
        dynamic_cast<Geometry*>(getContainer());
    UInt32           indexMappingSize = UInt32(_indexMapping.size());

    if(indexMappingSize <= 1)
    {
        OSG_OSB_LOG(("OSBGeometryElement::postReadV100: "
                "Converting single index.\n"          ));

        if(_indicesPacked)
        {
            OSG_OSB_LOG(("OSBGeometryElement::postReadV100: "
                    "Converting packed indices.\n"        ));
            geo->setIndices(_indices);
        }
        else
        {
            OSG_OSB_LOG(("OSBGeometryElement::postReadV100: "
                    "Converting non-packed indices.\n"    ));

            // indices stored in container with id _indicesId
            // create PtrFieldInfo structure to set all entries of field
            // "propIndices" to the container with id _indicesId

            FieldDescriptionBase *indFieldDesc =
                geo->getFieldDescription("propIndices");
            UInt32                indFieldId   = indFieldDesc->getFieldId();

            root->editPtrFieldList().push_back(PtrFieldInfo(geo, indFieldId));
            PtrFieldInfo &indFieldPFI = root->editPtrFieldList().back();

            for(UInt32 i = 0; i < Geometry::MaxAttribs; ++i)
            {
                indFieldPFI.editIdStore().push_back(_indicesId);
            }
        }
    }
    else
    {
        OSG_OSB_LOG(("OSBGeometryElement::postReadV100: "
                "Converting multi index.\n"          ));

        OSBGeometryHelper gh;

        if(_indicesPacked)
        {
            OSG_OSB_LOG(("OSBGeometryElement::postReadV100: "
                    "Converting packed indices.\n"        ));

            // create 16 bit or 32 bit indices
            if(_indices16Bit)
            {
                GeoUInt16Property *ui16Indices =
                    dynamic_pointer_cast<GeoUInt16Property>(_indices);

                gh.splitMultiIndex<GeoUInt16Property *>(
                    _indexMapping, ui16Indices, geo);
            }
            else
            {
                GeoUInt32Property *ui32Indices =
                    dynamic_pointer_cast<GeoUInt32Property>(_indices);

                gh.splitMultiIndex<GeoUInt32Property *>(
                    _indexMapping, ui32Indices, geo);
            }
        }
        else
        {
            OSG_OSB_LOG(("OSBGeometryElement::postReadV100: "
                         "Converting non-packed indices.\n"    ));

            FieldContainerIdMapConstIt mapIt =
                root->getIdMap().find(_indicesId);

            if(mapIt != root->getIdMap().end())
            {
                _indices = dynamic_cast<GeoIntegralProperty *>(
                    FieldContainerFactory::the()->getContainer(mapIt->second));
            }
            else
            {
                FWARNING(("OSBGeometryElement::postReadV100: "
                          "Could not find indices property.\n"));
                return;
            }

            if(_indices->getFormatSize() == sizeof(UInt16))
            {
                GeoUInt16Property *ui16Indices =
                    dynamic_pointer_cast<GeoUInt16Property>(_indices);

                gh.splitMultiIndex<GeoUInt16Property *>(
                    _indexMapping, ui16Indices, geo);
            }
            else if(_indices->getFormatSize() == sizeof(UInt32))
            {
                GeoUInt32Property *ui32Indices =
                    dynamic_pointer_cast<GeoUInt32Property>(_indices);

                gh.splitMultiIndex<GeoUInt32Property *>(
                    _indexMapping, ui32Indices, geo);
            }
        }
    }
}
void
OSBGeometryElement::readV100(void)
{
    OSG_OSB_LOG(("OSBGeometryElement::readV100:\n"));

    OSBRootElement    *root = editRoot();
    BinaryReadHandler *rh   = editRoot()->getReadHandler();
    OSBGeometryHelper  gh;

    GeometryUnrecPtr geo = Geometry::create();
    setContainer(geo);

    // The "properties" mfield can be thought of the unification of the
    // "positions", "normals", etc sfields of the 1.x Geometry.
    // For the conversion the PtrFieldInfo structure for the "properties"
    // mfield is filled with the corresponding ids of the sfields from the
    // file. The remapping after postRead will fill in the right pointers.

    FieldDescriptionBase *propFieldDesc =
        geo->getFieldDescription("properties");
    UInt32                propFieldId   = propFieldDesc->getFieldId();

    root->editPtrFieldList().push_back(PtrFieldInfo(geo, propFieldId));
    PtrFieldInfo &propFieldPFI = root->editPtrFieldList().back();

    propFieldPFI.editIdStore().resize(Geometry::MaxAttribs);

    while(true)
    {
        std::string    fieldName;
        std::string    fieldTypeName;
        UInt32         fieldSize;
        PtrFieldListIt ptrFieldIt;

        if(!readFieldHeader("", fieldName, fieldTypeName, fieldSize))
        {
            OSG_OSB_LOG(("OSBGeometryElement::readV100: "
                    "Reading stopped at field: [%s].\n", fieldName.c_str()));
            break;
        }

        if(fieldName == "indexMapping")
        {
            // read into temporary field
            MField<UInt16> indexMappingField;
            indexMappingField.copyFromBin(*rh);

            // copy to member for use in postRead
            indexMappingField.getValues().swap(_indexMapping);
        }
        else if(fieldName == "indices")
        {
            // read container id of indices property
            // postRead will handle the conversion of multi indices
            rh->getValue(_indicesId);
        }
        else if(fieldName == "positions")
        {
            UInt32 positionsId;
            rh->getValue(positionsId);
            propFieldPFI.editIdStore()[Geometry::PositionsIndex] = positionsId;
        }
        else if(fieldName == "normals")
        {
            UInt32 normalsId;
            rh->getValue(normalsId);
            propFieldPFI.editIdStore()[Geometry::NormalsIndex] = normalsId;
        }
        else if(fieldName == "colors")
        {
            UInt32 colorsId;
            rh->getValue(colorsId);
            propFieldPFI.editIdStore()[Geometry::ColorsIndex] = colorsId;
        }
        else if(fieldName == "secondaryColors")
        {
            UInt32 secondaryColorsId;
            rh->getValue(secondaryColorsId);
            propFieldPFI.editIdStore()[Geometry::SecondaryColorsIndex] =
                secondaryColorsId;
        }
        else if(fieldName == "texCoords")
        {
            UInt32 texCoordsId;
            rh->getValue(texCoordsId);
            propFieldPFI.editIdStore()[Geometry::TexCoordsIndex] =
                texCoordsId;
        }
        else if(fieldName == "texCoords1")
        {
            UInt32 texCoordsId1;
            rh->getValue(texCoordsId1);
            propFieldPFI.editIdStore()[Geometry::TexCoords1Index] =
                texCoordsId1;
        }
        else if(fieldName == "texCoords2")
        {
            UInt32 texCoordsId2;
            rh->getValue(texCoordsId2);
            propFieldPFI.editIdStore()[Geometry::TexCoords2Index] =
                texCoordsId2;
        }
        else if(fieldName == "texCoords3")
        {
            UInt32 texCoordsId3;
            rh->getValue(texCoordsId3);
            propFieldPFI.editIdStore()[Geometry::TexCoords3Index] =
                texCoordsId3;
        }
        else if(fieldName == "texCoords4")
        {
            UInt32 texCoordsId4;
            rh->getValue(texCoordsId4);
            propFieldPFI.editIdStore()[Geometry::TexCoords4Index] =
                texCoordsId4;
        }
        else if(fieldName == "texCoords5")
        {
            UInt32 texCoordsId5;
            rh->getValue(texCoordsId5);
            propFieldPFI.editIdStore()[Geometry::TexCoords5Index] =
                texCoordsId5;
        }
        else if(fieldName == "texCoords6")
        {
            UInt32 texCoordsId6;
            rh->getValue(texCoordsId6);
            propFieldPFI.editIdStore()[Geometry::TexCoords6Index] =
                texCoordsId6;
        }
        else if(fieldName == "texCoords7")
        {
            UInt32 texCoordsId7;
            rh->getValue(texCoordsId7);
            propFieldPFI.editIdStore()[Geometry::TexCoords7Index] =
                texCoordsId7;
        }
        else if(fieldName == "pindices")
        {
            UInt32 maxValue;
            UInt32 propSize;
            UInt32 byteSize;

            _indicesPacked = true;

            gh.readPackedIntegralPropertyHeader(rh, maxValue,
                                                propSize, byteSize);

            if(root->getOptions().unpack16BitIndices())
            {
                if(maxValue > TypeTraits<UInt16>::getMax())
                {
                    GeoUInt32PropertyUnrecPtr ui32Indices =
                        GeoUInt32Property::create();
                    gh.readPackedIntegralProperty(rh, ui32Indices, maxValue,
                                                  propSize, byteSize        );

                    _indices16Bit = false;
                    _indices      = ui32Indices;
                }
                else
                {
                    GeoUInt16PropertyUnrecPtr ui16Indices =
                        GeoUInt16Property::create();
                    gh.readPackedIntegralProperty(rh, ui16Indices, maxValue,
                                                  propSize, byteSize        );

                    _indices16Bit = true;
                    _indices      = ui16Indices;
                }
            }
            else
            {
                GeoUInt32PropertyUnrecPtr ui32Indices =
                    GeoUInt32Property::create();
                gh.readPackedIntegralProperty(rh, ui32Indices, maxValue,
                                              propSize, byteSize        );

                _indices16Bit = false;
                _indices      = ui32Indices;
            }
        }
        else if(fieldName == "qpositions")
        {
            // Quantized positions are stored inside the geometry object, not
            // in the geo-property. They are always of type Pnt3f.
            GeoPnt3fPropertyUnrecPtr propPos    = GeoPnt3fProperty::create();
            UInt8                    resolution;
            Real32                   minValue;
            Real32                   maxValue;
            UInt32                   propSize;

            gh.readQuantizedVectorPropertyHeader(rh, resolution, minValue,
                                                 maxValue, propSize       );
            gh.readQuantizedVectorProperty(rh, propPos, fieldSize, resolution,
                                           minValue, maxValue, propSize       );

            geo->setProperty(propPos, Geometry::PositionsIndex);
        }
        else if(fieldName == "qnormals")
        {
            // Quantized normals are stored inside the geometry object, not
            // in the geo-property. They are always of type Vec3f.
            GeoVec3fPropertyUnrecPtr propNorm   = GeoVec3fProperty::create();
            UInt8                    resolution;
            Real32                   minValue;
            Real32                   maxValue;
            UInt32                   propSize;

            gh.readQuantizedVectorPropertyHeader(
                rh, resolution, minValue, maxValue, propSize);
            gh.readQuantizedVectorProperty(
                rh, propNorm, fieldSize, resolution,
                minValue, maxValue, propSize        );

            geo->setProperty(propNorm, Geometry::NormalsIndex);
        }
        else if(fieldName == "qtexCoords")
        {
            // Quantized texCoords are stored inside the geometry object, not
            // in the geo-property. They are always of type Vec2f.
            GeoVec2fPropertyUnrecPtr propTexCoords = GeoVec2fProperty::create();
            UInt8                    resolution;
            Real32                   minValue;
            Real32                   maxValue;
            UInt32                   propSize;

            gh.readQuantizedVectorPropertyHeader(
                rh, resolution, minValue, maxValue, propSize);
            gh.readQuantizedVectorProperty(
                rh, propTexCoords, fieldSize, resolution,
                minValue, maxValue, propSize             );

            geo->setProperty(propTexCoords, Geometry::NormalsIndex);
        }
        else
        {
            // 1.x Geometry has _sfVbo, it can be skipped

            readFieldContent(fieldName, fieldTypeName, fieldSize,
                             "'vbo'", ptrFieldIt                      );
        }
    }
}
void FieldAnimation::changed(ConstFieldMaskArg whichField, 
                             UInt32            origin,
                             BitVector         details)
{
    Inherited::changed(whichField, origin, details);

    //Do not respond to changes that have a Sync origin
    if(origin & ChangedOrigin::Sync)
    {
        return;
    }

    if(whichField & FieldNameFieldMask)
    {
        if(getContainer() != NULL)
        {

            FieldDescriptionBase * f = getContainer()->getFieldDescription(getFieldName().c_str());
            if( f == NULL )
            {
                SWARNING << "Could not find Field "<< getFieldName() << " in Field Container " << getContainer()->getTypeName()  << std::endl;
                return;
            }
            else
            {
                setFieldId(f->getFieldId());
                //commitChanges();
            }
        }
        else
        {
            SWARNING << "There is no Field Container defined to Animate"  << std::endl;
            return;
        }
    }
    else if((whichField & FieldIdFieldMask) ||
            (whichField & ContainerFieldMask))
    {
        if(getContainer() != NULL)
        {
            FieldDescriptionBase * f = getContainer()->getFieldDescription(getFieldId());
            if( f == NULL )
            {
                SWARNING << "Could not find Field ID"<< getFieldId() << " in Field Container " << getContainer()->getTypeName()  << std::endl;
                return;
            }
            else
            {
                if(getAnimator()->getDataType() == NULL)
                {
                    SWARNING << "Cannot update animation, because the animator attached to this animation does not work on any data types."  << std::endl;
                    return;
                }
                //Check if it's the right type
                if(getContainer()->getFieldDescription(getFieldId())->getFieldType().getContentType()
                   != *getAnimator()->getDataType())
                {
                    SWARNING << "The data type of the field: "
                             << getContainer()->getFieldDescription(getFieldId())->getName()
                             << " with type: "
                             << getContainer()->getFieldDescription(getFieldId())->getFieldType().getContentType().getCName()
                             << " connected to this animation is not the same data type: "
                             << getAnimator()->getDataType()->getCName()
                             << ", that the animator works on."  << std::endl;
                    return;
                }
            }
        }
        else
        {
            SWARNING << "There is no Field Container defined to Animate"  << std::endl;
            return;
        }
    }
    if(whichField & IndexFieldMask)
    {
        if(getContainer() != NULL)
        {
            FieldDescriptionBase * f = getContainer()->getFieldDescription(getFieldId());
            if( f == NULL )
            {
                SWARNING << "Could not find Field ID"<< getFieldId() << " in Field Container " << getContainer()->getTypeName()  << std::endl;
            }
            else
            {

                //Check if animator supports any types
                if(getAnimator()->getDataType() == NULL)
                {
                    SWARNING << "Cannot update animation, because the animator attached to this animation does not work on any data types."  << std::endl;
                }
                //Check if it's the right type
                if(getContainer()->getFieldDescription(getFieldId())->getFieldType().getContentType()
                   != *getAnimator()->getDataType())
                {
                    SWARNING << "The data type of the field: "
                             << getContainer()->getFieldDescription(getFieldId())->getName()
                             << " with type: "
                             << getContainer()->getFieldDescription(getFieldId())->getFieldType().getContentType().getCName()
                             << " connected to this animation is not the same data type: "
                             << getAnimator()->getDataType()->getCName()
                             << ", that the animator works on."  << std::endl;
                }
                GetFieldHandlePtr TheFieldHandle = getContainer()->getField( getFieldId() );

                if( getIndex() > 0 )
                {
                    if(TheFieldHandle->getCardinality() != FieldType::MultiField)
                    {
                        SWARNING << "Cannot attach to index: " << getIndex() 
                                 << " of field " << getContainer()->getFieldDescription(getFieldId())->getName() 
                                 << " because it has cardinality 1." << std::endl;
                    }
                    else if(getIndex() < TheFieldHandle->size())
                    {
                        SWARNING << "Cannot attach to index: " << getIndex() 
                                 << " of field " << getContainer()->getFieldDescription(getFieldId())->getName() 
                                 << " because that index is out of bounds on a field of size " << TheFieldHandle->size() << "." << std::endl;
                    }
                }
            }
        }
        else
        {
            SWARNING << "There is no Field Container defined to Animate"  << std::endl;
        }
    }
}
Action::ResultE
bindEnterDefault(NodeCore *core, Action *action)
{
    AnimBindAction     *bindAct  = dynamic_cast<AnimBindAction *>(action);
    Animation          *anim     = bindAct->getAnim    ();
    const AnimTemplate *animTmpl = bindAct->getTemplate();

    AnimTargetAttachment *targetAtt = getTargetAtt(core);

    FDEBUG(("bindEnterDefault: core [%p] targetAtt [%p]\n",
            core, targetAtt));

    if(targetAtt == NULL)
        return Action::Continue;

    Int32 srcIdx = 0;

    while((srcIdx = animTmpl->findTargetId(targetAtt->getTargetId(),
                                           srcIdx                   )) != -1)
    {
        std::string targetId;
        std::string subTargetId;

        bindAct->splitTargetId(
            animTmpl->getTargetIds(srcIdx), targetId, subTargetId);

        FDEBUG(("bindEnterDefault: targetId [%s] subTargetId [%s]\n",
                targetId.c_str(), subTargetId.c_str()));

        // create the channel

        AnimDataSource      *src     = animTmpl->getSources   (srcIdx);
        AnimChannelUnrecPtr  channel = src     ->createChannel(      );
        anim->editMFChannels()->push_back(channel);

        FieldDescriptionBase *fDesc =
            core->getType().getFieldDesc(subTargetId.c_str());

        if(fDesc == NULL)
        {
            SWARNING << "bindEnterDefault: no field for subTargetId ["
                     << subTargetId << "] found." << std::endl;
            continue;
        }

        // create the blender

        UInt32              fId     = fDesc->getFieldId();
        
        if(targetAtt->getMFBlenders()->size() <= fId)
            targetAtt->editMFBlenders()->resize(fId + 1, NULL);

        AnimBlenderUnrecPtr blender = targetAtt->getBlenders(fId);

        if(blender == NULL)
        {
            blender = src->createBlender();
            (*targetAtt->editMFBlenders())[fId] = blender;
        }

        // connect

        blender->addChannel(channel               );
        blender->connectTo (core, fDesc->getName());

        ++srcIdx;
    }

    return Action::Continue;
}
Action::ResultE
AnimBindAction::bindFields(AttachmentContainer *attCon)
{
    AnimTargetAttachment *targetAtt = getTargetAtt(attCon);

    if(targetAtt == NULL)
        return Action::Continue;

    Animation       *anim  = getAnim();
    DataSourceMapIt  dsIt  = _dsMap.begin();
    DataSourceMapIt  dsEnd = _dsMap.end  ();

    while(dsIt != dsEnd)
    {
        if(dsIt->first.find(targetAtt->getTargetId()) != 0)
        {
            ++dsIt;
            continue;
        }

        std::string targetId;
        std::string subTargetId;

        splitTargetId(dsIt->first, targetId, subTargetId);

        if(targetId != targetAtt->getTargetId())
        {
            ++dsIt;
            continue;
        }

        SINFO << "AnimBindAction::bindFields: binding source '"
              << dsIt->first << "' to '" << targetId << "' - '"
              << subTargetId << "'" << std::endl;

        FieldDescriptionBase *fDesc =
            attCon->getType().getFieldDesc(subTargetId.c_str());

        if(fDesc == NULL)
        {
            SWARNING << "AnimBindAction::bindFields: no Field for "
                     << "subTargetId [" << subTargetId << "] found."
                     << std::endl;
            ++dsIt;
            continue;
        }

        // create channel
        AnimChannelUnrecPtr channel = dsIt->second->createChannel();
        anim->editMFChannels()->push_back(channel);

         // create blender
        UInt32 fId = fDesc->getFieldId();

        if(targetAtt->getMFBlenders()->size() <= fId)
            targetAtt->editMFBlenders()->resize(fId + 1, NULL);

        AnimBlenderUnrecPtr blender = targetAtt->getBlenders(fId);

        if(blender == NULL)
        {
            blender = dsIt->second->createBlender();
            targetAtt->editMFBlenders()->replace(fId, blender);
        }

        // on create all fields are marked as changed - this causes
        // the blender to write to its destination even though
        // it has no valid input data - avoid it by committing before
        // connecting the blender to its dest
        commitChanges();

        blender->addChannel(channel                 );
        blender->connectTo (attCon, fDesc->getName());

        // remove bound data source from map
        DataSourceMapIt eraseIt = dsIt;
        ++dsIt;
        _dsMap.erase(eraseIt);
    }

    if(_dsMap.empty() == true)
    {
        return Action::Quit;
    }
    else
    {
        return Action::Continue;
    }
}
/*! Reads the contents of a field from the stream. It is intended to be used
    in conjunction with readFieldHeader and uses the information obtained
    by it (\a fieldName, \a fieldTypeName, \a fieldSize ).

    If a field is not to be read, but skipped instead, its name can be passed
    in the \a excludeFields argument. The string has the format:
    "'name1' 'name2' 'name3'", the spaces between the "'" are mandatory.

    \param[in] fieldName Name of the field.
    \param[in] fieldTypeName Type of the field.
    \param[in] fieldSize Size in bytes of the field.
    \param[in] excludeFields
    \param[out] ptrFieldIt Iterator that points to the PtrFieldInfo structure
    that was created, if this is a "pointer field" - only valid if true is
    returned.

    \return True, if the field is a "pointer field", i.e. a field holding
    pointers to other FieldContainers, false otherwise.
 */
bool
OSBCommonElement::readFieldContent(
    const std::string    &fieldName,
    const std::string    &fieldTypeName,
    const UInt32          fieldSize,
    const std::string    &excludeFields,
          PtrFieldListIt &ptrFieldIt    )
{
    OSG_OSB_LOG(("OSBCommonElement::readFieldContent: [%s] [%s] [%u]\n",
            fieldName.c_str(), fieldTypeName.c_str(), fieldSize));

    BinaryReadHandler    *rh         = editRoot()->getReadHandler();
    bool                  isPtrField = false;
    FieldDescriptionBase *fieldDesc  =
        getContainer()->getFieldDescription(fieldName.c_str());

    if((!excludeFields.empty()                                        ) &&
       (excludeFields.find("'" + fieldName + "'") != std::string::npos)   )
    {
        OSG_OSB_LOG(("OSBCommonElement::readFieldContent: "
                "Skipping excluded field [%s] [%s]\n",
                fieldName.c_str(), fieldTypeName.c_str()));

        rh->skip(fieldSize);
        return false;
    }

    if(fieldDesc == 0)
    {
        DynFieldContainerInterface *pIf = 
            dynamic_cast<DynFieldContainerInterface *>(getContainer());

        if(pIf != NULL)
        {
            pIf->addField(fieldTypeName.c_str(), fieldName.c_str());

            fieldDesc = getContainer()->getFieldDescription(fieldName.c_str());
        }
    }

    if(fieldDesc == 0)
    {
        FWARNING(("OSBCommonElement::readFieldContent: "
                  "Skipping unknown field [%s] [%s].\n",
                  fieldName.c_str(), fieldTypeName.c_str()));

        rh->skip(fieldSize);
        return false;
    }

    const FieldType &fieldType  = fieldDesc->getFieldType();
    UInt32           fieldId    = fieldDesc->getFieldId  ();
    BitVector        fieldMask  = fieldDesc->getFieldMask();

    if(fieldType.getContentType().isDerivedFrom(
        FieldTraits<FieldContainer *>::getMapType()) == true)
    {
        ptrFieldIt = readAttachmentMapField(fieldId, fieldSize);
        isPtrField = true;
    }
    else if(fieldType.getContentType().isDerivedFrom(
        FieldTraits<FieldContainer *>::getType()) == true)
    {
        if(fieldType.getClass() == FieldType::ParentPtrField)
        {
            rh->skip(fieldSize);
            isPtrField = false;
        }
        else
        {
            if(fieldType.getCardinality() == FieldType::SingleField)
            {
                ptrFieldIt = readPtrSingleField(fieldId);
                isPtrField = true;
            }
            else if(fieldType.getCardinality() == FieldType::MultiField)
            {
                ptrFieldIt = readPtrMultiField(fieldId, fieldSize);
                isPtrField = true;
            }
        }
    }
    else
    {
        getContainer()->copyFromBin(*rh, fieldMask);
        isPtrField = false;
    }

    return isPtrField;
}
bool FieldContainerType::setPrototype(FieldContainer *pPrototype)
{
    bool returnValue = false;

    if(this->isAbstract() == false)
    {
        if(pPrototype != NULL)
        {
            TypePredicates::IsBaseOf baseTypePred(pPrototype->getType());

            if(baseTypePred(this) == true)
            {
                pPrototype->addReferenceUnrecorded();
            
                _pPrototype->subReferenceUnrecorded();

                _pPrototype = pPrototype;

                BitVector bCurrent = 0x0002;

                for(UInt32 i = 1; i <= this->getNumFieldDescs(); ++i)
                {
                    FieldDescriptionBase *pDesc = this->getFieldDesc(i);

                    if(pDesc == NULL)
                        continue;

                    if(0x0000 == (bCurrent & 
                                _pPrototype->_pFieldFlags->_bThreadLocalFlags))
                    {
                        pDesc->setFlags(pDesc->getFlags()  | 
                                        Field::FThreadLocal);
                    }
                    else
                    {
                        pDesc->setFlags(pDesc->getFlags()   & 
                                        ~Field::FThreadLocal);
                    }

                    if(0x0000 == (bCurrent & 
                                _pPrototype->_pFieldFlags->_bClusterLocalFlags))
                    {
                        pDesc->setFlags(pDesc->getFlags()   | 
                                        Field::FClusterLocal);
                    }
                    else
                    {
                        pDesc->setFlags(pDesc->getFlags()    & 
                                        ~Field::FClusterLocal);
                    }

                    bCurrent <<= 1;
                }

                returnValue = true;
            }
            else
            {
                FWARNING(("can not set unrelated container of type %s "
                          "as prototype for type %s\n",
                          pPrototype->getType().getCName(),
                          this->getCName()));
            }
        }
        else
        {
            FWARNING(("can not delete prototype of a concrete object\n"));
        }
    }
    else
    {
        FWARNING(("can not set prototype of an abstract object\n"));
    }

    return returnValue;
}
/*\return true if no Python error was set, false otherwise             */
bool PyFieldAccessHandler::generateCorePythonCode(const std::string& fieldName,
                                                  bool& getAccess,
                                                  bool& editAccess,
                                                  bool& setAccess)
{
    FieldDescriptionBase *desc =
            _pPythonScript->getType().getFieldDesc(fieldName.c_str());
    FieldType::Class classType = desc->getFieldType().getClass();
    std::string fieldTypeName(desc->getFieldType().getName());
    std::string valueTypeName(fieldTypeName);

    removeFieldQualifier   (valueTypeName);
    removeRefCountQualifier(valueTypeName);

    std::string setAccessMethod ("unsupported");
    std::string editAccessMethod("unsupported");
    std::string getAccessMethod ("unsupported");

    switch(classType)
    {
    case FieldType::ValueField:
    {
        if(desc->isSField())
        {
            setAccessMethod  = "setValueSField_"    + valueTypeName;
            getAccessMethod  = "getValueSField_"    + valueTypeName;

            // The following types cannot be changed using the
            // editAccessMethod, as Python does not provide access via a
            // reference for them. They have to be set with the
            // setAccessMethod.
            if(valueTypeName != "Bool"   &&
               valueTypeName != "Int32"  &&
               valueTypeName != "Int64"  &&
               valueTypeName != "UInt32" &&
               valueTypeName != "UInt64" &&
               valueTypeName != "Real32" &&
               valueTypeName != "Real64" &&
               valueTypeName != "Time"   &&
               valueTypeName != "String"   )
            {
                editAccessMethod = "changeValueSField_" + valueTypeName;
            }

#ifdef OSGPY_DEBUG_CODEGENERATION
            std::cout << "    VALUE single-field" << std::endl;
#endif
        }
        else
        {
            setAccessMethod  = "setValueMField_"    + valueTypeName;
            editAccessMethod = "changeValueMField_" + valueTypeName;
            getAccessMethod  = "getValueMField_"    + valueTypeName;

#ifdef OSGPY_DEBUG_CODEGENERATION
            std::cout << "    VALUE multi-field" << std::endl;
#endif
        }
    }
    break;
    case FieldType::PtrField:
    {
        if(desc->isSField())
        {
            setAccessMethod  = "setPtrSField";
            editAccessMethod = "changePtrSField";
            getAccessMethod  = "getPtrSField";
#ifdef OSGPY_DEBUG_CODEGENERATION
            std::cout << "    pointer single-field" << std::endl;
#endif
        }
        else
        {
            setAccessMethod  = "unsupported";
            editAccessMethod = "changePointerMField";
            getAccessMethod  = "getPointerMField";
#ifdef OSGPY_DEBUG_CODEGENERATION
            std::cout << "    pointer multi-field" << std::endl;
#endif
        }
    }
    break;
    default:
    {
        std::string tmp("unknown");
        if(classType == FieldType::ChildPtrField)
        {
            tmp = "ChildPtrField";
        }
        else if (classType == FieldType::ParentPtrField)
        {
            tmp = "ParentPtrField";
        }

        if(desc->isSField())
        {
            std::cerr << "    UNSUPPORTED single-field type: " << tmp << std::endl;
        }
        else
        {
            std::cerr << "    UNSUPPORTED multi-field type: "  << tmp << std::endl;

        }

        assert(false);
    }
    }

    std::string pyCode;

    if(setAccessMethod != "unsupported")
    {
        setAccess = true;

        const std::string setMethod = "def _set_" + fieldName + "(self, value):\n"
                "   _fieldAccessHandler." + setAccessMethod + "('" + fieldName + "', value)\n";
        pyCode += setMethod;

#ifdef OSGPY_DEBUG_CODEGENERATION
        std::cout << "    'set'  support: yes" << std::endl;
#endif
    }
#ifdef OSGPY_DEBUG_CODEGENERATION
    else
    {
        std::cout << "    'set'  support: no" << std::endl;
    }
#endif
    if(editAccessMethod != "unsupported")
    {
        editAccess = true;

        const std::string editMethod = "def _edit_" + fieldName + "(self):\n"
                "   return _fieldAccessHandler." + editAccessMethod + "('" + fieldName + "')\n";
        pyCode += editMethod;
#ifdef OSGPY_DEBUG_CODEGENERATION
        std::cout << "    'edit' support: yes" << std::endl;
#endif
    }
#ifdef OSGPY_DEBUG_CODEGENERATION
    else
    {
        std::cout << "    'edit' support: no" << std::endl;
    }
#endif
    if(getAccessMethod != "unsupported")
    {
        getAccess = true;

        const std::string getMethod = "def _get_" + fieldName + "(self):\n"
                "   return _fieldAccessHandler." + getAccessMethod + "('" + fieldName + "')\n";
        pyCode += getMethod;
#ifdef OSGPY_DEBUG_CODEGENERATION
        std::cout << "    'get'  support: yes" << std::endl;
#endif
    }
#ifdef OSGPY_DEBUG_CODEGENERATION
    else
    {
        std::cout << "    'get'  support: no" << std::endl;
    }


    std::cout << std::endl << "Generated Python glue code:" << std::endl;
    std::cout << pyCode << std::endl;
#endif

    return(_pPyInterpreter->run(pyCode));
}
void FieldAnimation::changed(ConstFieldMaskArg whichField,
                             UInt32            origin,
                             BitVector         details)
{
    Inherited::changed(whichField, origin, details);

    if(whichField & FieldNameFieldMask)
    {
        if(getContainer() != NULL)
        {

            FieldDescriptionBase * f = getContainer()->getFieldDescription(getFieldName().c_str());
            if( f == NULL )
            {
                SWARNING << "Could not find Field "<< getFieldName() << " in Field Container " << getContainer()->getTypeName()  << std::endl;
                return;
            }
            else
            {
                setFieldId(f->getFieldId());
                commitChanges();
            }
        }
        else
        {
            SWARNING << "There is no Field Container defined to Animate"  << std::endl;
            return;
        }
    }
    else if((whichField & FieldIdFieldMask) ||
            (whichField & ContainerFieldMask))
    {
        if(getContainer() != NULL)
        {
            FieldDescriptionBase * f = getContainer()->getFieldDescription(getFieldId());
            if( f == NULL )
            {
                SWARNING << "Could not find Field ID"<< getFieldId() << " in Field Container " << getContainer()->getTypeName()  << std::endl;
                return;
            }
            else
            {
                //Check if it's the right type
                if(getContainer()->getFieldDescription(getFieldId())->getFieldType().getContentType() != getAnimator()->getDataType())
                {
                    SWARNING << "The data type of the field: " << getContainer()->getFieldDescription(getFieldId())->getName() << " with type: "  << getContainer()->getFieldDescription(getFieldId())->getFieldType().getContentType().getCName() << " connected to this animation is not the same data type: " << getAnimator()->getDataType().getCName() << ", that the animator works on."  << std::endl;
                    return;
                }
            }
        }
        else
        {
            SWARNING << "There is no Field Container defined to Animate"  << std::endl;
            return;
        }
    }
    if(whichField & IndexFieldMask)
    {
        if(getContainer() != NULL)
        {
            FieldDescriptionBase * f = getContainer()->getFieldDescription(getFieldId());
            if( f == NULL )
            {
                SWARNING << "Could not find Field ID"<< getFieldId() << " in Field Container " << getContainer()->getTypeName()  << std::endl;
                return;
            }
            else
            {

                //Check if it's the right type
                if(getContainer()->getFieldDescription(getFieldId())->getFieldType().getContentType() != getAnimator()->getDataType())
                {
                    SWARNING << "The data type of the field: " << getContainer()->getFieldDescription(getFieldId())->getName() << " with type: "  << getContainer()->getFieldDescription(getFieldId())->getFieldType().getContentType().getCName() << " connected to this animation is not the same data type: " << getAnimator()->getDataType().getCName() << ", that the animator works on."  << std::endl;
                    return;
                }
                const Field* TheField = getContainer()->getField( getFieldId() )->getField();

                if( getIndex() >= 0 &&
                        TheField->getCardinality() != FieldType::MultiField &&
                        getIndex() < TheField->getSize())
                {
                    SWARNING << "If the Index for the field animation is > 0 then the animated field must be a multi field and the index must be less than the size of this field." << getAnimator()->getDataType().getCName() << "."  << std::endl;
                    return;
                }
                else if( getIndex() < 0 &&
                         TheField->getCardinality() != FieldType::SingleField)
                {
                    SWARNING << "If the Index for the field animation is < 0 then the animated field must be a single field." << getAnimator()->getDataType().getCName()  << std::endl;
                }
            }
        }
        else
        {
            SWARNING << "There is no Field Container defined to Animate"  << std::endl;
            return;
        }
    }
}