/* * NodeIndexedFaceSet.cpp * * Copyright (C) 1999 Stephen F. White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file "COPYING" for details); if * not, write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. */ #include #include #include "stdafx.h" #include "NodeIndexedFaceSet.h" #include "Proto.h" #include "Scene.h" #include "FieldValue.h" #include "Node.h" #include "Mesh.h" #include "Face.h" #include "Vec3f.h" #include "NodeColor.h" #include "NodeCoordinate.h" #include "NodeNormal.h" #include "NodeTextureCoordinate.h" #include "NodeIndexedLineSet.h" ProtoIndexedFaceSet::ProtoIndexedFaceSet(Scene *scene) : Proto(scene, "IndexedFaceSet") { color.set( addExposedField(SFNODE, "color", new SFNode(NULL), NODE_COLOR)); coord.set( addExposedField(SFNODE, "coord", new SFNode(NULL), NODE_COORDINATE)); normal.set( addExposedField(SFNODE, "normal", new SFNode(NULL), NODE_NORMAL)); texCoord.set( addExposedField(SFNODE, "texCoord", new SFNode(NULL), TEXTURE_COORDINATE_NODE)); ccw.set( addField(SFBOOL, "ccw", new SFBool(true))); colorIndex.set( addField(MFINT32, "colorIndex", new MFInt32(), new SFInt32(-1))); colorPerVertex.set( addField(SFBOOL, "colorPerVertex", new SFBool(true))); convex.set( addField(SFBOOL, "convex", new SFBool(true))); coordIndex.set( addField(MFINT32, "coordIndex", new MFInt32(), new SFInt32(-1))); creaseAngle.set( addField(SFFLOAT, "creaseAngle", new SFFloat(0.0), new SFFloat(0.0f))); normalIndex.set( addField(MFINT32, "normalIndex", new MFInt32(), new SFInt32(-1))); normalPerVertex.set( addField(SFBOOL, "normalPerVertex", new SFBool(true))); solid.set( addField(SFBOOL, "solid", new SFBool(true))); texCoordIndex.set( addField(MFINT32, "texCoordIndex", new MFInt32(), new SFInt32(-1))); addEventIn(MFINT32, "set_colorIndex", 0, colorIndex); addEventIn(MFINT32, "set_coordIndex", 0, coordIndex); addEventIn(MFINT32, "set_normalIndex", 0, normalIndex); addEventIn(MFINT32, "set_texCoordIndex", 0, texCoordIndex); } Node * ProtoIndexedFaceSet::create(Scene *scene) { return new NodeIndexedFaceSet(scene, this); } NodeIndexedFaceSet::NodeIndexedFaceSet(Scene *scene, Proto *def) : MeshBasedNode(scene, def) { _mesh = NULL; _meshDirty = true; } NodeIndexedFaceSet::~NodeIndexedFaceSet() { delete _mesh; } void NodeIndexedFaceSet::setField(int index, FieldValue *value) { _meshDirty = true; Node::setField(index, value); } MFVec3f * NodeIndexedFaceSet::getCoordinates() { Node *ncoord = coord()->getValue(); if (ncoord == NULL) return NULL; else return ((NodeCoordinate *)ncoord)->point(); } MFInt32 * NodeIndexedFaceSet::getCoordIndex() { return coordIndex(); } MFInt32 * NodeIndexedFaceSet::getColorIndex() { return colorIndex(); } MFInt32 * NodeIndexedFaceSet::getNormalIndex() { return normalIndex(); } MFVec2f * NodeIndexedFaceSet::getTextureCoordinates() { Node *ntexCoord = texCoord()->getValue(); if (ntexCoord == NULL) return NULL; else return ((NodeTextureCoordinate *)ntexCoord)->point(); } MFInt32 * NodeIndexedFaceSet::getTexCoordIndex() { return texCoordIndex(); } void NodeIndexedFaceSet::createMesh() { Node *coord = ((SFNode *) getField(coord_Index(),true))->getValue(); // bool bcolorPerVertex = colorPerVertex()->getValue(); // bool bconvex = convex()->getValue(); MFInt32 *colorIndex = getColorIndex(); MFInt32 *coordIndex = getCoordIndex(); MFInt32 *normalIndex = getNormalIndex(); MFInt32 *texCoordIndex = getTexCoordIndex(); if (!coord || ((NodeCoordinate *) coord)->point()->getType() != MFVEC3F) return; MFVec3f *coords = ((NodeCoordinate *)coord)->point(); MFVec3f *normals = NULL; MFColor *colors = NULL; MFVec2f *texCoords = NULL; if (normal()->getValue()) if (normal()->getValue()->getType() == NODE_NORMAL) normals = ((NodeNormal *)(normal()->getValue()))->vector(); if (color()->getValue()) if (color()->getValue()->getType() == NODE_COLOR) colors = ((NodeColor *)(color()->getValue()))->color(); if (texCoord()->getValue()) if (texCoord()->getValue()->getType() == NODE_TEXTURE_COORDINATE) texCoords = ((NodeTextureCoordinate *)(texCoord()->getValue())) ->point(); if (colorIndex->getSize() != coordIndex->getSize()) { colorIndex = coordIndex; } if (texCoordIndex->getSize() != coordIndex->getSize()) { texCoordIndex = coordIndex; } if (!texCoord()->getValue()) { texCoords = generateTextureCoordinates(coords, texCoordIndex); } if (normalIndex->getSize() != coordIndex->getSize()) { normalIndex = coordIndex; } int meshFlags = 0; if (ccw()->getValue()) meshFlags |= MESH_CCW; if (solid()->getValue()) meshFlags |= MESH_SOLID; if (convex()->getValue()) meshFlags |= MESH_CONVEX; if (normalPerVertex()->getValue()) meshFlags |= MESH_NORMAL_PER_VERTEX; if (_mesh) delete _mesh; _mesh = new Mesh(coords, coordIndex, normals, normalIndex, colors, colorIndex, texCoords, texCoordIndex, creaseAngle()->getValue(), meshFlags); } MFVec3f * NodeIndexedFaceSet::getSmoothNormals(void) { if (_mesh == NULL) return NULL; MFVec3f *v = _mesh->getNormals(); if (v != NULL) { v = new MFVec3f((float *)((MFVec3f *)v->copy())->getValues(), v->getSize()); } return v; } MFInt32 * NodeIndexedFaceSet::getSmoothNormalIndex(void) { if (_mesh == NULL) return NULL; MFInt32 *i = _mesh->getNormalIndex(); if (i != NULL) { i = new MFInt32((int *)((MFInt32 *)i->copy())->getValues(), i->getSize()); } return i; } Node * NodeIndexedFaceSet::toIndexedLineSet(void) { if (_mesh == NULL) return NULL; NodeCoordinate *ncoord = (NodeCoordinate *)_scene->createNode("Coordinate"); ncoord->point(new MFVec3f(*(_mesh->getVertices()))); NodeIndexedLineSet *node = (NodeIndexedLineSet *) _scene->createNode("IndexedLineSet"); node->coord(new SFNode(ncoord)); node->coordIndex(new MFInt32(*(_mesh->getCoordIndex()))); return node; } void NodeIndexedFaceSet::flip(int index) { NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue(); if (ncoord) if (ncoord->getType() == NODE_COORDINATE) { MFVec3f *coords = ncoord->point(); if (coords != NULL) coords->flip(index); } NodeNormal *nnormal = (NodeNormal *)normal()->getValue(); if (nnormal) if (nnormal->getType() == NODE_NORMAL) { MFVec3f *normals = nnormal->vector(); if (normals != NULL) normals->flip(index); } SFBool *bccw = new SFBool(!(ccw()->getValue())); ccw(bccw); _meshDirty = true; }