File indexing completed on 2024-03-24 15:17:26

0001 /*
0002     SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "deepstaritem.h"
0007 
0008 #include "deepstarcomponent.h"
0009 #include "labelsitem.h"
0010 #include "Options.h"
0011 #include "rootnode.h"
0012 #include "skymesh.h"
0013 #include "starblock.h"
0014 #include "starblockfactory.h"
0015 #include "starblocklist.h"
0016 #include "starcomponent.h"
0017 #include "htmesh/MeshIterator.h"
0018 #include "projections/projector.h"
0019 #include "skynodes/pointsourcenode.h"
0020 #include "skynodes/trixelnode.h"
0021 
0022 DeepStarItem::DeepStarItem(DeepStarComponent *deepStarComp, RootNode *rootNode)
0023     : SkyItem(LabelsItem::label_t::NO_LABEL, rootNode), m_deepStarComp(deepStarComp),
0024       m_staticStars(deepStarComp->staticStars)
0025 {
0026     m_starBlockList = &m_deepStarComp->m_starBlockList;
0027 
0028     if (m_staticStars)
0029     {
0030         for (int c = 0; c < m_starBlockList->size(); ++c)
0031         {
0032             TrixelNode *trixel = new TrixelNode(m_starBlockList->at(c)->getTrixel());
0033             appendChildNode(trixel);
0034             int blockCount = m_starBlockList->at(c)->getBlockCount();
0035 
0036             for (int i = 0; i < blockCount; ++i)
0037             {
0038                 std::shared_ptr<StarBlock> block = m_starBlockList->at(c)->block(i);
0039                 //            qDebug() << "---> Drawing stars from block " << i << " of trixel " <<
0040                 //                currentRegion << ". SB has " << block->getStarCount() << " stars" << endl;
0041                 int starCount = block->getStarCount();
0042                 for (int j = 0; j < starCount; j++)
0043                 {
0044                     StarObject *star = &(block->star(j)->star);
0045 
0046                     if (star)
0047                     {
0048                         trixel->m_nodes.append(QPair<SkyObject *, SkyNode *>(star, 0));
0049                     }
0050                 }
0051             }
0052         }
0053     }
0054 
0055     m_skyMesh          = SkyMesh::Instance();
0056     m_StarBlockFactory = StarBlockFactory::Instance();
0057 }
0058 
0059 void DeepStarItem::update()
0060 {
0061     if (m_staticStars) // dynamic stars under construction
0062     {
0063         SkyMapLite *map   = SkyMapLite::Instance();
0064         KStarsData *data  = KStarsData::Instance();
0065         UpdateID updateID = data->updateID();
0066 
0067         //FIXME_FOV -- maybe not clamp like that...
0068         float radius = map->projector()->fov();
0069         if (radius > 90.0)
0070             radius = 90.0;
0071 
0072         if (m_skyMesh != SkyMesh::Instance() && m_skyMesh->inDraw())
0073         {
0074             printf("Warning: aborting concurrent DeepStarComponent::draw()");
0075         }
0076         bool checkSlewing = (map->isSlewing() && Options::hideOnSlew());
0077 
0078         //shortcuts to inform whether to draw different objects
0079         bool hideFaintStars(checkSlewing && Options::hideStars());
0080         double hideStarsMag = Options::magLimitHideStar();
0081 
0082         //adjust maglimit for ZoomLevel
0083         //    double lgmin = log10(MINZOOM);
0084         //    double lgmax = log10(MAXZOOM);
0085         //    double lgz = log10(Options::zoomFactor());
0086         // TODO: Enable hiding of faint stars
0087 
0088         float maglim = StarComponent::zoomMagnitudeLimit();
0089 
0090         if (maglim < m_deepStarComp->triggerMag || !m_staticStars)
0091         {
0092             hide();
0093             return;
0094         }
0095         else
0096         {
0097             show();
0098         }
0099 
0100         //float m_zoomMagLimit = maglim;
0101 
0102         m_skyMesh->inDraw(true);
0103 
0104         SkyPoint *focus = map->focus();
0105         m_skyMesh->aperture(focus, radius + 1.0, DRAW_BUF); // divide by 2 for testing
0106 
0107         MeshIterator region(m_skyMesh, DRAW_BUF);
0108 
0109         // If we are to hide the fainter stars (eg: while slewing), we set the magnitude limit to hideStarsMag.
0110         if (hideFaintStars && maglim > hideStarsMag)
0111             maglim = hideStarsMag;
0112 
0113         StarBlockFactory *m_StarBlockFactory = StarBlockFactory::Instance();
0114         //    m_StarBlockFactory->drawID = m_skyMesh->drawID();
0115         //    qDebug() << "Mesh size = " << m_skyMesh->size() << "; drawID = " << m_skyMesh->drawID();
0116 
0117         /*t_dynamicLoad = 0;
0118         t_updateCache = 0;
0119         t_drawUnnamed = 0;*/
0120 
0121         //visibleStarCount = 0;
0122 
0123         // Mark used blocks in the LRU Cache. Not required for static stars
0124         if (!m_staticStars)
0125         {
0126             //Under construction
0127             //            while( region.hasNext() ) {
0128             //                Trixel currentRegion = region.next();
0129             //                for( int i = 0; i < m_starBlockList->at( currentRegion )->getBlockCount(); ++i ) {
0130             //                    StarBlock *prevBlock = ( ( i >= 1 ) ? m_starBlockList->at( currentRegion )->block( i - 1 ) : nullptr );
0131             //                    StarBlock *block = m_starBlockList->at( currentRegion )->block( i );
0132 
0133             //                    if( i == 0  &&  !m_StarBlockFactory->markFirst( block ) )
0134             //                        qDebug() << "markFirst failed in trixel" << currentRegion;
0135             //                    if( i > 0   &&  !m_StarBlockFactory->markNext( prevBlock, block ) )
0136             //                        qDebug() << "markNext failed in trixel" << currentRegion << "while marking block" << i;
0137             //                    if( i < m_starBlockList->at( currentRegion )->getBlockCount()
0138             //                            && m_starBlockList->at( currentRegion )->block( i )->getFaintMag() < maglim )
0139             //                        break;
0140             //                }
0141             //            }
0142             //            //t_updateCache = t.restart();
0143             //            region.reset();
0144         }
0145 
0146         m_StarBlockFactory->drawID = m_skyMesh->drawID();
0147 
0148         int regionID = -1;
0149         if (region.hasNext())
0150         {
0151             regionID = region.next();
0152         }
0153 
0154         int trixelID = 0;
0155 
0156         QSGNode *firstTrixel = firstChild();
0157         TrixelNode *trixel   = static_cast<TrixelNode *>(firstTrixel);
0158 
0159         while (trixel != 0)
0160         {
0161             if (m_staticStars)
0162             {
0163                 const Projector *projector = SkyMapLite::Instance()->projector();
0164                 double delLim              = SkyMapLite::deleteLimit();
0165 
0166                 if (trixelID != regionID)
0167                 {
0168                     trixel->hide();
0169 
0170                     if (trixel->hideCount() > delLim)
0171                     {
0172                         QLinkedList<QPair<SkyObject *, SkyNode *>>::iterator i = trixel->m_nodes.begin();
0173 
0174                         while (i != trixel->m_nodes.end())
0175                         {
0176                             SkyNode *node = (*i).second;
0177                             if (node)
0178                             {
0179                                 trixel->removeChildNode(node);
0180                                 delete node;
0181 
0182                                 *i = QPair<SkyObject *, SkyNode *>((*i).first, 0);
0183                             }
0184                             ++i;
0185                         }
0186                     }
0187 
0188                     trixel = static_cast<TrixelNode *>(trixel->nextSibling());
0189                     ++trixelID;
0190                     continue;
0191                 }
0192                 else
0193                 {
0194                     trixel->show();
0195 
0196                     if (region.hasNext())
0197                     {
0198                         regionID = region.next();
0199                     }
0200 
0201                     QLinkedList<QPair<SkyObject *, SkyNode *>>::iterator i = (&trixel->m_nodes)->begin();
0202 
0203                     while (i != (&trixel->m_nodes)->end())
0204                     {
0205                         bool hide     = false;
0206                         bool hideSlew = false;
0207 
0208                         bool drawLabel = false;
0209 
0210                         StarObject *starObj = static_cast<StarObject *>((*i).first);
0211                         SkyNode *node       = (*i).second;
0212 
0213                         int mag = starObj->mag();
0214 
0215                         // break loop if maglim is reached
0216                         if (mag > maglim)
0217                             hide = true;
0218                         if (hideFaintStars && hideStarsMag)
0219                             hideSlew = true;
0220                         if (starObj->updateID != KStarsData::Instance()->updateID())
0221                             starObj->JITupdate();
0222 
0223                         if (node)
0224                         {
0225                             if (node->hideCount() > delLim || hide)
0226                             {
0227                                 trixel->removeChildNode(node);
0228                                 delete node;
0229                                 *i = QPair<SkyObject *, SkyNode *>((*i).first, 0);
0230                             }
0231                             else
0232                             {
0233                                 if (!hideSlew)
0234                                 {
0235                                     node->update(drawLabel);
0236                                 }
0237                                 else
0238                                 {
0239                                     node->hide();
0240                                 }
0241                             }
0242                         }
0243                         else
0244                         {
0245                             if (!hide && !hideSlew && projector->checkVisibility(starObj))
0246                             {
0247                                 QPointF pos;
0248 
0249                                 bool visible = false;
0250                                 pos          = projector->toScreen(starObj, true, &visible);
0251                                 if (visible && projector->onScreen(pos))
0252                                 {
0253                                     PointSourceNode *point =
0254                                         new PointSourceNode(starObj, rootNode(), LabelsItem::label_t::STAR_LABEL,
0255                                                             starObj->spchar(), starObj->mag(), trixelID);
0256                                     trixel->appendChildNode(point);
0257 
0258                                     *i = QPair<SkyObject *, SkyNode *>((*i).first, static_cast<SkyNode *>(point));
0259                                     point->updatePos(pos, drawLabel);
0260                                 }
0261                             }
0262                         }
0263                         ++i;
0264                     }
0265                 }
0266             }
0267             else if (false)
0268             {
0269                 //Dynamic stars are under construction
0270                 if (!m_staticStars && !m_starBlockList->at(regionID)->fillToMag(maglim) &&
0271                     maglim <= m_deepStarComp->m_FaintMagnitude * (1 - 1.5 / 16))
0272                 {
0273                     qDebug() << "SBL::fillToMag( " << maglim << " ) failed for trixel " << regionID << " !" << endl;
0274                 }
0275 
0276                 for (int i = 0; i < m_starBlockList->at(regionID)->getBlockCount(); ++i)
0277                 {
0278                     bool hide = false;
0279 
0280                     std::shared_ptr<StarBlock> block = m_starBlockList->at(regionID)->block(i);
0281 
0282                     for (int j = 0; j < block->getStarCount(); j++)
0283                     {
0284                         StarNode *star         = block->star(j);
0285                         StarObject *curStar    = &(star->star);
0286                         PointSourceNode *point = star->starNode;
0287 
0288                         if (curStar->updateID != updateID)
0289                             curStar->JITupdate();
0290 
0291                         float mag = curStar->mag();
0292 
0293                         if (!hide)
0294                         {
0295                             if (mag > maglim)
0296                                 hide = true;
0297                         }
0298 
0299                         if (!hide)
0300                         {
0301                             if (!point)
0302                             {
0303                                 star->starNode = new PointSourceNode(curStar, rootNode(), LabelsItem::label_t::NO_LABEL,
0304                                                                      curStar->spchar(), curStar->mag(), regionID);
0305                                 point          = star->starNode;
0306                                 trixel->appendChildNode(point);
0307                             }
0308                             //point->setSizeMagLim(m_zoomMagLimit);
0309                             point->update();
0310                         }
0311                         else
0312                         {
0313                             if (point)
0314                                 point->hide();
0315                         }
0316                     }
0317                 }
0318             }
0319             trixel = static_cast<TrixelNode *>(trixel->nextSibling());
0320             trixelID++;
0321         }
0322         m_skyMesh->inDraw(false);
0323     }
0324 }