Ejemplo n.º 1
0
pointXY *getLinePoints(pointXY p1, pointXY p2, int *numElems, pointXY *(*draw)(pointXY, pointXY, int *)) {
    int i = 0;
    pointXY *line;
    
    // Calculate the number of elements and the slope
    float m = slope(p1, p2);
    
    // Check if there are special cases or not
    if ( (m == 0.0) || (m == 1.0) || (m == -1.0) || (m == INFINITY) || (m == -INFINITY) ) {
        pointXY newP2 = p2;
        newP2.x -= p1.x;
        newP2.y -= p1.y;
        
        int incX = 0, incY = 0;
        
        // Define the increments (due to the type of line)
        // If both conditionals meet, the line is diagonal
        if (p1.x != p2.x) incX = 1; // For vertical line
        if (p1.y != p2.y) incY = 1; // For horizontal line
        if (p2.x < p1.x) incX = -incX;
        if (p2.y < p1.y) incY = -incY;
        
        if ( (incX == 0) && (incY == 0) ) *numElems = 0;
        else if ( incX == 0 ) *numElems = abs(p2.y - p1.y);
        else *numElems = abs(p2.x - p1.x);
        (*numElems)++;
        
        line = calloc(*numElems, sizeof *line);
        
        for (i = 0; i < *numElems; i++) {
            line[i].x = p1.x + incX * i;
            line[i].y = p1.y + incY * i;
        }
    } else {
        // 1. Check which octant is the line, and pass it to the first one
        int steps = stepsToFirstOctant(p1, p2);
        int mX = (steps & 4) >> 2;
        int mY = (steps & 2) >> 1;
        int sw = steps & 1;
        
        if (mX == 1) { p1 = mirrorX(p1); p2 = mirrorX(p2); }
        if (mY == 1) { p1 = mirrorY(p1); p2 = mirrorY(p2); }
        if (sw == 1) { p1 = swap(p1); p2 = swap(p2); }
        
        // 2. Compute the line with the desired algorithm
        line = draw(p1, p2, numElems);
        
        // 3. Return the generated line to its corresponding octant
        for (i = 0; i < *numElems; i++) {
            if (sw == 1) line[i] = swap(line[i]);
            if (mY == 1) line[i] = mirrorY(line[i]);
            if (mX == 1) line[i] = mirrorX(line[i]);
        }
    }
    
    // Finally, return the computed line
    return line;
}
Ejemplo n.º 2
0
void WireBoxCornerShrinkGrow::createWireBoxCorner(const quint8 rotate, const quint8 flip)
{
    quint8 xyz = 0;
    for (quint16 j = 0; j < m_iterations; j++)
    {
        for (quint8 i = 0; i < CUBE_SIZE * 2; i++)
        {
            xyz = CUBE_SIZE - 1 - i;
            if (i > CUBE_SIZE - 1)
                xyz = i - CUBE_SIZE;
            fillCubeArray(0x00);
            boxWireframe(0, 0, 0, xyz, xyz, xyz);

            if (flip > 0)
                mirrorZ();
            if (rotate == 1 || rotate == 3)
                mirrorY();
            if (rotate == 2 || rotate == 3)
                mirrorX();
            if(m_abort)
                return;
            waitMs(speed());
        }
    }
}
Ejemplo n.º 3
0
void
TBIndex::setSquare(int pieceNo, int square) {
    if (pieceNo == 0) { // White king
        idx &= ~(0xf << (6*p-5));
        idx |= kingMap[square] << (6*p-5);

        int sym = symType[square];
        if (sym & 1)
            mirrorX();
        if (sym & 2)
            mirrorY();
        if (sym & 4)
            mirrorD();
    } else if (pieceNo == nWhite) { // Black king
        int oldSq = getSquare(pieceNo);
        for (int i = 1; i < p; i++) {
            if (getSquare(i) == oldSq) {
                idx &= ~(0x3f << pieceShift(i));
                idx |= square << pieceShift(i);
            }
        }
    } else {
        idx &= ~(0x3f << pieceShift(pieceNo));
        idx |= square << pieceShift(pieceNo);
    }
}
Ejemplo n.º 4
0
void Bonfire::animate()
{
	frames++;	

	if (frames % DEFAULT_ANIMATION_REFRESH_INTERVAL == 0)
	{
		mirrorX();

		if (frames >= INT_MAX)
		{
			frames = 0;
		}
	}
}
Ejemplo n.º 5
0
AViz::AViz() 
    : QMainWindow()
{
    // Make menus in menubar
    QMenu *file = menuBar()->addMenu("&File");
    QMenu *elements = menuBar()->addMenu( "&Elements");
    QMenu *view = menuBar()->addMenu( "&View");
    QMenu *settings = menuBar()->addMenu( "&Settings");
    QMenu *data = menuBar()->addMenu("&Data");
    menuBar()->addSeparator();
    QMenu *help = menuBar()->addMenu("&Help");

    // Make a cascade menu to read files
    QMenu *openfile = file->addMenu("&Open");
    openfile->addAction("Open XYZ File...", this, SLOT(openXYZ()));
    openfile->addAction("Open File List...", this, SLOT(openList()));
    openfile->addAction("Open ViewParam File...", this, SLOT(openViewParam()));



    file->addAction( "Save ViewParam File...", this, SLOT(saveViewParam()) );
    file->addSeparator();
    file->addAction( "File List...", this, SLOT(launchFileList()) );
    file->addAction( "Animation...", this, SLOT(launchAnimation()) );
    file->addSeparator();
    m_inOutWatchModelAction = file->addAction( "Watch XYZ File", this, SLOT(watchFile()) );
    file->addSeparator();
    file->addAction( "Snap PNG File...", this, SLOT(savePNGFile()) );
    file->addSeparator();
    file->addAction( "Set Default View Param", this, SLOT(setDefaultView()));
    file->addSeparator();
    file->addAction( "E&xit", qApp, SLOT(quit()), Qt::CTRL+Qt::Key_Q );

    // Make a general view menu
    QMenu *viewpoint = view->addMenu("Set &Viewpoint");
    view->addAction( "Clipping...", this, SLOT(launchClip()) );
    view->addAction( "Slicing...", this, SLOT(launchSlice()) );

    // Make a cascade menu to set standard view points
    viewpoint->addAction( "Explicit...", this, SLOT(launchExplicit()) );
    viewpoint->addSeparator();
    viewpoint->addAction( "Default View", this, SLOT(setDefaults()) );
    viewpoint->addSeparator();
    viewpoint->addAction( "View XY +", this, SLOT(viewXYPlus()) );
    viewpoint->addAction( "View XY -", this, SLOT(viewXYMinus()) );
    viewpoint->addSeparator();
    viewpoint->addAction( "View XZ +", this, SLOT(viewXZPlus()) );
    viewpoint->addAction( "View XZ -", this, SLOT(viewXZMinus()) );
    viewpoint->addSeparator();
    viewpoint->addAction( "View YZ +", this, SLOT(viewYZPlus()) );
    viewpoint->addAction( "View YZ -", this, SLOT(viewYZMinus()) );


    // Fill a general elements menu
    m_atomsMenu = elements->addMenu("Atoms...");

    // Make a submenu for atom specifications
    m_atomsMenu->addAction( "Atoms/Molecules...", this, SLOT(launchAtoms()) );
    m_atomsMenu->addAction( "Bonds...", this, SLOT(launchBonds()) );

    m_spinsAction = elements->addAction( "Spins...", this, SLOT(launchSpins()) );
    m_liquidCrystalsAction = elements->addAction( "Liquid Crystals...", this, SLOT(launchLiquidCrystals()) );
    m_polymersMenu = elements->addMenu( "Polymers...");
    m_poresAction = elements->addAction( "Pores ...", this, SLOT(launchPores()) );
    elements->addAction( "Lights...", this, SLOT(launchLights()) );
    elements->addAction( "Annotation...", this, SLOT(launchAnnotation()) );

    // fill submenu for polymer specifications
    m_polymersMenu->addAction( "Polymers...", this, SLOT(launchPolymers()) );
    m_polymersMenu->addAction( "Bonds...", this, SLOT(launchBonds()) );


    // fill a general settings menu
    m_showHideAxesAction = settings->addAction( "Hide Axes", this, SLOT(showHideAxesCB()) );
    m_showHideContourAction = settings->addAction( "Hide Contour", this, SLOT(showHideContourCB()) );
    m_onlyContourAction = settings->addAction( "Only Contour", this, SLOT(onlyContourCB()) );

    // fill a general data menu
    data->addAction( "&Translate...", this, SLOT(launchTranslation()) );
    data->addSeparator();
    data->addAction( "Swap XY", this, SLOT(swapXY()) );
    data->addAction( "Swap XZ", this, SLOT(swapXZ()) );
    data->addAction( "Swap YZ", this, SLOT(swapYZ()) );
    data->addSeparator();
    data->addAction( "Mirror X", this, SLOT(mirrorX()) );
    data->addAction( "Mirror Y", this, SLOT(mirrorY()) );
    data->addAction( "Mirror Z", this, SLOT(mirrorZ()) );
    data->addSeparator();
    data->addAction( "Stretch XYZ...", this, SLOT(launchStretch()) );

    // fill a general help menu
    help->addAction( "&About", this, SLOT(about()), Qt::CTRL+Qt::Key_H );
    help->addAction( "License", this, SLOT(license()) );
    help->addAction( "Distribution", this, SLOT(distribute()) );

    // Now construct the main form
    // (Note having aviz as paramter for MainForm ctor
    // is "This is an ugly hack, intended to propagate the
    // address of the calling class")
    m_mainForm = new MainForm(this/*parent*/, this /*aviz*/);
    setCentralWidget(m_mainForm);

    // Construct a timer
    m_watchTimer = new QTimer(this);

    // Set initial settings
    setAtomMenus();
}
Ejemplo n.º 6
0
void
NBNetBuilder::compute(OptionsCont& oc,
                      const std::set<std::string>& explicitTurnarounds,
                      bool removeElements) {
    GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing();


    const bool lefthand = oc.getBool("lefthand");
    if (lefthand) {
        mirrorX();
    };

    // MODIFYING THE SETS OF NODES AND EDGES

    // Removes edges that are connecting the same node
    long before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Removing self-loops");
    myNodeCont.removeSelfLoops(myDistrictCont, myEdgeCont, myTLLCont);
    PROGRESS_TIME_MESSAGE(before);
    //
    if (oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Finding isolated roads");
        myNodeCont.removeIsolatedRoads(myDistrictCont, myEdgeCont, myTLLCont);
        PROGRESS_TIME_MESSAGE(before);
    }
    //
    if (oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) {
        if (oc.isSet("keep-edges.explicit") || oc.isSet("keep-edges.input-file")) {
            before = SysUtils::getCurrentMillis();
            PROGRESS_BEGIN_MESSAGE("Removing unwished edges");
            myEdgeCont.removeUnwishedEdges(myDistrictCont);
            PROGRESS_TIME_MESSAGE(before);
        }
    }
    if (oc.getBool("junctions.join") || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))) {
        // preliminary geometry computations to determine the length of edges
        // This depends on turning directions and sorting of edge list
        // in case junctions are joined geometry computations have to be repeated
        // preliminary roundabout computations to avoid damaging roundabouts via junctions.join or ramps.guess
        NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false);
        NBNodesEdgesSorter::sortNodesEdges(myNodeCont);
        myEdgeCont.computeLaneShapes();
        myNodeCont.computeNodeShapes();
        myEdgeCont.computeEdgeShapes();
        if (oc.getBool("roundabouts.guess")) {
            myEdgeCont.guessRoundabouts();
        }
        const std::set<EdgeSet>& roundabouts = myEdgeCont.getRoundabouts();
        for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin();
                it_round != roundabouts.end(); ++it_round) {
            std::vector<std::string> nodeIDs;
            for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) {
                nodeIDs.push_back((*it_edge)->getToNode()->getID());
            }
            myNodeCont.addJoinExclusion(nodeIDs);
        }
    }
    // join junctions (may create new "geometry"-nodes so it needs to come before removing these
    if (oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
        myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
    }
    unsigned int numJoined = myNodeCont.joinLoadedClusters(myDistrictCont, myEdgeCont, myTLLCont);
    if (oc.getBool("junctions.join")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Joining junction clusters");
        numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont);
        PROGRESS_TIME_MESSAGE(before);
    }
    if (oc.getBool("junctions.join") || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))) {
        // reset geometry to avoid influencing subsequent steps (ramps.guess)
        myEdgeCont.computeLaneShapes();
    }
    if (numJoined > 0) {
        // bit of a misnomer since we're already done
        WRITE_MESSAGE(" Joined " + toString(numJoined) + " junction cluster(s).");
    }
    //
    if (removeElements) {
        unsigned int no = 0;
        const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
        // removeUnwishedNodes needs turnDirections. @todo: try to call this less often
        NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false);
        no = myNodeCont.removeUnwishedNodes(myDistrictCont, myEdgeCont, myTLLCont, removeGeometryNodes);
        PROGRESS_TIME_MESSAGE(before);
        WRITE_MESSAGE("   " + toString(no) + " nodes removed.");
    }

    // MOVE TO ORIGIN
    // compute new boundary after network modifications have taken place
    Boundary boundary;
    for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) {
        boundary.add(it->second->getPosition());
    }
    for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) {
        boundary.add(it->second->getGeometry().getBoxBoundary());
    }
    geoConvHelper.setConvBoundary(boundary);

    if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
        moveToOrigin(geoConvHelper, lefthand);
    }
    geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point

    if (oc.exists("geometry.min-dist") && oc.isSet("geometry.min-dist")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Reducing geometries");
        myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist"));
        PROGRESS_TIME_MESSAGE(before);
    }
    // @note: removing geometry can create similar edges so joinSimilarEdges  must come afterwards
    // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before
    if (removeElements && oc.getBool("edges.join")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Joining similar edges");
        myNodeCont.joinSimilarEdges(myDistrictCont, myEdgeCont, myTLLCont);
        PROGRESS_TIME_MESSAGE(before);
    }
    if (oc.getBool("opposites.guess")) {
        PROGRESS_BEGIN_MESSAGE("guessing opposite direction edges");
        myEdgeCont.guessOpposites();
        PROGRESS_DONE_MESSAGE();
    }
    //
    if (oc.exists("geometry.split") && oc.getBool("geometry.split")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Splitting geometry edges");
        myEdgeCont.splitGeometry(myNodeCont);
        PROGRESS_TIME_MESSAGE(before);
    }
    // turning direction
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing turning directions");
    NBTurningDirectionsComputer::computeTurnDirections(myNodeCont);
    PROGRESS_TIME_MESSAGE(before);
    // correct edge geometries to avoid overlap
    myNodeCont.avoidOverlap();
    // guess ramps
    if ((oc.exists("ramps.guess") && oc.getBool("ramps.guess")) || (oc.exists("ramps.set") && oc.isSet("ramps.set"))) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Guessing and setting on-/off-ramps");
        NBNodesEdgesSorter::sortNodesEdges(myNodeCont);
        NBRampsComputer::computeRamps(*this, oc);
        PROGRESS_TIME_MESSAGE(before);
    }
    // guess sidewalks
    if (oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")) {
        const int sidewalks = myEdgeCont.guessSidewalks(oc.getFloat("default.sidewalk-width"),
                              oc.getFloat("sidewalks.guess.min-speed"),
                              oc.getFloat("sidewalks.guess.max-speed"),
                              oc.getBool("sidewalks.guess.from-permissions"));
        WRITE_MESSAGE("Guessed " + toString(sidewalks) + " sidewalks.");
    }

    // check whether any not previously setable connections may be set now
    myEdgeCont.recheckPostProcessConnections();

    // remap ids if wished
    if (oc.getBool("numerical-ids")) {
        int numChangedEdges = myEdgeCont.mapToNumericalIDs();
        int numChangedNodes = myNodeCont.mapToNumericalIDs();
        if (numChangedEdges + numChangedNodes > 0) {
            WRITE_MESSAGE("Remapped " + toString(numChangedEdges) + " edge IDs and " + toString(numChangedNodes) + " node IDs.");
        }
    }

    //
    if (oc.exists("geometry.max-angle")) {
        myEdgeCont.checkGeometries(
            DEG2RAD(oc.getFloat("geometry.max-angle")),
            oc.getFloat("geometry.min-radius"),
            oc.getBool("geometry.min-radius.fix"));
    }

    // GEOMETRY COMPUTATION
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Sorting nodes' edges");
    NBNodesEdgesSorter::sortNodesEdges(myNodeCont);
    PROGRESS_TIME_MESSAGE(before);
    myEdgeCont.computeLaneShapes();
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing node shapes");
    if (oc.exists("geometry.junction-mismatch-threshold")) {
        myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
    } else {
        myNodeCont.computeNodeShapes();
    }
    PROGRESS_TIME_MESSAGE(before);
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing edge shapes");
    myEdgeCont.computeEdgeShapes();
    PROGRESS_TIME_MESSAGE(before);
    // resort edges based on the node and edge shapes
    NBNodesEdgesSorter::sortNodesEdges(myNodeCont, true);
    NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false);

    // APPLY SPEED MODIFICATIONS
    if (oc.exists("speed.offset")) {
        const SUMOReal speedOffset = oc.getFloat("speed.offset");
        const SUMOReal speedFactor = oc.getFloat("speed.factor");
        if (speedOffset != 0 || speedFactor != 1 || oc.isSet("speed.minimum")) {
            const SUMOReal speedMin = oc.isSet("speed.minimum") ? oc.getFloat("speed.minimum") : -std::numeric_limits<SUMOReal>::infinity();
            before = SysUtils::getCurrentMillis();
            PROGRESS_BEGIN_MESSAGE("Applying speed modifications");
            for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
                (*i).second->setSpeed(-1, MAX2((*i).second->getSpeed() * speedFactor + speedOffset, speedMin));
            }
            PROGRESS_TIME_MESSAGE(before);
        }
    }

    // CONNECTIONS COMPUTATION
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing node types");
    NBNodeTypeComputer::computeNodeTypes(myNodeCont);
    PROGRESS_TIME_MESSAGE(before);
    //
    bool haveCrossings = false;
    if (oc.getBool("crossings.guess")) {
        haveCrossings = true;
        int crossings = 0;
        for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
            crossings += (*i).second->guessCrossings();
        }
        WRITE_MESSAGE("Guessed " + toString(crossings) + " pedestrian crossings.");
    }
    if (!haveCrossings) {
        // recheck whether we had crossings in the input
        for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
            if (i->second->getCrossings().size() > 0) {
                haveCrossings = true;
                break;
            }
        }
    }

    if (oc.isDefault("no-internal-links") && !haveCrossings && myHaveLoadedNetworkWithoutInternalEdges) {
        oc.set("no-internal-links", "true");
    }

    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing priorities");
    NBEdgePriorityComputer::computeEdgePriorities(myNodeCont);
    PROGRESS_TIME_MESSAGE(before);
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing approached edges");
    myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
    PROGRESS_TIME_MESSAGE(before);
    //
    if (oc.getBool("roundabouts.guess")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Guessing and setting roundabouts");
        const int numGuessed = myEdgeCont.guessRoundabouts();
        if (numGuessed > 0) {
            WRITE_MESSAGE(" Guessed " + toString(numGuessed) + " roundabout(s).");
        }
        PROGRESS_TIME_MESSAGE(before);
    }
    myEdgeCont.markRoundabouts();
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing approaching lanes");
    myEdgeCont.computeLanes2Edges();
    PROGRESS_TIME_MESSAGE(before);
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Dividing of lanes on approached lanes");
    myNodeCont.computeLanes2Lanes();
    myEdgeCont.sortOutgoingLanesConnections();
    PROGRESS_TIME_MESSAGE(before);
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Processing turnarounds");
    if (!oc.getBool("no-turnarounds")) {
        myEdgeCont.appendTurnarounds(oc.getBool("no-turnarounds.tls"));
    } else {
        myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
    }
    PROGRESS_TIME_MESSAGE(before);
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Rechecking of lane endings");
    myEdgeCont.recheckLanes();
    PROGRESS_TIME_MESSAGE(before);

    if (haveCrossings && !oc.getBool("no-internal-links")) {
        for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
            i->second->buildCrossingsAndWalkingAreas();
        }
    }

    // GUESS TLS POSITIONS
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Assigning nodes to traffic lights");
    if (oc.isSet("tls.set")) {
        std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
        TrafficLightType type = SUMOXMLDefinitions::TrafficLightTypes.get(oc.getString("tls.default-type"));
        for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
            NBNode* node = myNodeCont.retrieve(*i);
            if (node == 0) {
                WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known.");
            } else {
                myNodeCont.setAsTLControlled(node, myTLLCont, type);
            }
        }
    }
    myNodeCont.guessTLs(oc, myTLLCont);
    PROGRESS_TIME_MESSAGE(before);
    //
    if (oc.getBool("tls.join")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Joining traffic light nodes");
        myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
        PROGRESS_TIME_MESSAGE(before);
    }


    // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing traffic light control information");
    myTLLCont.setTLControllingInformation(myEdgeCont, myNodeCont);
    PROGRESS_TIME_MESSAGE(before);
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing node logics");
    myNodeCont.computeLogics(myEdgeCont, oc);
    PROGRESS_TIME_MESSAGE(before);
    //
    before = SysUtils::getCurrentMillis();
    PROGRESS_BEGIN_MESSAGE("Computing traffic light logics");
    std::pair<unsigned int, unsigned int> numbers = myTLLCont.computeLogics(oc);
    PROGRESS_TIME_MESSAGE(before);
    std::string progCount = "";
    if (numbers.first != numbers.second) {
        progCount = "(" + toString(numbers.second) + " programs) ";
    }
    WRITE_MESSAGE(" " + toString(numbers.first) + " traffic light(s) " + progCount + "computed.");
    //
    if (oc.isSet("street-sign-output")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Generating street signs");
        myEdgeCont.generateStreetSigns();
        PROGRESS_TIME_MESSAGE(before);
    }

    // FINISHING INNER EDGES
    if (!oc.getBool("no-internal-links")) {
        before = SysUtils::getCurrentMillis();
        PROGRESS_BEGIN_MESSAGE("Building inner edges");
        for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
            (*i).second->sortOutgoingConnectionsByIndex();
        }
        // walking areas shall only be built if crossings are wished as well
        for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
            (*i).second->buildInnerEdges();
        }
        PROGRESS_TIME_MESSAGE(before);
    }
    if (lefthand) {
        mirrorX();
    };

    // report
    WRITE_MESSAGE("-----------------------------------------------------");
    WRITE_MESSAGE("Summary:");
    myNodeCont.printBuiltNodesStatistics();
    WRITE_MESSAGE(" Network boundaries:");
    WRITE_MESSAGE("  Original boundary  : " + toString(geoConvHelper.getOrigBoundary()));
    WRITE_MESSAGE("  Applied offset     : " + toString(geoConvHelper.getOffsetBase()));
    WRITE_MESSAGE("  Converted boundary : " + toString(geoConvHelper.getConvBoundary()));
    WRITE_MESSAGE("-----------------------------------------------------");
    NBRequest::reportWarnings();
    // report on very large networks
    if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 ||
            MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) {
        WRITE_WARNING("Network contains very large coordinates and will probably flicker in the GUI. Check for outlying nodes and make sure the network is shifted to the coordinate origin");
    }
}