/*! 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); } }
/*! 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); } }
/*! Fills the "pointer field" described by \a ptrField with the correct pointers. \param[in] ptrField Field to fill. */ void OSBRootElement::mapPtrField(const PtrFieldInfo &ptrField) { OSG_OSB_LOG(("OSBRootElement::mapPtrField\n")); PtrFieldInfo::PtrIdStoreConstIt idIt = ptrField.beginIdStore(); PtrFieldInfo::PtrIdStoreConstIt idEnd = ptrField.endIdStore (); PtrFieldInfo::BindingStoreConstIt bindingIt = ptrField.beginBindingStore(); PtrFieldInfo::BindingStoreConstIt bindingEnd = ptrField.endBindingStore (); const FieldContainerIdMap &idMap = getIdMap(); FieldContainerIdMapConstIt idMapIt; FieldContainerIdMapConstIt idMapEnd = idMap.end(); if(bindingIt != bindingEnd) { if(ptrField.getHandledField() == true) { FieldContainer *fieldCon = ptrField.getContainer(); UInt32 fieldId = ptrField.getFieldId(); EditFieldHandlePtr fHandle = fieldCon->editField(fieldId); EditMapFieldHandlePtr sfMapField = boost::dynamic_pointer_cast<EditMapFieldHandle>(fHandle); if(sfMapField == NULL || sfMapField->isValid() == false) return; sfMapField->fillFrom(ptrField.getBindingStore(), ptrField.getIdStore (), idMap); } else { Attachment *att = NULL; AttachmentContainer *attCon = dynamic_cast<AttachmentContainer *>(ptrField.getContainer()); for(; (idIt != idEnd) && (bindingIt != bindingEnd); ++idIt, ++bindingIt) { if(*idIt != 0) { idMapIt = idMap.find(*idIt); if(idMapIt != idMapEnd) { att = dynamic_cast<Attachment *>( FieldContainerFactory::the()->getContainer( idMapIt->second)); } else { FWARNING(("OSBRootElement::mapPtrField: could not find " "FieldContainer with id [%u]\n", *idIt)); att = NULL; } } else { att = NULL; } if(att != NULL) { OSG_OSB_LOG(("OSBRootElement::mapPtrField: adding " "attchment [%u] [%u]\n", att->getType().getGroupId(), *bindingIt)); } attCon->addAttachment(att, *bindingIt); } } } else { FieldContainer *fc = NULL; FieldContainer *fieldCon = ptrField.getContainer(); UInt32 fieldId = ptrField.getFieldId(); EditFieldHandlePtr fHandle = fieldCon->editField(fieldId); FieldContainerPtrSFieldBase::EditHandlePtr pSFHandle = boost::dynamic_pointer_cast< FieldContainerPtrSFieldBase::EditHandle>(fHandle); FieldContainerPtrMFieldBase::EditHandlePtr pMFHandle = boost::dynamic_pointer_cast< FieldContainerPtrMFieldBase::EditHandle>(fHandle); for(; idIt != idEnd; ++idIt) { if(*idIt != 0) { idMapIt = idMap.find(*idIt); if(idMapIt != idMapEnd) { fc = FieldContainerFactory::the()->getContainer( idMapIt->second); } else { FWARNING(("OSBRootElement::mapPtrField: could not find " "FieldContainer with (file) id [%u]\n", *idIt)); fc = NULL; } } else { fc = NULL; } if(pSFHandle != NULL && pSFHandle->isValid()) { pSFHandle->set(fc); } else if(pMFHandle != NULL && pMFHandle->isValid()) { pMFHandle->add(fc); } else { FWARNING(("OSBRootElement::mapPtrField: FieldHandles invalid, " "can not set pointer - target fc [%u][%s] " "fieldId [%u][%s] file id [%u] system id [%u]\n", (fc != NULL ? fc->getId() : 0), (fc != NULL ? fc->getType().getCName() : ""), fieldId, (fc != NULL ? fc->getType().getFieldDesc(fieldId)->getCName() : ""), *idIt, (idMapIt != idMapEnd ? idMapIt->second : 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); } } } } }
void printFieldContainer() { int N = FieldContainerFactory::the()->getNumTotalContainers(); for (int i=0;i<N;++i) { FieldContainer* fc = FieldContainerFactory::the()->getContainer(i); if(fc == 0) continue; // skip prototypes if(fc->getType().getPrototype() == 0 || fc->getType().getPrototype() == fc ) continue; //cout << "\nFC id: " << fc->getId() << flush; AttachmentContainer* ac = dynamic_cast<AttachmentContainer*>(fc); if (ac == 0) { Attachment* a = dynamic_cast<Attachment*>(fc); if (a != 0) { FieldContainer* dad = 0; if (a->getMFParents()->size() > 0) dad = a->getParents(0); ac = dynamic_cast<AttachmentContainer*>(dad); } } const Char8* name = getName(ac); if (name != 0) printf("Detected living FC %s (%s) %p refcount %d ID %d\n", fc->getTypeName(), name, fc, fc->getRefCount(), fc->getId()); else printf( "Detected living FC %s %p refcount %d ID %d\n", fc->getTypeName(), fc, fc->getRefCount(), fc->getId() ); } }