AcEdJig 示例代码
本示例创建一个类,使用户能够通过选取椭圆的中心点,然后拖动以选择所需的长轴和短轴长度来创建椭圆。在拖动操作期间,用户可以随时看到椭圆的样子。 注意:
如果用户尝试使短轴比长轴长,则椭圆最终为圆形,因为半径比不能大于 1.0。 class AsdkEllipseJig : public AcEdJig // This class allows the user to create an ellipse by // picking its center point and then dragging to select the // desired major axis and minor axis lengths. During the // drag operations, the user will be able to visually see // what the ellipse looks like at any time. // { public: AsdkEllipseJig(const AcGePoint3d&, const AcGeVector3d&); void doIt(); virtual DragStatus sampler(); virtual Adesk::Boolean update(); virtual AcDbEntity* entity() const; private: AcDbEllipse *mpEllipse; AcGePoint3d mCenterPt, mAxisPt; AcGeVector3d mMajorAxis, mNormal; double mRadiusRatio; int mPromptCounter; }; // The following defines the constructor that accepts a point to be // used as the centerpoint of the ellipse and the current UCS normal // vector to be used as the normal for the ellipse. It also // initializes the radius ratio to a small value so that during // selection of the major axis, the ellipse will appear as a line. // The prompt counter is also initialized to 0. // AsdkEllipseJig::AsdkEllipseJig( const AcGePoint3d& pt, const AcGeVector3d& normal) : mCenterPt(pt), mNormal(normal), mRadiusRatio(0.00001), mPromptCounter(0) { } // This function creates an AcDbEllipse object and gets the // jig started acquiring the necessary info to properly fill // it in. // void AsdkEllipseJig::doIt() { mpEllipse = new AcDbEllipse; // Get the major axis vector from the user. // At this time, mPromptCounter == 0. // setDispPrompt("\nEllipse major axis: "); AcEdJig::DragStatus stat = drag(); // Get the ellipse's radius ratio. // mPromptCounter++; // now == 1 setDispPrompt("\nEllipse minor axis: "); stat = drag(); // Now add the ellipse to the database's current space. // append(); } // This function is called by the drag function to // acquire a sample input. // AcEdJig::DragStatus AsdkEllipseJig::sampler() { DragStatus stat; setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNoNegativeResponseAccepted | AcEdJig::kNoZeroResponseAccepted)); if (mPromptCounter == 0) { // Aquire the major axis endpoint. // // If the newly acquired point is the same as it was // in the last sample, then we return kNoChange so the // AsdkEllipseJig::update() function will not be called // and the last update call will be able to finish, thus // allowing the ellipse to fully elaborate. // static AcGePoint3d axisPointTemp; stat = acquirePoint(mAxisPt, mCenterPt); if (axisPointTemp != mAxisPt) axisPointTemp = mAxisPt; else if (stat == AcEdJig::kNormal) return AcEdJig::kNoChange; } else if (mPromptCounter == 1) { // Aquire the distance from ellipse center to minor // axis endpoint. This will be used to calculate the // radius ratio. // // If the newly acquired distance is the same as it was // in the last sample, then we return kNoChange so the // AsdkEllipseJig::update() function will not be called // and the last update call will be able to finish, thus // allowing the ellipse to fully elaborate. // static double radiusRatioTemp = -1; stat = acquireDist(mRadiusRatio, mCenterPt); if (radiusRatioTemp != mRadiusRatio) radiusRatioTemp = mRadiusRatio; else if (stat == AcEdJig::kNormal) return AcEdJig::kNoChange; } return stat; } // This function is called to update the entity based on the // input values. // Adesk::Boolean AsdkEllipseJig::update() { switch (mPromptCounter) { case 0: // At this time, mAxis contains the value of one // endpoint of the desired major axis. The // AcDbEllipse class stores the major axis as the // vector from the center point to where the axis // intersects the ellipse path (such as half of the true // major axis), so we already have what we need. // mMajorAxis = mAxisPt - mCenterPt; break; case 1: // Calculate the radius ratio. mRadiusRatio // currently contains the distance from the ellipse // center to the current pointer position. This is // half of the actual minor axis length. Since // AcDbEllipse stores the major axis vector as the // vector from the center point to the ellipse curve // (half the major axis), to get the radius ratio we // simply divide the value currently in mRadiusRatio // by the length of the stored major axis vector. // mRadiusRatio = mRadiusRatio / mMajorAxis.length(); break; } // Now update the ellipse with the latest setting. // mpEllipse->set(mCenterPt, mNormal, mMajorAxis, mRadiusRatio); return Adesk::kTrue; } // This function must be implemented to return a pointer to // the entity being manipulated by the jig. // AcDbEntity* AsdkEllipseJig::entity() const { return mpEllipse; } // This function uses the AcEdJig mechanism to create and // drag an ellipse entity. The creation criteria are // slightly different from the AutoCAD command. In this // case, the user selects an ellipse center point and // drags to visually select the major and minor axes // lengths. This sample is somewhat limited; if the // minor axis ends up longer than the major axis, then the // ellipse will just be round because the radius ratio // cannot be greater than 1.0. // void createEllipse() { // First, have the user select the ellipse center point. // We don't use the jig for this because there is // nothing to see yet. // AcGePoint3d tempPt; struct resbuf rbFrom, rbTo; acedGetPoint(NULL, "\nEllipse center point: ", asDblArray(tempPt)); // The point we just got is in UCS coordinates, but // AcDbEllipse works in WCS, so convert the point. // rbFrom.restype = RTSHORT; rbFrom.resval.rint = 1; // from UCS rbTo.restype = RTSHORT; rbTo.resval.rint = 0; // to WCS acedTrans(asDblArray(tempPt), &rbFrom, &rbTo, Adesk::kFalse, asDblArray(tempPt)); // Now you need to get the current UCS z-Axis to be used // as the normal vector for the ellipse. // AcGeVector3d x = acdbHostApplicationServices()->workingDatabase()->ucsxdir(); AcGeVector3d y = acdbHostApplicationServices()->workingDatabase()->ucsydir(); AcGeVector3d normalVec = x.crossProduct(y); normalVec.normalize(); // Create an AsdkEllipseJig object passing in the // center point just selected by the user and the normal // vector just calculated. // AsdkEllipseJig *pJig = new AsdkEllipseJig(tempPt, normalVec); // Now start up the jig to interactively get the major // and minor axes lengths. // pJig->doIt(); // Now delete the jig object, since it is no longer needed. // delete pJig; } void initApp() { acedRegCmds->addCommand("ASDK_VISUAL_ELLIPSE", "ASDK_VELLIPSE", "VELLIPSE", ACRX_CMD_MODAL, createEllipse); } void unloadApp() { acedRegCmds->removeGroup("ASDK_VISUAL_ELLIPSE"); } extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* appId) { switch (msg) { case AcRx::kInitAppMsg: acrxDynamicLinker->unlockApplication(appId); acrxDynamicLinker->registerAppMDIAware(appId); initApp(); break; case AcRx::kUnloadAppMsg: unloadApp(); } return AcRx::kRetOK; }
父主题: |
|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2024-12-15 22:10
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.