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);
    }
}
Beispiel #2
0
static SbBool
soupgrader_exists(const SbName & name)
{
  assert(soupgrader_namedict);
  void * dummy;
  return soupgrader_namedict->get(name.getString(), dummy);
}
Beispiel #3
0
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;
	}
}
Beispiel #4
0
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;
}
Beispiel #5
0
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
}
Beispiel #6
0
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;
}
Beispiel #7
0
/*!
  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");
}
Beispiel #8
0
/*!
  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;
}
Beispiel #9
0
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);
  }
}
Beispiel #10
0
/*!
  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;
}
Beispiel #11
0
/*!
  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
  }
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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 */
}
Beispiel #15
0
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;
}
Beispiel #16
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;
}
Beispiel #17
0
// 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;
}
Beispiel #18
0
// 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;
}
Beispiel #19
0
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();
    }
}
Beispiel #20
0
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;
}
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)
Beispiel #22
0
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;
}
Beispiel #23
0
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());
  }
}
Beispiel #24
0
////////////////////////////////////////////////////////////////////////
//
// 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...
}
Beispiel #25
0
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;
}
Beispiel #26
0
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.
}
Beispiel #27
0
/**
 * 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);
}