📄 dgnwrite.cpp
字号:
}/* -------------------------------------------------------------------- *//* Clear location and id information. *//* -------------------------------------------------------------------- */ psClone->offset = -1; psClone->element_id = -1; return psClone;}/************************************************************************//* DGNUpdateElemCore() *//************************************************************************//** * Change element core values. * * The indicated values in the element are updated in the structure, as well * as in the raw data. The updated element is not written to disk. That * must be done with DGNWriteElement(). The element must have raw_data * loaded. * * @param hDGN the file on which the element belongs. * @param psElement the element to modify. * @param nLevel the new level value. * @param nGraphicGroup the new graphic group value. * @param nColor the new color index. * @param nWeight the new element weight. * @param nStyle the new style value for the element. * * @return Returns TRUE on success or FALSE on failure. */int DGNUpdateElemCore( DGNHandle hDGN, DGNElemCore *psElement, int nLevel, int nGraphicGroup, int nColor, int nWeight, int nStyle ){ psElement->level = nLevel; psElement->graphic_group = nGraphicGroup; psElement->color = nColor; psElement->weight = nWeight; psElement->style = nStyle; return DGNUpdateElemCoreExtended( hDGN, psElement );}/************************************************************************//* DGNUpdateElemCoreExtended() *//************************************************************************//** * Update internal raw data representation. * * The raw_data representation of the passed element is updated to reflect * the various core fields. The DGNElemCore level, type, complex, deleted, * graphic_group, properties, color, weight and style values are all * applied to the raw_data representation. Spatial bounds, element type * specific information and attributes are not updated in the raw data. * * @param hDGN the file to which the element belongs. * @param psElement the element to be updated. * * @return TRUE on success, or FALSE on failure. */int DGNUpdateElemCoreExtended( DGNHandle hDGN, DGNElemCore *psElement ){ GByte *rd = psElement->raw_data; int nWords = (psElement->raw_bytes / 2) - 2; if( psElement->raw_data == NULL || psElement->raw_bytes < 36 ) { CPLAssert( FALSE ); return FALSE; }/* -------------------------------------------------------------------- *//* Setup first four bytes. *//* -------------------------------------------------------------------- */ rd[0] = (GByte) psElement->level; if( psElement->complex ) rd[0] |= 0x80; rd[1] = (GByte) psElement->type; if( psElement->deleted ) rd[1] |= 0x80; rd[2] = (GByte) (nWords % 256); rd[3] = (GByte) (nWords / 256);/* -------------------------------------------------------------------- *//* If the attribute offset hasn't been set, set it now under *//* the assumption it should point to the end of the element. *//* -------------------------------------------------------------------- */ if( psElement->raw_data[30] == 0 && psElement->raw_data[31] == 0 ) { int nAttIndex = (psElement->raw_bytes - 32) / 2; psElement->raw_data[30] = (GByte) (nAttIndex % 256); psElement->raw_data[31] = (GByte) (nAttIndex / 256); }/* -------------------------------------------------------------------- *//* Handle the graphic properties. *//* -------------------------------------------------------------------- */ if( psElement->raw_bytes > 36 && DGNElemTypeHasDispHdr( psElement->type ) ) { rd[28] = (GByte) (psElement->graphic_group % 256); rd[29] = (GByte) (psElement->graphic_group / 256); rd[32] = (GByte) (psElement->properties % 256); rd[33] = (GByte) (psElement->properties / 256); rd[34] = (GByte) (psElement->style | (psElement->weight << 3)); rd[35] = (GByte) psElement->color; } return TRUE;}/************************************************************************//* DGNInitializeCore() *//************************************************************************/static void DGNInitializeElemCore( DGNHandle hDGN, DGNElemCore *psElement ){ memset( psElement, 0, sizeof(DGNElemCore) ); psElement->offset = -1; psElement->element_id = -1;}/************************************************************************//* DGNWriteBounds() *//* *//* Write bounds to element raw data. *//************************************************************************/static void DGNWriteBounds( DGNInfo *psInfo, DGNElemCore *psElement, DGNPoint *psMin, DGNPoint *psMax ){ CPLAssert( psElement->raw_bytes >= 28 ); DGNInverseTransformPointToInt( psInfo, psMin, psElement->raw_data + 4 ); DGNInverseTransformPointToInt( psInfo, psMax, psElement->raw_data + 16 ); /* convert from twos complement to "binary offset" format. */ psElement->raw_data[5] ^= 0x80; psElement->raw_data[9] ^= 0x80; psElement->raw_data[13] ^= 0x80; psElement->raw_data[17] ^= 0x80; psElement->raw_data[21] ^= 0x80; psElement->raw_data[25] ^= 0x80;}/************************************************************************//* DGNCreateMultiPointElem() *//************************************************************************//** * Create new multi-point element. * * The newly created element will still need to be written to file using * DGNWriteElement(). Also the level and other core values will be defaulted. * Use DGNUpdateElemCore() on the element before writing to set these values. * * NOTE: There are restrictions on the nPointCount for some elements. For * instance, DGNT_LINE can only have 2 points. Maximum element size * precludes very large numbers of points. * * @param hDGN the file on which the element will eventually be written. * @param nType the type of the element to be created. It must be one of * DGNT_LINE, DGNT_LINE_STRING, DGNT_SHAPE, DGNT_CURVE or DGNT_BSPLINE. * @param nPointCount the number of points in the pasVertices list. * @param pasVertices the list of points to be written. * * @return the new element (a DGNElemMultiPoint structure) or NULL on failure. */DGNElemCore *DGNCreateMultiPointElem( DGNHandle hDGN, int nType, int nPointCount, DGNPoint *pasVertices ){ DGNElemMultiPoint *psMP; DGNElemCore *psCore; DGNInfo *psDGN = (DGNInfo *) hDGN; int i; DGNPoint sMin, sMax; CPLAssert( nType == DGNT_LINE || nType == DGNT_LINE_STRING || nType == DGNT_SHAPE || nType == DGNT_CURVE || nType == DGNT_BSPLINE ); DGNLoadTCB( hDGN );/* -------------------------------------------------------------------- *//* Is this too many vertices to write to a single element? *//* -------------------------------------------------------------------- */ if( (psDGN->dimension == 2 && 38 + 8 * nPointCount >= 512) || (psDGN->dimension == 3 && 38 + 12 * nPointCount >= 512) ) { CPLError( CE_Failure, CPLE_ElementTooBig, "Attempt to create %s element with %d points failed.\n" "Element would be too large.", DGNTypeToName( nType ), nPointCount ); return NULL; }/* -------------------------------------------------------------------- *//* Allocate element. *//* -------------------------------------------------------------------- */ psMP = (DGNElemMultiPoint *) CPLCalloc( sizeof(DGNElemMultiPoint) + sizeof(DGNPoint) * (nPointCount-2), 1 ); psCore = &(psMP->core); DGNInitializeElemCore( hDGN, psCore ); psCore->stype = DGNST_MULTIPOINT; psCore->type = nType;/* -------------------------------------------------------------------- *//* Set multipoint specific information in the structure. *//* -------------------------------------------------------------------- */ psMP->num_vertices = nPointCount; memcpy( psMP->vertices + 0, pasVertices, sizeof(DGNPoint) * nPointCount );/* -------------------------------------------------------------------- *//* Setup Raw data for the multipoint section. *//* -------------------------------------------------------------------- */ if( nType == DGNT_LINE ) { CPLAssert( nPointCount == 2 ); psCore->raw_bytes = 36 + psDGN->dimension* 4 * nPointCount; psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1); DGNInverseTransformPointToInt( psDGN, pasVertices + 0, psCore->raw_data + 36 ); DGNInverseTransformPointToInt( psDGN, pasVertices + 1, psCore->raw_data + 36 + psDGN->dimension * 4 ); } else { CPLAssert( nPointCount >= 2 ); psCore->raw_bytes = 38 + psDGN->dimension * 4 * nPointCount; psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1); psCore->raw_data[36] = (unsigned char) (nPointCount % 256); psCore->raw_data[37] = (unsigned char) (nPointCount/256); for( i = 0; i < nPointCount; i++ ) DGNInverseTransformPointToInt( psDGN, pasVertices + i, psCore->raw_data + 38 + psDGN->dimension * i * 4 ); } /* -------------------------------------------------------------------- *//* Set the core raw data, including the bounds. *//* -------------------------------------------------------------------- */ DGNUpdateElemCoreExtended( hDGN, psCore ); sMin = sMax = pasVertices[0]; for( i = 1; i < nPointCount; i++ ) { sMin.x = MIN(pasVertices[i].x,sMin.x); sMin.y = MIN(pasVertices[i].y,sMin.y); sMin.z = MIN(pasVertices[i].z,sMin.z); sMax.x = MAX(pasVertices[i].x,sMax.x); sMax.y = MAX(pasVertices[i].y,sMax.y); sMax.z = MAX(pasVertices[i].z,sMax.z); } DGNWriteBounds( psDGN, psCore, &sMin, &sMax ); return psCore;}/************************************************************************//* DGNCreateArcElem2D() *//************************************************************************/DGNElemCore *DGNCreateArcElem2D( DGNHandle hDGN, int nType, double dfOriginX, double dfOriginY, double dfPrimaryAxis, double dfSecondaryAxis, double dfRotation, double dfStartAngle, double dfSweepAngle ){ return DGNCreateArcElem( hDGN, nType, dfOriginX, dfOriginY, 0.0, dfPrimaryAxis, dfSecondaryAxis, dfStartAngle, dfSweepAngle, dfRotation, NULL );} /************************************************************************//* DGNCreateArcElem() *//************************************************************************//** * Create Arc or Ellipse element. * * Create a new 2D or 3D arc or ellipse element. The start angle, and sweep * angle are ignored for DGNT_ELLIPSE but used for DGNT_ARC. * * The newly created element will still need to be written to file using * DGNWriteElement(). Also the level and other core values will be defaulted. * Use DGNUpdateElemCore() on the element before writing to set these values. * * @param hDGN the DGN file on which the element will eventually be written. * @param nType either DGNT_ELLIPSE or DGNT_ARC to select element type. * @param dfOriginX the origin (center of rotation) of the arc (X). * @param dfOriginY the origin (center of rotation) of the arc (Y). * @param dfOriginZ the origin (center of rotation) of the arc (Y). * @param dfPrimaryAxis the length of the primary axis. * @param dfSecondaryAxis the length of the secondary axis. * @param dfStartAngle start angle, degrees counterclockwise of primary axis. * @param dfSweepAngle sweep angle, degrees * @param dfRotation Counterclockwise rotation in degrees. * @param panQuaternion 3D orientation quaternion (NULL to use rotation). * * @return the new element (DGNElemArc) or NULL on failure. */DGNElemCore *DGNCreateArcElem( DGNHandle hDGN, int nType, double dfOriginX, double dfOriginY, double dfOriginZ,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -