//添加扩展数据
//实体添加扩展数据(字符串)
bool AddXData(CString appName, AcDbObjectId entId,CString data)
{
//open entity for read
AcDbEntity*pEnt;
Acad::ErrorStatus es=acdbOpenAcDbEntity(pEnt,entId,AcDb::kForRead);
if(es!=Acad::eOk)
{
ads_printf("error in open entity\n");
return false;
}
//get XData buffer
struct resbuf*pRb,*pTemp;
pRb=pEnt->xData(appName);
if(pRb!=NULL)//have XData
{
//pTemp移到表尾
pTemp=pRb;
for(pTemp=pRb;pTemp->rbnext!=NULL;pTemp=pTemp->rbnext){;}
}
else//NOT have XData
{
//create new xData
ads_regapp(appName);
pRb=ads_newrb(AcDb::kDxfRegAppName);
pRb->resval.rstring=(char*)malloc(appName.GetLength()+1);
strcpy(pRb->resval.rstring,appName);
pTemp=pRb;
}
//fill xData string
pTemp->rbnext=ads_newrb(AcDb::kDxfXdAsciiString);
pTemp=pTemp->rbnext;
pTemp->resval.rstring=(char*)malloc(data.GetLength()+1);
strcpy(pTemp->resval.rstring,data);
//add xData
es=pEnt->upgradeOpen();
if(es!=Acad::eOk)
{
ads_printf("\nError occur in updateOpen.");
pEnt->close();
ads_relrb(pRb);
return false;
}
es=pEnt->setXData(pRb);
if(es!=Acad::eOk)
{
ads_printf("\nError occur in setXData.");
pEnt->close();
ads_relrb(pRb);
return false;
}
//
pEnt->close();
ads_relrb(pRb);
return true;
}
//发命令前加按了两个ESCAPE
void SendCommand(char *cmd)
{
HWND wnd;
char cp[3];
wnd = adsw_acadMainWnd();
if(!wnd) return;
COPYDATASTRUCT cmddata;
cp[0] = VK_ESCAPE;
cp[1] = VK_ESCAPE;
cp[2] = NULL;
cmddata.dwData = (DWORD)1;
cmddata.cbData = (DWORD)strlen(cp)+1;
cmddata.lpData = cp;
SendMessage(wnd,WM_COPYDATA,(WPARAM)cp,(LPARAM)&cmddata);
cmddata.dwData = (DWORD)1;
cmddata.cbData = (DWORD)strlen(cmd)+1;
cmddata.lpData = cmd;
SendMessage(wnd,WM_COPYDATA,(WPARAM)wnd,(LPARAM)&cmddata);
}
//函数功能:根据用户指定的两点,自动创建破断线
void CAD_EXTBreakLine()
{
acutPrintf("指定两点,自动创建折线破断线\n");
ads_point StartPoint,EndPoint;
if(acedGetPoint(NULL,"\n请指定破断线的起点:",StartPoint)!=RTNORM) return;
if(acedGetPoint(StartPoint,"\n请指定破断线的终点:",EndPoint)!=RTNORM) return;
AcGePoint3d Start,End;
End = AcGePoint3d(EndPoint[X],EndPoint[Y],0);
Start = AcGePoint3d(StartPoint[X],StartPoint[Y],0);
float Length = Start.distanceTo(End);
AcGeVector3d Normal = End-Start;
Normal = Normal.normal(AcGeContext::gTol);
AcGePoint3d Point1(Start-Length*Normal*0.15);
AcGePoint3d Point2(Start+Length*Normal*0.45);
AcGePoint3d Point5(End-Length*Normal*0.45);
AcGePoint3d Point6(End+Length*Normal*0.15);
AcGeVector3d Normal2(-Normal.y,Normal.x,0);
AcGePoint3d Point3(Start+Length*Normal*0.5+Length*Normal2*0.10);
AcGePoint3d Point4(Start+Length*Normal*0.5-Length*Normal2*0.10);
AcGePoint3dArray vertices;
vertices.append(Point1);
vertices.append(Point2);
vertices.append(Point3);
vertices.append(Point4);
vertices.append(Point5);
vertices.append(Point6);
AddNewLayer("COMMANTARY");
AcDb2dPolyline* pBreakLine = new AcDb2dPolyline
(AcDb::k2dSimplePoly,vertices,0,Adesk::kTrue,0,0,NULL);
pBreakLine->setLayer("COMMANTARY",TRUE);
AcGeMatrix3d mat;
acdbUcsMatrix(mat,acdbHostApplicationServices()->workingDatabase());
pBreakLine->transformBy(mat);
pBreakLine->makeOpen();
AddEntityToDb(pBreakLine);
}
//******************生成回转体**********************
/* pt -- 旋转基点
ver -- 旋转轴
angle -- 旋转角度(角度制)
注意: 旋转轴不能垂直于面域平面、不能穿过面域*/
//**************************************************
void CreatRevolve(AcDbObjectId entid,
AcGeVector3d normal,
AcGePoint3d pt,
AcGeVector3d ver,
double angle)
{
Acad::ErrorStatus es;
AcDbCurve *curve;
AcDbObjectId tm;
if (acdbOpenObject(curve,entid,AcDb::kForWrite)!=Acad::eOk)
{
acutPrintf("打开实体失败!");
return ;
}
AcDbVoidPtrArray lines,regions1;
lines.append((void*)curve);
curve->close();
es = AcDbRegion::createFromCurves(lines,regions1);
if(es != Acad::eOk)
{
acutPrintf("获得面域失败!");
return ;
}
angle = angle*PI/180;
AcDbRegion *pregion1=AcDbRegion::cast((AcRxObject*)regions1[0]);
AcDb3dSolid *p3dobj = new AcDb3dSolid;
es = p3dobj->revolve(pregion1,pt,ver,angle);
if (es != Acad::eOk)
{
acutPrintf("建立回转体失败!请检查回转轴和基准点是否正确!");
}
pBlockTableRecord->appendAcDbEntity(tm,p3dobj);
p3dobj->close();
delete pregion1;
}
在ObjectARX 实现 Command 的 *Cancel* 功能: (类似 AutoLISP 中的 ^C)
acedCommand(0); // 就可以了
例如:
acedCommand (RTSTR, "dim1", RTSTR, "leader", RTSTR, "0,0", RTSTR, "10,10", 0);
acedCommand (0);
//复制对象
void cloneSameOwnerObjects()
{
// Step 1: Obtain the set of objects to be cloned.
ads_name sset;
if (acedSSGet(NULL, NULL, NULL, NULL, sset) != RTNORM) {
acutPrintf("\nNothing selected");
return;
}
// Step 2: Add obtained object IDs to list of objects
// to be cloned.
long length;
acedSSLength(sset, &length);
AcDbObjectIdArray objList;
AcDbObjectId ownerId = AcDbObjectId::kNull;
for (int i = 0; i < length; i++) {
ads_name ent;
acedSSName(sset, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
// Check to be sure this has the same owner as the first
// object.
//
AcDbObject *pObj;
acdbOpenObject(pObj, objId, AcDb::kForRead);
if (pObj->ownerId() == ownerId)
objList.append(objId);
else if (i == 0) {
ownerId = pObj->ownerId();
objList.append(objId);
}
pObj->close();
}
acedSSFree(sset);
// Step 3: Get the object ID of the desired owner for
// the cloned objects. We'll use model space for
// this example.
//
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbObjectId modelSpaceId;
pBlockTable->getAt(ACDB_MODEL_SPACE, modelSpaceId);
pBlockTable->close();
// Step 4: Create a new ID map.
//
AcDbIdMapping idMap;
// Step 5: Call deepCloneObjects().
//
acdbHostApplicationServices()->workingDatabase()
->deepCloneObjects(objList, modelSpaceId, idMap);
// Now we can go through the ID map and do whatever we'd
// like to the original and/or clone objects.
//
// For this example, we'll print out the object IDs of
// the new objects resulting from the cloning process.
//
AcDbIdMappingIter iter(idMap);
for (iter.start(); !iter.done(); iter.next()) {
AcDbIdPair idPair;
iter.getMap(idPair);
if (!idPair.isCloned())
continue;
acutPrintf("\nObjectId is: %Ld",
idPair.value().asOldId());
}
}
void selObj()
{
#ifdef OARXWIZDEBUG
acutPrintf ("\nOARXWIZDEBUG - caditdellayObjdellayObj() called.");
#endif // OARXWIZDEBUG
ads_name ents;
struct resbuf *rb;
AcDbEntity * pEnt;
AcDbText *sText;
AcDbObjectId objId;
ads_name ent;
rb=acutNewRb(AcDb::kDxfLayerName);
rb->rbnext=acutNewRb(AcDb::kDxfRegAppName);
rb->restype=8;
rb->resval.rstring="001";
rb=rb->rbnext;
rb->restype=1001;
rb->resval.rstring ="ll";
rb->rbnext=NULL;
acedSSGet("X",NULL,NULL,rb,ents);
long entNums=0;
acedSSLength(ents,&entNums);
if (entNums!= 0)
{
for (long a = 0; a < entNums ; a ++)
{
acedSSName(ents,a,ent);
// ads_entdel(ent);
acdbGetObjectId(objId, ent);
acdbOpenObject(pEnt, objId,AcDb::kForRead);
if(pEnt->isKindOf(AcDbText::desc()))
{
pEnt->close();
acdbOpenObject(sText, objId,AcDb::kForWrite);
ads_printf(sText->textString());
if (strcmp(sText->textString(),"text")==0)
{
sText->setHeight(100);
sText->setTextString("HELLO");
sText->setColorIndex(5);
}
sText->close();
}
else
{
pEnt->close();
}
}
}
acedSSFree(ents);
acutRelRb(rb);
// TODO: Implement the command
}
//转换AcDbCurve到AcGeCurve3d
Acad::ErrorStatus XdDbUtils::convertDbCurveToGeCurve(AcDbCurve *pDbCurve,AcGeCurve3d *&pGeCurve)
{
pGeCurve=NULL;
if (pDbCurve->isKindOf(AcDbLine::desc()))
{
AcDbLine *pL=(AcDbLine *)pDbCurve;
AcGeLineSeg3d *pGL=new AcGeLineSeg3d;
pGL->set(pL->startPoint(),pL->endPoint());
pGeCurve=(AcGeCurve3d *)pGL;
}
else if (pDbCurve->isKindOf(AcDbArc::desc()))
{
AcDbArc *pArc=(AcDbArc *)pDbCurve;
double ans,ane;
ans=pArc->startAngle();
ane=pArc->endAngle();
AcGeCircArc3d *pGArc=new AcGeCircArc3d;
pGArc->setCenter(pArc->center());
pGArc->setRadius(pArc->radius());
pGArc->setAngles(ans,ane);
pGeCurve=(AcGeCurve3d *)pGArc;
}
else if (pDbCurve->isKindOf(AcDbCircle::desc()))
{
AcDbCircle *pCir=(AcDbCircle *)pDbCurve;
AcGeCircArc3d * pGCir=new AcGeCircArc3d;
pGCir->setCenter(pCir->center());
pGCir->setRadius(pCir->radius());
pGeCurve=(AcGeCurve3d *)pGCir;
}
else if (pDbCurve->isKindOf(AcDbEllipse::desc()))
{
AcDbEllipse *pEli=(AcDbEllipse *)pDbCurve;
AcGePoint3d pt1,center=pEli->center();
AcGeEllipArc3d *pGEli=new AcGeEllipArc3d;
pGEli->setCenter(center);
pGEli->setAxes(pEli->majorAxis(),pEli->minorAxis());
pEli->getClosestPointTo(center,pt1,Adesk::kTrue);
pGEli->setMajorRadius(pt1.distanceTo(center)/pEli->radiusRatio());
pGEli->setMinorRadius(pt1.distanceTo(center));
double endang=pEli->endAngle(),startang=pEli->startAngle();
if (startang>endang){
endang+=2*PI;
}
pGEli->setAngles(endang,startang);
pGeCurve=(AcGeCurve3d *)pGEli;
}
else if (pDbCurve->isKindOf(AcDbSpline::desc()))
{
AcDbSpline *pSL=(AcDbSpline *)pDbCurve;
if (!pSL)
return Acad::eNotImplemented;
if (pSL->isNull()==Adesk::kTrue)
return Acad::eNotImplemented;
int degree;
Adesk::Boolean rational;
Adesk::Boolean closed;
Adesk::Boolean periodic;
AcGePoint3dArray controlPoints;
AcGeDoubleArray knots;
AcGeDoubleArray weights;
double controlPtTol;
double knotTol;
AcGeTol tol;
Acad::ErrorStatus es;
es=pSL->getNurbsData(degree,rational,closed,periodic,controlPoints,knots,weights,
controlPtTol,knotTol);
if (es!=Acad::eOk)
return Acad::eNotImplemented;
if (rational==Adesk::kTrue)
{
AcGeNurbCurve3d *pNurb=new AcGeNurbCurve3d(degree,knots,controlPoints,weights,periodic);
if (closed==Adesk::kTrue)
pNurb->makeClosed();
if (pSL->hasFitData()==Adesk::kTrue)
{
AcGePoint3dArray fitPoints;
double fitTolerance;
Adesk::Boolean tangentsExist;
AcGeVector3d startTangent;
AcGeVector3d endTangent;
pSL->getFitData(fitPoints,degree,fitTolerance,tangentsExist,startTangent,endTangent);
tol.setEqualPoint(fitTolerance);
if (tangentsExist==Adesk::kTrue)
pNurb->setFitData(fitPoints,startTangent,endTangent,tol);
else
pNurb->setFitData(degree,fitPoints,tol);
}
pGeCurve=(AcGeCurve3d *)pNurb;
}
else
{
AcGeNurbCurve3d *pNurb=new AcGeNurbCurve3d(degree,knots,controlPoints,periodic);
if (closed==Adesk::kTrue)
pNurb->makeClosed();
if (pSL->hasFitData()==Adesk::kTrue)
{
AcGePoint3dArray fitPoints;
double fitTolerance;
Adesk::Boolean tangentsExist;
AcGeVector3d startTangent;
AcGeVector3d endTangent;
pSL->getFitData(fitPoints,degree,fitTolerance,tangentsExist,startTangent,endTangent);
tol.setEqualPoint(fitTolerance);
if (tangentsExist==Adesk::kTrue)
pNurb->setFitData(fitPoints,startTangent,endTangent,tol);
else
pNurb->setFitData(degree,fitPoints,tol);
}
pGeCurve=(AcGeCurve3d *)pNurb;
}
}
else if ((pDbCurve->isKindOf(AcDb2dPolyline::desc()))||
(pDbCurve->isKindOf(AcDbPolyline::desc())))
{
int type=0;
AcDbPolyline *pPoly;
if (pDbCurve->isKindOf(AcDb2dPolyline::desc()))
{
AcDb2dPolyline *p2L=(AcDb2dPolyline *)pDbCurve;
XdDbUtils::Poly2dToLWPoly(p2L,pPoly);
type=1;
}
else
pPoly=(AcDbPolyline *)pDbCurve;
XdDbUtils::convertPolylineToGeCurve(pPoly,pGeCurve);
if (type)
delete pPoly;
}
return (pGeCurve)?Acad::eOk:Acad::eNotImplemented;
}