void FaceSpatializeIndexed<BasicTraits>::CategoryGeneral::addData (OpenSGFaceBase<OpenSGTraits>* node, const FaceIterator& face) { u32 offsetSize = m_offset.size(); CategoryColor::addData(node, face); if (m_hasTex) { if (offsetSize < m_offset.size()) { m_offsetIt->second.tex1 = m_texCoord->size(); GeoTexCoords2f::StoredFieldType* t = m_texCoord->getFieldPtr(); GeoTexCoordsPtr faceT = m_original.getTexCoords(); for (u32 k=0; k<faceT->getSize(); ++k) { t->addValue(faceT->getValue(k)); } } // set indices for TexCoords if (face.getLength() == 3) { u32 i = m_quadOffset - 3*m_indexStride + m_indexOffset.tex1; for (u32 k=0; k<3; ++k) { m_index->setValue(face.getTexCoordsIndex(k)+m_offsetIt->second.tex1, i); assert(face.getTexCoordsIndex(k)+m_offsetIt->second.tex1 < m_texCoord->size()); i += m_indexStride; } } else { u32 i = m_index->size() - 4*m_indexStride + m_indexOffset.tex1; for (u32 k=0; k<4; ++k) { m_index->setValue(face.getTexCoordsIndex(k)+m_offsetIt->second.tex1, i); assert(face.getTexCoordsIndex(k)+m_offsetIt->second.tex1 < m_texCoord->size()); i += m_indexStride; } } } }
void FaceSpatializeIndexed<BasicTraits>::CategoryColor::addData (OpenSGFaceBase<OpenSGTraits>* node, const FaceIterator& face) { u32 offsetSize = m_offset.size(); CategoryRaw::addData(node, face); if (m_hasColor) { if (offsetSize < m_offset.size()) { m_offsetIt->second.color = m_color->size(); GeoColors3f::StoredFieldType* c = m_color->getFieldPtr(); GeoColorsPtr faceC = m_original.getColors(); for (u32 k=0; k<faceC->getSize(); ++k) { c->addValue(faceC->getValue(k)); } } // set indices for colors if (face.getLength() == 3) { u32 i = m_quadOffset - 3*m_indexStride + m_indexOffset.color; for (u32 k=0; k<3; ++k) { m_index->setValue(face.getColorIndex(k)+m_offsetIt->second.color, i); assert(face.getColorIndex(k)+m_offsetIt->second.color < m_color->size()); i += m_indexStride; } } else { u32 i = m_index->size() - 4*m_indexStride + m_indexOffset.color; for (u32 k=0; k<4; ++k) { m_index->setValue(face.getColorIndex(k)+m_offsetIt->second.color, i); assert(face.getColorIndex(k)+m_offsetIt->second.color < m_color->size()); i += m_indexStride; } } } }
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 FaceSpatialize<BasicTraits>::CategoryGeneral::addData (OpenSGFaceBase<OpenSGTraits>* node, const FaceIterator& face) { CategoryColor::addData(node, face); if (m_hasTex) { GeoTexCoords2f::StoredFieldType* t = m_texCoord->getFieldPtr(); for (u32 k=0; k<face.getLength(); ++k) { t->addValue(face.getTexCoords(k)); } assert(m_coord->getSize() == m_texCoord->getSize()); } }
void FaceSpatialize<BasicTraits>::CategoryColor::addData (OpenSGFaceBase<OpenSGTraits>* node, const FaceIterator& face) { CategoryRaw::addData(node, face); if (m_hasColor) { GeoColors3f::StoredFieldType* c = m_color->getFieldPtr(); for (u32 k=0; k<face.getLength(); ++k) { c->addValue(face.getColor(k)); } assert(m_coord->getSize() == m_color->getSize()); } }
void FaceSpatialize<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(); GeoPositionsPtr faceP = node->getPositions(); addRefCP(faceP); u32 k; for (k=0; k<faceP->getSize(); ++k) { p->addValue(faceP->getValue(k)); if (face.getLength()==3) { m_index->insertValue(p->size()-1, m_quadOffset++); } else { m_index->addValue(p->size()-1); } } if (!m_hasNormal) { #if 1 Vec3f p0(faceP->getValue(0)); Vec3f p1(faceP->getValue(1)); Vec3f p2(faceP->getValue(2)); p2 -= p1; p0 -= p1; if (m_ccw) { p0.crossThis(p2); p0.normalize(); n->addValue(p0); } else { p2.crossThis(p0); p2.normalize(); n->addValue(p2); } #endif } else { // per-vertex normals or per-face normals GeoNormalsPtr faceN = node->getNormals(); addRefCP(faceN); for (k=0; k<faceN->getSize(); ++k) { n->addValue(faceN->getValue(k)); } subRefCP(faceN); } subRefCP(faceP); }
/* Aufruf dieser Funktion erfolgt bei Traversierung des Szenengraphen mittels OpenSG-Funktion traverse(). Enthaelt ein Knoten verwertbare Geometrieinformation so tragen wir Zeiger auf seine Geometrie (OpenSG-Strukturen) im array gla_meshInfo_ ein. Nebenbei bestimmen wir für die Geometrie auch noch die World-Space- Transformation (evtl. existiert eine OpenSG-Funktion um diese Information zu erhalten, der Autor hat keine in der OpenSG-API entdeckt). */ Action::ResultE enter(NodePtr &node) { int i, j, h; Pnt3f v; int numFaces, numFaceVertices, vId, size; MeshInfo meshInfo; TinyMatrix transf; FaceIterator fit; int numQuads; NamePtr namePtr; char name[255]; namePtr = NamePtr::dcast(node->findAttachment(Name::getClassType().getGroupId())); if(namePtr == osg::NullFC) strcpy(name, ""); else { strcpy(name, namePtr->getFieldPtr()->getValue().c_str()); } SINFO << "Node name = '" << name << "'" << endl << endLog; GeometryPtr geo = GeometryPtr::dcast(node->getCore()); if(geo != NullFC) { GeoPLengthsUI32Ptr pLength = GeoPLengthsUI32Ptr::dcast(geo->getLengths()); GeoPTypesUI8Ptr pTypes = GeoPTypesUI8Ptr::dcast(geo->getTypes()); /* pLength and pTypes should not be NullFC, however VRML Importer/Exporter code is instable by now, so this can happen */ if((pLength != NullFC) && (pTypes != NullFC)) { GeoPLengthsUI32::StoredFieldType * pLengthField = pLength->getFieldPtr(); GeoPTypesUI8::StoredFieldType * pTypeField = pTypes->getFieldPtr(); size = pLengthField->size(); for(h = 0; h < size; h++) { if(((*pTypeField)[h] == GL_TRIANGLES) || ((*pTypeField)[h] == GL_QUADS)) { /* may quads appear in GL_TRIANGLES ? */ /* check if all triangles have three vertices */ numQuads = 0; fit = geo->beginFaces(); while(fit != geo->endFaces()) { numFaceVertices = fit.getLength(); if(numFaceVertices == 4) numQuads++; if(numFaceVertices > 4) { SWARNING << "More than 4 vertices in face!" << endl << endLog; return Action::Continue; // exit(1); } ++fit; } if(numQuads > 0) { SWARNING << "Quad encountered" << endl << endLog; } if(gl_sga->nodeDepth_ > 0) { for(i = 0; i < gl_sga->nodeDepth_; i++) { meshInfo.transf = meshInfo.transf * gl_sga->transf_[i]; } } else meshInfo.transf.identity(); /* access to vertices */ GeoPositions3fPtr pPos = GeoPositions3fPtr::dcast(geo->getPositions()); GeoPositions3f::StoredFieldType * pPosField = pPos->getFieldPtr(); /* access to faces */ numFaces = 0; fit = geo->beginFaces(); for(fit = geo->beginFaces(); fit != geo->endFaces(); ++fit) { numFaceVertices = fit.getLength(); for(j = 0; j < numFaceVertices; j++) { vId = fit.getPositionIndex(j); } numFaces++; } /* for fit */ /* set other mesh attributes */ meshInfo.numQuads = numQuads; meshInfo.geoPtr = geo; meshInfo.vPtr = pPosField; meshInfo.triangularFaces = (numQuads == 0); meshInfo.numVertices = pPosField->size(); meshInfo.numFaces = numFaces; gl_sga->meshInfo_.push_back(meshInfo); gl_sga->numGeometryNodes_++; } else { // SWARNING << "Neither triangle nor quad. Field type = " << // (*pTypeField)[h] << endl << endLog; } } /* for h */ } /* if pLength!=NullFC */ } else if(node->getCore()->getType().isDerivedFrom(Transform::getClassType())) { TransformPtr t = TransformPtr::dcast(node->getCore()); Matrix ma; ma = t->getMatrix(); SINFO << "Node type derived from transform, skipping children" << endl << endLog; for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { transf[i][j] = ma[j][i]; /* the matrix is stored as columns/rows ? */ } } if(gl_sga->nodeDepth_ > gl_sga->maxNodeDepth_) { gl_sga->maxNodeDepth_ = gl_sga->nodeDepth_; gl_sga->transf_.push_back(transf); } else { gl_sga->transf_[gl_sga->nodeDepth_] = transf; } gl_sga->nodeDepth_++; } return Action::Continue; }
/* Konvertierung des mit meshId bezeichneten IndexedFaceSets in ein Mesh vom Typ TriangleSet. Zu beachten: IndexedFaceSets, die Eckpunkte "shared", werden beim Parsen des Szenengraphen (Konstruktor) zu einem Teilmesh zusammengefasst (erhalten dieselbe ID). Bei der Konvertierung wird aus diesen ein Mesh generiert. */ int WmSceneGraphAccess::convertToTs(TriangleSet *ts, int *numQuadsFound, GEOMARK_BitArray **isQuadVertex, int meshId) { int i, j, k; int offsetVertices, numVertices, numFaces, numFaceVertices; int to, from; TinyVector v; FaceIterator fit; int trVIds[3], quadVIds[4]; GeometryPtr geoPtr; BOOL quadsPresent; int numQuads; if(numMeshes_ < 1) return -1; offsetVertices = 0; *isQuadVertex = NULL; quadsPresent = FALSE; numQuads = 0; if(meshId == -1) { /* generate single flat mesh */ /* first pass */ SINFO << "Generating single flat mesh" << endl << endLog; numVertices = 0; numFaces = 0; numQuads = 0; for(i = 0; i < numGeometryNodes_; i++) { if((i == 0) || (meshInfo_[i].meshId != meshInfo_[i - 1].meshId)) { numVertices += meshInfo_[i].numVertices; SINFO << "mesh id = " << meshInfo_[i].meshId << endl << "# of vertices = " << meshInfo_[i].numVertices << endl << endLog; } numFaces += meshInfo_[i].numFaces; numQuads += meshInfo_[i].numQuads; if((!quadsPresent) && (meshInfo_[i].numQuads > 0)) quadsPresent = TRUE; } if(quadsPresent) { *isQuadVertex = new GEOMARK_BitArray(numVertices); numFaces += numQuads; } SINFO << "# of faces = " << numFaces << endl << endLog; ts->init(numVertices, numFaces); /* second pass */ numVertices = 0; numFaces = 0; for(i = 0; i < numGeometryNodes_; i++) { if((i > 0) && (meshInfo_[i].meshId != meshInfo_[i - 1].meshId)) { offsetVertices += meshInfo_[i - 1].numVertices; } if((i == 0) || (meshInfo_[i].meshId != meshInfo_[i - 1].meshId)) { /* set vertex data */ for(j = 0; j < meshInfo_[i].vPtr->size(); j++) { v[0] = (*meshInfo_[i].vPtr)[j][0]; v[1] = (*meshInfo_[i].vPtr)[j][1]; v[2] = (*meshInfo_[i].vPtr)[j][2]; /* transformation does matter for case of single flat mesh */ v = meshInfo_[i].transf * v; /* transform into world space */ ts->setVertex(offsetVertices + j, v); } numVertices += meshInfo_[i].numVertices; } /* set face data */ geoPtr = meshInfo_[i].geoPtr; for(fit = geoPtr->beginFaces(); fit != geoPtr->endFaces(); ++fit) { /* this should be always 3 */ numFaceVertices = fit.getLength(); if(numFaceVertices == 4) { for(j = 0; j < 4; j++) { quadVIds[j] = fit.getPositionIndex(j); (*isQuadVertex)->setBit(quadVIds[j], 1); } /* split quad into two triangles */ ts->setFace(numFaces, offsetVertices + quadVIds[0], offsetVertices + quadVIds[1], offsetVertices + quadVIds[2]); numFaces++; ts->setFace(numFaces, offsetVertices + quadVIds[2], offsetVertices + quadVIds[3], offsetVertices + quadVIds[0]); numFaces++; } else { if(numFaceVertices != 3) { printf("numFaceVertices=%d\n", numFaceVertices); // exit(1); return -1; } for(j = 0; j < 3; j++) { trVIds[j] = fit.getPositionIndex(j); } ts->setFace(numFaces, offsetVertices + trVIds[0], offsetVertices + trVIds[1], offsetVertices + trVIds[2]); numFaces++; } } /* for fit */ } /* for i */ ts->meshComplete(); } else { /* generate triangleset for mesh meshId */ from = 0; while((from < numGeometryNodes_) && (meshInfo_[from].meshId < meshId)) { from++; } if((from < numGeometryNodes_) && (meshInfo_[from].meshId == meshId)) { /* first pass: count vertices and faces */ numVertices = 0; numFaces = 0; offsetVertices = 0; /* const 0 */ i = from; numVertices = meshInfo_[i].numVertices; numQuads = 0; while((i < numGeometryNodes_) && (meshInfo_[i].meshId == meshId)) { numFaces += meshInfo_[i].numFaces; numQuads += meshInfo_[i].numQuads; i++; } SINFO << "# of vertices = " << numVertices << endLog; SINFO << "# of quads = " << numQuads << endLog; SINFO << "# of faces = " << numFaces << endl << endLog; if(numQuads > 0) { *isQuadVertex = new GEOMARK_BitArray(numVertices); numFaces += numQuads; } ts->init(numVertices, numFaces); /* second pass */ numVertices = 0; numFaces = 0; offsetVertices = 0; i = from; while((i < numGeometryNodes_) && (meshInfo_[i].meshId == meshId)) { /* set vertex data */ for(j = 0; j < meshInfo_[i].vPtr->size(); j++) { v[0] = (*meshInfo_[i].vPtr)[j][0]; v[1] = (*meshInfo_[i].vPtr)[j][1]; v[2] = (*meshInfo_[i].vPtr)[j][2]; /* transformation does not matter for single IndexedFaceSets */ ts->setVertex(offsetVertices + j, v); } /* set face data */ geoPtr = meshInfo_[i].geoPtr; for(fit = geoPtr->beginFaces(); fit != geoPtr->endFaces(); ++fit) { numFaceVertices = fit.getLength(); if(numFaceVertices == 4) { SWARNING << "Quad found. Will be split" << endl << endLog; for(j = 0; j < 4; j++) { quadVIds[j] = fit.getPositionIndex(j); (*isQuadVertex)->setBit(quadVIds[j], 1); } /* split quad into two triangles */ ts->setFace(numFaces, offsetVertices + quadVIds[0], offsetVertices + quadVIds[1], offsetVertices + quadVIds[2]); numFaces++; ts->setFace(numFaces, offsetVertices + quadVIds[2], offsetVertices + quadVIds[3], offsetVertices + quadVIds[0]); numFaces++; } else { if(numFaceVertices != 3) { SFATAL << "# of vertices for face = " << numFaceVertices << endl << endLog; return 1; } for(j = 0; j < 3; j++) { trVIds[j] = fit.getPositionIndex(j); } ts->setFace(numFaces, offsetVertices + trVIds[0], offsetVertices + trVIds[1], offsetVertices + trVIds[2]); numFaces++; } } /* for fit */ i++; } /* while i */ SINFO << "# of faces = " << numFaces << endl << endLog; ts->meshComplete(); } /* if */ else { SFATAL << "No mesh with id " << meshId << endl << endLog; return 1; } } /* generate flat mesh from all nodes */ *numQuadsFound = numQuads; return 0; }