AcDbObjectId PostToMS(AcDbEntity *pEnt) { AcDbBlockTable *pBlkTbl; acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead); AcDbBlockTableRecord *pMS; pBlkTbl->getAt(ACDB_MODEL_SPACE,pMS,AcDb::kForWrite); pBlkTbl->close(); AcDbObjectId EntID; pMS->appendAcDbEntity(EntID,pEnt); pMS->close(); return EntID; }
static void ROYMyTest_Test3(void) { // Add your code for command ROYMyTest._Test3 here ads_point pt,SidePt; ads_name eName; if (acedEntSel(_T("\nSelect a polyline:"),eName,pt)!=RTNORM) return; ads_real dDistance; acedInitGet(RSG_NONEG | RSG_NOZERO,_T("")); CString strPrompt; struct resbuf rb; acedGetVar(_T("OFFSETDIST"),&rb); strPrompt.Format(_T("\nInput offset distance<%.2f>:"),rb.resval.rreal); int state; state=acedGetReal(strPrompt,&dDistance); switch (state) { case RTNONE: dDistance=rb.resval.rreal; break; case RTCAN: return; case RTNORM: default: break; } rb.resval.rreal=dDistance; acedSetVar(_T("OFFSETDIST"),&rb);
AcDbObjectId EntID; AcDbEntity *pEnt; if (acdbGetObjectId(EntID,eName)!=Acad::eOk || acedGetPoint(NULL,_T("\nPick up a point on side to offset:"),SidePt)!=RTNORM) return; if (acdbOpenAcDbEntity(pEnt,EntID,AcDb::kForRead)!=Acad::eOk) return;
AcDbPolyline *pPLine=NULL; if (!pEnt->isKindOf(AcDbPolyline::desc())) { pEnt->close(); return; } else pPLine=AcDbPolyline::cast(pEnt); if (pPLine==NULL) return;
AcGePoint3d ptOnPolyLine; if (pPLine->getClosestPointTo(asPnt3d(pt),ptOnPolyLine)!=Acad::eOk) { pPLine->close(); return; }
double dParam; AcGeLineSeg3d line3d; AcGeCircArc3d CirArc3d; AcGeLine3d *pOffsetRetLine3d=NULL; AcGeCircArc3d *pOffsetRetCirArc3d=NULL; AcGePoint3d SidePtClosestPtOnCurve; pPLine->getParamAtPoint(ptOnPolyLine,dParam); AcGeVoidPointerArray CurvePointers; AcGePoint3d PreStartPt,PreEndPt,OffsetedStartPt,OffsetedEndPt; AcGePoint3d arcCenterPt; AcGeVector3d OffsetPositiveDirection,CurveDirectionAtPt,ProjectVec,SidePtDirection; if (pPLine->segType((int)dParam)==AcDbPolyline::kLine) { pPLine->getLineSegAt((int)dParam,line3d); SidePtClosestPtOnCurve=line3d.closestPointTo(asPnt3d(SidePt)); CurveDirectionAtPt=line3d.direction(); SidePtDirection=SidePtClosestPtOnCurve-asPnt3d(SidePt); OffsetPositiveDirection=CurveDirectionAtPt.crossProduct(AcGeVector3d::kZAxis);  rojectVec=SidePtDirection.orthoProject(OffsetPositiveDirection.perpVector()); if (ProjectVec.isCodirectionalTo(OffsetPositiveDirection)) line3d.getTrimmedOffset(dDistance,AcGeVector3d::kZAxis,CurvePointers); else line3d.getTrimmedOffset(-1*dDistance,AcGeVector3d::kZAxis,CurvePointers); for (int i=0;i<CurvePointers.length();i++) { pOffsetRetLine3d=(AcGeLine3d*)CurvePointers.at(i); if (pOffsetRetLine3d!=NULL) { pOffsetRetLine3d->hasStartPoint(OffsetedStartPt); pOffsetRetLine3d->hasEndPoint(OffsetedEndPt); delete pOffsetRetLine3d; AcDbLine *pLine; pLine=new AcDbLine(); pLine->setStartPoint(OffsetedStartPt); pLine->setEndPoint(OffsetedEndPt);  ostToMS((AcDbEntity*)pLine); pLine->close(); } } } else if (pPLine->segType((int)dParam)==AcDbPolyline::kArc) { pPLine->getArcSegAt((int)dParam,CirArc3d); SidePtClosestPtOnCurve=CirArc3d.closestPointTo(asPnt3d(SidePt)); CurveDirectionAtPt=(CirArc3d.center()-SidePtClosestPtOnCurve).crossProduct( CirArc3d.normal()); SidePtDirection=SidePtClosestPtOnCurve-asPnt3d(SidePt); OffsetPositiveDirection=CurveDirectionAtPt.crossProduct(AcGeVector3d::kZAxis);  rojectVec=SidePtDirection.orthoProject(OffsetPositiveDirection.perpVector()); if (ProjectVec.isCodirectionalTo(OffsetPositiveDirection)) CirArc3d.getTrimmedOffset(dDistance,AcGeVector3d::kZAxis,CurvePointers); else CirArc3d.getTrimmedOffset(-1*dDistance,AcGeVector3d::kZAxis,CurvePointers);
if (CurvePointers.length()==0) { acutPrintf(_T("\n输入的偏移距离太大!")); return; } for (int i=0;i<CurvePointers.length();i++) { pOffsetRetCirArc3d=(AcGeCircArc3d*)CurvePointers.at(i); if (pOffsetRetCirArc3d!=NULL) { double dRadius; dRadius=pOffsetRetCirArc3d->radius(); pOffsetRetCirArc3d->hasStartPoint(OffsetedStartPt); pOffsetRetCirArc3d->hasEndPoint(OffsetedEndPt); arcCenterPt=pOffsetRetCirArc3d->center(); AcGeVector3d normalVec=pOffsetRetCirArc3d->normal(); delete pOffsetRetCirArc3d; AcDbArc *pArc; pArc=new AcDbArc(); pArc->setCenter(arcCenterPt); double dStartAngle=(OffsetedStartPt-arcCenterPt).angleOnPlane( AcGePlane::kXYPlane); double dEndAngle=(OffsetedEndPt-arcCenterPt).angleOnPlane( AcGePlane::kXYPlane); if (normalVec.isCodirectionalTo(AcGeVector3d::kZAxis)) { pArc->setStartAngle(dStartAngle); pArc->setEndAngle(dEndAngle); } else { pArc->setStartAngle(dEndAngle); pArc->setEndAngle(dStartAngle); } pArc->setRadius(dRadius);  ostToMS((AcDbEntity*)pArc); pArc->close(); } } } pPLine->close(); }
从多段线上直接偏移一条线段或是圆弧,就是偏移串接好多段线上的某个图元.
程序比较复杂,不知道有没有更好的方法!
难点是根据点选位置确定偏移方向!
|