Exemple #1
0
 void addVertex(initializer_list<double > pt) {
    addVertex(Vec3(pt)); 
 }
Exemple #2
0
/// @par
///
/// @note If the mesh data is to be used to construct a Detour navigation mesh, then the upper 
/// limit must be retricted to <= #DT_VERTS_PER_POLYGON.
///
/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig
bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMesh& mesh)
{
	rcAssert(ctx);
	
	ctx->startTimer(RC_TIMER_BUILD_POLYMESH);

	rcVcopy(mesh.bmin, cset.bmin);
	rcVcopy(mesh.bmax, cset.bmax);
	mesh.cs = cset.cs;
	mesh.ch = cset.ch;
	mesh.borderSize = cset.borderSize;
	
	int maxVertices = 0;
	int maxTris = 0;
	int maxVertsPerCont = 0;
	for (int i = 0; i < cset.nconts; ++i)
	{
		// Skip null contours.
		if (cset.conts[i].nverts < 3) continue;
		maxVertices += cset.conts[i].nverts;
		maxTris += cset.conts[i].nverts - 2;
		maxVertsPerCont = rcMax(maxVertsPerCont, cset.conts[i].nverts);
	}
	
	if (maxVertices >= 0xfffe)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many vertices %d.", maxVertices);
		return false;
	}
		
	rcScopedDelete<unsigned char> vflags = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxVertices, RC_ALLOC_TEMP);
	if (!vflags)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'vflags' (%d).", maxVertices);
		return false;
	}
	memset(vflags, 0, maxVertices);
	
	mesh.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertices*3, RC_ALLOC_PERM);
	if (!mesh.verts)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices);
		return false;
	}
	mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris*nvp*2, RC_ALLOC_PERM);
	if (!mesh.polys)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2);
		return false;
	}
	mesh.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris, RC_ALLOC_PERM);
	if (!mesh.regs)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.regs' (%d).", maxTris);
		return false;
	}
	mesh.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxTris, RC_ALLOC_PERM);
	if (!mesh.areas)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.areas' (%d).", maxTris);
		return false;
	}
	
	mesh.nverts = 0;
	mesh.npolys = 0;
	mesh.nvp = nvp;
	mesh.maxpolys = maxTris;
	
	memset(mesh.verts, 0, sizeof(unsigned short)*maxVertices*3);
	memset(mesh.polys, 0xff, sizeof(unsigned short)*maxTris*nvp*2);
	memset(mesh.regs, 0, sizeof(unsigned short)*maxTris);
	memset(mesh.areas, 0, sizeof(unsigned char)*maxTris);
	
	rcScopedDelete<int> nextVert = (int*)rcAlloc(sizeof(int)*maxVertices, RC_ALLOC_TEMP);
	if (!nextVert)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'nextVert' (%d).", maxVertices);
		return false;
	}
	memset(nextVert, 0, sizeof(int)*maxVertices);
	
	rcScopedDelete<int> firstVert = (int*)rcAlloc(sizeof(int)*VERTEX_BUCKET_COUNT, RC_ALLOC_TEMP);
	if (!firstVert)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT);
		return false;
	}
	for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i)
		firstVert[i] = -1;
	
	rcScopedDelete<int> indices = (int*)rcAlloc(sizeof(int)*maxVertsPerCont, RC_ALLOC_TEMP);
	if (!indices)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'indices' (%d).", maxVertsPerCont);
		return false;
	}
	rcScopedDelete<int> tris = (int*)rcAlloc(sizeof(int)*maxVertsPerCont*3, RC_ALLOC_TEMP);
	if (!tris)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'tris' (%d).", maxVertsPerCont*3);
		return false;
	}
	rcScopedDelete<unsigned short> polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*(maxVertsPerCont+1)*nvp, RC_ALLOC_TEMP);
	if (!polys)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'polys' (%d).", maxVertsPerCont*nvp);
		return false;
	}
	unsigned short* tmpPoly = &polys[maxVertsPerCont*nvp];

	for (int i = 0; i < cset.nconts; ++i)
	{
		rcContour& cont = cset.conts[i];
		
		// Skip null contours.
		if (cont.nverts < 3)
			continue;
		
		// Triangulate contour
		for (int j = 0; j < cont.nverts; ++j)
			indices[j] = j;
			
		int ntris = triangulate(cont.nverts, cont.verts, &indices[0], &tris[0]);
		if (ntris <= 0)
		{
			// Bad triangulation, should not happen.
/*			printf("\tconst float bmin[3] = {%ff,%ff,%ff};\n", cset.bmin[0], cset.bmin[1], cset.bmin[2]);
			printf("\tconst float cs = %ff;\n", cset.cs);
			printf("\tconst float ch = %ff;\n", cset.ch);
			printf("\tconst int verts[] = {\n");
			for (int k = 0; k < cont.nverts; ++k)
			{
				const int* v = &cont.verts[k*4];
				printf("\t\t%d,%d,%d,%d,\n", v[0], v[1], v[2], v[3]);
			}
			printf("\t};\n\tconst int nverts = sizeof(verts)/(sizeof(int)*4);\n");*/
			ctx->log(RC_LOG_WARNING, "rcBuildPolyMesh: Bad triangulation Contour %d.", i);
			ntris = -ntris;
		}
				
		// Add and merge vertices.
		for (int j = 0; j < cont.nverts; ++j)
		{
			const int* v = &cont.verts[j*4];
			indices[j] = addVertex((unsigned short)v[0], (unsigned short)v[1], (unsigned short)v[2],
								   mesh.verts, firstVert, nextVert, mesh.nverts);
			if (v[3] & RC_BORDER_VERTEX)
			{
				// This vertex should be removed.
				vflags[indices[j]] = 1;
			}
		}

		// Build initial polygons.
		int npolys = 0;
		memset(polys, 0xff, maxVertsPerCont*nvp*sizeof(unsigned short));
		for (int j = 0; j < ntris; ++j)
		{
			int* t = &tris[j*3];
			if (t[0] != t[1] && t[0] != t[2] && t[1] != t[2])
			{
				polys[npolys*nvp+0] = (unsigned short)indices[t[0]];
				polys[npolys*nvp+1] = (unsigned short)indices[t[1]];
				polys[npolys*nvp+2] = (unsigned short)indices[t[2]];
				npolys++;
			}
		}
		if (!npolys)
			continue;
		
		// Merge polygons.
		if (nvp > 3)
		{
			for(;;)
			{
				// Find best polygons to merge.
				int bestMergeVal = 0;
				int bestPa = 0, bestPb = 0, bestEa = 0, bestEb = 0;
				
				for (int j = 0; j < npolys-1; ++j)
				{
					unsigned short* pj = &polys[j*nvp];
					for (int k = j+1; k < npolys; ++k)
					{
						unsigned short* pk = &polys[k*nvp];
						int ea, eb;
						int v = getPolyMergeValue(pj, pk, mesh.verts, ea, eb, nvp);
						if (v > bestMergeVal)
						{
							bestMergeVal = v;
							bestPa = j;
							bestPb = k;
							bestEa = ea;
							bestEb = eb;
						}
					}
				}
				
				if (bestMergeVal > 0)
				{
					// Found best, merge.
					unsigned short* pa = &polys[bestPa*nvp];
					unsigned short* pb = &polys[bestPb*nvp];
					mergePolys(pa, pb, bestEa, bestEb, tmpPoly, nvp);
					unsigned short* lastPoly = &polys[(npolys-1)*nvp];
					if (pb != lastPoly)
						memcpy(pb, lastPoly, sizeof(unsigned short)*nvp);
					npolys--;
				}
				else
				{
					// Could not merge any polygons, stop.
					break;
				}
			}
		}
		
		// Store polygons.
		for (int j = 0; j < npolys; ++j)
		{
			unsigned short* p = &mesh.polys[mesh.npolys*nvp*2];
			unsigned short* q = &polys[j*nvp];
			for (int k = 0; k < nvp; ++k)
				p[k] = q[k];
			mesh.regs[mesh.npolys] = cont.reg;
			mesh.areas[mesh.npolys] = cont.area;
			mesh.npolys++;
			if (mesh.npolys > maxTris)
			{
				ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many polygons %d (max:%d).", mesh.npolys, maxTris);
				return false;
			}
		}
	}
	
	
	// Remove edge vertices.
	for (int i = 0; i < mesh.nverts; ++i)
	{
		if (vflags[i])
		{
			if (!canRemoveVertex(ctx, mesh, (unsigned short)i))
				continue;
			if (!removeVertex(ctx, mesh, (unsigned short)i, maxTris))
			{
				// Failed to remove vertex
				ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Failed to remove edge vertex %d.", i);
				return false;
			}
			// Remove vertex
			// Note: mesh.nverts is already decremented inside removeVertex()!
			// Fixup vertex flags
			for (int j = i; j < mesh.nverts; ++j)
				vflags[j] = vflags[j+1];
			--i;
		}
	}
	
	// Calculate adjacency.
	if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, nvp))
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Adjacency failed.");
		return false;
	}
	
	// Find portal edges
	if (mesh.borderSize > 0)
	{
		const int w = cset.width;
		const int h = cset.height;
		for (int i = 0; i < mesh.npolys; ++i)
		{
			unsigned short* p = &mesh.polys[i*2*nvp];
			for (int j = 0; j < nvp; ++j)
			{
				if (p[j] == RC_MESH_NULL_IDX) break;
				// Skip connected edges.
				if (p[nvp+j] != RC_MESH_NULL_IDX)
					continue;
				int nj = j+1;
				if (nj >= nvp || p[nj] == RC_MESH_NULL_IDX) nj = 0;
				const unsigned short* va = &mesh.verts[p[j]*3];
				const unsigned short* vb = &mesh.verts[p[nj]*3];

				if ((int)va[0] == 0 && (int)vb[0] == 0)
					p[nvp+j] = 0x8000 | 0;
				else if ((int)va[2] == h && (int)vb[2] == h)
					p[nvp+j] = 0x8000 | 1;
				else if ((int)va[0] == w && (int)vb[0] == w)
					p[nvp+j] = 0x8000 | 2;
				else if ((int)va[2] == 0 && (int)vb[2] == 0)
					p[nvp+j] = 0x8000 | 3;
			}
		}
	}

	// Just allocate the mesh flags array. The user is resposible to fill it.
	mesh.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*mesh.npolys, RC_ALLOC_PERM);
	if (!mesh.flags)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.flags' (%d).", mesh.npolys);
		return false;
	}
	memset(mesh.flags, 0, sizeof(unsigned short) * mesh.npolys);
	
	if (mesh.nverts > 0xffff)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff);
	}
	if (mesh.npolys > 0xffff)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff);
	}
	
	ctx->stopTimer(RC_TIMER_BUILD_POLYMESH);
	
	return true;
}
Exemple #3
0
void Spline::addVertices(const unsigned int index, const std::vector<sf::Vector2f>& positions)
{
	for (auto& position : positions)
		addVertex(index, position);
}
void IcoSphere::create(int recursionLevel)
{
	vertices.clear();
	lineIndices.clear();
	triangleIndices.clear();
	faces.clear();
	middlePointIndexCache.clear();
	index = 0;
 
	float t = (1.0f + Ogre::Math::Sqrt(5.0f)) / 2.0f;
 
	addVertex(Ogre::Vector3(-1.0f,  t,  0.0f));
	addVertex(Ogre::Vector3( 1.0f,  t,  0.0f));
	addVertex(Ogre::Vector3(-1.0f, -t,  0.0f));
	addVertex(Ogre::Vector3( 1.0f, -t,  0.0f));
 
	addVertex(Ogre::Vector3( 0.0f, -1.0f,  t));
	addVertex(Ogre::Vector3( 0.0f,  1.0f,  t));
	addVertex(Ogre::Vector3( 0.0f, -1.0f, -t));
	addVertex(Ogre::Vector3( 0.0f,  1.0f, -t));
 
	addVertex(Ogre::Vector3( t,  0.0f, -1.0f));
	addVertex(Ogre::Vector3( t,  0.0f,  1.0f));
	addVertex(Ogre::Vector3(-t,  0.0f, -1.0f));
	addVertex(Ogre::Vector3(-t,  0.0f,  1.0f));
 
	addFace(0, 11, 5);
	addFace(0, 5, 1);
	addFace(0, 1, 7);
	addFace(0, 7, 10);
	addFace(0, 10, 11);
 
	addFace(1, 5, 9);
	addFace(5, 11, 4);
	addFace(11, 10, 2);
	addFace(10, 7, 6);
	addFace(7, 1, 8);
 
	addFace(3, 9, 4);
	addFace(3, 4, 2);
	addFace(3, 2, 6);
	addFace(3, 6, 8);
	addFace(3, 8, 9);
 
	addFace(4, 9, 5);
	addFace(2, 4, 11);
	addFace(6, 2, 10);
	addFace(8, 6, 7);
	addFace(9, 8, 1);
 
	addLineIndices(1, 0);
	addLineIndices(1, 5);
	addLineIndices(1, 7);
	addLineIndices(1, 8);
	addLineIndices(1, 9);
 
	addLineIndices(2, 3);
	addLineIndices(2, 4);
	addLineIndices(2, 6);
	addLineIndices(2, 10);
	addLineIndices(2, 11);
 
	addLineIndices(0, 5);
	addLineIndices(5, 9);
	addLineIndices(9, 8);
	addLineIndices(8, 7);
	addLineIndices(7, 0);
 
	addLineIndices(10, 11);
	addLineIndices(11, 4);
	addLineIndices(4, 3);
	addLineIndices(3, 6);
	addLineIndices(6, 10);
 
	addLineIndices(0, 11);
	addLineIndices(11, 5);
	addLineIndices(5, 4);
	addLineIndices(4, 9);
	addLineIndices(9, 3);
	addLineIndices(3, 8);
	addLineIndices(8, 6);
	addLineIndices(6, 7);
	addLineIndices(7, 10);
	addLineIndices(10, 0);
 
	for (int i = 0; i < recursionLevel; i++)
	{
		std::list<TriangleIndices> faces2;
 
		for (std::list<TriangleIndices>::iterator j = faces.begin(); j != faces.end(); j++)
		{
			TriangleIndices f = *j;
			int a = getMiddlePoint(f.v1, f.v2);
			int b = getMiddlePoint(f.v2, f.v3);
			int c = getMiddlePoint(f.v3, f.v1);
 
			removeLineIndices(f.v1, f.v2);
			removeLineIndices(f.v2, f.v3);
			removeLineIndices(f.v3, f.v1);
 
			faces2.push_back(TriangleIndices(f.v1, a, c));
			faces2.push_back(TriangleIndices(f.v2, b, a));
			faces2.push_back(TriangleIndices(f.v3, c, b));
			faces2.push_back(TriangleIndices(a, b, c));
 
			addTriangleLines(f.v1, a, c);
			addTriangleLines(f.v2, b, a);
			addTriangleLines(f.v3, c, b);
		}
 
		faces = faces2;
	}
}
Exemple #5
0
void FileGraphics::initializeGL()
{
    if (fcontroller->isOpenedFile())
    {
        int rows, cols;
        DemInterface* demObject = fcontroller->getDemObject();
        cols = demObject->getCols();
        rows = demObject->getRows();
        int centerX = cols/2;
        float posX, posY = 0;
        scale = (float)getSize().width() / (float)cols;
        int centerY = rows/2;
        ColorRGBA color;
        std::vector<float> band_data = demObject->readDem();
        maxZ = demObject->maxHeight();
        int step = demObject->getZoom();

        for (int k = 0; k < rows; k=k+step) {
            posY = (float)(centerY - k)/centerY;
            for (int j =0; j < cols; j=j+step) {

                posX = (float)(j - centerX)/centerX;
                if (k < rows -step && j-step >= 0) {
                    color = colorController->getColor(band_data[k*rows + j]);
                    addVertex(
                                Vertex(
                                    QVector3D(posX, posY, getZCoordinate(band_data[k*rows + j])),
                                    QVector3D(color.r, color.g, color.b)
                                )
                            );

                    float nposY = (float)(centerY - (k +step))/centerY;
                    color = colorController->getColor(band_data[(k+step)*rows + j]);
                    addVertex(
                                Vertex(
                                    QVector3D(posX, nposY, getZCoordinate(band_data[(k+step)*rows + j])),
                                    QVector3D(color.r, color.g, color.b)
                                )
                            );

                    float nposX = (float)(j - step - centerX)/centerX;
                    color = colorController->getColor(band_data[k*rows + j - step]);
                    addVertex(
                                Vertex(
                                    QVector3D(nposX, posY, getZCoordinate(band_data[k*rows + j - step])),
                                    QVector3D(color.r, color.g, color.b)
                                )
                            );
                }
                if (k - step >= 0 && j < cols -step) {
                    color = colorController->getColor(band_data[k*rows + j]);
                    addVertex(
                                Vertex(
                                    QVector3D(posX, posY, getZCoordinate(band_data[k*rows + j])),
                                    QVector3D(color.r, color.g, color.b)
                                )
                            );

                    float nposY = (float)(centerY - (k -step))/centerY;
                    color = colorController->getColor(band_data[(k-step)*rows + j]);
                    addVertex(
                                Vertex(
                                    QVector3D(posX, nposY, getZCoordinate(band_data[(k-step)*rows + j])),
                                    QVector3D(color.r, color.g, color.b)
                                )
                            );

                    float nposX = (float)(j +step - centerX)/centerX;
                    color = colorController->getColor(band_data[k*rows + j+step]);
                    addVertex(
                                Vertex(
                                    QVector3D(nposX, posY, getZCoordinate(band_data[k*rows + j+step])),
                                    QVector3D(color.r, color.g, color.b)
                                )
                            );
                }

            }
        }
        bsController->generateBaseSupport();
    }
}
//----------------------------------------
void ofxBox2dPolygon::addVertexes(vector <ofVec2f> &pts) {
	for (int i=0; i<pts.size(); i++) {
		addVertex(pts[i].x, pts[i].y);
	}
}
void Mesh::addCappedCylinder(const Vector3 &p1, const Vector3 &p2, float radius1, float radius2,
    unsigned detail1, unsigned detail2, const Color &color, const Vector3 &up, uint8_t existence)
{
  float fdetail1 = static_cast<float>(detail1);
  float fdetail2 = static_cast<float>(detail2);
  Vector3 unit_forward = normalize(p2 - p1);
  Vector3 unit_up = normalize(up);

  // Might easily degenerate, prevent it.
  if(dnload_fabsf(dot_product(unit_up, unit_forward)) > 0.999f)
  {
    unit_up = Vector3(0.0f, 0.0f, 1.0f);
  }

  Vector3 unit_right = normalize(cross_product(unit_forward, unit_up));
  unit_up = normalize(cross_product(unit_right, unit_forward));

  //std::cout << unit_right << " ; " << unit_up << std::endl;

  unsigned index_base = static_cast<unsigned>(m_vertices.getSize());

  Vector3 tip1 = p1 - (radius1 * unit_forward);
  Vector3 tip2 = p2 + (radius2 * unit_forward);

  if(existence & SIDE_FRONT)
  {
    addVertex(tip1, color);

    // Create vertices for first cap
    for(unsigned jj = 0; jj < detail2; ++jj)
    {
      float t = static_cast<float>(jj+1)/fdetail2;
      float r = dnload_sinf(t * static_cast<float>(M_PI / 2.0)) * radius1;
      Vector3 c = tip1 + (t * t * unit_forward);

      for(unsigned ii = 0; ii < detail1; ++ii)
      {
        float angle = static_cast<float>(ii) / fdetail1 * static_cast<float>(M_PI * 2.0) +
          static_cast<float>(M_PI) / fdetail1;
        float ca = dnload_cosf(angle);
        float sa = dnload_sinf(angle);

        addVertex(c + ca * unit_right * r + sa * unit_up * r, color);
      }
    }

    // Create tip of the cap.
    for(unsigned ii = 0; ii < detail1; ++ii)
    {
      unsigned ii_next = (ii+1) % detail1;
      addFace(index_base, ii+index_base+1, ii_next+index_base+1);
    }

    // The rest of the cap...
    for(unsigned jj = 0; jj < detail2-1; ++jj)
    {
      unsigned local_base = (jj*detail1) + 1 + index_base;
      for(unsigned ii = 0; ii < detail1; ++ii)
      {
        unsigned next1 = (ii+1) % detail1;
        unsigned next2 = next1 + detail1;
        addFace(next2+local_base, next1+local_base, ii+local_base, ii+detail1+local_base);
      }
    }
  }
  else
  {
    for(unsigned ii = 0; ii < detail1; ++ii)
    {
      float angle = static_cast<float>(ii) / fdetail1 * static_cast<float>(M_PI * 2.0) +
        static_cast<float>(M_PI) / fdetail1;
      float ca = dnload_cosf(angle);
      float sa = dnload_sinf(angle);

      addVertex(p1 + ca * unit_right * radius1 + sa * unit_up * radius1, color);
    }
  }

  index_base = static_cast<unsigned>(m_vertices.getSize());

  if(existence & SIDE_BACK)
  {
    // Create vertices for second cap
    for(unsigned jj = 0; jj < detail2; ++jj)
    {
      float t = static_cast<float>(jj)/fdetail2;
      float r = dnload_sinf((1.0f-t) * static_cast<float>(M_PI / 2.0)) * radius2;
      Vector3 c = p2 + (t * unit_forward);

      for(unsigned ii = 0; ii < detail1; ++ii)
      {
        float angle = static_cast<float>(ii) / fdetail1 * static_cast<float>(M_PI * 2.0) +
          static_cast<float>(M_PI) / fdetail1;
        float ca = dnload_cosf(angle);
        float sa = dnload_sinf(angle);

        addVertex(c + ca * unit_right * r + sa * unit_up * r, color);
      }
    }

    addVertex(tip2, color);
  }
  else
  {
    for(unsigned ii = 0; (ii < detail1); ++ii)
    {
      float angle = static_cast<float>(ii) / fdetail1 * static_cast<float>(M_PI * 2.0) +
        static_cast<float>(M_PI) / fdetail1;
      float ca = dnload_cosf(angle);
      float sa = dnload_sinf(angle);

      addVertex(p2 + ca * unit_right * radius2 + sa * unit_up * radius1, color);
    }
  }

  // Mid-part
  for(unsigned ii = 0; ii < detail1; ++ii)
  {
    unsigned index_base2 = index_base - detail1;
    unsigned next = (ii+1) % detail1;
    addFace(index_base2+ii, index_base+ii, index_base+next, index_base2+next);
  }

  if(existence & SIDE_BACK)
  {
    // Faces for the second cap
    for(unsigned jj = 0; jj < detail2-1; ++jj)
    {
      unsigned local_base = (jj*detail1) + index_base;
      for(unsigned ii = 0; ii < detail1; ++ii)
      {
        unsigned next1 = (ii+1) % detail1;
        unsigned next2 = next1 + detail1;
        addFace(next2+local_base, next1+local_base, ii+local_base, ii+detail1+local_base);
      }
    }

    index_base = static_cast<unsigned>(m_vertices.getSize()) - 1;
    unsigned index_base2 = index_base - detail1 - 1;

    // Create tip of the cap.
    for(unsigned ii = 0; ii < detail1; ++ii)
    {
      unsigned next = (ii+1) % detail1;
      addFace(index_base, index_base2+next, index_base2+ii);
    }
  }
}
Exemple #8
0
// auxiliars
void CRender::auxAxis() {
	setLineWidth(3.0f);
	setColor(1.0f,0.0,0.0);
	beginShapeLines();
		addVertex(0.0f,0.0f,0.0f);
		addVertex(1000.0f,0.0f,0.0f); // X
	endShape();
	
	enableLineStipple();
	setLineStipple(1,0xaaaa);
	
	beginShapeLines();
		addVertex(0.0f,0.0f,0.0f);
		addVertex(-1000.0f,0.0f,0.0f); // X neg
	endShape();
	disableLineStipple();
	
	setColor(0.0f,1.0,0.0);
	beginShapeLines();
		addVertex(0.0f,0.0f,0.0f);
		addVertex(0.0f,1000.0f,0.0f); // y
	endShape();
	
	enableLineStipple();
	beginShapeLines();
		addVertex(0.0f,0.0f,0.0f);
		addVertex(0.0f,-1000.0f,0.0f); // y neg
	endShape();
	disableLineStipple();
	
	setColor(0.0f,0.0,1.0);
	beginShapeLines();
	addVertex(0.0f,0.0f,0.0f);
	addVertex(0.0f,0.0f,1000.0f); // z
	endShape();
	
	enableLineStipple();
	beginShapeLines();
	addVertex(0.0f,0.0f,0.0f);
	addVertex(0.0f,0.0f,-1000.0f); // z neg
	endShape();
	disableLineStipple();
	setLineWidth(1.0f);
	
}
Exemple #9
0
bool rcMeshLoaderObj::load(const char* filename)
{
    char* buf = 0;
    FILE* fp = fopen(filename, "rb");
    if (!fp)
        return false;
    fseek(fp, 0, SEEK_END);
    long bufSize = ftell(fp);
    if (bufSize < 0)
    {
        fclose(fp);
        return false;
    }
    fseek(fp, 0, SEEK_SET);
    buf = new char[bufSize];
    if (!buf)
    {
        fclose(fp);
        return false;
    }
    size_t readSize = fread(buf, bufSize, 1, fp);
    fclose(fp);

    if (readSize != (size_t) bufSize) 
    {
        delete [] buf;
        return false;
    }

    char* src = buf;
    char* srcEnd = buf + bufSize;
    char row[512];
    int face[32];
    float x,y,z;
    int nv;
    int vcap = 0;
    int tcap = 0;
    
    while (src < srcEnd)
    {
        // Parse one row
        row[0] = '\0';
        src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
        // Skip comments
        if (row[0] == '#') continue;
        if (row[0] == 'v' && row[1] != 'n' && row[1] != 't')
        {
            // Vertex pos
            sscanf(row+1, "%f %f %f", &x, &y, &z);
            addVertex(x, y, z, vcap);
        }
        if (row[0] == 'f')
        {
            // Faces
            nv = parseFace(row+1, face, 32, m_vertCount);
            for (int i = 2; i < nv; ++i)
            {
                const int a = face[0];
                const int b = face[i-1];
                const int c = face[i];
                if (a < 0 || a >= m_vertCount || b < 0 || b >= m_vertCount || c < 0 || c >= m_vertCount)
                    continue;
                addTriangle(a, b, c, tcap);
            }
        }
    }

    delete [] buf;

    // Calculate normals.
    m_normals = new float[m_triCount*3];
    for (int i = 0; i < m_triCount*3; i += 3)
    {
        const float* v0 = &m_verts[m_tris[i]*3];
        const float* v1 = &m_verts[m_tris[i+1]*3];
        const float* v2 = &m_verts[m_tris[i+2]*3];
        float e0[3], e1[3];
        for (int j = 0; j < 3; ++j)
        {
            e0[j] = v1[j] - v0[j];
            e1[j] = v2[j] - v0[j];
        }
        float* n = &m_normals[i];
        n[0] = e0[1]*e1[2] - e0[2]*e1[1];
        n[1] = e0[2]*e1[0] - e0[0]*e1[2];
        n[2] = e0[0]*e1[1] - e0[1]*e1[0];
        float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
        if (d > 0)
        {
            d = 1.0f/d;
            n[0] *= d;
            n[1] *= d;
            n[2] *= d;
        }
    }
    
    strncpy(m_filename, filename, sizeof(m_filename));
    m_filename[sizeof(m_filename)-1] = '\0';
    
    return true;
}
Exemple #10
0
 Grid(Vec3 pts): Grid() {
   addVertex(pts); 
 }
Exemple #11
0
		Mesh::Mesh(istream &is, bool calculateEdges) : calculateEdges(calculateEdges) {
			FileId id;												// Read File header
			get(is, id);

			if (!is) {
				console::print(1.0f, 0.0f, 0.0f, "Failed to load mesh!");
				return;
			}

			if (id != string2id("mESH")) {
				console::print(1.0f, 0.0f, 0.0f, "Not a mesh file!");
				return;
			}

			FileVersion ver;
			get(is, ver);

			if (ver.major != 1 || ver.minor != 0) {
				console::print(1.0f, 0.0f, 0.0f, "Unknown mesh version!");
				return;
			}

			MeshHeader header;										// Read mesh file header
			get(is, header);									

			for (dword i = 0; i < header.textures; ++i) {			// Read textures
				char name[256];
				byte length;
				get(is, length);
				is.read(name, (int)length + 1);
				addTexture(name);
			}

			for (dword i = 0; i < header.materials; i++) {			// Read materials
				addMaterial(Material(is));
			}

			for (dword i = 0; i < header.vertices; i++) {			// Read vertices
				Vector3 v;
				get(is, v[0]);
				get(is, v[1]);
				get(is, v[2]);
				addVertex(v);
			}
			
			for (dword i = 0; i < header.vertices; i++) {			// Read normals
				Vector3 n;
				get(is, n[0]);
				get(is, n[1]);
				get(is, n[2]);
				setNormal(i, n);
			}
			
			for (dword i = 0; i < header.vertices; i++) {			// Read texture coordinates
				Vector2 uv;
				get(is, uv[0]);
				get(is, uv[1]);
				addTexCoord(uv);
			}
			
			for (dword i = 0; i < header.triangles; i++) {			// Read triangles
				Triangle tri;
				get(is, tri.v[0]);
				get(is, tri.v[1]);
				get(is, tri.v[2]);
				get(is, tri.texture);
				get(is, tri.material);
				tri.uv[0] = tri.v[0];
				tri.uv[1] = tri.v[1];
				tri.uv[2] = tri.v[2];
				addTriangle(tri);
			}
			
			for (dword i = 0; i < header.edges; i++) {				// Read edges
				Edge e;
				get(is, e.v[0]);
				get(is, e.v[1]);
				get(is, e.plane[0]);
				get(is, e.plane[1]);
				if (!calculateEdges) addEdge(e);
			}
		}
Exemple #12
0
 Grid(initializer_list<initializer_list<double > > pts):Grid() {
   addVertex(pts);
 }
Exemple #13
0
 void addVertex(initializer_list<initializer_list<double > > pts) {
    for (auto i = pts.begin(); i != pts.end(); ++i) { addVertex(*i); }    
 }
Exemple #14
0
 void addVertex(vector<Vec3 > pts) {
   for (auto pt : pts) { addVertex(pt); }
 }
void QgsMapToolReshape::cadCanvasReleaseEvent( QgsMapMouseEvent * e )
{
  //check if we operate on a vector layer //todo: move this to a function in parent class to avoid duplication
  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );

  if ( !vlayer )
  {
    notifyNotVectorLayer();
    return;
  }

  if ( !vlayer->isEditable() )
  {
    notifyNotEditableLayer();
    return;
  }

  //add point to list and to rubber band
  if ( e->button() == Qt::LeftButton )
  {
    int error = addVertex( e->mapPoint(), e->mapPointMatch() );
    if ( error == 1 )
    {
      //current layer is not a vector layer
      return;
    }
    else if ( error == 2 )
    {
      //problem with coordinate transformation
      emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING );
      return;
    }

    startCapturing();
  }
  else if ( e->button() == Qt::RightButton )
  {
    deleteTempRubberBand();

    //find out bounding box of mCaptureList
    if ( size() < 1 )
    {
      stopCapturing();
      return;
    }
    QgsPoint firstPoint = points().at( 0 );
    QgsRectangle bbox( firstPoint.x(), firstPoint.y(), firstPoint.x(), firstPoint.y() );
    for ( int i = 1; i < size(); ++i )
    {
      bbox.combineExtentWith( points().at( i ).x(), points().at( i ).y() );
    }

    //query all the features that intersect bounding box of capture line
    QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) );
    QgsFeature f;
    int reshapeReturn;
    bool reshapeDone = false;

    vlayer->beginEditCommand( tr( "Reshape" ) );
    while ( fit.nextFeature( f ) )
    {
      //query geometry
      //call geometry->reshape(mCaptureList)
      //register changed geometry in vector layer
      QgsGeometry geom = f.geometry();
      if ( !geom.isEmpty() )
      {
        reshapeReturn = geom.reshapeGeometry( points() );
        if ( reshapeReturn == 0 )
        {
          //avoid intersections on polygon layers
          if ( vlayer->geometryType() == QgsWkbTypes::PolygonGeometry )
          {
            //ignore all current layer features as they should be reshaped too
            QHash<QgsVectorLayer*, QSet<QgsFeatureId> > ignoreFeatures;
            ignoreFeatures.insert( vlayer, vlayer->allFeatureIds() );

            if ( geom.avoidIntersections( ignoreFeatures ) != 0 )
            {
              emit messageEmitted( tr( "An error was reported during intersection removal" ), QgsMessageBar::CRITICAL );
              vlayer->destroyEditCommand();
              stopCapturing();
              return;
            }

            if ( geom.isGeosEmpty() ) //intersection removal might have removed the whole geometry
            {
              emit messageEmitted( tr( "The feature cannot be reshaped because the resulting geometry is empty" ), QgsMessageBar::CRITICAL );
              vlayer->destroyEditCommand();
              stopCapturing();
              return;
            }
          }

          vlayer->changeGeometry( f.id(), geom );
          reshapeDone = true;
        }
      }
    }

    if ( reshapeDone )
    {
      vlayer->endEditCommand();
    }
    else
    {
      vlayer->destroyEditCommand();
    }

    stopCapturing();
  }
}
 void lineTo(const osg::Vec2& pos)
 {
     addVertex( osg::Vec3(pos.x(),pos.y(),0) );
 }
//----------------------------------------
void ofxBox2dPolygon::addVertexes(ofPolyline &polyline) {
	for (int i=0; i<polyline.size(); i++) {
		addVertex(polyline[i].x, polyline[i].y);
	}
}
Exemple #18
0
Shader::Shader(const char* vert_src, const char* frag_src)
{
  g_shProg = glCreateProgram();
  addVertex(vert_src);
  addFragment(frag_src);
}
Exemple #19
0
bool OptimizableGraph::load(istream& is, bool createEdges)
{
  // scna for the paramers in the whole file
  if (!_parameters.read(is))
    return false;
  cerr << "Loaded " << _parameters.size() << " parameters" << endl;
  is.clear();
  is.seekg(ios_base::beg);
  set<string> warnedUnknownTypes;
  stringstream currentLine;
  string token;

  Factory* factory = Factory::instance();
  HyperGraph::GraphElemBitset elemBitset;
  elemBitset[HyperGraph::HGET_PARAMETER] = 1;
  elemBitset.flip();

  Vertex* previousVertex = 0;

  while (1) {
    int bytesRead = readLine(is, currentLine);
    if (bytesRead == -1)
      break;
    currentLine >> token;
    if (bytesRead == 0 || token.size() == 0 || token[0] == '#')
      continue;

    // handle commands encoded in the file
    bool handledCommand = false;
    
    if (token == "FIX") {
      handledCommand = true;
      int id;
      while (currentLine >> id) {
        OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(vertex(id));
        if (v) {
#        ifndef NDEBUG
          cerr << "Fixing vertex " << v->id() << endl;
#        endif
          v->setFixed(true);
        } else {
          cerr << "Warning: Unable to fix vertex with id " << id << ". Not found in the graph." << endl;
        }
      }
    }

    if (handledCommand)
      continue;
     
    // do the mapping to an internal type if it matches
    if (_renamedTypesLookup.size() > 0) {
      map<string, string>::const_iterator foundIt = _renamedTypesLookup.find(token);
      if (foundIt != _renamedTypesLookup.end()) {
        token = foundIt->second;
      }
    }

    if (! factory->knowsTag(token)) {
      if (warnedUnknownTypes.count(token) != 1) {
        warnedUnknownTypes.insert(token);
        cerr << CL_RED(__PRETTY_FUNCTION__ << " unknown type: " << token) << endl;
      }
      continue;
    }

    HyperGraph::HyperGraphElement* element = factory->construct(token, elemBitset);

    if (dynamic_cast<Vertex*>(element)) { // it's a vertex type
      Vertex* v = static_cast<Vertex*>(element);
      int id;
      currentLine >> id;
      bool r = v->read(currentLine);
      if (! r)
        cerr << __PRETTY_FUNCTION__ << ": Error reading vertex " << token << " " << id << endl;
      v->setId(id);
      if (!addVertex(v)) {
        cerr << __PRETTY_FUNCTION__ << ": Failure adding Vertex, " << token << " " << id << endl;
        delete v;
      } else {
        previousVertex = v;
      }
    }
Exemple #20
0
bool CalHardwareModel::load(int baseVertexIndex, int startIndex,int maxBonesPerMesh)
{
  if(m_pVertexBuffer==NULL ||  m_pNormalBuffer ==NULL|| m_pWeightBuffer ==NULL || m_pMatrixIndexBuffer ==NULL)
  {
    CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
    return false;   
  }

  int mapId;
  for(mapId = 0; mapId < m_textureCoordNum; mapId++)
  {
    if(m_pTextureCoordBuffer[mapId]==NULL)
    {
      CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
      return false;         
    }  
  } 
  
  m_vectorVertexIndiceUsed.resize(50000);
  int vertexCount=baseVertexIndex;
  int faceIndexCount = startIndex;
        
        // unused.
  //CalCoreSkeleton * pCoreSkeleton = m_pCoreModel->getCoreSkeleton();
  //std::vector< CalCoreBone *>& vectorBone = pCoreSkeleton->getVectorCoreBone();

  // if unspecified, fill with all core mesh ids
  if(m_coreMeshIds.empty())
  {
    for(int coreMeshId = 0; coreMeshId < m_pCoreModel->getCoreMeshCount(); coreMeshId++)
      m_coreMeshIds.push_back(coreMeshId);
  }
    
  for(std::vector<int>::iterator meshIdIt = m_coreMeshIds.begin();meshIdIt != m_coreMeshIds.end(); meshIdIt++)
  {
    int meshId = *meshIdIt;
    CalCoreMesh *pCoreMesh = m_pCoreModel->getCoreMesh(meshId);
    int submeshCount= pCoreMesh->getCoreSubmeshCount();
    int submeshId;
    for(submeshId = 0 ;submeshId < submeshCount ; submeshId++)
    {     
      CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId);
      
      std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pCoreSubmesh->getVectorVertex();
      std::vector<CalCoreSubmesh::Face>& vectorFace = pCoreSubmesh->getVectorFace();
                        // unused.
      //std::vector< std::vector<CalCoreSubmesh::TextureCoordinate> >& vectorTex = pCoreSubmesh->getVectorVectorTextureCoordinate();
      
      CalHardwareMesh hardwareMesh;

      hardwareMesh.meshId = meshId;
      hardwareMesh.submeshId = submeshId;
      
      hardwareMesh.baseVertexIndex=vertexCount;     
      hardwareMesh.startIndex=faceIndexCount;
      hardwareMesh.m_vectorBonesIndices.clear();          
      
      hardwareMesh.vertexCount=0;
      hardwareMesh.faceCount=0;     
      
      int startIndex=hardwareMesh.startIndex;
      
      int faceId;     
      for( faceId =0 ;faceId<pCoreSubmesh->getFaceCount();faceId++)
      {
        if(canAddFace(hardwareMesh,vectorFace[faceId],vectorVertex,maxBonesPerMesh))
        {
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3]=   addVertex(hardwareMesh,vectorFace[faceId].vertexId[0],pCoreSubmesh,maxBonesPerMesh);
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+1]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[1],pCoreSubmesh,maxBonesPerMesh);
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+2]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[2],pCoreSubmesh,maxBonesPerMesh);
          hardwareMesh.faceCount++;
        }
        else
        {
          vertexCount+=hardwareMesh.vertexCount;
          faceIndexCount+=hardwareMesh.faceCount*3;
          hardwareMesh.pCoreMaterial= m_pCoreModel->getCoreMaterial(pCoreSubmesh->getCoreMaterialThreadId());
          
          m_vectorHardwareMesh.push_back(hardwareMesh);
          
          hardwareMesh.baseVertexIndex=vertexCount;
          hardwareMesh.startIndex=faceIndexCount;
          
          hardwareMesh.m_vectorBonesIndices.clear();
          hardwareMesh.vertexCount=0; 
          hardwareMesh.faceCount=0;
          
          startIndex=hardwareMesh.startIndex;
          
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3]=   addVertex(hardwareMesh,vectorFace[faceId].vertexId[0],pCoreSubmesh,maxBonesPerMesh);
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+1]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[1],pCoreSubmesh,maxBonesPerMesh);
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+2]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[2],pCoreSubmesh,maxBonesPerMesh);
          hardwareMesh.faceCount++;         
        }
      }
      
      vertexCount+=hardwareMesh.vertexCount;
      faceIndexCount+=hardwareMesh.faceCount*3;
      hardwareMesh.pCoreMaterial= m_pCoreModel->getCoreMaterial(pCoreSubmesh->getCoreMaterialThreadId());
      
      m_vectorHardwareMesh.push_back(hardwareMesh);
      
    }
  }
  
    m_vectorVertexIndiceUsed.clear();


  m_totalFaceCount=0;
  m_totalVertexCount=0;

  for(size_t hardwareMeshId = 0; hardwareMeshId <  m_vectorHardwareMesh.size(); hardwareMeshId++)
  {
    m_totalFaceCount+=m_vectorHardwareMesh[hardwareMeshId].faceCount;
    m_totalVertexCount+=m_vectorHardwareMesh[hardwareMeshId].vertexCount;
  }

    
    return true;
}  
Exemple #21
0
void GOCube::refreshBuffers() {
	GameObject::refreshBuffers();

	// for centering
	float offsetX = size.x / 2;
	float offsetY = size.y / 2;
	float offsetZ = size.z / 2;

	if (verticesBuff == NULL) {
		//verticesBuff = new vec3f[36];

		// allocate a new buffer
		glGenBuffers(1, &VBOBuffer);
		// bind the buffer object to use
		glBindBuffer(GL_ARRAY_BUFFER, VBOBuffer);
		// allocate enough space for the VBO
		glBufferData(GL_ARRAY_BUFFER, sizeof(vec3f) * 36 * 2, 0, GL_STATIC_DRAW);
	} else {
		glBindBuffer(GL_ARRAY_BUFFER, VBOBuffer);
	}

	verticesBuff = (vec3f*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);

	addVertex(0, 0.0 - offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f);
	addVertex(1, 0.0 - offsetX, 0.0 - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f);
	addVertex(2, size.x - offsetX, 0.0 - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f);
	addVertex(3, size.x - offsetX, 0.0 - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f);
	addVertex(4, size.x - offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f);
	addVertex(5, 0.0 - offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f);

	addVertex(6, -offsetX, size.y - offsetY, -offsetZ, 0.0f, 0.0f, -1.0f);
	addVertex(7, size.x - offsetX, size.y - offsetY, -offsetZ, 0.0f, 0.0f, -1.0f);
	addVertex(8, size.x - offsetX, -offsetY, -offsetZ, 0.0f, 0.0f, -1.0f);
	addVertex(9, size.x - offsetX, -offsetY, -offsetZ, 0.0f, 0.0f, -1.0f);
	addVertex(10, -offsetX, -offsetY, -offsetZ, 0.0f, 0.0f, -1.0f);
	addVertex(11,  -offsetX, size.y - offsetY, -offsetZ, 0.0f, 0.0f, -1.0f);

	addVertex(12, size.x - offsetX, -offsetY, size.z - offsetZ, 1.0f, 0.0f, 0.0f);
	addVertex(13, size.x - offsetX, -offsetY, -offsetZ, 1.0f, 0.0f, 0.0f);
	addVertex(14, size.x - offsetX, size.y - offsetY, size.z - offsetZ, 1.0f, 0.0f, 0.0f);
	addVertex(15, size.x - offsetX, -offsetY, -offsetZ, 1.0f, 0.0f, 0.0f);
	addVertex(16, size.x - offsetX, size.y - offsetY, -offsetZ, 1.0f, 0.0f, 0.0f);
	addVertex(17, size.x - offsetX, size.y - offsetY, size.z - offsetZ, 1.0f, 0.0f, 0.0f);

	addVertex(18, -offsetX, size.y - offsetY, size.z - offsetZ, -1.0f, 0.0f, 0.0f);
	addVertex(19, -offsetX, size.y - offsetY, -offsetZ, -1.0f, 0.0f, 0.0f);
	addVertex(20, -offsetX, -offsetY, -offsetZ, -1.0f, 0.0f, 0.0f);
	addVertex(21, -offsetX, size.y - offsetY, size.z - offsetZ, -1.0f, 0.0f, 0.0f);
	addVertex(22, -offsetX, -offsetY, -offsetZ, -1.0f, 0.0f, 0.0f);
	addVertex(23, -offsetX, -offsetY, size.z - offsetZ, -1.0f, 0.0f, 0.0f);

	addVertex(24, size.x - offsetX, size.y - offsetY, -offsetZ, 0.0f, 1.0f, 0.0f);
	addVertex(25, -offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 1.0f, 0.0f);
	addVertex(26, size.x - offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 1.0f, 0.0f);
	addVertex(27, -offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 1.0f, 0.0f);
	addVertex(28, size.x - offsetX, size.y - offsetY, -offsetZ, 0.0f, 1.0f, 0.0f);
	addVertex(29, -offsetX, size.y - offsetY, -offsetZ, 0.0f, 1.0f, 0.0f);

	addVertex(30, -offsetX, -offsetY, -offsetZ, 0.0f, -1.0f, 0.0f);
	addVertex(31, size.x - offsetX, -offsetY, -offsetZ, 0.0f, -1.0f, 0.0f);
	addVertex(32, -offsetX, -offsetY, size.z - offsetZ, 0.0f, -1.0f, 0.0f);
	addVertex(33, size.x - offsetX, -offsetY, size.z - offsetZ, 0.0f, -1.0f, 0.0f);
	addVertex(34, -offsetX, -offsetY, size.z - offsetZ, 0.0f, -1.0f, 0.0f);
	addVertex(35, size.x - offsetX, -offsetY, -offsetZ, 0.0f, -1.0f, 0.0f);

	//glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vec3f) * 36, verticesBuff);
	glUnmapBuffer(GL_ARRAY_BUFFER);
}
Exemple #22
0
/* ------------------------------------------------------------------------- */
void Mesh_Icosa::fillMesh()
{
	TRACE(">> Mesh_Icosa::fillMesh()");

	// Key values for the icosaedre.
	Real C  = sqrt(5.0)/5;
	Real Bp = (5+sqrt(5.0))/10;
	Real Bm = (5-sqrt(5.0))/10;
	Real Ap = sqrt(Bp);
	Real Am = sqrt(Bm);
	Real r  = mRadius;

	// Generate the 12 vertices of the icosaedre
	// pentagon1 = P1-P5-P4-P3-P2  (CW)
	// pentagon2 = P10-P6-P7-P8-P9 (CW)
	// Do not change this order => it is the index.
	addVertexUV(r, 0,  1,  0, 0.0); // P0  - upper (with U for 1-2-base triangle)

	addVertex (r, Am, C, -Bp); // P1  - penta1 - (Edge : U=0.9)
	addVertex (r,-Am, C, -Bp); // P2  - penta1
	addVertex (r,-Ap, C,  Bm); // P3  - penta1
	addVertex (r, 0,  C, 2*C); // P4  - penta1
	addVertex (r, Ap, C,  Bm); // P5  - penta1
	addVertex (r, Am,-C,  Bp); // P6  - penta2
	addVertex (r,-Am,-C,  Bp); // P7  - penta2
	addVertex (r,-Ap,-C, -Bm); // P8  - penta2
	addVertex (r, 0, -C,-2*C); // P9  - penta2 - (Edge : U=1)
	addVertex (r, Ap,-C, -Bm); // P10 - penta2
	addVertex (r, 0, -1,  0 ); // P11 - lower (7-6-base-triangle)

	// The edge of the texture: we duplicate the vertices
	addVertexUV (r, 0, -C,-2*C, 0.0);  // P12 - border (= P9)
	addVertexUV (r, Am, C,-Bp ,-0.1);  // P13 - border (= P1)

	// The upper vertex has 5 UV coordinates (one is already done = P0)
	addVertexUV (r, 0, 1, 0, 0.2); // P14 = P0 with U for 2-3-base triangle
	addVertexUV (r, 0, 1, 0, 0.4); // P15 = P0 with U for 3-4-base triangle
	addVertexUV (r, 0, 1, 0, 0.6); // P16 = P0 with U for 4-5-base triangle
	addVertexUV (r, 0, 1, 0, 0.8); // P17 = P0 with U for 5-1-base triangle

	// The lower vertex has 5 UV coordinates (one is already done = P11)
	addVertexUV (r, 0,-1, 0, 0.1); // P18 = P11 with U for 12-8-base triangle
	addVertexUV (r, 0,-1, 0, 0.3); // P19 = P11 with U for 8-7-base triangle
	addVertexUV (r, 0,-1, 0, 0.7); // P20 = P11 with U for 6-10-base triangle
	addVertexUV (r, 0,-1, 0, 0.9); // P21 = P11 with U for 10-9-base triangle

	// Central zone (10 triangles)
	addTriangle(10,9,1);
	addTriangle(12,2,13);  // = P1-P2-P9
	addTriangle(12,8,2);   // = P2-P8-P9
	addTriangle(8,3,2);
	addTriangle(8,7,3);
	addTriangle(7,4,3);
	addTriangle(7,6,4);
	addTriangle(6,5,4);
	addTriangle(6,10,5);
	addTriangle(10,1,5);
	// upper zone (5 triangles)
	// upper is P0-14-15-16-17 
	// pentagon1 = P2-P3-P4-P5-P1  (CCW)
	addTriangle(2,0,13); 
	addTriangle(3,14,2); 
	addTriangle(4,15,3); 
	addTriangle(5,16,4); 
	addTriangle(1,17,5); 
	// lower zone (5 triangles) 
	addTriangle(11,6,7);
	addTriangle(18,8,12);
	addTriangle(19,7,8);
	addTriangle(21,9,10);
	addTriangle(20,10,6);


/*	// Central zone (10 triangles)
	mVerticeIndex = 0;
	addTriangle(1,9,10);
	addTriangle(13,2,12);  // = P1-P2-P9
	addTriangle(2,8,12);   // = P2-P8-P9
	addTriangle(2,3,8);
	addTriangle(3,7,8);
	addTriangle(3,4,7);
	addTriangle(4,6,7);
	addTriangle(4,5,6);
	addTriangle(5,10,6);
	addTriangle(5,1,10);
	// upper zone (5 triangles) 
	addTriangle(13,0,2);
	addTriangle(2,14,3);
	addTriangle(3,15,4);
	addTriangle(4,16,5); 
	addTriangle(5,17,1);
	// lower zone (5 triangles) 
	addTriangle(6,10,20);
	addTriangle(7,6,11);
	addTriangle(8,7,19);
	addTriangle(12,8,18);
	addTriangle(10,9,21);
*/
}
void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mLayer );

  if ( !vlayer )
    //if no given layer take the current from canvas
    vlayer = currentVectorLayer();

  if ( !vlayer )
  {
    notifyNotVectorLayer();
    return;
  }

  QgsWkbTypes::Type layerWKBType = vlayer->wkbType();

  QgsVectorDataProvider *provider = vlayer->dataProvider();

  if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) )
  {
    emit messageEmitted( tr( "The data provider for this layer does not support the addition of features." ), Qgis::Warning );
    return;
  }

  if ( !vlayer->isEditable() )
  {
    notifyNotEditableLayer();
    return;
  }

  // POINT CAPTURING
  if ( mode() == CapturePoint )
  {
    if ( e->button() != Qt::LeftButton )
      return;

    //check we only use this tool for point/multipoint layers
    if ( vlayer->geometryType() != QgsWkbTypes::PointGeometry && mCheckGeometryType )
    {
      emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), Qgis::Warning );
      return;
    }

    QgsPoint savePoint; //point in layer coordinates
    bool isMatchPointZ = false;
    try
    {
      QgsPoint fetchPoint;
      int res;
      res = fetchLayerPoint( e->mapPointMatch(), fetchPoint );
      if ( QgsWkbTypes::hasZ( fetchPoint.wkbType() ) )
        isMatchPointZ = true;

      if ( res == 0 )
      {
        if ( isMatchPointZ )
          savePoint = fetchPoint;
        else
          savePoint = QgsPoint( fetchPoint.x(), fetchPoint.y() );
      }
      else
      {
        QgsPointXY layerPoint = toLayerCoordinates( vlayer, e->mapPoint() );
        if ( isMatchPointZ )
          savePoint = QgsPoint( QgsWkbTypes::PointZ, layerPoint.x(), layerPoint.y(), fetchPoint.z() );
        else
          savePoint = QgsPoint( layerPoint.x(), layerPoint.y() );
      }
    }
    catch ( QgsCsException &cse )
    {
      Q_UNUSED( cse );
      emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::Warning );
      return;
    }

    //only do the rest for provider with feature addition support
    //note that for the grass provider, this will return false since
    //grass provider has its own mechanism of feature addition
    if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures )
    {
      QgsFeature f( vlayer->fields(), 0 );

      QgsGeometry g;
      if ( layerWKBType == QgsWkbTypes::Point )
      {
        g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint ) );
      }
      else if ( !QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) )
      {
        g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue() ) );
      }
      else if ( QgsWkbTypes::isMultiType( layerWKBType ) && !QgsWkbTypes::hasZ( layerWKBType ) )
      {
        g = QgsGeometry::fromMultiPointXY( QgsMultiPointXY() << savePoint );
      }
      else if ( QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) )
      {
        QgsMultiPoint *mp = new QgsMultiPoint();
        mp->addGeometry( new QgsPoint( QgsWkbTypes::PointZ, savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue() ) );
        g.set( mp );
      }
      else
      {
        // if layer supports more types (mCheckGeometryType is false)
        g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint ) );
      }

      if ( QgsWkbTypes::hasM( layerWKBType ) )
      {
        g.get()->addMValue();
      }

      f.setGeometry( g );
      f.setValid( true );

      digitized( f );

      // we are done with digitizing for now so instruct advanced digitizing dock to reset its CAD points
      cadDockWidget()->clearPoints();
    }
  }

  // LINE AND POLYGON CAPTURING
  else if ( mode() == CaptureLine || mode() == CapturePolygon )
  {
    //check we only use the line tool for line/multiline layers
    if ( mode() == CaptureLine && vlayer->geometryType() != QgsWkbTypes::LineGeometry && mCheckGeometryType )
    {
      emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), Qgis::Warning );
      return;
    }

    //check we only use the polygon tool for polygon/multipolygon layers
    if ( mode() == CapturePolygon && vlayer->geometryType() != QgsWkbTypes::PolygonGeometry && mCheckGeometryType )
    {
      emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), Qgis::Warning );
      return;
    }

    //add point to list and to rubber band
    if ( e->button() == Qt::LeftButton )
    {
      int error = addVertex( e->mapPoint(), e->mapPointMatch() );
      if ( error == 1 )
      {
        //current layer is not a vector layer
        return;
      }
      else if ( error == 2 )
      {
        //problem with coordinate transformation
        emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::Warning );
        return;
      }

      startCapturing();
    }
    else if ( e->button() == Qt::RightButton )
    {
      // End of string
      deleteTempRubberBand();

      //lines: bail out if there are not at least two vertices
      if ( mode() == CaptureLine && size() < 2 )
      {
        stopCapturing();
        return;
      }

      //polygons: bail out if there are not at least two vertices
      if ( mode() == CapturePolygon && size() < 3 )
      {
        stopCapturing();
        return;
      }

      if ( mode() == CapturePolygon )
      {
        closePolygon();
      }

      //create QgsFeature with wkb representation
      std::unique_ptr< QgsFeature > f( new QgsFeature( vlayer->fields(), 0 ) );

      //does compoundcurve contain circular strings?
      //does provider support circular strings?
      bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
      bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;

      QList<QgsPointLocator::Match> snappingMatchesList;
      QgsCurve *curveToAdd = nullptr;
      if ( hasCurvedSegments && providerSupportsCurvedSegments )
      {
        curveToAdd = captureCurve()->clone();
      }
      else
      {
        curveToAdd = captureCurve()->curveToLine();
        snappingMatchesList = snappingMatches();
      }

      if ( mode() == CaptureLine )
      {
        QgsGeometry g( curveToAdd );
        f->setGeometry( g );
      }
      else
      {
        QgsCurvePolygon *poly = nullptr;
        if ( hasCurvedSegments && providerSupportsCurvedSegments )
        {
          poly = new QgsCurvePolygon();
        }
        else
        {
          poly = new QgsPolygon();
        }
        poly->setExteriorRing( curveToAdd );
        QgsGeometry g( poly );
        f->setGeometry( g );

        QgsGeometry featGeom = f->geometry();
        int avoidIntersectionsReturn = featGeom.avoidIntersections( QgsProject::instance()->avoidIntersectionsLayers() );
        f->setGeometry( featGeom );
        if ( avoidIntersectionsReturn == 1 )
        {
          //not a polygon type. Impossible to get there
        }
        if ( f->geometry().isEmpty() ) //avoid intersection might have removed the whole geometry
        {
          emit messageEmitted( tr( "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ), Qgis::Critical );
          stopCapturing();
          return;
        }
      }
      f->setValid( true );

      digitized( *f );

      stopCapturing();
    }
  }
}
void QgsMapToolAddFeature::canvasMapReleaseEvent( QgsMapMouseEvent* e )
{
  QgsDebugMsg( "entered." );

  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );

  if ( !vlayer )
  {
    notifyNotVectorLayer();
    return;
  }

  QGis::WkbType layerWKBType = vlayer->wkbType();

  QgsVectorDataProvider* provider = vlayer->dataProvider();

  if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) )
  {
    emit messageEmitted( tr( "The data provider for this layer does not support the addition of features." ), QgsMessageBar::WARNING );
    return;
  }

  if ( !vlayer->isEditable() )
  {
    notifyNotEditableLayer();
    return;
  }

  // POINT CAPTURING
  if ( mode() == CapturePoint )
  {
    if ( e->button() != Qt::LeftButton )
      return;

    //check we only use this tool for point/multipoint layers
    if ( vlayer->geometryType() != QGis::Point )
    {
      emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), QgsMessageBar::WARNING );
      return;
    }



    QgsPoint savePoint; //point in layer coordinates
    try
    {
      savePoint = toLayerCoordinates( vlayer, e->mapPoint() );
      QgsDebugMsg( "savePoint = " + savePoint.toString() );
    }
    catch ( QgsCsException &cse )
    {
      Q_UNUSED( cse );
      emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING );
      return;
    }

    //only do the rest for provider with feature addition support
    //note that for the grass provider, this will return false since
    //grass provider has its own mechanism of feature addition
    if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures )
    {
      QgsFeature f( vlayer->pendingFields(), 0 );

      QgsGeometry *g = 0;
      if ( layerWKBType == QGis::WKBPoint || layerWKBType == QGis::WKBPoint25D )
      {
        g = QgsGeometry::fromPoint( savePoint );
      }
      else if ( layerWKBType == QGis::WKBMultiPoint || layerWKBType == QGis::WKBMultiPoint25D )
      {
        g = QgsGeometry::fromMultiPoint( QgsMultiPoint() << savePoint );
      }

      f.setGeometry( g );

      addFeature( vlayer, &f, false );

      mCanvas->refresh();
    }
  }

  // LINE AND POLYGON CAPTURING
  else if ( mode() == CaptureLine || mode() == CapturePolygon )
  {
    //check we only use the line tool for line/multiline layers
    if ( mode() == CaptureLine && vlayer->geometryType() != QGis::Line )
    {
      emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), QgsMessageBar::WARNING );
      return;
    }

    //check we only use the polygon tool for polygon/multipolygon layers
    if ( mode() == CapturePolygon && vlayer->geometryType() != QGis::Polygon )
    {
      emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), QgsMessageBar::WARNING );
      return;
    }

    //add point to list and to rubber band
    if ( e->button() == Qt::LeftButton )
    {
      int error = addVertex( e->mapPoint() );
      if ( error == 1 )
      {
        //current layer is not a vector layer
        return;
      }
      else if ( error == 2 )
      {
        //problem with coordinate transformation
        emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING );
        return;
      }

      startCapturing();
    }
    else if ( e->button() == Qt::RightButton )
    {
      // End of string
      deleteTempRubberBand();

      //lines: bail out if there are not at least two vertices
      if ( mode() == CaptureLine && size() < 2 )
      {
        stopCapturing();
        return;
      }

      //polygons: bail out if there are not at least two vertices
      if ( mode() == CapturePolygon && size() < 3 )
      {
        stopCapturing();
        return;
      }

      //create QgsFeature with wkb representation
      QgsFeature* f = new QgsFeature( vlayer->pendingFields(), 0 );

      QgsGeometry *g;

      if ( mode() == CaptureLine )
      {
        if ( layerWKBType == QGis::WKBLineString || layerWKBType == QGis::WKBLineString25D )
        {
          g = QgsGeometry::fromPolyline( points().toVector() );
        }
        else if ( layerWKBType == QGis::WKBMultiLineString || layerWKBType == QGis::WKBMultiLineString25D )
        {
          g = QgsGeometry::fromMultiPolyline( QgsMultiPolyline() << points().toVector() );
        }
        else
        {
          emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL );
          stopCapturing();
          return; //unknown wkbtype
        }

        f->setGeometry( g );
      }
      else // polygon
      {
        if ( layerWKBType == QGis::WKBPolygon ||  layerWKBType == QGis::WKBPolygon25D )
        {
          g = QgsGeometry::fromPolygon( QgsPolygon() << points().toVector() );
        }
        else if ( layerWKBType == QGis::WKBMultiPolygon ||  layerWKBType == QGis::WKBMultiPolygon25D )
        {
          g = QgsGeometry::fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << points().toVector() ) );
        }
        else
        {
          emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL );
          stopCapturing();
          return; //unknown wkbtype
        }

        if ( !g )
        {
          stopCapturing();
          delete f;
          return; // invalid geometry; one possibility is from duplicate points
        }
        f->setGeometry( g );

        int avoidIntersectionsReturn = f->geometry()->avoidIntersections();
        if ( avoidIntersectionsReturn == 1 )
        {
          //not a polygon type. Impossible to get there
        }
#if 0
        else if ( avoidIntersectionsReturn == 2 ) //MH120131: disable this error message until there is a better way to cope with the single type / multi type problem
        {
          //bail out...
          emit messageEmitted( tr( "The feature could not be added because removing the polygon intersections would change the geometry type" ), QgsMessageBar::CRITICAL );
          delete f;
          stopCapturing();
          return;
        }
#endif
        else if ( avoidIntersectionsReturn == 3 )
        {
          emit messageEmitted( tr( "An error was reported during intersection removal" ), QgsMessageBar::CRITICAL );
        }

        if ( !f->geometry()->asWkb() ) //avoid intersection might have removed the whole geometry
        {
          QString reason;
          if ( avoidIntersectionsReturn != 2 )
          {
            reason = tr( "The feature cannot be added because it's geometry is empty" );
          }
          else
          {
            reason = tr( "The feature cannot be added because it's geometry collapsed due to intersection avoidance" );
          }
          emit messageEmitted( reason, QgsMessageBar::CRITICAL );
          delete f;
          stopCapturing();
          return;
        }
      }

      if ( addFeature( vlayer, f, false ) )
      {
        //add points to other features to keep topology up-to-date
        int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );

        //use always topological editing for avoidIntersection.
        //Otherwise, no way to guarantee the geometries don't have a small gap in between.
        QStringList intersectionLayers = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList" );
        bool avoidIntersection = !intersectionLayers.isEmpty();
        if ( avoidIntersection ) //try to add topological points also to background layers
        {
          QStringList::const_iterator lIt = intersectionLayers.constBegin();
          for ( ; lIt != intersectionLayers.constEnd(); ++lIt )
          {
            QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( *lIt );
            QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( ml );
            //can only add topological points if background layer is editable...
            if ( vl && vl->geometryType() == QGis::Polygon && vl->isEditable() )
            {
              vl->addTopologicalPoints( f->geometry() );
            }
          }
        }
        else if ( topologicalEditing )
        {
          vlayer->addTopologicalPoints( f->geometry() );
        }
      }

      stopCapturing();
    }
  }
}
Exemple #25
0
/// @see rcAllocPolyMesh, rcPolyMesh
bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh)
{
	rcAssert(ctx);
	
	if (!nmeshes || !meshes)
		return true;

	ctx->startTimer(RC_TIMER_MERGE_POLYMESH);

	mesh.nvp = meshes[0]->nvp;
	mesh.cs = meshes[0]->cs;
	mesh.ch = meshes[0]->ch;
	rcVcopy(mesh.bmin, meshes[0]->bmin);
	rcVcopy(mesh.bmax, meshes[0]->bmax);

	int maxVerts = 0;
	int maxPolys = 0;
	int maxVertsPerMesh = 0;
	for (int i = 0; i < nmeshes; ++i)
	{
		rcVmin(mesh.bmin, meshes[i]->bmin);
		rcVmax(mesh.bmax, meshes[i]->bmax);
		maxVertsPerMesh = rcMax(maxVertsPerMesh, meshes[i]->nverts);
		maxVerts += meshes[i]->nverts;
		maxPolys += meshes[i]->npolys;
	}
	
	mesh.nverts = 0;
	mesh.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVerts*3, RC_ALLOC_PERM);
	if (!mesh.verts)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.verts' (%d).", maxVerts*3);
		return false;
	}

	mesh.npolys = 0;
	mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys*2*mesh.nvp, RC_ALLOC_PERM);
	if (!mesh.polys)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.polys' (%d).", maxPolys*2*mesh.nvp);
		return false;
	}
	memset(mesh.polys, 0xff, sizeof(unsigned short)*maxPolys*2*mesh.nvp);

	mesh.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys, RC_ALLOC_PERM);
	if (!mesh.regs)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.regs' (%d).", maxPolys);
		return false;
	}
	memset(mesh.regs, 0, sizeof(unsigned short)*maxPolys);

	mesh.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxPolys, RC_ALLOC_PERM);
	if (!mesh.areas)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.areas' (%d).", maxPolys);
		return false;
	}
	memset(mesh.areas, 0, sizeof(unsigned char)*maxPolys);

	mesh.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys, RC_ALLOC_PERM);
	if (!mesh.flags)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.flags' (%d).", maxPolys);
		return false;
	}
	memset(mesh.flags, 0, sizeof(unsigned short)*maxPolys);
	
	rcScopedDelete<int> nextVert = (int*)rcAlloc(sizeof(int)*maxVerts, RC_ALLOC_TEMP);
	if (!nextVert)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'nextVert' (%d).", maxVerts);
		return false;
	}
	memset(nextVert, 0, sizeof(int)*maxVerts);
	
	rcScopedDelete<int> firstVert = (int*)rcAlloc(sizeof(int)*VERTEX_BUCKET_COUNT, RC_ALLOC_TEMP);
	if (!firstVert)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT);
		return false;
	}
	for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i)
		firstVert[i] = -1;

	rcScopedDelete<unsigned short> vremap = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertsPerMesh, RC_ALLOC_PERM);
	if (!vremap)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'vremap' (%d).", maxVertsPerMesh);
		return false;
	}
	memset(vremap, 0, sizeof(unsigned short)*maxVertsPerMesh);
	
	for (int i = 0; i < nmeshes; ++i)
	{
		const rcPolyMesh* pmesh = meshes[i];
		
		const unsigned short ox = (unsigned short)floorf((pmesh->bmin[0]-mesh.bmin[0])/mesh.cs+0.5f);
		const unsigned short oz = (unsigned short)floorf((pmesh->bmin[2]-mesh.bmin[2])/mesh.cs+0.5f);
		
		bool isMinX = (ox == 0);
		bool isMinZ = (oz == 0);
		bool isMaxX = ((unsigned short)floorf((mesh.bmax[0] - pmesh->bmax[0]) / mesh.cs + 0.5f)) == 0;
		bool isMaxZ = ((unsigned short)floorf((mesh.bmax[2] - pmesh->bmax[2]) / mesh.cs + 0.5f)) == 0;
		bool isOnBorder = (isMinX || isMinZ || isMaxX || isMaxZ);

		for (int j = 0; j < pmesh->nverts; ++j)
		{
			unsigned short* v = &pmesh->verts[j*3];
			vremap[j] = addVertex(v[0]+ox, v[1], v[2]+oz,
								  mesh.verts, firstVert, nextVert, mesh.nverts);
		}
		
		for (int j = 0; j < pmesh->npolys; ++j)
		{
			unsigned short* tgt = &mesh.polys[mesh.npolys*2*mesh.nvp];
			unsigned short* src = &pmesh->polys[j*2*mesh.nvp];
			mesh.regs[mesh.npolys] = pmesh->regs[j];
			mesh.areas[mesh.npolys] = pmesh->areas[j];
			mesh.flags[mesh.npolys] = pmesh->flags[j];
			mesh.npolys++;
			for (int k = 0; k < mesh.nvp; ++k)
			{
				if (src[k] == RC_MESH_NULL_IDX) break;
				tgt[k] = vremap[src[k]];
			}

			if (isOnBorder)
			{
				for (int k = mesh.nvp; k < mesh.nvp * 2; ++k)
				{
					if (src[k] & 0x8000 && src[k] != 0xffff)
					{
						unsigned short dir = src[k] & 0xf;
						switch (dir)
						{
							case 0: // Portal x-
								if (isMinX)
									tgt[k] = src[k];
								break;
							case 1: // Portal z+
								if (isMaxZ)
									tgt[k] = src[k];
								break;
							case 2: // Portal x+
								if (isMaxX)
									tgt[k] = src[k];
								break;
							case 3: // Portal z-
								if (isMinZ)
									tgt[k] = src[k];
								break;
						}
					}
				}
			}
		}
	}

	// Calculate adjacency.
	if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, mesh.nvp))
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Adjacency failed.");
		return false;
	}

	if (mesh.nverts > 0xffff)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff);
	}
	if (mesh.npolys > 0xffff)
	{
		ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff);
	}
	
	ctx->stopTimer(RC_TIMER_MERGE_POLYMESH);
	
	return true;
}
   AppMeshLock MsAppMesh::lockMesh(const AppTime & time, const Matrix<4,4,F32> &objectOffset)
   {
      msMesh *mesh = mMsNode->getMsMesh();

      assert(mesh && "NULL milkshape mesh");

      S32 lastMatIdx = -1;

      // start lists empty
      mFaces.clear();
      mVerts.clear();
      mTVerts.clear();
      mIndices.clear();
      mSmooth.clear();
      mVertId.clear();

      // start out with faces and crop data allocated
      mFaces.resize(msMesh_GetTriangleCount(mesh));

      S32 vCount = msMesh_GetVertexCount(mesh);

      // Transform the vertices by the bounds and scale
      std::vector<Point3D> verts(vCount, Point3D());

      for (int i = 0; i < vCount; i++)
         verts[i] = objectOffset * (getVert(mesh, i) * mMsNode->getScale());

      int numTriangles = mFaces.size();
      for (int i = 0; i < numTriangles; i++)
      {
         msTriangle *msFace = msMesh_GetTriangleAt(mesh, i);
         Primitive &tsFace = mFaces[i];

         // set faces material index
         S32 matIndex = msMesh_GetMaterialIndex(mesh);
         tsFace.type = (matIndex >= 0) ? matIndex : Primitive::NoMaterial;
         tsFace.firstElement = mIndices.size();
         tsFace.numElements = 3;
         tsFace.type |= Primitive::Triangles | Primitive::Indexed;

         // set vertex indices
         word vertIndices[3];
         msTriangle_GetVertexIndices(msFace, vertIndices);

         Point3D vert0 = verts[vertIndices[0]];
         Point3D vert1 = verts[vertIndices[1]];
         Point3D vert2 = verts[vertIndices[2]];

         Point3D norm0 = getNormal(mesh, i, 0);
         Point3D norm1 = getNormal(mesh, i, 1);
         Point3D norm2 = getNormal(mesh, i, 2);

         // set texture vertex indices
         Point2D tvert0 = getTVert(mesh, i, 0);
         Point2D tvert1 = getTVert(mesh, i, 1);
         Point2D tvert2 = getTVert(mesh, i, 2);

         // now add indices (switch order to be CW)
         mIndices.push_back(addVertex(vert0,norm0,tvert0,vertIndices[0]));
         mIndices.push_back(addVertex(vert2,norm2,tvert2,vertIndices[2]));
         mIndices.push_back(addVertex(vert1,norm1,tvert1,vertIndices[1]));

         // if the material is double-sided, add the backface as well
         if (!(tsFace.type & Primitive::NoMaterial))
         {
            bool doubleSided = false;
            MilkshapeMaterial *msMat = mMsNode->getMaterial();
            msMat->getUserPropBool("doubleSided", doubleSided);

            if (doubleSided)
            {
               Primitive backface = tsFace;
               backface.firstElement = mIndices.size();
               mFaces.push_back(backface);

               // add verts with order reversed to get the backface
               mIndices.push_back(addVertex(vert0,-norm0,tvert0,vertIndices[0]));
               mIndices.push_back(addVertex(vert1,-norm1,tvert1,vertIndices[1]));
               mIndices.push_back(addVertex(vert2,-norm2,tvert2,vertIndices[2]));
            }
         }
      }

      return Parent::lockMesh(time,objectOffset);
   }
Exemple #27
0
void Spline::addVertices(const std::vector<sf::Vector2f>& positions)
{
	for (auto& position : positions)
		addVertex(position);
}
void ofxPolyline2Mesh::addVertexes(const vector<ofVec3f>& verts)
{
	for (int i = 0; i < verts.size(); i++)
		addVertex(verts[i]);
}
Exemple #29
0
void Spline::addVertices(const unsigned int numberOfVertices, const sf::Vector2f position)
{
	for (unsigned int i{ 0 }; i < numberOfVertices; ++i)
		addVertex(position);
}
Exemple #30
0
the::mesh::ptr Polygon2d::createMesh(strref name, float zOffset, bool flipTriangles)
{
	std::vector<std::vector<p2t::Point*>> polylines;
	std::vector<std::vector<p2t::Point*>> holes;

	std::vector<Vertex> engineVerts;
	std::vector<uint16_t> engineIndices;

	for(int i = 0;i<polygon.num_contours;i++)
	{
		std::vector<p2t::Point*> polyline;
		for(int j = 0; j < polygon.contour[i].num_vertices; j++)
			polyline.push_back(new p2t::Point(polygon.contour[i].vertex[j].x, polygon.contour[i].vertex[j].y));
		if(polygon.hole[i]==0)
		{
			polylines.push_back(polyline);
		}
		else
		{
			holes.push_back(polyline);
		}
	}

	for(auto i = 0u; i < polylines.size(); i++)
	{
		std::vector<p2t::Point*> polyline = polylines[i];

		p2t::CDT* cdt = new p2t::CDT(polyline);

		for(auto j = 0u; j < holes.size(); j++)
		{
			cdt->AddHole(holes[j]);
		}

		cdt->Triangulate();
		std::vector<p2t::Triangle*> currentOutput = cdt->GetTriangles();

		for(auto i = 0u; i < currentOutput.size(); i++)
		{
			p2t::Triangle *currentTriangle = currentOutput[i];
			Vertex v1 = {{static_cast<float>(currentTriangle->GetPoint(0)->x),static_cast<float>(currentTriangle->GetPoint(0)->y), zOffset}, {1, 1}, {0, 0, flipTriangles?-1.0f:1.0f}};
			Vertex v2 = {{static_cast<float>(currentTriangle->GetPoint(1)->x),static_cast<float>(currentTriangle->GetPoint(1)->y), zOffset}, {1, 1}, {0, 0, flipTriangles?-1.0f:1.0f}};
			Vertex v3 = {{static_cast<float>(currentTriangle->GetPoint(2)->x),static_cast<float>(currentTriangle->GetPoint(2)->y), zOffset}, {1, 1}, {0, 0, flipTriangles?-1.0f:1.0f}};
			int offset = engineVerts.size();

			int t1 = flipTriangles?1:2;
			int t2 = flipTriangles?2:1;

			engineIndices.push_back(offset+0);
			engineIndices.push_back(offset+t2);
			engineIndices.push_back(offset+t1);

			engineVerts.push_back(v1);
			engineVerts.push_back(v2);
			engineVerts.push_back(v3);
		}
		delete cdt;
	}

	for(auto i = 0u; i < polylines.size(); i++)
	{
		std::vector<p2t::Point*> &polyline = polylines[i];
		for(auto item:polyline)
			delete item;
	}
	for(auto i = 0u; i < holes.size(); i++)
	{
		std::vector<p2t::Point*> &hole = holes[i];
		for(auto item:hole)
			delete item;
	}

	auto g = std::make_shared<the::mesh>();
	g->setTag(name);
	g->addVertex(engineVerts);
	g->addSurface(std::move(the::surface(std::move(engineIndices), "plane")));
	g->bind();
	g->setMaterial(the::material::get("def::base"));
	g->setTexture(0, the::texture::get("def::base"));

	return g;
}