// Рисует панель высот вершин (справа). void MaxFlowVisualizer::drawHeightsBar(QPainter &painter) { painter.save(); painter.setPen(QPen(Qt::black, 3)); painter.setBrush(Qt::lightGray); size_t verteciesNumber = verteciesList.size(); int levelCount = countUsedHeightLevels(); int borderOffset = VisableVertex::DEFAULT_VERTEX_RADIUS; // Для удобства перенесем систему коодинат в левый верхний угол будующей панели. painter.translate(width() - RIGHT_BAR_OF_HEIGHTS_WIDTH, borderOffset); unsigned barWidth = RIGHT_BAR_OF_HEIGHTS_WIDTH; int barHeight = height() - 2 * borderOffset; int bottomY = barHeight; double scaleHeight = barHeight / levelCount; // Рисует горизонтальные линии, соответсвующие уровням. for (size_t level = 0; level < levelCount; ++level) { int x = 0; painter.drawLine(x, bottomY - scaleHeight * level, x + barWidth, bottomY - scaleHeight * level); } // Отображение вершин на панели высот. double scaleWidth = RIGHT_BAR_OF_HEIGHTS_WIDTH / verteciesNumber; for (size_t vertex = 0; vertex < verteciesNumber; ++vertex) { // Для того, чтобы все визуальные эффекты вершины (выделение, надписи и т.д.) // отображались и на боковой панели высот, мы в явном виде создаем новую // вершину - точную копию исходной (простой конструктор копирования) // и перемещаем ее на нужное место на панели высот. VisableVertex currentVertex(verteciesList[vertex]); currentVertex.setCenterCoordX(borderOffset + scaleWidth * vertex); currentVertex.setCenterCoordY(bottomY - scaleHeight * relabelToFrontAlgo.getVertexHeight(vertex)); drawVertex(currentVertex, painter); } painter.restore(); }
bool ConvexHull::PointInsideHull(const Vec2f &point) { int sgn = 0; for(unsigned int i = 0, numVertices = m_vertices.size(); i < numVertices; i++) { int wrappedIndex = Wrap(i + 1, numVertices); Vec2f currentVertex(GetWorldVertex(i)); Vec2f side(GetWorldVertex(wrappedIndex) - currentVertex); Vec2f toPoint(point - currentVertex); float cpd = side.Cross(toPoint); int cpdi = static_cast<int>(cpd / abs(cpd)); if(sgn == 0) sgn = cpdi; else if(cpdi != sgn) return false; } return true; }
std::vector<Vertex> ObjectImporter::importObj(std::string objFileName) { std::cout << "trying to parse " << objFileName << std::endl; std::string pathToObject = "../Resources/objects/" + objFileName + ".obj"; std::ifstream objFileStream; objFileStream.open(pathToObject); char errorString[1024]; if (errno != 0) { strerror_s(errorString, errno); std::cout << "Error: " << errorString << " while trying to open: " << pathToObject << std::endl; } std::vector<glm::vec3> vertPosVec; std::vector<glm::vec3> vertNormsVec; std::vector<glm::vec3> vertColorVec; std::vector<glm::vec2> vertTextureVec; std::vector<Vertex> vertexVec; std::string currentLine; float randR = ((float)rand() / (RAND_MAX)); float randG = ((float)rand() / (RAND_MAX)); float randB = ((float)rand() / (RAND_MAX)); while (!objFileStream.eof()) { std::getline(objFileStream, currentLine); if (currentLine.length() > 0 && currentLine.at(0) != '#') { switch (currentLine.at(0)) { case 'v': //get the vertices if (currentLine.at(1) == ' ') { float vertPos[3]; int position = 2; for (int i = 0; i < 3; ++i) { std::string currentFloat; while (currentLine.at(position++) == ' '); position--; while (position < currentLine.length() && currentLine.at(position) != ' ') currentFloat += currentLine.at(position++); vertPos[i] = std::atof(currentFloat.c_str()); } vertPosVec.push_back(glm::vec3(vertPos[0], vertPos[1], vertPos[2])); } else if (currentLine.at(1) == 'n') { float vertPos[3]; int position = 2; for (int i = 0; i < 3; ++i) { std::string currentFloat; while (currentLine.at(position++) == ' '); position--; while (position < currentLine.length() && currentLine.at(position) != ' ') currentFloat += currentLine.at(position++); vertPos[i] = std::atof(currentFloat.c_str()); } vertNormsVec.push_back(glm::vec3(vertPos[0], vertPos[1], vertPos[2])); } else if (currentLine.at(1) == 't') { float vertPos[2]; int position = 2; for (int i = 0; i < 2; ++i) { std::string currentFloat; while (currentLine.at(position++) == ' '); position--; while (position < currentLine.length() && currentLine.at(position) != ' ') currentFloat += currentLine.at(position++); vertPos[i] = std::atof(currentFloat.c_str()); } vertTextureVec.push_back(glm::vec2(vertPos[0], vertPos[1])); } break; case 'f': int position = 1; for (int numVertex = 0; position < currentLine.length(); ++numVertex) { int vertInds[3]; while (currentLine.at(position++) == ' '); position--; for (int i = 0; i < 3; ++i) { std::string currentInt; while (position < currentLine.length() && currentLine.at(position) != '/' && currentLine.at(position) != ' ') { currentInt += currentLine.at(position++); } vertInds[i] = std::atoi(currentInt.c_str()); position++; } Vertex currentVertex(vertPosVec[vertInds[0] - 1]); currentVertex.addTexData(vertTextureVec[vertInds[1] - 1]); currentVertex.addNormalData(vertNormsVec[vertInds[2] - 1]); currentVertex.addColorData(glm::vec3(randR, randG, randB)); vertexVec.push_back(currentVertex); } } } } std::cout << "succesfully imported" << std::endl; return vertexVec; }
void IndexedFaceSetNode::initContext(GLContextData& contextData) const { /* Create a data item and store it in the context: */ DataItem* dataItem=new DataItem; contextData.addDataItem(this,dataItem); /* Do nothing if the vertex buffer object extension is not supported: */ if(dataItem->vertexBufferObjectId==0||dataItem->indexBufferObjectId==0) return; const TextureCoordinateNode* texCoordNode=dynamic_cast<const TextureCoordinateNode*>(texCoord.getPointer()); const ColorNode* colorNode=dynamic_cast<const ColorNode*>(color.getPointer()); const NormalNode* normalNode=dynamic_cast<const NormalNode*>(normal.getPointer()); const CoordinateNode* coordNode=dynamic_cast<const CoordinateNode*>(coord.getPointer()); /********************************************************************* The problem with indexed face sets in VRML is that the format supports component-wise vertex indices, i.e., a vertex used in a face can have different indices for texture coordinate, color, normal, and position. OpenGL, on the other hand, only supports a single index for all vertex components. This method tries to reuse vertices as much as possible, by mapping tuples of per-component vertex indices to complete OpenGL vertex indices using a hash table. *********************************************************************/ /* Create a hash table to map compound vertex indices to complete vertices: */ typedef Misc::HashTable<VertexIndices,GLuint,VertexIndices> VertexHasher; VertexHasher vertexHasher(101); /* Count the number of vertices that need to be created and store their compound indices: */ std::vector<int>::const_iterator texCoordIt=texCoordIndices.empty()?coordIndices.begin():texCoordIndices.begin(); std::vector<int>::const_iterator colorIt=colorIndices.empty()?coordIndices.begin():colorIndices.begin(); int colorCounter=0; std::vector<int>::const_iterator normalIt=normalIndices.empty()?coordIndices.begin():normalIndices.begin(); int normalCounter=0; std::vector<int>::const_iterator coordIt=coordIndices.begin(); VertexIndices currentVertex(0,0,0,0); std::vector<VertexIndices> vertexIndices; std::vector<GLuint> triangleVertexIndices; dataItem->numTriangles=0; while(coordIt!=coordIndices.end()) { /* Process the vertices of this face: */ std::vector<GLuint> faceVertexIndices; while(*coordIt>=0) { /* Create the current compound vertex: */ if(texCoordNode!=0) currentVertex.texCoord=*texCoordIt; if(colorNode!=0) { if(!colorPerVertex&&colorIndices.empty()) currentVertex.color=colorCounter; else currentVertex.color=*colorIt; } if(normalNode!=0) { if(!normalPerVertex&&normalIndices.empty()) currentVertex.normal=normalCounter; else currentVertex.normal=*normalIt; } currentVertex.coord=*coordIt; if(currentVertex.texCoord<0||currentVertex.color<0||currentVertex.normal<0||currentVertex.coord<0) Misc::throwStdErr("Bad index in vertex!"); /* Find the index of the complete vertex: */ int vertexIndex; VertexHasher::Iterator vhIt=vertexHasher.findEntry(currentVertex); if(vhIt.isFinished()) { /* Create a new vertex and store its index: */ faceVertexIndices.push_back(vertexIndices.size()); vertexHasher.setEntry(VertexHasher::Entry(currentVertex,vertexIndices.size())); vertexIndices.push_back(currentVertex); } else { /* Store the existing vertex index: */ faceVertexIndices.push_back(vhIt->getDest()); } /* Go to the next vertex in the same face: */ ++texCoordIt; if(colorPerVertex) ++colorIt; if(normalPerVertex) ++normalIt; ++coordIt; } /* Create triangles for this face: */ for(int i=2;i<faceVertexIndices.size();++i) { triangleVertexIndices.push_back(faceVertexIndices[0]); triangleVertexIndices.push_back(faceVertexIndices[i-1]); triangleVertexIndices.push_back(faceVertexIndices[i]); ++dataItem->numTriangles; } /* Go to the next face: */ ++texCoordIt; if(!colorPerVertex&&colorIndices.empty()) ++colorCounter; else ++colorIt; if(!normalPerVertex&&normalIndices.empty()) ++normalCounter; else ++normalIt; ++coordIt; } /* Upload all vertices into the vertex buffer: */ glBindBufferARB(GL_ARRAY_BUFFER_ARB,dataItem->vertexBufferObjectId); glBufferDataARB(GL_ARRAY_BUFFER_ARB,vertexIndices.size()*sizeof(Vertex),0,GL_STATIC_DRAW_ARB); Vertex* vertices=static_cast<Vertex*>(glMapBufferARB(GL_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB)); for(std::vector<VertexIndices>::const_iterator viIt=vertexIndices.begin();viIt!=vertexIndices.end();++viIt,++vertices) { /* Assemble the vertex from its components: */ if(texCoordNode!=0) vertices->texCoord=Vertex::TexCoord(texCoordNode->getPoint(viIt->texCoord).getComponents()); if(colorNode!=0) vertices->color=colorNode->getColor(viIt->color); if(normalNode!=0) vertices->normal=Vertex::Normal(normalNode->getVector(viIt->normal).getComponents()); vertices->position=Vertex::Position(coordNode->getPoint(viIt->coord).getComponents()); } /* Unmap and protect the vertex buffer: */ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB,0); /* Upload all vertex indices into the index buffers: */ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,dataItem->indexBufferObjectId); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,triangleVertexIndices.size()*sizeof(GLuint),&triangleVertexIndices[0],GL_STATIC_DRAW_ARB); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0); }
void IndexedLineSetNode::initContext(GLContextData& contextData) const { /* Create a data item and store it in the context: */ DataItem* dataItem=new DataItem; contextData.addDataItem(this,dataItem); /* Do nothing if the vertex buffer object extension is not supported: */ if(dataItem->vertexBufferObjectId==0||dataItem->indexBufferObjectId==0) return; const ColorNode* colorNode=dynamic_cast<const ColorNode*>(color.getPointer()); const CoordinateNode* coordNode=dynamic_cast<const CoordinateNode*>(coord.getPointer()); /********************************************************************* The problem with indexed line sets in VRML is that the format supports component-wise vertex indices, i.e., a vertex used in a face can have different indices for color and position. OpenGL, on the other hand, only supports a single index for all vertex components. This method tries to reuse vertices as much as possible, by mapping tuples of per-component vertex indices to complete OpenGL vertex indices using a hash table. *********************************************************************/ /* Create a hash table to map compound vertex indices to complete vertices: */ typedef Misc::OrderedTuple<int,2> VertexIndices; // (colorIndex, vertexIndex) typedef Misc::HashTable<VertexIndices,GLuint,VertexIndices> VertexHasher; VertexHasher vertexHasher(101); std::vector<int>::const_iterator colorIt=colorIndices.empty()?coordIndices.begin():colorIndices.begin(); int colorCounter=0; std::vector<int>::const_iterator coordIt=coordIndices.begin(); VertexIndices currentVertex(0,0); std::vector<VertexIndices> vertexIndices; std::vector<GLuint> lineVertexIndices; while(coordIt!=coordIndices.end()) { /* Process the vertices of this line strip: */ GLsizei numVertices=0; while(*coordIt>=0) { /* Create the current compound vertex: */ if(colorNode!=0) { if(!colorPerVertex&&colorIndices.empty()) currentVertex.set(0,colorCounter); else currentVertex.set(0,*colorIt); } currentVertex.set(1,*coordIt); if(currentVertex[0]<0||currentVertex[1]<0) Misc::throwStdErr("Bad index in vertex!"); /* Find the index of the complete vertex: */ int vertexIndex; VertexHasher::Iterator vhIt=vertexHasher.findEntry(currentVertex); if(vhIt.isFinished()) { /* Create a new vertex and store its index: */ lineVertexIndices.push_back(vertexIndices.size()); vertexHasher.setEntry(VertexHasher::Entry(currentVertex,vertexIndices.size())); vertexIndices.push_back(currentVertex); } else { /* Store the existing vertex index: */ lineVertexIndices.push_back(vhIt->getDest()); } /* Go to the next vertex in the same polyline: */ if(colorPerVertex) ++colorIt; ++coordIt; ++numVertices; } /* Generate a line strip for this polyline: */ dataItem->numLineStripVertices.push_back(numVertices); /* Go to the next polyline: */ if(!colorPerVertex&&colorIndices.empty()) ++colorCounter; else ++colorIt; ++coordIt; } /* Upload all vertices into the vertex buffer: */ glBindBufferARB(GL_ARRAY_BUFFER_ARB,dataItem->vertexBufferObjectId); glBufferDataARB(GL_ARRAY_BUFFER_ARB,vertexIndices.size()*sizeof(Vertex),0,GL_STATIC_DRAW_ARB); Vertex* vertices=static_cast<Vertex*>(glMapBufferARB(GL_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB)); for(std::vector<VertexIndices>::const_iterator viIt=vertexIndices.begin();viIt!=vertexIndices.end();++viIt,++vertices) { /* Assemble the vertex from its components: */ if(colorNode!=0) vertices->color=colorNode->getColor((*viIt)[0]); vertices->position=Vertex::Position(coordNode->getPoint((*viIt)[1]).getComponents()); } /* Unmap and protect the vertex buffer: */ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB,0); /* Upload all vertex indices into the index buffers: */ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,dataItem->indexBufferObjectId); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,lineVertexIndices.size()*sizeof(GLuint),&lineVertexIndices[0],GL_STATIC_DRAW_ARB); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0); }