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 SoUnknownNode::createFromIsA(SoMFString *isA) // //////////////////////////////////////////////////////////////////////// { for (int i = 0; i < isA->getNum(); i++) { SoType t = SoType::fromName((*isA)[i]); if (t.canCreateInstance() && t.isDerivedFrom(SoNode::getClassTypeId())) { SoNode *alternateRep = (SoNode *)t.createInstance(); alternateRep->ref(); #ifdef DEBUG if (alternateRep == NULL) { SoDebugError::post("SoUnknownNode::createFromIsA", "SoType.createInstance returned " "NULL (type %s)", t.getName().getString()); return; } #endif // Copy over all fields that are shared: int num = instanceFieldData->getNumFields(); for (int j=0; j<num; j++) { const SbName &fieldName = instanceFieldData->getFieldName(j); SoField *f = instanceFieldData->getField(this, j); // Don't copy over fields with default values: if (f->isDefault()) continue; SoField *nf = alternateRep->getField(fieldName); if (nf != NULL && nf->getTypeId() == f->getTypeId()) { nf->copyFrom(*f); if (f->isConnectedFromField()) { SoField *cf; f->getConnectedField(cf); nf->connectFrom(cf); } else if (f->isConnectedFromEngine()) { SoEngineOutput *eo; f->getConnectedEngine(eo); nf->connectFrom(eo); } } } // And if alternateRep is a group, copy over hidden // children: if (alternateRep->isOfType(SoGroup::getClassTypeId())) { SoGroup *g = (SoGroup *)alternateRep; for (int kid = 0; kid < hiddenChildren.getLength(); kid++) { g->addChild(hiddenChildren[kid]); } } addChild(alternateRep); return; } } }
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. }