const EdgeIterator &EdgeIterator::operator++() { // already at end? if(isAtEnd()) return *this; ++_edgeIndex; // at end of primitive? if(_actPrimIndex >= PrimitiveIterator::getLength() || getType() == GL_LINE_STRIP || getType() == GL_LINE_LOOP ) // TODO: add GL_POLYLINE here ?!?! { ++(static_cast<PrimitiveIterator&>(*this)); startPrim(); return *this; } switch(getType()) { case GL_LINES: _edgePntIndex[0] = _actPrimIndex++; _edgePntIndex[1] = _actPrimIndex++; break; #if 0 // probably to be implemented case GL_POLYGON: TODO break; case GL_TRIANGLES: TODO break; case GL_QUAD_STRIP: TODO break; case GL_TRIANGLE_STRIP: TODO break; case GL_TRIANGLE_FAN: TODO break; case GL_QUADS: TODO break; #endif // probably to be implemented default: SWARNING << "EdgeIterator::++: encountered " << "unknown primitive type " << getType() << ", ignoring!" << std::endl; startPrim(); break; } return *this; }
/*! Set the iterator to the beginning of the geometry. Is primarily used by OSG::Geometry::beginFaces, but can also be used to quickly recycle an iterator. */ void FaceIterator::setToBegin(void) { PrimitiveIterator::setToBegin(); _faceIndex = 0; startPrim(); }
/*! The increment operator steps the iterator to the next face. If it is already beyond the last face it does not change. \dev This is the central function of the whole iterator. It changes _facePntIndex to contain the data for the next face, depending on the type of the currently active primitive and steps to the next primitive if the current one is exhausted. The only tricky part is the left/right swap for triangle strips, the rest is pretty simple. \enddev */ void FaceIterator::operator++() { // already at end? if(isAtEnd()) return; ++_faceIndex; // at end of primitive? if(_actPrimIndex >= PrimitiveIterator::getLength()) { ++(static_cast<PrimitiveIterator&>(*this)); startPrim(); return; } switch(getType()) { case GL_TRIANGLES: _facePntIndex[0] = _actPrimIndex++; _facePntIndex[1] = _actPrimIndex++; _facePntIndex[2] = _actPrimIndex++; _facePntIndex[3] = -1; break; case GL_QUAD_STRIP: _facePntIndex[0] = _facePntIndex[3]; _facePntIndex[1] = _facePntIndex[2]; _facePntIndex[3] = _actPrimIndex++; _facePntIndex[2] = _actPrimIndex++; break; case GL_TRIANGLE_STRIP: if(_actPrimIndex & 1) { _facePntIndex[0] = _facePntIndex[2]; } else { _facePntIndex[1] = _facePntIndex[2]; } _facePntIndex[2] = _actPrimIndex++; if(getPositionIndex(0) == getPositionIndex(1) || getPositionIndex(0) == getPositionIndex(2) || getPositionIndex(1) == getPositionIndex(2)) { --_faceIndex; ++(*this); } break; case GL_POLYGON: case GL_TRIANGLE_FAN: _facePntIndex[1] = _facePntIndex[2]; _facePntIndex[2] = _actPrimIndex++; break; case GL_QUADS: _facePntIndex[0] = _actPrimIndex++; _facePntIndex[1] = _actPrimIndex++; _facePntIndex[2] = _actPrimIndex++; _facePntIndex[3] = _actPrimIndex++; break; default: SWARNING << "FaceIterator::++: encountered " << "unknown primitive type " << getType() << ", ignoring!" << std::endl; startPrim(); break; } }
/*! Set the iterator to the beginning of the geometry. Is primarily used by OSG::Geometry::beginEdges, but can also be used to quickly recycle an iterator. */ void EdgeIterator::setToBegin(void) { PrimitiveIterator::setToBegin(); _edgeIndex = 0; startPrim(); }