// // Vrml 97 library // Copyright (C) 1998 Chris Morley // // %W% %G% // VrmlNodeIFaceSet.cpp #include "VrmlNodeIFaceSet.h" #include "VrmlNodeType.h" #include "VrmlNodeColor.h" #include "VrmlNodeCoordinate.h" #include "VrmlNodeNormal.h" #include "VrmlNodeTextureCoordinate.h" #include "Viewer.h" static VrmlNode *creator( VrmlScene *s ) { return new VrmlNodeIFaceSet(s); } // Define the built in VrmlNodeType:: "IndexedFaceSet" fields VrmlNodeType *VrmlNodeIFaceSet::defineType(VrmlNodeType *t) { static VrmlNodeType *st = 0; if (! t) { if (st) return st; t = st = new VrmlNodeType("IndexedFaceSet", creator); } VrmlNodeIndexedSet::defineType(t); // Parent class t->addEventIn("set_normalIndex", VrmlField::MFINT32); t->addEventIn("set_texCoordIndex", VrmlField::MFINT32); t->addExposedField("normal", VrmlField::SFNODE); t->addExposedField("texCoord", VrmlField::SFNODE); t->addField("ccw", VrmlField::SFBOOL); t->addField("convex", VrmlField::SFBOOL); t->addField("creaseAngle", VrmlField::SFFLOAT); t->addField("normalIndex", VrmlField::MFINT32); t->addField("normalPerVertex", VrmlField::SFBOOL); t->addField("solid", VrmlField::SFBOOL); t->addField("texCoordIndex", VrmlField::MFINT32); return t; } VrmlNodeType *VrmlNodeIFaceSet::nodeType() const { return defineType(0); } VrmlNodeIFaceSet::VrmlNodeIFaceSet(VrmlScene *scene) : VrmlNodeIndexedSet(scene), d_ccw(true), d_convex(true), d_creaseAngle(0.0), d_normalPerVertex(true), d_solid(true) { } VrmlNodeIFaceSet::~VrmlNodeIFaceSet() { } VrmlNode *VrmlNodeIFaceSet::cloneMe() const { return new VrmlNodeIFaceSet(*this); } void VrmlNodeIFaceSet::cloneChildren(VrmlNamespace* ns) { if (d_color.get()) d_color.set(d_color.get()->clone(ns)); if (d_coord.get()) d_coord.set(d_coord.get()->clone(ns)); if (d_normal.get()) d_normal.set(d_normal.get()->clone(ns)); if (d_texCoord.get()) d_texCoord.set(d_texCoord.get()->clone(ns)); } bool VrmlNodeIFaceSet::isModified() const { return ( d_modified || (d_color.get() && d_color.get()->isModified()) || (d_coord.get() && d_coord.get()->isModified()) || (d_normal.get() && d_normal.get()->isModified()) || (d_texCoord.get() && d_texCoord.get()->isModified()) ); } void VrmlNodeIFaceSet::clearFlags() { VrmlNode::clearFlags(); if (d_color.get()) d_color.get()->clearFlags(); if (d_coord.get()) d_coord.get()->clearFlags(); if (d_normal.get()) d_normal.get()->clearFlags(); if (d_texCoord.get()) d_texCoord.get()->clearFlags(); } void VrmlNodeIFaceSet::addToScene( VrmlScene *s, const char *rel ) { d_scene = s; if (d_color.get()) d_color.get()->addToScene(s, rel); if (d_coord.get()) d_coord.get()->addToScene(s, rel); if (d_normal.get()) d_normal.get()->addToScene(s, rel); if (d_texCoord.get()) d_texCoord.get()->addToScene(s, rel); } void VrmlNodeIFaceSet::copyRoutes( VrmlNamespace *ns ) const { VrmlNode::copyRoutes(ns); if (d_color.get()) d_color.get()->copyRoutes(ns); if (d_coord.get()) d_coord.get()->copyRoutes(ns); if (d_normal.get()) d_normal.get()->copyRoutes(ns); if (d_texCoord.get()) d_texCoord.get()->copyRoutes(ns); } ostream& VrmlNodeIFaceSet::printFields(ostream& os, int indent) { if (! d_ccw.get()) PRINT_FIELD(ccw); if (! d_convex.get()) PRINT_FIELD(convex); if (! d_normalPerVertex.get()) PRINT_FIELD(normalPerVertex); if (! d_solid.get()) PRINT_FIELD(solid); if (d_creaseAngle.get() != 0.0) PRINT_FIELD(creaseAngle); if (d_normal.get()) PRINT_FIELD(normal); if (d_normalIndex.size() > 0) PRINT_FIELD(normalIndex); if (d_texCoord.get()) PRINT_FIELD(texCoord); if (d_texCoordIndex.size() > 0) PRINT_FIELD(texCoordIndex); VrmlNodeIndexedSet::printFields(os, indent); return os; } // TO DO: stripify, crease angle, generate normals ... Viewer::Object VrmlNodeIFaceSet::insertGeometry(Viewer *viewer) { Viewer::Object obj = 0; if (d_coord.get() && d_coordIndex.size() > 0) { VrmlMFVec3f &coord = d_coord.get()->toCoordinate()->coordinate(); int nvert = coord.size(); float *tc = 0, *color = 0, *normal = 0; int ntc = 0; int ntci = 0, *tci = 0; // texture coordinate indices int nci = 0, *ci = 0; // color indices int nni = 0, *ni = 0; // normal indices // Get texture coordinates and texCoordIndex if (d_texCoord.get()) { VrmlMFVec2f &texcoord = d_texCoord.get()->toTextureCoordinate()->coordinate(); tc = &texcoord[0][0]; ntc = texcoord.size(); ntci = d_texCoordIndex.size(); if (ntci) tci = d_texCoordIndex.get(); } // check #tc is consistent with #coords/max texCoordIndex... if (tci && ntci < d_coordIndex.size()) { theSystem->error("IndexedFaceSet: not enough texCoordIndex values (there should be at least as many as coordIndex values).\n"); theSystem->error("IndexedFaceSet: #coord %d, #coordIndex %d, #texCoord %d, #texCoordIndex %d\n", nvert, d_coordIndex.size(), ntc, ntci); tci = 0; ntci = 0; } // check #colors is consistent with colorPerVtx, colorIndex... if (d_color.get()) { VrmlMFColor &c = d_color.get()->toColor()->color(); color = &c[0][0]; nci = d_colorIndex.size(); if (nci) ci = d_colorIndex.get(); } // check #normals is consistent with normalPerVtx, normalIndex... if (d_normal.get()) { VrmlMFVec3f &n = d_normal.get()->toNormal()->normal(); normal = &n[0][0]; nni = d_normalIndex.size(); if (nni) ni = d_normalIndex.get(); } unsigned int optMask = 0; if (d_ccw.get()) optMask |= Viewer::MASK_CCW; if (d_convex.get()) optMask |= Viewer::MASK_CONVEX; if (d_solid.get()) optMask |= Viewer::MASK_SOLID; if (d_colorPerVertex.get()) optMask |= Viewer::MASK_COLOR_PER_VERTEX; if (d_normalPerVertex.get()) optMask |= Viewer::MASK_NORMAL_PER_VERTEX; obj = viewer->insertShell(optMask, nvert, &coord[0][0], d_coordIndex.size(), &d_coordIndex[0], tc, ntci, tci, normal, nni, ni, color, nci, ci); } if (d_color.get()) d_color.get()->clearModified(); if (d_coord.get()) d_coord.get()->clearModified(); if (d_normal.get()) d_normal.get()->clearModified(); if (d_texCoord.get()) d_texCoord.get()->clearModified(); return obj; } // Set the value of one of the node fields. void VrmlNodeIFaceSet::setField(const char *fieldName, const VrmlField &fieldValue) { if TRY_FIELD(ccw, SFBool) else if TRY_FIELD(convex, SFBool) else if TRY_FIELD(creaseAngle, SFFloat) else if TRY_SFNODE_FIELD(normal, Normal) else if TRY_FIELD(normalIndex, MFInt) else if TRY_FIELD(normalPerVertex, SFBool) else if TRY_FIELD(solid, SFBool) else if TRY_FIELD(normalIndex, MFInt) else if TRY_SFNODE_FIELD(texCoord, TextureCoordinate) else if TRY_FIELD(texCoordIndex, MFInt) else VrmlNodeIndexedSet::setField(fieldName, fieldValue); } VrmlNode* VrmlNodeIFaceSet::getNormal() { return d_normal.get(); } const VrmlMFInt& VrmlNodeIFaceSet::getNormalIndex() const { return d_normalIndex; } VrmlNode* VrmlNodeIFaceSet::getTexCoord() { return d_texCoord.get(); } const VrmlMFInt& VrmlNodeIFaceSet::getTexCoordIndex() const { return d_texCoordIndex; } VrmlNodeIFaceSet* VrmlNodeIFaceSet::toIFaceSet() const { return (VrmlNodeIFaceSet*) this; }