dgnread.cpp
来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 1,808 行 · 第 1/5 页
CPP
1,808 行
*(psText->string + n) = (char) (w & 0xFF); n++; // skip 1 byte; } else { // if extend code area : 2 byte Korean character *(psText->string + n) = (char) (w >> 8); // hi *(psText->string + n + 1) = (char) (w & 0xFF); // lo n+=2; // 2 byte } } psText->string[n] = '\0'; // terminate C string } else { memcpy( psText->string, psDGN->abyElem + text_off, num_chars ); psText->string[num_chars] = '\0'; } } break; case DGNT_TCB: psElement = DGNParseTCB( psDGN ); break; case DGNT_COMPLEX_CHAIN_HEADER: case DGNT_COMPLEX_SHAPE_HEADER: { DGNElemComplexHeader *psHdr; psHdr = (DGNElemComplexHeader *) CPLCalloc(sizeof(DGNElemComplexHeader),1); psElement = (DGNElemCore *) psHdr; psElement->stype = DGNST_COMPLEX_HEADER; DGNParseCore( psDGN, psElement ); psHdr->totlength = psDGN->abyElem[36] + psDGN->abyElem[37] * 256; psHdr->numelems = psDGN->abyElem[38] + psDGN->abyElem[39] * 256; } break; case DGNT_TAG_VALUE: { DGNElemTagValue *psTag; psTag = (DGNElemTagValue *) CPLCalloc(sizeof(DGNElemTagValue),1); psElement = (DGNElemCore *) psTag; psElement->stype = DGNST_TAG_VALUE; DGNParseCore( psDGN, psElement ); psTag->tagType = psDGN->abyElem[74] + psDGN->abyElem[75] * 256; memcpy( &(psTag->tagSet), psDGN->abyElem + 68, 4 ); psTag->tagSet = CPL_LSBWORD32(psTag->tagSet); psTag->tagIndex = psDGN->abyElem[72] + psDGN->abyElem[73] * 256; psTag->tagLength = psDGN->abyElem[150] + psDGN->abyElem[151] * 256; if( psTag->tagType == 1 ) { psTag->tagValue.string = CPLStrdup( (char *) psDGN->abyElem + 154 ); } else if( psTag->tagType == 3 ) { memcpy( &(psTag->tagValue.integer), psDGN->abyElem + 154, 4 ); psTag->tagValue.integer = CPL_LSBWORD32( psTag->tagValue.integer ); } else if( psTag->tagType == 4 ) { memcpy( &(psTag->tagValue.real), psDGN->abyElem + 154, 8 ); DGN2IEEEDouble( &(psTag->tagValue.real) ); } } break; case DGNT_APPLICATION_ELEM: if( nLevel == 24 ) { psElement = DGNParseTagSet( psDGN ); } else { psElement = (DGNElemCore *) CPLCalloc(sizeof(DGNElemCore),1); psElement->stype = DGNST_CORE; DGNParseCore( psDGN, psElement ); } break; case DGNT_CONE: { DGNElemCone *psCone; psCone = (DGNElemCone *) CPLCalloc(sizeof(DGNElemCone),1); psElement = (DGNElemCore *) psCone; psElement->stype = DGNST_CONE; DGNParseCore( psDGN, psElement ); CPLAssert( psDGN->dimension == 3 ); psCone->unknown = psDGN->abyElem[36] + psDGN->abyElem[37] * 256; psCone->quat[0] = DGN_INT32( psDGN->abyElem + 38 ); psCone->quat[1] = DGN_INT32( psDGN->abyElem + 42 ); psCone->quat[2] = DGN_INT32( psDGN->abyElem + 46 ); psCone->quat[3] = DGN_INT32( psDGN->abyElem + 50 ); memcpy( &(psCone->center_1.x), psDGN->abyElem + 54, 8 ); DGN2IEEEDouble( &(psCone->center_1.x) ); memcpy( &(psCone->center_1.y), psDGN->abyElem + 62, 8 ); DGN2IEEEDouble( &(psCone->center_1.y) ); memcpy( &(psCone->center_1.z), psDGN->abyElem + 70, 8 ); DGN2IEEEDouble( &(psCone->center_1.z) ); memcpy( &(psCone->radius_1), psDGN->abyElem + 78, 8 ); DGN2IEEEDouble( &(psCone->radius_1) ); memcpy( &(psCone->center_2.x), psDGN->abyElem + 86, 8 ); DGN2IEEEDouble( &(psCone->center_2.x) ); memcpy( &(psCone->center_2.y), psDGN->abyElem + 94, 8 ); DGN2IEEEDouble( &(psCone->center_2.y) ); memcpy( &(psCone->center_2.z), psDGN->abyElem + 102, 8 ); DGN2IEEEDouble( &(psCone->center_2.z) ); memcpy( &(psCone->radius_2), psDGN->abyElem + 110, 8 ); DGN2IEEEDouble( &(psCone->radius_2) ); psCone->radius_1 *= psDGN->scale; psCone->radius_2 *= psDGN->scale; DGNTransformPoint( psDGN, &psCone->center_1 ); DGNTransformPoint( psDGN, &psCone->center_2 ); } break; case DGNT_3DSURFACE_HEADER: case DGNT_3DSOLID_HEADER: { DGNElemComplexHeader *psShape; psShape = (DGNElemComplexHeader *) CPLCalloc(sizeof(DGNElemComplexHeader),1); psElement = (DGNElemCore *) psShape; psElement->stype = DGNST_COMPLEX_HEADER; DGNParseCore( psDGN, psElement ); // Read complex header psShape->totlength = psDGN->abyElem[36] + psDGN->abyElem[37] * 256; psShape->numelems = psDGN->abyElem[38] + psDGN->abyElem[39] * 256; psShape->surftype = psDGN->abyElem[40]; psShape->boundelms = psDGN->abyElem[41] + 1; } break; case DGNT_BSPLINE_SURFACE_HEADER: { DGNElemBSplineSurfaceHeader *psSpline; psSpline = (DGNElemBSplineSurfaceHeader *) CPLCalloc(sizeof(DGNElemBSplineSurfaceHeader), 1); psElement = (DGNElemCore *) psSpline; psElement->stype = DGNST_BSPLINE_SURFACE_HEADER; DGNParseCore( psDGN, psElement ); // Read B-Spline surface header psSpline->desc_words = DGN_INT32(psDGN->abyElem + 36); psSpline->curve_type = psDGN->abyElem[41]; // U psSpline->u_order = (psDGN->abyElem[40] & 0x0f) + 2; psSpline->u_properties = psDGN->abyElem[40] & 0xf0; psSpline->num_poles_u = psDGN->abyElem[42] + psDGN->abyElem[43]*256; psSpline->num_knots_u = psDGN->abyElem[44] + psDGN->abyElem[45]*256; psSpline->rule_lines_u = psDGN->abyElem[46] + psDGN->abyElem[47]*256; // V psSpline->v_order = (psDGN->abyElem[48] & 0x0f) + 2; psSpline->v_properties = psDGN->abyElem[48] & 0xf0; psSpline->num_poles_v = psDGN->abyElem[50] + psDGN->abyElem[51]*256; psSpline->num_knots_v = psDGN->abyElem[52] + psDGN->abyElem[53]*256; psSpline->rule_lines_v = psDGN->abyElem[54] + psDGN->abyElem[55]*256; psSpline->num_bounds = psDGN->abyElem[56] + psDGN->abyElem[57]*556; } break; case DGNT_BSPLINE_CURVE_HEADER: { DGNElemBSplineCurveHeader *psSpline; psSpline = (DGNElemBSplineCurveHeader *) CPLCalloc(sizeof(DGNElemBSplineCurveHeader), 1); psElement = (DGNElemCore *) psSpline; psElement->stype = DGNST_BSPLINE_CURVE_HEADER; DGNParseCore( psDGN, psElement ); // Read B-Spline curve header psSpline->desc_words = DGN_INT32(psDGN->abyElem + 36); // flags psSpline->order = (psDGN->abyElem[40] & 0x0f) + 2; psSpline->properties = psDGN->abyElem[40] & 0xf0; psSpline->curve_type = psDGN->abyElem[41]; psSpline->num_poles = psDGN->abyElem[42] + psDGN->abyElem[43]*256; psSpline->num_knots = psDGN->abyElem[44] + psDGN->abyElem[45]*256; } break; case DGNT_BSPLINE_SURFACE_BOUNDARY: { DGNElemBSplineSurfaceBoundary *psBounds; int numverts = psDGN->abyElem[38] + psDGN->abyElem[39]*256; psBounds = (DGNElemBSplineSurfaceBoundary *) CPLCalloc(sizeof(DGNElemBSplineSurfaceBoundary)+ (numverts-1)*sizeof(DGNPoint), 1); psElement = (DGNElemCore *) psBounds; psElement->stype = DGNST_BSPLINE_SURFACE_BOUNDARY; DGNParseCore( psDGN, psElement ); // Read B-Spline surface boundary psBounds->number = psDGN->abyElem[36] + psDGN->abyElem[37]*256; psBounds->numverts = numverts; for (int i=0;i<psBounds->numverts;i++) { psBounds->vertices[i].x = DGN_INT32( psDGN->abyElem + 40 + i*8 ); psBounds->vertices[i].y = DGN_INT32( psDGN->abyElem + 44 + i*8 ); psBounds->vertices[i].z = 0; } } break; case DGNT_BSPLINE_KNOT: case DGNT_BSPLINE_WEIGHT_FACTOR: { DGNElemKnotWeight *psArray; // FIXME: Is it OK to assume that the # of elements corresponds // directly to the element size? kintel 20051215. int attr_bytes = psDGN->nElemBytes - (psDGN->abyElem[30] + psDGN->abyElem[31]*256)*2 - 32; int numelems = (psDGN->nElemBytes - 36 - attr_bytes)/4; psArray = (DGNElemKnotWeight *) CPLCalloc(sizeof(DGNElemKnotWeight) + (numelems-1)*sizeof(float), 1); psElement = (DGNElemCore *) psArray; psElement->stype = DGNST_KNOT_WEIGHT; DGNParseCore( psDGN, psElement ); // Read array for (int i=0;i<numelems;i++) { psArray->array[i] = 1.0f * DGN_INT32(psDGN->abyElem + 36 + i*4) / ((1L << 31) - 1); } } break; case DGNT_SHARED_CELL_DEFN: { DGNElemSharedCellDefn *psShared; psShared = (DGNElemSharedCellDefn *) CPLCalloc(sizeof(DGNElemSharedCellDefn),1); psElement = (DGNElemCore *) psShared; psElement->stype = DGNST_SHARED_CELL_DEFN; DGNParseCore( psDGN, psElement ); psShared->totlength = psDGN->abyElem[36] + psDGN->abyElem[37] * 256; } break; default: { psElement = (DGNElemCore *) CPLCalloc(sizeof(DGNElemCore),1); psElement->stype = DGNST_CORE; DGNParseCore( psDGN, psElement ); } break; }/* -------------------------------------------------------------------- *//* If the element structure type is "core" or if we are running *//* in "capture all" mode, record the complete binary image of *//* the element. *//* -------------------------------------------------------------------- */ if( psElement->stype == DGNST_CORE || (psDGN->options & DGNO_CAPTURE_RAW_DATA) ) { psElement->raw_bytes = psDGN->nElemBytes; psElement->raw_data = (unsigned char *)CPLMalloc(psElement->raw_bytes); memcpy( psElement->raw_data, psDGN->abyElem, psElement->raw_bytes ); }/* -------------------------------------------------------------------- *//* Collect some additional generic information. *//* -------------------------------------------------------------------- */ psElement->element_id = psDGN->next_element_id - 1; psElement->offset = VSIFTell( psDGN->fp ) - psDGN->nElemBytes; psElement->size = psDGN->nElemBytes; return psElement;}/************************************************************************//* DGNReadElement() *//************************************************************************//** * Read a DGN element. * * This function will return the next element in the file, starting with the * first. It is affected by DGNGotoElement() calls. * * The element is read into a structure which includes the DGNElemCore * structure. It is expected that applications will inspect the stype * field of the returned DGNElemCore and use it to cast the pointer to the * appropriate element structure type such as DGNElemMultiPoint. * * @param hDGN the handle of the file to read from. * * @return pointer to element structure, or NULL on EOF or processing error. * The structure should be freed with DGNFreeElement() when no longer needed. */DGNElemCore *DGNReadElement( DGNHandle hDGN ){ DGNInfo *psDGN = (DGNInfo *) hDGN; DGNElemCore *psElement = NULL; int nType, nLevel; int bInsideFilter;/* -------------------------------------------------------------------- *//* Load the element data into the current buffer. If a spatial *//* filter is in effect, loop until we get something within our *//* spatial constraints. *//* -------------------------------------------------------------------- */ do { bInsideFilter = TRUE; if( !DGNLoadRawElement( psDGN, &nType, &nLevel ) ) return NULL; if( psDGN->has_spatial_filter ) { GUInt32 nXMin, nXMax, nYMin, nYMax; if( !psDGN->sf_converted_to_uor ) DGNSpatialFilterToUOR( psDGN ); if( !DGNGetRawExtents( psDGN, nType, NULL, &nXMin, &nYMin, NULL, &nXMax, &nYMax, NULL ) ) { /* If we don't have spatial characterists for the element we will pass it through. */ bInsideFilter = TRUE; } else if( nXMin > psDGN->sf_max_x || nYMin > psDGN->sf_max_y || nXMax < psDGN->sf_min_x || nYMax < psDGN->sf_min_y ) bInsideFilter = FALSE; /* ** We want to select complex elements based on the extents of ** the header, not the individual elements. */ if( nType == DGNT_COMPLEX_CHAIN_HEADER || nType == DGNT_COMPLEX_SHAPE_HEADER )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?