Exemplo n.º 1
0
bool QgsCircularString::deleteVertex( QgsVertexId position )
{
  int nVertices = this->numPoints();
  if ( nVertices < 4 ) //circular string must have at least 3 vertices
  {
    clear();
    return true;
  }
  if ( position.vertex < 0 || position.vertex > ( nVertices - 1 ) )
  {
    return false;
  }

  if ( position.vertex < ( nVertices - 2 ) )
  {
    //remove this and the following vertex
    deleteVertex( position.vertex + 1 );
    deleteVertex( position.vertex );
  }
  else //remove this and the preceding vertex
  {
    deleteVertex( position.vertex );
    deleteVertex( position.vertex - 1 );
  }

  clearCache(); //set bounding box invalid
  return true;
}
Exemplo n.º 2
0
int VertexTreeWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QTreeWidget::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: redraw(); break;
        case 1: updateMesh(); break;
        case 2: addEdgeBetweenFaces((*reinterpret_cast< Vertex*(*)>(_a[1]))); break;
        case 3: sendX((*reinterpret_cast< double(*)>(_a[1]))); break;
        case 4: sendY((*reinterpret_cast< double(*)>(_a[1]))); break;
        case 5: sendZ((*reinterpret_cast< double(*)>(_a[1]))); break;
        case 6: enableXYZ((*reinterpret_cast< bool(*)>(_a[1]))); break;
        case 7: enableRGB((*reinterpret_cast< bool(*)>(_a[1]))); break;
        case 8: sendVertex((*reinterpret_cast< Vertex*(*)>(_a[1]))); break;
        case 9: acceptMesh((*reinterpret_cast< Mesh*(*)>(_a[1]))); break;
        case 10: setX((*reinterpret_cast< double(*)>(_a[1]))); break;
        case 11: setY((*reinterpret_cast< double(*)>(_a[1]))); break;
        case 12: setZ((*reinterpret_cast< double(*)>(_a[1]))); break;
        case 13: deleteVertex(); break;
        case 14: addVertexToEdge(); break;
        case 15: addEdgeBetweenFaces(); break;
        case 16: activated(); break;
        default: ;
        }
        _id -= 17;
    }
    return _id;
}
Exemplo n.º 3
0
void MKM::findBlockingFlow()
{
  initBlockingFlow();

  uint32_t nOfVertices = network_->getNOfVertices();

  while (1)
  {
    uint32_t curVertex = nOfVertices;

    for (uint32_t tryVertex = 0; tryVertex < nOfVertices; tryVertex++)
    {
      if (visitedVertex_[tryVertex]) continue;

      if (curVertex == nOfVertices || 
          getPotential (tryVertex) < getPotential (curVertex))
        curVertex = tryVertex;
    }

    if (curVertex == nOfVertices)
        break;

    Capacity_t deltaFlow = getPotential (curVertex);
    network_->addNetworkFlow (deltaFlow);

    pushPreflow (curVertex, deltaFlow, Forward);
    pushPreflow (curVertex, deltaFlow, Backward);

    deleteVertex (curVertex);
  }
}
Exemplo n.º 4
0
void My3DViewer::setAztec(MyGLWidget* m){
	aztec=m;
	connect(splitQuad, SIGNAL(clicked()), aztec, SLOT(splitQuad()));
	connect(deleteVertex, SIGNAL(clicked()), aztec, SLOT(deleteVertex()));
	connect(insertEdge, SIGNAL(clicked()), aztec, SLOT(insertEdge()));
	connect(incrementSharpness, SIGNAL(clicked()), aztec, SLOT(incSharpness()));
	connect(decrementSharpness, SIGNAL(clicked()), aztec, SLOT(decSharpness()));
	connect(forcePlanarity, SIGNAL(clicked()), aztec, SLOT(toggleForcePlanarity()));
	connect(insertVertex, SIGNAL(clicked()), aztec, SLOT(insertVertex()));
	connect(smooth, SIGNAL(clicked()), aztec, SLOT(smooth()));
	connect(extrude, SIGNAL(clicked()), aztec, SLOT(extrude2()));

	connect(faceButton, SIGNAL(clicked()), aztec, SLOT(enterFaceMode()));
	connect(objectButton, SIGNAL(clicked()), aztec, SLOT(enterObjectMode()));
	connect(vertexButton, SIGNAL(clicked()), aztec, SLOT(enterVertexMode()));
	connect(edgeButton, SIGNAL(clicked()), aztec, SLOT(enterEdgeMode()));
	connect(cpButton, SIGNAL(clicked()), aztec, SLOT(enterCPMode()));

	connect(snapToFace, SIGNAL(clicked()), aztec, SLOT(snapToFace()));
	connect(snapToEdge, SIGNAL(clicked()), aztec, SLOT(snapToEdge()));
	connect(snapToVertex, SIGNAL(clicked()), aztec, SLOT(snapToVertex()));

	//Connect mouse move events
	connect(aztec, SIGNAL(sendMouseEvent(QMouseEvent*)), this, SLOT(moveEvent(QMouseEvent*)));

		//errors
	connect(aztec, SIGNAL(error(char*)), this, SLOT(throwError(char*)));
	
}
Exemplo n.º 5
0
void SuffixTree::deleteVertex(Vertex * vertex)
{
    for (int i = 0; i < ALPHABET; ++i) {
        if (vertex->getNext(i) != nullptr) {
        deleteVertex(vertex->getNext(i));
        }
    }
    delete vertex;
}
main()
{
	int choice,u,origin,destin;
	
	while(1)
	{
		
		printf("1.Insert a Vertex\n");
		printf("2.Insert an Edge\n");
		printf("3.Delete a Vertex\n");
		printf("4.Delete an Edge\n");
		printf("5.Display\n");
		printf("6.Exit\n");
		printf("Enter your choice : ");
		scanf("%d",&choice);
		system("cls");
			
		switch(choice)
		{
		 case 1:
			printf("Enter a vertex to be inserted : ");
			scanf("%d",&u);
			insertVertex(u);
			break;
		 case 2:
			printf("Enter an Edge to be inserted : ");
			scanf("%d %d",&origin,&destin);
			insertEdge(origin,destin);
			break;
		 case 3:
			printf("Enter a vertex to be deleted : ");
			scanf("%d",&u);
			/*This function deletes all edges coming to this vertex*/
			deleteIncomingEdges(u);
			/*This function deletes the vertex from the vertex list*/
			deleteVertex(u);
			break;
		 case 4:
			printf("Enter an edge to be deleted : ");
			scanf("%d %d",&origin,&destin);
			deleteEdge(origin,destin);
			break;
		 case 5:
			display();
			break;
		 case 6:
			exit(1);
		 default:
			printf("Wrong choice\n");
			break;
		 }/*End of switch*/
	}/*End of while*/
}/*End of main()*/
Exemplo n.º 7
0
    //-----------------------------------------------------------------------
    void Polygon::removeDuplicates( void )
    {
        for ( size_t i = 0; i < getVertexCount(); ++i )
        {
            const Vector3& a = getVertex( i );
            const Vector3& b = getVertex( (i + 1)%getVertexCount() );

            if (a.positionEquals(b))
            {
                deleteVertex(i);
                --i;
            }
        }
    }
Exemplo n.º 8
0
int bipartGraphDeleteVertex(bpGraph_t* pGraph, int vertId, int partite)
{
	int errorStatus;

	if (partite == 1) {

		/* delete linked list node */
		errorStatus = deleteVertex(pGraph->vertices1, vertId);

		if (errorStatus > 0) {

            findAndDelete(pGraph, vertId, partite);

			return FOUND;
		}

		/* vertex not in graph */
		return NOT_FOUND;
	}
	else if (partite == 2) {

		/* delete linked list node */
		errorStatus = deleteVertex(pGraph->vertices2, vertId);

		if (errorStatus > 0) {

            findAndDelete(pGraph, vertId, partite);

			return FOUND;
		}
		/* vertex not in graph */
		return NOT_FOUND;
	}

	return ERROR_VALUE;
} /* end of bipartGraphDeleteVertex() */
void SelectableGeometryFeatures::deleteVertex(const Vector2dd &point)
{
    vector<Vertex*> toDelete;

    for (unsigned i = 0; i < mPoints.size(); i++)
    {
        if (mPoints[i]->position == point)
        {
            toDelete.push_back(mPoints[i]);
        }
    }

    for (unsigned i = 0; i < toDelete.size(); i++)
    {       
        deleteVertex(toDelete[i]);
    }
}
Exemplo n.º 10
0
int main()
{
	int flag, vertex1, vertex2, del_vertex;
	createGraph(8);
	do{
		printf("1.Insert  2.Delete  3.Print  4.DFS  5.BFS  6.Quit\n");
		scanf("%d",&flag);
		switch(flag){
		case 1:
			printf("Start Vertex와 End Vertex를 입력하세요 (quit:-1 -1)\n");
			scanf("%d%d",&vertex1,&vertex2);
			while(vertex1!=-1){
				insertEdge(vertex1, vertex2);
				insertEdge(vertex2, vertex1);
				printf("Start Vertex와 End Vertex를 입력하세요 (quit:-1 -1)\n");
				scanf("%d%d",&vertex1,&vertex2);
			}
			break;
		case 2:
			printf("삭제할 Vertex를 입력하세요 : ");
			scanf("%d",&del_vertex);
			deleteVertex(del_vertex);
			break;
		case 3:
			printGraph();
			break;
		case 4:
			vertexInit();
			dfs(0);
			printf("\n");
			break;
		case 5:
			vertexInit();
			bfs(0);
			printf("\n");
			break;
		}
	}while(flag!=6);
	return 0;
}
Exemplo n.º 11
0
void QgsGrassEdit::keyPress( QKeyEvent *e )
{
  QgsDebugMsg( "entered." );
  // This does not work:
  //keyPressEvent(e);

  // TODO: this is not optimal
  switch ( e->key() )
  {
    case Qt::Key_F1: newPoint(); break;
    case Qt::Key_F2: newLine(); break;
    case Qt::Key_F3: newBoundary(); break;
    case Qt::Key_F4: newCentroid(); break;
    case Qt::Key_F5: moveVertex(); break;
    case Qt::Key_F6: addVertex(); break;
    case Qt::Key_F7: deleteVertex(); break;
    case Qt::Key_F9: moveLine(); break;
    case Qt::Key_F10: splitLine(); break;
    case Qt::Key_F11: deleteLine(); break;
    default: break;
  }
}
Exemplo n.º 12
0
void Mesh::optimize(bool topological, int nSmooth) {
    int i;

    if (topological) {
        calcNeigTria();
        calcNeigbor();

        for (int i = 0; i < 5; i++)
            smoothing();

        deleteVertex();
        for(i=0;i<5;i++)
            smoothing();

        mergeVertex();
        mergeVertex();
        mergeVertex();
        for(i=0;i<5;i++)
            smoothing();

        splitVertex();
        splitVertex();
        splitVertex();

        swapEdge();
        for(i=0;i<5;i++)
            smoothing();
        swapEdge();
        for(i=0;i<5;i++)
            smoothing();
        swapEdge();
        for(i=0;i<5;i++)
            smoothing();
        swapEdge();
    }

    for(i=0;i<nSmooth;i++)
        smoothing();
}
Exemplo n.º 13
0
void MainWindow::keyPressEvent(QKeyEvent *event)
{
	switch(event->key())
	{
	case Qt::Key_S:
		settingsWidget->show();
		settingsWidget->raise();
		break;
    case Qt::Key_G:
		createDistanceField();
		break;
    case Qt::Key_I:
		addVertex();
		break;
    case Qt::Key_D:
		if(mainSpline->getPoints().size() > 3)
			deleteVertex();
		break;
	default:
		event->ignore();
	}
}
graphe* purgeGraphe(call_t* c, int farestNode, int fromNode, int predNode)
{
	struct nodedata *nodedata = get_node_private_data(c);
	int ret;
	graphe* g = copieGraphe(nodedata->g2hop);
	double costMax = getEdgeCost(g, c->node, farestNode), cost;
	
	// on enleve du graphe tous les voisins directs de fromNode
	// sauf celui qu'on doit toucher et nous meme
	// on garde egalement les noeuds voisins de fromNode qui sont plus pres de nous que farestNode
	
	voisin* voisinsFromNode = getNeighboursFromLabel(g, fromNode);
	while(voisinsFromNode != 0)
	{
		if(
		   (voisinsFromNode->vLabel != c->node)
		   &&
		   (getEdgeCost(g, c->node, voisinsFromNode->vLabel) > costMax)
		   )
		{
			//printf("1 - purge vertex %d\n", voisinsFromNode->vLabel);
			ret = deleteVertex(g, voisinsFromNode->vLabel);
			if(ret == -1)
				break;
			
			voisinsFromNode = getNeighboursFromLabel(g, fromNode);
		}
		else
		{
			voisinsFromNode = voisinsFromNode->vSuiv;
		}
	}
	
	// on enleve du graphe celui qui nous a envoye le paquet
	deleteVertex(g, fromNode);
	
	
	voisin* voisinsPredNode = getNeighboursFromLabel(g, predNode);
	while(voisinsPredNode != 0)
	{
		if(
		   (voisinsPredNode->vLabel != c->node)
		   &&
		   (getEdgeCost(g, c->node, voisinsPredNode->vLabel) > costMax)
		   )
		{
			//printf("1 - purge vertex %d\n", voisinsFromNode->vLabel);
			ret = deleteVertex(g, voisinsPredNode->vLabel);
			if(ret == -1)
				break;
			
			voisinsPredNode = getNeighboursFromLabel(g, predNode);
		}
		else
		{
			voisinsPredNode = voisinsPredNode->vSuiv;
		}
	}
	
	// on enleve du graphe celui qui nous a relaye le paquet
	deleteVertex(g, predNode);
	//printf("2 - purge vertex %d\n", fromNode);
	
	// on enleve du graphe les voisins directs plus loins que farestNode
	voisin* fils = getNeighboursFromLabel(g, c->node);
	
	while(fils != 0)
	{
		cost = fils->cout;
		if(cost	> costMax)
		{
			//printf("3 - purge vertex %d\n", fils->vLabel);
			ret = deleteVertex(g, fils->vLabel);
			if(ret == -1)
				break;
			fils = getNeighboursFromLabel(g, c->node);
		}
		else
			fils = fils->vSuiv;
	}
	
	// on purge le graphe
	purgeGrapheOfStables(g);
	
	return g;
}
Exemplo n.º 15
0
void QgsGrassEdit::init()
{
  if ( !( mProvider->isGrassEditable() ) )
  {
    QMessageBox::warning( 0, tr( "Warning" ),
                          tr( "You are not owner of the mapset, cannot open the vector for editing." ) );
    return;
  }

  if ( !( mProvider->startEdit() ) )
  {
    QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector for update." ) );
    return;
  }

  mRubberBandLine = new QgsRubberBand( mCanvas );
  mRubberBandIcon = new QgsVertexMarker( mCanvas );
  mRubberBandLine->setZValue( 20 );
  mRubberBandIcon->setZValue( 20 );

  connect( mCanvas, SIGNAL( keyPressed( QKeyEvent * ) ), this, SLOT( keyPress( QKeyEvent * ) ) );


  mToolBar = addToolBar( tr( "Edit tools" ) );

  mNewPointAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_new_point.png" ), tr( "New point" ), this );
  mNewPointAction->setShortcut( QKeySequence( Qt::Key_F1 ) );
  mToolBar->addAction( mNewPointAction );
  connect( mNewPointAction, SIGNAL( triggered() ), this, SLOT( newPoint() ) );

  mNewLineAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_new_line.png" ), tr( "New line" ), this );
  mNewLineAction->setShortcut( QKeySequence( Qt::Key_F2 ) );
  mToolBar->addAction( mNewLineAction );
  connect( mNewLineAction, SIGNAL( triggered() ), this, SLOT( newLine() ) );

  mNewBoundaryAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_new_boundary.png" ), tr( "New boundary" ), this );
  mNewBoundaryAction->setShortcut( QKeySequence( Qt::Key_F3 ) );
  mToolBar->addAction( mNewBoundaryAction );
  connect( mNewBoundaryAction, SIGNAL( triggered() ), this, SLOT( newBoundary() ) );

  mNewCentroidAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_new_centroid.png" ), tr( "New centroid" ), this );
  mNewCentroidAction->setShortcut( QKeySequence( Qt::Key_F4 ) );
  mToolBar->addAction( mNewCentroidAction );
  connect( mNewCentroidAction, SIGNAL( triggered() ), this, SLOT( newCentroid() ) );

  mMoveVertexAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_move_vertex.png" ), tr( "Move vertex" ), this );
  mMoveVertexAction->setShortcut( QKeySequence( Qt::Key_F5 ) );
  mToolBar->addAction( mMoveVertexAction );
  connect( mMoveVertexAction, SIGNAL( triggered() ), this, SLOT( moveVertex() ) );

  mAddVertexAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_add_vertex.png" ), tr( "Add vertex" ), this );
  mAddVertexAction->setShortcut( QKeySequence( Qt::Key_F6 ) );
  mToolBar->addAction( mAddVertexAction );
  connect( mAddVertexAction, SIGNAL( triggered() ), this, SLOT( addVertex() ) );

  mDeleteVertexAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_delete_vertex.png" ), tr( "Delete vertex" ), this );
  mDeleteVertexAction->setShortcut( QKeySequence( Qt::Key_F7 ) );
  mToolBar->addAction( mDeleteVertexAction );
  connect( mDeleteVertexAction, SIGNAL( triggered() ), this, SLOT( deleteVertex() ) );

  mMoveLineAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_move_line.png" ), tr( "Move element" ), this );
  mMoveLineAction->setShortcut( QKeySequence( Qt::Key_F9 ) );
  mToolBar->addAction( mMoveLineAction );
  connect( mMoveLineAction, SIGNAL( triggered() ), this, SLOT( moveLine() ) );

  mSplitLineAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_split_line.png" ), tr( "Split line" ), this );
  mSplitLineAction->setShortcut( QKeySequence( Qt::Key_F10 ) );
  mToolBar->addAction( mSplitLineAction );
  connect( mSplitLineAction, SIGNAL( triggered() ), this, SLOT( splitLine() ) );

  mDeleteLineAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_delete_line.png" ), tr( "Delete element" ), this );
  mDeleteLineAction->setShortcut( QKeySequence( Qt::Key_F11 ) );
  mToolBar->addAction( mDeleteLineAction );
  connect( mDeleteLineAction, SIGNAL( triggered() ), this, SLOT( deleteLine() ) );

  mEditAttributesAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_edit_attributes.png" ), tr( "Edit attributes" ), this );
  mToolBar->addAction( mEditAttributesAction );
  connect( mEditAttributesAction, SIGNAL( triggered() ), this, SLOT( editAttributes() ) );

  mCloseEditAction = new QAction(
    QgsGrassPlugin::getThemeIcon( "grass_close_edit.png" ), tr( "Close" ), this );
  mToolBar->addAction( mCloseEditAction );
  connect( mCloseEditAction, SIGNAL( triggered() ), this, SLOT( closeEdit() ) );

  mNewPointAction->setCheckable( true );
  mNewLineAction->setCheckable( true );
  mNewBoundaryAction->setCheckable( true );
  mNewCentroidAction->setCheckable( true );
  mMoveVertexAction->setCheckable( true );
  mAddVertexAction->setCheckable( true );
  mDeleteVertexAction->setCheckable( true );
  mMoveLineAction->setCheckable( true );
  mSplitLineAction->setCheckable( true );
  mDeleteLineAction->setCheckable( true );
  mEditAttributesAction->setCheckable( true );

  QActionGroup *ag = new QActionGroup( this );
  ag->addAction( mNewPointAction );
  ag->addAction( mNewLineAction );
  ag->addAction( mNewBoundaryAction );
  ag->addAction( mNewCentroidAction );
  ag->addAction( mMoveVertexAction );
  ag->addAction( mAddVertexAction );
  ag->addAction( mDeleteVertexAction );
  ag->addAction( mMoveLineAction );
  ag->addAction( mSplitLineAction );
  ag->addAction( mDeleteLineAction );
  ag->addAction( mEditAttributesAction );

  mEditPoints = Vect_new_line_struct();
  mPoints = Vect_new_line_struct();
  mCats = Vect_new_cats_struct();

  // Set lines symbology from map
  int nlines = mProvider->numLines();
  mLineSymb.resize( nlines + 1000 );
  for ( int line = 1; line <= nlines; line++ )
  {
    mLineSymb[line] = lineSymbFromMap( line );
  }

  // Set nodes symbology from map
  int nnodes = mProvider->numNodes();
  mNodeSymb.resize( nnodes + 1000 );
  for ( int node = 1; node <= nnodes; node++ )
  {
    mNodeSymb[node] = nodeSymbFromMap( node );
  }

  // Set default colors
  mSymb.resize( SYMB_COUNT );
  mSymb[SYMB_BACKGROUND].setColor( QColor( 255, 255, 255 ) );       // white
  mSymb[SYMB_HIGHLIGHT].setColor( QColor( 255, 255,   0 ) );        // yellow
  mSymb[SYMB_DYNAMIC].setColor( QColor( 125, 125, 125 ) );          // grey
  mSymb[SYMB_POINT].setColor( QColor( 0,   0,   0 ) );              // black
  mSymb[SYMB_LINE].setColor( QColor( 0,   0,   0 ) );               // black
  mSymb[SYMB_BOUNDARY_0].setColor( QColor( 255,   0,   0 ) );       // red
  mSymb[SYMB_BOUNDARY_1].setColor( QColor( 255, 125,   0 ) );       // orange
  mSymb[SYMB_BOUNDARY_2].setColor( QColor( 0, 255,   0 ) );         // green
  mSymb[SYMB_CENTROID_IN].setColor( QColor( 0, 255,   0 ) );        // green
  mSymb[SYMB_CENTROID_OUT].setColor( QColor( 255,   0,   0 ) );     // red
  mSymb[SYMB_CENTROID_DUPL].setColor( QColor( 255,   0, 255 ) );    // magenta
  mSymb[SYMB_NODE_1].setColor( QColor( 255,   0,   0 ) );           // red
  mSymb[SYMB_NODE_2].setColor( QColor( 0, 255,   0 ) );             // green

  // Set mSymbDisplay
  mSymbDisplay.resize( SYMB_COUNT );
  mSymbDisplay[SYMB_BACKGROUND] = true;
  mSymbDisplay[SYMB_HIGHLIGHT] = true;
  mSymbDisplay[SYMB_DYNAMIC] = true;
  mSymbDisplay[SYMB_POINT] = true;
  mSymbDisplay[SYMB_LINE] = true;
  mSymbDisplay[SYMB_BOUNDARY_0] = true;
  mSymbDisplay[SYMB_BOUNDARY_1] = true;
  mSymbDisplay[SYMB_BOUNDARY_2] = true;
  mSymbDisplay[SYMB_CENTROID_IN] = true;
  mSymbDisplay[SYMB_CENTROID_OUT] = true;
  mSymbDisplay[SYMB_CENTROID_DUPL] = true;
  mSymbDisplay[SYMB_NODE_1] = true;
  mSymbDisplay[SYMB_NODE_2] = true;

  // Set symbology names
  mSymbName.resize( SYMB_COUNT );
  mSymbName[SYMB_BACKGROUND]    = tr( "Background" );
  mSymbName[SYMB_HIGHLIGHT]     = tr( "Highlight" );
  mSymbName[SYMB_DYNAMIC]       = tr( "Dynamic" );
  mSymbName[SYMB_POINT]         = tr( "Point" );
  mSymbName[SYMB_LINE]          = tr( "Line" );
  mSymbName[SYMB_BOUNDARY_0]    = tr( "Boundary (no area)" );
  mSymbName[SYMB_BOUNDARY_1]    = tr( "Boundary (1 area)" );
  mSymbName[SYMB_BOUNDARY_2]    = tr( "Boundary (2 areas)" );
  mSymbName[SYMB_CENTROID_IN]   = tr( "Centroid (in area)" );
  mSymbName[SYMB_CENTROID_OUT]  = tr( "Centroid (outside area)" );
  mSymbName[SYMB_CENTROID_DUPL] = tr( "Centroid (duplicate in area)" );
  mSymbName[SYMB_NODE_1]        = tr( "Node (1 line)" );
  mSymbName[SYMB_NODE_2]        = tr( "Node (2 lines)" );

  // Restore symbology
  QString spath = "/GRASS/edit/symb/";
  QSettings settings;

  mLineWidth = settings.value(
                 spath + "lineWidth", 1 ).toInt();
  mSize = settings.value(
            spath + "markerSize", 9 ).toInt();
  mLineWidthSpinBox->setValue( mLineWidth );
  mMarkerSizeSpinBox->setValue( mSize );

  for ( int i = 0; i < SYMB_COUNT; i++ )
  {
    bool ok = settings.contains(
                spath + "display/" + QString::number( i ) );
    bool displ = settings.value(
                   spath + "display/" + QString::number( i ),
                   true ).toBool();
    if ( ok )
    {
      mSymbDisplay[i] = displ;
    }

    ok = settings.contains(
           spath + "color/" + QString::number( i ) );
    QString colorName = settings.value(
                          spath + "color/" + QString::number( i ),
                          "" ).toString();
    if ( ok )
    {
      QColor color( colorName );
      mSymb[i].setColor( color );
      // Use the 'dynamic' color for mRubberBand
      if ( i == SYMB_DYNAMIC )
      {
        mRubberBandLine->setColor( QColor( colorName ) );
      }
    }
    mSymb[i].setWidth( mLineWidth );
  }

  // Set Symbology in dialog
  symbologyList->setColumnWidth( 0, 40 );
  symbologyList->setColumnWidth( 1, 50 );
  symbologyList->setColumnWidth( 2, 200 );

  for ( int i = 0; i < SYMB_COUNT; i++ )
  {
    if ( i == SYMB_NODE_0 )
      continue;

    QPixmap pm( 40, 15 );
    pm.fill( mSymb[i].color() );
    QString index;
    index.sprintf( "%d", i );

    QTreeWidgetItem *item = new QTreeWidgetItem( symbologyList );
    if ( !( i == SYMB_BACKGROUND || i == SYMB_HIGHLIGHT || i == SYMB_DYNAMIC ) )
    {
      item->setCheckState( 0, mSymbDisplay[i] ? Qt::Checked : Qt::Unchecked );
    }
    item->setIcon( 1, pm );
    item->setText( 2, mSymbName[i] );
    item->setText( 3, index );
  }

  connect( symbologyList, SIGNAL( itemPressed( QTreeWidgetItem *, int ) ),
           this, SLOT( changeSymbology( QTreeWidgetItem *, int ) ) );

  // Init table tab
  mAttributeTable->setItemDelegate( new QgsGrassEditAttributeTableItemDelegate( this ) );
  mAttributeTable->verticalHeader()->hide();

  int ndblinks = mProvider->numDbLinks();

  if ( ndblinks > 0 )
  {
    for ( int i = 0; i < ndblinks; i++ )
    {
      int f = mProvider->dbLinkField( i );

      QString str;
      str.sprintf( "%d", f );
      mTableField->addItem( str );
      mFieldBox->addItem( str );
      if ( i == 0 )
      {
        setAttributeTable( f );
      }
    }
    mTableField->setCurrentIndex( 0 );
    mFieldBox->setCurrentIndex( 0 );
  }
  else
  {
    mTableField->addItem( "1" );
    setAttributeTable( 1 );

    mFieldBox->addItem( "1" );
  }

  connect( mAttributeTable, SIGNAL( cellChanged( int, int ) ), this, SLOT( columnTypeChanged( int, int ) ) );

  // Set variables
  mSelectedLine = 0;
  mAttributes = 0;

  // Read max cats
  for ( int i = 0; i < mProvider->cidxGetNumFields(); i++ )
  {
    int field = mProvider->cidxGetFieldNumber( i );
    if ( field > 0 )
    {
      int cat = mProvider->cidxGetMaxCat( i );
      MaxCat mc;
      mc.field = field;
      mc.maxCat = cat;
      mMaxCats.push_back( mc );
    }
  }

  connect( mCanvas, SIGNAL( renderComplete( QPainter * ) ), this, SLOT( postRender( QPainter * ) ) );

  mCanvasEdit = new QgsGrassEditLayer( mCanvas );

  mPixmap = &mCanvasEdit->pixmap();

  // Init GUI values
  mCatModeBox->addItem( tr( "Next not used" ), CAT_MODE_NEXT );
  mCatModeBox->addItem( tr( "Manual entry" ), CAT_MODE_MANUAL );
  mCatModeBox->addItem( tr( "No category" ), CAT_MODE_NOCAT );
  catModeChanged( );

  // TODO: how to get keyboard events from canvas (shortcuts)

  restorePosition();

  mValid = true;
  mInited = true;
}
Exemplo n.º 16
0
bool Network::deleteVertex(const std::string& vertex_name) {
	if (!isNamed()) throw OperationNotSupportedException("Cannot reference a named vertex in an unnamed network");
	if (!containsVertex(vertex_name)) return false;
	deleteVertex(vertex_name_to_id[vertex_name]);
	return true;
}
Exemplo n.º 17
0
typename PolygonMesh<PointType>::FaceIterator PolygonMesh<PointType>::removeVertex(const typename PolygonMesh<PointType>::VertexIterator& vertexIt)
	{
	if(vertexIt->isInterior())
		{
		/* Combine all surrounding faces into a single face: */
		Face* vertexFace=newFace();
		Edge* lastEdge=0;
		Edge* ePtr=vertexIt->getEdge();
		ePtr->getOpposite()->setOpposite(0);
		while(ePtr!=0)
			{
			/* Re-arrange all face pointers: */
			Edge* vePtr=ePtr->getFaceSucc();
			while(vePtr!=ePtr->getFacePred())
				{
				vePtr->setFace(vertexFace);
				vePtr=vePtr->getFaceSucc();
				}
			
			/* Fix up the vertex: */
			ePtr->getEnd()->setEdge(ePtr->getFaceSucc());
			
			/* Delete the outgoing and incoming edges: */
			Edge* nextEptr=ePtr->getVertexSucc();
			ePtr->getFaceSucc()->setFacePred(lastEdge);
			if(lastEdge!=0)
				lastEdge->setFacePred(ePtr->getFaceSucc());
			else
				vertexFace->setEdge(ePtr->getFaceSucc());
			lastEdge=ePtr->getFacePred()->getFacePred();
			deleteFace(ePtr->getFace());
			deleteEdge(ePtr->getFacePred());
			deleteEdge(ePtr);
			
			/* Go to the next face: */
			ePtr=nextEptr;
			}
		
		/* Close the face loop: */
		lastEdge->setFaceSucc(vertexFace->getEdge());
		vertexFace->getEdge()->setFacePred(lastEdge);
		
		deleteVertex(vertexIt.vertex);
		return vertexFace;
		}
	else if(vertexIt->getEdge()!=0)
		{
		/* Go backwards until border edge is hit: */
		Edge* ePtr;
		for(ePtr=vertexIt->getEdge();ePtr->getOpposite()!=0;ePtr=ePtr->getVertexPred())
			;
		
		/* Remove all surrounding faces: */
		while(ePtr!=0)
			{
			Edge* nextEptr=ePtr->getVertexSucc();
			deleteFace(ePtr->getFace());
			Edge* fePtr=ePtr;
			do
				{
				Edge* nextFePtr=fePtr->getFaceSucc();
				
				/* Fix up the vertex: */
				if(nextFePtr!=ePtr)
					{
					if(nextFePtr->getVertexPred()!=0)
						nextFePtr->getStart()->setEdge(nextFePtr->getVertexPred());
					else
						nextFePtr->getStart()->setEdge(fePtr->getOpposite()->getFacePred());
					}
				
				/* Remove the edge: */
				if(fePtr->getOpposite()!=0)
					fePtr->getOpposite()->setOpposite(0);
				deleteEdge(fePtr);
				}
			while(fePtr!=ePtr);
			
			ePtr=nextEptr;
			}
		
		deleteVertex(vertexIt.vertex);
		return FaceIterator(0);
		}
	else // Dangling vertex
		{
		deleteVertex(vertexIt.vertex);
		return FaceIterator(0);
		}
	}
Exemplo n.º 18
0
SuffixTree::~SuffixTree()
{
    deleteVertex(root);
    delete blank;
    line.clear();
}
Exemplo n.º 19
0
View2D::View2D(const QString &name, QWidget *parent)
    : QFrame(parent)
{
    setFrameStyle(Sunken | StyledPanel);
    graphicsView = new GraphicsView(this);
    graphicsView->setRenderHint(QPainter::Antialiasing, false);
    graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
    graphicsView->setOptimizationFlags(QGraphicsView::DontSavePainterState);
    graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);

    int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
    QSize iconSize(size, size);

    QToolButton *zoomInIcon = new QToolButton;
    zoomInIcon->setAutoRepeat(true);
    zoomInIcon->setAutoRepeatInterval(33);
    zoomInIcon->setAutoRepeatDelay(0);
    zoomInIcon->setIcon(QPixmap(":/zoomin.png"));
    zoomInIcon->setIconSize(iconSize);
    QToolButton *zoomOutIcon = new QToolButton;
    zoomOutIcon->setAutoRepeat(true);
    zoomOutIcon->setAutoRepeatInterval(33);
    zoomOutIcon->setAutoRepeatDelay(0);
    zoomOutIcon->setIcon(QPixmap(":/zoomout.png"));
    zoomOutIcon->setIconSize(iconSize);
    zoomSlider = new QSlider;
    zoomSlider->setMinimum(0);
    zoomSlider->setMaximum(500);
    zoomSlider->setValue(250);
    zoomSlider->setTickPosition(QSlider::TicksRight);

    // Zoom slider layout
    QVBoxLayout *zoomSliderLayout = new QVBoxLayout;
    zoomSliderLayout->addWidget(zoomInIcon);
    zoomSliderLayout->addWidget(zoomSlider);
    zoomSliderLayout->addWidget(zoomOutIcon);

    QToolButton *rotateLeftIcon = new QToolButton;
    rotateLeftIcon->setIcon(QPixmap(":/rotateleft.png"));
    rotateLeftIcon->setIconSize(iconSize);
    QToolButton *rotateRightIcon = new QToolButton;
    rotateRightIcon->setIcon(QPixmap(":/rotateright.png"));
    rotateRightIcon->setIconSize(iconSize);
    rotateSlider = new QSlider;
    rotateSlider->setOrientation(Qt::Horizontal);
    rotateSlider->setMinimum(-360);
    rotateSlider->setMaximum(360);
    rotateSlider->setValue(0);
    rotateSlider->setTickPosition(QSlider::TicksBelow);

    // Rotate slider layout
    QHBoxLayout *rotateSliderLayout = new QHBoxLayout;
    rotateSliderLayout->addWidget(rotateLeftIcon);
    rotateSliderLayout->addWidget(rotateSlider);
    rotateSliderLayout->addWidget(rotateRightIcon);

    resetButton = new QToolButton;
    resetButton->setText(tr("0"));
    resetButton->setEnabled(false);

    // Label layout
    QHBoxLayout *labelLayout = new QHBoxLayout;
    label = new QLabel(name);
	deleteVertexButton = new QToolButton;
	deleteVertexButton->setText(tr("Delete"));
    label2 = new QLabel(tr("Pointer Mode"));
    selectModeButton = new QToolButton;
    selectModeButton->setText(tr("Select"));
    selectModeButton->setCheckable(true);
    selectModeButton->setChecked(true);
    dragModeButton = new QToolButton;
    dragModeButton->setText(tr("Drag"));
    dragModeButton->setCheckable(true);
    dragModeButton->setChecked(false);
    antialiasButton = new QToolButton;
    antialiasButton->setText(tr("Antialiasing"));
    antialiasButton->setCheckable(true);
    antialiasButton->setChecked(false);
    openGlButton = new QToolButton;
    openGlButton->setText(tr("OpenGL"));
    openGlButton->setCheckable(true);
#ifndef QT_NO_OPENGL
    openGlButton->setEnabled(QGLFormat::hasOpenGL());
#else
    openGlButton->setEnabled(false);
#endif
    printButton = new QToolButton;
    printButton->setIcon(QIcon(QPixmap(":/fileprint.png")));

    QButtonGroup *pointerModeGroup = new QButtonGroup;
    pointerModeGroup->setExclusive(true);
    pointerModeGroup->addButton(selectModeButton);
    pointerModeGroup->addButton(dragModeButton);

    labelLayout->addWidget(label);
    labelLayout->addStretch();
    //labelLayout->addWidget(label2);
    //labelLayout->addWidget(selectModeButton);
    //labelLayout->addWidget(dragModeButton);
    //labelLayout->addStretch();
    //labelLayout->addWidget(antialiasButton);
    //labelLayout->addWidget(openGlButton);
    //labelLayout->addWidget(printButton);
	labelLayout->addWidget(deleteVertexButton);

    QGridLayout *topLayout = new QGridLayout;
    //topLayout->addLayout(labelLayout, 0, 0);
    topLayout->addWidget(graphicsView, 1, 0);
    topLayout->addLayout(zoomSliderLayout, 1, 1);
    topLayout->addLayout(rotateSliderLayout, 2, 0);
    topLayout->addWidget(resetButton, 2, 1);
    setLayout(topLayout);

    connect(resetButton, SIGNAL(clicked()), this, SLOT(resetView()));
    connect(zoomSlider, SIGNAL(valueChanged(int)), this, SLOT(setupMatrix()));
    connect(rotateSlider, SIGNAL(valueChanged(int)), this, SLOT(setupMatrix()));
    connect(graphicsView->verticalScrollBar(), SIGNAL(valueChanged(int)),
            this, SLOT(setResetButtonEnabled()));
    connect(graphicsView->horizontalScrollBar(), SIGNAL(valueChanged(int)),
            this, SLOT(setResetButtonEnabled()));
    connect(selectModeButton, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode()));
    connect(dragModeButton, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode()));
    connect(antialiasButton, SIGNAL(toggled(bool)), this, SLOT(toggleAntialiasing()));
    connect(openGlButton, SIGNAL(toggled(bool)), this, SLOT(toggleOpenGL()));
    connect(rotateLeftIcon, SIGNAL(clicked()), this, SLOT(rotateLeft()));
    connect(rotateRightIcon, SIGNAL(clicked()), this, SLOT(rotateRight()));
    connect(zoomInIcon, SIGNAL(clicked()), this, SLOT(zoomIn()));
    connect(zoomOutIcon, SIGNAL(clicked()), this, SLOT(zoomOut()));
    connect(printButton, SIGNAL(clicked()), this, SLOT(print()));
	connect(deleteVertexButton, SIGNAL(clicked()), this, SLOT(deleteVertex()));
    setupMatrix();
}
Exemplo n.º 20
0
typename PolygonMesh<PointType>::FaceIterator PolygonMesh<PointType>::vertexToFace(const typename PolygonMesh<PointType>::VertexIterator& vertexIt)
	{
	/* Remove solitary vertices: */
	if(vertexIt->getEdge()==0)
		{
		deleteVertex(vertexIt.vertex);
		return FaceIterator(0);
		}
	
	/* Walk around the vertex and flip its edges: */
	Face* vertexFace=newFace();
	Edge* lastEdge=0;
	Edge* ePtr=vertexIt->getEdge();
	do
		{
		Edge* nextEdge=ePtr->getFacePred()->getOpposite();
		
		/* Remove the edge from its current face and add it to the vertex face: */
		Edge* pred=ePtr->getFacePred();
		Edge* succ=ePtr->getFaceSucc();
		
		/* Test for the dangerous special case of a triangle: */
		if(succ->getFaceSucc()==pred)
			{
			/* Remove the triangle completely: */
			deleteFace(succ->getFace());
			deleteEdge(ePtr);
			deleteEdge(pred);
			
			/* Put the outside edge into the new face loop: */
			succ->set(succ->getStart(),vertexFace,lastEdge,0,succ->getOpposite());
			ePtr=succ;
			}
		else
			{
			pred->setFaceSucc(succ);
			succ->setFacePred(pred);
			ePtr->set(succ->getStart(),vertexFace,lastEdge,0,pred);
			pred->setOpposite(ePtr);
			ePtr->sharpness=pred->sharpness=0;
			pred->getFace()->setEdge(pred);

			#ifndef NDEBUG
			pred->getFace()->checkFace();
			#endif
			}
		
		if(lastEdge!=0)
			{
			lastEdge->setFaceSucc(ePtr);
			
			#ifndef NDEBUG
			ePtr->getStart()->checkVertex();
			#endif
			}
		else
			vertexFace->setEdge(ePtr);
		lastEdge=ePtr;
		
		ePtr=nextEdge;
		}
	while(ePtr!=vertexIt->getEdge());
	lastEdge->setFaceSucc(vertexFace->getEdge());
	vertexFace->getEdge()->setFacePred(lastEdge);
	
	#ifndef NDEBUG
	ePtr->getStart()->checkVertex();
	vertexFace->checkFace();
	#endif
	
	/* Delete the vertex and return the new face: */
	vertexIt->setEdge(0);
	deleteVertex(vertexIt.vertex);
	
	return FaceIterator(vertexFace);
	}
Exemplo n.º 21
0
   VertexIter HalfedgeMesh::collapseEdge( EdgeIter e )
   {
      // TODO This method should collapse the given edge and return an iterator to the new vertex created by the collapse.
		 
		 //1. collect elements
		 EdgeIter e4 = e;

		 //Halfedges
		 HalfedgeIter h1 = e4->halfedge();
		 HalfedgeIter h5 = h1->twin();
		 
		 //Faces
		 FaceIter f0 = h1->face();
		 FaceIter f1 = h5->face();
		 
		 //Early Exit #1: Ignore requests to collapse boundary edges
		 if(f0->isBoundary() || f1->isBoundary())
			 return verticesEnd();
		 
		 //Halfedges, cont'
		 HalfedgeIter h2 = h1->next();
		 HalfedgeIter h0 = h2->next();
		 HalfedgeIter h3 = h5->next();
		 HalfedgeIter h4 = h3->next();
		 
		 HalfedgeIter h7 = h0->twin();
		 HalfedgeIter h12 = h3->twin();
		 
		 HalfedgeIter h20 = h2->twin();
		 HalfedgeIter h15 = h4->twin();
		 
		 //Edges
		 EdgeIter e0 = h0->edge();
		 EdgeIter e1 = h3->edge();
		 EdgeIter e2 = h4->edge();
		 EdgeIter e3 = h2->edge();
			//EdgeIter e4
		 
		 //Faces
		 
		 //Vertices
		 VertexIter v0 = h0->vertex();
		 VertexIter v1 = h3->vertex();
		 VertexIter v2 = h4->vertex();
		 VertexIter v3 = h2->vertex();
		 
		 //Early Exit #2: The number of the joint neighbor vertices of the two merging vertices
		 //must be EXACTLY TWO
		 std::vector<VertexIter> v1_neighbors;
		 std::vector<VertexIter> v3_neighbors;
		 HalfedgeIter h = h3;
		 do
		 {
			 h = h->twin();
			 if(h->vertex() != v1)
				 v1_neighbors.push_back(h->vertex());
			 h = h->next();
		 }
		 while(h != h3);
		 h = h2;
		 do
		 {
			 h = h->twin();
			 if(h->vertex() != v3)
				 v3_neighbors.push_back(h->vertex());
			 h = h->next();
		 }
		 while(h != h2);
		 std::sort(v1_neighbors.begin(), v1_neighbors.end());
		 std::sort(v3_neighbors.begin(), v3_neighbors.end());
		 std::vector<VertexIter> joint_neighbors;
		 std::set_intersection(v1_neighbors.begin(), v1_neighbors.end(),
													 v3_neighbors.begin(), v3_neighbors.end(),
													 std::back_inserter(joint_neighbors));
		 if(joint_neighbors.size() != 2)
			 return verticesEnd();
		 
		 //Early Exit #3: mesh must have more than 4 vertices if neither v1 nor v3 is boundary vertex,
		 //and more than 3 vertices if either v1 or v3 is boundary vertex
		 if(!v1->isBoundary() && !v3->isBoundary() && nVertices() <= 4)
			 return verticesEnd();
		 if((v1->isBoundary() || v3->isBoundary()) && nVertices() <= 3)
			 return verticesEnd();
		 
		 //Early Exit #4: v1, v3 cannot be both boundary vertex
		 if(v1->isBoundary() && v3->isBoundary())
			 return verticesEnd();
		 
		 //Early Exit #5: boundary vertex needs at least one triangle
		 //By convention, Vertex::degree() returns the face degree
		 if(v0->isBoundary() && v0->degree() <= 1)
			 return verticesEnd();
		 if(v1->isBoundary() && v1->degree() <= 1)
			 return verticesEnd();
		 if(v2->isBoundary() && v2->degree() <= 1)
			 return verticesEnd();
		 if(v3->isBoundary() && v3->degree() <= 1)
			 return verticesEnd();
		
		 //Early Exit #6: degenerated case: v0/v1/v2/v3 are duplicated
		 if(v0 == v1 || v0 == v2 || v0 == v3 || v1 == v2 || v1 == v3 || v2 == v3)
			 return verticesEnd();
		 

		 
		 VertexIter output = verticesEnd();
		 if(v3->isBoundary())
		 {
			 std::vector<HalfedgeIter> v1_out;
			 HalfedgeIter h = v1->halfedge();
			 do
			 {
				 v1_out.push_back(h);
				 h = h->next()->next()->twin();
			 }
			 while(h != v1->halfedge());
			 
			 //2. reassign elements
			 
			 //Halfedges
			 h7->twin() = h20; h7->edge() = e3;
			 h20->twin() = h7;
			 h12->twin() = h15; h12->edge() = e2;
			 h15->twin() = h12;
			 
			 for(auto h = v1_out.begin(); h!= v1_out.end(); ++h)
				 (*h)->vertex() = v3;
			 
			 //Vertices
			 v0->halfedge() = h20;
			 v3->halfedge() = h15;
			 v3->position = 0.5f * (v1->position + v3->position);
			 v2->halfedge() = h12;
			 
			 //Edges
			 e3->halfedge() = h20;
			 e2->halfedge() = h15;
			 
			 //Faces
			 
			 //3. delete elements
			 //Halfedges
			 deleteHalfedge(h0);
			 deleteHalfedge(h1);
			 deleteHalfedge(h2);
			 deleteHalfedge(h3);
			 deleteHalfedge(h4);
			 deleteHalfedge(h5);
			 
			 //Vertices
			 deleteVertex(v1);
			 
			 //Edges
			 deleteEdge(e0);
			 deleteEdge(e1);
			 deleteEdge(e4);
			 
			 //Faces
			 deleteFace(f0);
			 deleteFace(f1);
			 
			 output = v3;
		 }
		 else
		 {
			 std::vector<HalfedgeIter> v3_out;
			 HalfedgeIter h = v3->halfedge();
			 do
			 {
				 v3_out.push_back(h);
				 h = h->next()->next()->twin();
			 }
			 while(h != v3->halfedge());
			 
			 //2. reassign elements
			 
			 //Halfedges
			 h7->twin() = h20;
			 h20->twin() = h7; h20->edge() = e0;
			 h12->twin() = h15;
			 h15->twin() = h12; h15->edge() = e1;
			 
			 for(auto h = v3_out.begin(); h!= v3_out.end(); ++h)
				 (*h)->vertex() = v1;
			 
			 //Vertices
			 v0->halfedge() = h20;
			 v1->halfedge() = h15;
			 v1->position = 0.5f * (v1->position + v3->position);
			 v2->halfedge() = h12;
			 
			 //Edges
			 e0->halfedge() = h20;
			 e1->halfedge() = h15;
			 
			 //Faces
			 
			 //3. delete elements
			 //Halfedges
			 deleteHalfedge(h0);
			 deleteHalfedge(h1);
			 deleteHalfedge(h2);
			 deleteHalfedge(h3);
			 deleteHalfedge(h4);
			 deleteHalfedge(h5);
			 
			 //Vertices
			 deleteVertex(v3);
			 
			 //Edges
			 deleteEdge(e2);
			 deleteEdge(e3);
			 deleteEdge(e4);
			 
			 //Faces
			 deleteFace(f0);
			 deleteFace(f1);
			 
			 output = v1;
		 }
		 
		 return output;
   }
Exemplo n.º 22
0
bool AutoTriangleMesh<PointType>::collapseEdge(const typename AutoTriangleMesh<PointType>::EdgeIterator& edge)
	{
	/* Get triangle topology: */
	Edge* e1=&(*edge);
	Edge* e2=e1->getFaceSucc();
	Edge* e3=e1->getFacePred();
	Edge* e4=e1->getOpposite();
	if(e4==0)
		return false;
	
	Edge* e5=e4->getFaceSucc();
	Edge* e6=e4->getFacePred();
	Edge* e7=e2->getOpposite();
	Edge* e8=e3->getOpposite();
	Edge* e9=e5->getOpposite();
	Edge* e10=e6->getOpposite();
	Vertex* v1=e1->getStart();
	Vertex* v2=e2->getStart();
	Vertex* v3=e3->getStart();
	Vertex* v4=e6->getStart();
	Face* f1=e1->getFace();
	Face* f2=e4->getFace();
	
	/* Check if v3 has valence of at least 4: */
	if(e7->getFacePred()->getOpposite()->getFacePred()==e8)
		return false;
	
	/* Check if v4 has valence of at least 4: */
	if(e9->getFacePred()->getOpposite()->getFacePred()==e10)
		return false;
	
	/* Check if v1 and v2 together have at least valence 7 (then collapsed v1 will have at least valence 3): */
	if(e7->getFaceSucc()==e10&&e9->getFaceSucc()==e8)
		return false;
	
	/* Check if platelets of v1 and v2 have common vertices (except each other, of course): */
	/* Currently highly inefficient at O(n^2); need to optimize! */
	for(Edge* ve1=e10->getFacePred();ve1!=e7;ve1=ve1->getOpposite()->getFacePred())
		for(Edge* ve2=e8->getFacePred();ve2!=e9;ve2=ve2->getOpposite()->getFacePred())
			if(ve1->getStart()==ve2->getStart())
				return false;
	
	assert(v2->getEdge()!=0);
	assert(f1->getEdge()!=0);
	assert(f2->getEdge()!=0);
	
	assert(e2->getFaceSucc()==e3&&e3->getFacePred()==e2);
	assert(e5->getFaceSucc()==e6&&e6->getFacePred()==e5);
	assert(e4->getStart()==v2);
	assert(e5->getStart()==v1);
	assert(e7->getOpposite()==e2);
	assert(e8->getOpposite()==e3);
	assert(e9->getOpposite()==e5);
	assert(e10->getOpposite()==e6);
	assert(e7->getStart()==v3);
	assert(e8->getStart()==v1);
	assert(e9->getStart()==v4);
	assert(e10->getStart()==v2);
	assert(e2->getFace()==f1);
	assert(e3->getFace()==f1);
	assert(e5->getFace()==f2);
	assert(e6->getFace()==f2);
	assert(f1->getEdge()==e1||f1->getEdge()==e2||f1->getEdge()==e3);
	assert(f2->getEdge()==e4||f2->getEdge()==e5||f2->getEdge()==e6);
	
	/* Move v1 to edge midpoint: */
	Point p=Point::zero();
	p.add(*v1);
	p.add(*v2);
	p.normalize(2);
	p.index=v1->index;
	v1->setPoint(p);
	
	/* Remove both faces from mesh: */
	e7->setOpposite(e8);
	e8->setOpposite(e7);
	if(e7->sharpness<e8->sharpness)
		e7->sharpness=e8->sharpness;
	else
		e8->sharpness=e7->sharpness;
	e9->setOpposite(e10);
	e10->setOpposite(e9);
	if(e9->sharpness<e10->sharpness)
		e9->sharpness=e10->sharpness;
	else
		e10->sharpness=e9->sharpness;
	v1->setEdge(e8);
	v3->setEdge(e7);
	v4->setEdge(e9);
	
	/* Remove v2 from mesh: */
	/* Note: Works currently only for closed meshes! */
	for(Edge* e=e10;e!=e8;e=e->getVertexSucc())
		{
		assert(e->getStart()==v2);
		e->setStart(v1);
		}
	
	assert(e7->getOpposite()==e8);
	assert(e8->getOpposite()==e7);
	assert(e9->getOpposite()==e10);
	assert(e10->getOpposite()==e9);
	assert(e7->getStart()==v3);
	assert(e8->getStart()==v1);
	assert(e9->getStart()==v4);
	assert(e10->getStart()==v1);
	
	/* Delete removed objects: */
	v2->setEdge(0);
	f1->setEdge(0);
	f2->setEdge(0);
	
	deleteEdge(e1);
	deleteEdge(e2);
	deleteEdge(e3);
	deleteEdge(e4);
	deleteEdge(e5);
	deleteEdge(e6);
	deleteVertex(v2);
	deleteFace(f1);
	deleteFace(f2);
	
	/* Update version numbers of all involved vertices: */
	++version;
	v1->version=version;
	Edge* e=v1->getEdge();
	do
		{
		e->getEnd()->version=version;
		e=e->getVertexSucc();
		}
	while(e!=v1->getEdge());
	
	return true;
	}