作者:成宣方

簡介: AutoCAD在中國有很廣泛的使用者基礎,同時也有很多專業的、業餘的開發人員。從R13版本開始,Autodesk 提供了ARX開發工具,物件導向的特性使開發人員如沐春風。有關ARX程式設計與ADS程式設計的比較這裡不再贅述,此處只講如何用ARX實現我們所要求的功能,不足之處請指正。

 

  許多二次開發軟體均提供超級編輯命令,如Genius 14、HMCAD 6.0等等。讀者或許對這些命令很感興趣,能不能自己開發類似的功能呢?只要您對C++和ARX程式設計有一些瞭解,利用Autodesk提供的ObjectARX SDK套裝軟體(可以到Autodesk網址上免費下載),您能很方便的寫出此類程式,雖說不能和專業人員提供的超級編輯命令相媲美,但也能給您帶來不少方便。本文利用ObjectARX提供的範例程式(缺省安裝ObjectARX SDK後的路徑是X:\OBJECTARX\ARXLABS\LAB07)進行簡單的修改即可實現我們所要求的功能。以下是採用ObjectARX SDK 2.0,在MSVC 5.0編譯環境下測試通過。

 

  首先我們要修改enttemp.h檔:

 

  原檔如下:

 

class EntTemperature : public AcRxObject

 

{

 

public:

 

ACRX_DECLARE_MEMBERS(EntTemperature);

 

virtual double reflectedEnergy(AcDbEntity* pEnt) const = 0;

 

};

 

將斜體部分修改成如下:

 

virtual Adesk::Boolean HgyModify(AcDbEntity* pEnt)

 

const = 0;

 

  因為我們以後要以EntTemperature作為基類,而且HgyModify函數在繼承類中要重寫並要求實現動態調用,故此處必須聲明為虛擬函數。Virtual關健字即為C++物件導向的重要的特性。

 

  第二、刪除tempapp.def檔中的energy文本。

 

  第三、修改tempapp.cpp檔:

 

  1、 刪除CircleTemperature、RigonTemperature及EllipseTemperature類的所有相關內容。

 

  2、 修改原檔中如下的內容:

 

class DefaultTemperature : public EntTemperature

 

{

 

public:

 

virtual double reflectedEnergy(AcDbEntity* pEnt) const;

 

};

 

double DefaultTemperature::reflectedEnergy

 

(AcDbEntity* pEnt) const

 

{

 

ads_printf("\nThis entity has no area, and no reflection.\n");

 

return -1.0;

 

}

 

修改後的內容如下:

 

class DefaultTemperature : public EntTemperature

 

{

 

public:

 

virtual Adesk::Boolean HgyModify(AcDbEntity* pEnt) const;

 

};

 

Adesk::Boolean DefaultTemperature::

 

HgyModify(AcDbEntity* pEnt) const

 

{

 

ads_printf("\nThe entity hasn't defined,

 

and nothing to be modified.\n");

 

return Acad::eOk;

 

}

 

為簡單起見,我們只對直線和圓定義超級編輯命令,

 

在此定義有關line和circle類。在tempapp.cpp

 

檔中增加CircleTemperature和LineTemperature類,

 

定義如下:

 

class CircleTemperature : public EntTemperature

 

{

 

public:

 

virtual Adesk::Boolean HgyModify(AcDbEntity* pEnt) const;

 

};

 

Adesk::Boolean

 

CircleTemperature::HgyModify(AcDbEntity* pEnt) const

 

{

 

AcDbCircle *pCircle = AcDbCircle::cast(pEnt);

 

if (!pCircle) {

 

ads_printf("The entity selected is not a circle\n");

 

pEnt- >close();

 

return Acad::eNotImplementedYet;

 

}

 

AcGePoint3d p,q;

 

double r;

 

p=P_TO_P(pCircle- >center());

 

if (getPoint((double*)(&p), "Center Point: ", p)== RTNORM

 

&& ads_getdist((double*)(&p), "Blob radius: ", &r) == RTNORM)

 

{

 

pCircle- >setCenter(p);

 

pCircle- >setRadius(r);

 

pCircle- >close();

 

}

 

return Acad::eOk;

 

}

 

class LineTemperature : public EntTemperature

 

{

 

public:

 

virtual Adesk::Boolean HgyModify(AcDbEntity* pEnt) const;

 

};

 

Adesk::Boolean

 

LineTemperature::HgyModify(AcDbEntity* pEnt) const

 

{

 

AcDbLine *pLine = AcDbLine::cast(pEnt);

 

if (!pLine) {

 

ads_printf("The entity selected is not a line.\n");

 

pEnt- >close();

 

return eNotImplementedYet;

 

}

 

AcGePoint3d p,q;

 

p= P_TO_P (pLine- >startPoint());

 

if (getPoint ((double*)(&p), "From Point: ", p)== RTNORM

 

&& getPoint((double*)(&p), "To point: ", q) == RTNORM)

 

{

 

pLine- >setStartPoint(p);

 

pLine- >setEndPoint(q);

 

pLine- >close();

 

}

 

return Acad::eOk;

 

}

 

  如您所見,HgyModify函數也要完全重寫。至此我們對CircleTemperature和LineTemperature的定義已經完成。上面P_TO_P()只是一個點對點賦值,getPoint()是自訂的取點函數。增加全域變數:這樣我們在初始化或清除記憶體過程中可以存取該類。

 

LineTemperature *pLineTemp;

 

CircleTemperature *pCircleTemp;

 

InitApp()函數中更改部分:

 

acedRegCmds- >addCommand("TEMPERATURE_APP",

 

"MODIFY", "MODIFY",

 

ACRX_CMD_TRANSPARENT, printEnergy);

 

更改程式中別的函數中的相應的部分。

 

注意printEnergy()函數中selectEntity()

 

函數的第二個參數必須是AcDb::kForWrite;

 

  編譯後在AutoCAD(如R14)中測試回合,敲入modify後隨便選取直線或圓,您就會能體會到超級編輯命令的方便之處。或許您會認為此命令沒有什麼特別之處,但若您仔細研究lab10子目錄中的內容,定義自己的實體如門、窗或機械特徵,特別是您自己才會用到的特殊物件,給物件增加此命令,您就會體會到ARX程式設計的魅力了。
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()