void QGLSection::appendSmooth(const QLogicalVertex &lv, int index) { Q_ASSERT(lv.hasField(QGL::Position)); Q_ASSERT(lv.hasField(QGL::Normal)); int found_index = -1; QMap<int, int>::const_iterator it = d->index_map.constFind(index); if (it != d->index_map.constEnd()) found_index = it.value(); if (found_index == -1) { int newIndex = appendVertex(lv); d->index_map.insert(index, newIndex); appendIndex(newIndex); d->accumulateNormal(newIndex, lv.normal()); } else { appendIndex(found_index); if (!d->normalAccumulated(found_index, lv.normal())) { normal(found_index) += lv.normal(); d->accumulateNormal(found_index, lv.normal()); } } d->finalized = false; m_displayList->setDirty(true); }
int QGLSection::appendOne(const QLogicalVertex &lv) { #ifndef QT_NO_DEBUG_STREAM if (count() && lv.fields() != fields()) { qDebug() << "Warning: adding" << lv << "fields:" << lv.fields() << "fields do not match existing:" << fields() << "create new section first?"; } #endif int index = appendVertex(lv); d->mapVertex(lv.vertex(), index); appendIndex(index); return index; }
/*! \internal Adds the logical vertex \a lv to this section of a display list. Two QLogicalVertex instances a and b are treated as being duplicates for the purpose of smoothing, if \c{qFuzzyCompare(a.vertex(), b.vertex())} is true All duplicate occurrences of a vertex are coalesced, that is replaced by a GL index referencing the one copy. In order to draw \a lv as part of a smooth continuous surface, with no distinct edge, duplicates of vertex \a lv are coalesced into one (within this section) and the normal for that one set to the average of the incoming unique normals. The incoming vertex \a lv is not treated as a duplicate if \a lv has different texture coordinates or attributes. This occurs for example in the case of a texture seam, where two different texture coordinates are required at the same point on the geometry. In that case a new duplicate vertex is added to carry the unique texture coordinates or attributes. When new vertex copies are added in this way all copies receive the averaged normals. Call this function to add the vertices of a smooth face to the section of a display list, or use: \code myDisplayList->newSection(QGLBuilder::Smooth); myDisplayList->addTriangle(a, b, c); \endcode In smooth surfaces, the vertex and its normal is only sent to the graphics hardware once (not once per face), thus smooth geometry may consume fewer resources. \sa appendFaceted(), updateTexCoord(), QGLBuilder::newSection() */ void QGLSection::appendSmooth(const QLogicalVertex &lv) { Q_ASSERT(lv.hasField(QGL::Position)); Q_ASSERT(lv.hasField(QGL::Normal)); int found_index = d->findVertex(lv.vertex()); bool coalesce = false; if (found_index == -1) { int newIndex = appendOne(lv); d->accumulateNormal(newIndex, lv.normal()); } else { while (!coalesce && found_index != -1) { if (qCompareByAttributes(lv, logicalVertexAt(found_index))) coalesce = true; else found_index = d->nextIndex(); } if (!coalesce) // texture or attributes prevented coalesce { // new vert to carry tex/attrib data d->accumulateNormal(appendOne(lv), lv.normal()); } else { appendIndex(found_index); while (found_index != -1) { if (!d->normalAccumulated(found_index, lv.normal())) { normal(found_index) += lv.normal(); d->accumulateNormal(found_index, lv.normal()); } found_index = d->nextIndex(); } } } d->finalized = false; m_displayList->setDirty(true); }
void recordStackDump(jvmtiEnv* jvmti) { //long long before = getNanoTime(); jvmtiStackInfo* stackInfo; jint threadCount; jvmtiError err; err = jvmti->GetAllStackTraces(MAX_FRAMES, &stackInfo, &threadCount); if (err != JVMTI_ERROR_NONE) { ERROR("GetAllStackTraces failed with %d", err); return; } for (int ti = 0; ti < threadCount; ++ti) { jvmtiStackInfo* infop = &stackInfo[ti]; jthread thread = infop->thread; jvmtiFrameInfo* frames = infop->frame_buffer; jvmtiThreadInfo thread_info; err = jvmti->GetThreadInfo(thread, &thread_info); if(err != JVMTI_ERROR_NONE) { ERROR("GetMethodName failed with %d", err); return; } if(infop->frame_count > 0) { appendIndex(method_count); for (int fi = 0; fi < infop->frame_count; fi++) { appendMethod(frames[fi].method); } } } err = jvmti->Deallocate((unsigned char*) stackInfo); //long long after = getNanoTime(); //total += after-before; //count++; //fprintf (stderr, "time = %lldns (%lldns avg)\n", after-before, total / count); }
/*! \internal Add the logical vertex \a lv to this section of a display list. The vertex will be drawn as a distinct edge, instead of just part of a continuous smooth surface. To acheive this the vertex value of \a lv is duplicated for each unique normal in the current section. Note that duplication is only for unique normals: if a vertex is already present with a given normal it is coalesced and simply referenced by index. As for appendSmooth() vertices are not coalesced in this way if \a lv has a different texture coordinate or attribute than its duplicate. This function is used to add the vertices of a faceted face to the list: \code myDisplayList->newSection(QGLBuilder::Faceted); myDisplayList->addVertex(lv); \endcode In faceted surfaces, the vertex is sent to the graphics hardware once for each normal it has, and thus may consume more resources. \sa appendSmooth(), updateTexCoord(), QGLBuilder::newSection() */ void QGLSection::appendFaceted(const QLogicalVertex &lv) { Q_ASSERT(lv.hasField(QGL::Position)); Q_ASSERT(lv.hasField(QGL::Normal)); int found_index = d->findVertex(lv.vertex()); bool coalesce = false; while (!coalesce && found_index != -1) { if (logicalVertexAt(found_index) == lv) coalesce = true; else found_index = d->nextIndex(); } if (coalesce) // found { appendIndex(found_index); } else { appendOne(lv); } d->finalized = false; m_displayList->setDirty(true); }
void DeepSkyComponent::loadData() { KStarsData* data = KStarsData::Instance(); //Check whether we need to concatenate a split NGC/IC catalog //(i.e., if user has downloaded the Steinicke catalog) mergeSplitFiles(); QList< QPair<QString,KSParser::DataTypes> > sequence; QList<int> widths; sequence.append(qMakePair(QString("Flag"), KSParser::D_QSTRING)); widths.append(1); sequence.append(qMakePair(QString("ID"), KSParser::D_INT)); widths.append(4); sequence.append(qMakePair(QString("suffix"), KSParser::D_QSTRING)); widths.append(1); sequence.append(qMakePair(QString("RA_H"), KSParser::D_INT)); widths.append(2); sequence.append(qMakePair(QString("RA_M"),KSParser::D_INT)); widths.append(2); sequence.append(qMakePair(QString("RA_S"),KSParser::D_FLOAT)); widths.append(4); sequence.append(qMakePair(QString("D_Sign"),KSParser::D_QSTRING)); widths.append(2); sequence.append(qMakePair(QString("Dec_d"),KSParser::D_INT)); widths.append(2); sequence.append(qMakePair(QString("Dec_m"),KSParser::D_INT)); widths.append(2); sequence.append(qMakePair(QString("Dec_s"),KSParser::D_INT)); widths.append(2); sequence.append(qMakePair(QString("BMag"),KSParser::D_QSTRING)); widths.append(6); sequence.append(qMakePair(QString("type"),KSParser::D_INT)); widths.append(2); sequence.append(qMakePair(QString("a"),KSParser::D_FLOAT)); widths.append(6); sequence.append(qMakePair(QString("b"),KSParser::D_FLOAT)); widths.append(6); sequence.append(qMakePair(QString("pa"),KSParser::D_QSTRING)); widths.append(4); sequence.append(qMakePair(QString("PGC"),KSParser::D_INT)); widths.append(7); sequence.append(qMakePair(QString("other cat"),KSParser::D_QSTRING)); widths.append(4); sequence.append(qMakePair(QString("other1"),KSParser::D_QSTRING)); widths.append(6); sequence.append(qMakePair(QString("other2"),KSParser::D_QSTRING)); widths.append(6); sequence.append(qMakePair(QString("Messr"),KSParser::D_QSTRING)); widths.append(2); sequence.append(qMakePair(QString("MessrNum"),KSParser::D_INT)); widths.append(4); sequence.append(qMakePair(QString("Longname"),KSParser::D_QSTRING)); //No width to be appended for last sequence object QString file_name = KSPaths::locate(QStandardPaths::GenericDataLocation, QString("ngcic.dat") ); KSParser deep_sky_parser(file_name, '#', sequence, widths); deep_sky_parser.SetProgress( i18n("Loading NGC/IC objects"), 13444, 10 ); qDebug() << "Loading NGC/IC objects"; QHash<QString,QVariant> row_content; while (deep_sky_parser.HasNextRow()) { row_content = deep_sky_parser.ReadNextRow(); QString iflag; QString cat; iflag = row_content["Flag"].toString().mid( 0, 1 ); //check for NGC/IC catalog flag /* Q_ASSERT(iflag == "I" || iflag == "N" || iflag == " "); // (spacetime): ^ Why an assert? Change in implementation of ksparser // might result in crash for no reason. // n.b. We also allow non-NGC/IC objects which have a blank iflag */ float mag(1000.0); int type, ingc, imess(-1), pa; int pgc, ugc; QString ss, name, name2, longname; QString cat2; // Designation if ( iflag == "I" ) cat = "IC"; else if ( iflag == "N" ) cat = "NGC"; ingc = row_content["ID"].toInt(); // NGC/IC catalog number if ( ingc==0 ) cat.clear(); //object is not in NGC or IC catalogs QString suffix = row_content["suffix"].toString(); // multipliticity suffixes, eg: the 'A' in NGC 4945A Q_ASSERT( suffix.isEmpty() || ( suffix.at( 0 ) >= QChar( 'A' ) && suffix.at( 0 ) <= QChar( 'Z' ) ) || (suffix.at( 0 ) >= QChar( 'a' ) && suffix.at( 0 ) <= QChar( 'z' ) ) ); //coordinates int rah = row_content["RA_H"].toInt(); int ram = row_content["RA_M"].toInt(); float ras = row_content["RA_S"].toFloat(); QString sgn = row_content["D_Sign"].toString(); int dd = row_content["Dec_d"].toInt(); int dm = row_content["Dec_m"].toInt(); int ds = row_content["Dec_s"].toInt(); if ( !( (0.0 <= rah && rah < 24.0) || (0.0 <= ram && ram < 60.0) || (0.0 <= ras && ras < 60.0) || (0.0 <= dd && dd <= 90.0) || (0.0 <= dm && dm < 60.0) || (0.0 <= ds && ds < 60.0) ) ) { qDebug() << "Bad coordinates while processing NGC/IC object: " << cat << ingc; qDebug() << "RA H:M:S = " << rah << ":" << ram << ":" << ras << "; Dec D:M:S = " << dd << ":" << dm << ":" << ds; Q_ASSERT( false ); } //Ignore lines with no coordinate values if not debugging if (rah==0 && ram==0 && ras==0) continue; //B magnitude ss = row_content["BMag"].toString(); if (ss == "") { mag = 99.9f; } else { mag = ss.toFloat(); } //object type type = row_content["type"].toInt(); //major and minor axes float a = row_content["a"].toFloat(); float b = row_content["b"].toFloat(); //position angle. The catalog PA is zero when the Major axis //is horizontal. But we want the angle measured from North, so //we set PA = 90 - pa. ss = row_content["pa"].toString(); if (ss == "" ) { pa = 90; } else { pa = 90 - ss.toInt(); } //PGC number pgc = row_content["PGC"].toInt(); //UGC number if (row_content["other cat"].toString().trimmed() == "UGC") { ugc = row_content["other1"].toString().toInt(); } else { ugc = 0; } //Messier number if ( row_content["Messr"].toString().trimmed() == "M" ) { cat2 = cat; if ( ingc == 0 ) cat2.clear(); cat = 'M'; imess = row_content["MessrNum"].toInt(); } longname = row_content["Longname"].toString(); dms r; r.setH( rah, ram, int(ras) ); dms d( dd, dm, ds ); if ( sgn == "-" ) { d.setD( -1.0*d.Degrees() ); } bool hasName = true; QString snum; if (cat=="IC" || cat=="NGC") { snum.setNum(ingc); name = cat + ' ' + ( ( suffix.isEmpty() ) ? snum : ( snum + suffix ) ); } else if (cat == "M") { snum.setNum( imess ); name = cat + ' ' + snum; // Note: Messier has no suffixes if (cat2 == "NGC" || cat2 == "IC") { snum.setNum( ingc ); name2 = cat2 + ' ' + ( ( suffix.isEmpty() ) ? snum : ( snum + suffix ) ); } else { name2.clear(); } } else { if (!longname.isEmpty()) name = longname; else { hasName = false; name = i18n( "Unnamed Object" ); } } name = i18nc("object name (optional)", name.toLatin1().constData()); if (!longname.isEmpty()) longname = i18nc("object name (optional)", longname.toLatin1().constData()); // create new deepskyobject DeepSkyObject *o = 0; if ( type==0 ) type = 1; //Make sure we use CATALOG_STAR, not STAR o = new DeepSkyObject( type, r, d, mag, name, name2, longname, cat, a, b, pa, pgc, ugc ); o->EquatorialToHorizontal( data->lst(), data->geo()->lat() ); // Add the name(s) to the nameHash for fast lookup -jbb if ( hasName) { nameHash[ name.toLower() ] = o; if ( ! longname.isEmpty() ) nameHash[ longname.toLower() ] = o; if ( ! name2.isEmpty() ) nameHash[ name2.toLower() ] = o; } Trixel trixel = m_skyMesh->index(o); //Assign object to general DeepSkyObjects list, //and a secondary list based on its catalog. m_DeepSkyList.append( o ); appendIndex( o, &m_DeepSkyIndex, trixel ); if ( o->isCatalogM()) { m_MessierList.append( o ); appendIndex( o, &m_MessierIndex, trixel ); } else if (o->isCatalogNGC() ) { m_NGCList.append( o ); appendIndex( o, &m_NGCIndex, trixel ); } else if ( o->isCatalogIC() ) { m_ICList.append( o ); appendIndex( o, &m_ICIndex, trixel ); } else { m_OtherList.append( o ); appendIndex( o, &m_OtherIndex, trixel ); } // JM: VERY INEFFICIENT. Disabling for now until we figure out how to deal with dups. QSet? //if ( ! name.isEmpty() && !objectNames(type).contains(name)) if ( ! name.isEmpty() ) objectNames(type).append( name ); //Add long name to the list of object names //if ( ! longname.isEmpty() && longname != name && !objectNames(type).contains(longname)) if ( ! longname.isEmpty() && longname != name) objectNames(type).append( longname ); deep_sky_parser.ShowProgress(); } foreach(QStringList list, objectNames()) list.removeDuplicates(); }