#ifndef __LEDSTABLES_H__ #define __LEDSTABLES_H__ #include "datalib.h" #include "ledsdata.h" // (Steve) #include #include using namespace std; #include "genlib.h" #include "ledsedgeuse.h" #include "ledsface.h" #include "ledsvertex.h" #ifdef __OS_IRIX__ #include #include #endif class CLEDSliteEdgeUse; class CLEDSliteFace; class CLEDSliteVertex; class CLEDSGeometry; extern UINT_32 g_uiPartitionsRequested; extern UINT_32 g_uiNumBuckets; //#define RESORTABLE //#define SHOWSIZES //#define SHOWSIZES2 //#define QUIET // Change to eliminate VIDTable use; improves performance only if files // are quite big. Hasn't been tested in undefined configuration with // more recent changes (e.g. CHANGE_C), won't work undefined with // CHANGE_D defined. #define CHANGE_TWO // Change to insert edges in list immediately upon identifying them // (Despite eliminating intermediate edge table, this makes performance worse) //#define CHANGE_SIX // Change to copy over original VEU table that was in EU order //#define CHANGE_SEVEN // Change to partition EUNVETable #define CHANGE_B // Change to do both translation steps at once if possible #define CHANGE_C // Change to do bucket sort of vertices by Z-coordinate // won't work if CHANGE_2 not defined also // Need to change so that this isn't called if user didn't call slicer w/ // -b option. #define CHANGE_D // Change F is mostly in list.h, allowing initialization of entire link buffer // for lists of known size. No ifdef for it right now. // It gave a speedup of about 3%. // Change G is moving initialization of lists to BuildLists function. int lidPrCompareBoth(const void *arg1, const void *arg2); //inline int lidCompare(const void *arg1, const void *arg2); //inline int lidPrCompare1st(const void *arg1, const void *arg2); //inline int lidPrCompare2nd(const void *arg1, const void *arg2); inline int lidCompare(const void *arg1, const void *arg2) { LID lid1 = *((LID *)arg1); LID lid2 = *((LID *)arg2); if (lid1 < lid2) { return (-1); } else //if (lid1 > lid2) { return (1); } /* else { return (0); } */ } // What I'd prefer is to template PrCompare1st on what we're casting to, but // certain compilers don't seem to be able to deal with that. // CC wants the types we're templating on to appear in the arg list; // g++ doesn't like the way I instantiate the templated function. inline int lidPrCompare1st(const void *arg1, const void *arg2) { LID lid1 = ((Pair *) arg1)->GetFirst(); LID lid2 = ((Pair *) arg2)->GetFirst(); if (lid1 < lid2) { return (-1); } else //if (lid1 > lid2) { return (1); } /* else { return (0); } */ } inline int lidPrCompare2nd(const void *arg1, const void *arg2) { LID lid1 = ((Pair *) arg1)->GetSecond(); LID lid2 = ((Pair *) arg2)->GetSecond(); if (lid1 < lid2) { return (-1); } else //if (lid1 > lid2) { return (1); } /* else { return (0); } */ } inline int TripleCompare2ndZ(const void *arg1, const void *arg2) { Triple vid1 = ((Triple,Triple > *) arg1)->GetSecond(); Triple vid2 = ((Triple,Triple > *) arg2)->GetSecond(); if (vid1.GetThird() < vid2.GetThird()) { return (-1); } else //if (vid1 > vid2) { return (1); } /* else { return (0); } */ } template class CLEDSTables { ////////////////////////////////////////////////// // Initialization // public: inline CLEDSTables(); inline ~CLEDSTables(); inline VOID PreInit(CLEDSGeometry *, BOOL bPrevPtrs); inline VOID Uninit(); ////////////////////////////////////////////////// // Input functions // public: // these functions all add appropriate ptr from 1st thing to 2nd, // e.g. AddFaceOC adds a ptr from a Face to an Outer Contour (OC). inline VOID AddFaceOC(LID, LID); #ifdef GENERAL_FACES inline VOID AddFaceIC(LID, LID); #endif inline VOID AddEUFace(LID, LID); inline VOID AddEUNextContEU(LID, LID); #ifndef CHANGE_B inline VOID AddEUNextVtxEU(LID, LID); #else inline VOID AddEUNextVtxEU(UINT_32, LID, LID); #endif inline UINT_32 AddVertex(VID *); // add an edge with this LID between the vertices with these VIDs #ifndef CHANGE_TWO inline VOID AddEdge(LID, UINT_32, UINT_32); #else inline VOID AddEdge(LID, VID *, VID *); #endif ////////////////////////////////////////////////// // Other functions // public: inline VOID Process(CLEDSliteEdgeUse **); inline VOID UpdateEUTables(); inline VOID BuildEUs(CLEDSliteEdgeUse **, CLEDSliteVertex **, CLEDSliteFace **); inline VOID BuildFaces(CLEDSliteFace **, CLEDSliteEdgeUse **); inline VOID BuildVertices(CLEDSliteVertex **, CLEDSliteEdgeUse **, CLEDSliteFace **); #ifdef CHANGE_G inline VOID BuildLists(CLEDSliteEdgeUse **, CLEDSliteVertex **, CLEDSliteFace **); #endif private: inline UINT_32 EstimatePartitions(); inline UINT_32 EstimateEdgePartitions(); #ifndef CHANGE_D inline UINT_32 GetPartition(VID *); #else inline UINT_32 GetPartition(VID *, FLOAT *); #endif inline UINT_32 GetEdgePartition(LID, LID); inline VOID AllocateFullyTranslated(); inline LID LookUpVtx(VID, COpenHashTable *); // COpenHashTable *BuildVIDHashPartition(DataFile *); inline COpenHashTable *InitVIDHashPartition(UINT_32); #ifdef CHANGE_D inline UINT_32 FindBucket(FLOAT fZ); inline VOID BucketSort(); inline UINT_32 DivideBucket(UINT_32, FLOAT *, UINT_32, UINT_32 *, UINT_32); inline FLOAT *CalculatePartitionLimits(); #endif #ifndef CHANGE_D #ifndef CHANGE_TWO inline VOID Translate1stVID(COpenHashTable *, DataPairFile, LID, LID> *, DataTripleFile, LID, UINT_32, UINT_32 > *, UINT_32); #else inline VOID Translate1stVID(COpenHashTable *, DataPairFile, LID, LID> *, DataTripleFile, LID,VID,VID> *, UINT_32); #endif #else inline UINT_32 Translate1stVID(COpenHashTable *, DataPairFile, LID, LID> *, UINT_32, UINT_32, FLOAT *); #endif #ifndef CHANGE_TWO inline VOID Translate2ndVID(COpenHashTable *, DataTripleFile, LID, LID, UINT_32 > *); #else inline VOID Translate2ndVID(COpenHashTable *, DataTripleFile, LID,LID,VID> *); #endif inline VOID FindSiblings(DataPairFile, LID, LID> *, DataTripleFile, LID, LID, LID > *, CLEDSliteEdgeUse **); inline VOID SortTables(); ////////////////////////////////////////////////// // Output Functions // public: #ifdef LEDSDEBUG inline VOID PrintTables() const; inline VOID PrintSortedTables() const; #endif //inline LID GetLIDcount() const; inline UINT_32 GetEUcount() const; inline UINT_32 GetFaceCount() const; inline UINT_32 GetICcount() const; inline UINT_32 GetVtxCount() const; #ifdef GENERAL_FACES inline DataPairFile, LID, LID> *GetEUFTable() const; inline DataPairFile, LID, LID> *GetEUNCETable() const; inline DataPairFile, LID, LID> *GetFOCTable() const; inline DataPairFile, LID, LID> *GetFICTable() const; #endif //inline DataPairFile, LID, LID> *GetVEUTable() const; //inline DataPairFile, LID, LID> *GetEUVTableBackwards() const; //inline DataPairFile, LID, LID> *GetEUSibTable() const; //inline DataPairFile, LID, VID> *GetLIDVIDTable() const; inline DataFile *GetLIDVIDTable() const; inline DataFile *GetEdgeTable() const; ////////////////////////////////////////////////// // Member Variables // protected: CLEDSGeometry *m_pCLEDSGeometry; UINT_32 m_uiEUcount; UINT_32 m_uiFaceCount; UINT_32 m_uiICcount; UINT_32 m_uiVtxCount; UINT_32 m_uiPartitions; UINT_32 m_uiEdgePartitions; size_t m_sizeEU; BOOL m_bPrevPtrs; // tables for translated LID to LID relationships // Edge Use to Next Vertex Edge use #ifndef CHANGE_B DataPairFile, LID, LID> *m_plidPrEUNVETable; #else DataPairFile, LID, LID> **m_pplidPrEUNVETables; #endif #ifdef GENERAL_FACES // Edge Use to Face DataPairFile, LID, LID> *m_plidPrEUFTable; // Edge Use to Next in Countour Edge use DataPairFile, LID, LID> *m_plidPrEUNCETable; // Face to Outer Contour edge use DataPairFile, LID, LID> *m_plidPrFOCTable; // Face to Inner Contour edge use // (may be multiple that need to be put in list) DataPairFile, LID, LID> **m_plidPrFICTables; #endif // Vertex to all Edge Uses DataPairFile, LID, LID> **m_pplidPrVEUTables; // Edge Use to root Vertex // Actual table derived by re-sorting above DataPairFile, LID, LID> **m_pplidPrEUVTablesBackwards; // Edge Use to Sibling edge Use DataPairFile, LID, LID> **m_pplidPrEUSibTables; // for storing VIDs after their LIDs are assigned // DataPairFile, LID, VID> *m_pLIDVIDTable; DataFile *m_pLIDVIDTable; // For storing all the VIDs before their LIDs are assigned // DataFile **m_ppVIDTables; #ifndef CHANGE_TWO DataFile *m_pVIDTable; #endif // Hash tables for Vertex IDs (VIDs) divided into partitions COpenHashTable **m_ppVIDHashTables; // For storing an EU LID per edge DataFile *m_pEdgeTable; // tables for untranslated and partially translated relationship data // (divided into partitions) #ifndef CHANGE_TWO DataTripleFile,LID,UINT_32,UINT_32> **m_ppEUuntranslatedVdata; DataTripleFile,LID,LID,UINT_32> **m_ppEUsemitranslatedVdata; #else DataTripleFile,LID,VID,VID> **m_ppEUuntranslatedVdata; DataTripleFile,LID,LID,VID> **m_ppEUsemitranslatedVdata; #endif #ifdef CHANGE_D // DataTripleFile,LID,VID,VID> *m_pEUuntranslatedVdata; DataFile *m_pEUuntranslatedVdata; #endif DataTripleFile,LID,LID,LID> **m_ppEUfullytranslatedVdata; // Hash table for edges not divided into partitions COpenHashTable, Pair > *m_pedgeHashTablePart; #ifdef CHANGE_D FLOAT m_fMaxZ, m_fMinZ, m_fBucketSize; #endif }; template inline UINT_32 CLEDSTables::GetEUcount() const { return m_uiEUcount; } template inline UINT_32 CLEDSTables::GetFaceCount() const { return m_uiFaceCount; } template inline UINT_32 CLEDSTables::GetICcount() const { return m_uiICcount; } template inline UINT_32 CLEDSTables::GetVtxCount() const { return m_uiVtxCount; } #ifdef GENERAL_FACES template inline DataPairFile, LID, LID> * CLEDSTables::GetEUFTable() const { return m_plidPrEUFTable; } template inline DataPairFile, LID, LID> * CLEDSTables::GetEUNCETable() const { return m_plidPrEUNCETable; } template inline DataPairFile, LID, LID> * CLEDSTables::GetFOCTable() const { return m_plidPrFOCTable; } template inline DataPairFile, LID, LID> * CLEDSTables::GetFICTable() const { return m_plidPrFICTable; } #endif /* template inline DataPairFile, LID, LID> * CLEDSTables::GetVEUTable() const { return m_plidPrVEUTable; } template inline DataPairFile, LID, LID> * CLEDSTables::GetEUVTableBackwards() const { return m_plidPrEUVTableBackwards; } template inline DataPairFile, LID, LID> * CLEDSTables::GetEUSibTable() const { return m_plidPrEUSibTable; } */ //inline DataPairFile, LID, VID> * template inline DataFile *CLEDSTables::GetLIDVIDTable() const { return m_pLIDVIDTable; } template inline DataFile *CLEDSTables::GetEdgeTable() const { return m_pEdgeTable; } ////////////////////////////////////////////////////////////////////////////// // CLEDStables Class methods // template inline CLEDSTables::CLEDSTables() { m_uiEUcount = 0; m_uiFaceCount = 0; m_uiICcount = 0; m_uiVtxCount = 0; m_uiPartitions = 1; m_uiEdgePartitions = 1; m_sizeEU = 0; m_bPrevPtrs = FALSE; #ifndef CHANGE_B m_plidPrEUNVETable = NULL; #else m_pplidPrEUNVETables = NULL; #endif #ifdef GENERAL_FACES m_plidPrEUFTable = NULL; m_plidPrEUNCETable = NULL; m_plidPrFOCTable = NULL; m_plidPrFICTable = NULL; #endif m_pplidPrVEUTables = NULL; m_pplidPrEUVTablesBackwards = NULL; m_pplidPrEUSibTables = NULL; m_pLIDVIDTable = NULL; #ifndef CHANGE_TWO m_pVIDTable = NULL; #endif m_ppEUuntranslatedVdata = NULL; #ifdef CHANGE_D m_pEUuntranslatedVdata = NULL; #endif m_ppEUsemitranslatedVdata = NULL; m_ppEUfullytranslatedVdata = NULL; m_ppVIDHashTables = NULL; m_pedgeHashTablePart = NULL; m_pEdgeTable = NULL; } template inline CLEDSTables::~CLEDSTables() { Uninit(); } // Allocate all the tables that will be filled in while reading the // original file. template inline VOID CLEDSTables::PreInit(CLEDSGeometry *pCLEDSGeometry, BOOL bPrevPtrs) { m_pCLEDSGeometry = pCLEDSGeometry; m_bPrevPtrs = bPrevPtrs; if (m_bPrevPtrs) { m_sizeEU = sizeof(CLEDSEdgeUsePrev); } else { m_sizeEU = sizeof(CLEDSliteEdgeUse); } // Initialize with arbitrary (but small) amount of storage. // UINT_32 uiFacesGuess = 8; // UINT_32 uiFacesGuess = 20000; UINT_32 uiFacesGuess = 8192 * m_uiPartitions; UINT_32 uiEUsGuess = 3 * uiFacesGuess; #ifdef GENERAL_FACES // allocate minimal space for inner contour storage since there may be none UINT_32 uiICsGuess = 1; m_plidPrEUFTable = new DataPairFile, LID, LID>; m_plidPrEUFTable->Init(uiEUsGuess); m_plidPrEUNCETable = new DataPairFile, LID, LID>; m_plidPrEUNCETable->Init(uiEUsGuess); m_plidPrFOCTable = new DataPairFile, LID, LID>; m_plidPrFOCTable->Init(uiFacesGuess); m_plidPrFICTable = new DataPairFile, LID, LID>; m_plidPrFICTable->Init(uiICsGuess); #endif // AddEdge fills m_ppVIDTables and m_ppEUuntranslatedVdata, // so pre-allocate them here m_uiPartitions = EstimatePartitions(); m_uiEdgePartitions = EstimateEdgePartitions(); #ifndef CHANGE_TWO m_pVIDTable = new DataFile; m_ppEUuntranslatedVdata = new DataTripleFile, LID, UINT_32, UINT_32 > *[m_uiPartitions]; #else // CHANGE_TWO #ifndef CHANGE_D m_ppEUuntranslatedVdata = new DataTripleFile,LID,VID,VID> *[m_uiPartitions]; #else //CHANGE_D m_ppEUuntranslatedVdata = new DataTripleFile,LID,VID,VID> *[g_uiNumBuckets]; #endif //CHANGE_D #endif // CHANGE_TWO #ifndef CHANGE_TWO m_pVIDTable->Init(uiEUsGuess); #endif // CHANGE_TWO UINT_32 i; for (i = 0; i < m_uiPartitions; i++) { #ifndef CHANGE_TWO #ifndef CHANGE_D m_ppEUuntranslatedVdata[i] = new DataTripleFile, LID, UINT_32, UINT_32 >; #endif //CHANGE_D #else // CHANGE_TWO #ifndef CHANGE_D m_ppEUuntranslatedVdata[i] = new DataTripleFile,LID,VID,VID>; #endif //CHANGE_D #endif // CHANGE_TWO #ifndef CHANGE_D m_ppEUuntranslatedVdata[i]->Init(uiEUsGuess/m_uiPartitions); #endif //CHANGE_D } #ifdef CHANGE_D m_pEUuntranslatedVdata = new DataFile; // DataTripleFile,LID,VID,VID>; m_pEUuntranslatedVdata->Init(uiEUsGuess); for (i = 0; i < g_uiNumBuckets; i++) { m_ppEUuntranslatedVdata[i] = new DataTripleFile,LID,VID,VID>; m_ppEUuntranslatedVdata[i]->Init(uiEUsGuess/g_uiNumBuckets); // What was this old initialization based upon?!? // m_ppEUuntranslatedVdata[i]->Init(64 * m_uiPartitions); } m_fMaxZ = -FLT_MAX; m_fMinZ = FLT_MAX; m_fBucketSize = 0; #endif //CHANGE_D } template inline VOID CLEDSTables::Uninit() { #ifdef GENERAL_FACES if (m_plidPrEUFTable) delete m_plidPrEUFTable; if (m_plidPrEUNCETable) delete m_plidPrEUNCETable; if (m_plidPrFOCTable) delete m_plidPrFOCTable; if (m_plidPrFICTable) delete m_plidPrFICTable; #endif if (m_pLIDVIDTable) delete m_pLIDVIDTable; UINT_32 i; for (i = 0; i < m_uiPartitions; i++) { // if (m_ppVIDTables) // delete m_ppVIDTables[i]; if (m_pplidPrVEUTables) delete m_pplidPrVEUTables[i]; if (m_pplidPrEUVTablesBackwards) delete m_pplidPrEUVTablesBackwards[i]; if (m_pplidPrEUSibTables) delete m_pplidPrEUSibTables[i]; #ifndef CHANGE_D if (m_ppEUuntranslatedVdata) delete m_ppEUuntranslatedVdata[i]; #endif if (m_ppEUsemitranslatedVdata) delete m_ppEUsemitranslatedVdata[i]; if (m_ppVIDHashTables) delete m_ppVIDHashTables[i]; #ifdef CHANGE_B if (m_pplidPrEUNVETables) delete m_pplidPrEUNVETables[i]; #endif } for (i = 0; i < m_uiEdgePartitions; i++) { if (m_ppEUfullytranslatedVdata) delete m_ppEUfullytranslatedVdata[i]; } #ifdef CHANGE_D if (m_ppEUuntranslatedVdata) { for (i = 0; i < g_uiNumBuckets; i++) { delete m_ppEUuntranslatedVdata[i]; } } #endif #ifndef CHANGE_B if (m_plidPrEUNVETable) delete m_plidPrEUNVETable; #else if (m_pplidPrEUNVETables) delete [] m_pplidPrEUNVETables; #endif if (m_pplidPrVEUTables) delete [] m_pplidPrVEUTables; if (m_pplidPrEUVTablesBackwards) delete [] m_pplidPrEUVTablesBackwards; if (m_pplidPrEUSibTables) delete [] m_pplidPrEUSibTables; #ifndef CHANGE_TWO if (m_pVIDTable) delete m_pVIDTable; #endif if (m_ppEUuntranslatedVdata) delete [] m_ppEUuntranslatedVdata; if (m_ppEUsemitranslatedVdata) delete [] m_ppEUsemitranslatedVdata; if (m_ppEUfullytranslatedVdata) delete [] m_ppEUfullytranslatedVdata; if (m_ppVIDHashTables) delete [] m_ppVIDHashTables; if (m_pedgeHashTablePart) delete m_pedgeHashTablePart; if (m_pEdgeTable) delete m_pEdgeTable; } template inline VOID CLEDSTables::AddEUFace(LID lidEU, LID lidFace) { m_plidPrEUFTable->AddPair(lidEU, lidFace); } template inline VOID CLEDSTables::AddEUNextContEU(LID lidEU, LID lidNextContEU) { m_plidPrEUNCETable->AddPair(lidEU, lidNextContEU); } #ifndef CHANGE_B template inline VOID CLEDSTables::AddEUNextVtxEU(LID lidEU, LID lidNextVtxEU) { m_plidPrEUNVETable->AddPair(lidEU, lidNextVtxEU); } #else template inline VOID CLEDSTables::AddEUNextVtxEU(UINT_32 uiPartition, LID lidEU, LID lidNextVtxEU) { m_pplidPrEUNVETables[uiPartition]->AddPair(lidEU, lidNextVtxEU); } #endif template inline VOID CLEDSTables::AddFaceOC(LID lidFace, LID lidEU) { #ifdef GENERAL_FACES m_plidPrFOCTable->AddPair(lidFace, lidEU); #endif m_uiFaceCount++; } #ifdef GENERAL_FACES template inline VOID CLEDSTables::AddFaceIC(LID lidFace, LID lidEU) { m_plidPrFICTable->AddPair(lidFace, lidEU); m_uiICcount++; } #endif template inline UINT_32 CLEDSTables::AddVertex(VID *pvid) { #ifndef CHANGE_TWO return (m_pVIDTable->AddItem(*pvid)); #endif } #ifndef CHANGE_TWO template inline VOID CLEDSTables::AddEdge(LID lidEU, UINT_32 uiVtx1, UINT_32 uiVtx2) { // UINT_32 partition = GetPartition(pvid1); UINT_32 partition = GetPartition(m_pVIDTable->GetItem(uiVtx1)); m_uiEUcount++; m_ppEUuntranslatedVdata[partition]->AddTriple(lidEU, uiVtx1, uiVtx2); } #else template inline VOID CLEDSTables::AddEdge(LID lidEU, VID *pvid1, VID *pvid2) { #ifndef CHANGE_D UINT_32 partition = GetPartition(pvid1); m_ppEUuntranslatedVdata[partition]->AddTriple(lidEU, *pvid1, *pvid2); #else float fCurZ = pvid1->GetThird(); if (fCurZ > m_fMaxZ) { m_fMaxZ = fCurZ; } else if (fCurZ < m_fMinZ) { m_fMinZ = fCurZ; } // m_pEUuntranslatedVdata->AddTriple(lidEU, *pvid1, *pvid2); m_pEUuntranslatedVdata->AddItem(*pvid1); #endif m_uiEUcount++; } #endif template inline UINT_32 CLEDSTables::EstimatePartitions() { // use 's getrlimit( RLIMIT_RSS, struct rlimit*) // to find limit on regular set size and set partitions? // Hmm, lockable pages are smaller than RSS limit. if (g_uiPartitionsRequested == 0) return (3); else return (g_uiPartitionsRequested); } template inline UINT_32 CLEDSTables::EstimateEdgePartitions() { UINT_32 uiPartitions = EstimatePartitions(); return (uiPartitions*2); } #ifndef CHANGE_D template inline UINT_32 CLEDSTables::GetPartition(VID *pvid) { UINT_32 ui = Hash(*pvid) % m_uiPartitions; return (ui); } #else template inline UINT_32 CLEDSTables::GetPartition(VID *pvid, FLOAT *pfMaxZ) { UINT_32 i; FLOAT fZ = pvid->GetThird(); if (fZ < pfMaxZ[0]) return 0; for (i = 1; i < m_uiPartitions; i++) { if ((fZ < pfMaxZ[i]) && (fZ >= pfMaxZ[i - 1])) return i; } ASSERT(FALSE); return 0; } #endif template inline UINT_32 CLEDSTables::GetEdgePartition(LID lid1, LID lid2) { // UINT_32 ui = ((UINT_64)lid1 + (UINT_64)lid2)%(UINT_64)m_uiEdgePartitions; UINT_32 ui = (lid1 + lid2)%m_uiEdgePartitions; return (ui); } // Assigns LIDs to the VIDs via the hash table (partition) it builds up template inline COpenHashTable * CLEDSTables::InitVIDHashPartition (UINT_32 uiNumEUs) { COpenHashTable *HashPartition = new COpenHashTable; // average vtx order is 6, but want some free space in the hash table HashPartition->Init(uiNumEUs/4); #ifdef SHOWSIZES size_t size = sizeof(*(HashPartition->GetData())); fprintf(stdout, "Vertex Hash Partition initialized with %d entries\n", (pEUVdataPartition->GetCurrentIndex())/4); fprintf(stdout, "Vertex Hash Partition sizeof is %d\n", size); #endif return (HashPartition); } template inline LID CLEDSTables:: LookUpVtx(VID vidToTranslate, COpenHashTable *pVIDHashTablePartition) { LID lidCurV, lidNew, *plidRetrieved; plidRetrieved = pVIDHashTablePartition->Peek(vidToTranslate); if (!plidRetrieved) { m_uiVtxCount++; lidNew = m_pCLEDSGeometry->GetLIDmapVtx()->GetNewLID(); // The LIDs are assigned sequentially, so we don't bother to // record them in the list of all unique VIDs. m_pLIDVIDTable->AddItem(vidToTranslate); pVIDHashTablePartition->Insert(&lidNew, vidToTranslate); lidCurV = lidNew; } else { lidCurV = *plidRetrieved; } return lidCurV; } #ifdef CHANGE_D template inline UINT_32 CLEDSTables::FindBucket(FLOAT fZ) { UINT_32 uiBucket; uiBucket = (UINT_32)((fZ - m_fMinZ)/m_fBucketSize); if (uiBucket == g_uiNumBuckets) { uiBucket--; } return (uiBucket); } template inline VOID CLEDSTables::BucketSort() { VID vidToTranslate; #ifndef CHANGE_TWO UINT_32 uiVtxToTranslate; Triple *pTripleCur; DataFileIter > TripleIter; #else Triple Triple;//1, pTriple2, pTriple3; // DataFileIter > TripleIter; VID *pvid1, *pvid2, *pvid3; DataFileIter TripleIter; #endif // UINT_32 uiBucket; UINT_32 uiBucket1, uiBucket2, uiBucket3; LID lidEU; m_fBucketSize = (m_fMaxZ - m_fMinZ)/((FLOAT)g_uiNumBuckets); /* TripleIter.Init(m_pEUuntranslatedVdata); // pTripleCur = TripleIter.PeekLastItem(); // do { while (TripleIter.Valid()) { // lookup & translate the first VID in the EU,VID,VID triples pTripleCur = TripleIter.PeekNextItem(); #ifndef CHANGE_TWO uiVtxToTranslate = pTripleCur->GetSecond(); vidToTranslate = *(m_pVIDTable->GetItem(uiVtxToTranslate)); #else vidToTranslate = pTripleCur->GetSecond(); #endif uiBucket = (UINT_32)((vidToTranslate.GetThird() - m_fMinZ)/fBucketSize); if (uiBucket == g_uiNumBuckets) { uiBucket--; } else { ASSERT (vidToTranslate.GetThird() <= (m_fMinZ + (fBucketSize * (FLOAT)(uiBucket+1)))); } m_ppEUuntranslatedVdata[uiBucket]->AddItem(*pTripleCur); // pTripleCur = TripleIter.PeekPrevItem(); //} while (TripleIter.Valid()); } */ TripleIter.Init(m_pEUuntranslatedVdata); lidEU = 1; while (lidEU < m_uiEUcount) { pvid1 = TripleIter.PeekNextItem(); pvid2 = TripleIter.PeekNextItem(); pvid3 = TripleIter.PeekNextItem(); uiBucket1 = FindBucket(pvid1->GetThird()); uiBucket2 = FindBucket(pvid2->GetThird()); uiBucket3 = FindBucket(pvid3->GetThird()); Triple.SetFirst(lidEU++); Triple.SetSecond(*pvid1); Triple.SetThird(*pvid2); m_ppEUuntranslatedVdata[uiBucket1]->AddItem(Triple); Triple.SetFirst(lidEU++); Triple.SetSecond(*pvid2); Triple.SetThird(*pvid3); m_ppEUuntranslatedVdata[uiBucket2]->AddItem(Triple); Triple.SetFirst(lidEU++); Triple.SetSecond(*pvid3); Triple.SetThird(*pvid1); m_ppEUuntranslatedVdata[uiBucket3]->AddItem(Triple); } delete m_pEUuntranslatedVdata; } // Tries to find a z-value that divides bucket such that there are // uiTargetSize values less than that z. Records Z in pMax[uiPartition], // and returns number of items over that z. template inline UINT_32 CLEDSTables::DivideBucket (UINT_32 uiCurBucket, FLOAT *pMax, UINT_32 uiPartition, UINT_32 *puiNumProcessed, UINT_32 uiTargetSize) { Triple *pTriple; FLOAT fZ; UINT_32 ui, uiSize; m_ppEUuntranslatedVdata[uiCurBucket]->Sort(TripleCompare2ndZ); pTriple = m_ppEUuntranslatedVdata[uiCurBucket]->GetItem(uiTargetSize); fZ = pTriple->GetSecond().GetThird(); pMax[uiPartition] = fZ; uiSize = m_ppEUuntranslatedVdata[uiCurBucket]->GetCurrentIndex(); for (ui = uiTargetSize+1; ui < uiSize; ui++) { pTriple = m_ppEUuntranslatedVdata[uiCurBucket]->GetItem(ui); if (pTriple->GetSecond().GetThird() > fZ) break; } *puiNumProcessed += ui; return (uiSize - ui); } // Figures out how buckets should be divided into partitions. // Tries to divide on bucket boundaries, but if that's too lop-sided, // divides buckets between partitions. // Returns an array of the max Z value for each partition. template inline FLOAT *CLEDSTables::CalculatePartitionLimits() { UINT_32 i, uiNumProcessed, uiTargetNumProcessed, uiTolerance; UINT_32 uiTargetSize, uiCurBucket, uiCurBucketSize; FLOAT *pMax; pMax = new FLOAT [m_uiPartitions]; uiNumProcessed = 0; uiCurBucket = 0; uiTargetSize = (m_uiEUcount/m_uiPartitions); //TODO: make sure double/uint32 conversion below is as expected. // uiTolerance = 1 + (uiTargetSize * .1); // the tolerance is on both sides, uiTolerance = 1 + (UINT_32)((FLOAT)uiTargetSize * .1); ASSERT(uiTolerance == 1 + (uiTargetSize * .1)); // so the total size of the partition could be off by .2 from target uiCurBucketSize = m_ppEUuntranslatedVdata[uiCurBucket]->GetCurrentIndex(); for (i = 0; i < m_uiPartitions - 1; i++) { uiTargetNumProcessed = (i + 1) * uiTargetSize; while (uiNumProcessed < uiTargetNumProcessed) { uiNumProcessed += uiCurBucketSize; if (uiNumProcessed > (uiTargetNumProcessed + uiTolerance)) { uiNumProcessed -= uiCurBucketSize; break; } uiCurBucket++; uiCurBucketSize = m_ppEUuntranslatedVdata[uiCurBucket]->GetCurrentIndex(); } if (uiNumProcessed < (uiTargetNumProcessed - uiTolerance)) { uiCurBucketSize = DivideBucket(uiCurBucket, pMax, i, &uiNumProcessed, uiTargetNumProcessed - uiNumProcessed); } else { pMax[i] = m_fMinZ + (m_fBucketSize * (FLOAT)uiCurBucket); // roundoff error possibility here - // some entries in the last bucket may be equal to or slightly greater // than pMax calculated here. If so, those entries will go in next // partition by mistake and the partition sizes won't be calculated // quite correctly here, but nothing should get lost. (See comment // in Translate1stVID.) } } // The interval for each partition is closed on the low end and open // on the right end: i-th partition is [pMax[i-1], pMax[i]). // Except for the last partition, [pMax[i-1], m_fMaxZ], but we // record a higher value than m_fMaxZ so we don't have a special case. pMax[m_uiPartitions - 1] = m_fMaxZ + 1; return pMax; } #endif // This is the old one with CHANGE_TWO option -- too hard to keep track // with CHANGE_D too, so assume that CHANGE_TWO is defined for new one. #ifndef CHANGE_D template inline VOID CLEDSTables:: Translate1stVID(COpenHashTable *pVIDHashTablePartition, DataPairFile, LID, LID> *plidPrVEUTable, #ifndef CHANGE_TWO // DataTripleFile,LID,UINT_32,UINT_32> *pEUVIDVIDdata, // UINT_32 uiCurPartition) #else DataTripleFile, LID,VID,VID> *pEUVIDVIDdata, UINT_32 uiCurPartition) #endif { LID lidCurV, lidEU; VID vidToTranslate; #ifndef CHANGE_TWO UINT_32 uiVtxToTranslate, uiVtxToPartition; Triple *pTripleCur; DataFileIter > TripleIter; #else VID vidToPartition; Triple *pTripleCur; DataFileIter > TripleIter; #endif #ifdef CHANGE_C LID lidNextV; #endif UINT_32 partition; #ifndef QUIET Timer timer; timer.Start(); #endif TripleIter.Init(pEUVIDVIDdata); while (TripleIter.Valid()) { // lookup & translate the first VID in the EU,VID,VID triples pTripleCur = TripleIter.PeekNextItem(); #ifndef CHANGE_TWO uiVtxToTranslate = pTripleCur->GetSecond(); vidToTranslate = *(m_pVIDTable->GetItem(uiVtxToTranslate)); #else vidToTranslate = pTripleCur->GetSecond(); #endif lidCurV = LookUpVtx(vidToTranslate, pVIDHashTablePartition); // append EU,Vtx LIDs to the m_plidPrVEUTable lidEU = pTripleCur->GetFirst(); plidPrVEUTable->AddPair(lidCurV, lidEU); // append EU,LID,VID to the appropriate partition of semitranslated tables // OR if to same partition, translate next ID as well and output to // fullytranslated tables. #ifndef CHANGE_TWO uiVtxToPartition = pTripleCur->GetThird(); partition = GetPartition(m_pVIDTable->GetItem(uiVtxToPartition)); #ifdef CHANGE_C if (partition == uiCurPartition) { vidToPartition = *(m_pVIDTable->GetItem(uiVtxToPartition)); lidNextV = LookUpVtx(vidToPartition, pVIDHashTablePartition); // write out into appropriate fully translated partition partition = GetEdgePartition (lidNextV, lidCurV); m_ppEUfullytranslatedVdata[partition]-> AddTriple(lidEU, lidCurV,lidNextV); } else #endif // #ifdef CHANGE_C m_ppEUsemitranslatedVdata[partition]-> AddTriple(lidEU, lidCurV, uiVtxToPartition ); #else //#ifndef CHANGE_TWO vidToPartition = pTripleCur->GetThird(); partition = GetPartition (&vidToPartition); #ifdef CHANGE_C if (partition == uiCurPartition) { lidNextV = LookUpVtx(vidToPartition, pVIDHashTablePartition); // write out into appropriate fully translated partition partition = GetEdgePartition (lidNextV, lidCurV); m_ppEUfullytranslatedVdata[partition]-> AddTriple(lidEU, lidCurV,lidNextV); } else #endif // #ifdef CHANGE_C m_ppEUsemitranslatedVdata[partition]-> AddTriple(lidEU, lidCurV, vidToPartition); #endif //#ifndef CHANGE_TWO } #ifndef QUIET timer.Stop(); DOUBLE dfoo = timer.GetSeconds(); fprintf(stdout, "Translate1stVID took %f seconds\n", dfoo); #endif } #else // CHANGE_D template inline UINT_32 CLEDSTables:: Translate1stVID(COpenHashTable *pVIDHashTablePartition, DataPairFile, LID, LID> *plidPrVEUTable, UINT_32 uiCurBucket, UINT_32 uiCurPartition, FLOAT *pfMaxZ) { LID lidCurV, lidEU; VID vidToTranslate; VID vidToPartition; Triple *pTripleCur; DataFileIter > TripleIter; #ifdef CHANGE_C LID lidNextV; #endif UINT_32 partition; BOOL bLargerEntriesSkipped = FALSE; #ifndef QUIET Timer timer; timer.Start(); #endif TripleIter.Init(m_ppEUuntranslatedVdata[uiCurBucket]); while (uiCurBucket < g_uiNumBuckets) { while (TripleIter.Valid()) { // lookup & translate the first VID in the EU,VID,VID triple pTripleCur = TripleIter.PeekNextItem(); vidToTranslate = pTripleCur->GetSecond(); // Only need to check this more than once if bucket split, but // splitting may not be explicit if it was roundoff error induced, // so check each entry in bucket. if ((vidToTranslate.GetThird() < pfMaxZ[uiCurPartition]) && ((uiCurPartition == 0) || (vidToTranslate.GetThird() >= pfMaxZ[uiCurPartition-1]))){ lidCurV = LookUpVtx(vidToTranslate, pVIDHashTablePartition); // append EU,Vtx LIDs to the m_plidPrVEUTable lidEU = pTripleCur->GetFirst(); plidPrVEUTable->AddPair(lidCurV, lidEU); // append EU,LID,VID to appropriate partition of semitranslated tables // OR if to same partition, translate next ID as well and output to // fullytranslated tables (CHANGE_C) vidToPartition = pTripleCur->GetThird(); partition = GetPartition (&vidToPartition, pfMaxZ); #ifdef CHANGE_C if (partition == uiCurPartition) { lidNextV = LookUpVtx(vidToPartition, pVIDHashTablePartition); // write out into appropriate fully translated partition partition = GetEdgePartition (lidNextV, lidCurV); m_ppEUfullytranslatedVdata[partition]-> AddTriple(lidEU, lidCurV,lidNextV); } else #endif // #ifdef CHANGE_C m_ppEUsemitranslatedVdata[partition]-> AddTriple(lidEU, lidCurV, vidToPartition); } else { if (vidToTranslate.GetThird() >= pfMaxZ[uiCurPartition]) bLargerEntriesSkipped = TRUE; } } uiCurBucket++; // This old test didn't work due to floating point error // if (((((FLOAT)uiCurBucket)*fBucketSize) + m_fMinZ) > // pfMaxZ[uiCurPartition]) { if (bLargerEntriesSkipped) { uiCurBucket--; // some entries in here go in next partition too break; // next partition, finish off this bucket } else if (((((FLOAT)uiCurBucket)*m_fBucketSize) + m_fMinZ) == pfMaxZ[uiCurPartition]) { delete m_ppEUuntranslatedVdata[uiCurBucket - 1]; break; // next partition, new Bucket } delete m_ppEUuntranslatedVdata[uiCurBucket - 1]; TripleIter.Init(m_ppEUuntranslatedVdata[uiCurBucket]); } #ifndef QUIET timer.Stop(); DOUBLE dfoo = timer.GetSeconds(); fprintf(stdout, "Translate1stVID took %f seconds\n", dfoo); #endif return uiCurBucket; } #endif template inline VOID CLEDSTables:: AllocateFullyTranslated() { UINT_32 i; m_ppEUfullytranslatedVdata = new DataTripleFile, LID, LID, LID > *[m_uiEdgePartitions]; for (i = 0; i < m_uiEdgePartitions; i++) { m_ppEUfullytranslatedVdata[i] = new DataTripleFile, LID, LID, LID >; m_ppEUfullytranslatedVdata[i]->Init((5*m_uiEUcount)/(4*m_uiEdgePartitions)); } } template inline VOID CLEDSTables:: Translate2ndVID(COpenHashTable *pVIDHashTablePartition, #ifndef CHANGE_TWO DataTripleFile,LID,LID,UINT_32> *pEULIDVIDdata) #else DataTripleFile, LID,LID,VID> *pEULIDVIDdata) #endif { LID lidCurV, lidEU, lidOtherV; #ifndef CHANGE_TWO UINT_32 uiVtxToTranslate; Triple *pTripleCur; DataFileIter > TripleIter; #else VID vidToTranslate; Triple *pTripleCur; DataFileIter > TripleIter; #endif UINT_32 partition; TripleIter.Init(pEULIDVIDdata); while (TripleIter.Valid()) { // lookup & translate the last VID in the EU,VID,VID triples pTripleCur = TripleIter.PeekNextItem(); #ifndef CHANGE_TWO uiVtxToTranslate = pTripleCur->GetThird(); lidCurV = * (pVIDHashTablePartition->Peek (*(m_pVIDTable->GetItem(uiVtxToTranslate)))); #else vidToTranslate = pTripleCur->GetThird(); lidCurV = * (pVIDHashTablePartition->Peek(vidToTranslate)); #endif // write out into appropriate fully translated partition lidEU = pTripleCur->GetFirst(); lidOtherV = pTripleCur->GetSecond(); partition = GetEdgePartition (lidCurV, lidOtherV); m_ppEUfullytranslatedVdata[partition]-> AddTriple(lidEU, lidOtherV,lidCurV); } } template inline VOID CLEDSTables:: FindSiblings(DataPairFile, LID, LID> *plidPrEUSibTable, DataTripleFile,LID,LID,LID> *pEULIDLIDdata, CLEDSliteEdgeUse **ppEUs) { LID lidFirstV, lidSecondV, lidTemp; LID lidEUfirst, lidEUcurrent, lidEUlast; Triple *pTripleCur; Pair lidPrVtxPr, lidPrEUPr, *plidPrRetrieved; DataFileIter > TripleIter; m_pedgeHashTablePart = new COpenHashTable, Pair >; // Expect each edge to appear twice, but make hash table bigger to // keep hit rate reasonable. m_pedgeHashTablePart->Init((pEULIDLIDdata->GetCurrentIndex()*3)/4); m_pedgeHashTablePart->lock(); #ifdef SHOWSIZES size_t size = sizeof(*(m_pedgeHashTablePart->GetData())); fprintf(stdout, "Edge Hash Partition initialized with %d entries\n", (pEULIDLIDdata->GetCurrentIndex()*3)/4); fprintf(stdout, "Edge Hash Partition sizeof is %d\n", size); #ifdef SHOWSIZES2 size = sizeof(Triple); fprintf(stdout, "fully translated sizeof is %d\n", size); #endif #endif TripleIter.Init(pEULIDLIDdata); while (TripleIter.Valid()) { pTripleCur = TripleIter.PeekNextItem(); // Construct the hash key, which will be the pair of vtx LIDs // with smaller first (we're looking up undirected edge, // not directed edge use) lidFirstV = pTripleCur->GetSecond(); lidSecondV = pTripleCur->GetThird(); if (lidSecondV < lidFirstV) { lidTemp = lidFirstV; lidFirstV = lidSecondV; lidSecondV = lidTemp; } lidPrVtxPr.Init(lidFirstV, lidSecondV); // Look up the key to see what data we have for that edge plidPrRetrieved = m_pedgeHashTablePart->Peek(lidPrVtxPr); lidEUcurrent = pTripleCur->GetFirst(); // if we have data (we've seen the edge before) if (plidPrRetrieved) { lidPrEUPr = *plidPrRetrieved; lidEUfirst = lidPrEUPr.GetFirst(); lidEUlast = lidPrEUPr.GetSecond(); plidPrRetrieved->SetSecond(lidEUcurrent); // if we already have >= 2 edge uses for this edge, // add it to the chain of edge uses (assumes that // when we process the pairs that last->current will // overwrite previous last->first assignment) // WARNING: This works because we can maintain this ordering // when we sort because we process the lidEUcurrent's in // order of increasing LID. if (lidEUlast) { plidPrEUSibTable->AddPair(lidEUlast, lidEUcurrent); plidPrEUSibTable->AddPair(lidEUcurrent, lidEUfirst); } // otherwise, this is 2nd edge use. Have it point to // the first one and first one to it. else { plidPrEUSibTable->AddPair(lidEUfirst, lidEUcurrent); plidPrEUSibTable->AddPair(lidEUcurrent,lidEUfirst); } } // otherwise, this edge & edge use needs to be added to hash table else { // LID assignments should reserve zero as non-valid LID (NON_LID) lidPrEUPr.Init(lidEUcurrent, NON_LID); m_pedgeHashTablePart->Insert(&lidPrEUPr, lidPrVtxPr); // also add it to list of edges #ifndef CHANGE_SIX m_pEdgeTable->AddItem(lidEUcurrent); #else m_pCLEDSGeometry->GetCListEdges()->InsertLast ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidEUcurrent)), 0); #endif } } m_pedgeHashTablePart->unlock(); delete m_pedgeHashTablePart; m_pedgeHashTablePart = NULL; // Instead of deleting, put this edge hash table pointer into classwide // list, so that we can build a big edge hash table later. // Nope, for the moment I'm not going to worry about later so that we // get better memory usage now. // m_pCLEDSGeometry->GetCListEdgeHashTables()->InsertLast(m_pedgeHashTablePart, 0); } // After we've processed all of the vertices, update and sort the EU tables // before processing Edge Uses. template inline VOID CLEDSTables::UpdateEUTables() { int i; for (i = m_uiPartitions - 1; i >= 0; i--) { #ifndef CHANGE_SEVEN // m_pplidPrEUVTablesBackwards[i] = m_pplidPrVEUTables[i]; m_pplidPrEUVTablesBackwards[i]->Sort(lidPrCompare2nd); #endif #ifdef CHANGE_B m_pplidPrEUNVETables[i]->Sort(lidPrCompare1st); #endif } #ifndef CHANGE_B m_plidPrEUNVETable->Sort(lidPrCompare1st); #endif } template inline VOID CLEDSTables::SortTables() { UINT_32 i; // sort EUsibs, more recently created, first for (i = 0; i < m_uiPartitions; i++) { m_pplidPrEUSibTables[i]->Sort(lidPrCompareBoth); } for (i = 0; i < m_uiPartitions; i++) { #ifdef CHANGE_SEVEN // copy the VEUTable partition into a EUVTablesBackwards // so that we won't have to re-sort them later m_pplidPrEUVTablesBackwards[i] = m_pplidPrVEUTables[i]->Copy(); #else m_pplidPrEUVTablesBackwards[i] = m_pplidPrVEUTables[i]; #endif m_pplidPrVEUTables[i]->Sort(lidPrCompare1st); } } template inline VOID CLEDSTables::Process(CLEDSliteEdgeUse **ppEUs) { UINT_32 i; UINT_32 uiSize; #ifdef CHANGE_D UINT_32 uiCurBucket = 0; #endif FLOAT fFudge = 1.1f; m_pplidPrVEUTables = new DataPairFile, LID, LID> *[m_uiPartitions]; m_pplidPrEUVTablesBackwards = new DataPairFile, LID, LID> *[m_uiPartitions]; m_pLIDVIDTable = new DataFile; // Don't know the number of vertices yet, but we can make a good guess. m_pLIDVIDTable->Init((UINT_32)((FLOAT)m_uiFaceCount*.51)); #ifndef CHANGE_TWO m_ppEUsemitranslatedVdata = new DataTripleFile, LID, LID, UINT_32 > *[m_uiPartitions]; #else m_ppEUsemitranslatedVdata = new DataTripleFile,LID,LID,VID> *[m_uiPartitions]; #endif m_ppVIDHashTables = new COpenHashTable *[m_uiPartitions]; // Allocate all the semi-translated partitions before filling in any for (i = 0; i < m_uiPartitions; i++) { #ifndef CHANGE_D uiSize = m_ppEUuntranslatedVdata[i]->GetCurrentIndex(); #else //TODO: make sure double/uint32 conversion below is as expected. // uiSize = (m_uiEUcount/m_uiPartitions)*fFudge; uiSize = UINT_32((m_uiEUcount/m_uiPartitions)*fFudge); ASSERT(uiSize == (m_uiEUcount/m_uiPartitions)*fFudge); #endif #ifndef QUIET fprintf(stdout,"untranslated partition %d is size %d\n",i,uiSize); #endif #ifndef CHANGE_TWO m_ppEUsemitranslatedVdata[i] = new DataTripleFile, LID, LID, UINT_32 >; #else m_ppEUsemitranslatedVdata[i] = new DataTripleFile,LID,LID,VID>; #endif #ifdef CHANGE_C if (m_uiPartitions < 10) { //TODO: make sure double/uint32 conversion below is as expected. //m_ppEUsemitranslatedVdata[i]->Init((fFudge*uiSize*(m_uiPartitions-1))/ // m_uiPartitions); m_ppEUsemitranslatedVdata[i]->Init((UINT_32)((fFudge*uiSize*(m_uiPartitions-1))/ m_uiPartitions)); ASSERT(((UINT_32)((fFudge*uiSize*(m_uiPartitions-1))/m_uiPartitions)) == ((fFudge*uiSize*(m_uiPartitions-1))/m_uiPartitions)); } else #endif m_ppEUsemitranslatedVdata[i]->Init(uiSize); //m_ppEUsemitranslatedVdata[i]->Init((m_uiEUcount * 5)/(m_uiPartitions * 4)); //m_ppEUsemitranslatedVdata[i]->Init(m_uiEUcount); } #ifdef CHANGE_C AllocateFullyTranslated(); #endif #ifndef QUIET #ifdef __OS_IRIX__ struct rusage *prusage; long lPageFaultsPrev, lPageFaultsNow; prusage = new struct rusage; getrusage(RUSAGE_SELF, prusage); lPageFaultsPrev = lPageFaultsNow = prusage->ru_majflt; fprintf(stdout, "Page Faults so far: %d\n", lPageFaultsPrev); #endif Timer timer, otimer; timer.Start(); #endif #ifdef CHANGE_D BucketSort(); FLOAT *pfMaxZ = CalculatePartitionLimits(); #endif for (i = 0; i < m_uiPartitions; i++) { // allocate the corresponding VEUTable #ifndef CHANGE_D uiSize = m_ppEUuntranslatedVdata[i]->GetCurrentIndex(); #else //TODO: make sure double/uint32 conversion below is as expected. uiSize = (UINT_32)((m_uiEUcount/m_uiPartitions)*fFudge); #endif m_pplidPrVEUTables[i] = new DataPairFile, LID, LID>; m_pplidPrVEUTables[i]->Init(uiSize); // build the hash table, assign LIDs, etc //m_ppVIDHashTables[i] = InitVIDHashPartition(m_ppVIDTables[i]); #ifndef CHANGE_D m_ppVIDHashTables[i] = InitVIDHashPartition(m_ppEUuntranslatedVdata[i]-> GetCurrentIndex()); #else m_ppVIDHashTables[i] = InitVIDHashPartition((3 * m_uiFaceCount)/(4 * m_uiPartitions)); #endif // lock hash table in memory m_ppVIDHashTables[i]->lock(); // translate the first VID in the EU,VID,VID triples #ifndef CHANGE_D #ifndef CHANGE_TWO Translate1stVID(m_ppVIDHashTables[i], m_pplidPrVEUTables[i], m_ppEUuntranslatedVdata[i], i); #else Translate1stVID(m_ppVIDHashTables[i], m_pplidPrVEUTables[i], m_ppEUuntranslatedVdata[i], i); #endif #else uiCurBucket = Translate1stVID(m_ppVIDHashTables[i],m_pplidPrVEUTables[i], uiCurBucket, i, pfMaxZ); #endif m_ppVIDHashTables[i]->unlock(); #ifndef QUIET otimer.Start(); #endif #ifndef CHANGE_D delete m_ppEUuntranslatedVdata[i]; #endif #ifndef QUIET otimer.Stop(); #endif // delete m_ppVIDTables[i]; } #ifndef QUIET otimer.Start(); #endif delete [] m_ppEUuntranslatedVdata; #ifndef QUIET otimer.Stop(); DOUBLE ofoo = otimer.GetSeconds(); fprintf(stdout, "Freeing m_ppEUuntranslatedVdata %f seconds\n",ofoo); #endif m_ppEUuntranslatedVdata = NULL; #ifndef QUIET timer.Stop(); DOUBLE foo = timer.GetSeconds(); fprintf(stdout, "Building vtx hash and Translate1stVID took %f seconds\n",foo); #ifdef __OS_IRIX__ getrusage(RUSAGE_SELF, prusage); lPageFaultsPrev = lPageFaultsNow; lPageFaultsNow = prusage->ru_majflt; fprintf(stdout, "Page Faults during 1st vtx hash: %d\n", lPageFaultsNow - lPageFaultsPrev); #endif #endif // delete [] m_ppVIDTables; //m_ppVIDTables = NULL; // This can't go inside same for loop above even though we're using the // same hash table partitions because we will have repartitioned the data // on the second VID. #ifndef QUIET Timer timer2; timer2.Start(); #endif #ifndef CHANGE_C AllocateFullyTranslated(); #endif // process in opposite order so we start with the hash table partition // we just used above. // for (i = 0; i < m_uiPartitions; i++) if (m_uiPartitions == 1) { m_ppVIDHashTables[0]->lock(); Translate2ndVID(m_ppVIDHashTables[0], m_ppEUsemitranslatedVdata[0]); m_ppVIDHashTables[0]->unlock(); delete m_ppVIDHashTables[0]; delete m_ppEUsemitranslatedVdata[0]; } else { for (i = m_uiPartitions -1; i >= 0; i--) { // if (m_ppVIDHashTables[i]) { // translate the second VID in the EU,VID,VID triples m_ppVIDHashTables[i]->lock(); Translate2ndVID(m_ppVIDHashTables[i], m_ppEUsemitranslatedVdata[i]); m_ppVIDHashTables[i]->unlock(); delete m_ppVIDHashTables[i]; delete m_ppEUsemitranslatedVdata[i]; // delete m_ppVIDTables[i]; } } delete [] m_ppVIDHashTables; m_ppVIDHashTables = NULL; delete [] m_ppEUsemitranslatedVdata; m_ppEUsemitranslatedVdata = NULL; // delete [] m_ppVIDTables; // m_ppVIDTables = NULL; #ifndef CHANGE_TWO delete m_pVIDTable; m_pVIDTable = NULL; #endif #ifndef QUIET timer2.Stop(); foo = timer2.GetSeconds(); fprintf(stdout, "Translate2ndVID, freeing vtx hash, VID tables took %f secs\n",foo); #ifdef __OS_IRIX__ getrusage(RUSAGE_SELF, prusage); lPageFaultsPrev = lPageFaultsNow; lPageFaultsNow = prusage->ru_majflt; fprintf(stdout, "Page Faults during 2nd vtx hash: %d\n", lPageFaultsNow - lPageFaultsPrev); #endif Timer timer3; timer3.Start(); #endif m_pplidPrEUSibTables = new DataPairFile, LID, LID> *[m_uiPartitions]; // m_plidPrEUSibTable->Init(m_uiEUcount); m_pEdgeTable = new DataFile; m_pEdgeTable->Init((UINT_32)(.51*(FLOAT)m_uiEUcount)); // This could probably go into 2nd for loop above, but we wait // in order to delay initialization of EdgeTable and lidPrEUSibTable. // /* if (m_bPrevPtrs) *ppEUs = new CLEDSEdgeUsePrev[m_uiEUcount+1]; else *ppEUs = new CLEDSliteEdgeUse[m_uiEUcount+1]; */ for (i = 0; i < m_uiEdgePartitions; i++) { // Now find the edge use siblings from translated data if ((i%2) == 0) { // m_uiEdgePartitions must be twice m_uiPartitions for this to work!! m_pplidPrEUSibTables[i/2] = new DataPairFile, LID, LID>; uiSize = m_ppEUfullytranslatedVdata[i]->GetCurrentIndex(); if ((i+1) < m_uiEdgePartitions) uiSize += m_ppEUfullytranslatedVdata[i+1]->GetCurrentIndex(); m_pplidPrEUSibTables[i/2]->Init(uiSize); #ifdef SHOWSIZES fprintf(stdout, "EU Sib partition %d has %d entries\n",i,uiSize); size_t size = sizeof(*(m_pplidPrEUSibTables[i])); fprintf(stdout, "EU Sib table sizeof is %d\n", size); #endif } FindSiblings(m_pplidPrEUSibTables[i/2], m_ppEUfullytranslatedVdata[i], ppEUs); delete m_ppEUfullytranslatedVdata[i]; } delete [] m_ppEUfullytranslatedVdata; m_ppEUfullytranslatedVdata = NULL; #ifndef QUIET timer3.Stop(); foo = timer3.GetSeconds(); fprintf(stdout, "FindSiblings took %f seconds\n",foo); #ifdef __OS_IRIX__ getrusage(RUSAGE_SELF, prusage); lPageFaultsPrev = lPageFaultsNow; lPageFaultsNow = prusage->ru_majflt; fprintf(stdout, "Page Faults during edge hash: %d\n", lPageFaultsNow - lPageFaultsPrev); #endif #endif #ifdef LEDSDEBUG PrintTables(); #endif #ifndef QUIET Timer timer4; timer4.Start(); #endif SortTables(); #ifndef QUIET timer4.Stop(); foo = timer4.GetSeconds(); fprintf(stdout, "Sorting tables took %f seconds\n",foo); #ifdef __OS_IRIX__ getrusage(RUSAGE_SELF, prusage); lPageFaultsPrev = lPageFaultsNow; lPageFaultsNow = prusage->ru_majflt; fprintf(stdout, "Page Faults during Sorting: %d\n", lPageFaultsNow - lPageFaultsPrev); #endif #endif #ifdef LEDSDEBUG PrintSortedTables(); #endif } template inline VOID CLEDSTables::BuildVertices(CLEDSliteVertex **ppVtxs, CLEDSliteEdgeUse **ppEUs, CLEDSliteFace **ppFaces) { UINT_32 i, uiCurPartition; DataFileIter > *VEUTableIters; DataFileIter LIDVIDTableIter; LID lidLastVtx = NON_LID; LID lidFirstEU = NON_LID; LID lidCurVtx = 0; LID lidLastEU, lidCurEU; Pair *plidPair; Point Pt; VID *pVID; #ifndef QUIET Timer timer; #endif // Allocate space for the leds vertices, EUs and faces // (0th elt of arrays unused; hence the +1) *ppVtxs = new CLEDSliteVertex[m_uiVtxCount+1]; // move to ? so that an edge per EU can be put in list as identified if (m_bPrevPtrs) *ppEUs = new CLEDSEdgeUsePrev[m_uiEUcount+1]; else *ppEUs = new CLEDSliteEdgeUse[m_uiEUcount+1]; // allocate EUNVETable #ifndef QUIET timer.Start(); #endif #ifndef CHANGE_B m_plidPrEUNVETable = new DataPairFile, LID, LID>; m_plidPrEUNVETable->Init(m_uiEUcount); #else m_pplidPrEUNVETables = new DataPairFile, LID, LID> *[m_uiPartitions]; for (i = 0; i < m_uiPartitions; i++) { m_pplidPrEUNVETables[i] = new DataPairFile, LID, LID>; m_pplidPrEUNVETables[i]-> Init(1 + m_pplidPrVEUTables[i]->GetCurrentIndex()); // +1 just in case off-by-one bug would require doubling size } #endif #ifndef QUIET timer.Stop(); DOUBLE dfoo = timer.GetSeconds(); fprintf(stdout, "Allocating EUNVETables took %f seconds\n", dfoo); #endif // initialize iterators VEUTableIters = new DataFileIter > [m_uiPartitions]; for (i = 0; i < m_uiPartitions; i++) { VEUTableIters[i].Init(m_pplidPrVEUTables[i]); // fprintf(stdout, "m_pplidPrVEUTables[i]: %d.\n", m_pplidPrVEUTables[i]); } LIDVIDTableIter.Init(m_pLIDVIDTable); while (LIDVIDTableIter.Valid()) { // plidvidPair = LIDVIDTableIter.PeekNextItem(); // lidCurVtx = plidvidPair->GetFirst(); lidCurVtx++; // Pt = *(LIDVIDTableIter.PeekNextItem()); pVID = LIDVIDTableIter.PeekNextItem(); // if STL, the VID is a Triple of FLOATS. Need to get that info somehow. Pt.Set(pVID->GetFirst(), pVID->GetSecond(), pVID->GetThird()); uiCurPartition = 9999; for (i = 0; i < m_uiPartitions; i++) { if (VEUTableIters[i].Valid()) { plidPair = VEUTableIters[i].PeekNextItem(); if (plidPair->GetFirst() == lidCurVtx) { uiCurPartition = i; VEUTableIters[i].BackUp(); break; } VEUTableIters[i].BackUp(); } } ASSERT(uiCurPartition != 9999); while (VEUTableIters[uiCurPartition].Valid() && (plidPair = VEUTableIters[uiCurPartition].PeekNextItem()) && (plidPair->GetFirst() == lidCurVtx) ) { //plidPair = VEUTableIters[uiCurPartition].PeekNextItem(); //ASSERT(plidPair->GetFirst() == lidCurVtx); lidCurEU = plidPair->GetSecond(); if (lidCurVtx != lidLastVtx) { // it's a new Vertex // Complete the loop of NVE ptrs for previous vertex if (lidFirstEU != NON_LID) { #ifndef CHANGE_B AddEUNextVtxEU(lidLastEU, lidFirstEU); #else AddEUNextVtxEU(uiCurPartition, lidLastEU, lidFirstEU); #endif } lidFirstEU = lidCurEU; // get its VID and record that in the leds as well // plidvidPair = LIDVIDTableIter.PeekNextItem(); // ASSERT(plidvidPair->GetFirst() == lidCurVtx); // if STL, the VID is a point. Need to get that info somehow. // Pt = (plidvidPair->GetSecond()); #ifdef RESORTABLE m_pCLEDSGeometry->GetLIDmapVtx()->SetPtr(lidCurVtx, &((*ppVtxs)[lidCurVtx])); #endif (*ppVtxs)[lidCurVtx].Init (Pt, (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurEU)), m_pCLEDSGeometry); } else { // We already have an EU for this vertex; convert rest to // Next Vertex Edge Use ptrs and put in EU-NVE Table #ifndef CHANGE_B AddEUNextVtxEU(lidLastEU, lidCurEU); #else AddEUNextVtxEU(uiCurPartition, lidLastEU, lidCurEU); #endif } lidLastVtx = lidCurVtx; lidLastEU = lidCurEU; } if (VEUTableIters[uiCurPartition].Valid()) VEUTableIters[uiCurPartition].BackUp(); } if (lidFirstEU != NON_LID) { #ifndef CHANGE_B AddEUNextVtxEU(lidLastEU, lidFirstEU); #else AddEUNextVtxEU(uiCurPartition, lidLastEU, lidFirstEU); #endif } #ifdef LEDSDEBUG UINT_32 j; for (j = 1; j < m_uiVtxCount+1; j++) { (*ppVtxs)[j].Display(); } #endif #ifdef CHANGE_SEVEN for (i = 0; i < m_uiPartitions; i++) { delete m_pplidPrVEUTables[i]; } delete [] m_pplidPrVEUTables; m_pplidPrVEUTables = NULL; #endif delete m_pLIDVIDTable; m_pLIDVIDTable = NULL; #ifndef CHANGE_G // Now need to fill global Vtx list with the elts of this array m_pCLEDSGeometry->GetCListVertices()->Init(m_uiVtxCount); m_pCLEDSGeometry->GetCListVertices()->InsertArray(&((*ppVtxs)[1]), sizeof(CLEDSliteVertex), m_uiVtxCount); #endif } template inline VOID CLEDSTables::BuildEUs(CLEDSliteEdgeUse **ppEUs, CLEDSliteVertex **ppVtxs, CLEDSliteFace **ppFaces) { // need to do BuildVertices before BUildEUS because some V-EU pairs become // EU-NVE pairs (Edge to Next Vertex Edge use). *ppFaces = new CLEDSliteFace[m_uiFaceCount+1]; UINT_32 uiCurSibPartition, uiCurEUVPartition, uiCurNVEPartition, i; #ifdef GENERAL_FACES DataFileIter > EUFTableIter; // 1 entry each EU DataFileIter > EUNCETableIter; // 1 each (closed face input) Pair *plidPrEUF, *plidPrEUNCE; #endif DataFileIter > *EUVTablesBackwardsIters; // 1 entry each EU DataFileIter > *EUSibTableIters; // 0 or 1 entry each EU #ifndef CHANGE_B DataFileIter > EUNVETableIter; // 1 entry each EU #else DataFileIter > *EUNVETableIters; // 1 entry each EU #endif Pair *plidPrSib, *plidPrEUNVE, *plidPrEUV; LID lidCurEU, lidCurFace, lidCurNCE, lidCurV, lidCurNVE, lidCurSibEUto; LID lidCurSibEUfrom = NON_LID; #ifndef QUIET Timer timer; #endif // The VEUTable now needs to be sorted on EU instead of on V // and the EUNVETable needs to be sorted, too UpdateEUTables(); // Initialize iterators #ifdef GENERAL_FACES EUFTableIter.Init(m_plidPrEUFTable); EUNCETableIter.Init(m_plidPrEUNCETable); #endif #ifndef CHANGE_B EUNVETableIter.Init(m_plidPrEUNVETable); #else EUNVETableIters = new DataFileIter > [m_uiPartitions]; #endif EUSibTableIters = new DataFileIter > [m_uiPartitions]; EUVTablesBackwardsIters = new DataFileIter > [m_uiPartitions]; for (i = 0; i < m_uiPartitions; i++) { #ifdef CHANGE_B EUNVETableIters[i].Init(m_pplidPrEUNVETables[i]); #endif EUSibTableIters[i].Init(m_pplidPrEUSibTables[i]); // Remember, this table is backwards, ie V is first, EU is second // It should be in increasing EU order though. EUVTablesBackwardsIters[i].Init(m_pplidPrEUVTablesBackwards[i]); } // Pre-read first Sibling and Edge entries /* if (EUSibTableIter.Valid()){ plidPrSib = EUSibTableIter.PeekNextItem(); lidCurSibEUfrom = plidPrSib->GetFirst(); } */ #ifndef CHANGE_G // this moves to findsiblings if CHANGE_SIX defined #ifndef CHANGE_SIX DataFileIter EdgeTableIter; // 0 or 1 entry each EU LID *plidCurEdge; #ifndef QUIET Timer timerSort; timerSort.Start(); #endif m_pEdgeTable->Sort(lidCompare); EdgeTableIter.Init(m_pEdgeTable); m_pCLEDSGeometry->GetCListEdges()->Init(m_pEdgeTable->GetCurrentIndex()); while (EdgeTableIter.Valid()){ plidCurEdge = EdgeTableIter.PeekNextItem(); m_pCLEDSGeometry->GetCListEdges()->InsertLast ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+ (m_sizeEU*(*plidCurEdge))), 0); } #ifndef QUIET timerSort.Stop(); DOUBLE dSecs = timerSort.GetSeconds(); fprintf(stdout, "Building edge list took %f seconds\n",dSecs); #endif #endif /* delete m_pEdgeTable; m_pEdgeTable = NULL; */ #endif // this should just increment the known number of EUs // while (EUNVETableIter.Valid()) { for (lidCurEU = 1; lidCurEU <= m_uiEUcount; lidCurEU++) { #ifndef CHANGE_B ASSERT(EUNVETableIter.Valid()); plidPrEUNVE = EUNVETableIter.PeekNextItem(); ASSERT(lidCurEU == plidPrEUNVE->GetFirst()); lidCurNVE = plidPrEUNVE->GetSecond(); #endif #ifdef GENERAL_FACES ASSERT (EUFTableIter.Valid()); plidPrEUF = EUFTableIter.PeekNextItem(); ASSERT(lidCurEU == plidPrEUF->GetFirst()); lidCurFace = plidPrEUF->GetSecond(); ASSERT(EUNCETableIter.Valid()); plidPrEUNCE = EUNCETableIter.PeekNextItem(); ASSERT(plidPrEUNCE->GetFirst() == lidCurEU); lidCurNCE = plidPrEUNCE->GetSecond(); #else if (lidCurEU%3 == 0) { lidCurFace = lidCurEU/3; lidCurNCE = lidCurEU - 2; } else { lidCurFace = (lidCurEU/3) + 1; lidCurNCE = lidCurEU + 1; } #endif #ifndef QUIET timer.Start(); #endif // find correct partition for EUVTablesBackwards uiCurEUVPartition = 9999; for (i = 0; i < m_uiPartitions; i++) { if (EUVTablesBackwardsIters[i].Valid()) { plidPrEUV = EUVTablesBackwardsIters[i].PeekNextItem(); if (plidPrEUV->GetSecond() == lidCurEU) { uiCurEUVPartition = i; break; } EUVTablesBackwardsIters[i].BackUp(); } } ASSERT(uiCurEUVPartition != 9999); lidCurV = plidPrEUV->GetFirst(); /* if ((lidCurEU == 1) || (lidCurEU == 2) || (lidCurEU == 3) || (lidCurEU == 10000) || (lidCurEU == 10002) || (lidCurEU == 10003)) { CLEDSliteVertex *pVtx; fprintf(stdout, "\nlid %d :", lidCurEU); (*ppVtxs)[lidCurV].Display(); } */ // find correct partition for EUSib uiCurSibPartition = 9999; for (i = 0; i < m_uiPartitions; i++) { if (EUSibTableIters[i].Valid()) { plidPrSib = EUSibTableIters[i].PeekNextItem(); if (plidPrSib->GetFirst() == lidCurEU) { uiCurSibPartition = i; lidCurSibEUfrom = plidPrSib->GetFirst(); break; } EUSibTableIters[i].BackUp(); } } if (uiCurSibPartition == 9999) // there is no sibling lidCurSibEUfrom = NON_LID; #ifdef CHANGE_B // find correct partition for EUNVE uiCurNVEPartition = 9999; for (i = 0; i < m_uiPartitions; i++) { if (EUNVETableIters[i].Valid()) { plidPrEUNVE = EUNVETableIters[i].PeekNextItem(); if (plidPrEUNVE->GetFirst() == lidCurEU) { uiCurNVEPartition = i; //I thought I should be able to fold this in above loop for EUV. // Checked with this assert, but it failed on many files, // eg tetria.stl. // ASSERT(uiCurNVEPartition==uiCurEUVPartition); lidCurNVE = plidPrEUNVE->GetSecond(); break; } EUNVETableIters[i].BackUp(); } } ASSERT(uiCurNVEPartition != 9999); #endif #ifndef QUIET timer.Stop(); #endif /* ASSERT(EUVTableBackwardsIter.Valid()); plidPrEUV = EUVTableBackwardsIter.PeekNextItem(); ASSERT(plidPrEUV->GetSecond() == lidCurEU); lidCurV = plidPrEUV->GetFirst(); */ /* // this moves to findsiblings if CHANGE_SIX defined #ifndef CHANGE_SIX if (plidCurEdge && (lidCurEU == *plidCurEdge)) { m_pCLEDSGeometry->GetCListEdges()->InsertLast ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurEU)), 0); plidCurEdge = EdgeTableIter.PeekNextItem(); } #endif */ if (lidCurEU == lidCurSibEUfrom) { lidCurSibEUto = plidPrSib->GetSecond(); #ifdef RESORTABLE m_pCLEDSGeometry->GetLIDmapEU()->SetPtr (lidCurEU, (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurEU))); #endif ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurEU)))->Init (&(*ppVtxs)[lidCurV], (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurNCE)), (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurSibEUto)), (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurNVE)), &(*ppFaces)[lidCurFace], m_pCLEDSGeometry); // There may be multiple entries in the table for the same 'from' EU. // Need to overwrite if so, so that we end up with the last, correct // sibling pointer. while ((EUSibTableIters[uiCurSibPartition].Valid()) && (lidCurEU == lidCurSibEUfrom)) { plidPrSib = EUSibTableIters[uiCurSibPartition].PeekNextItem(); lidCurSibEUfrom = plidPrSib->GetFirst(); if (lidCurEU == lidCurSibEUfrom) { lidCurSibEUto = plidPrSib->GetSecond(); ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurEU))) ->SetLEDSSiblingEdgeUse ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurSibEUto))); } else EUSibTableIters[uiCurSibPartition].BackUp(); } } else // there is no sibling entry so we make it pt back to itself { #ifdef RESORTABLE m_pCLEDSGeometry->GetLIDmapEU()->SetPtr (lidCurEU, (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurEU))); #endif ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurEU)))->Init (&(*ppVtxs)[lidCurV], (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurNCE)), (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurEU)), (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurNVE)), &(*ppFaces)[lidCurFace], m_pCLEDSGeometry); } } #ifdef GENERAL_FACES ASSERT (!(EUNCETableIter.Valid())); #endif /* ASSERT (!(EUVTablesBackwardsIters.Valid())); ASSERT (!(EUNVETablesIters.Valid())); ASSERT (!(EUSibTableIters.Valid())); */ #ifdef LEDSDEBUG UINT_32 j; for (j = 1; j < m_uiEUcount+1; j++) { ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*j)))->Display(); } #endif #ifndef QUIET DOUBLE foo = timer.GetSeconds(); fprintf(stdout, "Finding partitions took %f seconds\n",foo); Timer timer2; timer2.Start(); #endif // Free memory from tables #ifdef GENERAL_FACES delete m_plidPrEUFTable; m_plidPrEUFTable = NULL; delete m_plidPrEUNCETable; m_plidPrEUNCETable = NULL; #endif for (i = 0; i < m_uiPartitions; i++) { #ifndef CHANGE_SEVEN // this first one should be freed back in buildvertices otherwise; // If CHANGE_SEVEN is defined then it is freed below because // its entries are the same as m_pplidPrEUVTablesBackwards[i] // delete m_pplidPrVEUTables[i]; #endif delete m_pplidPrEUVTablesBackwards[i]; delete m_pplidPrEUSibTables[i]; #ifdef CHANGE_B delete m_pplidPrEUNVETables[i]; #endif } #ifndef CHANGE_B delete m_plidPrEUNVETable; m_plidPrEUNVETable = NULL; #else delete [] m_pplidPrEUNVETables; m_pplidPrEUNVETables = NULL; #endif #ifndef CHANGE_SEVEN delete [] m_pplidPrVEUTables; m_pplidPrVEUTables = NULL; #endif delete [] m_pplidPrEUVTablesBackwards; m_pplidPrEUVTablesBackwards = NULL; delete [] m_pplidPrEUSibTables; m_pplidPrEUSibTables = NULL; /* delete m_plidPrVEUTable; m_plidPrVEUTable = NULL; // This is a problem since it has the same data as table above // delete m_plidPrEUVTableBackwards; m_plidPrEUVTableBackwards = NULL; delete m_plidPrEUSibTable; m_plidPrEUSibTable = NULL; */ /* // BuildVertices does it now delete m_pLIDVIDTable; m_pLIDVIDTable = NULL; */ delete m_pEdgeTable; m_pEdgeTable = NULL; #ifndef QUIET timer2.Stop(); foo = timer2.GetSeconds(); fprintf(stdout, "Freeing memory took %f seconds\n",foo); #endif #ifndef CHANGE_G // Now fill in the global list of EUs m_pCLEDSGeometry->GetCListEUs()->Init(m_uiEUcount); m_pCLEDSGeometry->GetCListEUs()->InsertArray ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU)), sizeof(CLEDSliteEdgeUse), m_uiEUcount); // InsertArray(&((*ppEUs)[1]), sizeof(CLEDSliteEdgeUse), m_uiEUcount); #endif } template inline VOID CLEDSTables::BuildFaces(CLEDSliteFace **ppFaces, CLEDSliteEdgeUse **ppEUs) { // *ppFaces = new CLEDSliteFace[m_uiFaceCount]; // UINT_32 FaceIndex = 0; LID lidCurOCFace, lidCurOCEU; CListInt *pListIC = NULL; #ifdef GENERAL_FACES LID lidLastICFace = NON_LID; LID lidCurICFace, lidCurICEU; DataFileIter > FOCTableIter; Pair *plidPrFIC, *plidPrFOC; DataFileIter > FICTableIter; FOCTableIter.Init(m_plidPrFOCTable); FICTableIter.Init(m_plidPrFICTable); #endif #ifndef GENERAL_FACES for (lidCurOCFace = 1; lidCurOCFace <= m_uiFaceCount; lidCurOCFace++) { lidCurOCEU = (3*lidCurOCFace) - 2; #ifdef RESORTABLE m_pCLEDSGeometry->GetLIDmapFace()->SetPtr(lidCurOCFace, &((*ppFaces)[lidCurOCFace])); #endif // RESORTABLE (*ppFaces)[lidCurOCFace].Init(pListIC, (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurOCEU)), m_pCLEDSGeometry); } #else // GENERAL_FACES // Pre-read first inner contour entry before going through // list of outer contours if (FICTableIter.Valid()){ plidPrFIC = FICTableIter.PeekNextItem(); lidCurICFace = plidPrFIC->GetFirst(); } else { lidCurICFace = NON_LID; } while (FOCTableIter.Valid()) { plidPrFOC = FOCTableIter.PeekNextItem(); lidCurOCFace = plidPrFOC->GetFirst(); lidCurOCEU = plidPrFOC->GetSecond(); fprintf (stdout, "lidFace: %d, lidEU: %d\n", lidCurOCFace, lidCurOCEU); // ASSERT (lidCurOCFace == lidFace); // ASSERT (lidCurOCEU == (3*lidCurOCFace) - 2); // lidFace++; // The flow control/logic here is a bit baroque - the Valid // check has to go at the end because we advance the FIC iterator // before the do loop in order to find the current ICFace so that we // can test and see whether it matches the current OCFace. We only // want to advance the FIC iterator if they match. // We assume that there are no faces from the FIC table that // aren't in the FOC table and that both are sorted by Face. do { if (lidCurICFace == lidCurOCFace) { // If this is first inner contour for the face, allocate IC list if (lidCurICFace != lidLastICFace) { pListIC = new CListInt; } lidLastICFace = lidCurICFace; // Add the EU to the IC list lidCurICEU = plidPrFIC->GetSecond(); pListIC->InsertLast( &(lidCurICEU), 0); // read next IC ptr for next time through loop if (FICTableIter.Valid()) { plidPrFIC = FICTableIter.PeekNextItem(); if (plidPrFIC) { lidCurICFace = plidPrFIC->GetFirst(); } } } } while (lidCurICFace == lidCurOCFace && FICTableIter.Valid()); #ifdef RESORTABLE m_pCLEDSGeometry->GetLIDmapFace()->SetPtr(lidCurOCFace, &((*ppFaces)[lidCurOCFace])); #endif //cout << "face array index " << FaceIndex << " lid " << lidCurOCFace << endl; //(*ppFaces)[lidCurOCFace].Init(pListIC, &(*ppEUs)[lidCurOCEU],m_pCLEDSGeometry); (*ppFaces)[lidCurOCFace].Init (pListIC, (CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU*lidCurOCEU)), m_pCLEDSGeometry); } ASSERT (!(FICTableIter.Valid())); #endif // GENERAL_FACES #ifdef LEDSDEBUG UINT_32 i; for (i = 1; i < m_uiFaceCount+1; i++) { (*ppFaces)[i].Display(); } #endif #ifndef CHANGE_G // Now need to fill global Face list with the elts of this array m_pCLEDSGeometry->GetCListFaces()->Init(m_uiFaceCount); m_pCLEDSGeometry->GetCListFaces()->InsertArray(&((*ppFaces)[1]), sizeof(CLEDSliteFace), m_uiFaceCount); #endif // free memory from tables #ifdef GENERAL_FACES delete m_plidPrFOCTable; m_plidPrFOCTable = NULL; delete m_plidPrFICTable; m_plidPrFICTable = NULL; #endif } #ifdef CHANGE_G template inline VOID CLEDSTables::BuildLists(CLEDSliteEdgeUse **ppEUs, CLEDSliteVertex **ppVtxs, CLEDSliteFace **ppFaces) { m_pCLEDSGeometry->GetCListVertices()->Init(m_uiVtxCount); m_pCLEDSGeometry->GetCListVertices()->InsertArray(&((*ppVtxs)[1]), sizeof(CLEDSliteVertex), m_uiVtxCount); fprintf(stdout, "listvertices\n"); m_pCLEDSGeometry->GetCListEUs()->Init(m_uiEUcount); m_pCLEDSGeometry->GetCListEUs()->InsertArray ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+(m_sizeEU)), sizeof(CLEDSliteEdgeUse), m_uiEUcount); fprintf(stdout, "listEUs\n"); // this moves to findsiblings if CHANGE_SIX defined #ifndef CHANGE_SIX DataFileIter EdgeTableIter; // 0 or 1 entry each EU LID *plidCurEdge; #ifndef QUIET Timer timerSort; timerSort.Start(); #endif m_pEdgeTable->Sort(lidCompare); EdgeTableIter.Init(m_pEdgeTable); m_pCLEDSGeometry->GetCListEdges()->Init(m_pEdgeTable->GetCurrentIndex()); while (EdgeTableIter.Valid()){ plidCurEdge = EdgeTableIter.PeekNextItem(); m_pCLEDSGeometry->GetCListEdges()->InsertLast ((CLEDSliteEdgeUse *)((UINT_32)(*ppEUs)+ (m_sizeEU*(*plidCurEdge))), 0); } #ifndef QUIET timerSort.Stop(); DOUBLE dSecs = timerSort.GetSeconds(); fprintf(stdout, "Building edge list took %f seconds\n",dSecs); #endif #endif delete m_pEdgeTable; m_pEdgeTable = NULL; m_pCLEDSGeometry->GetCListFaces()->Init(m_uiFaceCount); m_pCLEDSGeometry->GetCListFaces()->InsertArray(&((*ppFaces)[1]), sizeof(CLEDSliteFace), m_uiFaceCount); } #endif #ifdef LEDSDEBUG template inline VOID CLEDSTables::PrintTables() const { UINT_32 i; #ifdef GENERAL_FACES cout << "The EU/F table\n***********************************\n"; m_plidPrEUFTable->DisplayAll(); cout << "The EU/NCE table\n***********************************\n"; m_plidPrEUNCETable->DisplayAll(); cout << "The F/OC table\n***********************************\n"; m_plidPrFOCTable->DisplayAll(); cout << "The F/IC table\n***********************************\n"; m_plidPrFICTable->DisplayAll(); #endif /* cout << "The untranslated vertex table\n********************************\n"; for (i = 0; i < m_uiPartitions; i++) { // (m_ppVIDTables[i])->DisplayAll(); } cout << "The Untranslated edge table\n**********************************\n"; for (i = 0; i < m_uiPartitions; i++) { m_ppEUuntranslatedVdata[i]->DisplayAll(); } cout << "The semitranslated edge tables\n********************************\n"; for (i = 0; i < m_uiPartitions; i++) { m_ppEUsemitranslatedVdata[i]->DisplayAll(); } cout << "The fullytranslated edge tables\n*******************************\n"; for (i = 0; i < m_uiPartitions; i++) { m_ppEUfullytranslatedVdata[i]->DisplayAll(); } */ cout << "The sibling edge use tables\n***********************************\n"; for (i = 0; i < m_uiPartitions; i++) { m_pplidPrEUSibTables[i]->DisplayAll(); } cout << "The Edge table\n***********************************\n"; m_pEdgeTable->DisplayAll(); } #endif #ifdef LEDSDEBUG template inline VOID CLEDSTables::PrintSortedTables() const { UINT_32 i; cout << "++++++++++++++++++++++++++++Sorted+++++++++++++++++++++++++++++\n"; #ifdef GENERAL_FACES cout << "The EU/F table\n***********************************\n"; m_plidPrEUFTable->DisplayAll(); cout << "The EU/NCE table\n***********************************\n"; m_plidPrEUNCETable->DisplayAll(); cout << "The F/OC table\n***********************************\n"; m_plidPrFOCTable->DisplayAll(); cout << "The F/IC table\n***********************************\n"; m_plidPrFICTable->DisplayAll(); #endif cout << "The vertex table\n***********************************\n"; m_pLIDVIDTable->DisplayAll(); cout << "The sibling edge use tables\n***********************************\n"; for (i = 0; i < m_uiPartitions; i++) { cout << "partition " << i << endl; m_pplidPrEUSibTables[i]->DisplayAll(); } } #endif #endif // __LEDSTABLES_H__