void CpuClipmapRenderer::createBlockIndices( GeometryClipmapLevel& level, const Rectangle2i& blockRect, int levelSampleCount, IndexList& indices ) { // todo: this needs rework.. if( blockRect.isEmpty() ) { return; } assert( blockRect._x0 >= 0 ); assert( blockRect._y0 >= 0 ); assert( blockRect._x1 > blockRect._x0 ); assert( blockRect._y1 > blockRect._y0 ); assert( blockRect._x0 < levelSampleCount ); assert( blockRect._y0 < levelSampleCount ); assert( blockRect._x1 < levelSampleCount ); assert( blockRect._y1 < levelSampleCount ); for( int y = blockRect._y0; y < blockRect._y1; ++y ) { assert( y + 1 < levelSampleCount ); const int row0 = ( level.blockOrigin[ 1 ] + y ) % levelSampleCount; const int row1 = ( level.blockOrigin[ 1 ] + y + 1 ) % levelSampleCount; for( int x = blockRect._x0; x < blockRect._x1; ++x ) { assert( x + 1 < levelSampleCount ); const int col0 = ( level.blockOrigin[ 0 ] + x ) % levelSampleCount; const int col1 = ( level.blockOrigin[ 0 ] + x + 1 ) % levelSampleCount; const int idx0 = row0 * levelSampleCount + col0; const int idx1 = row0 * levelSampleCount + col1; const int idx2 = row1 * levelSampleCount + col0; const int idx3 = row1 * levelSampleCount + col1; assert( idx0 < 65536 ); assert( idx1 < 65536 ); assert( idx2 < 65536 ); assert( idx3 < 65536 ); indices.push_back( idx0 ); indices.push_back( idx2 ); indices.push_back( idx1 ); indices.push_back( idx1 ); indices.push_back( idx2 ); indices.push_back( idx3 ); } } }
void init() { std::cout << "@Counter#init" << std::endl; max_robots = 0; min_fuels = 0; carriables.N = in->N; carriables.each([&]( const Int& x ) { std::cout << "x = " << x << std::endl; }); }
IndexList GLC_Mesh::equivalentTrianglesIndexOfstripsIndex(int lodIndex, GLC_uint materialId) { IndexList trianglesIndex; if (containsStrips(lodIndex, materialId)) { const QList<QVector<GLuint> > stripsIndex= getStripsIndex(lodIndex, materialId); const int stripCount= stripsIndex.count(); for (int i= 0; i < stripCount; ++i) { const QVector<GLuint> currentStripIndex= stripsIndex.at(i); trianglesIndex.append(currentStripIndex.at(0)); trianglesIndex.append(currentStripIndex.at(1)); trianglesIndex.append(currentStripIndex.at(2)); const int stripSize= currentStripIndex.size(); for (int j= 3; j < stripSize; ++j) { if ((j % 2) != 0) { trianglesIndex.append(currentStripIndex.at(j)); trianglesIndex.append(currentStripIndex.at(j - 1)); trianglesIndex.append(currentStripIndex.at(j - 2)); } else { trianglesIndex.append(currentStripIndex.at(j)); trianglesIndex.append(currentStripIndex.at(j - 2)); trianglesIndex.append(currentStripIndex.at(j - 1)); } } } } return trianglesIndex; }
inline void operator() (Lattice& L, IndexList& idx) { typedef typename Lattice::element element; for(int dim = 0; dim < idx.size(); ++dim) { sum += L(idx) * L.get_n_left(idx, dim); sum += L(idx) * L.get_n_right(idx, dim); } }
inline void operator() (Lattice& L, IndexList& idx) { typename Lattice::element delta = 0; for(int dim = 0; dim < idx.size(); ++dim) { delta += L.get_n_left(idx, dim); delta += L.get_n_right(idx, dim); } L(idx) += delta; }
void RenderingEngine::GenerateTriangleIndices(size_t lineCount, IndexList& triangles) const { size_t destVertCount = lineCount * 8; triangles.resize(lineCount * 18); IndexList::iterator triangle = triangles.begin(); for (GLushort v = 0; v < destVertCount; v += 8) { *triangle++ = 0 + v; *triangle++ = 1 + v; *triangle++ = 2 + v; *triangle++ = 2 + v; *triangle++ = 1 + v; *triangle++ = 3 + v; *triangle++ = 2 + v; *triangle++ = 3 + v; *triangle++ = 4 + v; *triangle++ = 4 + v; *triangle++ = 3 + v; *triangle++ = 5 + v; *triangle++ = 4 + v; *triangle++ = 5 + v; *triangle++ = 6 + v; *triangle++ = 6 + v; *triangle++ = 5 + v; *triangle++ = 7 + v; } }
void Sky::Subdivide(std::vector<D3DXVECTOR3>& vertices, std::vector<DWORD>& indices) { VertexList vin = vertices; IndexList iin = indices; vertices.resize(0); indices.resize(0); UINT numTris = (UINT)iin.size()/3; for(UINT i = 0; i < numTris; ++i) { D3DXVECTOR3 v0 = vin[ iin[i*3+0] ]; D3DXVECTOR3 v1 = vin[ iin[i*3+1] ]; D3DXVECTOR3 v2 = vin[ iin[i*3+2] ]; D3DXVECTOR3 m0 = 0.5f*(v0 + v1); D3DXVECTOR3 m1 = 0.5f*(v1 + v2); D3DXVECTOR3 m2 = 0.5f*(v0 + v2); vertices.push_back(v0); // 0 vertices.push_back(v1); // 1 vertices.push_back(v2); // 2 vertices.push_back(m0); // 3 vertices.push_back(m1); // 4 vertices.push_back(m2); // 5 indices.push_back(i*6+0); indices.push_back(i*6+3); indices.push_back(i*6+5); indices.push_back(i*6+3); indices.push_back(i*6+4); indices.push_back(i*6+5); indices.push_back(i*6+5); indices.push_back(i*6+4); indices.push_back(i*6+2); indices.push_back(i*6+3); indices.push_back(i*6+1); indices.push_back(i*6+4); } }
// Add triangles Fan GLC_uint GLC_Mesh::addTrianglesFan(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy) { GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy); Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId)); Q_ASSERT(!indexList.isEmpty()); GLC_uint id= 0; if (0 == lod) { id= m_NextPrimitiveLocalId++; } m_MeshData.trianglesAdded(lod, indexList.size() - 2); m_PrimitiveGroups.value(lod)->value(groupId)->addTrianglesFan(indexList, id); // Invalid the geometry m_GeometryIsValid = false; return id; }
IndexList GLC_Mesh::equivalentTrianglesIndexOfFansIndex(int lodIndex, GLC_uint materialId) { IndexList trianglesIndex; if (containsFans(lodIndex, materialId)) { const QList<QVector<GLuint> > fanIndex= getFansIndex(lodIndex, materialId); const int fanCount= fanIndex.count(); for (int i= 0; i < fanCount; ++i) { const QVector<GLuint> currentFanIndex= fanIndex.at(i); const int size= currentFanIndex.size(); for (int j= 1; j < size - 1; ++j) { trianglesIndex.append(currentFanIndex.first()); trianglesIndex.append(currentFanIndex.at(j)); trianglesIndex.append(currentFanIndex.at(j + 1)); } } } return trianglesIndex; }
IndexList GLC_Mesh::getEquivalentTrianglesStripsFansIndex(int lod, GLC_uint materialId) { IndexList subject; if (containsTriangles(lod, materialId)) { subject= getTrianglesIndex(lod, materialId).toList(); } if (containsStrips(lod, materialId)) { subject.append(equivalentTrianglesIndexOfstripsIndex(lod, materialId)); } if (containsFans(lod, materialId)) { subject.append(equivalentTrianglesIndexOfFansIndex(lod, materialId)); } Q_ASSERT((subject.count() % 3) == 0); return subject; }
PWIZ_API_DECL IndexList ProteinList::findKeyword(const string& keyword, bool caseSensitive /*= true*/) const { IndexList indexList; if (caseSensitive) { for (size_t index = 0, end = size(); index < end; ++index) if (protein(index, false)->description.find(keyword) != string::npos) indexList.push_back(index); } else { string lcKeyword = keyword; for (size_t index = 0, end = size(); index < end; ++index) { string lcDescription = protein(index, false)->description; bal::to_lower(lcDescription); if (lcDescription.find(lcKeyword) != string::npos) indexList.push_back(index); } } return indexList; }
void IndexArrayMapBuilder::addPolygon(const IndexList& indices) { const size_t count = indices.size(); IndexList polyIndices(0); polyIndices.reserve(3 * (count - 2)); for (size_t i = 0; i < count - 2; ++i) { polyIndices.push_back(indices[0]); polyIndices.push_back(indices[i + 1]); polyIndices.push_back(indices[i + 2]); } add(GL_TRIANGLES, polyIndices); }
double scn::GetVulnerability(UGraph::pGraph graph,size_t indexOfNode) { double original_efficiency = GetGlobalEfficiency(graph); std::pair<IndexList, IndexList> result; if(indexOfNode != Graph::NaF) {//compute the vulnerability of one node //remove the current node, note: only in_degree is used in //UGraph result = graph->RemoveNode(indexOfNode); IndexList& edges = result.first; //node edge double new_efficiency = GetGlobalEfficiency(graph); //restore the original graph graph->AddEdge(graph->AddNode(indexOfNode), edges); return (original_efficiency - new_efficiency) / original_efficiency; } else {//compute the vunlerability of the whole network IndexList setOfNode = graph->CopyIndexOfNodes(); //compute double max_vul = -1e200, new_vul; for(auto node = setOfNode.begin(); node != setOfNode.end(); node++) { //remove the current node, note: only in_degree is used in //UGraph result = graph->RemoveNode(*node); IndexList& edges = result.first; new_vul = (original_efficiency - GetGlobalEfficiency(graph)) / original_efficiency; if(new_vul > max_vul) max_vul = new_vul; //restore the original graph graph->AddEdge(graph->AddNode(*node), edges); } return max_vul; } }
void process_for_equations(Modelica::MMO_Class &mmo_class) { EquationList &equations = mmo_class.equations_ref().equations_ref(); EquationList new_equations; foreach_ (Equation &e, equations) { if (is<ForEq>(e)) { ForEq feq = boost::get<ForEq>(e); IndexList il = feq.range().indexes(); ERROR_UNLESS(il.size() == 1, "process_for_equations:\n" "forIndexList with more than 1 forIndex are not supported yet\n"); Index in = il.front(); Name variable = in.name(); OptExp ind = in.exp(); ERROR_UNLESS(ind, "for-equation's index with implicit range not supported yet\n"); Expression exp = ind.get(); ForIndexIterator *forIndexIter = NULL; if (is<Range>(exp)) { forIndexIter = new RangeIterator(get<Range>(exp),mmo_class.syms_ref()); } else if (is<Brace>(exp)) { forIndexIter = new BraceIterator(get<Brace>(exp),mmo_class.syms_ref()); } else { ERROR("For Iterator not supported"); } while (forIndexIter->hasNext()) { Real index_val = forIndexIter->next(); foreach_ (Equation eq, feq.elements()) new_equations.push_back(instantiate_equation(eq, variable, index_val, mmo_class.syms_ref())); } delete forIndexIter; } else { // Not a for eq new_equations.push_back(e); } } mmo_class.equations_ref().equations_ref()=new_equations; }
inline void operator()(unsigned int p1, unsigned int p2, unsigned int p3) { if (_remapIndices.empty()) { _in_indices.push_back(p1); _in_indices.push_back(p2); _in_indices.push_back(p3); } else { _in_indices.push_back(_remapIndices[p1]); _in_indices.push_back(_remapIndices[p2]); _in_indices.push_back(_remapIndices[p3]); } }
//*************************************************************************************** // Name: BuildGeoSphere // Desc: Function approximates a sphere by tesselating an icosahedron. //*************************************************************************************** void BuildGeoSphere(UINT numSubdivisions, float radius, VertexList& vertices, IndexList& indices) { // Put a cap on the number of subdivisions. numSubdivisions = Min(numSubdivisions, UINT(5)); // Approximate a sphere by tesselating an icosahedron. const float X = 0.525731f; const float Z = 0.850651f; D3DXVECTOR3 pos[12] = { D3DXVECTOR3(-X, 0.0f, Z), D3DXVECTOR3(X, 0.0f, Z), D3DXVECTOR3(-X, 0.0f, -Z), D3DXVECTOR3(X, 0.0f, -Z), D3DXVECTOR3(0.0f, Z, X), D3DXVECTOR3(0.0f, Z, -X), D3DXVECTOR3(0.0f, -Z, X), D3DXVECTOR3(0.0f, -Z, -X), D3DXVECTOR3(Z, X, 0.0f), D3DXVECTOR3(-Z, X, 0.0f), D3DXVECTOR3(Z, -X, 0.0f), D3DXVECTOR3(-Z, -X, 0.0f) }; DWORD k[60] = { 1,4,0, 4,9,0, 4,5,9, 8,5,4, 1,8,4, 1,10,8, 10,3,8, 8,3,5, 3,2,5, 3,7,2, 3,10,7, 10,6,7, 6,11,7, 6,0,11, 6,1,0, 10,1,6, 11,0,9, 2,11,9, 5,2,9, 11,2,7 }; vertices.resize(12); indices.resize(60); for(int i = 0; i < 12; ++i) vertices[i] = pos[i]; for(int i = 0; i < 60; ++i) indices[i] = k[i]; for(UINT i = 0; i < numSubdivisions; ++i) Subdivide(vertices, indices); // Project vertices onto sphere and scale. for(size_t i = 0; i < vertices.size(); ++i) { D3DXVec3Normalize(&vertices[i], &vertices[i]); vertices[i] *= radius; } }
// Add triangle strip to the group void GLC_PrimitiveGroup::addTrianglesStrip(const IndexList& input, GLC_uint id) { m_StripsIndex+= input; m_TrianglesStripSize= m_StripsIndex.size(); m_StripIndexSizes.append(static_cast<GLsizei>(input.size())); if (m_StripIndexOffseti.isEmpty()) { m_StripIndexOffseti.append(0); } int offset= m_StripIndexOffseti.last() + m_StripIndexSizes.last(); m_StripIndexOffseti.append(offset); // The strip id if (0 != id) m_StripsId.append(id); else Q_ASSERT(m_StripsId.isEmpty()); }
void medTestDbApp::handleNonPersistentDataImported() { CHECK_TEST_RESULT(importedIndex.isValid()); CHECK_TEST_RESULT(importedIndex.isValidForSeries()); const int persistentSourceId = 1; const int nonPersistentSourceId = 2; // Check freshly imported data exists. npDb = dataManager->controllerForDataSource(nonPersistentSourceId); CHECK_TEST_RESULT( npDb ); CHECK_TEST_RESULT(npDb->dataSourceId() == nonPersistentSourceId); CHECK_TEST_RESULT( !npDb->isPersistent() ); typedef QList<medDataIndex> IndexList; IndexList patients = npDb->patients(); qDebug() << "patient size:"<< patients.size(); CHECK_TEST_RESULT(patients.size() == 1); CHECK_TEST_RESULT(patients[0].patientId() == importedIndex.patientId()); IndexList studies = npDb->studies(patients[0]); CHECK_TEST_RESULT(studies.size() == 1); CHECK_TEST_RESULT(studies[0].studyId() == importedIndex.studyId()); IndexList series = npDb->series(studies[0]); CHECK_TEST_RESULT(series.size() == 1); CHECK_TEST_RESULT(series[0].seriesId() == importedIndex.seriesId()); // Ensure persistent DB is empty at first db = dataManager->controllerForDataSource(persistentSourceId); CHECK_TEST_RESULT( db ); CHECK_TEST_RESULT( db->patients().size() == 0 ); // Test import from non-Persistent to persistent //disconnect(dataManager); disconnect(dataManager, 0, this, 0); connect(dataManager, SIGNAL(dataAdded(const medDataIndex&)), this, SLOT(onPersistentDataImported(const medDataIndex&))); //TODO: reeanble this test when fixing supported extension bug, //and priority list! //dataManager->storeNonPersistentSingleDataToDatabase(importedIndex); //when reenabling, remove these two lines testResult = DTK_SUCCEED; exit(); }
virtual void CacheFileInfo(nsCString& aFileName, nsAString& aFaceList, PRUint32 aTimestamp, PRUint32 aFileSize, IndexList &aIndexList) { if (!mMap.ops) return; FNCMapEntry* entry = static_cast<FNCMapEntry*> (PL_DHashTableOperate(&mMap, aFileName.get(), PL_DHASH_ADD)); if (entry) { entry->mFilename = aFileName; entry->mTimestamp = aTimestamp; entry->mFilesize = aFileSize; entry->mFaces.Assign(aFaceList); for (PRUint32 i = 0; i < aIndexList.Length(); i++) { entry->mIndexes.AppendInt(aIndexList[i]); entry->mIndexes.Append(","); } } mWriteNeeded = PR_TRUE; }
void medTestDbApp::handlePersistentDataImported() { CHECK_TEST_RESULT( db->patients().size() == 1 ); CHECK_TEST_RESULT( npDb->patients().size() == 0 ); typedef QList<medDataIndex> IndexList; IndexList patients = db->patients(); CHECK_TEST_RESULT(patients.size() == 1); IndexList studies = db->studies(patients[0]); CHECK_TEST_RESULT(studies.size() == 1); IndexList series = db->series(studies[0]); CHECK_TEST_RESULT(series.size() == 1); const medDataIndex persImportedIndex = series[0]; this->processEvents(); // clear cache. dataManager->clearCache(); // Check data in db matches original. dtkSmartPointer<dtkAbstractData> testDataFromDb = dataManager->data( persImportedIndex ); CHECK_TEST_RESULT(testDataFromDb->identifier() == testData->identifier()); CHECK_TEST_RESULT(medMetaDataKeys::PatientName.getFirstValue(testDataFromDb) == medMetaDataKeys::PatientName.getFirstValue(testData)); // Check removing works ok - need to use synchronous version. //dataManager->removeData( persImportedIndex ); //this->processEvents(); medDatabaseRemover remover( persImportedIndex ); remover.run(); // Should be no patients now. patients = db->patients(); CHECK_TEST_RESULT(patients.size() == 0); //close db? medDatabaseController::instance()->closeConnection(); testResult = DTK_SUCCEED; exit(); }
double scn::GetRichClubCoeff(UGraph::pGraph graph,size_t degree) { IndexList setOfHighNode;//whose degree is greater than //argument degree for(auto node = graph->begin(); node != graph->end(); node++) { if(node->GetDegree() > degree) { setOfHighNode.push_back(*node); } } double sum = 0; for(auto one = setOfHighNode.begin(); one != setOfHighNode.end(); one++) { for(auto two = one + 1; two != setOfHighNode.end(); two++) { if(graph->HasEdge(*one, *two)) sum++; } } return 2 * sum / static_cast<double>(setOfHighNode.size() * (setOfHighNode.size() - 1)); }
virtual void GetInfoForFile(nsCString& aFileName, nsAString& aFaceList, PRUint32 *aTimestamp, PRUint32 *aFileSize, IndexList &aIndexList) { if (!mMap.ops) return; PLDHashEntryHdr *hdr = PL_DHashTableOperate(&mMap, aFileName.get(), PL_DHASH_LOOKUP); if (!hdr) return; FNCMapEntry* entry = static_cast<FNCMapEntry*>(hdr); if (entry && entry->mTimestamp && entry->mFilesize) { *aTimestamp = entry->mTimestamp; *aFileSize = entry->mFilesize; char* indexes = const_cast<char*>(entry->mIndexes.get()); char* endptr = indexes + 1; unsigned long index = strtoul(indexes, &endptr, 10); while (indexes < endptr && indexes[0] != '\0') { aIndexList.AppendElement(index); indexes = endptr + 1; } aFaceList.Assign(entry->mFaces); } }
void IndexArrayMapBuilder::addLines(const IndexList& indices) { assert(indices.size() % 2 == 0); add(GL_LINES, indices); }
double GLC_Mesh::volume() { double resultVolume= 0.0; if (!m_MeshData.isEmpty()) { IndexList triangleIndex; QList<GLC_Material*> materials= materialSet().toList(); const int materialsCount= materials.count(); for (int i= 0; i < materialsCount; ++i) { GLC_uint materialId= materials.at(i)->id(); if (containsTriangles(0, materialId)) { triangleIndex.append(getTrianglesIndex(0, materialId).toList()); } if (containsStrips(0, materialId)) { triangleIndex.append(equivalentTrianglesIndexOfstripsIndex(0, materialId)); } if (containsFans(0, materialId)) { triangleIndex.append(equivalentTrianglesIndexOfFansIndex(0, materialId)); } } GLfloatVector vertices= m_MeshData.positionVector(); Q_ASSERT((triangleIndex.count() % 3) == 0); const int triangleCount= triangleIndex.count() / 3; for (int i= 0; i < triangleCount; ++i) { const int index= i * 3; const double v1x= vertices.at(triangleIndex.at(index) * 3); const double v1y= vertices.at(triangleIndex.at(index) * 3 + 1); const double v1z= vertices.at(triangleIndex.at(index) * 3 + 2); const double v2x= vertices.at(triangleIndex.at(index + 1) * 3); const double v2y= vertices.at(triangleIndex.at(index + 1) * 3 + 1); const double v2z= vertices.at(triangleIndex.at(index + 1) * 3 + 2); const double v3x= vertices.at(triangleIndex.at(index + 2) * 3); const double v3y= vertices.at(triangleIndex.at(index + 2) * 3 + 1); const double v3z= vertices.at(triangleIndex.at(index + 2) * 3 + 2); resultVolume+= ((v2y - v1y) * (v3z - v1z) - (v2z - v1z) * (v3y - v1y)) * (v1x + v2x + v3x); } resultVolume= resultVolume / 6.0; } return resultVolume; }
void TriStripVisitor::stripify(Geometry& geom) { if (geom.containsDeprecatedData()) geom.fixDeprecatedData(); if (osg::getBinding(geom.getNormalArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return; if (osg::getBinding(geom.getColorArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return; if (osg::getBinding(geom.getSecondaryColorArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return; if (osg::getBinding(geom.getFogCoordArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return; // no point tri stripping if we don't have enough vertices. if (!geom.getVertexArray() || geom.getVertexArray()->getNumElements()<3) return; // check for the existence of surface primitives unsigned int numSurfacePrimitives = 0; unsigned int numNonSurfacePrimitives = 0; Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList(); Geometry::PrimitiveSetList::iterator itr; for(itr=primitives.begin(); itr!=primitives.end(); ++itr) { switch((*itr)->getMode()) { case(PrimitiveSet::TRIANGLES): case(PrimitiveSet::TRIANGLE_STRIP): case(PrimitiveSet::TRIANGLE_FAN): case(PrimitiveSet::QUADS): case(PrimitiveSet::QUAD_STRIP): case(PrimitiveSet::POLYGON): ++numSurfacePrimitives; break; default: ++numNonSurfacePrimitives; break; } } // nothitng to tri strip leave. if (!numSurfacePrimitives) return; // compute duplicate vertices typedef std::vector<unsigned int> IndexList; unsigned int numVertices = geom.getVertexArray()->getNumElements(); IndexList indices(numVertices); unsigned int i,j; for(i=0;i<numVertices;++i) { indices[i] = i; } VertexAttribComparitor arrayComparitor(geom); std::sort(indices.begin(),indices.end(),arrayComparitor); unsigned int lastUnique = 0; unsigned int numUnique = 1; unsigned int numDuplicate = 0; for(i=1;i<numVertices;++i) { if (arrayComparitor.compare(indices[lastUnique],indices[i])==0) { //std::cout<<" found duplicate "<<indices[lastUnique]<<" and "<<indices[i]<<std::endl; ++numDuplicate; } else { //std::cout<<" unique "<<indices[i]<<std::endl; lastUnique = i; ++numUnique; } } // std::cout<<" Number of duplicates "<<numDuplicate<<std::endl; // std::cout<<" Number of unique "<<numUnique<<std::endl; // std::cout<<" Total number of vertices required "<<numUnique<<" vs original "<<numVertices<<std::endl; // std::cout<<" % size "<<(float)numUnique/(float)numVertices*100.0f<<std::endl; IndexList remapDuplicatesToOrignals(numVertices); lastUnique = 0; for(i=1;i<numVertices;++i) { if (arrayComparitor.compare(indices[lastUnique],indices[i])!=0) { // found a new vertex entry, so previous run of duplicates needs // to be put together. unsigned int min_index = indices[lastUnique]; for(j=lastUnique+1;j<i;++j) { min_index = osg::minimum(min_index,indices[j]); } for(j=lastUnique;j<i;++j) { remapDuplicatesToOrignals[indices[j]]=min_index; } lastUnique = i; } } unsigned int min_index = indices[lastUnique]; for(j=lastUnique+1;j<i;++j) { min_index = osg::minimum(min_index,indices[j]); } for(j=lastUnique;j<i;++j) { remapDuplicatesToOrignals[indices[j]]=min_index; } // copy the arrays. IndexList finalMapping(numVertices); IndexList copyMapping; copyMapping.reserve(numUnique); unsigned int currentIndex=0; for(i=0;i<numVertices;++i) { if (remapDuplicatesToOrignals[i]==i) { finalMapping[i] = currentIndex; copyMapping.push_back(i); currentIndex++; } } for(i=0;i<numVertices;++i) { if (remapDuplicatesToOrignals[i]!=i) { finalMapping[i] = finalMapping[remapDuplicatesToOrignals[i]]; } } MyTriangleIndexFunctor taf; taf._remapIndices.swap(finalMapping); Geometry::PrimitiveSetList new_primitives; new_primitives.reserve(primitives.size()); for(itr=primitives.begin(); itr!=primitives.end(); ++itr) { switch((*itr)->getMode()) { case(PrimitiveSet::TRIANGLES): case(PrimitiveSet::TRIANGLE_STRIP): case(PrimitiveSet::TRIANGLE_FAN): case(PrimitiveSet::QUADS): case(PrimitiveSet::QUAD_STRIP): case(PrimitiveSet::POLYGON): (*itr)->accept(taf); break; default: new_primitives.push_back(*itr); break; } } float minimum_ratio_of_indices_to_unique_vertices = 1; float ratio_of_indices_to_unique_vertices = ((float)taf._in_indices.size()/(float)numUnique); OSG_INFO<<"TriStripVisitor::stripify(Geometry&): Number of indices"<<taf._in_indices.size()<<" numUnique"<< numUnique << std::endl; OSG_INFO<<"TriStripVisitor::stripify(Geometry&): ratio indices/numUnique"<< ratio_of_indices_to_unique_vertices << std::endl; // only tri strip if there is point in doing so. if (!taf._in_indices.empty() && ratio_of_indices_to_unique_vertices>=minimum_ratio_of_indices_to_unique_vertices) { OSG_INFO<<"TriStripVisitor::stripify(Geometry&): doing tri strip"<< std::endl; unsigned int in_numVertices = 0; for(triangle_stripper::indices::iterator itr=taf._in_indices.begin(); itr!=taf._in_indices.end(); ++itr) { if (*itr>in_numVertices) in_numVertices=*itr; } // the largest indice is in_numVertices, but indices start at 0 // so increment to give to the corrent number of verticies. ++in_numVertices; // remap any shared vertex attributes RemapArray ra(copyMapping); arrayComparitor.accept(ra); triangle_stripper::tri_stripper stripifier(taf._in_indices); stripifier.SetCacheSize(_cacheSize); stripifier.SetMinStripSize(_minStripSize); triangle_stripper::primitive_vector outPrimitives; stripifier.Strip(&outPrimitives); if (outPrimitives.empty()) { OSG_WARN<<"Error: TriStripVisitor::stripify(Geometry& geom) failed."<<std::endl; return; } triangle_stripper::primitive_vector::iterator pitr; if (_generateFourPointPrimitivesQuads) { OSG_INFO<<"Collecting all quads"<<std::endl; typedef triangle_stripper::primitive_vector::iterator prim_iterator; typedef std::multimap<unsigned int,prim_iterator> QuadMap; QuadMap quadMap; // pick out quads and place them in the quadMap, and also look for the max for(pitr=outPrimitives.begin(); pitr!=outPrimitives.end(); ++pitr) { if (pitr->Indices.size()==4) { std::swap(pitr->Indices[2],pitr->Indices[3]); unsigned int minValue = *(std::max_element(pitr->Indices.begin(),pitr->Indices.end())); quadMap.insert(QuadMap::value_type(minValue,pitr)); } } // handle the quads if (!quadMap.empty()) { IndexList indices; indices.reserve(4*quadMap.size()); // adds all the quads into the quad primitive, in ascending order // and the QuadMap stores the quad's in ascending order. for(QuadMap::iterator qitr=quadMap.begin(); qitr!=quadMap.end(); ++qitr) { pitr = qitr->second; unsigned int min_pos = 0; for(i=1;i<4;++i) { if (pitr->Indices[min_pos]>pitr->Indices[i]) min_pos = i; } indices.push_back(pitr->Indices[min_pos]); indices.push_back(pitr->Indices[(min_pos+1)%4]); indices.push_back(pitr->Indices[(min_pos+2)%4]); indices.push_back(pitr->Indices[(min_pos+3)%4]); } bool inOrder = true; unsigned int previousValue = indices.front(); for(IndexList::iterator qi_itr=indices.begin()+1; qi_itr!=indices.end() && inOrder; ++qi_itr) { inOrder = (previousValue+1)==*qi_itr; previousValue = *qi_itr; } if (inOrder) { new_primitives.push_back(new osg::DrawArrays(GL_QUADS,indices.front(),indices.size())); } else { unsigned int maxValue = *(std::max_element(indices.begin(),indices.end())); if (maxValue>=65536) { osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_QUADS); std::copy(indices.begin(),indices.end(),std::back_inserter(*elements)); new_primitives.push_back(elements); } else { osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(GL_QUADS); std::copy(indices.begin(),indices.end(),std::back_inserter(*elements)); new_primitives.push_back(elements); } } } } // handle non quad primitives for(pitr=outPrimitives.begin(); pitr!=outPrimitives.end(); ++pitr) { if (!_generateFourPointPrimitivesQuads || pitr->Indices.size()!=4) { bool inOrder = true; unsigned int previousValue = pitr->Indices.front(); for(triangle_stripper::indices::iterator qi_itr=pitr->Indices.begin()+1; qi_itr!=pitr->Indices.end() && inOrder; ++qi_itr) { inOrder = (previousValue+1)==*qi_itr; previousValue = *qi_itr; } if (inOrder) { new_primitives.push_back(new osg::DrawArrays(pitr->Type,pitr->Indices.front(),pitr->Indices.size())); } else { unsigned int maxValue = *(std::max_element(pitr->Indices.begin(),pitr->Indices.end())); if (maxValue>=65536) { osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(pitr->Type); elements->reserve(pitr->Indices.size()); std::copy(pitr->Indices.begin(),pitr->Indices.end(),std::back_inserter(*elements)); new_primitives.push_back(elements); } else { osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(pitr->Type); elements->reserve(pitr->Indices.size()); std::copy(pitr->Indices.begin(),pitr->Indices.end(),std::back_inserter(*elements)); new_primitives.push_back(elements); } } } } geom.setPrimitiveSetList(new_primitives); #if 0 // debugging code for indentifying the tri-strips. osg::Vec4Array* colors = new osg::Vec4Array(new_primitives.size()); for(i=0;i<colors->size();++i) { (*colors)[i].set(((float)rand()/(float)RAND_MAX), ((float)rand()/(float)RAND_MAX), ((float)rand()/(float)RAND_MAX), 1.0f); } geom.setColorArray(colors); geom.setColorBinding(osg::Array::BIND_PER_PRIMITIVE_SET); #endif } else { OSG_INFO<<"TriStripVisitor::stripify(Geometry&): not doing tri strip *****************"<< std::endl; } }
void GLC_Cone::createMeshAndWire() { Q_ASSERT(GLC_Mesh::isEmpty()); Q_ASSERT(m_WireData.isEmpty()); // Create cosinus and sinus array according to the discretion and radius const int vertexNumber= m_Discret + 1; // Normals values QVector<float> cosNormalArray(vertexNumber); QVector<float> sinNormalArray(vertexNumber); QVector<float> cosArray(vertexNumber); QVector<float> sinArray(vertexNumber); const double angle= (2.0 * glc::PI) / static_cast<double>(m_Discret); // Normal Z value GLC_Vector3d normalVector(1.0, 0.0, 0.0); GLC_Matrix4x4 rotation(glc::Y_AXIS, -atan(m_Radius / m_Length)); normalVector= rotation * normalVector; const float normalZ= static_cast<float>(normalVector.z()); const double factor= normalVector.x(); // Normailsation factor for (int i= 0; i < vertexNumber; ++i) { const double cosValue= cos(static_cast<double>(i) * angle); const double sinValue= sin(static_cast<double>(i) * angle); cosNormalArray[i]= static_cast<GLfloat>(factor * cosValue); sinNormalArray[i]= static_cast<GLfloat>(factor * sinValue); cosArray[i]= static_cast<GLfloat>(m_Radius * cosValue); sinArray[i]= static_cast<GLfloat>(m_Radius * sinValue); } // Mesh Data GLfloatVector verticeVector; GLfloatVector normalsVector; GLfloatVector texelVector; // Wire Data GLfloatVector bottomWireData(vertexNumber * 3); const int size= vertexNumber * 3; verticeVector.resize(3 * size); normalsVector.resize(3 * size); texelVector.resize(2 * size); for (int i= 0; i < vertexNumber; ++i) { // Bottom Mesh verticeVector[3 * i]= cosArray[i]; verticeVector[3 * i + 1]= sinArray[i]; verticeVector[3 * i + 2]= 0.0f; normalsVector[3 * i]= cosNormalArray[i]; normalsVector[3 * i + 1]= sinNormalArray[i]; normalsVector[3 * i + 2]= normalZ; texelVector[2 * i]= static_cast<float>(i) / static_cast<float>(m_Discret); texelVector[2 * i + 1]= 0.0f; // Bottom Wire bottomWireData[3 * i]= cosArray[i]; bottomWireData[3 * i + 1]= sinArray[i]; bottomWireData[3 * i + 2]= 0.0f; // Top verticeVector[3 * i + 3 * vertexNumber]= 0.0f; verticeVector[3 * i + 1 + 3 * vertexNumber]= 0.0f; verticeVector[3 * i + 2 + 3 * vertexNumber]= static_cast<float>(m_Length); normalsVector[3 * i + 3 * vertexNumber]= cosNormalArray[i]; normalsVector[3 * i + 1 + 3 * vertexNumber]= sinNormalArray[i]; normalsVector[3 * i + 2 + 3 * vertexNumber]= normalZ; texelVector[2 * i + 2 * vertexNumber]= texelVector[i]; texelVector[2 * i + 1 + 2 * vertexNumber]= 1.0f; // Bottom Cap ends verticeVector[3 * i + 2 * 3 * vertexNumber]= cosArray[i]; verticeVector[3 * i + 1 + 2 * 3 * vertexNumber]= sinArray[i]; verticeVector[3 * i + 2 + 2 * 3 * vertexNumber]= 0.0f; normalsVector[3 * i + 2 * 3 * vertexNumber]= 0.0f; normalsVector[3 * i + 1 + 2 * 3 * vertexNumber]= 0.0f; normalsVector[3 * i + 2 + 2 * 3 * vertexNumber]= -1.0f; texelVector[2 * i + 2 * 2 * vertexNumber]= texelVector[i]; texelVector[2 * i + 1 + 2 * 2 * vertexNumber]= 0.0f; } // Add bulk data in to the mesh GLC_Mesh::addVertice(verticeVector); GLC_Mesh::addNormals(normalsVector); GLC_Mesh::addTexels(texelVector); // Add polyline to wire data GLC_Geometry::addPolyline(bottomWireData); // Set the material to use GLC_Material* pCylinderMaterial; if (hasMaterial()) { pCylinderMaterial= this->firstMaterial(); } else { pCylinderMaterial= new GLC_Material(); } IndexList circumferenceStrips; // Create the index for (int i= 0; i < vertexNumber; ++i) { circumferenceStrips.append(i + vertexNumber); circumferenceStrips.append(i); } addTrianglesStrip(pCylinderMaterial, circumferenceStrips); { IndexList bottomCap; IndexList topCap; int id1= 0; int id2= m_Discret - 1; const int size= m_Discret / 2 + (m_Discret % 2); for (int i= 0; i < size; ++i) { bottomCap.append(id1 + 2 * vertexNumber); bottomCap.append(id2 + 2 * vertexNumber); id1+= 1; id2-= 1; } addTrianglesStrip(pCylinderMaterial, bottomCap); } finish(); }
void Cylinder::buildStacks(VertexList& vertices, IndexList& indices) { float stackHeight = mHeight / mNumStacks; // Amount to increment radius as we move up each stack level from bottom to top. float radiusStep = (mTopRadius - mBottomRadius) / mNumStacks; UINT numRings = mNumStacks+1; // Compute vertices for each stack ring. for(UINT i = 0; i < numRings; ++i) { float y = -0.5f*mHeight + i*stackHeight; float r = mBottomRadius + i*radiusStep; // Height and radius of next ring up. float y_next = -0.5f*mHeight + (i+1)*stackHeight; float r_next = mBottomRadius + (i+1)*radiusStep; // vertices of ring float dTheta = 2.0f*PI/mNumSlices; for(UINT j = 0; j <= mNumSlices; ++j) { float c = cosf(j*dTheta); float s = sinf(j*dTheta); float u = (float)j/mNumSlices; float v = 1.0f - (float)i/mNumStacks; // Partial derivative in theta direction to get tangent vector (this is a unit vector). D3DXVECTOR3 T(-s, 0.0f, c); // Compute tangent vector down the slope of the cone (if the top/bottom // radii differ then we get a cone and not a true cylinder). D3DXVECTOR3 P(r*c, y, r*s); D3DXVECTOR3 P_next(r_next*c, y_next, r_next*s); D3DXVECTOR3 B = P - P_next; D3DXVec3Normalize(&B, &B); D3DXVECTOR3 N; D3DXVec3Cross(&N, &T, &B); D3DXVec3Normalize(&N, &N); vertices.push_back( Vertex(P.x, P.y, P.z, T.x, T.y, T.z, N.x, N.y, N.z, u, v) ); } } UINT numRingVertices = mNumSlices+1; // Compute indices for each stack. for(UINT i = 0; i < mNumStacks; ++i) { for(UINT j = 0; j < mNumSlices; ++j) { indices.push_back(i*numRingVertices + j); indices.push_back((i+1)*numRingVertices + j); indices.push_back((i+1)*numRingVertices + j+1); indices.push_back(i*numRingVertices + j); indices.push_back((i+1)*numRingVertices + j+1); indices.push_back(i*numRingVertices + j+1); } } }
void IndexArrayMapBuilder::addQuads(const IndexList& indices) { assert(indices.size() % 4 == 0); add(GL_QUADS, indices); }
void IndexArrayMapBuilder::addTriangles(const IndexList& indices) { assert(indices.size() % 3 == 0); add(GL_TRIANGLES, indices); }
void IndexArrayMapBuilder::add(const PrimType primType, const IndexList& indices) { const size_t offset = m_ranges.add(primType, indices.size()); IndexList::iterator dest = m_indices.begin(); std::advance(dest, offset); std::copy(indices.begin(), indices.end(), dest); }