/*! Visits a SFFieldContainerPtr (or more specific pointer type) during
    preWrite. It creates an element for the pointed to container and
    calls preWrite on it. If the pointed to container is not in the
    root's id set it is added and thus scheduled for writing.

    \param[in] fieldId Id of the field in the container of this element.
 */
void
OSBCommonElement::preWritePtrSingleField(const UInt32 fieldId)
{
    OSG_OSB_LOG(("OSBCommonElement::preWritePtrSingleField: "
            "fieldId: [%u]\n", fieldId));

    OSBRootElement     *root       = editRoot();

    FieldContainerPtrSFieldBase::GetHandlePtr sfPtrField =
        boost::dynamic_pointer_cast<FieldContainerPtrSFieldBase::GetHandle>(
            getContainer()->getField(fieldId));

    if(sfPtrField == NULL || sfPtrField->isValid() == false)
        return;

    FieldContainer *refedFC = (*sfPtrField)->getValue();

    if(refedFC == NULL)
        return;

    UInt32             refedId  = refedFC->getId  ();
    const std::string &typeName = refedFC->getType().getName();

    // only schedule a container once
    if(root->getIdSet().count(refedId) == 0)
    {
        OSBElementBase *elem = OSBElementFactory::the()->acquire(
            typeName, root);

        root->editIdSet      ().insert   (refedId);
        root->editElementList().push_back(elem   );
        elem->setContainer(refedFC);
        elem->preWrite    (refedFC);
    }
}
/*! Callback called for each element in an AttachmentMap (this is used by
    preWriteAttachmentMapField).
 */
void OSBCommonElement::handleAttachmentMapElementPreWrite(
    FieldContainer *refedFC)
{
    OSG_OSB_LOG(("OSBCommonElement::handleAttachmentMapElementPreWrite\n"));

    if(refedFC == NULL)
        return;

    Attachment *refedAtt = dynamic_cast<Attachment *>(refedFC);

    // skip attachments marked as 'internal'
    if(refedAtt                              == NULL ||
       refedAtt->getSFInternal()->getValue() == true   )
    {
        return;
    }

    OSBRootElement    *root     = editRoot();
    UInt32             refedId  = refedAtt->getId  ();
    const std::string &typeName = refedAtt->getType().getName();

    // only schedule a container once
    if(root->getIdSet().count(refedId) > 0)
        return;

    OSBElementBase *elem = OSBElementFactory::the()->acquire(typeName, root);

    root->editIdSet      ().insert   (refedId);
    root->editElementList().push_back(elem   );
    elem->setContainer(refedAtt);
    elem->preWrite    (refedAtt);
}
/*! Collects all containers that are reachable from \a fc and schedules them
    for writing. For each container an approriate element is created and
    its preWrite method is called, thus recursively discovering all reachable
    containers.

    \param[in] fc FieldContainer that is inspected for reachable containers.
 */
void
OSBRootElement::preWrite(FieldContainer * const fc)
{
    OSG_OSB_LOG(("OSBRootElement::preWrite\n"));

    if(fc == NULL)
        return;

    const std::string    &typeName = fc->getType().getName();
          OSBElementBase *elem     = OSBElementFactory::the()->acquire(
        typeName, this);

    editElementList().push_back(elem);
    elem->setContainer(fc         );
    elem->setFCIdFile (fc->getId());
    elem->preWrite    (fc         );
}
/*! Visits a MFFieldContainerPtr (or more specific pointer type) during
    preWrite. It creates elements for the pointed to containers and
    calls preWrite on them. If the pointed to containers are not in the
    root's id set they are added and thus scheduled for writing.

    \param[in] fieldId Id of the field in the container of this element.
 */
void
OSBCommonElement::preWritePtrMultiField(const UInt32 fieldId)
{
    OSG_OSB_LOG(("OSBCommonElement::preWritePtrMultiField: "
            "fieldId: [%u]\n", fieldId));

    OSBRootElement           *root       = editRoot();

    FieldContainerPtrMFieldBase::GetHandlePtr mfPtrField =
        boost::dynamic_pointer_cast<FieldContainerPtrMFieldBase::GetHandle>(
            getContainer()->getField(fieldId));

    if(mfPtrField == NULL || mfPtrField->isValid() == false)
        return;

    FieldContainerPtrMFieldBase::const_iterator fieldIt  = 
        (*mfPtrField)->begin();

    FieldContainerPtrMFieldBase::const_iterator fieldEnd = 
        (*mfPtrField)->end  ();

    for(; fieldIt != fieldEnd; ++fieldIt)
    {
        FieldContainer *refedFC = *fieldIt;

        if(refedFC == NULL)
            continue;

        UInt32             refedId  = refedFC->getId  ();
        const std::string &typeName = refedFC->getType().getName();

        // only schedule a container once
        if(root->getIdSet().count(refedId) > 0)
            continue;

        OSBElementBase *elem = OSBElementFactory::the()->acquire(
            typeName, root);

        root->editIdSet      ().insert   (refedId);
        root->editElementList().push_back(elem   );
        elem->setContainer(refedFC);
        elem->preWrite    (refedFC);
    }
}
/*! Callback called for each element in a map field (this is used by
    preWriteMapField).
 */
void OSBCommonElement::handleMapElementPreWrite(FieldContainer *refedFC)
{
    if(refedFC == NULL)
        return;

    OSBRootElement    *root      = editRoot();
    UInt32             refedId  = refedFC->getId  ();
    const std::string &typeName = refedFC->getType().getName();

    // only schedule a container once
    if(root->getIdSet().count(refedId) > 0)
        return;

    OSBElementBase *elem = OSBElementFactory::the()->acquire(typeName, root);

    root->editIdSet      ().insert   (refedId);
    root->editElementList().push_back(elem   );
    elem->setContainer(refedFC);
    elem->preWrite    (refedFC);
}
예제 #6
0
void
OSBGeometryElement::preWrite(FieldContainer * const fc)
{
    OSG_OSB_LOG(("OSBGeometryElement::preWrite\n"));

    OSBRootElement *root       = editRoot();
    UInt32          fieldCount = fc->getType().getNumFieldDescs();

    UInt8 quanResPositions = root->getOptions().quantizePositions();
    UInt8 quanResNormals   = root->getOptions().quantizeNormals  ();
    UInt8 quanResTexCoords = root->getOptions().quantizeTexCoords();
    bool  packIndices      = root->getOptions().packIndices      ();

    // go through all fields and find those refering to other FCs
    for(UInt32 fieldId = 1; fieldId <= fieldCount; ++fieldId)
    {
        const FieldDescriptionBase *fieldDesc = fc->getFieldDescription(fieldId);
        const FieldType            &fieldType = fieldDesc->getFieldType();
        const std::string          &fieldName = fieldDesc->getName     ();

        // skip internal fields
        if(fieldDesc->isInternal())
        {
            OSG_OSB_LOG(("OSBGeometryElement::preWrite: "
                    "Skipping internal field: [%s]\n", fieldName.c_str()));
            continue;
        }

        if(fieldName == "properties")
        {
            // "properties" might be quantized
            FieldContainerPtrMFieldBase::GetHandlePtr fP =
                boost::dynamic_pointer_cast<
                    FieldContainerPtrMFieldBase::GetHandle>(
                        getContainer()->getField(fieldId));

            if(fP == NULL || fP->isValid() == false)
                continue;

            FieldContainerPtrMFieldBase::const_iterator fieldIt  = 
                (*fP)->begin();

            FieldContainerPtrMFieldBase::const_iterator fieldEnd = 
                (*fP)->end  ();

            for(UInt32 i = 0; fieldIt != fieldEnd; ++fieldIt, ++i)
            {
                FieldContainer *refedFC = *fieldIt;

                if(refedFC == NULL)
                    continue;

                      UInt32      refedId  = refedFC->getId  ();
                const std::string typeName = refedFC->getType().getName();

                // only schedule a container once
                if(root->getIdSet().count(refedId) > 0)
                    continue;

                OSBElementBase              *elem     =
                    OSBElementFactory::the()->acquire(typeName, root);
                OSBGeoVectorPropertyElement *propElem =
                    dynamic_cast<OSBGeoVectorPropertyElement *>(elem);

                if((propElem != 0) && (i == Geometry::PositionsIndex))
                {
                    propElem->setQuantizeResolution(quanResPositions);
                }
                else if((propElem != 0) && (i == Geometry::NormalsIndex))
                {
                    propElem->setQuantizeResolution(quanResNormals);
                }
                else if((propElem != 0) && (i >= Geometry::TexCoordsIndex) &&
                        (i <= Geometry::TexCoords7Index)                     )
                {
                    propElem->setQuantizeResolution(quanResTexCoords);
                }

                root->editIdSet      ().insert   (refedId);
                root->editElementList().push_back(elem   );
                elem->setContainer(refedFC);
                elem->preWrite    (refedFC);
            }
        }
        else if(fieldName == "propIndices")
        {
            // "propIndices" might be packed
            FieldContainerPtrMFieldBase::GetHandlePtr fP =
                boost::dynamic_pointer_cast<
                    FieldContainerPtrMFieldBase::GetHandle>(
                        getContainer()->getField(fieldId));

            if(fP == NULL || fP->isValid() == false)
                continue;

            FieldContainerPtrMFieldBase::const_iterator fieldIt  = 
                (*fP)->begin();
            FieldContainerPtrMFieldBase::const_iterator fieldEnd = 
                (*fP)->end  ();

            for(UInt32 i = 0; fieldIt != fieldEnd; ++fieldIt, ++i)
            {
                FieldContainer *refedFC = *fieldIt;

                if(refedFC == NULL)
                    continue;

                      UInt32      refedId  = refedFC->getId  ();
                const std::string typeName = refedFC->getType().getName();

                // only schedule a container once
                if(root->getIdSet().count(refedId) > 0)
                    continue;

                OSBElementBase                *elem     =
                    OSBElementFactory::the()->acquire(typeName, root);
                OSBGeoIntegralPropertyElement *propElem =
                    dynamic_cast<OSBGeoIntegralPropertyElement *>(elem);

                if((propElem != 0) && (packIndices == true))
                {
                    propElem->setPackData(true);
                }

                root->editIdSet      ().insert   (refedId);
                root->editElementList().push_back(elem   );
                elem->setContainer(refedFC);
                elem->preWrite    (refedFC);
            }
        }
        else if(fieldName == "attachments")
        {
            preWriteAttachmentMapField(fieldId);
        }
        else
        {
            // check if field refers to another FC, i.e. its a field holding
            // FieldContainerPtr or an FieldContainerAttachmentMap
            if(fieldType.getContentType().isDerivedFrom(
                FieldTraits<FieldContainer *>::getType()) == true)
            {
                if(fieldType.getCardinality() == FieldType::SingleField)
                {
                    preWritePtrSingleField(fieldId);
                }
                else if(fieldType.getCardinality() == FieldType::MultiField)
                {
                    preWritePtrMultiField(fieldId);
                }
            }
        }
    }
}