📄 dgnwrite.cpp
字号:
double dfPrimaryAxis, double dfSecondaryAxis, double dfStartAngle, double dfSweepAngle, double dfRotation, int *panQuaternion ){ DGNElemArc *psArc; DGNElemCore *psCore; DGNInfo *psDGN = (DGNInfo *) hDGN; DGNPoint sMin, sMax, sOrigin; GInt32 nAngle; CPLAssert( nType == DGNT_ARC || nType == DGNT_ELLIPSE ); DGNLoadTCB( hDGN );/* -------------------------------------------------------------------- *//* Allocate element. *//* -------------------------------------------------------------------- */ psArc = (DGNElemArc *) CPLCalloc( sizeof(DGNElemArc), 1 ); psCore = &(psArc->core); DGNInitializeElemCore( hDGN, psCore ); psCore->stype = DGNST_ARC; psCore->type = nType;/* -------------------------------------------------------------------- *//* Set arc specific information in the structure. *//* -------------------------------------------------------------------- */ sOrigin.x = dfOriginX; sOrigin.y = dfOriginY; sOrigin.z = dfOriginZ; psArc->origin = sOrigin; psArc->primary_axis = dfPrimaryAxis; psArc->secondary_axis = dfSecondaryAxis; memset( psArc->quat, 0, sizeof(int) * 4 ); psArc->startang = dfStartAngle; psArc->sweepang = dfSweepAngle; psArc->rotation = dfRotation; if( panQuaternion == NULL ) { DGNRotationToQuaternion( dfRotation, psArc->quat ); } else { memcpy( psArc->quat, panQuaternion, sizeof(long)*4 ); }/* -------------------------------------------------------------------- *//* Setup Raw data for the arc section. *//* -------------------------------------------------------------------- */ if( nType == DGNT_ARC ) { double dfScaledAxis; if( psDGN->dimension == 3 ) psCore->raw_bytes = 100; else psCore->raw_bytes = 80; psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1); /* start angle */ nAngle = (int) (dfStartAngle * 360000.0); DGN_WRITE_INT32( nAngle, psCore->raw_data + 36 ); /* sweep angle */ if( dfSweepAngle < 0.0 ) { nAngle = (int) (ABS(dfSweepAngle) * 360000.0); nAngle |= 0x80000000; } else if( dfSweepAngle > 364.9999 ) { nAngle = 0; } else { nAngle = (int) (dfSweepAngle * 360000.0); } DGN_WRITE_INT32( nAngle, psCore->raw_data + 40 ); /* axes */ dfScaledAxis = dfPrimaryAxis / psDGN->scale; memcpy( psCore->raw_data + 44, &dfScaledAxis, 8 ); IEEE2DGNDouble( psCore->raw_data + 44 ); dfScaledAxis = dfSecondaryAxis / psDGN->scale; memcpy( psCore->raw_data + 52, &dfScaledAxis, 8 ); IEEE2DGNDouble( psCore->raw_data + 52 ); if( psDGN->dimension == 3 ) { /* quaternion */ DGN_WRITE_INT32( psArc->quat[0], psCore->raw_data + 60 ); DGN_WRITE_INT32( psArc->quat[1], psCore->raw_data + 64 ); DGN_WRITE_INT32( psArc->quat[2], psCore->raw_data + 68 ); DGN_WRITE_INT32( psArc->quat[3], psCore->raw_data + 72 ); /* origin */ DGNInverseTransformPoint( psDGN, &sOrigin ); memcpy( psCore->raw_data + 76, &(sOrigin.x), 8 ); memcpy( psCore->raw_data + 84, &(sOrigin.y), 8 ); memcpy( psCore->raw_data + 92, &(sOrigin.z), 8 ); IEEE2DGNDouble( psCore->raw_data + 76 ); IEEE2DGNDouble( psCore->raw_data + 84 ); IEEE2DGNDouble( psCore->raw_data + 92 ); } else { /* rotation */ nAngle = (int) (dfRotation * 360000.0); DGN_WRITE_INT32( nAngle, psCore->raw_data + 60 ); /* origin */ DGNInverseTransformPoint( psDGN, &sOrigin ); memcpy( psCore->raw_data + 64, &(sOrigin.x), 8 ); memcpy( psCore->raw_data + 72, &(sOrigin.y), 8 ); IEEE2DGNDouble( psCore->raw_data + 64 ); IEEE2DGNDouble( psCore->raw_data + 72 ); } }/* -------------------------------------------------------------------- *//* Setup Raw data for the ellipse section. *//* -------------------------------------------------------------------- */ else { double dfScaledAxis; if( psDGN->dimension == 3 ) psCore->raw_bytes = 92; else psCore->raw_bytes = 72; psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1); /* axes */ dfScaledAxis = dfPrimaryAxis / psDGN->scale; memcpy( psCore->raw_data + 36, &dfScaledAxis, 8 ); IEEE2DGNDouble( psCore->raw_data + 36 ); dfScaledAxis = dfSecondaryAxis / psDGN->scale; memcpy( psCore->raw_data + 44, &dfScaledAxis, 8 ); IEEE2DGNDouble( psCore->raw_data + 44 ); if( psDGN->dimension == 3 ) { /* quaternion */ DGN_WRITE_INT32( psArc->quat[0], psCore->raw_data + 52 ); DGN_WRITE_INT32( psArc->quat[1], psCore->raw_data + 56 ); DGN_WRITE_INT32( psArc->quat[2], psCore->raw_data + 60 ); DGN_WRITE_INT32( psArc->quat[3], psCore->raw_data + 64 ); /* origin */ DGNInverseTransformPoint( psDGN, &sOrigin ); memcpy( psCore->raw_data + 68, &(sOrigin.x), 8 ); memcpy( psCore->raw_data + 76, &(sOrigin.y), 8 ); memcpy( psCore->raw_data + 84, &(sOrigin.z), 8 ); IEEE2DGNDouble( psCore->raw_data + 68 ); IEEE2DGNDouble( psCore->raw_data + 76 ); IEEE2DGNDouble( psCore->raw_data + 84 ); } else { /* rotation */ nAngle = (int) (dfRotation * 360000.0); DGN_WRITE_INT32( nAngle, psCore->raw_data + 52 ); /* origin */ DGNInverseTransformPoint( psDGN, &sOrigin ); memcpy( psCore->raw_data + 56, &(sOrigin.x), 8 ); memcpy( psCore->raw_data + 64, &(sOrigin.y), 8 ); IEEE2DGNDouble( psCore->raw_data + 56 ); IEEE2DGNDouble( psCore->raw_data + 64 ); } psArc->startang = 0.0; psArc->sweepang = 360.0; } /* -------------------------------------------------------------------- *//* Set the core raw data, including the bounds. *//* -------------------------------------------------------------------- */ DGNUpdateElemCoreExtended( hDGN, psCore ); sMin.x = dfOriginX - MAX(dfPrimaryAxis,dfSecondaryAxis); sMin.y = dfOriginY - MAX(dfPrimaryAxis,dfSecondaryAxis); sMin.z = dfOriginZ - MAX(dfPrimaryAxis,dfSecondaryAxis); sMax.x = dfOriginX + MAX(dfPrimaryAxis,dfSecondaryAxis); sMax.y = dfOriginY + MAX(dfPrimaryAxis,dfSecondaryAxis); sMax.z = dfOriginZ + MAX(dfPrimaryAxis,dfSecondaryAxis); DGNWriteBounds( psDGN, psCore, &sMin, &sMax ); return psCore;} /************************************************************************//* DGNCreateConeElem() *//************************************************************************//** * Create Cone element. * * Create a new 3D cone 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. * * @param hDGN the DGN file on which the element will eventually be written. * @param dfCenter1X the center of the first bounding circle (X). * @param dfCenter1Y the center of the first bounding circle (Y). * @param dfCenter1Z the center of the first bounding circle (Z). * @param dfRadius1 the radius of the first bounding circle. * @param dfCenter2X the center of the second bounding circle (X). * @param dfCenter2Y the center of the second bounding circle (Y). * @param dfCenter2Z the center of the second bounding circle (Z). * @param dfRadius2 the radius of the second bounding circle. * @param panQuaternion 3D orientation quaternion (NULL for default orientation - circles parallel to the X-Y plane). * * @return the new element (DGNElemCone) or NULL on failure. */DGNElemCore *DGNCreateConeElem( DGNHandle hDGN, double dfCenter_1X, double dfCenter_1Y, double dfCenter_1Z, double dfRadius_1, double dfCenter_2X, double dfCenter_2Y, double dfCenter_2Z, double dfRadius_2, int *panQuaternion ){ DGNElemCone *psCone; DGNElemCore *psCore; DGNInfo *psDGN = (DGNInfo *) hDGN; DGNPoint sMin, sMax, sCenter_1, sCenter_2; double dfScaledRadius; DGNLoadTCB( hDGN );/* -------------------------------------------------------------------- *//* Allocate element. *//* -------------------------------------------------------------------- */ psCone = (DGNElemCone *) CPLCalloc( sizeof(DGNElemCone), 1 ); psCore = &(psCone->core); DGNInitializeElemCore( hDGN, psCore ); psCore->stype = DGNST_CONE; psCore->type = DGNT_CONE;/* -------------------------------------------------------------------- *//* Set cone specific information in the structure. *//* -------------------------------------------------------------------- */ sCenter_1.x = dfCenter_1X; sCenter_1.y = dfCenter_1Y; sCenter_1.z = dfCenter_1Z; sCenter_2.x = dfCenter_2X; sCenter_2.y = dfCenter_2Y; sCenter_2.z = dfCenter_2Z; psCone->center_1 = sCenter_1; psCone->center_2 = sCenter_2; psCone->radius_1 = dfRadius_1; psCone->radius_2 = dfRadius_2; memset( psCone->quat, 0, sizeof(int) * 4 ); if( panQuaternion != NULL ) { memcpy( psCone->quat, panQuaternion, sizeof(long)*4 ); } else { psCone->quat[0] = 1 << 31; psCone->quat[1] = 0; psCone->quat[2] = 0; psCone->quat[3] = 0; }/* -------------------------------------------------------------------- *//* Setup Raw data for the cone. *//* -------------------------------------------------------------------- */ psCore->raw_bytes = 118; psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1); /* unknown data */ psCore->raw_data[36] = 0; psCore->raw_data[37] = 0; /* quaternion */ DGN_WRITE_INT32( psCone->quat[0], psCore->raw_data + 38 ); DGN_WRITE_INT32( psCone->quat[1], psCore->raw_data + 42 ); DGN_WRITE_INT32( psCone->quat[2], psCore->raw_data + 46 ); DGN_WRITE_INT32( psCone->quat[3], psCore->raw_data + 50 ); /* center_1 */ DGNInverseTransformPoint( psDGN, &sCenter_1 ); memcpy( psCore->raw_data + 54, &sCenter_1.x, 8 ); memcpy( psCore->raw_data + 62, &sCenter_1.y, 8 ); memcpy( psCore->raw_data + 70, &sCenter_1.z, 8 ); IEEE2DGNDouble( psCore->raw_data + 54 ); IEEE2DGNDouble( psCore->raw_data + 62 ); IEEE2DGNDouble( psCore->raw_data + 70 ); /* radius_1 */ dfScaledRadius = psCone->radius_1 / psDGN->scale; memcpy( psCore->raw_data + 78, &dfScaledRadius, 8 ); IEEE2DGNDouble( psCore->raw_data + 78 ); /* center_2 */ DGNInverseTransformPoint( psDGN, &sCenter_2 ); memcpy( psCore->raw_data + 86, &sCenter_2.x, 8 ); memcpy( psCore->raw_data + 94, &sCenter_2.y, 8 ); memcpy( psCore->raw_data + 102, &sCenter_2.z, 8 ); IEEE2DGNDouble( psCore->raw_data + 86 ); IEEE2DGNDouble( psCore->raw_data + 94 ); IEEE2DGNDouble( psCore->raw_data + 102 ); /* radius_2 */ dfScaledRadius = psCone->radius_2 / psDGN->scale; memcpy( psCore->raw_data + 110, &dfScaledRadius, 8 ); IEEE2DGNDouble( psCore->raw_data + 110 ); /* -------------------------------------------------------------------- *//* Set the core raw data, including the bounds. *//* -------------------------------------------------------------------- */ DGNUpdateElemCoreExtended( hDGN, psCore ); //FIXME: Calculate bounds. Do we need to take the quaternion into account? // kintel 20030819 // Old implementation attempt: // What if center_1.z > center_2.z ?// double largestRadius = // psCone->radius_1>psCone->radius_2?psCone->radius_1:psCone->radius_2;// sMin.x = psCone->center_1.x-largestRadius;// sMin.y = psCone->center_1.y-largestRadius;// sMin.z = psCone->center_1.z;// sMax.x = psCone->center_2.x+largestRadius;// sMax.y = psCone->center_2.y+largestRadius;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -