// Рисует панель высот вершин (справа).
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();
}
示例#2
0
	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;
	}
示例#3
0
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);
	}