void FaceSpatializeIndexed<BasicTraits>::CategoryRaw::addData (OpenSGFaceBase<OpenSGTraits>* node, const FaceIterator& face)
{
   GeoPositions3f::StoredFieldType*  p = m_coord->getFieldPtr();
   GeoNormals3f::StoredFieldType*    n = m_normal->getFieldPtr();
   //GeoIndicesUI32::StoredFieldType*  i = m_index->getFieldPtr();

   // find offset of positions and normals in the new geometry
   u32 i, k;
   m_offsetIt = m_offset.find(face.getGeometry());
   if (m_offsetIt == m_offset.end()) {
      // insert new offsets entry into map
      HashMapPair offsetPair = 
	m_offset.insert(HashMap::value_type(face.getGeometry(), quad()));
      m_offsetIt = offsetPair.first;

      m_offsetIt->second.position = m_coord->size();
      GeoPositionsPtr faceP = m_original.getPositions();
      addRefCP(faceP);
      for (k=0; k<faceP->getSize(); ++k) {
	 p->addValue(faceP->getValue(k));
      }
      if (m_hasNormal) {
 	 m_offsetIt->second.normal = m_normal->size();
	 GeoNormalsPtr faceN = m_original.getNormals();
	 addRefCP(faceN);
	 for (k=0; k<faceN->getSize(); ++k) {
	    n->addValue(faceN->getValue(k));
	 }
	 subRefCP(faceN);
      }
      subRefCP(faceP);
   }

   // insert indices
   if (face.getLength() == 3) {
      for (k=0; k<3; ++k) {
	 m_index->insertValue(face.getPositionIndex(k)+m_offsetIt->second.position, m_quadOffset++);
	 i = 1;
	 if (m_hasNormal) {
	    m_index->insertValue(face.getNormalIndex(k)+m_offsetIt->second.normal,     m_quadOffset++);
	    ++i;
	 }
	 for (; i<m_indexStride; ++i) {
	    m_index->insertValue(0, m_quadOffset++);
	 }
      }
   } else {
      for (k=0; k<4; ++k) {
	 m_index->addValue(face.getPositionIndex(k)+m_offsetIt->second.position);
	 i = 1;
	 if (m_hasNormal) {
	    m_index->addValue(face.getNormalIndex(k)+m_offsetIt->second.normal);
	    ++i;
	 }
	 for (; i<m_indexStride; ++i) {
	    m_index->addValue(0);
	 }
      }
   }
}
void FaceSpatializeIndexed<BasicTraits>::Category::addData (OpenSGFaceBase<OpenSGTraits>* arg)
{
   FaceIterator face = arg->getOriginal();
   if (
       face.getGeometry()->getMaterial()->isTransparent() // transparent face
       && m_trans.find(arg->getObjectAdapter().getNode()) != m_trans.end() // not processed
       ) { 
      // create object adapter
      OSGObjectBase convert(arg->getObjectAdapter().getNode());
      convert.setObjectAdapter(&arg->getObjectAdapter());
      NodePtr             newNode = Node::create();
      m_trans[convert.getOriginal()] = newNode;
      GeometryPtr         oldCore = GeometryPtr::dcast(convert.getOriginal()->getCore());
      GeometryPtr         newCore = oldCore->clone();
      beginEditCP(newNode);
      newNode->setCore(newCore);
      endEditCP(newNode);
      beginEditCP(newCore);
      newCore->setPositions(convert.getPositions());
      newCore->setNormals  (convert.getNormals());
      endEditCP(newCore);

      beginEditCP(m_root);
      m_root->addChild(newNode);
      endEditCP(m_root);

      return;
   }
   ++m_totalFaces;

   typename CategoryList::iterator c;
   for (c = m_all.begin();
	c != m_all.end();
	++c) {
      if ((*c)->isThisCategory(face)) {
         break;
      }
   }
   if (c == m_all.end()) { // new category
#if 0
      MaterialGroupPtr mat = MaterialGroup::create();
      beginEditCP(mat);
      mat->setMaterial(face.getGeometry()->getMaterial());
      endEditCP(mat);
      NodePtr matNode = Node::create();
      beginEditCP(matNode);
      matNode->setCore(mat);
      endEditCP(matNode);
      beginEditCP(m_root);
      m_root->addChild(matNode);
      endEditCP(m_root);
      c = m_all.insert(m_all.end(), new CategoryGeneral(matNode, arg, face));
#else
      c = m_all.insert(m_all.end(), new CategoryGeneral(m_root, arg, face));
#endif
      ++m_numGeom;
   }
   (*c)->addData(arg, face);
}
void FaceSpatialize<BasicTraits>::CategoryRaw::begin (const FaceIterator& face)
{
   m_coord  = GeoPositions3f::create();
   m_index  = GeoIndicesUI32::create();	
   m_len    = GeoPLengthsUI32::create();	
   m_type   = GeoPTypesUI8::create();	
   // store material of this geometry
   m_material = face.getGeometry()->getMaterial();
   // create geometry node
   m_node = Node::create();
   m_geom = Geometry::create();
   beginEditCP(m_node);
   m_node->setCore(m_geom);
   endEditCP(m_node);
   // assign geometry fields
   beginEditCP(m_geom);
   m_geom->setMaterial(m_material);
   m_geom->setPositions(m_coord);
   {
   //if (m_hasNormal) {
      m_normal = GeoNormals3f::create();
      m_geom->setNormals(m_normal);
   }
   m_geom->setIndices(m_index);
   m_geom->setTypes(m_type);
   m_geom->setLengths(m_len);
   endEditCP(m_geom);
   // edit geometry field contents
   beginEditCP(m_coord);
   beginEditCP(m_normal);
   beginEditCP(m_index);
   beginEditCP(m_type);
   beginEditCP(m_len);
   // store face type of this geometry
   //m_faceLength = face.getLength();
   GeoPTypesUI8::StoredFieldType* t = m_type->getFieldPtr();
   //t->addValue((m_faceLength==3 ? GL_TRIANGLES : GL_QUADS));
   t->addValue(GL_TRIANGLES); t->addValue(GL_QUADS);
   m_quadOffset = 0;
}
void FaceSpatializeIndexed<BasicTraits>::CategoryRaw::begin (OpenSGFaceBase<OpenSGTraits>* node, const FaceIterator& face)
{
   m_coord  = GeoPositions3f::create();
   m_index  = GeoIndicesUI32::create();	
   m_len    = GeoPLengthsUI32::create();	
   m_type   = GeoPTypesUI8::create();	
   // store material of this geometry
   m_material = face.getGeometry()->getMaterial();
   // create geometry node
   m_node = Node::create();
   m_geom = Geometry::create();
   beginEditCP(m_node);
   m_node->setCore(m_geom);
   endEditCP(m_node);
   // assign geometry fields
   beginEditCP(m_geom);
   m_geom->setMaterial(m_material);
   m_geom->setPositions(m_coord);
   m_indexStride = 1;
   m_indexOffset.position = 0;
   m_geom->getIndexMapping().addValue(Geometry::MapPosition);
   if (m_hasNormal) {
      m_normal = GeoNormals3f::create();
      m_geom->setNormals(m_normal);
      m_geom->getIndexMapping().addValue(Geometry::MapNormal);
      m_indexOffset.normal = m_indexOffset.position+1;
      ++m_indexStride;
   } else {
      m_indexOffset.normal = m_indexOffset.position;
   }
   if (m_hasColor) { 
      m_geom->getIndexMapping().addValue(Geometry::MapColor);
      m_indexOffset.color = m_indexOffset.normal+1;
      ++m_indexStride; 
   } else {
      m_indexOffset.color = m_indexOffset.normal;
   }
   if (m_hasTex) {
      m_geom->getIndexMapping().addValue(Geometry::MapTexCoords);
      m_indexOffset.tex1 = m_indexOffset.color+1;
      ++m_indexStride; 
   } else {
      m_indexOffset.tex1 = m_indexOffset.color;
   }
   m_geom->setIndices(m_index);
   m_geom->setTypes(m_type);
   m_geom->setLengths(m_len);
   endEditCP(m_geom);
   // edit geometry field contents
   beginEditCP(m_coord);
   beginEditCP(m_normal);
   beginEditCP(m_index);
   beginEditCP(m_type);
   beginEditCP(m_len);
   // store face type of this geometry
   //m_faceLength = face.getLength();
   GeoPTypesUI8::StoredFieldType* t = m_type->getFieldPtr();
   //t->addValue((m_faceLength==3 ? GL_TRIANGLES : GL_QUADS));
   t->addValue(GL_TRIANGLES); t->addValue(GL_QUADS);
   m_quadOffset = 0;
}