SbBool SoXipSFData::readValue(SoInput *in) { SbName name; if( in->read( name ) ) { if( name == "NULL" || name == "DATA" || name == "\"NULL\"" || name == "\"DATA\"" ) { setVal( NULL ); SbXipDirtyFieldList::append(this); return TRUE; } else in->putBack( name.getString() ); } SoBase* base; if( !SoBase::read( in, base, SoXipData::getClassTypeId() ) ) { setVal( NULL ); return FALSE; } setVal( NULL ); SbXipDirtyFieldList::append(this); return TRUE; }
SbBool SoSFPath::readValue(SoInput *in) // //////////////////////////////////////////////////////////////////////// { SbName name; SoBase *base; // See if it's a null pointer if (in->read(name)) { if (name == "NULL") { setVal(NULL); return TRUE; } else in->putBack(name.getString()); } // Read path if (! SoBase::read(in, base, SoPath::getClassTypeId())) { setVal(NULL); return FALSE; } setVal((SoPath *) base); return TRUE; }
void SoSFEnum::writeValue(SoOutput * out) const { const SbName *enumname; if (findEnumName(this->getValue(), enumname)) { out->write(const_cast<char *>(enumname->getString())); return; } // If we don't have any legal values for this field, // pass through read integer values. if (!this->legalValuesSet) { out->write(this->getValue()); return; } #if COIN_DEBUG // An unknown enumeration value will usually be an indication of a // more serious bug, so we elaborate a bit on the error to aid early // debugging. mortene. SbName name; const SoFieldContainer * thecontainer = this->getContainer(); const SbBool fname = thecontainer && thecontainer->getFieldName(this, name); SbString s(""); if (fname) { s.sprintf(" \"%s\"", name.getString()); } SoDebugError::post("SoSFEnum::writeValue", "Illegal enumeration value %d in field%s", this->getValue(), s.getString()); #endif // COIN_DEBUG }
QWidget* ParametersDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex &index) const { const ParametersModel* model = static_cast< const ParametersModel* >( index.model() ); SoField* field = model->ModelItem( index )->GetField(); if( field->getTypeId().isDerivedFrom( SoSFEnum::getClassTypeId() ) ) { QComboBox* editor = new QComboBox( parent ); SoSFEnum* enumField = static_cast< SoSFEnum* >( field ); for( int i = 0; i < enumField->getNumEnums() ; ++i ) { SbName enumName; enumField->getEnum( i , enumName ); editor->addItem( enumName.getString() ); } return editor; } else if( field->getTypeId().isDerivedFrom( SoMField::getClassTypeId() ) ) { ContainerEditor* editor = new ContainerEditor( parent ); editor->setGeometry(option.rect); connect( editor, SIGNAL( editingFinished( ) ), this, SLOT( CloseEditor() )); return editor; } else { QLineEdit* editor = new QLineEdit(parent); return editor; } }
void SoUnknownEngine::copyContents(const SoFieldContainer *fromFC, SbBool copyConnections) // //////////////////////////////////////////////////////////////////////// { // Make sure the copy has the correct class name const SoUnknownEngine *fromUnk = (const SoUnknownEngine *) fromFC; setClassName(fromUnk->className); // For each input in the original engine, create a new input and add // it to the new engine // NOTE: We can't use SoEngine::copyContents() to copy the field // data, since that uses SoFieldData::overlay(), which assumes the // fields have the same offsets in both engines. Instead, we just // copy the field values ourselves. const SoFieldData *fromData = fromUnk->getFieldData(); SoFieldData *toData = (SoFieldData *) getFieldData(); int i; for (i = 0; i < fromData->getNumFields(); i++) { SoField *fromField = fromData->getField(fromUnk, i); const SbName fieldName = fromData->getFieldName(i); SoType fieldType = fromField->getTypeId(); SoField *toField = (SoField *) (fieldType.createInstance()); toField->enableNotify(FALSE); toField->setContainer(this); toField->setDefault(TRUE); toField->enableNotify(TRUE); toData->addField(this, fieldName.getString(), toField); toField->setContainer(this); toField->copyFrom(*fromField); toField->setIgnored(fromField->isIgnored()); toField->setDefault(fromField->isDefault()); toField->fixCopy(copyConnections); if (fromField->isConnected() && copyConnections) toField->copyConnection(fromField); } // Copy the outputs SoEngineOutputData *toOutData = (SoEngineOutputData *) getOutputData(); SoEngineOutputList outList; fromUnk->getOutputs(outList); for(i = 0; i < outList.getLength(); i++) { SoEngineOutput *newOut = new SoEngineOutput; const SoType outType = outList[i]->getConnectionType(); SbName outName; getOutputName( outList[i], outName ); toOutData->addOutput(this, outName.getString(), newOut, outType); newOut->setContainer(this); } }
void list_enums(const Type * f) { const unsigned int nrenums = f->getNumEnums(); for (unsigned int k=0; k < nrenums; k++) { SbName name; const int val = f->getEnum(k, name); (void)fprintf(stdout, " %s == %d\n", name.getString(), val); } }
SbBool SoSFEnum::readValue(SoInput * in) { SbName n; int val; // Read mnemonic value as a character string identifier if (!in->read(n, TRUE)) { // If we don't have any legal values for this field, // give some slack and accept integer values. if (this->legalValuesSet || !in->read(val)) { SoReadError::post(in, "Couldn't read enumeration name"); return FALSE; } } else { if (!this->findEnumValue(n, val)) { // If we read an enum field written by an extension node, // we won't have any defined enum values. This is indicated by // this->legalValuesSet == FALSE. If this is the case, define // any encountered enum values on the fly but keep legalValuesSet // to FALSE in order not to fool built-in enum field to accept // illegal values. if (!this->legalValuesSet) { int *newvalues = new int[this->numEnums+1]; SbName *newnames = new SbName[this->numEnums+1]; int i; for (i = 0; i < this->numEnums; i++) { newvalues[i] = this->enumValues[i]; newnames[i] = this->enumNames[i]; } newvalues[i] = i; newnames[i] = n; delete[] this->enumValues; delete[] this->enumNames; this->enumValues = newvalues; this->enumNames = newnames; this->numEnums += 1; val = i; } else { SoReadError::post(in, "Unknown enumeration value \"%s\"", n.getString()); return FALSE; } } } this->value = val; return TRUE; }
static SbBool soupgrader_exists(const SbName & name) { assert(soupgrader_namedict); void * dummy; return soupgrader_namedict->get(name.getString(), dummy); }
/*! Action method for SoWriteAction. Writes out a node object, and any connected nodes, engines etc, if necessary. */ void SoNode::write(SoWriteAction * action) { SoOutput * out = action->getOutput(); SoNode * node = this; SoProtoInstance * proto = SoProtoInstance::findProtoInstance(this); if (proto) { node = proto; } if (out->getStage() == SoOutput::COUNT_REFS) { node->addWriteReference(out, FALSE); } else if (out->getStage() == SoOutput::WRITE) { if (node->writeHeader(out, FALSE, FALSE)) return; // check for special case where we actually have to write out an // SoEngineOutput "field". An engine output might be connected via // an IS reference in a PROTO, and we then need to write back this // IS reference when exporting the VRML file. SoProto * proto = out->getCurrentProto(); if (proto && node->isOfType(SoNodeEngine::getClassTypeId())) { SoEngineOutputList l; const int num = ((SoNodeEngine*)node)->getOutputs(l); for (int i = 0; i < num; i++) { SbName name; if (((SoNodeEngine*)node)->getOutputName(l[i], name)) { SbName pname = proto->findISReference(node, name); if (pname.getLength()) { out->indent(); out->write(name.getString()); out->write(" IS "); out->write(pname.getString()); out->write("\n"); } } } } node->getFieldData()->write(out, node); node->writeFooter(out); } else assert(0 && "unknown stage"); }
int main(void) { SoDB::init(); SoNodeKit::init(); SoInteraction::init(); SoTypeList tl; const unsigned int n = SoType::getAllDerivedFrom(SoNode::getClassTypeId(), tl); for (unsigned int i=0; i < n; i++) { (void)fprintf(stdout, "%s", tl[i].getName().getString()); SoFieldContainer * fc = (SoFieldContainer *) (tl[i].canCreateInstance() ? tl[i].createInstance() : NULL); if (fc == NULL) { (void)fprintf(stdout, " (abstract)\n"); continue; } (void)fprintf(stdout, "\n"); SoFieldList fl; const unsigned int nrf = fc->getAllFields(fl); for (unsigned int j=0; j < nrf; j++) { SoField * f = fl[j]; SoType ftype = f->getTypeId(); SbName fname; f->getContainer()->getFieldName(f, fname); (void)fprintf(stdout, " %s (%s)\n", fname.getString(), ftype.getName().getString()); if (ftype.isDerivedFrom(SoSFEnum::getClassTypeId())) { list_enums((SoSFEnum *)f); } else if (ftype.isDerivedFrom(SoMFEnum::getClassTypeId())) { list_enums((SoMFEnum *)f); } } } return 0; }
SbBool SoSFEnum::readValue(SoInput *in) // //////////////////////////////////////////////////////////////////////// { SbName n; // Read mnemonic value as a character string identifier if (! in->read(n, TRUE)) return FALSE; if (findEnumValue(n, value)) return TRUE; // Not found? Too bad SoReadError::post(in, "Unknown SoSFEnum enumeration value \"%s\"", n.getString()); return FALSE; }
/*! Registers a concrete SoForeignFileKit subtype to be a handler for files with the given extension. One class can be a handler for multiple filename extensions. FIXME: \e identify is not implemented */ SbBool SoForeignFileKit::registerFileExtension(SoType handler, SbName extension, SoForeignFileIdentifyFunc * COIN_UNUSED_ARG(identify)) { assert(SoForeignFileKitP::fileexts != NULL); assert(handler.canCreateInstance()); if (extension.getString()[0] == '.') { #if COIN_DEBUG SoDebugError::post("SoForeignFileKit::registerFileExtension", "Do not include the extension separator '.' " "when registering file extension."); #endif // COIN_DEBUG } if (SoForeignFileKitP::fileexts->put(extension.getString(), handler)) { return TRUE; } return FALSE; }
// Read boolean value from input stream, return TRUE if // successful. Used from SoSFBool and SoMFBool. SbBool sosfbool_read_value(SoInput * in, SbBool & val) { // accept 0 or 1 if (in->read(val)) { if (val != 0 && val != 1) { SoReadError::post(in, "Illegal value for field: %d (must be 0 or 1)", val); return FALSE; } return TRUE; } if (in->isBinary()) { SoReadError::post(in, "Premature end of file"); return FALSE; } // read TRUE/FALSE keyword SbName n; if (!in->read(n, TRUE)) { SoReadError::post(in, "Couldn't read field value"); return FALSE; } if (n == "TRUE") { val = TRUE; return TRUE; } if (n == "FALSE") { val = FALSE; return TRUE; } SoReadError::post(in, "Invalid value \"%s\" for field (must be TRUE or FALSE)", n.getString()); return FALSE; }
// Import node. SbBool SoSFNode::readValue(SoInput * in) { SoBase * baseptr; SbBool isVRMLspecialCase = FALSE; // Note: do *not* simply check for baseptr==NULL here, as that is a // valid condition for VRML97 files, where nodes can indeed be // explicitly given as a NULL value. See the 'vrml97nullchild' test // case near the end of this file for a valid case that would fail. if(in->isFileVRML1() || in->isFileVRML2()) { SbName name; in->read(name, TRUE); if (name == "NULL") { baseptr = NULL; isVRMLspecialCase = TRUE; } else { in->putBack(name.getString()); } } if (!isVRMLspecialCase) { if (!SoBase::read(in, baseptr, SoNode::getClassTypeId())) return FALSE; if (baseptr == NULL) { SoReadError::post(in, "Invalid node specification"); return FALSE; } } if (in->eof()) { SoReadError::post(in, "Premature end of file"); return FALSE; } if (baseptr != NULL) { this->setValue(coin_safe_cast<SoNode *>(baseptr)); } return TRUE; }
void SoDebug::writeField(SoField *field) // //////////////////////////////////////////////////////////////////////// { SoFieldContainer *fc = field->getContainer(); SbName fieldName; fc->getFieldName(field, fieldName); printf("Field name is: %s\n", fieldName.getString()); if (fc->isOfType(SoNode::getClassTypeId())) { printf("Field is part of node:\n"); SoNode *node = (SoNode *)fc; node->ref(); SoWriteAction wa; wa.apply(node); node->unrefNoDelete(); } }
SbBool SoMFBool::read1Value(SoInput *in, int index) // //////////////////////////////////////////////////////////////////////// { // accept 0 or 1 for both binary and ascii // with integer fields) if (in->read(values[index])) { if (values[index] != 0 && values[index] != 1) { SoReadError::post(in, "Illegal value for SoMFBool: %d " "(must be 0 or 1)", values[index]); return FALSE; } return TRUE; } // binary doesn't use TRUE/FALSE strings if (in->isBinary()) return FALSE; // read TRUE/FALSE keyword SbName n; if (! in->read(n, TRUE)) return FALSE; if (n == "TRUE") { values[index] = TRUE; return TRUE; } if (n == "FALSE") { values[index] = FALSE; return TRUE; } SoReadError::post(in, "Unknown value (\"%s\") for SoMFBool ", "(must be TRUE or FALSE)", n.getString()); return FALSE; }
/*! This method removes class type from the class system. Returns FALSE if a type with the given name doesn't exist. \since Coin 3.0 */ SbBool SoType::removeType(const SbName & name) { int16_t index = 0; if (!type_dict->get(name.getString(), index)) { SoDebugError::post("SoType::removeType", "type with name ``%s'' not found", name.getString()); return FALSE; } type_dict->erase(name.getString()); SoTypeData *typedata = (*SoType::typedatalist)[index]; (*SoType::typedatalist)[index] = NULL; delete typedata; #if COIN_DEBUG && 0 // debug SoDebugError::postInfo("SoType::removeType", "%s", name.getString()); #endif // debug return TRUE; }
/*! Set the value of this field by specifying an enumeration string value. */ void SoSFEnum::setValue(const SbName name) { int val; if (this->findEnumValue(name, val)) { this->setValue(val); } else { #if COIN_DEBUG SoDebugError::post("SoSFEnum::setValue", "Unknown enum '%s'", name.getString()); #endif // COIN_DEBUG } }
const SoType SoType::createType(const SoType parent, const SbName name, const instantiationMethod method, const uint16_t data) { #if COIN_DEBUG // We don't use SoType::fromName() to test if a type with this name // already exists to avoid loading extension nodes in this context. // You should be able to "override" dynamically loadable nodes in program // code. // FIXME: We ought to factor out and expose this functionality - testing // if a class type is already loaded and registered - in the public API. // 20040831 larsa (ref could-have-been-used-to-fix-upgrader-slowness-bug) int16_t discard; if (type_dict->get(name.getString(), discard)) { SoDebugError::post("SoType::createType", "a type with name ``%s'' already created", name.getString()); return SoType::fromName(name.getString()); } #endif // COIN_DEBUG #if COIN_DEBUG && 0 // debug SoDebugError::postInfo("SoType::createType", "%s", name.getString()); #endif // debug SoType newType; newType.index = SoType::typedatalist->getLength(); SoTypeData * typeData = new SoTypeData(name, newType, TRUE, data, parent, method); SoType::typedatalist->append(typeData); // add to dictionary for fast lookup type_dict->put(name.getString(), newType.getKey()); return newType; }
void SoSFEnum::setValue(const SbName &name) // //////////////////////////////////////////////////////////////////////// { int enumVal; if (findEnumValue(name, enumVal)) setValue(enumVal); #ifdef DEBUG else SoDebugError::post("SoSFEnum::setValue", "No enum for name \"%s\"", name.getString()); #endif /* DEBUG */ }
void MFieldEditor::on_table_customContextMenuRequested(QPoint pos) { //Miramos si se ha pulsado sobre algun item valido QTableWidgetItem *item = Ui.table->itemAt(pos); if (!item || current_mfield == NULL) return; int row = Ui.table->row(item); //int column = Ui.table->column(item); //Leemos el tipo de este campo SoType tipo=current_mfield->getTypeId(); const char*nombre_tipo = tipo.getName(); //Miramos si hay algun ayudante para este tipo... //Edicion de cualquier campo tipo SoMFBool if (!strcmp(nombre_tipo, "MFBool") ) { //Preparamos un menu flotante con opciones true/false QMenu popm(this); QAction actTrue("TRUE", this); QAction actFalse("FALSE", this); popm.addAction(&actTrue); popm.addAction(&actFalse); //Mostramos el menu flotante y recogemos la opcion escogida QAction *idx = popm.exec(QCursor::pos()); //Comprobamos que se ha seleccionado una opción válida. if (idx) item->setText(idx->text()); } //Edicion de cualquier campo tipo SoMFEnum //Edicion de cualquier campo tipo SoMFBitMask else if (!strcmp(nombre_tipo, "MFEnum") || !strcmp(nombre_tipo, "MFBitMask") ) { //Convertimos el tipo de field SoMFEnum *soMFEnum= (SoMFEnum *)current_mfield; //Preparamos un menu flotante QMenu popm(this); SbName nombre; int idx; //Probamos todos los indices y creamos una accion por cada for (idx=0; idx < soMFEnum->getNumEnums(); idx++) { soMFEnum->getEnum(idx, nombre); QAction *acc = new QAction(nombre.getString(), this); popm.addAction(acc); } //Mostramos el menu flotante y recogemos la opcion escogida QAction *acc = popm.exec(QCursor::pos()); //Comprobamos que se ha seleccionado una opción válida. if (!acc) return; item->setText(acc->text()); } //Edicion de cualquier campo tipo SoMFColor else if (!strcmp(nombre_tipo, "MFColor")) { //Lo convertimos en valores RGB y en un QColor QColor c (int(255*Ui.table->item(row,0)->text().toFloat()), int(255*Ui.table->item(row,1)->text().toFloat()), int(255*Ui.table->item(row,2)->text().toFloat()) ); //Solicitamos un color mediante QColorDialog c=QColorDialog::getColor(c, this); if (c.isValid() ) { QString S; //Modificamos la tabla Ui.table->item(row,0)->setText(S.setNum(c.red()/255.0, 'g',2)); Ui.table->item(row,1)->setText(S.setNum(c.green()/255.0, 'g',2)); Ui.table->item(row,2)->setText(S.setNum(c.blue()/255.0, 'g',2)); } } else { //No hay ayudante para este campo return; } }//void MFieldEditor::on_table_customContextMenuRequested(QPoint pos)
POTENTIAL_ROTTING_DOCUMENTATION /*! This static function returns the SoType object associated with name \a name. Type objects for builtin types can be retreived by name both with and without the "So" prefix. For dynamically loadable extension nodes, the name given to this function must match exactly. If no node type with the given name has been initialized, a dynamically loadable extension node with the given name is searched for. If one is found, it is loaded and initialized, and the SoType object for the newly initialized class type returned. If no module is found, or the initialization of the module fails, SoType::badType() is returned. Support for dynamically loadable extension nodes varies from platform to platform, and from compiler suite to compiler suite. So far code built with the following compilers are supported: GNU GCC v2-4, Microsoft Visual C++ v6, 2003, 2005 and 2008), SGI MIPSPro v7. Extensions built with compilers that are known to be binary compatible with the above compilers are also supported, such as e.g. the Intel x86 compiler compatible with MSVC++. To support dynamic loading for other compilers, we need to know how the compiler mangles the "static void classname::initClass(void)" symbol. If your compiler is not supported, tell us at \c [email protected] which it is and send us the output of a symbol-dump on the shared object. Typically you can do \code $ nm <Node>.so | grep initClass \endcode to find the relevant mangled symbol. */ SoType SoType::fromName(const SbName name) { static int enable_dynload = -1; if (enable_dynload == -1) { enable_dynload = TRUE; // the default setting const char * env = coin_getenv("COIN_NO_SOTYPE_DYNLOAD"); if (env && atoi(env) > 0) enable_dynload = FALSE; } assert((type_dict != NULL) && "SoType static class data not yet initialized"); // It should be possible to specify a type name with the "So" prefix // and get the correct type id, even though the types in some type // hierarchies are named internally without the prefix. SbString tmp(name.getString()); if ( tmp.compareSubString("So") == 0 ) tmp = tmp.getSubString(2); SbName noprefixname(tmp); int16_t index = 0; if (!type_dict->get(name.getString(), index) && !type_dict->get(noprefixname.getString(), index)) { if ( !SoDB::isInitialized() ) { return SoType::badType(); } if (enable_dynload) { // find out which C++ name mangling scheme the compiler uses static mangleFunc * manglefunc = getManglingFunction(); if ( manglefunc == NULL ) { // dynamic loading is not yet supported for this compiler suite static long first = 1; if ( first ) { const char * env = coin_getenv("COIN_DEBUG_DL"); if (env && (atoi(env) > 0)) { SoDebugError::post("SoType::fromName", "unable to figure out the C++ name mangling scheme"); } first = 0; } return SoType::badType(); } SbString mangled = manglefunc(name.getString()); if ( module_dict == NULL ) { module_dict = new Name2HandleMap; } // FIXME: should we search the application code for the initClass() // symbol first? dlopen(NULL) might not be portable enough, but it // could be a cool feature. 20030223 larsa // FIXME: We probably should use loadable modules (type MH_BUNDLE) // instead of shared libraries for dynamic extension nodes, on Mac // OS X, since (1) this is the Recommended Way for dynamically // loadable code and (2) it allows us to unload them when they are // no longer needed. Note that this would require major changes to // the Mac cc_dl_open() and cc_dl_sym() code. 20030318 kyrah static const char * modulenamepatterns[] = { "%s.so", "lib%s.so", "%s.dll", "lib%s.dll", "%s.dylib", "lib%s.dylib", NULL }; SbString modulenamestring; cc_libhandle handle = NULL; int i; for ( i = 0; (modulenamepatterns[i] != NULL) && (handle == NULL); i++ ) { modulenamestring.sprintf(modulenamepatterns[i], name.getString()); // We need to move the name string to an SbName since we use // the name string pointer for hash tables and need identical // names to produce the same pointers. SbName module(modulenamestring.getString()); // Register all the module names we have tried so we don't try // them again. if (dynload_tries == NULL) dynload_tries = new NameMap; void * dummy; if (dynload_tries->get(module.getString(), dummy)) continue; // already tried dynload_tries->put(module.getString(), NULL); cc_libhandle idx = NULL; if ( module_dict->get(module.getString(), idx) ) { // Module has been loaded, but type is not yet finished initializing. // SoType::badType() is here the expected return value. See below. return SoType::badType(); } // FIXME: should we maybe use a Coin-specific search path variable // instead of the LD_LIBRARY_PATH one? 20020216 larsa handle = cc_dl_open(module.getString()); if ( handle != NULL ) { // We register the module so we don't recurse infinitely in the // initClass() function which calls SoType::fromName() on itself // which expects SoType::badType() in return. See above. module_dict->put(module.getString(), handle); if (i > 0) { // We now know the file pattern used on this system, so we // should prioritize that pattern first. const char * pattern = modulenamepatterns[i]; modulenamepatterns[i] = modulenamepatterns[0]; modulenamepatterns[0] = pattern; } } } if ( handle == NULL ) return SoType::badType(); // find and invoke the initClass() function. // FIXME: declspec stuff initClassFunction * initClass = (initClassFunction *) cc_dl_sym(handle, mangled.getString()); if ( initClass == NULL ) { // FIXME: if a module is found and opened and initialization // fails, the remaining module name patterns are not tried. // might trigger as a problem one day... 2030224 larsa #if COIN_DEBUG SoDebugError::postWarning("SoType::fromName", "Mangled symbol %s not found in module %s. " "It might be compiled with the wrong compiler / " "compiler-settings or something similar.", mangled.getString(), modulenamestring.getString()); #endif cc_dl_close(handle); return SoType::badType(); } initClass(); // We run these tests to get the index. if (!type_dict->get(name.getString(), index) && !type_dict->get(noprefixname.getString(), index)) { assert(0 && "how did this happen?"); } } } assert(index >= 0 && index < SoType::typedatalist->getLength()); assert(((*SoType::typedatalist)[index]->name == name) || ((*SoType::typedatalist)[index]->name == noprefixname)); return (*SoType::typedatalist)[index]->type; }
SbBool SoSFBitMask::readValue(SoInput *in) // //////////////////////////////////////////////////////////////////////// { char c; SbName n; int v; value = 0; if (in->isBinary()) { // Read all non-empty strings while (in->read(n, TRUE) && ! (! n) ) { if (findEnumValue(n, v)) value |= v; else { SoReadError::post(in, "Unknown SoSFBitMask bit mask value \"%s\"", n.getString()); return FALSE; } } } else { // Read first character if (! in->read(c)) return FALSE; // Check for parenthesized list of bitwise-or'ed flags if (c == OPEN_PAREN) { // Read names separated by BITWISE_OR while (TRUE) { if (in->read(n, TRUE) && ! (! n) ) { if (findEnumValue(n, v)) value |= v; else { SoReadError::post(in, "Unknown SoSFBitMask bit " "mask value \"%s\"", n.getString()); return FALSE; } } if (! in->read(c)) { SoReadError::post(in, "EOF reached before '%c' " "in SoSFBitMask value", CLOSE_PAREN); return FALSE; } if (c == CLOSE_PAREN) break; else if (c != BITWISE_OR) { SoReadError::post(in, "Expected '%c' or '%c', got '%c' " "in SoSFBitMask value", BITWISE_OR, CLOSE_PAREN, c); return FALSE; } } } else { in->putBack(c); // Read mnemonic value as a character string identifier if (! in->read(n, TRUE)) return FALSE; if (! findEnumValue(n, value)) { SoReadError::post(in, "Unknown SoSFBitMask bit " "mask value \"%s\"", n.getString()); return FALSE; } } } return TRUE; }
void ScXMLDocument::PImpl::fillIdentifierMaps(ScXMLElt * object) { assert(object); if (object->isOfType(ScXMLAbstractStateElt::getClassTypeId())) { ScXMLAbstractStateElt * state = static_cast<ScXMLStateElt *>(object); SbName id(state->getIdAttribute()); this->stateidmap->insert(std::pair<const char *, ScXMLAbstractStateElt *>(id.getString(), state)); } if (object->isOfType(ScXMLDataElt::getClassTypeId())) { ScXMLDataElt * data = static_cast<ScXMLDataElt *>(object); const SbName id(data->getIDAttribute()); this->dataidmap->insert(std::pair<const char *, ScXMLDataElt *>(id.getString(), data)); } if (object->isOfType(ScXMLAnchorElt::getClassTypeId())) { /*ScXMLAnchorElt * anchor = */static_cast<ScXMLAnchorElt *>(object); } else if (object->isOfType(ScXMLDataElt::getClassTypeId())) { /*ScXMLDataElt * data = */static_cast<ScXMLDataElt *>(object); } else if (object->isOfType(ScXMLScxmlElt::getClassTypeId())) { ScXMLScxmlElt * root = static_cast<ScXMLScxmlElt *>(object); int c; for (c = 0; c < root->getNumStates(); ++c) { this->fillIdentifierMaps(root->getState(c)); } for (c = 0; c < root->getNumParallels(); ++c) { this->fillIdentifierMaps(root->getParallel(c)); } for (c = 0; c < root->getNumFinals(); ++c) { this->fillIdentifierMaps(root->getFinal(c)); } } else if (object->isOfType(ScXMLFinalElt::getClassTypeId())) { /*ScXMLFinalElt * final = */static_cast<ScXMLFinalElt *>(object); } else if (object->isOfType(ScXMLHistoryElt::getClassTypeId())) { const ScXMLHistoryElt * history = static_cast<ScXMLHistoryElt *>(object); if (history->getTransition()) { this->fillIdentifierMaps(history->getTransition()); } } else if (object->isOfType(ScXMLInitialElt::getClassTypeId())) { ScXMLInitialElt * initial = static_cast<ScXMLInitialElt *>(object); if (initial->getTransition()) { this->fillIdentifierMaps(initial->getTransition()); } } else if (object->isOfType(ScXMLInvokeElt::getClassTypeId())) { /*ScXMLInvokeElt * invoke = */static_cast<ScXMLInvokeElt *>(object); } else if (object->isOfType(ScXMLOnEntryElt::getClassTypeId())) { ScXMLOnEntryElt * onentry = static_cast<ScXMLOnEntryElt *>(object); int c; for (c = 0; c < onentry->getNumExecutables(); ++c) { this->fillIdentifierMaps(onentry->getExecutable(c)); } } else if (object->isOfType(ScXMLOnExitElt::getClassTypeId())) { ScXMLOnExitElt * onexit = static_cast<ScXMLOnExitElt *>(object); int c; for (c = 0; c < onexit->getNumExecutables(); ++c) { this->fillIdentifierMaps(onexit->getExecutable(c)); } } else if (object->isOfType(ScXMLStateElt::getClassTypeId())) { ScXMLStateElt * state = static_cast<ScXMLStateElt *>(object); int c; if (state->getOnEntry()) { this->fillIdentifierMaps(state->getOnEntry()); } if (state->getOnExit()) { this->fillIdentifierMaps(state->getOnExit()); } for (c = 0; c < state->getNumTransitions(); ++c) { this->fillIdentifierMaps(state->getTransition(c)); } if (state->getInitial()) { this->fillIdentifierMaps(state->getInitial()); } for (c = 0; c < state->getNumStates(); ++c) { this->fillIdentifierMaps(state->getState(c)); } for (c = 0; c < state->getNumParallels(); ++c) { this->fillIdentifierMaps(state->getParallel(c)); } for (c = 0; c < state->getNumFinals(); ++c) { this->fillIdentifierMaps(state->getFinal(c)); } for (c = 0; c < state->getNumHistories(); ++c) { this->fillIdentifierMaps(state->getHistory(c)); } for (c = 0; c < state->getNumAnchors(); ++c) { this->fillIdentifierMaps(state->getAnchor(c)); } if (state->getDataModel()) { this->fillIdentifierMaps(state->getDataModel()); } } else if (object->isOfType(ScXMLTransitionElt::getClassTypeId())) { ScXMLTransitionElt * transition = static_cast<ScXMLTransitionElt *>(object); int c; for (c = 0; c < transition->getNumExecutables(); ++c) { this->fillIdentifierMaps(transition->getExecutable(c)); } } else if (object->isOfType(ScXMLLogElt::getClassTypeId())) { /*ScXMLLogElt * log = */static_cast<ScXMLLogElt *>(object); } else if (object->isOfType(ScXMLSendElt::getClassTypeId())) { /*ScXMLSendElt * send = */static_cast<ScXMLSendElt *>(object); } else if (object->isOfType(ScXMLAssignElt::getClassTypeId())) { /*ScXMLAssignElt * assign = */static_cast<ScXMLAssignElt *>(object); } else if (object->isOfType(ScXMLDataModelElt::getClassTypeId())) { ScXMLDataModelElt * datamodel = static_cast<ScXMLDataModelElt *>(object); for (int c = 0; c < datamodel->getNumData(); ++c) { this->fillIdentifierMaps(datamodel->getData(c)); } } else { SoDebugError::postInfo("ScXMLDocument::fillIdentifierMap", "unsupported object type %s", object->getTypeId().getName().getString()); } }
//////////////////////////////////////////////////////////////////////// // // Description: // A virtual function that allows classes to treat parts that fail the // tests of 'tryToSetPartInNewNode' // // If tryToSetPartInNewNode fails, then this routine is called. // It will fail for the parts: // "appearance" and "childList." // This routine will simply discard those parts with a warning, but // no error. // // Use: public // SbBool SoV1LightKit::dealWithUpgradedPart( SoBaseKit *newNode, SoNode *newPart, const SbName &newPartName ) // //////////////////////////////////////////////////////////////////////// { // First, try to let base class handle it... if ( SoV1BaseKit::dealWithUpgradedPart( newNode, newPart, newPartName ) ) return TRUE; // If the part name is "appearance", or "childList", just print // a warning, don't set the part, and return TRUE. if ( newPartName == "appearance" || newPartName == "childList" ) { SoDebugError::postWarning("SoV1LightKit::dealWithUpgradedPart", "the input file contained a part named %s. This part no longer exists, so you will unfortunately have to lose it.", newPartName.getString() ); return TRUE; } return FALSE; // don't know how to do anything yet... }
void SoUnknownNode::copyContents(const SoFieldContainer *fromFC, SbBool copyConnections) // //////////////////////////////////////////////////////////////////////// { // Make sure the copy has the correct class name const SoUnknownNode *fromUnk = (const SoUnknownNode *) fromFC; setClassName(fromUnk->className); // For each field in the original node, create a new field and add // it to the new node // NOTE: We can't use SoNode::copyContents() to copy the field // data, since that uses SoFieldData::overlay(), which assumes the // fields have the same offsets in both nodes. Instead, we just // copy the field values ourselves. const SoFieldData *fromData = fromUnk->getFieldData(); SoFieldData *toData = (SoFieldData *) getFieldData(); int i; for (i = 0; i < fromData->getNumFields(); i++) { SoField *fromField = fromData->getField(fromUnk, i); const SbName fieldName = fromData->getFieldName(i); SoType fieldType = fromField->getTypeId(); SoField *toField = (SoField *) (fieldType.createInstance()); toField->enableNotify(FALSE); toField->setContainer(this); toField->setDefault(TRUE); toField->enableNotify(TRUE); toData->addField(this, fieldName.getString(), toField); toField->setContainer(this); toField->copyFrom(*fromField); toField->setIgnored(fromField->isIgnored()); toField->setDefault(fromField->isDefault()); toField->fixCopy(copyConnections); if (fromField->isConnected() && copyConnections) toField->copyConnection(fromField); } // Copy the kids for (i = 0; i < fromUnk->hiddenChildren.getLength(); i++) { // If this node is being copied, it must be "inside" (see // SoNode::copy() for details.) Therefore, all of its children // must be inside, as well, since our addToCopyDict() takes // care of that. SoNode *fromKid = fromUnk->getChild(i); SoNode *kidCopy = (SoNode *) findCopy(fromKid, copyConnections); #ifdef DEBUG if (kidCopy == NULL) SoDebugError::post("(internal) SoUnknownNode::copyContents", "Child %d has not been copied yet", i); #endif /* DEBUG */ hiddenChildren.append(kidCopy); } // No need to copy the override flag, since this flag will have no // effect on an unknown node, and it is not read from or written // to files. }
/** * Renders the label. */ void SoTextLabel::GLRender(SoGLRenderAction *action) { if (!this->shouldGLRender(action)) return; // only draw text without background if (!this->background.getValue()) { inherited::GLRender(action); return; } SoState * state = action->getState(); state->push(); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); SbBox3f box; SbVec3f center; this->computeBBox(action, box, center); if (!SoCullElement::cullTest(state, box, TRUE)) { SoMaterialBundle mb(action); mb.sendFirst(); const SbMatrix & mat = SoModelMatrixElement::get(state); //const SbViewVolume & vv = SoViewVolumeElement::get(state); const SbMatrix & projmatrix = (mat * SoViewingMatrixElement::get(state) * SoProjectionMatrixElement::get(state)); const SbViewportRegion & vp = SoViewportRegionElement::get(state); SbVec2s vpsize = vp.getViewportSizePixels(); // font stuff //float space = this->spacing.getValue(); //float fontsize = SoFontSizeElement::get(state); SbName fontname = SoFontNameElement::get(state); int lines = this->string.getNum(); // get left bottom corner of the label SbVec3f nilpoint(0.0f, 0.0f, 0.0f); projmatrix.multVecMatrix(nilpoint, nilpoint); nilpoint[0] = (nilpoint[0] + 1.0f) * 0.5f * vpsize[0]; nilpoint[1] = (nilpoint[1] + 1.0f) * 0.5f * vpsize[1]; #if 1 // Unfortunately, the size of the label is stored in the pimpl class of // SoText2 which cannot be accessed directly. However, there is a trick // to get the required information: set model, viewing and projection // matrix to the identity matrix and also view volume to some default // values. SoText2::computeBBox() then calls SoText2P::getQuad which // returns the sizes in form of the bounding box. These values can be // reverse-engineered to get width and height. state->push(); SoModelMatrixElement::set(state,this,SbMatrix::identity()); SoViewingMatrixElement::set(state,this,SbMatrix::identity()); SoProjectionMatrixElement::set(state,this,SbMatrix::identity()); SbViewVolume vv; vv.ortho(-1,1,-1,1,-1,1); SoViewVolumeElement::set(state,this,vv); SbBox3f box; SbVec3f center; this->computeBBox(action, box, center); state->pop(); float xmin,ymin,zmin,xmax,ymax,zmax; box.getBounds(xmin,ymin,zmin,xmax,ymax,zmax); SbVec3f v0(xmin,ymax,zmax); SbVec3f v1(xmax,ymax,zmax); SbVec3f v2(xmax,ymin,zmax); SbVec3f v3(xmin,ymin,zmax); vv.projectToScreen(v0,v0); vv.projectToScreen(v1,v1); vv.projectToScreen(v2,v2); vv.projectToScreen(v3,v3); float width,height; width = (v1[0]-v0[0])*vpsize[0]; height = (v1[1]-v3[1])*vpsize[1]; switch (this->justification.getValue()) { case SoText2::RIGHT: nilpoint[0] -= width; break; case SoText2::CENTER: nilpoint[0] -= 0.5f*width; break; default: break; } if (lines > 1) { nilpoint[1] -= (float(lines-1)/(float)lines*height); } #else // Unfortunately, the required size (in pixels) is stored in a non-accessible way // in the subclass SoText2. Thus, we try to get a satisfactory solution with Qt // methods. // The font name is of the form "family:style". If 'style' is given it can be // 'Bold', 'Italic' or 'Bold Italic'. QFont font; QString fn = QString::fromAscii(fontname.getString()); int pos = fn.indexOf(QLatin1Char(':')); if (pos > -1) { if (fn.indexOf(QLatin1String("Bold"),pos,Qt::CaseInsensitive) > pos) font.setBold(true); if (fn.indexOf(QLatin1String("Italic"),pos,Qt::CaseInsensitive) > pos) font.setItalic(true); fn = fn.left(pos); } font.setFamily(fn); font.setPixelSize((int)fontsize); QFontMetrics fm(font); float width = 0.0f; float height = 0.75f*fontsize*lines + (lines-1)*space;//fm.height(); float hh=0; for (int i = 0; i < lines; i++) { SbString str = this->string[i]; float w = fm.width(QLatin1String(this->string[i].getString())); width = std::max<float>(width, w); hh = fm.height(); } if (lines > 1) { nilpoint[1] -= ((lines-1)*fontsize*0.75f+space); } #endif SbVec3f toppoint = nilpoint; toppoint[0] += width; toppoint[1] += height; // Set new state. glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, vpsize[0], 0, vpsize[1], -1.0f, 1.0f); glPixelStorei(GL_UNPACK_ALIGNMENT,1); state->push(); // disable textures for all units SoGLTextureEnabledElement::set(state, this, FALSE); SoGLTexture3EnabledElement::set(state, this, FALSE); glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT); glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); // color and frame size SbColor color = this->backgroundColor.getValue(); float fs = this->frameSize.getValue(); // draw background glColor3f(color[0], color[1], color[2]); glBegin(GL_QUADS); glVertex3f(nilpoint[0]-fs,nilpoint[1]-fs,0.0f); glVertex3f(toppoint[0]+fs,nilpoint[1]-fs,0.0f); glVertex3f(toppoint[0]+fs,toppoint[1]+fs,0.0f); glVertex3f(nilpoint[0]-fs,toppoint[1]+fs,0.0f); glEnd(); // pop old state glPopClientAttrib(); glPopAttrib(); state->pop(); glPixelStorei(GL_UNPACK_ALIGNMENT,4); // Pop old GL matrix state. glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } state->pop(); inherited::GLRender(action); }