ZoneArray.hpp   ZoneArray.hpp 
skipping to change at line 27 skipping to change at line 27
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA.
*/ */
#ifndef _ZONEARRAY_HPP_ #ifndef _ZONEARRAY_HPP_
#define _ZONEARRAY_HPP_ #define _ZONEARRAY_HPP_
#include <QString> #include <QString>
#include <QFile>
#include <QDebug> #include <QDebug>
#include "ZoneData.hpp" #include "ZoneData.hpp"
#include "Star.hpp" #include "Star.hpp"
#include "GLee.h" #include "StelLoadingBar.hpp"
#include "LoadingBar.hpp"
#include "Projector.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "SkyDrawer.hpp" #include "StelSkyDrawer.hpp"
#include "STexture.hpp"
#include "StarMgr.hpp" #include "StarMgr.hpp"
#include "bytes.h" #include "bytes.h"
#ifndef WIN32 #include "StelPainter.hpp"
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#else
#include <io.h>
#include <windows.h>
#endif
// Patch by Rainer Canavan for compilation on irix with mipspro compiler pa rt 1 // Patch by Rainer Canavan for compilation on irix with mipspro compiler pa rt 1
#ifndef MAP_NORESERVE #ifndef MAP_NORESERVE
# ifdef MAP_AUTORESRV # ifdef MAP_AUTORESRV
# if (defined(__sgi) && defined(_COMPILER_VERSION)) # if (defined(__sgi) && defined(_COMPILER_VERSION))
# define MAP_NORESERVE MAP_AUTORESRV # define MAP_NORESERVE MAP_AUTORESRV
# endif # endif
# else # else
# define MAP_NORESERVE 0 # define MAP_NORESERVE 0
# endif # endif
#endif #endif
namespace BigStarCatalogExtension { namespace BigStarCatalogExtension
{
// A ZoneArray manages all ZoneData structures of a given GeodesicGrid leve
l.
class ZoneArray { #define NR_OF_HIP 120416
public: #define FILE_MAGIC 0x835f040a
static ZoneArray *create(const StarMgr &hip_star_mgr, #define FILE_MAGIC_OTHER_ENDIAN 0x0a045f83
const QString &extended_file_name, #define FILE_MAGIC_NATIVE 0x835f040b
LoadingBar &lb); #define MAX_MAJOR_FILE_VERSION 0
virtual ~ZoneArray(void) {nr_of_zones = 0;}
virtual void generateNativeDebugFile(const char *fname) const = 0; //! @struct HipIndexStruct
unsigned int getNrOfStars(void) const {return nr_of_stars;} //! Container for Hipparcos information. Stores a pointer to a Hipparcos st
virtual void updateHipIndex(HipIndexStruct hipIndex[]) const {} ar,
virtual void searchAround(int index,const Vec3d &v,double cosLimFov, //! its catalog and its triangle.
QList<StelObjectP > &result) = 0; struct HipIndexStruct
virtual void draw(int index,bool is_inside, {
const float *rcmag_table, Projector *prj, const SpecialZoneArray<Star1> *a;
unsigned int maxMagStarName,float names_brightness, const SpecialZoneData<Star1> *z;
SFont *starFont) const = 0; const Star1 *s;
bool isInitialized(void) const {return (nr_of_zones>0);}
void initTriangle(int index,
const Vec3d &c0,
const Vec3d &c1,
const Vec3d &c2);
virtual void scaleAxis(void) = 0;
const int level;
const int mag_min;
const int mag_range;
const int mag_steps;
double star_position_scale;
const StarMgr &hip_star_mgr;
protected:
static bool readFileWithLoadingBar(FILE *f,
void *data,size_t size,LoadingBar &lb)
;
ZoneArray(const StarMgr &hip_star_mgr,int level,
int mag_min,int mag_range,int mag_steps);
unsigned int nr_of_zones;
unsigned int nr_of_stars;
ZoneData *zones;
}; };
template<class Star> //! @class ZoneArray
class SpecialZoneArray : public ZoneArray { //! Manages all ZoneData structures of a given StelGeodesicGrid level. An
//! instance of this class is never created directly; the named constructor
//! returns an instance of one of its subclasses. All it really does is
//! bootstrap the loading process.
class ZoneArray
{
public: public:
SpecialZoneArray(FILE *f,bool byte_swap,bool use_mmap, //! Named public constructor for ZoneArray. Opens a catalog, reads i
LoadingBar &lb, ts
const StarMgr &hip_star_mgr,int level, //! header info, and creates a SpecialZoneArray or HipZoneArray for
int mag_min,int mag_range,int mag_steps); //! loading.
~SpecialZoneArray(void); //! @param extended_file_name path of the star catalog to load from
void generateNativeDebugFile(const char *fname) const; //! @param use_mmap whether or not to mmap the star catalog
protected: //! @param lb the loading bar on the splash screen
SpecialZoneData<Star> *getZones(void) const //! @return an instance of SpecialZoneArray or HipZoneArray
{return static_cast<SpecialZoneData<Star>*>(zones);} static ZoneArray *create(const QString &extended_file_name,
Star *stars; bool use_mmap,
private: StelLoadingBar &lb);
void *mmap_start; virtual ~ZoneArray(void)
#ifdef WIN32 {
HANDLE mapping_handle; nr_of_zones = 0;
#endif }
void scaleAxis(void);
void searchAround(int index,const Vec3d &v,double cosLimFov,
QList<StelObjectP > &result);
void draw(int index,bool is_inside,
const float *rcmag_table, Projector *prj,
unsigned int maxMagStarName,float names_brightness,
SFont *starFont) const;
};
template<class Star> //! Get the total number of stars in this catalog.
void SpecialZoneArray<Star>::scaleAxis(void) { unsigned int getNrOfStars(void) const { return nr_of_stars; }
star_position_scale /= Star::MaxPosVal;
for (ZoneData *z=zones+(nr_of_zones-1);z>=zones;z--) {
z->axis0 *= star_position_scale;
z->axis1 *= star_position_scale;
}
}
#define NR_OF_HIP 120416 //! Dummy method that does nothing. See subclass implementation.
virtual void updateHipIndex(HipIndexStruct hipIndex[]) const {}
struct HipIndexStruct { //! Pure virtual method. See subclass implementation.
const SpecialZoneArray<Star1> *a; virtual void searchAround(int index,const Vec3d &v,double cosLimFov,
const SpecialZoneData<Star1> *z; QList<StelObjectP > &result) = 0;
const Star1 *s;
};
class ZoneArray1 : public SpecialZoneArray<Star1> { //! Pure virtual method. See subclass implementation.
public: virtual void draw(int index,bool is_inside,
ZoneArray1(FILE *f,bool byte_swap,bool use_mmap, const float *rcmag_table, const StelProjectorP& pr
LoadingBar &lb,const StarMgr &hip_star_mgr, j,
int level,int mag_min,int mag_range,int mag_steps) unsigned int maxMagStarName,float names_brightness
: SpecialZoneArray<Star1>(f,byte_swap,use_mmap,lb,hip_star_mgr,level, ,
mag_min,mag_range,mag_steps) {} StelFont *starFont) const = 0;
private:
void updateHipIndex(HipIndexStruct hipIndex[]) const;
};
template<class Star> //! Get whether or not the catalog was successfully loaded.
void SpecialZoneArray<Star>::generateNativeDebugFile(const char *fname) con //! @return @c true if at least one zone was loaded, otherwise @c fa
st { lse
FILE *f = fopen(fname,"wb"); bool isInitialized(void) const { return (nr_of_zones>0); }
if (f) {
// write first 10 stars in native format to a file:
fwrite(stars,10,sizeof(Star),f);
fclose(f);
}
}
template<class Star> //! Initialize the ZoneData struct at the given index.
SpecialZoneArray<Star>::SpecialZoneArray(FILE *f,bool byte_swap,bool use_mm void initTriangle(int index,
ap, const Vec3d &c0,
LoadingBar &lb, const Vec3d &c1,
const StarMgr &hip_star_mgr, const Vec3d &c2);
int level, virtual void scaleAxis(void) = 0;
int mag_min,int mag_range,
int mag_steps)
:ZoneArray(hip_star_mgr,level,
mag_min,mag_range,mag_steps),
stars(0),
#ifndef WIN32
mmap_start(MAP_FAILED)
#else
mmap_start(NULL),
mapping_handle(NULL)
#endif
{
if (nr_of_zones > 0) {
lb.Draw(0.f);
zones = new SpecialZoneData<Star>[nr_of_zones];
if (zones == 0) {
qWarning() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: no memory (1)";
exit(1);
}
{
unsigned int *zone_size = new unsigned int[nr_of_zones];
if (zone_size == 0) {
qWarning() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: no memory (2)";
exit(1);
}
if (nr_of_zones != fread(zone_size,sizeof(unsigned int),nr_of_zones,f
)) {
delete[] getZones();
zones = 0;
nr_of_zones = 0;
} else {
const unsigned int *tmp = zone_size;
for (unsigned int z=0;z<nr_of_zones;z++,tmp++) {
const unsigned int tmp_spu_int32 = byte_swap?bswap_32(*tmp):*tmp;
nr_of_stars += tmp_spu_int32;
getZones()[z].size = tmp_spu_int32;
}
}
// delete zone_size before allocating stars
// in order to avoid memory fragmentation:
delete[] zone_size;
}
if (nr_of_stars == 0) {
// no stars ?
if (zones) delete[] getZones();
zones = 0;
nr_of_zones = 0;
} else {
if (use_mmap) {
const long start_in_file = ftell(f);
#ifndef WIN32
const long page_size = sysconf(_SC_PAGE_SIZE);
#else
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
const long page_size = system_info.dwAllocationGranularity;
#endif
const long mmap_offset = start_in_file % page_size;
#ifndef WIN32
mmap_start = mmap(0,mmap_offset+sizeof(Star)*nr_of_stars,PROT_READ,
MAP_PRIVATE | MAP_NORESERVE,
fileno(f),start_in_file-mmap_offset);
if (mmap_start == MAP_FAILED) {
qWarning() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: mmap(" << fileno(f)
<< ',' << start_in_file
<< ',' << (sizeof(Star)*nr_of_stars)
<< ") failed: " << strerror(errno);
stars = 0;
nr_of_stars = 0;
delete[] getZones();
zones = 0;
nr_of_zones = 0;
} else {
stars = (Star*)(((char*)mmap_start)+mmap_offset);
Star *s = stars;
for (unsigned int z=0;z<nr_of_zones;z++) {
getZones()[z].stars = s;
s += getZones()[z].size;
}
}
#else
HANDLE file_handle = (void*)_get_osfhandle(_fileno(f));
if (file_handle == INVALID_HANDLE_VALUE) {
qWarning() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: _get_osfhandle(_fileno(f)) fa
iled";
} else {
mapping_handle = CreateFileMapping(file_handle,NULL,PAGE_READONLY
,
0,0,NULL);
if (mapping_handle == NULL) {
// yes, NULL indicates failure, not INVALID_HANDLE_VALUE
qWarning() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: CreateFileMapping failed: "
<< GetLastError();
} else {
mmap_start = MapViewOfFile(mapping_handle,
FILE_MAP_READ,
0,
start_in_file-mmap_offset,
mmap_offset+sizeof(Star)*nr_of_stars
);
if (mmap_start == NULL) {
qWarning() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: "
<< "MapViewOfFile failed: "
<< GetLastError()
<< ", page_size: " << page_size;
stars = 0;
nr_of_stars = 0;
delete[] getZones();
zones = 0;
nr_of_zones = 0;
} else {
stars = (Star*)(((char*)mmap_start)+mmap_offset);
Star *s = stars;
for (unsigned int z=0;z<nr_of_zones;z++) {
getZones()[z].stars = s;
s += getZones()[z].size;
}
}
}
}
#endif
} else {
stars = new Star[nr_of_stars];
if (stars == 0) {
qWarning() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: no memory (3)";
exit(1);
}
if (!readFileWithLoadingBar(f,stars,sizeof(Star)*nr_of_stars,lb)) {
delete[] stars;
stars = 0;
nr_of_stars = 0;
delete[] getZones();
zones = 0;
nr_of_zones = 0;
} else {
Star *s = stars;
for (unsigned int z=0;z<nr_of_zones;z++) {
getZones()[z].stars = s;
s += getZones()[z].size;
}
if (
#if (!defined(__GNUC__))
true
#else
byte_swap
#endif
) {
s = stars;
for (unsigned int i=0;i<nr_of_stars;i++,s++) {
s->repack(
#ifdef WORDS_BIGENDIAN
// need for byte_swap on a BE machine means that catalog is LE
!byte_swap
#else
// need for byte_swap on a LE machine means that catalog is BE
byte_swap
#endif
);
}
}
// qDebug() << "\n"
// << "SpecialZoneArray<Star>::SpecialZoneArray(" << level
// << "): repack test start";
// stars[0].print();
// stars[1].print();
// qDebug() << "SpecialZoneArray<Star>::SpecialZoneArray(" << lev
el
// << "): repack test end";
}
}
}
lb.Draw(1.f);
}
}
template<class Star> //! File path of the catalog.
SpecialZoneArray<Star>::~SpecialZoneArray(void) { const QString fname;
if (stars) {
#ifndef WIN32 //! Level in StelGeodesicGrid.
if (mmap_start != MAP_FAILED) { const int level;
munmap(mmap_start,((char*)stars-(char*)mmap_start)
+sizeof(Star)*nr_of_stars); //! Lower bound of magnitudes in this catalog.
} else { const int mag_min;
delete[] stars;
} //! Range of magnitudes in this catalog.
#else const int mag_range;
if (mmap_start != NULL) {
CloseHandle(mapping_handle); //! Number of steps used to describe values in @em mag_range.
} else { const int mag_steps;
delete[] stars;
} double star_position_scale;
#endif protected:
stars = 0; //! Load a catalog and display its progress on the splash screen.
} //! @return @c true if successful, or @c false if an error occurred
if (zones) {delete[] getZones();zones = NULL;} static bool readFileWithStelLoadingBar(QFile& file, void *data,
nr_of_zones = 0; qint64 size,StelLoadingBar &l
nr_of_stars = 0; b);
}
//! Protected constructor. Initializes fields and does not load anyt
hing.
ZoneArray(const QString& fname, QFile* file, int level, int mag_min,
int mag_range, int mag_steps);
unsigned int nr_of_zones;
unsigned int nr_of_stars;
ZoneData *zones;
QFile* file;
};
//! @class SpecialZoneArray
//! Implements all the virtual methods in ZoneArray. Is only separate from
//! %ZoneArray because %ZoneArray decides on the template parameter.
//! @tparam Star either Star1, Star2 or Star3, depending on the brightness
of
//! stars in this catalog.
template<class Star> template<class Star>
void SpecialZoneArray<Star>::draw(int index,bool is_inside, class SpecialZoneArray : public ZoneArray
const float *rcmag_table,
Projector *prj,
unsigned int maxMagStarName,
float names_brightness,
SFont *starFont) const
{ {
SkyDrawer* drawer = StelApp::getInstance().getCore()->getSkyDrawer() public:
; //! Handles loading of the meaty part of star catalogs.
SpecialZoneData<Star> *const z = getZones() + index; //! @param file catalog to load from
Vec3d xy; //! @param byte_swap whether to switch endianness of catalog data
const Star *const end = z->getStars() + z->size; //! @param use_mmap whether or not to mmap the star catalog
const double d2000 = 2451545.0; //! @param lb the loading bar on the splash screen
const double movementFactor = (M_PI/180)*(0.0001/3600) * ((StarMgr:: //! @param level level in StelGeodesicGrid
getCurrentJDay()-d2000)/365.25) / star_position_scale; //! @param mag_min lower bound of magnitudes
for (const Star *s=z->getStars();s<end;s++) //! @param mag_range range of magnitudes
//! @param mag_steps number of steps used to describe values in rang
e
SpecialZoneArray(QFile* file,bool byte_swap,bool use_mmap,
StelLoadingBar &lb,int level,int mag_min,
int mag_range,int mag_steps);
~SpecialZoneArray(void);
protected:
//! Get an array of all SpecialZoneData objects in this catalog.
SpecialZoneData<Star> *getZones(void) const
{ {
if (is_inside ? prj->project(s->getJ2000Pos(z,movementFactor return static_cast<SpecialZoneData<Star>*>(zones);
),xy) : prj->projectCheck(s->getJ2000Pos(z,movementFactor),xy))
{
if (drawer->drawPointSource(xy[0],xy[1],rcmag_table
+ 2*(s->mag),s->bV)==false)
{
break;
}
if (s->mag < maxMagStarName)
{
const QString starname = s->getNameI18n();
if (!starname.isEmpty())
{
const float offset = (rcmag_table +
2*(s->mag))[0]*0.7;
const Vec3f& colorr = (StelApp::getI
nstance().getVisionModeNight() ? Vec3f(0.8, 0.2, 0.2) : SkyDrawer::indexToC
olor(s->bV))*0.75;
glColor4f(colorr[0], colorr[1], colo
rr[2],names_brightness);
prj->drawText(starFont,xy[0],xy[1],
starname, 0, offset, offset, false);
}
}
}
} }
}
template<class Star> //! Draw stars and their names onto the viewport.
void SpecialZoneArray<Star>::searchAround(int index,const Vec3d &v, //! @param index zone index to draw
double cosLimFov, //! @param is_inside whether the zone is inside the current viewport
QList<StelObjectP > &result) { //! @param rcmag_table table of magnitudes
const double d2000 = 2451545.0; //! @param prj projector to draw on
const double movementFactor = (M_PI/180)*(0.0001/3600) //! @param maxMagStarName magnitude limit of stars that display labe
* ((StarMgr::getCurrentJDay()-d2000)/365.25) ls
/ star_position_scale; //! @param names_brightness brightness of labels
const SpecialZoneData<Star> *const z = getZones()+index; //! @param starFont font of labels
for (int i=0;i<z->size;i++) { void draw(int index,bool is_inside,
if (z->getStars()[i].getJ2000Pos(z,movementFactor)*v >= cosLimFov) { const float *rcmag_table, const StelProjectorP& prj,
// TODO: do not select stars that are too faint to display unsigned int maxMagStarName,float names_brightness,
result.push_back(z->getStars()[i].createStelObject(this,z)); StelFont *starFont) const;
}
} void scaleAxis(void);
} void searchAround(int index,const Vec3d &v,double cosLimFov,
QList<StelObjectP > &result);
Star *stars;
private:
uchar *mmap_start;
#ifdef WIN32
HANDLE mapping_handle;
#endif
};
//! @class HipZoneArray
//! ZoneArray of Hipparcos stars. It's just a SpecialZoneArray<Star1> that
//! implements updateHipIndex(HipIndexStruct).
class HipZoneArray : public SpecialZoneArray<Star1>
{
public:
HipZoneArray(QFile* file,bool byte_swap,bool use_mmap,StelLoadingBar
&lb,
int level,int mag_min,int mag_range,int mag_steps)
: SpecialZoneArray<Star1>(file,byte_swap,use_mmap,lb
,level,
mag_min,mag_range,mag_step
s) {}
//! Add Hipparcos information for all stars in this catalog into @em
hipIndex.
//! @param hipIndex array of Hipparcos info structs
void updateHipIndex(HipIndexStruct hipIndex[]) const;
};
} // namespace BigStarCatalogExtension } // namespace BigStarCatalogExtension
#endif // _ZONEARRAY_HPP_ #endif // _ZONEARRAY_HPP_
 End of changes. 21 change blocks. 
381 lines changed or deleted 170 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/