Пример #1
0
//Reimplement draw function so that we have control over the order of
//elements, and we can add object labels
//
//The order in which components are drawn naturally determines the
//z-ordering (the layering) of the components.  Objects which
//should appear "behind" others should be drawn first.
void SkyMapComposite::draw( SkyPainter *skyp )
{
    SkyMap *map = SkyMap::Instance();
    KStarsData *data = KStarsData::Instance();

    // We delay one draw cycle before re-indexing
    // we MUST ensure CLines do not get re-indexed while we use DRAW_BUF
    // so we do it here.
    m_CLines->reindex( &m_reindexNum );
    // This queues re-indexing for the next draw cycle
    m_reindexNum = KSNumbers( data->updateNum()->julianDay() );

    // This ensures that the JIT updates are synchronized for the entire draw
    // cycle so the sky moves as a single sheet.  May not be needed.
    data->syncUpdateIDs();

    // prepare the aperture
    // FIXME_FOV: We may want to rejigger this to allow
    // wide-angle views --hdevalence
    float radius = map->projector()->fov();
    if ( radius > 180.0 )
        radius = 180.0;


    if ( m_skyMesh->inDraw() ) {
        printf("Warning: aborting concurrent SkyMapComposite::draw()\n");
        return;
    }

    m_skyMesh->inDraw( true );
    SkyPoint* focus = map->focus();
    m_skyMesh->aperture( focus, radius + 1.0, DRAW_BUF ); // divide by 2 for testing

    // create the no-precess aperture if needed
    if ( Options::showEquatorialGrid() || Options::showHorizontalGrid() || Options::showCBounds() || Options::showEquator() ) {
        m_skyMesh->index( focus, radius + 1.0, NO_PRECESS_BUF );
    }

    // clear marks from old labels and prep fonts
    m_skyLabeler->reset( map );
    m_skyLabeler->useStdFont();

    // info boxes have highest label priority
    // FIXME: REGRESSION. Labeler now know nothing about infoboxes
    // map->infoBoxes()->reserveBoxes( psky );

    if( KStars::Instance() ) {
        const QList<SkyObject*> obsList = KStarsData::Instance()->observingList()->sessionList();
        if( Options::obsListText() )
            foreach( SkyObject* obj, obsList ) {
                SkyLabeler::AddLabel( obj, SkyLabeler::RUDE_LABEL );
            }
    }
Пример #2
0
int main(int argc, char *argv[])
{
    KAboutData aboutData( "kstars", 0, ki18n("KStars"),
                          KSTARS_VERSION, ki18n(description), KAboutData::License_GPL,
                          ki18n("(c) 2001-2012, The KStars Team"), ki18n(notice), "http://edu.kde.org/kstars");
    aboutData.addAuthor(ki18n("Jason Harris"),KLocalizedString(), "*****@*****.**", "http://www.30doradus.org");
    aboutData.addAuthor(ki18n("Jasem Mutlaq"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("James Bowlin"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Pablo de Vicente"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Thomas Kabelmann"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Heiko Evermann"),KLocalizedString(), "*****@*****.**", "http://www.evermann.de");
    aboutData.addAuthor(ki18n("Carsten Niehaus"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Mark Hollomon"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Alexey Khudyakov"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("M&eacute;d&eacute;ric Boquien"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Akarsh Simha"), KLocalizedString(), "*****@*****.**", "http://www.ph.utexas.edu/~asimha");
    aboutData.addAuthor(ki18n("J&eacute;r&ocirc;me Sonrier"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Prakash Mohan"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Victor Cărbune"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Henry de Valence"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Samikshan Bairagya"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Rafał Kułaga"), KLocalizedString(), "*****@*****.**");
    aboutData.addAuthor(ki18n("Rishab Arora"), KLocalizedString(), "*****@*****.**");

    aboutData.addCredit(ki18n("Valery Kharitonov"), ki18n("Converted labels containing technical terms to links to documentation") );
    aboutData.addCredit(ki18n("Ana-Maria Constantin"), ki18n("Technical documentation on Astronomy and KStars") );
    aboutData.addCredit(ki18n("Andrew Stepanenko"), ki18n("Guiding code based on lin_guider") );
    aboutData.addCredit(ki18n("Nuno Pinheiro"), ki18n("Artwork") );

    KCmdLineArgs::init( argc, argv, &aboutData );

    KCmdLineOptions options;
    options.add("!dump", ki18n( "Dump sky image to file" ));
    options.add("script ", ki18n( "Script to execute" ));
    options.add("width ", ki18n( "Width of sky image" ), "640");
    options.add("height ", ki18n( "Height of sky image" ), "480");
    options.add("filename ", ki18n( "Filename for sky image" ), "kstars.png");
    options.add("date ", ki18n( "Date and time" ));
    options.add("!paused", ki18n( "Start with clock paused" ));
    KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

    KApplication a;

    if ( args->isSet( "dump" ) ) {
        kDebug() << i18n( "Dumping sky image" );

        //parse filename and image format
        const char* format = "PNG";
        QString fname = args->getOption( "filename" );
        QString ext = fname.mid( fname.lastIndexOf(".")+1 );
        if ( ext.toLower() == "png" ) { format = "PNG"; }
        else if ( ext.toLower() == "jpg" || ext.toLower() == "jpeg" ) { format = "JPG"; }
        else if ( ext.toLower() == "gif" ) { format = "GIF"; }
        else if ( ext.toLower() == "pnm" ) { format = "PNM"; }
        else if ( ext.toLower() == "bmp" ) { format = "BMP"; }
        else { kWarning() << i18n( "Could not parse image format of %1; assuming PNG.", fname ) ; }

        //parse width and height
        bool ok(false);
        int w(0), h(0);
        w = args->getOption( "width" ).toInt( &ok );
        if ( ok ) h =  args->getOption( "height" ).toInt( &ok );
        if ( !ok ) {
            kWarning() << "Unable to parse arguments: " ;
            kWarning() << "Width: " << args->getOption( "width" )
            << "  Height: " << args->getOption( "height" ) << endl;
            return 1;
        }

        KStarsData *dat = KStarsData::Create();
        QObject::connect( dat, SIGNAL( progressText(QString) ), dat, SLOT( slotConsoleMessage(QString) ) );
        dat->initialize();

        //Set Geographic Location
        dat->setLocationFromOptions();

        //Set color scheme
        dat->colorScheme()->loadFromConfig();

        //set clock now that we have a location:
        //Check to see if user provided a date/time string.  If not, use current CPU time
        QString datestring = args->getOption( "date" );
        KStarsDateTime kdt;
        if ( ! datestring.isEmpty() ) {
            if ( datestring.contains( "-" ) ) { //assume ISODate format
                if ( datestring.contains( ":" ) ) { //also includes time
                    kdt = KDateTime::fromString( datestring, KDateTime::ISODate );
                } else { //string probably contains date only
                    kdt.setDate( QDate::fromString( datestring, Qt::ISODate ) );
                    kdt.setTime( QTime( 0, 0, 0 ) );
                }
            } else { //assume Text format for date string
                kdt = dat->geo()->LTtoUT( KDateTime::fromString( datestring, KDateTime::QtTextDate ) );
            }

            if ( ! kdt.isValid() ) {
                kWarning() << i18n( "Using CPU date/time instead." ) ;

                kdt = KStarsDateTime::currentUtcDateTime();
            }
        } else {
            kdt = KStarsDateTime::currentUtcDateTime();
        }
        dat->clock()->setUTC( kdt );

        KSNumbers num( dat->ut().djd() );
        //		dat->initGuides(&num);

        SkyMap *map = SkyMap::Create();
        map->resize( w, h );
        QPixmap sky( w, h );

        dat->setFullTimeUpdate();
        dat->updateTime(dat->geo(), map );

        SkyPoint dest( Options::focusRA(), Options::focusDec() );
        map->setDestination( dest );
        map->destination()->EquatorialToHorizontal( dat->lst(), dat->geo()->lat() );
        map->setFocus( map->destination() );
        map->focus()->EquatorialToHorizontal( dat->lst(), dat->geo()->lat() );

        //Execute the specified script
        QString scriptfile = args->getOption( "script" );
        if ( ! scriptfile.isEmpty() ) {
            if ( dat->executeScript( scriptfile, map ) ) {
                std::cout << i18n( "Script executed." ).toUtf8().data() << std::endl;
            } else {
                kWarning() << i18n( "Could not execute script." ) ;
            }
        }

        qApp->processEvents();
        map->setupProjector();
        map->exportSkyImage( &sky );
        qApp->processEvents();

        if ( ! sky.save( fname, format ) ) kWarning() << i18n( "Unable to save image: %1 ", fname ) ;
        else kDebug() << i18n( "Saved to file: %1", fname );

        delete map;
        delete dat;
        return 0;
    }

    //start up normally in GUI mode

    //Try to parse the given date string
    QString datestring = args->getOption( "date" );
    //DEBUG
    kDebug() << "Date string: " << datestring;

    if ( ! datestring.isEmpty() && ! KStarsDateTime::fromString( datestring ).isValid() ) {
        kWarning() << i18n( "Using CPU date/time instead." ) ;
        datestring.clear();
    }

    KStars::createInstance( true, ! args->isSet( "paused" ), datestring );
    args->clear();
    QObject::connect(kapp, SIGNAL(lastWindowClosed()), kapp, SLOT(quit()));
    return a.exec();

}
Пример #3
0
int main(int argc, char *argv[])
{
#ifdef KSTARS_LITE
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QApplication app(argc, argv);

#ifdef Q_OS_OSX
    //Note, this function will return true on OS X if the data directories are good to go.  If not, quit with error code 1!
    if(!KSUtils::copyDataFolderFromAppBundleIfNeeded()){
        KMessageBox::sorry(0, i18n("Sorry, without a KStars Data Directory, KStars cannot operate. Exiting program now."));
        return 1;
    }
#endif
    app.setApplicationVersion(KSTARS_VERSION);
    /**
    * enable high dpi support
    */
     app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);

    KLocalizedString::setApplicationDomain("kstars");    
#ifndef KSTARS_LITE
    KCrash::initialize();

    KAboutData aboutData( "kstars", i18n("KStars"), KSTARS_VERSION, i18n(description), KAboutLicense::GPL,
                          "2001-" + QString::number(QDate::currentDate().year()) + i18n("(c), The KStars Team"), i18n(notice), "http://edu.kde.org/kstars");
    aboutData.addAuthor(i18n("Jason Harris"), i18n("Original Author"), "*****@*****.**", "http://www.30doradus.org");
    aboutData.addAuthor(i18n("Jasem Mutlaq"), i18n("Current Maintainer"), "*****@*****.**", "http://www.indilib.org");

    // Active developers
    aboutData.addAuthor(i18n("Akarsh Simha"), QString(), "*****@*****.**", "http://www.ph.utexas.edu/~asimha");
    aboutData.addAuthor(i18n("Artem Fedoskin"), i18n("KStars Lite"), "*****@*****.**");
    aboutData.addAuthor(i18n("Robert Lancaster"), i18n("FITSViewer Improvements. KStars OSX Port"), "*****@*****.**");

    // Inactive developers
    aboutData.addAuthor(i18n("James Bowlin"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Pablo de Vicente"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Thomas Kabelmann"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Heiko Evermann"),QString(), "*****@*****.**", "http://www.evermann.de");
    aboutData.addAuthor(i18n("Carsten Niehaus"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Mark Hollomon"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Alexey Khudyakov"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("M&eacute;d&eacute;ric Boquien"), QString(), "*****@*****.**");    
    aboutData.addAuthor(i18n("J&eacute;r&ocirc;me Sonrier"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Prakash Mohan"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Victor Cărbune"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Henry de Valence"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Samikshan Bairagya"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Rafał Kułaga"), QString(), "*****@*****.**");
    aboutData.addAuthor(i18n("Rishab Arora"), QString(), "*****@*****.**");

    // Contributors
    aboutData.addCredit(i18n("Valery Kharitonov"), i18n("Converted labels containing technical terms to links to documentation") );
    aboutData.addCredit(i18n("Ana-Maria Constantin"), i18n("Technical documentation on Astronomy and KStars") );
    aboutData.addCredit(i18n("Andrew Stepanenko"), i18n("Guiding code based on lin_guider") );
    aboutData.addCredit(i18n("Nuno Pinheiro"), i18n("Artwork") );
    aboutData.addCredit(i18n("Utkarsh Simha"), i18n("Improvements to observation plan execution, star hopper etc.") );
    aboutData.addCredit(i18n("Daniel Holler"), i18n("Extensive testing and suggestions for Ekos/INDI.") );
    aboutData.addCredit(i18n("Stephane Lucas"), i18n("Extensive testing and suggestions for Ekos Scheduler.") );
    aboutData.addCredit(i18n("Yuri Fabirovsky"), i18n("Splash screen for both regular KStars and KStars Lite.") );

    KAboutData::setApplicationData(aboutData);

    QCommandLineParser parser;
    aboutData.setupCommandLine(&parser);
    parser.setApplicationDescription(aboutData.shortDescription());
    parser.addVersionOption();
    parser.addHelpOption();

    //parser.addHelpOption(INSERT_DESCRIPTION_HERE);
    parser.addOption(QCommandLineOption(QStringList() << "dump", i18n( "Dump sky image to file" )));
    parser.addOption(QCommandLineOption(QStringList() << "script ", i18n( "Script to execute" )));
    parser.addOption(QCommandLineOption(QStringList() << "width ", i18n( "Width of sky image" ),  "640"));
    parser.addOption(QCommandLineOption(QStringList() << "height ", i18n( "Height of sky image" ), "480"));
    parser.addOption(QCommandLineOption(QStringList() << "filename ", i18n( "Filename for sky image" ), "kstars.png"));
    parser.addOption(QCommandLineOption(QStringList() << "date", i18n( "Date and time" )));
    parser.addOption(QCommandLineOption(QStringList() << "paused", i18n( "Start with clock paused" )));

    // urls to open
    parser.addPositionalArgument(QStringLiteral("urls"), i18n("FITS file(s) to open."), QStringLiteral("[urls...]"));

    parser.process(app);
    aboutData.processCommandLine(&parser);

    if ( parser.isSet( "dump" ) )
    {
        qDebug() << "Dumping sky image";

        //parse filename and image format
        const char* format = "PNG";
        QString fname = parser.value( "filename" );
        QString ext = fname.mid( fname.lastIndexOf(".")+1 );
        if ( ext.toLower() == "png" ) { format = "PNG"; }
        else if ( ext.toLower() == "jpg" || ext.toLower() == "jpeg" ) { format = "JPG"; }
        else if ( ext.toLower() == "gif" ) { format = "GIF"; }
        else if ( ext.toLower() == "pnm" ) { format = "PNM"; }
        else if ( ext.toLower() == "bmp" ) { format = "BMP"; }
        else { qWarning() << i18n( "Could not parse image format of %1; assuming PNG.", fname ) ; }

        //parse width and height
        bool ok(false);
        int w(0), h(0);
        w = parser.value( "width" ).toInt( &ok );
        if ( ok ) h =  parser.value( "height" ).toInt( &ok );
        if ( !ok ) {
            qWarning() << "Unable to parse arguments: " ;
            qWarning() << "Width: " << parser.value( "width" )
                       << "  Height: " << parser.value( "height" ) << endl;
            return 1;
        }
        KStarsData *dat = KStarsData::Create();
        QObject::connect( dat, SIGNAL( progressText(QString) ), dat, SLOT( slotConsoleMessage(QString) ) );
        dat->initialize();

        //Set Geographic Location
        dat->setLocationFromOptions();

        //Set color scheme
        dat->colorScheme()->loadFromConfig();

        //set clock now that we have a location:
        //Check to see if user provided a date/time string.  If not, use current CPU time
        QString datestring = parser.value( "date" );
        KStarsDateTime kdt;
        if ( ! datestring.isEmpty() ) {
            if ( datestring.contains( "-" ) ) { //assume ISODate format
                if ( datestring.contains( ":" ) ) { //also includes time
                    //kdt = QDateTime::fromString( datestring, QDateTime::ISODate );
                    kdt = QDateTime::fromString( datestring, Qt::ISODate );
                } else { //string probably contains date only
                    //kdt.setDate( QDate::fromString( datestring, Qt::ISODate ) );
                    kdt.setDate( QDate::fromString( datestring, Qt::ISODate ) );
                    kdt.setTime( QTime( 0, 0, 0 ) );
                }
            } else { //assume Text format for date string
                kdt = dat->geo()->LTtoUT( QDateTime::fromString( datestring, Qt::TextDate ) );
            }

            if ( ! kdt.isValid() ) {
                qWarning() << i18n( "Using CPU date/time instead." ) ;

                kdt = KStarsDateTime::currentDateTimeUtc();
            }
        } else {
            kdt = KStarsDateTime::currentDateTimeUtc();
        }
        dat->clock()->setUTC( kdt );

        SkyMap *map = SkyMap::Create();
        map->resize( w, h );
        QPixmap sky( w, h );

        dat->setFullTimeUpdate();
        dat->updateTime(dat->geo(), map );

        SkyPoint dest( Options::focusRA(), Options::focusDec() );
        map->setDestination( dest );
        map->destination()->EquatorialToHorizontal( dat->lst(), dat->geo()->lat() );
        map->setFocus( map->destination() );
        map->focus()->EquatorialToHorizontal( dat->lst(), dat->geo()->lat() );

        //Execute the specified script
        QString scriptfile = parser.value( "script" );
        if ( ! scriptfile.isEmpty() ) {
            if ( dat->executeScript( scriptfile, map ) ) {
                std::cout << i18n( "Script executed." ).toUtf8().data() << std::endl;
            } else {
                qWarning() << i18n( "Could not execute script." ) ;
            }
        }

        qApp->processEvents();
        map->setupProjector();
        map->exportSkyImage( &sky );
        qApp->processEvents();

        if ( ! sky.save( fname, format ) )
            qWarning() << "Unable to save image: " << fname;
        else
            qDebug() << "Saved to file: %1" << fname;

        delete map;
        delete dat;
        return 0;
    }

    //Try to parse the given date string
    QString datestring = parser.value( "date" );

    if ( ! datestring.isEmpty() && ! KStarsDateTime::fromString( datestring ).isValid() )
    {
        qWarning() << i18n( "Using CPU date/time instead." ) ;
        datestring.clear();
    }

#endif
    // Create writable data dir if it does not exist
    QDir writableDir;
    writableDir.mkdir(KSPaths::writableLocation(QStandardPaths::GenericDataLocation));
#ifndef KSTARS_LITE

    KStars::createInstance( true, ! parser.isSet( "paused" ), datestring );

    // no session.. just start up normally
    const QStringList urls = parser.positionalArguments();

    // take arguments
    if( ! urls.isEmpty() )
    {
        foreach (const QString &url, urls) {
            const QUrl u = QUrl::fromUserInput(url, QDir::currentPath());
            KStars::Instance()->openFITS(u);
        }
    }
Пример #4
0
// TODO: Optimize draw, if it is worth it.
void DeepStarComponent::draw( SkyPainter *skyp ) {
#ifndef KSTARS_LITE
    if ( !fileOpened ) return;

#ifdef PROFILE_SINCOS
    long trig_calls_here = - dms::trig_function_calls;
    long trig_redundancy_here = - dms::redundant_trig_function_calls;
    long cachingdms_bad_uses = -CachingDms::cachingdms_bad_uses;
    dms::seconds_in_trig = 0.;
#endif

#ifdef PROFILE_UPDATECOORDS
    StarObject::updateCoordsCpuTime = 0.;
    StarObject::starsUpdated = 0;
#endif
    SkyMap *map = SkyMap::Instance();
    KStarsData* data = KStarsData::Instance();
    UpdateID updateID = data->updateID();

    //FIXME_FOV -- maybe not clamp like that...
    float radius = map->projector()->fov();
    if ( radius > 90.0 ) radius = 90.0;

    if ( m_skyMesh != SkyMesh::Instance() && m_skyMesh->inDraw() ) {
        printf("Warning: aborting concurrent DeepStarComponent::draw()");
    }
    bool checkSlewing = ( map->isSlewing() && Options::hideOnSlew() );

    //shortcuts to inform whether to draw different objects
    bool hideFaintStars( checkSlewing && Options::hideStars() );
    double hideStarsMag = Options::magLimitHideStar();

    //adjust maglimit for ZoomLevel
//    double lgmin = log10(MINZOOM);
//    double lgmax = log10(MAXZOOM);
//    double lgz = log10(Options::zoomFactor());
    // TODO: Enable hiding of faint stars

    float maglim = StarComponent::zoomMagnitudeLimit();

    if( maglim < triggerMag )
        return;

    m_zoomMagLimit = maglim;

    m_skyMesh->inDraw( true );

    SkyPoint* focus = map->focus();
    m_skyMesh->aperture( focus, radius + 1.0, DRAW_BUF ); // divide by 2 for testing

    MeshIterator region(m_skyMesh, DRAW_BUF);

    magLim = maglim;

    // If we are to hide the fainter stars (eg: while slewing), we set the magnitude limit to hideStarsMag.
    if( hideFaintStars && maglim > hideStarsMag )
        maglim = hideStarsMag;

    StarBlockFactory *m_StarBlockFactory = StarBlockFactory::Instance();
    //    m_StarBlockFactory->drawID = m_skyMesh->drawID();
    //    qDebug() << "Mesh size = " << m_skyMesh->size() << "; drawID = " << m_skyMesh->drawID();
    QTime t;
    int nTrixels = 0;

    t_dynamicLoad = 0;
    t_updateCache = 0;
    t_drawUnnamed = 0;

    visibleStarCount = 0;

    t.start();

    // Mark used blocks in the LRU Cache. Not required for static stars
    if( !staticStars ) {
        while( region.hasNext() ) {
            Trixel currentRegion = region.next();
            for( int i = 0; i < m_starBlockList.at( currentRegion )->getBlockCount(); ++i ) {
                StarBlock *prevBlock = ( ( i >= 1 ) ? m_starBlockList.at( currentRegion )->block( i - 1 ) : NULL );
                StarBlock *block = m_starBlockList.at( currentRegion )->block( i );

                if( i == 0  &&  !m_StarBlockFactory->markFirst( block ) )
                    qDebug() << "markFirst failed in trixel" << currentRegion;
                if( i > 0   &&  !m_StarBlockFactory->markNext( prevBlock, block ) )
                    qDebug() << "markNext failed in trixel" << currentRegion << "while marking block" << i;
                if( i < m_starBlockList.at( currentRegion )->getBlockCount()
                    && m_starBlockList.at( currentRegion )->block( i )->getFaintMag() < maglim )
                    break;

            }
        }
        t_updateCache = t.restart();
        region.reset();
    }

    while ( region.hasNext() ) {
        ++nTrixels;
        Trixel currentRegion = region.next();

        // NOTE: We are guessing that the last 1.5/16 magnitudes in the catalog are just additions and the star catalog
        //       is actually supposed to reach out continuously enough only to mag m_FaintMagnitude * ( 1 - 1.5/16 )
        // TODO: Is there a better way? We may have to change the magnitude tolerance if the catalog changes
        // Static stars need not execute fillToMag

	if( !staticStars && !m_starBlockList.at( currentRegion )->fillToMag( maglim ) && maglim <= m_FaintMagnitude * ( 1 - 1.5/16 ) ) {
            qDebug() << "SBL::fillToMag( " << maglim << " ) failed for trixel "
                     << currentRegion << " !"<< endl;
	}

        t_dynamicLoad += t.restart();

        //        qDebug() << "Drawing SBL for trixel " << currentRegion << ", SBL has "
        //                 <<  m_starBlockList[ currentRegion ]->getBlockCount() << " blocks" << endl;

        // REMARK: The following should never carry state, except for const parameters like updateID and maglim
        std::function<void( StarBlock * )> mapFunction = [&updateID, &maglim]( StarBlock *myBlock ) {
            for ( StarObject &star : myBlock->contents() ) {
                if ( star.updateID != updateID )
                    star.JITupdate();
                if ( star.mag() > maglim )
                    break;
            }
        };

        QtConcurrent::blockingMap( m_starBlockList.at( currentRegion )->contents(), mapFunction );

        for( int i = 0; i < m_starBlockList.at( currentRegion )->getBlockCount(); ++i ) {

            StarBlock *block = m_starBlockList.at( currentRegion )->block( i );
            //            qDebug() << "---> Drawing stars from block " << i << " of trixel " <<
            //                currentRegion << ". SB has " << block->getStarCount() << " stars" << endl;
            for( int j = 0; j < block->getStarCount(); j++ ) {

                StarObject *curStar = block->star( j );

                //                qDebug() << "We claim that he's from trixel " << currentRegion
                //<< ", and indexStar says he's from " << m_skyMesh->indexStar( curStar );

                float mag = curStar->mag();

                if ( mag > maglim )
                    break;

                if( skyp->drawPointSource(curStar, mag, curStar->spchar() ) )
                    visibleStarCount++;
            }
        }

        // DEBUG: Uncomment to identify problems with Star Block Factory / preservation of Magnitude Order in the LRU Cache
        //        verifySBLIntegrity();
        t_drawUnnamed += t.restart();

    }
    m_skyMesh->inDraw( false );
#ifdef PROFILE_SINCOS
    trig_calls_here += dms::trig_function_calls;
    trig_redundancy_here += dms::redundant_trig_function_calls;
    cachingdms_bad_uses += CachingDms::cachingdms_bad_uses;
    qDebug() << "Spent " << dms::seconds_in_trig << " seconds doing " << trig_calls_here << " trigonometric function calls amounting to an average of " << 1000.0 * dms::seconds_in_trig/double( trig_calls_here ) << " ms per call";
    qDebug() << "Redundancy of trig calls in this draw: " << double( trig_redundancy_here ) / double( trig_calls_here ) * 100. << "%";
    qDebug() << "CachedDms constructor calls so far: " << CachingDms::cachingdms_constructor_calls;
    qDebug() << "Caching has prevented " << CachingDms::cachingdms_delta << " redundant trig function calls";
    qDebug() << "Bad cache uses in this draw: " << cachingdms_bad_uses;
#endif
#ifdef PROFILE_UPDATECOORDS
    qDebug() << "Spent " << StarObject::updateCoordsCpuTime << " seconds updating " << StarObject::starsUpdated << " stars' coordinates (StarObject::updateCoords) for an average of " << double( StarObject::updateCoordsCpuTime )/double( StarObject::starsUpdated ) * 1.e6 << " us per star.";
#endif

#else
    Q_UNUSED(skyp)
#endif
}