📄 dgnread.cpp
字号:
CPLFree( psTagSet->tagList[iTag].prompt ); if( psTagSet->tagList[iTag].type == 1 ) CPLFree( psTagSet->tagList[iTag].defaultValue.string ); } CPLFree( psTagSet->tagList ); } else if( psElement->stype == DGNST_TAG_VALUE ) { if( ((DGNElemTagValue *) psElement)->tagType == 1 ) CPLFree( ((DGNElemTagValue *) psElement)->tagValue.string ); } CPLFree( psElement );}/************************************************************************//* DGNRewind() *//************************************************************************//** * Rewind element reading. * * Rewind the indicated DGN file, so the next element read with * DGNReadElement() will be the first. Does not require indexing like * the more general DGNReadElement() function. * * @param hDGN handle to file. */void DGNRewind( DGNHandle hDGN ){ DGNInfo *psDGN = (DGNInfo *) hDGN; VSIRewind( psDGN->fp ); psDGN->next_element_id = 0; psDGN->in_complex_group = FALSE;}/************************************************************************//* DGNTransformPoint() *//************************************************************************/void DGNTransformPoint( DGNInfo *psDGN, DGNPoint *psPoint ){ psPoint->x = psPoint->x * psDGN->scale - psDGN->origin_x; psPoint->y = psPoint->y * psDGN->scale - psDGN->origin_y; psPoint->z = psPoint->z * psDGN->scale - psDGN->origin_z;}/************************************************************************//* DGNInverseTransformPoint() *//************************************************************************/void DGNInverseTransformPoint( DGNInfo *psDGN, DGNPoint *psPoint ){ psPoint->x = (psPoint->x + psDGN->origin_x) / psDGN->scale; psPoint->y = (psPoint->y + psDGN->origin_y) / psDGN->scale; psPoint->z = (psPoint->z + psDGN->origin_z) / psDGN->scale; psPoint->x = MAX(-2147483647,MIN(2147483647,psPoint->x)); psPoint->y = MAX(-2147483647,MIN(2147483647,psPoint->y)); psPoint->z = MAX(-2147483647,MIN(2147483647,psPoint->z));}/************************************************************************//* DGNInverseTransformPointToInt() *//************************************************************************/void DGNInverseTransformPointToInt( DGNInfo *psDGN, DGNPoint *psPoint, unsigned char *pabyTarget ){ double adfCT[3]; int i; adfCT[0] = (psPoint->x + psDGN->origin_x) / psDGN->scale; adfCT[1] = (psPoint->y + psDGN->origin_y) / psDGN->scale; adfCT[2] = (psPoint->z + psDGN->origin_z) / psDGN->scale; for( i = 0; i < psDGN->dimension; i++ ) { GInt32 nCTI; unsigned char *pabyCTI = (unsigned char *) &nCTI; nCTI = (GInt32) MAX(-2147483647,MIN(2147483647,adfCT[i])); #ifdef WORDS_BIGENDIAN pabyTarget[i*4+0] = pabyCTI[1]; pabyTarget[i*4+1] = pabyCTI[0]; pabyTarget[i*4+2] = pabyCTI[3]; pabyTarget[i*4+3] = pabyCTI[2];#else pabyTarget[i*4+3] = pabyCTI[1]; pabyTarget[i*4+2] = pabyCTI[0]; pabyTarget[i*4+1] = pabyCTI[3]; pabyTarget[i*4+0] = pabyCTI[2];#endif }}/************************************************************************//* DGNLoadTCB() *//************************************************************************//** * Load TCB if not already loaded. * * This function will load the TCB element if it is not already loaded. * It is used primarily to ensure the TCB is loaded before doing any operations * that require TCB values (like creating new elements). * * @return FALSE on failure or TRUE on success. */int DGNLoadTCB( DGNHandle hDGN ){ DGNInfo *psDGN = (DGNInfo *) hDGN; if( psDGN->got_tcb ) return TRUE; while( !psDGN->got_tcb ) { DGNElemCore *psElem = DGNReadElement( hDGN ); if( psElem == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "DGNLoadTCB() - unable to find TCB in file." ); return FALSE; } DGNFreeElement( hDGN, psElem ); } return TRUE;}/************************************************************************//* DGNGetElementIndex() *//************************************************************************//** * Fetch element index. * * This function will return an array with brief information about every * element in a DGN file. It requires one pass through the entire file to * generate (this is not repeated on subsequent calls). * * The returned array of DGNElementInfo structures contain the level, type, * stype, and other flags for each element in the file. This can facilitate * application level code representing the number of elements of various types * effeciently. * * Note that while building the index requires one pass through the whole file, * it does not generally request much processing for each element. * * @param hDGN the file to get an index for. * @param pnElementCount the integer to put the total element count into. * * @return a pointer to an internal array of DGNElementInfo structures (there * will be *pnElementCount entries in the array), or NULL on failure. The * returned array should not be modified or freed, and will last only as long * as the DGN file remains open. */const DGNElementInfo *DGNGetElementIndex( DGNHandle hDGN, int *pnElementCount ){ DGNInfo *psDGN = (DGNInfo *) hDGN; DGNBuildIndex( psDGN ); if( pnElementCount != NULL ) *pnElementCount = psDGN->element_count; return psDGN->element_index;}/************************************************************************//* DGNGetExtents() *//************************************************************************//** * Fetch overall file extents. * * The extents are collected for each element while building an index, so * if an index has not already been built, it will be built when * DGNGetExtents() is called. * * The Z min/max values are generally meaningless (0 and 0xffffffff in uor * space). * * @param hDGN the file to get extents for. * @param padfExtents pointer to an array of six doubles into which are loaded * the values xmin, ymin, zmin, xmax, ymax, and zmax. * * @return TRUE on success or FALSE on failure. */int DGNGetExtents( DGNHandle hDGN, double * padfExtents ){ DGNInfo *psDGN = (DGNInfo *) hDGN; DGNPoint sMin, sMax; DGNBuildIndex( psDGN ); if( !psDGN->got_bounds ) return FALSE; sMin.x = psDGN->min_x - 2147483648.0; sMin.y = psDGN->min_y - 2147483648.0; sMin.z = psDGN->min_z - 2147483648.0; DGNTransformPoint( psDGN, &sMin ); padfExtents[0] = sMin.x; padfExtents[1] = sMin.y; padfExtents[2] = sMin.z; sMax.x = psDGN->max_x - 2147483648.0; sMax.y = psDGN->max_y - 2147483648.0; sMax.z = psDGN->max_z - 2147483648.0; DGNTransformPoint( psDGN, &sMax ); padfExtents[3] = sMax.x; padfExtents[4] = sMax.y; padfExtents[5] = sMax.z; return TRUE;}/************************************************************************//* DGNBuildIndex() *//************************************************************************/void DGNBuildIndex( DGNInfo *psDGN ){ int nMaxElements, nType, nLevel; long nLastOffset; GUInt32 anRegion[6]; if( psDGN->index_built ) return; psDGN->index_built = TRUE; DGNRewind( psDGN ); nMaxElements = 0; nLastOffset = VSIFTell( psDGN->fp ); while( DGNLoadRawElement( psDGN, &nType, &nLevel ) ) { DGNElementInfo *psEI; if( psDGN->element_count == nMaxElements ) { nMaxElements = (int) (nMaxElements * 1.5) + 500; psDGN->element_index = (DGNElementInfo *) CPLRealloc( psDGN->element_index, nMaxElements * sizeof(DGNElementInfo) ); } psEI = psDGN->element_index + psDGN->element_count; psEI->level = (unsigned char) nLevel; psEI->type = (unsigned char) nType; psEI->flags = 0; psEI->offset = (long) nLastOffset; if( psDGN->abyElem[0] & 0x80 ) psEI->flags |= DGNEIF_COMPLEX; if( psDGN->abyElem[1] & 0x80 ) psEI->flags |= DGNEIF_DELETED; if( nType == DGNT_LINE || nType == DGNT_LINE_STRING || nType == DGNT_SHAPE || nType == DGNT_CURVE || nType == DGNT_BSPLINE ) psEI->stype = DGNST_MULTIPOINT; else if( nType == DGNT_GROUP_DATA && nLevel == DGN_GDL_COLOR_TABLE ) { DGNElemCore *psCT = DGNParseColorTable( psDGN ); DGNFreeElement( (DGNHandle) psDGN, psCT ); psEI->stype = DGNST_COLORTABLE; } else if( nType == DGNT_ELLIPSE || nType == DGNT_ARC ) psEI->stype = DGNST_ARC; else if( nType == DGNT_COMPLEX_SHAPE_HEADER || nType == DGNT_COMPLEX_CHAIN_HEADER || nType == DGNT_3DSURFACE_HEADER || nType == DGNT_3DSOLID_HEADER) psEI->stype = DGNST_COMPLEX_HEADER; else if( nType == DGNT_TEXT ) psEI->stype = DGNST_TEXT; else if( nType == DGNT_TAG_VALUE ) psEI->stype = DGNST_TAG_VALUE; else if( nType == DGNT_APPLICATION_ELEM ) { if( nLevel == 24 ) psEI->stype = DGNST_TAG_SET; else psEI->stype = DGNST_CORE; } else if( nType == DGNT_TCB ) { DGNElemCore *psTCB = DGNParseTCB( psDGN ); DGNFreeElement( (DGNHandle) psDGN, psTCB ); psEI->stype = DGNST_TCB; } else if( nType == DGNT_CONE ) psEI->stype = DGNST_CONE; else psEI->stype = DGNST_CORE; if( !(psEI->flags & DGNEIF_DELETED) && !(psEI->flags & DGNEIF_COMPLEX) && DGNGetRawExtents( psDGN, nType, NULL, anRegion+0, anRegion+1, anRegion+2, anRegion+3, anRegion+4, anRegion+5 ) ) {#ifdef notdef printf( "panRegion[%d]=%.1f,%.1f,%.1f,%.1f,%.1f,%.1f\n", psDGN->element_count, anRegion[0] - 2147483648.0, anRegion[1] - 2147483648.0, anRegion[2] - 2147483648.0, anRegion[3] - 2147483648.0, anRegion[4] - 2147483648.0, anRegion[5] - 2147483648.0 );#endif if( psDGN->got_bounds ) { psDGN->min_x = MIN(psDGN->min_x, anRegion[0]); psDGN->min_y = MIN(psDGN->min_y, anRegion[1]); psDGN->min_z = MIN(psDGN->min_z, anRegion[2]); psDGN->max_x = MAX(psDGN->max_x, anRegion[3]); psDGN->max_y = MAX(psDGN->max_y, anRegion[4]); psDGN->max_z = MAX(psDGN->max_z, anRegion[5]); } else { memcpy( &(psDGN->min_x), anRegion, sizeof(GInt32) * 6 ); psDGN->got_bounds = TRUE; } } psDGN->element_count++; nLa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -