void IfReplacer::replaceMaterials(SoNode *sceneRoot, const SoType &typeToReplace) { // Find all nodes of the given type SoSearchAction sa; sa.setType(typeToReplace); sa.setInterest(SoSearchAction::ALL); sa.apply(sceneRoot); // Replace the tail of each path with a material. To do this, we // need to apply an SoCallbackAction to the path to gather the // material components. for (int i = 0; i < sa.getPaths().getLength(); i++) { // Cast the path to a full path, just in case SoFullPath *path = (SoFullPath *) sa.getPaths()[i]; ASSERT(path->getTail()->isOfType(typeToReplace)); // The path better have at least one group above the material if (path->getLength() < 2 || ! path->getNodeFromTail(1)->isOfType(SoGroup::getClassTypeId())) continue; // Create a material node that represents the material in // effect at the tail of the path SoMaterial *newMaterial = createMaterialForPath(path); newMaterial->ref(); // Replace the tail node with that material SoGroup *parent = (SoGroup *) path->getNodeFromTail(1); parent->replaceChild(path->getTail(), newMaterial); newMaterial->unref(); } }
static SoCallbackAction::Response processNodesCB(void *userData, SoCallbackAction *ca, const SoNode *node) { #ifdef DEBUG cerr << "The node is of type " << node->getTypeId().getName().getString() << endl; #endif if (node->isOfType(SoShape::getClassTypeId())) { SbPList *data_list = (SbPList *) userData; OSUObjectData *data = new OSUObjectData; data_list->append((void *) data); data->shape = node->copy(); data->shape->ref(); SoVertexShape* vertShape = (SoVertexShape *)data->shape; SoState* state = ca->getState(); SoLazyElement* le = SoLazyElement::getInstance(state); le->print(stderr); int sIndex = 0; if (node->isOfType(SoVertexShape::getClassTypeId())) { #ifdef DEBUG cerr << " Found a Vertex Shape!\n"; #endif const SoCoordinateElement* ce; ce = SoCoordinateElement::getInstance(state); // If we don't start at 0 then why copy those vertices. // We could also check to see just how many points we use and // remove those as well, but that will take a bit more work. if (vertShape->isOfType(SoNonIndexedShape::getClassTypeId())){ sIndex = ((SoNonIndexedShape*)vertShape)->startIndex.getValue(); ((SoNonIndexedShape*)vertShape)->startIndex.setValue(0); } if (ce->is3D() ){ // It's 3D #ifdef DEBUG cerr << " There are " << ce->getNum() << " 3D coords\n"; #endif SoCoordinate3 *Ps = new SoCoordinate3; Ps->point.setValues(0, ce->getNum() - sIndex,&ce->get3(sIndex)); Ps->ref(); data->points = (SoNode *) Ps; } else { // It's 4D #ifdef DEBUG cerr << " There are " << ce->getNum() << " 4D coords\n"; #endif SoCoordinate4 *Ps = new SoCoordinate4; Ps->point.setValues(0, ce->getNum() - sIndex,&ce->get4(sIndex)); Ps->ref(); data->points = (SoNode *) Ps; } const SoNormalElement* ne = SoNormalElement::getInstance(state); SoNormalBinding::Binding nb = (SoNormalBinding::Binding)SoNormalBindingElement::get(state); int startNrmIndex = 0; if (ne != NULL && ne->getNum()>0){ // vp->normalBinding.setValue(nb); if (nb == SoNormalBinding::PER_VERTEX){ startNrmIndex = sIndex; } data->normals = new SoNormal; data->normals->ref(); data->normals->vector.setValues(0, (ne->getNum())-startNrmIndex, &ne->get(startNrmIndex)); } } // End vertex shapes // If there are texture coordinates in the state, //put them into the vertex property node. int startTxtIndex = 0; SoTextureCoordinateBinding::Binding tcb = (SoTextureCoordinateBinding::Binding) SoTextureCoordinateBindingElement::get(state); if (tcb == SoTextureCoordinateBinding::PER_VERTEX) startTxtIndex = sIndex; const SoTextureCoordinateElement* tce = SoTextureCoordinateElement::getInstance(state); if (tce->getType() == SoTextureCoordinateElement::EXPLICIT && (tce->getNum() > 0 )){ data->texture_points = new SoTextureCoordinate2; data->texture_points->ref(); data->texture_points->point.setValues(0, tce->getNum() - startTxtIndex, &tce->get2(startTxtIndex)); // vp->texCoord.setValues(0, tce->getNum() - startTxtIndex, // &tce->get2(startTxtIndex)); } SbVec2s size; int numcomponents, wrapS, wrapT, model; SbColor blendColor(0,0,0); const unsigned char *timage = SoTextureImageElement::get(state, size, numcomponents, wrapS, wrapT, model, blendColor); if (timage) { data->texture = new SoTexture2; data->texture->ref(); // data->texture->filename.setValue(tfilename); // data->texture->image.setValue(size, numcomponents, timage); timage = ca->getTextureImage(size, numcomponents); data->texture->image.setValue(size, numcomponents, timage); data->texture->wrapS = wrapS; data->texture->wrapT = wrapT; data->texture->model = model; data->texture->blendColor.setValue(blendColor); } data->complexity = new SoComplexity; data->complexity->ref(); data->complexity->value = ca->getComplexity(); data->complexity->type = ca->getComplexityType(); data->draw_style = new SoDrawStyle; data->draw_style->ref(); data->draw_style->style = ca->getDrawStyle(); data->draw_style->pointSize = ca->getPointSize(); data->draw_style->lineWidth = ca->getLineWidth(); data->draw_style->linePattern = ca->getLinePattern(); #ifdef DEBUG cerr << "The model matrix is " << ca->getModelMatrix() << endl; #endif SbMatrix const xm = ca->getModelMatrix(); data->transformation = new SoTransform; data->transformation->ref(); data->transformation->setMatrix(xm); SoMaterial *material = new SoMaterial; material->ref(); material->ambientColor = SoLazyElement::getAmbient(state); material->diffuseColor = SoLazyElement::getDiffuse(state, 0); material->specularColor = SoLazyElement::getSpecular(state); material->emissiveColor = SoLazyElement::getEmissive(state); material->shininess = SoLazyElement::getShininess(state); material->transparency = SoLazyElement::getTransparency(state, 0); data->material = material; } return SoCallbackAction::CONTINUE; }