Ejemplo n.º 1
0
void ossimQuadTreeWarpNode::removeVertices()
{
   removeVertex(theUlVertex);
   removeVertex(theUrVertex);
   removeVertex(theLrVertex);
   removeVertex(theLlVertex);
}
Ejemplo n.º 2
0
void ossimQuadTreeWarpNode::clear()
{
   theBoundingRect.makeNan();
   theChildren.clear();
   theParent = NULL;
   removeVertex(theUlVertex);
   removeVertex(theUrVertex);
   removeVertex(theLrVertex);
   removeVertex(theLlVertex);
}
Ejemplo n.º 3
0
void Graph::extractFilament(Vertex* v0, Vertex* v1,
							set<VertexPtr> &heap, vector<Primitive*> &primitives) {
	//printf("extractFilament %i %i\n", v0->index, v1->index);
	if(getCycleEdge(v0->index, v1->index)) {
		if(v0->adjacent.size() >= 3) {
			removeEdge(v0->index, v1->index);
			v0 = v1;
			if(v0->adjacent.size() == 1)
				v1 = v0->adjacent[0];
		}
		while(v0->adjacent.size() == 1) {
			v1 = v0->adjacent[0];
			if(getCycleEdge(v0->index, v1->index)) {
				heap.erase(v0);
				removeEdge(v0->index, v1->index);
				removeVertex(v0->index);
				v0 = v1;
			}
			else break;
		}

		if(v0->adjacent.size() == 0) {
			heap.erase(v0);
			removeVertex(v0->index);
		}
	}

	else {
		Primitive* p = new Primitive(PT_FILAMENT);

		if(v0->adjacent.size() >= 3) {
			p->seq.push_back(PrimitiveVertex(v0->x,v0->y,v0->index));
			removeEdge(v0->index, v1->index);
			v0 = v1;
			if(v0->adjacent.size() == 1)
				v1 = v0->adjacent[0];
		}

		while(v0->adjacent.size() == 1) {
			v1 = v0->adjacent[0];
			p->seq.push_back(PrimitiveVertex(v0->x,v0->y,v0->index));
			heap.erase(v0);
			removeEdge(v0->index, v1->index);
			removeVertex(v0->index);
			v0 = v1;
		}

		p->seq.push_back(PrimitiveVertex(v0->x,v0->y,v0->index));
		if(v0->adjacent.size() == 0) {
			heap.erase(v0);
			removeVertex(v0->index);
		}
		primitives.push_back(p);
	}
}
Ejemplo n.º 4
0
void	SpuVoronoiSimplexSolver::reduceVertices (const SpuUsageBitfield& usedVerts)
{
	if ((numVertices() >= 4) && (!usedVerts.usedVertexD))
		removeVertex(3);

	if ((numVertices() >= 3) && (!usedVerts.usedVertexC))
		removeVertex(2);

	if ((numVertices() >= 2) && (!usedVerts.usedVertexB))
		removeVertex(1);
	
	if ((numVertices() >= 1) && (!usedVerts.usedVertexA))
		removeVertex(0);

}
Ejemplo n.º 5
0
void Graph::extractVertex(Vertex* v0, set<VertexPtr> &heap, vector<Primitive*> &primitives) {
	//printf("extractVertex %i\n", v0->index);
	Primitive* p = new Primitive(PT_VERTEX);

	p->seq.push_back(PrimitiveVertex(v0->x,v0->y,v0->index));
	heap.erase(v0);
	removeVertex(v0->index);
	primitives.push_back(p);
}
Ejemplo n.º 6
0
void MeshBuilder::removeUnusedVertices()
{
	for ( int k = 0 ; k < vertices() ; )
	{
		Vertex* vert = getVertex( k );
		if ( 0 == vert->polygons() )
			removeVertex( k );
		else
			++k;
	}
}
Ejemplo n.º 7
0
void ClosureBuffer::updateList(int windowSize){
  for(std::list<VertexTime>::iterator it = _vertexList.begin(); it!= _vertexList.end(); it++){
    (*it).time++;
  }
     
  std::list<VertexTime> tmp(_vertexList);
  for(std::list<VertexTime>::iterator it = tmp.begin(); it!= tmp.end(); it++){
    if ((*it).time >= windowSize) 
      removeVertex((*it).v);
  }
}
Ejemplo n.º 8
0
void graph::removeVertex(const int id)
{
	map<int, vertex*>::iterator itr = nodeMap.find(id);
	if (itr != nodeMap.end())
	{
		removeVertex(itr->second);
	}
	else
	{
		cout << "\n Node doesn't exist \n";
	}
}
Ejemplo n.º 9
0
	void Mesh::assertManifold()
	{
		std::map<Vertex*, std::vector<Triangle *> > triRing;

		// for each triangle
		for( std::vector<Triangle *>::iterator tit = triangles.begin(); tit != triangles.end(); ++tit )
		{
			Triangle *t = *tit;

			for( size_t i=0; i<3; ++i )
				triRing[ t->v[i] ].push_back( t );
		}

		for( std::map<Vertex*, std::vector<Triangle *> >::iterator it = triRing.begin(); it != triRing.end(); ++it )
		{
			Vertex *v = it->first;

			if( it->second.size() < 3 )
			{
				printf( "degenerated vertex detected (referenced by less then 3 triangles) -> removed\n" );

				// remove all triangles referencing v
				for( std::vector<Triangle *>::iterator tit = it->second.begin(); tit != it->second.end(); ++tit )
				{
					Triangle *t = *tit;

					// remove triangle from triangleRings from all reference vertices
					for( size_t i =0;i<3; ++i )
						if( t->v[i] != v )
						{
							triRing[t->v[i]].erase( std::find( triRing[t->v[i]].begin(), triRing[t->v[i]].end(), t ) );
							// TODO: check if new degenerate vertices are created
						}

					// remove the triangle
					removeTriangle( t );
				}

				// remove v itsself
				removeVertex( v );
			}
		}


	}
void ProfileScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent)
{

    if (!isProfileSelected) {
        return;
    }

    if (mouseEvent->button() ==  Qt::RightButton){
        if(ctrl_pressed){
            addVertex(mouseEvent->lastScenePos().toPoint());
        } else if (shift_pressed) {
            //remove point if clicked on a point
            removeVertex();
        } else {
            moveVertex();
        }
    }
}
Ejemplo n.º 11
0
 bool mutate(MutationCfg mcfg)
     {
         // delete some nodes;
         int i;
         BernoulliDistribution bd(0);
         bool b;
         // Delete nodes
         bd.setProbTrue(mcfg.nodeDeleteProb/nrVertices());
         for (i=0;i<nrVertices();i++)
         {
             if (bd.draw(b) && b)
             {
                 cout << "Removing node " << i << endl;
                 removeVertex(i);
             }
         }
         // Add nodes
         bd.setProbTrue(mcfg.nodeAddProb);
         bool mustAdd;
         int nrV = nrVertices();
         for (i=0;i<nrV;i++)
         {
             if (bd.draw(b) && b)
             {
                 vector<int> edges;
                 int j;
                 BernoulliDistribution bdH(mcfg.edgeAddProbNewNode);
                 for (j=0;j<nrV;j++)
                     if (bdH.draw(b) && b)
                         edges.push_back(j);
                 if (!edges.empty())
                 {
                     addVertex();
                     for (j=0;j<edges.size();j++)
                         addEdge(mVertices.size()-1,edges[j]);
                 }
             }
         }
         return true;
     }
void FloorScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
    if (mouseEvent->button() ==  Qt::RightButton){
        if(ctrl_pressed){
            addVertex(mouseEvent->lastScenePos().toPoint());
        } else if (shift_pressed) {
            removeVertex();
        } else {
            unsigned int floorPlanSize = mesh->getFloorPlanSize();

            // we have have at least one vertex on the floor plan, if we click on it, we can move it
            // and we draw his profile
            if (floorPlanSize != 0) {
                moveVertex();
            // else if we do not have any vertices on the floor plan, we create a floor plan
            } else {
                QPoint mousePos = mouseEvent->lastScenePos().toPoint();
                // no point defined thus we add an initial geometric structure
                basicCircle(&mousePos, 10);
            }
        }
    }
}
Ejemplo n.º 13
0
int runKarger(Graph *g)
{
  while(g->numVertices > 2){
    // pick edge at random
    Edge *ep = g->edges+(rand()%g->numEdges);
    //grab the edges 2 vertices
    Vertex *v1 = ep->endpoint1->sourceVertex;
    Vertex *v2 = ep->endpoint2->sourceVertex;
    // printf("Conracting edge (%d,%d)\n", v1->label, v2->label);
    // add v2's list onto the end of v1
    v1->tail->next = v2->head;
    v2->head->prev = v1->tail;
    v1->tail = v2->tail;
    v2->head = NULL;
    v2->tail = NULL;

    // loop through linked list, point them all to v1, delete self loops
    ConnectorElement *curElement = v1->head;
    while(curElement){
      curElement->sourceVertex = v1;
      Edge *edgeToCheck = curElement->adjacentEdge;
      curElement = curElement->next;
      // if I got really unlucky and switched to a connector element that shares
      // the same edge as the prev element, I need to switch again
      if(curElement && curElement->adjacentEdge==edgeToCheck){
        curElement->sourceVertex = v1;
        curElement = curElement->next;
      }
      // if its a self loop, remove edge
      if(edgeToCheck->endpoint1->sourceVertex==v1 && edgeToCheck->endpoint2->sourceVertex==v1){
        removeEdge(g, edgeToCheck);
      }
    }
    removeVertex(g, v2);
  }
  return g->numEdges;
}
Ejemplo n.º 14
0
void ProfileScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent) {
    float tmpx = mouseEvent->lastScenePos().toPoint().x();
    float tmpy = mouseEvent->lastScenePos().toPoint().y();
    QRectF thisSize = this->sceneRect();
    Utils::adjustCoordinatesSceneTo3D(tmpx, tmpy, thisSize.width(), thisSize.height());
    std::cerr << "P: " << tmpx << ", " << tmpy << std::endl;

    if (!isProfileSelected) {
        return;
    }

    if (mouseEvent->button() ==  Qt::RightButton){
        // if user use right click + ctrl
        if(mouseEvent->modifiers() == Qt::ControlModifier){
            addVertex(mouseEvent->lastScenePos().toPoint());
        // if user use right click + shift
        } else if (mouseEvent->modifiers() == Qt::ShiftModifier) {
            //remove point if clicked on a point
            removeVertex();
        } else {
            moveVertex();
        }
    }
}
Ejemplo n.º 15
0
  bool HyperGraph::mergeVertices(Vertex* vBig, Vertex* vSmall, bool erase)
  {
    VertexIDMap::iterator it=_vertices.find(vBig->id());
    if (it==_vertices.end())
      return false;

    it=_vertices.find(vSmall->id());
    if (it==_vertices.end())
      return false;

    EdgeSet tmp(vSmall->edges());
    bool ok = true;
    for(EdgeSet::iterator it=tmp.begin(); it!=tmp.end(); ++it){
      HyperGraph::Edge* e = *it;
      for (size_t i=0; i<e->vertices().size(); i++){
        Vertex* v=e->vertex(i);
        if (v==vSmall)
          ok &= setEdgeVertex(e,i,vBig);
      }
    }
    if (erase)
      removeVertex(vSmall);
    return ok;
  }
Ejemplo n.º 16
0
bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, 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;
	
	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 'mesh.verts' (%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*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);
					memcpy(pb, &polys[(npolys-1)*nvp], 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()!
			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;
	}

	// 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, "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_BUILD_POLYMESH);
	
	return true;
}
Ejemplo n.º 17
0
//main/////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(){
    mapa m;
    grafo g = inicializaGrafo(&g, &m);
    int i, i1, i2, i3;

    char esc[20];       //comando a ser digitado

    int FM = 1;
    while (FM == 1){

        scanf("%s", esc);  //lerá o comando até o primeiro espaço, para depois ler até o proximo espaço, e assim por diante
        int escI = identificaComando(esc);  //identifica o comando digitado
        switch(escI){
            case _CV:   //cria vértice
                scanf("%d", &i1);
                insertVertex(&g, &m, i1);
                break;

            case _DV:   //destrói vértice
                scanf("%d", &i1);
                removeVertex(&g, i1, &m);
                break;

            case _CA:   //cria aresta
                scanf("%d %d %d", &i1, &i2, &i3);
                insertEdge(&g, i1, i2, &m, i3);
                break;

            case _DA:   //destrói aresta
                scanf("%d", &i1);
                removeEdge(&g, i1, &m);
                break;

            case _TV:   //troca vértice
                scanf("%d %d", &i1, &i2);
                replaceVertex(i1, i2, m);
                break;

            case _TA:   //troca aresta
                scanf("%d %d", &i1, &i2);
                replaceEdge(i1, i2, m);
                break;

            case _IG:   //imprime grafo
                printf("%d\n", g.nvertices);
                for (i = 0; i < m.indiceVert; i++){
                    vertice *v = pegaVertRef(m, i+1);
                    if (v != NULL){
                        printf("%d ", i+1);
                        printf("%d\n", v->conteudo);
                    }
                }

                printf("%d\n", g.narestas);
                for (i = 0; i < m.indiceAres; i++){
                    aresta *a = pegaAresRef(m, i+1);
                    if (a != NULL){
                        printf("%d ", i+1);
                        vertice *vT = a->dir;
                        printf("%d ", pegaVertInd(m, vT));
                        vT = a->esq;
                        printf("%d ", pegaVertInd(m, vT));
                        printf("%d\n", a->conteudo);
                    }
                }
                break;

            case _CM:   //caminho mínimo
                scanf("%d %d", &i1, &i2);
                dijkstra(&g, m, i1, i2);
                break;

            case _FM:   //fim
                FM = 0;
                break;

        }
    }
    return 0;
}
Ejemplo n.º 18
0
void MeshBuilder::removeVertices()
{
	for ( int i = vertices()-1 ; i >= 0 ; --i )
		removeVertex(i);
}
Ejemplo n.º 19
0
Archivo: Graph.hpp Proyecto: quano1/Cpp
void Graph<T, C, W>::removeVertex(vector<Vertex<T, C, W>* > const &vertexList) {
    for(auto vertex : vertexList) {
        removeVertex(*vertex);
    }
}
Ejemplo n.º 20
0
int main(int argc, char const *argv[]) {
	int running = 1, cost = 0, i, j;
	char input[BUFFER_SIZE], *aft;
	char vertex, dest, option;
	Graph *g = NULL;
	createGraph(&g);

	#ifdef DEV

	insertVertex(g, 'a');
	insertVertex(g, 'b');
	insertVertex(g, 'c');
	insertVertex(g, 'd');
	insertVertex(g, 'e');
	insertVertex(g, 'f');
	insertEdge(g, 'a', 'b', 100);
	insertEdge(g, 'a', 'c', 300);
	insertEdge(g, 'a', 'a', 100);
	insertEdge(g, 'd', 'b', 70);
	insertEdge(g, 'f', 'c', 10);
	insertEdge(g, 'a', 'f', 10);
	insertEdge(g, 'a', 'f', 20);
	insertEdge(g, 'a', 'a', 100);
	displayGraph(g);
	greedySearch(g, 'a');
	destroyGraph(g);
	#else

        while (running) {
                memset(input, 0, BUFFER_SIZE);
                printf("\n1 - inserir vertice\n");
                printf("2 - inserir aresta\n");
                printf("3 - remover vertice\n");
                printf("4 - remover aresta\n");
                printf("5 - imprimir grafo\n");
                printf("6 - Busca Gulosa\n");
                printf("7 - sair\n");
                printf("\n$");

                scanf(" %c", &option);
                switch (option) {
                case '1':
                        printf("Digite um id para o novo no (apenas um caracter)\n");
                        printf(">>");
                        scanf(" %c", &vertex);
                        if (!insertVertex(g, vertex)) {
                                printf("Vertice inserido!\n");
                                printf("Digite os vizinhos (exemplo:b10 c20 d30) obs: caso o valor nao seja indicado o default sera 0\n");
                                getchar();
                                fgets(input, BUFFER_SIZE, stdin);
                                for(i = 0; i < strlen(input); i++) {
                                        if(isalpha(input[i])) {
                                                dest = input[i];
                                                for(j = i+1; j <= strlen(input); j++) {
                                                        if(isdigit(input[j])) {
                                                                cost = strtod(&input[j], &aft);
                                                                i = (aft - input) -1;
                                                                if(!insertEdge(g, vertex, dest, cost))
                                                                        printf("Aresta inserida [%c] - [%c] com custo %d!\n", vertex, dest, cost);
                                                                break;
                                                        }
                                                        if(isalpha(input[j]) || input[j] == '\0') {
                                                                if(!insertEdge(g, vertex, dest, 0))
                                                                        printf("Aresta inserida [%c] - [%c] com custo 0!\n", vertex, dest);
                                                                break;
                                                        }
                                                }
                                        }
                                }
                        }

                        break;
                case '2':
                        printf("Digite um par de vertices e um custo para a nova aresta (exemplo: A B 100)\n");
                        printf(">>");
                        scanf(" %c %c %d", &vertex, &dest, &cost);
                        if(!insertEdge(g, vertex, dest, cost))
                                printf("Aresta inserida!\n");
                        break;
                case '3':
                        printf("Digite o id do vertice a ser deletado\n");
                        printf(">>");
                        scanf(" %c", &vertex);
                        if(!removeVertex(g, vertex))
                                printf("vertice removido\n");
                        break;
                case '4':
                        printf("Digite o par de vertices e o custo da aresta (exemplo: A B 100)\n");
                        printf(">>");
                        scanf(" %c %c %d", &vertex, &dest, &cost);
                        if(!removeEdge(g, vertex, dest, cost))
                                printf("aresta removida!\n");
                        break;
                case '5':
                        displayGraph(g);
                        break;
                case '6':
                        printf("Digite um vertice para inicio da busca\n");
                        printf(">>");
                        scanf(" %c", &vertex);
                        greedySearch(g, vertex);
                        break;

                case '7':
                        printf("Ate logo\n");
                        running = 0;
                        destroyGraph(g);
                        break;
                default:
                        printf("Opcao invalida\n");
                        break;
                }
        }
	#endif
	return 0;
}
Ejemplo n.º 21
0
//
// removes the given vertex and retriangulates the hole which would be made
//
// The method returns true if the vertex has been removed and false if the vertex has been retained.
//
bool MeshEx::removeVertexAndReTriangulateNeighbourhood( Vertex *v )
{
	std::vector<MeshEx::Edge *>                                          boundaryEdges; // boundary edges which form the polygon which has to be triangulated
	std::vector<MeshEx::Edge *>                                          criticalEdges; // edges which are not only connected to other vertices of the vertexring through boundary edges
	std::map<MeshEx::Vertex *, EdgeInfoHelper>                            boundaryRing; // maps incomming and outgoing edge to each vertex of the boundary vertex-ring



	// gather and prepare information ------------------------------------------------
	for( std::vector<Triangle *>::iterator it = v->triangleRing.begin(); it != v->triangleRing.end(); ++it )
	{
		Triangle *t = (*it);

		Edge *boundaryEdge = t->getOtherEdge( v );

		boundaryRing[boundaryEdge->v1].registerEdge( boundaryEdge );
		boundaryRing[boundaryEdge->v2].registerEdge( boundaryEdge );

		boundaryEdges.push_back( boundaryEdge );
	}


	// align the edges so that for each vertex e1 is the incomming and e2 is the outgoing edge
	Vertex *first = boundaryRing.begin()->first;
	Vertex *current = first;
	Vertex *next = 0;
	Vertex *prev = 0;
	
	do
	{
		// we have to be sure that each boundaryRing Vertex has an incomming and outgoing edge
		if( !boundaryRing[current].e1 || !boundaryRing[current].e2 )
		{
			printf( "error : edge ring around vertex not closed boundary vertex has less than 2 edges (polygon hole?)\n" );
			//++g_iterations;
			return false;
		}

		boundaryRing[current].setVertex( current );

		next = boundaryRing[current].next;

		if( boundaryRing[next].e1 != boundaryRing[current].e2 )
			boundaryRing[next].swap();

		current = next;
	}while( current != first );

	// we have to collect all edges going out from the vertex-ring vertices which are connected to
	// other vertices of the vertex ring - these will later be used for consistency check #2 (see chapter 4.4 of the paper)
	// for each vertex of the vertex Ring V
	for( std::map<Vertex *, EdgeInfoHelper>::iterator it = boundaryRing.begin(); it != boundaryRing.end(); ++it )
	{
		Vertex *rv       = it->first; // current vertex of the vertex ring

		// for each triangle referencing rv...
		for( std::vector<Triangle *>::iterator tit = rv->triangleRing.begin(); tit != rv->triangleRing.end(); ++tit )
		{
			Triangle *rv_tri = *tit;

			// ... which doesnt belong to the triangleRing of v
			if( std::find( v->triangleRing.begin(), v->triangleRing.end(), rv_tri ) == v->triangleRing.end() )
			{
				// collect the edges containing rv...
				for( size_t i=0; i<3; ++i )
					if( rv_tri->e[i]->contains(rv) )
						// ...and dont belong to the edgeRing list
						if( std::find( boundaryEdges.begin(), boundaryEdges.end(), rv_tri->e[i] ) == boundaryEdges.end() )
							// store the edge if the node on the other side references another vertex of the vertex-ring
							if( boundaryRing.find( rv_tri->e[i]->getOtherVertex(rv) ) != boundaryRing.end() )
								criticalEdges.push_back( rv_tri->e[i] );

			}
		}
	}

	// remove duplicate entries
	std::sort( criticalEdges.begin(), criticalEdges.end() );
	criticalEdges.erase( std::unique(criticalEdges.begin(), criticalEdges.end()), criticalEdges.end() );

	// Now we will project the neighbourhood of v onto a plane so that we can employ the greedy
	// triangulation. For this we will have to find a projection of the neighbourhood of v so that
	// no edges intersect on that plane. If they would, then the greedy triangulation would introduce
	// folds which means that the topology would be destroyed.
	// Looking for a working projection may lead to a number of projection-trials. For the first try
	// we will take the plane to be the plane defined by the normal of v and (its distance to the origin).
	// This will do the job most of the time.
	math::Vec3f                           normal; // direction of the projection plane
	math::Vec3f                            base1; // base vector which builds the 2d-coordinate system
	math::Vec3f                            base2; // base vector which builds the 2d-coordinate system
	float                               distance; // distance of the plane to the origin
	CGAL::Orientation boundaryPolygonOrientation; // orientation (clockwise/counterclockwise of the boundary polyon)

	distance = -math::dotProduct( v->position, normal );

	size_t   trialCount = 13; // only one trial for now
	size_t currentTrial = 0;
	bool    success = true;
	do
	{
		// we assume that we will be successfull
		success = true;

		switch(currentTrial)
		{
		case 0:
			// first trial: we take the plane defined by the normal of v
			normal = v->normal;
			break;
		// for all other trials we will try one of 12 different directions
		case  1:normal = math::normalize( math::Vec3f( .8507f, .4472f, .2764f ));break;
		case  2:normal = math::normalize( math::Vec3f( -.8507f, .4472f, .2764f ));break;
		case  3:normal = math::normalize( math::Vec3f( .8507f, -.4472f, -.2764f ));break;
		case  4:normal = math::normalize( math::Vec3f( -.8507f, -.4472f, -.2764f ));break;
		case  5:normal = math::normalize( math::Vec3f( .5257f, -.4472f, .7236f ));break;
		case  6:normal = math::normalize( math::Vec3f( .5257f, .4472f, -.7236f ));break;
		case  7:normal = math::normalize( math::Vec3f( -.5257f, -.4472f, .7236f ));break;
		case  8:normal = math::normalize( math::Vec3f( -.5257f, .4472f, -.7236f ));break;
		case  9:normal = math::normalize( math::Vec3f( .0f, .4472f, .8944f ));break;
		case 10:normal = math::normalize( math::Vec3f( .0f, -1.0f, .0f ));break;
		case 11:normal = math::normalize( math::Vec3f( .0f, 1.0f, .0f ));break;
		case 12:normal = math::normalize( math::Vec3f( .0f, -.4472f, -.8944f ));break;
		};

		// compute the basis of the 2d-coordinate system of the plane defined by current normal
		base1 = math::normalize( math::projectPointOnPlane( normal, distance, boundaryRing.begin()->first->position ) - v->position );
		base2 = math::normalize( math::crossProduct( normal, base1 ) );


		// project neighbours into the given plane
		for( std::map<Vertex *, EdgeInfoHelper>::iterator it = boundaryRing.begin(); it != boundaryRing.end(); ++it )
			it->second.projected = _get2d( base1, base2, math::projectPointOnPlane( normal, distance, it->first->position ) );

		// topologic constistency check #1 (see chapter 4.4 of the paper)
		// now do the consistency check: test if all edges dont intersect and dont lie over each other
		// if any edge between the projected vertices intersect -> success = false
		// test each projected edge of the edge ring against each other edge
		for( std::vector<Edge *>::iterator it1 = boundaryEdges.begin(); it1 != boundaryEdges.end() - 1; ++it1 )
		{
			for( std::vector<Edge *>::iterator it2 = it1+1; it2 != boundaryEdges.end(); ++it2 )
			{
				Edge *e1 = *it1;
				Edge *e2 = *it2;
				math::Vec3f intersectionPoint;

				// skip if the 2 lines share a common vertex
				if( e2->contains(e1->v1) || e2->contains(e1->v2) )
					continue;

				math::Vec2f e1_v1_projected = boundaryRing[e1->v1].projected;
				math::Vec2f e1_v2_projected = boundaryRing[e1->v2].projected;
				math::Vec2f e2_v1_projected = boundaryRing[e2->v1].projected;
				math::Vec2f e2_v2_projected = boundaryRing[e2->v2].projected;

				CGAL::Segment_2<K> line_1( Point( e1_v1_projected.x, e1_v1_projected.y ), Point(e1_v2_projected.x, e1_v2_projected.y) );
				CGAL::Segment_2<K> line_2( Point( e2_v1_projected.x, e2_v1_projected.y ), Point(e2_v2_projected.x, e2_v2_projected.y) );

				if( CGAL::do_intersect( line_1, line_2 ) )
				{
					success = false;
					break;
				}
			}

			if( !success )
				break;
		}


		if( success )
		{
			//
			// now we do the topology consistency check #2 (see chapter 4.4 of the paper)
			// this is done by checking all critical edges whether they cross the interior of the
			// polygon boundary which is formed by the projected vertex ring vertices
			// to do this we create the 2 polygongs which can be made by using the edge as a divider
			// the line crosses the interior if both polgons have a counterclockwise orientation
			//
			for( std::vector<Edge *>::iterator it = criticalEdges.begin(); it != criticalEdges.end(); ++it )
			{
				Edge *criticalEdge = *it;


				// setup left polygon
				// start from v1 and go to v2
				Polygon leftPoly;

				prev = 0;
				current = criticalEdge->v1;
				do
				{
					leftPoly.push_back( current, boundaryRing[current].projected );
					prev = current;
					current = boundaryRing[current].next;

				}while( current != criticalEdge->v2 );
				leftPoly.push_back( current, boundaryRing[current].projected );


				// setup right polygon
				// start from v2 and go to v1
				Polygon rightPoly;

				prev = 0;
				current = criticalEdge->v2;
				do
				{
					rightPoly.push_back( current, boundaryRing[current].projected );
					prev = current;
					current = boundaryRing[current].next;

				}while( current != criticalEdge->v1 );
				rightPoly.push_back( current, boundaryRing[current].projected );


				// if orientations of both polygons are the same then the critical edge crosses the bounding polygon interior
				if( leftPoly.orientation() == rightPoly.orientation() )
				{
					printf( "info : unable to triangulate since critical edge(es) would cross the polygon interior - vertex is not removed\n" );

					success = false;
					break;
				}
			}
		}
	}while( (++currentTrial < trialCount)&&(!success) );

	
	if( !success )
	{
		// we dont remove the vertex since we didnt managed to find a planar
		// projection of the neighbourhood which would not destroy the topology
		printf( "info : unable to find planar projection for vertex remove and retriangulation - vertex is not removed\n" );
		//++g_iterations;
		return false;
	}

	boundaryPolygonOrientation = CGAL::orientation( Point_3( v->position ), Point_3( v->position + base1 ), Point_3( v->position + base2 ), Point_3( v->position + normal ) );



	// execute the result ------------------------------------------------------------

	// remove vertex v and the triangle ring around v
	removeVertex( v );


	// compute squared distances
	
	// compute the squared distances of all point pairs
	std::vector<DistanceHelper> sqDistances;  // sorted distances of each pair of points
	for( std::map<Vertex *, EdgeInfoHelper>::iterator it1 = boundaryRing.begin(); it1 != boundaryRing.end(); ++it1 )
		for( std::map<Vertex *, EdgeInfoHelper>::iterator it2 = it1; it2 != boundaryRing.end(); ++it2 )
		{
			Vertex *v1 = it1->first;
			Vertex *v2 = it2->first;

			if( v1 == v2 )
				continue;

			// we dont want to add pairs, which would build a boundary edge, since those
			// already exist -> simply check for next or prev vertex in boundaryRing
			if( (boundaryRing[v1].next == v2)||(boundaryRing[v1].prev == v2) )
				continue;


			sqDistances.push_back( DistanceHelper( it1->first, it2->first ) );
		}

	// sort
	std::sort( sqDistances.begin(), sqDistances.end() );


	//
	std::list<Polygon *>                                                polygons; // polygons which have to be triangulated
	std::vector<Edge *>        edges( boundaryEdges.begin(), boundaryEdges.end() ); // created edges

	// create polygon which is made by the boundary edges and put it on polygon list
	Polygon *boundaryPolygon = new Polygon();


	first = boundaryRing.begin()->first;
	current = first;
	prev = 0;

	do
	{
		boundaryPolygon->push_back( current, boundaryRing[current].projected );
		prev = current;
		current = boundaryRing[current].next;
	}while( current != first );

	if( boundaryPolygon->orientation() != boundaryPolygonOrientation )
		boundaryPolygon->flip();


	polygons.push_back( boundaryPolygon );

	// for each entry in the sqDistance list
	//     find the polygon on the polygon list which contains h->v1 and h->v2
	//     check if edge is outside the polygon by checking the orientations of the left and right sides (build left and right polygons)
	//     check if edge intersects with any other existing edge which dont have a point in h->v1 or h->v2
	//     if checks pass:
	//         create edge -> assign it to the left and right polygons | add it to the list of edges
	//         split the polygon by removing the polygon from polygon list and putting the left and right polygons on the list if it is not a triangle
	//     
	// if the any polygon remains on the polygon list, throw an error that the triangulation has created a hole in the mesh
	//std::vector<Edge *> edges( edgeRing.begin(), edgeRing.end() );

	// when the mother polygon is already a triangle, then we have sqDistances.size() == 0
	// and we have to handle the polygon
	if( boundaryPolygon->isTriangle() )
	{
		createTriangle( boundaryPolygon->vertices[0], boundaryPolygon->vertices[1], boundaryPolygon->vertices[2], edges );
		polygons.clear();
		delete boundaryPolygon;

		//++g_iterations;
		return true;

	}


	for( std::vector<DistanceHelper>::iterator it=sqDistances.begin(); it != sqDistances.end(); ++it )
	{
		DistanceHelper *h = &(*it);

		Polygon *poly = 0; // polygon which contains both vertices of h

		std::list<Polygon *>::iterator pit;

		// find the polygon which contains both vertices of h
		for( pit = polygons.begin(); pit != polygons.end(); ++pit )
		{
			Polygon *p = *pit;
			if( p->contains( h->v1 ) && p->contains( h->v2 ) )
			{
				poly = p;
				break;
			}
		}

		// if no polygon could be found which contains both vertices of h, then
		// we can skip this one
		if( !poly )
			continue;

		// test for intersection with all existing edges
		bool intersection = false;
		for( std::vector<Edge *>::iterator eit = edges.begin(); eit != edges.end(); ++eit)
		{
			Edge *e = (*eit);

			math::Vec3f intersectionPoint;

			// ---- test for intersection of the edges projected into 2d plane using cgal ----
			// skip if the 2 lines share a common vertex
			if( e->contains(h->v1) || e->contains(h->v2) )
				continue;

			CGAL::Segment_2<K> line_1( Point( boundaryRing[e->v1].projected.x, boundaryRing[e->v1].projected.y ), Point(boundaryRing[e->v2].projected.x, boundaryRing[e->v2].projected.y) );
			CGAL::Segment_2<K> line_2( Point( boundaryRing[h->v1].projected.x, boundaryRing[h->v1].projected.y ), Point(boundaryRing[h->v2].projected.x, boundaryRing[h->v2].projected.y) );

			if( CGAL::do_intersect( line_1, line_2 ) )
			{
				intersection = true;
				break;
			}
		}

		// if there was an intersection, then we can skip this one
		// since a non-compatible edge would be introduced
		if( intersection )
			continue;

		// no intersection, get the 2 polygons which would be created from dividing the mother polyon along the edge
		Polygon *left, *right;

		left = right = 0;

		poly->split( left, right, h->v1, h->v2 );

		// if the 2 polygons have the same orientation, then we can be sure that
		// the edge goes through the interior of the polygon

		if( left->orientation() == right->orientation() )
		{

			// remove the current polygon from the list of polygons
			polygons.erase( pit );
			delete poly;

			// create the edge h->v1 -> h->v2
			Edge *edge = createEdge( h->v1, h->v2 );

			edges.push_back( edge );

			// and add the left and righ polygon to the list if they are not triangles
			if( left->isTriangle() )
			{
				// add triangle to the mesh
				createTriangle( left->vertices[0], left->vertices[1], left->vertices[2], edges );

				// remove polygon helper structure
				delete left;
			}else
				polygons.push_back( left );

			if( right->isTriangle() )
			{
				// add triangle to the mesh
				createTriangle( right->vertices[0], right->vertices[1], right->vertices[2], edges );

				// remove polygon helper structure
				delete right;
			}else
				polygons.push_back( right );
		}else
		{
			delete left;
			delete right;
		}
	}

	if( !polygons.empty() )
		printf( "error : hole created during retriangulation\n" );

	for( std::list<Polygon *>::iterator pit = polygons.begin(); pit != polygons.end(); ++pit )
		delete *pit;
	polygons.clear();


	//++g_iterations;
	return true;
}
Ejemplo n.º 22
0
bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
{
	rcTimeVal startTime = rcGetPerformanceTimer();

	vcopy(mesh.bmin, cset.bmin);
	vcopy(mesh.bmax, cset.bmax);
	mesh.cs = cset.cs;
	mesh.ch = cset.ch;
	
	int maxVertices = 0;
	int maxTris = 0;
	int maxVertsPerCont = 0;
	for (int i = 0; i < cset.nconts; ++i)
	{
		maxVertices += cset.conts[i].nverts;
		maxTris += cset.conts[i].nverts - 2;
		maxVertsPerCont = rcMax(maxVertsPerCont, cset.conts[i].nverts);
	}
	
	if (maxVertices >= 0xfffe)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many vertices %d.", maxVertices);
		return false;
	}
	
	unsigned char* vflags = 0;
	int* nextVert = 0;
	int* firstVert = 0;
	int* indices = 0;
	int* tris = 0;
	unsigned short* polys = 0;
	
	vflags = new unsigned char[maxVertices];
	if (!vflags)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices);
		goto failure;
	}
	memset(vflags, 0, maxVertices);
	
	mesh.verts = new unsigned short[maxVertices*3];
	if (!mesh.verts)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices);
		goto failure;
	}
	mesh.polys = new unsigned short[maxTris*nvp*2];
	if (!mesh.polys)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2);
		goto failure;
	}
	mesh.regs = new unsigned short[maxTris];
	if (!mesh.regs)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.regs' (%d).", maxTris);
		goto failure;
	}
	mesh.nverts = 0;
	mesh.npolys = 0;
	mesh.nvp = nvp;
	
	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);
	
	nextVert = new int[maxVertices];
	if (!nextVert)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'nextVert' (%d).", maxVertices);
		goto failure;
	}
	memset(nextVert, 0, sizeof(int)*maxVertices);
	
	firstVert = new int[VERTEX_BUCKET_COUNT];
	if (!firstVert)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT);
		goto failure;
	}
	for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i)
		firstVert[i] = -1;
	
	indices = new int[maxVertsPerCont];
	if (!indices)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'indices' (%d).", maxVertsPerCont);
		goto failure;
	}
	tris = new int[maxVertsPerCont*3];
	if (!tris)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'tris' (%d).", maxVertsPerCont*3);
		goto failure;
	}
	polys = new unsigned short[(maxVertsPerCont+1)*nvp];
	if (!polys)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'polys' (%d).", maxVertsPerCont*nvp);
		goto failure;
	}
	unsigned short* tmpPoly = &polys[maxVertsPerCont*nvp];

	for (int i = 0; i < cset.nconts; ++i)
	{
		rcContour& cont = cset.conts[i];
		
		// Skip empty 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.
/*			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]);
				if (nBadPos < 100)
				{
					badPos[nBadPos*3+0] = v[0];
					badPos[nBadPos*3+1] = v[1];
					badPos[nBadPos*3+2] = v[2];
					nBadPos++;
				}
			}*/
			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)
		{
			while (true)
			{
				// Find best polygons to merge.
				int bestMergeVal = 0;
				int bestPa, bestPb, bestEa, bestEb;
				
				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, mesh.verts, bestEa, bestEb, tmpPoly, nvp);
					memcpy(pb, &polys[(npolys-1)*nvp], 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.npolys++;
		}
	}
	
	
	// Remove edge vertices.
	for (int i = 0; i < mesh.nverts; ++i)
	{
		if (vflags[i])
		{
			if (!removeVertex(mesh, i, maxTris))
				goto failure;
			for (int j = i; j < mesh.nverts-1; ++j)
				vflags[j] = vflags[j+1];
			--i;
		}
	}

	delete [] vflags;
	delete [] firstVert;
	delete [] nextVert;
	delete [] indices;
	delete [] tris;
	
	// Calculate adjacency.
	if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, nvp))
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Adjacency failed.");
		return false;
	}
	
	rcTimeVal endTime = rcGetPerformanceTimer();
	
//	if (rcGetLog())
//		rcGetLog()->log(RC_LOG_PROGRESS, "Build polymesh: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f);
	if (rcGetBuildTimes())
		rcGetBuildTimes()->buildPolymesh += rcGetDeltaTimeUsec(startTime, endTime);
	
	return true;

failure:
	delete [] vflags;
	delete [] tmpPoly;
	delete [] firstVert;
	delete [] nextVert;
	delete [] indices;
	delete [] tris;

	return false;
}
Ejemplo n.º 23
0
int main(int argc,char * argv[])
{
	int rc;
	GLMDB_env *genv;
	printf("opening graph!\n");
	rc = openGraph(&genv, "/home/pieter/Downloads/glmdb-blueprints/src/main/native/testdb");
	if (rc != 0) {
		printf("opening graph failure  = %i!\n", rc);
		goto fail;
	}

	MDB_txn *txn;
	MDB_cursor *cursor;
	rc = mdb_txn_begin(genv->env, NULL, 1, &txn);
	if (rc != 0) {
		printf("begin transaction failure  = %i!\n", rc);
		goto fail;
	}
	rc = mdb_cursor_open(txn, genv->vertexDb, &cursor);
	if (rc != 0) {
		printf("open cursor failure  = %i!\n", rc);
		goto fail;
	}
	MDB_val vertexKey;
	rc = addVertex(cursor, genv->vertexDb, genv->vertexIdSequence++, &vertexKey);
	if (rc != 0) {
		printf("add out vertex failure  = %i!\n", rc);
		goto fail;
	}
	VertexDbId outVertexDbId = (*((VertexDbId *) (vertexKey.mv_data)));
	signed long long outVertexId = outVertexDbId.vertexId;

	char *propertyValue1 = malloc(5);
	char v1[] = "12345";
	memcpy(propertyValue1, v1, 5);
	rc = setVertexPropertyString(cursor, 0, 0, 5, propertyValue1);
	if (rc != 0) {
		printf("setVertexPropertyChar failure  = %i!\n", rc);
		goto fail;
	}

	char *propertyValue2 = malloc(5);
	char v2[] = "12345";
	memcpy(propertyValue2, v2, 5);
	rc = setVertexPropertyString(cursor, 0, 1, 5, propertyValue2);
	if (rc != 0) {
		printf("setVertexPropertyChar failure  = %i!\n", rc);
		goto fail;
	}


	jint *propertyKeyIdSize = (jint *)malloc(sizeof(int));
	jint **propertyKeyId = malloc(sizeof(void *));
	rc = getVertexPropertyKeys(cursor, 0, propertyKeyIdSize, propertyKeyId);
	if (rc != 0 && rc != MDB_NOTFOUND) {
		goto fail;
	}

	int i = 0;
	for (i = 0; i < 10; i = i + 1) {
		rc = addVertex(cursor, genv->vertexDb, genv->vertexIdSequence++, &vertexKey);
		if (rc != 0) {
			printf("add in vertex failure  = %i!\n", rc);
			goto fail;
		}
		VertexDbId inVertexDbId = (*((VertexDbId *) (vertexKey.mv_data)));
		signed long long inVertexId = inVertexDbId.vertexId;
		rc = addEdge(txn, genv->vertexDb, genv->edgeDb, genv->edgeIdSequence++, 0, outVertexId, inVertexId);
		if (rc != 0) {
			printf("add edge failure  = %i!\n", rc);
			goto fail;
		}
		MDB_cursor *edgeCursor;
		rc = mdb_cursor_open(txn, genv->edgeDb, &edgeCursor);
		if (rc != 0) {
			printf("open cursor failure  = %i!\n", rc);
			goto fail;
		}

		char *edgePropertyValue2 = malloc(5);
		char v2[] = "12345";
		memcpy(edgePropertyValue2, v2, 5);

		rc = setEdgePropertyString(edgeCursor, genv->edgeIdSequence - 1, 0, 5, edgePropertyValue2);

		mdb_cursor_close(edgeCursor);

		if (rc != 0) {
			printf("setEdgePropertyChar failure  = %i!\n", rc);
			goto fail;
		}
	}
	mdb_cursor_close(cursor);
	mdb_txn_commit(txn);

	rc = mdb_txn_begin(genv->env, NULL, 1, &txn);
	if (rc != 0) {
		printf("transaction begin = %i!\n", rc);
		goto fail;
	}
	rc = mdb_cursor_open(txn, genv->vertexDb, &cursor);
	if (rc != 0) {
		printf("open cursor failure  = %i!\n", rc);
		goto fail;
	}
	rc = getVertex(cursor, 0LL, &vertexKey);
	if (rc != 0) {
		printf("get vertex failure  = %i!\n", rc);
		goto fail;
	}

	jlong *edgeIdResultC = (jlong *)malloc(sizeof(signed long long));
	jlong *outVertexIdC = (jlong *)malloc(sizeof(signed long long));
	jlong *inVertexIdC = (jlong *)malloc(sizeof(signed long long));

	rc = getFirstEdgefromVertex(cursor, 0, 0, 0LL, edgeIdResultC, outVertexIdC, inVertexIdC);
	if (rc != 0) {
		printf("getFirstEdgefromVertex failure  = %i!\n", rc);
		goto fail;
	}

	rc = getNextEdgefromVertex(cursor, 0, 0, 0LL, edgeIdResultC, outVertexIdC, inVertexIdC);
	if (rc != 0) {
		printf("getNextEdgefromVertex failure  = %i!\n", rc);
		goto fail;
	}

	mdb_cursor_close(cursor);
	mdb_txn_commit(txn);

	rc = mdb_txn_begin(genv->env, NULL, 1, &txn);
	if (rc != 0) {
		printf("transaction begin = %i!\n", rc);
		goto fail;
	}

	printf("before remove traverseVertexDb\n");
	traverseVertexDb(genv, txn);

	printf("before remove traverseEdgeDb\n");
	traverseEdgeDb(genv, txn);

	mdb_txn_commit(txn);

	rc = mdb_txn_begin(genv->env, NULL, 1, &txn);
	if (rc != 0) {
		printf("transaction begin failure = %i!\n", rc);
		goto fail;
	}
	rc = mdb_cursor_open(txn, genv->vertexDb, &cursor);
	if (rc != 0) {
		printf("open cursor failure  = %i!\n", rc);
		goto fail;
	}

//	rc = removeEdge(txn, genv, 9LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 8LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 7LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 6LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 5LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 4LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 3LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 2LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 1LL);
//	printf("rc = %i\n", rc);
//	rc = removeEdge(txn, genv, 0LL);
//	printf("rc = %i\n", rc);

	rc = removeVertex(txn, genv, 10LL);
	rc = removeVertex(txn, genv, 9LL);
	rc = removeVertex(txn, genv, 8LL);
	rc = removeVertex(txn, genv, 7LL);
	rc = removeVertex(txn, genv, 6LL);
	rc = removeVertex(txn, genv, 5LL);
	rc = removeVertex(txn, genv, 4LL);
	rc = removeVertex(txn, genv, 3LL);
	rc = removeVertex(txn, genv, 2LL);
	rc = removeVertex(txn, genv, 1LL);
	rc = removeVertex(txn, genv, 0LL);

//	rc = removeVertex(txn, genv, 0LL);
//	rc = removeVertex(txn, genv, 1LL);
//	rc = removeVertex(txn, genv, 2LL);
//	rc = removeVertex(txn, genv, 3LL);
//	rc = removeVertex(txn, genv, 4LL);
//	rc = removeVertex(txn, genv, 5LL);
//	rc = removeVertex(txn, genv, 6LL);
//	rc = removeVertex(txn, genv, 7LL);
//	rc = removeVertex(txn, genv, 8LL);
//	rc = removeVertex(txn, genv, 9LL);
//	rc = removeVertex(txn, genv, 10LL);


	printf("before traverseVertexDb\n");
	traverseVertexDb(genv, txn);

	printf("before traverseEdgeDb\n");
	traverseEdgeDb(genv, txn);

	mdb_txn_commit(txn);

	fail:
	printf("closing graph!\n");
	closeGraph(genv);
	return 0;
}