//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, SH Software Co. Ltd. // = FileName : 导出全局函数头文件 // = Version : ver2.0 // = Author : zjq // = CreateDate : 2002-09-09 // = Description: 全局函数的声明 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "XGlobalFunc.h" #include "XPoly.h" #include "XCircle.h" #include "XRectAngle.h" #include "XScreenDc.h" #include "XPushVar.h" #include "XPushMemVar.h" #include "XSearchRegionFromCurve.h" #include "XSearchRegionFromCurve.h" #include "XRegion.h" #include "XDbObject.h" #include "DStack.h" #include "XBlockTableRecPtr.h" #include "XDirectionCurve.h" #include "XCurveSegInters.h" #include "XCurveIntersection.h" #include "CTempTol.h" #include "XConfigBase.h" #include "XHoleModel.h" #include "AEntityBase.h" #include "XGlobalFunc.h" #include "XGlobalCurveFunc.h" #include "XPrivateGlobalFunc.h" #if ARX > 17 #include "AcStatusBar.h" #include "AecDbGrip.h" #include "AecDbGripDistDim.h" #include "AecDbGripAngleDim.h" #include "AecDbGripRadiusDim.h" #endif #include "XCurveInline.h" static int CompareDouble(const double *p1, const double *p2) { if(*p1>*p2) return 1; return -1; } static int CompareDouble(double x1, double x2) { if (fabs(x1 - x2) < _DIST_SNAP) { return 0; } if (x1 < x2) { return -1; } return 1; } static void GetPolyRect(const XPoint &ptCorn1, double nAngle, const XPoint &ptCorn2, XPoly2D &poly) { poly.Reset(); poly.SetFlag(1); XPoint pt1, pt2; XLine lnSide1(ptCorn1, nAngle); XLine lnSide2(ptCorn2, nAngle + PI / 2.0); lnSide1.Intersection(&lnSide2, pt1); XLine lnSide3(ptCorn1, nAngle + PI / 2.0); XLine lnSide4(ptCorn2, nAngle); lnSide3.Intersection(&lnSide4, pt2); poly.AppendNode(ptCorn1); poly.AppendNode(pt1); poly.AppendNode(ptCorn2); poly.AppendNode(pt2); } static XPoly2D g_polyRect; static double g_nRot; static XPoint g_ptCorn1; #if ARX > 22 static bool MouseMoveMonitor(MSG* msg) #else static BOOL MouseMoveMonitor(MSG* msg) #endif { if (!acdbCurDwg()) { return FALSE; } BOOL bRet = FALSE; switch(msg->message) { case WM_MOUSEMOVE: { CPoint ptClient = msg->pt; acedGetAcadDwgView()->ScreenToClient(&ptClient); int nVpNum = acedGetWinNum(ptClient.x, ptClient.y); int nCurVp = 0; VERIFY(xg_getvar(_T("CVPORT"), &nCurVp) == RTNORM); if (nVpNum == nCurVp) { XPoint ptDwgWcs, ptDwgDcs; BOOL nRetCode = TRUE; if (acedCoordFromPixelToWorld(nVpNum, ptClient, ptDwgWcs)) { XScreenDc dc(-1); if (g_polyRect.Length()) { dc << g_polyRect; } XPoint ptDwgUcs = Wcs2Ucs(ptDwgWcs); ptDwgUcs.z = g_ptCorn1.z; GetPolyRect(g_ptCorn1, g_nRot, ptDwgUcs, g_polyRect); dc << g_polyRect; } } } break; default: break; } return bRet; } static int GetRectAngle(const XPoint &ptCorn1, double nAngle, XPoint &ptCorn2) { int nRet = RTNORM; g_polyRect.Reset(); g_polyRect.SetFlag(1); g_nRot = nAngle; g_ptCorn1 = ptCorn1; acedRegisterFilterWinMsg(MouseMoveMonitor); nRet = ads_getpoint(NULL, _T(""), ptCorn2); acedRemoveFilterWinMsg(MouseMoveMonitor); g_polyRect.Reset(); ads_redraw(NULL,0); return nRet; } int XExport2::GetRectAngleStatic(const XPoint &ptCorn1, double nAngle, XPoint &ptCorn2) { return GetRectAngle(ptCorn1, nAngle, ptCorn2); } int XExport2::XGetCorner(const XPoint &ptCorn1, const TCHAR *pszMsg, XPoint &ptCorn2) { if (pszMsg) { XGeLib::adsout << pszMsg; } return GetRectAngle(ptCorn1, 0.0, ptCorn2); } XCell* XExport2::GetShape(const Point& pickPt) { XPushVar vOsMode(_T("OSMODE"), 0); Entity eL, entPline; eL.GetLast(); if (SHads_command(RTSTR, _T("-BOUNDARY"), RTPOINT, &pickPt, RTSTR, _T(""), RTNONE) == RTNORM) { Entity entNew; entNew.GetLast(); if (entNew == eL) { NULL; } else { entPline = entNew; } } if (!entPline) { return NULL; } else { XCell* presult; XPoly* pPoly = new XPoly(entPline); ads_point ptcen; double dw, dh; if (pPoly->Length() == 2) { presult = new XCircle(*(*pPoly)[0], *(*pPoly)[1]); } else if (pPoly->IsRectAngle(ptcen, &dw, &dh)) { presult = new XRectAngle(ptcen, dw, dh); } else { presult = NULL; } entPline.Delete(); PickSet ss(SS_FREE); RBList fence = pPoly->Fence(); if (ss.Get(_T("F"), fence) == RTNORM) { ads_redraw(NULL, 0); } if (presult) { delete pPoly; return presult; } return pPoly; } return NULL; } Acad::ErrorStatus XExport2::ExplodeBlockRef(AcDbBlockTableRecord &blockRec, ads_matrix matForInsert, DList &entSet) { AcGeMatrix3d mat; memcpy(&mat, matForInsert, sizeof(ads_matrix)); AcDbBlockTableRecordIterator* pBlockIterator; Acad::ErrorStatus es = blockRec.newIterator(pBlockIterator, Adesk::kTrue, Adesk::kFalse); ASSERT(es == Acad::eOk); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity; es = pBlockIterator->getEntity(pEntity, AcDb::kForRead, Adesk::kTrue); ASSERT(es == Acad::eOk); if (pEntity->visibility() == AcDb::kInvisible) { pEntity->close(); continue; } if (pEntity->isKindOf(AcDbLine::desc())) { //显示LINE AcDbLine *pLine = AcDbLine::cast(pEntity); AcGePoint3d ptStart = pLine->startPoint(), ptEnd = pLine->endPoint(); ptStart.transformBy(mat); ptEnd.transformBy(mat); entSet.Append(new AcDbLine(ptStart, ptEnd)); } else if (pEntity->isKindOf(AcDbArc::desc())) { AcDbArc *pArc = AcDbArc::cast(pEntity); XPoint ptCen; (AcGePoint3d &)ptCen = pArc->center(); XArc ar(ptCen, pArc->radius(), pArc->startAngle(), pArc->endAngle()); XPoint ptStart, ptEnd, ptMid; ar.GetStartPoint(ptStart); ar.GetEndPoint(ptEnd); ar.MidPoint(ptMid); ((AcGePoint3d &)ptStart).transformBy(mat); ((AcGePoint3d &)ptEnd).transformBy(mat); ((AcGePoint3d &)ptMid).transformBy(mat); XArc arNew(ptStart, ptMid, ptEnd); entSet.Append(new AcDbArc(arNew.GetCenterPt(), arNew.GetRadius(), arNew.GetStarAngle(), arNew.GetEndAngle())); } else { AcDbEntity *pEntCopy = NULL; if (pEntity->getTransformedCopy(mat, pEntCopy) == Acad::eOk && pEntCopy) { entSet.Append(pEntCopy); } } pEntity->close(); } delete pBlockIterator; return Acad::eOk; } // 由二维曲线, 求若干个最外边界轮廓线 int XExport2::GetExternalBoundaryFromCurves(const DList &lstSegs, DList &lstPolys) { if (!lstSegs.Length()) { return RTERROR; } DList ss; for (int i = 0; i &lstCurves, double dPrec) { DList ss1; int nCount = lstCurves.Length(); for (int nn = 0; nn < nCount; nn++) { XCurveSegment *pSeg = lstCurves[nn]; if (!pSeg->Is(CURVE_CIRCLE) && pSeg->GetLength() > _DIST_SNAP) { XCurveSegment *pNewSeg = new XCurveSegment(*pSeg); pNewSeg->SetLineFlag(LS_FINITE); ss1.Append(pNewSeg); } } int len1 = ss1.Length(); if (g_bEchoSearch) { acedSetStatusBarProgressMeter(_T("求交线"), 0, len1); } int nStep = len1/100; if (nStep<1) { nStep = 1; } DList *lstDistArray = new DList [len1]; for (int nn = 0; nn1 && !(nn%nStep)) { acedSetStatusBarProgressMeterPos(nn); } XCurveSegment &line1 = *ss1[nn]; for (int kk = nn+1; kk_DIST_SNAP) { lstDistArray[nn].Append(new double(nDist1)); } if (nDist2>_DIST_SNAP) { lstDistArray[kk].Append(new double(nDist2)); } } } } } lstCurves.Reset(); for (int nn = 0; nn &lstDistSeg = lstDistArray[nn]; XCurveSegment &line1 = *ss1[nn]; double nDist0 = line1.GetLength(); lstDistSeg.QuickSort(CompareDouble); lstDistSeg.Append(new double(nDist0)); XPoint &ptStart = line1.StartPoint(); XPoint ptS = ptStart; for (int kk = 0; kk_DIST_SNAP) { XCurveSegment *pSeg = new XCurveSegment(line1); pSeg->SetPoints(ptS, ptE); lstCurves.Append(pSeg); } ptS = ptE; } } delete [] lstDistArray; if (g_bEchoSearch) { acedRestoreStatusBar(); } } void XExport2::RemoveDupCurves(DList &lstCurves) { DList lstLines, lstCirArcs; ASSERT(lstCurves.GetDelFlag() != FALSE); lstCurves.SetDelFlag(FALSE); int nCount = lstCurves.Length(); for (int i = 0; iIs(CURVE_LINE)) { lstLines.Append(pSeg); } else { lstCirArcs.Append(pSeg); } } lstCurves.Reset(); lstCurves.SetDelFlag(TRUE); { XPushMemVar vTemp(g_bEchoSearch, FALSE); _RemoveDupCurves(lstCirArcs); lstCirArcs.SetDelFlag(FALSE); nCount = lstCirArcs.Length(); for (int i = 0; i &ss, XPoly2D &polyOutline) { DList lstSegs; for (int i = 0; iCenterPoly2D(polyOutline); polyOutline.Compress(); return RTNORM; } return RTERROR; } // 用区域裁剪实体 void XExport2::ClipEntitiesByPoly(XPoly2D & polyOutline, PickSet &ssBack) { PickSet ssBackInsert(SS_FREE), ssIn(SS_FREE), ssOut(SS_FREE), ssEdge(SS_FREE); ssBackInsert += ssBack; RBList rr((RTDXF0, _T("POLYLINE,LWPOLYLINE,INSERT,AEC_BLOCK_INSERT"), NULL)); ssBackInsert.BaseFilter(rr); ssBack -= ssBackInsert; // 裁剪曲线 PolyClip(ssBack, polyOutline, ssIn, ssOut, ssEdge); if (ssIn.Length()) { ssIn.Erase(); } if (ssEdge.Length()) { ssEdge.Erase(); } // 裁剪图块 long lCount = ssBackInsert.Length(); for (long idx = 0L; idxexplode(entSet); for (long i = 0;i0) { PickSet ssIn(SS_FREE), ssOut(SS_FREE), ssEdge(SS_FREE); PolyClip(ss,polyOutline, ssIn, ssOut,ssEdge); if (ssOut.Length() > 0)//裁剪发生 { if (ssIn.Length() > 0) { ssIn.Erase(); } if (ssEdge.Length() > 0) { ssEdge.Erase(); } if (bBlock) { XPoint ptInsert; entBack.GetData(10, &ptInsert); XString sNewBlockName(256); if (ssOut.MakeAnonymous(ptInsert, sNewBlockName, FALSE) == RTNORM) { OPENOBJ_BEGIN(entBack, AcDb::kForWrite, AcDbBlockReference, pInsert); if (pInsert) { pInsert->setBlockTableRecord(GetBlockIdFromString(sNewBlockName)); pInsert->setScaleFactors(AcGeScale3d(1.0,1.0,1.0)); pInsert->setRotation(0.0); } OPENOBJ_END(); } } else { entBack.Erase(); } } else { ss.Erase(); } } } } int XExport2::GetClipBoundary(XPoly2D &poly2d) { const TCHAR *szPrompts[2] = {_T("\n矩形的第一个角点或 [多边形裁剪(P)]<退出>:"), _T("\n多边形的第一点或 [矩形裁剪(R)]<退出>:")}; const TCHAR *szKeywords[2] = {_T("P"), _T("R")}; int nClipType = 0; XPoint ptStart; while(1) { XGeLib::adsout << szPrompts[nClipType]; int nCode; INITGET_BEG(0, szKeywords[nClipType]); nCode = ads_getpoint(NULL, _T(""), ptStart); INITGET_END(); if (nCode == RTKWORD) { nClipType = 1 - nClipType; } else { if (nCode == RTNORM) { break; } else { return nCode; } } } if (nClipType == 0) { XPoint ptOther; int nCode = XGetCorner(ptStart, _T("\n另一个角点<退出>:"), ptOther); if (nCode != RTNORM) { return nCode; } XRectAngle rect(ptStart, ptOther); rect.AsPoly2D(poly2d); } else { XPoint pt2; XScreenDc dc; dc.m_nDrawMode = 1; DStack aStack; aStack.Push(new XPoint(ptStart)); while(1) { XPoint &ptFrom = *aStack.Top(); if (aStack.Length() >= 3) { XGeLib::adsout << _T("\n下一点或 [回退(U)]<封闭>: "); } else { XGeLib::adsout << _T("\n下一点或 [回退(U)]<退出>: "); } int rc; INITGET_BEG(0, _T("U")); rc = ads_getpoint(ptFrom, _T(""), pt2); INITGET_END(); if (rc == RTCAN) { aStack.Reset(); return rc; } else if (rc == RTKWORD) { if (*aStack.Top() != ptStart) {// Not on first state XPoint *pPt2 = aStack.Pop(); XPoint *pPt1 = aStack.Top(); dc.SetColor(-1); dc << XLine(*pPt1, *pPt2); delete pPt2; } } else { if (rc == RTNONE) { if (aStack.Length() < 3) { return RTERROR; } else { pt2 = ptStart; } } XLine ln(*aStack.Top(), pt2); if (ln.GetLength() > _DIST_SNAP) { dc.SetColor(7); dc << ln; if (!(rc == RTNONE)) { aStack.Push(new XPoint(pt2)); } else { break; } } } } poly2d.Reset(); XPoint *ptCur = NULL; while((ptCur = aStack.Pop()) != NULL) { poly2d.AppendNode(*ptCur); delete ptCur; } poly2d.Compress(); if (!poly2d || poly2d.Length() < 3) { return RTERROR; } } return RTNORM; } // 从块表中取所有的曲线: 包括LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE,以及在INSERT中的前述实体 void XExport2::Get2DCurveFromBlock(AcDbBlockTableRecord &blockRec, ads_matrix matForInsert, DList &lstResult) { AcGeMatrix3d mat; memcpy(&mat, matForInsert, sizeof(ads_matrix)); AcDbBlockTableRecordIterator* pBlockIterator = NULL; Acad::ErrorStatus es = blockRec.newIterator(pBlockIterator, Adesk::kTrue, Adesk::kFalse); ASSERT(es == Acad::eOk && !!pBlockIterator); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity; es = pBlockIterator->getEntity(pEntity, AcDb::kForRead, Adesk::kTrue); ASSERT(es == Acad::eOk); if (pEntity->visibility() == AcDb::kInvisible) { pEntity->close(); continue; } if (pEntity->isKindOf(AcDbLine::desc())) { //显示LINE AcDbLine *pLine = AcDbLine::cast(pEntity); XPoint ptStart = pLine->startPoint(),ptEnd = pLine->endPoint(); ptStart.TransformBy(matForInsert); ptEnd.TransformBy(matForInsert); lstResult.Append(new XCurveSegment(ptStart, ptEnd, 0.0)); } else if (pEntity->isKindOf(AcDbArc::desc())) { AcDbArc *pArc = AcDbArc::cast(pEntity); XPoint ptCen; (AcGePoint3d &)ptCen = pArc->center(); XArc ar(ptCen, pArc->radius(), pArc->startAngle(), pArc->endAngle()); XPoint ptStart, ptEnd, ptMid; ar.GetStartPoint(ptStart); ar.GetEndPoint(ptEnd); ar.MidPoint(ptMid); ((AcGePoint3d &)ptStart).transformBy(mat); ((AcGePoint3d &)ptEnd).transformBy(mat); ((AcGePoint3d &)ptMid).transformBy(mat); XCurveSegment *pSeg = new XCurveSegment; *pSeg = XArc(ptStart, ptMid, ptEnd); lstResult.Append(pSeg); } else if (pEntity->isKindOf(AcDbCircle::desc())) { //圆的变换为近似, 不变半径 AcDbCircle *pCir = AcDbCircle::cast(pEntity); XPoint ptCen = pCir->center(); ptCen.TransformBy(matForInsert); XCurveSegment *pSeg = new XCurveSegment; *pSeg = XCircle(ptCen, pCir->radius()); lstResult.Append(pSeg); } else if (pEntity->isKindOf(AcDbPolyline::desc()) || pEntity->isKindOf(AcDb2dPolyline::desc())) { AcDbPolyline pline; Entity ent; acdbGetAdsName(ent.name, pEntity->objectId()); if (!(!ent)) { XPoly2D poly(ent); if (!poly) { ; } else { poly.TransUCS(matForInsert); for (int i = 0; iisKindOf(AcDbBlockReference::desc())) { //嵌套图块 AcDbBlockReference *pInsert = AcDbBlockReference::cast(pEntity); ASSERT(pInsert); XPoint ptLoc = pInsert->position(); double nRot = pInsert->rotation(); AcGeScale3d scale = pInsert->scaleFactors(); AcDbObjectId idBlock = pInsert->blockTableRecord(); XDbObject objBlock(idBlock, AcDb::kForRead); ASSERT(!!objBlock); AcDbBlockTableRecord *pRec = AcDbBlockTableRecord::cast(objBlock.m_pObject); ASSERT(pRec); XPoint ptBase = pRec->origin(); ads_matrix mat1, mat2; get_matrix(ptBase, ptLoc, scale[0], scale[1], scale[2], nRot, mat1); AT_multiply_matrix(matForInsert, mat1, mat2); Get2DCurveFromBlock(*pRec, mat2, lstResult); } pEntity->close(); } delete pBlockIterator; } // 由二维图块提取二维曲线段 int XExport2::GetCurveFromInsert2D(Entity &ent, DList &lstSegs) { if (!ent.Is(_T("INSERT")) && !ent.Is(_T("AEC_BLOCK_INSERT")) && !ent.Is(_T("AEC_MVINSERT"))) { return RTERROR; } ads_matrix mat; GetInsertMatrix(ent, mat); XString sBlockName(256); int nCode = (ent.Is(_T("AEC_MVINSERT"))? 1 : 2); VERIFY(ent.GetData(nCode, (TCHAR *)sBlockName) == RTNORM); XBlockTableRecPtr rec(sBlockName, AcDb::kForRead); ASSERT(!!rec); Get2DCurveFromBlock(*rec.m_pBlockTableRec, mat, lstSegs); return RTNORM; } // 有若干线搜索区域 int XExport2::SearchOutRegions(const DList &lstSeg1In, DList &lstDest) { XSearchRegionFromCurve aSearch; try { aSearch.InitStart(lstSeg1In); } catch(...) { XGeLib::adsout << /*UMSG*/_T("\n发生例外情况!"); return RTERROR; } if (aSearch.SearchRegions()) { DList lstOut; if (aSearch.GetOutsideRegions1(lstOut) && !!lstOut) { for (int n = 0; nCenterPoly2D(*pNewPoly) == RTNORM); pNewPoly->Compress(); lstDest.Append(pNewPoly); } } } return RTNORM; } // 把Poly2D分解为若干段曲线 void XExport2::ExplodePoly2D(const XPoly2D &poly, DList &lstSegs) { for (int i = 0; i_DIST_SNAP) { curveSegments.append(new AcDbLine(seg.GetStartPoint(), seg.GetEndPoint())); } } AcDbVoidPtrArray regions; if (AcDbRegion::createFromCurves(curveSegments, regions) == Acad::eOk && regions.length()>0) { AcDbRegion *regioni = (AcDbRegion *)regions[0]; regions.removeAt(0); XExport::ReleaseEntSet(regions); XExport::ReleaseEntSet(curveSegments); return regioni; } XExport::ReleaseEntSet(curveSegments); return NULL; } int XExport2::FindNearestEdge(const XPoly2D &poly, const XPoint &ptEdge) { int nEdge = -1; double nNearDist = 0.0; for (int i = 0; isetAssociative(Adesk::kFalse); pHatch->setPattern(AcDbHatch::kPreDefined,_T("SOLID")); pHatch->setHatchStyle(AcDbHatch::kNormal); bulges.setPhysicalLength(0).setLogicalLength(nVert + 1); vertices.setPhysicalLength(0).setLogicalLength(nVert + 1); int i(0); for (i = 0; iappendLoop(AcDbHatch::kExternal|AcDbHatch::kPolyline|AcDbHatch::kDerived,vertices,bulges); pHatch->evaluateHatch(true); return pHatch; } AcDbHatch * XExport2::NewHatchFromPoly2D(const XPoly2D &poly, const TCHAR *pszPattern0, double nScl) { XString sPattern; sPattern = pszPattern0; TCHAR *pScale = sPattern.StrChr(_T(':')); if (pScale) { *pScale = EOS; pScale++; double nScaleAdd = _tstof(pScale); if (nScaleAdd > 1.0E-6) { nScl *= nScaleAdd; } } AcGeDoubleArray bulges; AcGePoint2dArray vertices; int nVert = poly.Length(); AcDbHatch *pHatch = new AcDbHatch(); pHatch->setAssociative(Adesk::kFalse); pHatch->setPatternScale(nScl); pHatch->setHatchStyle(AcDbHatch::kNormal); if (pHatch->setPattern(AcDbHatch::kPreDefined, sPattern) != Acad::eOk) { delete pHatch; return NULL; } bulges.setPhysicalLength(0).setLogicalLength(nVert+1); vertices.setPhysicalLength(0).setLogicalLength(nVert+1); int i(0); for (i = 0; iappendLoop(AcDbHatch::kExternal | AcDbHatch::kPolyline | AcDbHatch::kDerived, vertices, bulges); Acad::ErrorStatus es; if ((es = pHatch->evaluateHatch(true)) != Acad::eOk) { delete pHatch; return NULL; } return pHatch; } AcDbHatch * XExport2::NewHatchFromPoly2D(const XPoly2D &poly, const TCHAR *pszPattern0, double nScl,double rotation) { XString sPattern; sPattern = pszPattern0; TCHAR *pScale = sPattern.StrChr(_T(':')); if (pScale) { *pScale = EOS; pScale++; double dScaleAdd = _tstof(pScale); if (dScaleAdd > 1.0E-6) { nScl *= dScaleAdd; } } AcGeDoubleArray bulges; AcGePoint2dArray vertices; int nVert = poly.Length(); AcDbHatch *pHatch = new AcDbHatch(); pHatch->setAssociative(Adesk::kFalse); pHatch->setPatternScale(nScl); pHatch->setPatternAngle(rotation); pHatch->setHatchStyle(AcDbHatch::kNormal); if (pHatch->setPattern(AcDbHatch::kPreDefined, sPattern) != Acad::eOk) { delete pHatch; return NULL; } bulges.setPhysicalLength(0).setLogicalLength(nVert + 1); vertices.setPhysicalLength(0).setLogicalLength(nVert + 1); int i(0); for (i = 0; iappendLoop(AcDbHatch::kExternal|AcDbHatch::kPolyline|AcDbHatch::kDerived,vertices,bulges); Acad::ErrorStatus es; if ((es = pHatch->evaluateHatch(true)) != Acad::eOk) { delete pHatch; return NULL; } return pHatch; } Acad::ErrorStatus XExport2::ReadPoly2D(AcDbDwgFiler *pFiler, XPoly2D &poly) { Adesk::UInt8 bIsClosed = 0; pFiler->readItem(&bIsClosed); Adesk::UInt16 nVertexCount = 0; pFiler->readItem(&nVertexCount); poly.Reset(); poly.SetFlag(bIsClosed); for (Adesk::UInt16 i = 0; ireadItem(&pt); pFiler->readItem(&bulge); poly.AppendNode(XPoint(pt[0],pt[1], 0.0), bulge); } return pFiler->filerStatus(); } Acad::ErrorStatus XExport2::WritePoly2D(AcDbDwgFiler *pFiler, const XPoly2D &poly) { pFiler->writeItem((Adesk::UInt8)poly.GetFlag()); Adesk::UInt16 nVertexCount = poly.Length(); pFiler->writeItem(nVertexCount); for (Adesk::UInt16 i = 0; iwriteItem(poly[i].AsAcGePoint2d()); pFiler->writeItem(poly.GetBulge(i)); } return pFiler->filerStatus(); } int XExport2::_SplitPoly2D(const XPoly2D &poly, const XPoint &pt1, const XPoint &pt2, XPoly2D &res1, XPoly2D &res2) { ASSERT(poly.IsClosed()); XPoint ptBreak[2] = {pt1, pt2}; XPoint ptOnPoly[2] = {pt1, pt2}; int nBreakIndex[2] = {-1,-1}; double minDist[2] = {-1.0, -1.0}; int nSeg = poly.TotalSegments(); for (int i = 0; iptEnd if (ads_distance(ptMin, seg.GetEndPoint()) < _DIST_SNAP) { continue; //忽略这一段 } double nBulge = 0.0; if (seg.IsMinusArc()) { XArc ar = seg.GetArc(); ar.SetAngleByPoints(seg.GetEndPoint(), ptMin); nBulge = -ar.Bulge(); } else { seg.SetPoints(ptMin, seg.GetEndPoint()); nBulge = seg.GetBulge(); } res1.AppendNode(ptMin, nBulge); } if (i == maxIndex) { // get ptStart->ptBreak if (ads_distance(ptMax, seg.GetStartPoint()) < _DIST_SNAP) { res1.AppendNode(ptMax, 0.0); continue; //忽略这一段 } double nBulge = 0.0; if (seg.IsMinusArc()) { XArc ar = seg.GetArc(); ar.SetAngleByPoints(ptMax, seg.StartPoint()); nBulge = -ar.Bulge(); } else { seg.SetPoints(seg.StartPoint(), ptMax); nBulge = seg.GetBulge(); } res1.AppendNode(seg.StartPoint(), nBulge); res1.AppendNode(ptMax, 0.0); } if (i != minIndex && i != maxIndex) { res1.AppendNode(seg.StartPoint(), seg.GetBulge()); } } // 取得res2 for (int i = maxIndex; i <= minIndex+nSeg; i++) { int idx = XExport::DePeriod(nSeg, i); XDirectionCurve seg; poly.Nth(idx, seg); if (idx == maxIndex) { // get ptBreak->ptEnd if (ads_distance(ptMax, seg.GetEndPoint()) < _DIST_SNAP) { continue; //忽略这一段 } double nBulge = 0.0; if (seg.IsMinusArc()) { XArc ar = seg.GetArc(); ar.SetAngleByPoints(seg.GetEndPoint(), ptMax); nBulge = -ar.Bulge(); } else { seg.SetPoints(ptMax, seg.GetEndPoint()); nBulge = seg.GetBulge(); } res2.AppendNode(ptMax, nBulge); } if (idx == minIndex) { // get ptStart->ptBreak if (ads_distance(ptMin, seg.GetStartPoint()) < _DIST_SNAP) { res2.AppendNode(ptMin, 0.0); continue; } double nBulge = 0.0; if (seg.IsMinusArc()) { XArc ar = seg.GetArc(); ar.SetAngleByPoints(ptMin, seg.StartPoint()); nBulge = -ar.Bulge(); } else { seg.SetPoints(seg.StartPoint(), ptMin); nBulge = seg.GetBulge(); } res2.AppendNode(seg.StartPoint(), nBulge); res2.AppendNode(ptMin, 0.0); } if (i != minIndex && i != maxIndex) { res2.AppendNode(seg.StartPoint(), seg.GetBulge()); } } return RTNORM; } int XExport2::SplitPoly2D(const XPoly2D &poly, const XPoint &pt1, const XPoint &pt2, XPoly2D &res1, XPoly2D &res2) { ASSERT(poly.IsClosed()); AcDbPolyline pline; XPoint ptOnCurve1, ptOnCurve2; XExport2::PolyConvert(poly, pline); if (pline.getClosestPointTo(pt1, ptOnCurve1) != Acad::eOk || pline.getClosestPointTo(pt2, ptOnCurve2) != Acad::eOk) { return RTERROR; } // ARX的SplitCurve有错误,因此自己编写 int nIndex1 = poly.HitTestOnCurve(ptOnCurve1); int nIndex2 = poly.HitTestOnCurve(ptOnCurve2); if (!nIndex1 || !nIndex2) { return RTERROR; } int nPeriod = poly.Length(); if (nIndex1>0 && nIndex2>0) { //顶点到顶点 int nVert1 = nIndex1-1; int nVert2 = nIndex2-1; if (nVert1 == nVert2) { return RTERROR; } // nVert1到nVert2 int nTo = (nVert2>nVert1) ? nVert2 : nVert2+nPeriod; for (int iVert = nVert1; iVert <= nTo; iVert++) { int idx = XExport::DePeriod(nPeriod, iVert); res1.AppendNode(poly[idx], poly.GetBulge(idx)); } // nVert2到nVert1 nTo = (nVert1>nVert2) ? nVert1 : nVert1+nPeriod; for (int iVert = nVert2; iVert <= nTo; iVert++) { int idx = XExport::DePeriod(nPeriod, iVert); res2.AppendNode(poly[idx], poly.GetBulge(idx)); } } else if (nIndex1<0 && nIndex2<0) { // 边到边 int nEdge1 = abs(nIndex1)-1; int nEdge2 = abs(nIndex2)-1; // Edge1到Edge2 XDirectionCurve seg; if (nEdge1 == nEdge2) { poly.Nth(nEdge1, seg); if (seg.PathDistance(ptOnCurve1)>seg.PathDistance(ptOnCurve2)&&seg.Is(CURVE_ARC))//add by w on 070302,解决两点在同一弧边的问题 { seg.SetPoints(ptOnCurve2, ptOnCurve1); seg.Reverse(); } else { seg.SetPoints(ptOnCurve1, ptOnCurve2); } res1.AppendNode(seg.StartPoint(), seg.GetBulge()); res1.AppendNode(seg.EndPoint(),0.0); } else { // 第一段 poly.Nth(nEdge1, seg); seg.SetPoints(ptOnCurve1, seg.GetEndPoint()); res1.AppendNode(seg.StartPoint(), seg.GetBulge()); // 中间段 int nToEdge = (nEdge2>nEdge1)? nEdge2 : nEdge2+nPeriod; for (int iVert = nEdge1+1; iVert <= nToEdge-1; iVert++) { int idx = XExport::DePeriod(nPeriod, iVert); res1.AppendNode(poly[idx], poly.GetBulge(idx)); } // 最后一段 poly.Nth(nEdge2, seg); seg.SetPoints(seg.StartPoint(), ptOnCurve2); res1.AppendNode(seg.StartPoint(), seg.GetBulge()); // 最后一点 res1.AppendNode(ptOnCurve2, 0.0); } // Edge2到Edge1 // 第一段 poly.Nth(nEdge2, seg); seg.SetPoints(ptOnCurve2, seg.EndPoint()); res2.AppendNode(seg.StartPoint(), seg.GetBulge()); // 中间段 int nToEdge = (nEdge1>nEdge2) ? nEdge1 : nEdge1+nPeriod; for (int iVert = nEdge2+1; iVert <= nToEdge-1; iVert++) { int idx = XExport::DePeriod(nPeriod, iVert); res2.AppendNode(poly[idx], poly.GetBulge(idx)); } // 最后一段 poly.Nth(nEdge1, seg); seg.SetPoints(seg.StartPoint(), ptOnCurve1); res2.AppendNode(seg.StartPoint(), seg.GetBulge()); // 最后一点 res2.AppendNode(ptOnCurve1, 0.0); } else if (nIndex1>0 && nIndex2<0) { //顶点到边 int nVert1 = nIndex1-1; int nEdge2 = abs(nIndex2)-1; // nVert1到Edge2 XDirectionCurve seg; // 中间段 int nToEdge = (nEdge2 >= nVert1)? nEdge2 : nEdge2+nPeriod; for (int iVert = nVert1; iVert <= nToEdge-1; iVert++) { int idx = XExport::DePeriod(nPeriod, iVert); res1.AppendNode(poly[idx], poly.GetBulge(idx)); } // 最后一段 poly.Nth(nEdge2, seg); seg.SetPoints(seg.StartPoint(), ptOnCurve2); res1.AppendNode(seg.StartPoint(), seg.GetBulge()); // 最后一点 res1.AppendNode(ptOnCurve2, 0.0); // Edge2到nVert1 // 第一段 poly.Nth(nEdge2, seg); seg.SetPoints(ptOnCurve2, seg.EndPoint()); res2.AppendNode(seg.StartPoint(), seg.GetBulge()); // 中间段 nToEdge = (nVert1 >= nEdge2) ? nVert1 : nVert1+nPeriod; for (int iVert = nEdge2+1; iVert <= nVert1-1; iVert++) { int idx = XExport::DePeriod(nPeriod, iVert); res2.AppendNode(poly[idx], poly.GetBulge(idx)); } // 最后一点 res2.AppendNode(ptOnCurve1, 0.0); } else { // 边到顶点 int nEdge1 = abs(nIndex1)-1; int nVert2 = nIndex2-1; // nEdge1到nVert2 XDirectionCurve seg; // 第一段 poly.Nth(nEdge1, seg); seg.SetPoints(ptOnCurve1, seg.EndPoint()); res1.AppendNode(seg.StartPoint(), seg.GetBulge()); // 中间段 int nToEdge = (nVert2>nEdge1) ? nVert2 : nVert2+nPeriod; for (int iVert = nEdge1+1; iVert <= nToEdge-1; iVert++) { int idx = XExport::DePeriod(nPeriod, iVert); res1.AppendNode(poly[idx], poly.GetBulge(idx)); } // 最后一点 res1.AppendNode(ptOnCurve2, 0.0); // nVert2到nEdge1 if (nEdge1 == nVert2) { poly.Nth(nEdge1, seg); seg.SetPoints(ptOnCurve2, ptOnCurve1); res1.AppendNode(seg.StartPoint(), seg.GetBulge()); res1.AppendNode(seg.EndPoint(),0.0); } else { // 中间段 int nToEdge = (nEdge1>nVert2) ? nEdge1 : nEdge1+nPeriod; for (int iVert = nVert2; iVert <= nToEdge-1; iVert++) { int idx = XExport::DePeriod(nPeriod, iVert); res2.AppendNode(poly[idx], poly.GetBulge(idx)); } // 最后一段 poly.Nth(nEdge1, seg); seg.SetPoints(seg.StartPoint(), ptOnCurve1); res2.AppendNode(seg.StartPoint(), seg.GetBulge()); //最后一点 res2.AppendNode(ptOnCurve1, 0.0); } } return RTNORM; } void XExport2::SplitPoly2D(const XPoly2D &poly, AcDbVoidPtrArray &entSet) { for (int i = 0; i < poly.TotalSegments(); i++) { XCurveSegment cv; if (poly.Nth(i, cv) == RTNORM) { if (cv.Is(CURVE_LINE)) { XLine ln = cv.GetLine(); entSet.append(new AcDbLine(ln.GetStartPoint(), ln.GetEndPoint())); } else if (cv.Is(CURVE_ARC)) { XArc ar = cv.GetArc(); entSet.append(new AcDbArc(ar.GetCenterPt(), ar.GetRadius(), ar.GetStarAngle(), ar.GetEndAngle())); } } } } // 把区域分解为曲线段 void XExport2::Region2Curves(const AcDbRegion *pClone, DList&lstSegs) { AcDbVoidPtrArray entSet; pClone->explode(entSet); int nLen = entSet.length(); for (int j = 0; j < nLen; j++) { AcDbEntity *pEnt = (AcDbEntity *)entSet[j]; AcRxClass *pClass = pEnt->isA(); if (pClass == AcDbLine::desc()) { AcDbLine *pLine = (AcDbLine *)pEnt; lstSegs.Append(new XCurveSegment(XPoint(pLine->startPoint()), XPoint(pLine->endPoint()), 0.0, LS_FINITE)); } else if (pClass == AcDbArc::desc()) { AcDbArc *pLine = (AcDbArc *)pEnt; XPoint ptCen; (AcGePoint3d &)ptCen = pLine->center(); XVector3D vtNormal; (AcGeVector3d &)vtNormal = pLine->normal(); ptCen = Wcs2Ecs(ptCen, vtNormal); XArc ar(ptCen, pLine->radius(), pLine->startAngle(), pLine->endAngle()); XCurveSegment *pSeg = new XCurveSegment; *pSeg = ar; lstSegs.Append(pSeg); } else if (pClass == AcDbPolyline::desc()) { XPoly2D polyTemp; XExport2::PolyConvert(*(AcDbPolyline *)pEnt, polyTemp); XExport2::ExplodePoly2D(polyTemp, lstSegs); } else if (pClass = AcDbRegion::desc()) { XExport2::Region2Curves((AcDbRegion *)pEnt, lstSegs); } } XExport::ReleaseEntSet(entSet); } int XExport2::HandleCurveInters(PickSet &ss, double dPrec) { //_angSnap = 0.001; _DIST_SNAP = 0.1; // for Debug PickSet ssNew(SS_FREE|SS_CREATE), ssCir(SS_FREE|SS_CREATE), ssDel(SS_FREE|SS_CREATE); XCurveSegInters::minLen = dPrec; ssNew.IncludeBegin(); XCurveSegInters::GlobalCurveList.Reset(); long len = ss.Length(); DList &curves = XCurveSegInters::GlobalCurveList; for (long i = 0; iGetLength() < _DIST_SNAP) { delete curve; ssDel += ss[i]; } else { curves.Append(curve); } } len = curves.Length(); for (int i = 0; iDivideToSegments(); if (curve->Update() == RTNORM && curve->Is(CURVE_CIRCLE)) { ssCir += curve->acadEnt; } } ssNew.IncludeEnd(); ss -= ssDel; ss -= ssCir; ss += ssNew; XCurveSegInters::GlobalCurveList.Reset(); ssDel.Erase(); ads_redraw(NULL, 0); return RTNORM; } // 连接桥的确定有问题 // 新的桥接算法 // 2D only int XExport2::ConnectPolygon(const XPolygonEx &poly1, const XPolygonEx &poly2, const XPolyDist &polyDist, XPolygonEx &res) { ASSERT(poly1.Length()>1 && poly2.Length()>1); int nIndex1 = polyDist.nIndex1; int num1 = poly1.Length(); int nIndex2 = polyDist.nIndex2; //poly2与pt最近的顶点 int num2 = poly2.Length(); res.Reset(); BOOL bOnVertex1 = FALSE, bOnVertex2 = FALSE; if (polyDist.ptLocation1.Distance2d(poly1.GetVertex(polyDist.nIndex1))<_DIST_SNAP) { bOnVertex1 = TRUE; } else if (polyDist.ptLocation1.Distance2d(poly1.GetVertex(polyDist.nIndex1+1))<_DIST_SNAP) { bOnVertex1 = TRUE; nIndex1++; } if (polyDist.ptLocation2.Distance2d(poly2.GetVertex(polyDist.nIndex2))<_DIST_SNAP) { bOnVertex2 = TRUE; } else if (polyDist.ptLocation2.Distance2d(poly2.GetVertex(polyDist.nIndex2+1))<_DIST_SNAP) { bOnVertex2 = TRUE; nIndex2++; } int j = 0, i = 0; if (bOnVertex1) { for (j = nIndex1; j1 && poly2.Length()>1); int nIndex1 = 0; int num1 = poly1.Length(); int nIndex2 = 0; //poly2与pt最近的顶点 double dMinDist = 0.0; int num2 = poly2.Length(); for (int j = 0; j &lstCurves, double dPrec) { XCurveIntersection::minLen = dPrec; XCurveIntersection::GlobalCurveList.Reset(); int len = lstCurves.Length(); for (int i = 0; iDivideToSegments(); XPoly2D poly; curve->segments.AsPoly2D(poly); for (int n = 0; n max(_DIST_SNAP,dPrec)) { lstCurves.Append(new XCurveSegment(seg)); } } } XCurveIntersection::GlobalCurveList.Reset(); if (g_bEchoSearch) { acedRestoreStatusBar(); } } // poly的坐标为当前UCS下的坐标 // ss1--inside; ss2--outside // Status: Only use in WCS int XExport2::PolyClip(const DList &ss, XPoly2D &poly, DList &ss1, DList &ss2) { int len = ss.Length(); for (int i = 0; iz); // Z坐标相等 PointList pts(seg.GetStartPoint(), seg.GetEndPoint(), seg.GetBulge()); IntersectWith(seg, poly, pts); // 先求出所有的交点,并排序 int listLen = pts.Length(); if (pts.curveType == CURVE_CIRCLE) { if (listLen <= 2) { // circle, but not cut to arcs XPoint mpt = seg.GetCircle().GetCenterPt(); if ((mpt&poly) == PR_INSIDE) { ss1.Append(new XCurveSegment(ss[i])); } else { ss2.Append(new XCurveSegment(ss[i])); } continue; } for (int i = 1; i &ss, const XPoly2D &poly1, DList &ss1, DList &ss2, DList &ssOnEdge) { XPoly2D &poly = (XPoly2D &)poly1; ASSERT(!!poly); int len = ss.Length(); for (int i = 0; iz); // Z坐标相等 PointList pts(seg.GetStartPoint(), seg.GetEndPoint(), seg.GetBulge()); IntersectWith(seg, poly, pts); // 先求出所有的交点,并排序 int listLen = pts.Length(); if (pts.curveType == CURVE_CIRCLE) { if (listLen <= 2) { // circle, but not cut to arcs XPoint mpt = seg.GetCircle().GetCenterPt(); if ((mpt&poly) == PR_INSIDE) { ss1.Append(new XCurveSegment(ss[i])); } else { ss2.Append(new XCurveSegment(ss[i])); } continue; } for (int i = 1; iz); // Z坐标相等 PointList pts(seg.GetStartPoint(), seg.GetEndPoint(), seg.GetBulge()); IntersectWith(seg, poly, pts); // 先求出所有的交点,并排序 int listLen = pts.Length(); Entity entRef = ent; if (pts.curveType == CURVE_CIRCLE) { if (listLen <= 2) { // circle, but not cut to arcs XPoint mpt = seg.GetCircle().GetCenterPt(); if ((mpt&poly) == PR_INSIDE) { ss1 += ent; } else { ss2 += ent; } continue; } // 圆被裁为弧 TCHAR lay[80] = _T("0"); entRef.GetData(8, lay); for (int i = 1; iz); // Z坐标相等 PointList pts(seg.GetStartPoint(), seg.GetEndPoint(), seg.GetBulge()); IntersectWith(seg, poly, pts); // 先求出所有的交点,并排序 int listLen = pts.Length(); Entity entRef = ent; if (pts.curveType == CURVE_CIRCLE) { if (listLen <= 2) { // circle, but not cut to arcs XPoint mpt = seg.GetCircle().GetCenterPt(); if ((mpt&poly) == PR_INSIDE) { ss1 += ent; } else { ss2 += ent; } continue; } // 圆被裁为弧 TCHAR lay[80] = _T("0"); entRef.GetData(8, lay); for (int i = 1; iexplode(arpCurve)) != Acad::eOk) { return; } int nLen = arpCurve.length(); if (nLen < 1) { XExport::ReleaseEntSet(arpCurve); return; } // 求由一组曲线组成的边界,返回polyline线 AcDbVoidPtrArray arpResult; AcDbCurve* pBound = ConvertCurves2Loops(arpCurve, arpResult); if (pBound == NULL) { XExport::ReleaseEntSet(arpCurve); return; } AcRxClass *pClass = pBound->isA(); if (pClass = AcDbPolyline::desc()) { // 将AcDbPolyline转化为XPoly2D XExport2::PolyConvert(*(AcDbPolyline *)pBound, poly2D); } XExport::ReleaseEntSet(arpCurve); if (pBound != NULL) { delete pBound; } // 设置闭合 poly2D.SetFlag(1); } // 布尔运算,与PolyBoolOper函数接口不变,但使用AcDbRegion::booleanOper函数,内部计算时,将标高设置为0 void XExport2::RegionBoolOper(const XPoly2D &poly1, const XPoly2D &poly2, DList &lstResult, AcDb::BoolOperType operation) { // 091119,临时将精确度改为g_globleSnap CTempTol globleTol(g_globleSnap); // 清空 lstResult.Reset(); XPoly2D pline1 = poly1, pline2 = poly2; // 强制设置PLine封闭 pline1.SetFlag(1); pline2.SetFlag(1); // 强制将标高设置为0 pline1.SetElevation(0.0); pline2.SetElevation(0.0); // 将PLine转化为Region AcDbRegion *pRegion1 = pline1.AsRegion(), *pRegion2 = pline2.AsRegion(); if (pRegion1 != NULL && pRegion2 != NULL) { // 对两区域进行布尔运算 if (pRegion1->booleanOper(operation, pRegion2) == Acad::eOk) { // 把区域分解为逆时针排列的XPoly2D XPoly2D *pNewPoly = new XPoly2D(1); XExport2::Region2XPoly2D(pRegion1, *pNewPoly); if (pNewPoly->Length() > 0) { lstResult.Append(pNewPoly); } else { delete pNewPoly; } } } if (pRegion1 != NULL) { delete pRegion1; } if (pRegion2 != NULL) { delete pRegion2; } } // 8.0先解决角度不大于MIN_PL_ANGEL的情况 // 自动处理封闭的XPoly2D,只处理外轮廓线 // 若某段长度不大于MIN_PL_DISTANCE,或者相临两段夹角不大于MIN_PL_ANGEL度,则自动减点 void XExport2::AutoDelExPoly2DPt(XPoly2D &poly) { int nLen = poly.Length(); // 总点数 if (nLen < 3) { return; } XPoly2D dest(1); // 设置闭合 double dAngle = 0.0, // 以当前点为顶点,前后点连线为边的夹角 dBulge = 0.0; // 当前点应该有的Bulge值 BOOL bAdd2Dest = TRUE; // 标记是否将当前点添加到dest中 int nPrev(0), nNext(0); // 前、后点标号 XPoint ptCur, ptPrev, ptNext; for (int i = 0; i < nLen; i++) { bAdd2Dest = TRUE; // 标记是否将当前点添加到dest中 // 封闭路径,周期查找 nPrev = XExport::DePeriod(nLen, i - 1); nNext = XExport::DePeriod(nLen, i + 1); ptCur = *poly[i]; // 当前点 ptPrev = *poly[nPrev]; // 前一点 ptNext = *poly[nNext]; // 后一点 dBulge = poly.GetBulge(i); // 默认取当前点的Bulge值 AcGeVector3d vec1 = ptPrev.AsAcGePoint3d() - ptCur.AsAcGePoint3d(), vec2 = ptNext.AsAcGePoint3d() - ptCur.AsAcGePoint3d(); dAngle = vec1.angleTo(vec2); // 角度在[0,PI]范围内 if (dAngle < MIN_PL_ANGEL + _angSnap) // 角度不大于1 { double dPrevBulge = poly.GetBulge(nPrev); if (fabs(dBulge)<_angSnap && fabs(dPrevBulge)<_angSnap) { bAdd2Dest = FALSE; continue; } } // 将当前点添加到dest中 if (bAdd2Dest) { dest.AppendNode(ptCur, dBulge); } } poly.Reset(); poly = dest; } void XExport2::GetGripPoints(const XPoly2D &poly, AcGePoint3dArray &gripPoints) { int nVertexCount = poly.Length(); for (int i = 0; i= nTotalEdge) { return Acad::eInvalidInput; } //移动边 XDirectionCurve cv; poly.Nth(nEdgeIndex, cv); ASSERT(!!cv); if (cv.Is(CURVE_LINE)) { // Move XLine ln = cv.GetLine(); ln.SetStartPoint(ln.GetStartPoint() + vtOffset); ln.SetEndPoint(ln.GetEndPoint() + vtOffset); ln.SetLineFlag(LS_INFINITE); XDirectionCurve prevSeg, nextSeg; int nPrev = nEdgeIndex-1, nNext = nEdgeIndex+1; if (poly.IsClosed()) { nPrev = XExport::DePeriod(nTotalEdge, nPrev); nNext = XExport::DePeriod(nTotalEdge, nNext); } XPoint ptStart, ptEnd; BOOL bUpdateIt = TRUE; //更新起点 if (nPrev >= 0 && nPrev= 0 && nNext 1.0E-5) { XArc prevArc = prevSeg.GetArc(); double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.GetStartPoint()); double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart); if (prevSeg.IsMinusArc()) { nPrevBulge = -XExport::CT_std_angle(nAngBeg-nAngEnd); } else { nPrevBulge = XExport::CT_std_angle(nAngEnd-nAngBeg); } } if (fabs(nextSeg.GetBulge()) > 1.0E-5) { XArc nextArc = nextSeg.GetArc(); double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd); double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.GetEndPoint()); if (nextSeg.IsMinusArc()) { nNextBulge = -XExport::CT_std_angle(nAngBeg-nAngEnd); } else { nNextBulge = XExport::CT_std_angle(nAngEnd-nAngBeg); } } *poly[nEdgeIndex] = ptStart; if (nNext >= 0 && nNext < poly.Length()) { *poly[nNext] = ptEnd; poly.SetBulge(nNext, nNextBulge); } if (nPrev >= 0 && nPrev < poly.Length()) { poly.SetBulge(nPrev, nPrevBulge); } } } else { // Change Arc Segment--bulge XPoint ptMid = cv.MidPoint(); XPoint ptMidNew = ptMid + vtOffset; XArc arNew(cv.GetStartPoint(), ptMidNew, cv.GetEndPoint()); if (!!arNew) { //新的弧有效 XCurveSegment cvLine(cv.GetStartPoint(), cv.GetEndPoint(), 0.0); int nSideOld = cvLine.OnWhichSide(ptMid); int nSideNew = cvLine.OnWhichSide(ptMidNew); double dSignal = cv.GetBulge() / fabs(cv.GetBulge()); if (nSideOld == nSideNew) { poly.SetBulge(nEdgeIndex, dSignal * arNew.Bulge()); } else { poly.SetBulge(nEdgeIndex, -dSignal * arNew.Bulge()); } } } } poly.Compress(false); return Acad::eOk; } void XExport2::GetGripPoints(const XPoly2D &poly,AcGeVector3d &normal,AcGePoint3dArray &gripPoints) { int nVertexCount = poly.Length(); for (int i = 0; i < nVertexCount; i++) { const XPoint &pt = poly[i]; gripPoints.append(Ecs2Wcs(pt,normal).AsAcGePoint3d()); } //边上的夹点 int nEdgeNum = poly.TotalSegments(); for (int i = 0; i < nEdgeNum; i++) { XCurveSegment seg; poly.Nth(i, seg); XPoint ptMid = seg.MidPoint(); gripPoints.append(Ecs2Wcs(ptMid,normal).AsAcGePoint3d()); } } Acad::ErrorStatus XExport2::MoveGripPointsAt(XPoly2D &polyPath, AcGeVector3d &vtNormal, const AcDbIntArray& indices, const AcGeVector3d& offset) { int nVertexCount = polyPath.Length(); XPoint vtOffset = Wcs2Ecs(*(XPoint *)&offset, vtNormal); for (int i = 0; i < indices.length(); i++) { int idx = indices[i]; if (idx= 0 && nPrev < nTotalEdge) { poly2d.Nth(nPrev, prevSeg); prevSeg.SetLineFlag(LS_INFINITE); XPoint ptInt[2]; int nIntNum = prevSeg.Intersection(ln, ptInt[0], ptInt[1]); if (nIntNum == 1) { ptStart = ptInt[0]; } else if (nIntNum == 2) { ptStart = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetStartPoint()); } else { bUpdateIt = FALSE; } } else { ptStart = *poly2d[nEdgeIndex] + vtOffset; } // 更新下一点 if (nNext >= 0 && nNext < nTotalEdge) { poly2d.Nth(nNext, nextSeg); nextSeg.SetLineFlag(LS_INFINITE); XPoint ptInt[2]; int nIntNum = nextSeg.Intersection(ln, ptInt[0], ptInt[1]); if (nIntNum == 1) { ptEnd = ptInt[0]; } else if (nIntNum == 2) { ptEnd = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetEndPoint()); } else { bUpdateIt = FALSE; } } else { ptEnd = *poly2d[nEdgeIndex+1] + vtOffset; } if (bUpdateIt) { double nPrevBulge = 0.0, nNextBulge = 0.0; if (fabs(prevSeg.GetBulge())>1.0E-5) { XArc prevArc = prevSeg.GetArc(); double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.GetStartPoint()); double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart); if (prevSeg.IsMinusArc()) { nPrevBulge = -XExport::CT_std_angle(nAngBeg-nAngEnd); } else { nPrevBulge = XExport::CT_std_angle(nAngEnd-nAngBeg); } } if (fabs(nextSeg.GetBulge()) > 1.0E-5) { XArc nextArc = nextSeg.GetArc(); double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd); double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.GetEndPoint()); if (nextSeg.IsMinusArc()) { nNextBulge = -XExport::CT_std_angle(nAngBeg-nAngEnd); } else { nNextBulge = XExport::CT_std_angle(nAngEnd-nAngBeg); } } *poly2d[nEdgeIndex] = ptStart; if (nNext >= 0 && nNext < poly2d.Length()) { *poly2d[nNext] = ptEnd; poly2d.SetBulge(nNext, nNextBulge); } if (nPrev >= 0 && nPrev < poly2d.Length()) { poly2d.SetBulge(nPrev, nPrevBulge); } } } else { // Change Arc Segment--bulge XPoint ptMid = cv.MidPoint(); XPoint ptMidNew = ptMid + vtOffset; XArc arNew(cv.GetStartPoint(), ptMidNew, cv.GetEndPoint()); if (!!arNew) { //新的弧有效 XCurveSegment cvLine(cv.GetStartPoint(), cv.GetEndPoint(), 0.0); int nSideOld = cvLine.OnWhichSide(ptMid); int nSideNew = cvLine.OnWhichSide(ptMidNew); double dSignal = cv.GetBulge()/fabs(cv.GetBulge()); if (nSideOld == nSideNew) { poly2d.SetBulge(nEdgeIndex, dSignal * arNew.Bulge()); } else { poly2d.SetBulge(nEdgeIndex, -dSignal * arNew.Bulge()); } } } for (int n = 0; nz = polyPath[n]->z; } polyPath = poly2d; } } } polyPath.Compress(false); return Acad::eOk; } Acad::ErrorStatus XExport2::GetGripText(const XPoly2D&poly,int idx,CString &cs) { Acad::ErrorStatus es = Acad::eNotApplicable; int nVertexCount = poly.Length(); if (idx 17 void XExport2::CreateGrip(AEntityBase* pThis,XPoly2D& poly,int iFirst) { XPoly2D&m_polyBase = poly; //节点 for (long i = 0;i < m_polyBase.Length();i++) { if (m_polyBase.IsClosed() || i > 0)//有前段 { bool bPreArc = fabs(m_polyBase.GetBulge((i - 1 + m_polyBase.Length()) % m_polyBase.Length())) > 1E-5;//前段是否为弧段 if (!bPreArc)//直段 { pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripDistDim(AcDbDimData::kDimResultantLength));//长度 } else//弧段 { pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//包络角度[0,360) } } if (m_polyBase.IsClosed() || i < m_polyBase.Length() - 1)//有后段 { bool bNextArc = fabs(m_polyBase.GetBulge(i % m_polyBase.Length())) > 1E-5;//后段的是否为弧段 if (!bNextArc)//直段 { pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripDistDim(AcDbDimData::kDimResultantLength));//长度 } else//弧段 { pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//包络角度[0,360) } } if (m_polyBase.IsClosed()||i>0)//有前段 { bool bPreArc = fabs(m_polyBase.GetBulge((i - 1 + m_polyBase.Length()) % m_polyBase.Length())) > 1E-5;//前段是否为弧段 if (!bPreArc)//直段 { pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//角度[0,180] } else//弧段 { pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//前弧终止角度[0,180] } } if (m_polyBase.IsClosed() || i < m_polyBase.Length() - 1)//有后段 { bool bNextArc = fabs(m_polyBase.GetBulge(i % m_polyBase.Length())) > 1E-5;//后段的是否为弧段 if (!bNextArc)//直段 { pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//角度[0,180] } else//弧段 { pThis->GetGrip(i + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//后弧起始角度[0,180] } } } //边中点 for (int i = 0;i 1E-5;//是否弧边 long iSeg = i+m_polyBase.Length(); if (bArc) { pThis->GetGrip(iSeg + iFirst)->AppendDim(new AecDbGripRadiusDim(AcDbDimData::kDimRadius));//半径 pThis->GetGrip(iSeg + iFirst)->AppendDim(new AecDbGripAngleDim(AcDbDimData::kDimResultantAngle));//包络角度[0,360) } else { pThis->GetGrip(iSeg + iFirst)->AppendDim(new AecDbGripDistDim(AcDbDimData::kDimDeltaLength,false));//偏移 } } } Acad::ErrorStatus XExport2::EntityToDim(AEntityBase* pThis,XPoly2D polyPath,long iGrip,long iDim,int iFirst) { AecDbGripDim *pDim = pThis->GetGripDim(iGrip,iDim); if (pDim == NULL) { return Acad::eInvalidInput; } iGrip -= iFirst; XPoly2D m_polyBase; AcGeVector3d normal; pThis->GetPathPoly(m_polyBase,normal); XPoint ptLow,ptUp; polyPath.GetExtend(ptLow,ptUp); //中点 if (iGrip >= polyPath.Length()) { int nPos = iGrip - polyPath.Length(); XDirectionCurve seg; polyPath.Nth(nPos, seg); bool bArc = fabs(polyPath.GetBulge(nPos)) > 1E-5;//是否为弧段 if (!bArc)//直段 { switch(iDim) { case 0: { AecDbGripDistDim* pDistDim = (AecDbGripDistDim*)pDim; XDirectionCurve seg1; m_polyBase.Nth(nPos, seg1); XPoint pt; seg1.ProjectToMe(seg.MidPoint().AsAcGePoint3d(),pt); pDistDim->SetData(pt.AsAcGePoint3d(),seg.MidPoint().AsAcGePoint3d(),0); } break; default: return Acad::eNotImplementedYet; } } else//弧段 { switch(iDim) { case 0: { AecDbGripRadiusDim* pRadiusDim = (AecDbGripRadiusDim* )pDim; pRadiusDim->SetData(seg.GetArc().GetCenterPt().AsAcGePoint3d(),seg.MidPoint().AsAcGePoint3d()); } break; case 1: { AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; if ( seg.GetBulge() < 0) { seg.Reverse(); } pAngleDim->SetData(seg); } break; default: return Acad::eNotImplementedYet; } } return Acad::eOk; } // 端点 bool bPre = polyPath.IsClosed() || iGrip > 0; int nPre = (iGrip - 1 + polyPath.Length()) % polyPath.Length(); XDirectionCurve segPre; polyPath.Nth(nPre, segPre); AcGeVector2d vtPre = segPre.Direction3d().AsAcGeVector2d(); bool bPreArc = fabs(polyPath.GetBulge(nPre)) > 1E-5;//前段是否为弧段 bool bNext = polyPath.IsClosed() || iGrip < polyPath.Length() - 1; int nNext = iGrip % polyPath.Length(); XDirectionCurve segNext; polyPath.Nth(nNext, segNext); AcGeVector2d vtNext = segNext.Direction3d().AsAcGeVector2d(); bool bNextArc = fabs(polyPath.GetBulge(nNext)) > 1E-5;//后段的是否为弧段 if (bPre && bNext) {// 有前段有后段 switch(iDim) { case 0: { if (!bPreArc)//长度 { AecDbGripDistDim* pDistDim = (AecDbGripDistDim* )pDim; double dGrip = vtPre.angle() - vtNext.angle(); if ( dGrip < -1E-6 ) { dGrip += 2 * PI; } if ( dGrip > 0 && dGrip < PI ) { segPre.Reverse(); } pDistDim->SetData(segPre.GetStartPoint().AsAcGePoint3d(), segPre.GetEndPoint().AsAcGePoint3d()); } else//包络角度 { AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; if ( segPre.GetBulge() < 0) { segPre.Reverse(); } pAngleDim->SetData(segPre); } } break; case 1: { if (!bNextArc)//长度 { AecDbGripDistDim* pDistDim = (AecDbGripDistDim* )pDim; double dGrip = vtPre.angle() - vtNext.angle(); if ( dGrip < -1E-6 ) { dGrip += 2 * PI; } if ( dGrip > 0 && dGrip < PI ) { segNext.Reverse(); } pDistDim->SetData(segNext.GetStartPoint().AsAcGePoint3d(), segNext.GetEndPoint().AsAcGePoint3d()); } else//包络角度 { AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; if ( segNext.GetBulge() < 0) { segNext.Reverse(); } pAngleDim->SetData(segNext); } } break; case 2: { if (!bPreArc)//角度 { AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; XPoint ptEnd = segPre.GetStartPoint() + XPoint(1000,0,0); pAngleDim->SetData(segPre.GetStartPoint().AsAcGePoint3d(),segPre.GetEndPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d()); } else//前弧终止角度 { AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; XArc arc = segPre.GetArc(); XPoint ptHorz = arc.GetCenterPt() + XPoint(arc.GetRadius(),0,0); pAngleDim->SetData(arc.GetCenterPt().AsAcGePoint3d(),segPre.GetEndPoint().AsAcGePoint3d(),ptHorz.AsAcGePoint3d()); } } break; case 3: { if (!bNextArc)//角度 { AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; XPoint ptEnd = segNext.GetEndPoint() + XPoint(1000,0,0); pAngleDim->SetData(segNext.GetEndPoint().AsAcGePoint3d(),segNext.GetStartPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d()); } else//前弧终止角度 { AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; XArc arc = segNext.GetArc(); XPoint ptHorz = arc.GetCenterPt() + XPoint(arc.GetRadius(),0,0); pAngleDim->SetData(arc.GetCenterPt().AsAcGePoint3d(),segNext.GetStartPoint().AsAcGePoint3d(),ptHorz.AsAcGePoint3d()); } } break; default: return Acad::eNotImplementedYet; } } else if (bPre && !bNext) {// 有前段无后段 switch(iDim) { case 0: { if (!bPreArc) {//长度 AecDbGripDistDim* pDistDim = (AecDbGripDistDim* )pDim; if ( segPre.Direction3d().y >= 0 ) { pDistDim->SetData(segPre.GetEndPoint().AsAcGePoint3d(), segPre.GetStartPoint().AsAcGePoint3d()); } else { pDistDim->SetData(segPre.GetStartPoint().AsAcGePoint3d(), segPre.GetEndPoint().AsAcGePoint3d()); } } else {//包络角度 AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; if ( segPre.GetBulge() < 0) { segPre.Reverse(); } pAngleDim->SetData(segPre); } } break; case 1: { if (!bPreArc) {//角度 AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; XPoint ptEnd = segPre.GetStartPoint() + XPoint(1000,0,0); pAngleDim->SetData(segPre.GetStartPoint().AsAcGePoint3d(),segPre.GetEndPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d()); } else {//后弧起始角度 AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; XArc arc = segPre.GetArc(); XPoint ptHorz = arc.GetCenterPt() + XPoint(arc.GetRadius(),0,0); pAngleDim->SetData(arc.GetCenterPt().AsAcGePoint3d(),segPre.GetEndPoint().AsAcGePoint3d(),ptHorz.AsAcGePoint3d()); } } break; default: return Acad::eNotImplementedYet; } } else if (!bPre && bNext) {// 无前段有后段 switch(iDim) { case 0: { if (!bNextArc) {//长度 AecDbGripDistDim* pDistDim = (AecDbGripDistDim* )pDim; if ( segNext.Direction3d().y >= 0 ) { pDistDim->SetData(segNext.GetEndPoint().AsAcGePoint3d(), segNext.GetStartPoint().AsAcGePoint3d()); } else { pDistDim->SetData(segNext.GetStartPoint().AsAcGePoint3d(), segNext.GetEndPoint().AsAcGePoint3d()); } } else {//包络角度 AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; if ( segNext.GetBulge() < 0) { segNext.Reverse(); } pAngleDim->SetData(segNext); } } break; case 1: { if (!bNextArc) {//角度 AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; XPoint ptEnd = segNext.GetEndPoint() + XPoint(1000,0,0); pAngleDim->SetData(segNext.GetEndPoint().AsAcGePoint3d(),segNext.GetStartPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d()); } else {//后弧起始角度 AecDbGripAngleDim* pAngleDim = (AecDbGripAngleDim* )pDim; XArc arc = segNext.GetArc(); XPoint ptHorz = arc.GetCenterPt() + XPoint(arc.GetRadius(),0,0); pAngleDim->SetData(arc.GetCenterPt().AsAcGePoint3d(),segNext.GetStartPoint().AsAcGePoint3d(),ptHorz.AsAcGePoint3d()); } } break; default: return Acad::eNotImplementedYet; } } else { return Acad::eNotImplementedYet; } return Acad::eOk; } Acad::ErrorStatus XExport2::DimToEntity(AEntityBase* pThis,XPoly2D &m_polyBase,long iGrip,long iDim,double newValue,const AcGeVector3d& offset,int iFirst) { AcGePoint3d ptNew = pThis->GetGripPoint(iGrip) + offset; iGrip -= iFirst; //中点 if (iGrip >= m_polyBase.Length()) { int nPos = iGrip - m_polyBase.Length(); bool bArc = fabs(m_polyBase.GetBulge(nPos)) > 1E-5;//是否为弧段 if (!bArc)//直段 { switch(iDim) { case 0://偏移 { XPoly2D poly2d(m_polyBase); poly2d.SetElevation(0.0); int nTotalEdge = poly2d.TotalSegments(); XDirectionCurve seg; poly2d.Nth(nPos, seg); AcGeVector3d vtOffset = offset; vtOffset.normalize(); double dAngle = vtOffset.angleTo(seg.Direction3d().AsAcGeVector3d()); vtOffset *= newValue / sin(dAngle); if (seg.OnWhichSide(ptNew) == 0) {//左边 newValue *= -1; } XLine ln = seg.GetLine(); ln = ln.Offset(newValue); ln.SetLineFlag( LS_INFINITE); XDirectionCurve prevSeg, nextSeg; int nPrev = nPos - 1; int nNext = nPos + 1; if (poly2d.IsClosed()) { nPrev = XExport::DePeriod(nTotalEdge, nPrev); nNext = XExport::DePeriod(nTotalEdge, nNext); } XPoint ptStart, ptEnd; BOOL bUpdateIt = TRUE; //更新起点 if (nPrev >= 0 && nPrev < nTotalEdge) { poly2d.Nth(nPrev, prevSeg); prevSeg.SetLineFlag( LS_INFINITE); XPoint ptInt[2]; int nIntNum = prevSeg.Intersection(ln, ptInt[0], ptInt[1]); if (nIntNum == 1) { ptStart = ptInt[0]; } else if (nIntNum == 2) { ptStart = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetStartPoint()); } else { bUpdateIt = FALSE; } } else { ptStart = *poly2d[nPos] + vtOffset; } // 更新下一点 if (nNext >= 0 && nNext < nTotalEdge) { poly2d.Nth(nNext, nextSeg); nextSeg.SetLineFlag(LS_INFINITE); XPoint ptInt[2]; int nIntNum = nextSeg.Intersection(ln, ptInt[0], ptInt[1]); if (nIntNum == 1) { ptEnd = ptInt[0]; } else if (nIntNum == 2) { ptEnd = XLine(ptInt[0], ptInt[1]).NearPoint(ln.GetEndPoint()); } else { bUpdateIt = FALSE; } } else { ptEnd = *poly2d[nPos + 1] + vtOffset; } if (bUpdateIt) { double nPrevBulge = 0.0, nNextBulge = 0.0; if (fabs(prevSeg.GetBulge()) > 1.0E-5) { XArc prevArc = prevSeg.GetArc(); double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.GetStartPoint()); double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart); if (prevSeg.IsMinusArc()) { nPrevBulge = -XExport::CT_std_angle(nAngBeg - nAngEnd); } else { nPrevBulge = XExport::CT_std_angle(nAngEnd - nAngBeg); } } if (fabs(nextSeg.GetBulge()) > 1.0E-5) { XArc nextArc = nextSeg.GetArc(); double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd); double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.GetEndPoint()); if (nextSeg.IsMinusArc()) { nNextBulge = -XExport::CT_std_angle(nAngBeg - nAngEnd); } else { nNextBulge = XExport::CT_std_angle(nAngEnd - nAngBeg); } } *poly2d[nPos] = ptStart; if (nNext >= 0 && nNext < poly2d.Length()) { *poly2d[nNext] = ptEnd; poly2d.SetBulge(nNext, nNextBulge); } if (nPrev >= 0 && nPrev < poly2d.Length()) { poly2d.SetBulge(nPrev, nPrevBulge); } for (int n = 0; n < poly2d.Length(); n++) { poly2d[n]->z = m_polyBase[n]->z; } m_polyBase = poly2d; } } break; } } else { XDirectionCurve seg; m_polyBase.Nth(nPos, seg); switch(iDim) { case 0://半径 { XCurveSegment line(seg.GetStartPoint(),seg.GetEndPoint(),0); double len = line.GetLength(); if (newValue < 0.5 * len) { return Acad::eInvalidInput; } newValue = 2.0 * asin(len* 0.5 / newValue); XPoint ptMid = seg.MidPoint(); if (ptMid.Distance2d(ptNew) > len / 2) { newValue = 2.0 * PI - newValue; } } case 1://包络角 { seg.SetBulge(0); if (seg.OnWhichSide(ptNew) == 0) {//左边 newValue *= -1; } m_polyBase.SetBulge(nPos, newValue); } break; } } return Acad::eOk; } // 端点 bool bPre = m_polyBase.IsClosed() || iGrip > 0; int nPre = (iGrip - 1 + m_polyBase.Length()) % m_polyBase.Length(); XDirectionCurve segPre; m_polyBase.Nth(nPre, segPre); bool bPreArc = fabs(m_polyBase.GetBulge(nPre)) > 1E-5;//前段是否为弧段 bool bNext = m_polyBase.IsClosed() || iGrip < m_polyBase.Length() - 1; int nNext = iGrip % m_polyBase.Length(); XDirectionCurve segNext; m_polyBase.Nth(nNext, segNext); bool bNextArc = fabs(m_polyBase.GetBulge(nNext)) > 1E-5;//后段的是否为弧段 if (bPre && bNext) {// 有前段有后段 switch(iDim) { case 0: { if (!bPreArc)//长度 { if (newValue>1E-6) { XPoint vt = segPre.Direction3d(); AcGeVector3d vt1 = ptNew - segPre.GetStartPoint().AsAcGePoint3d(); if (vt.AsAcGeVector3d().dotProduct(vt1) > 0) { vt *= newValue; } else { vt *= -newValue; } *m_polyBase[nPre + 1] = segPre.GetStartPoint() + vt; } } else//包络角度 { XArc arc = segPre.GetArc(); if (segPre.GetBulge() < 0) { arc.SetStarAngle(arc.GetEndAngle() - newValue); arc.GetStartPoint(segPre.StartPoint()); arc.GetEndPoint(segPre.EndPoint()); m_polyBase.SetBulge(nPre, -arc.Bulge()); *m_polyBase[nPre + 1] = segPre.GetStartPoint(); } else { arc.SetEndAngle(arc.GetStarAngle() + newValue); arc.GetStartPoint(segPre.StartPoint()); arc.GetEndPoint(segPre.EndPoint()); m_polyBase.SetBulge(nPre, arc.Bulge()); *m_polyBase[nPre + 1] = segPre.GetEndPoint(); } } } break; case 1: { if (!bNextArc) {//长度 if (newValue>1E-6) { XPoint vt = segNext.Direction3d(); AcGeVector3d vt1 = ptNew - segNext.GetEndPoint().AsAcGePoint3d(); if (vt.AsAcGeVector3d().dotProduct(vt1) > 0) { vt *= newValue; } else { vt *= -newValue; } *m_polyBase[nNext] = segNext.GetEndPoint() + vt; } } else {//包络角度 XArc arc = segNext.GetArc(); if (segNext.GetBulge() < 0) { arc.SetEndAngle(arc.GetStarAngle() + newValue); arc.GetStartPoint(segNext.StartPoint()); arc.GetEndPoint(segNext.EndPoint()); m_polyBase.SetBulge(nNext, -arc.Bulge()); *m_polyBase[nNext] = segNext.GetEndPoint(); } else { arc.SetStarAngle(arc.GetEndAngle() - newValue); arc.GetStartPoint(segNext.StartPoint()); arc.GetEndPoint(segNext.EndPoint()); m_polyBase.SetBulge(nNext, arc.Bulge()); *m_polyBase[nNext] = segNext.GetStartPoint(); } } } break; case 2: { if (!bPreArc) {//角度 AcGeVector3d vt1 = ptNew - segPre.GetStartPoint().AsAcGePoint3d(); if (vt1.y < 0) { newValue *= -1; } XPoint vt2(segPre.GetLength(),0,0); vt2.Rotate(newValue); *m_polyBase[nPre + 1] = segPre.GetStartPoint() + vt2; } else {//前弧终止角度 XArc arc = segPre.GetArc(); if (ptNew.y < arc.GetCenterPt().y) { newValue = 2.0 * PI - newValue; } if (segPre.GetBulge() < 0) { arc.SetStarAngle( newValue); arc.GetStartPoint(segPre.StartPoint()); arc.GetEndPoint(segPre.EndPoint()); m_polyBase.SetBulge(nPre, -arc.Bulge()); } else { arc.SetEndAngle(newValue); arc.GetStartPoint(segPre.StartPoint()); arc.GetEndPoint(segPre.EndPoint()); m_polyBase.SetBulge(nPre, arc.Bulge()); } *m_polyBase[nPre + 1] = segPre.GetEndPoint(); } } break; case 3: { if (!bNextArc) {//角度 AcGeVector3d vt1 = ptNew - segNext.GetEndPoint().AsAcGePoint3d(); if (vt1.y < 0) { newValue *= -1; } XPoint vt2(segNext.GetLength(),0,0); vt2.Rotate(newValue); *m_polyBase[nNext] = segNext.GetEndPoint() + vt2; } else {//后弧起始角度 XArc arc = segNext.GetArc(); if (ptNew.y < arc.GetCenterPt().y) { newValue = 2.0 * PI - newValue; } if (segNext.GetBulge() < 0) { arc.SetEndAngle(newValue); arc.GetStartPoint(segNext.StartPoint()); arc.GetEndPoint(segNext.EndPoint()); m_polyBase.SetBulge(nNext, -arc.Bulge()); } else { arc.SetStarAngle(newValue); arc.GetStartPoint(segNext.StartPoint()); arc.GetEndPoint(segNext.EndPoint()); m_polyBase.SetBulge(nNext, arc.Bulge()); } *m_polyBase[nNext] = segNext.GetStartPoint(); } } break; } } else if (bPre && !bNext) {// 有前段无后段 switch(iDim) { case 0: { if (!bPreArc)//长度 { if (newValue > 1E-6) { XPoint vt = segPre.Direction3d(); AcGeVector3d vt1 = ptNew - segPre.GetStartPoint().AsAcGePoint3d(); if (vt.AsAcGeVector3d().dotProduct(vt1) > 0) { vt *= newValue; } else { vt *= -newValue; } *m_polyBase[nPre + 1] = segPre.GetStartPoint() + vt; } } else//包络角度 { XArc arc = segPre.GetArc(); if (segPre.GetBulge() < 0) { arc.SetStarAngle(arc.GetEndAngle() - newValue); arc.GetStartPoint(segPre.StartPoint()); arc.GetEndPoint(segPre.EndPoint()); m_polyBase.SetBulge(nPre, -arc.Bulge()); *m_polyBase[nPre + 1] = segPre.GetStartPoint(); } else { arc.SetEndAngle(arc.GetStarAngle() + newValue); arc.GetStartPoint(segPre.StartPoint()); arc.GetEndPoint(segPre.EndPoint()); m_polyBase.SetBulge(nPre, arc.Bulge()); *m_polyBase[nPre + 1] = segPre.GetEndPoint(); } } } break; case 1: { if (!bPreArc) {//角度 AcGeVector3d vt1 = ptNew - segPre.GetStartPoint().AsAcGePoint3d(); if (vt1.y < 0) { newValue *= -1; } XPoint vt2(segPre.GetLength(),0,0); vt2.Rotate(newValue); *m_polyBase[nPre + 1] = segPre.GetStartPoint() + vt2; } else {//前弧终止角度 XArc arc = segPre.GetArc(); if (ptNew.y < arc.GetCenterPt().y) { newValue = 2.0 * PI - newValue; } if (segPre.GetBulge() < 0) { arc.SetStarAngle(newValue); arc.GetStartPoint(segPre.StartPoint()); arc.GetEndPoint(segPre.EndPoint()); m_polyBase.SetBulge(nPre, -arc.Bulge()); } else { arc.SetEndAngle(newValue); arc.GetStartPoint(segPre.StartPoint()); arc.GetEndPoint(segPre.EndPoint()); m_polyBase.SetBulge(nPre, arc.Bulge()); } *m_polyBase[nPre + 1] = segPre.GetEndPoint(); } } break; } } else if (!bPre && bNext) {// 无前段有后段 switch(iDim) { case 0: { if (!bNextArc) {//长度 if (newValue > 1E-6) { XPoint vt = segNext.Direction3d(); AcGeVector3d vt1 = ptNew - segNext.GetEndPoint().AsAcGePoint3d(); if (vt.AsAcGeVector3d().dotProduct(vt1) > 0) { vt *= newValue; } else { vt *= -newValue; } *m_polyBase[nNext] = segNext.GetEndPoint() + vt; } } else {//包络角度 XArc arc = segNext.GetArc(); if (segNext.GetBulge() < 0) { arc.SetEndAngle(arc.GetStarAngle() + newValue); arc.GetStartPoint(segNext.StartPoint()); arc.GetEndPoint(segNext.EndPoint()); m_polyBase.SetBulge(nNext, -arc.Bulge()); *m_polyBase[nNext] = segNext.GetEndPoint(); } else { arc.SetStarAngle(arc.GetEndAngle() - newValue); arc.GetStartPoint(segNext.StartPoint()); arc.GetEndPoint(segNext.EndPoint()); m_polyBase.SetBulge(nNext, arc.Bulge()); *m_polyBase[nNext] = segNext.GetStartPoint(); } } } break; case 1: { if (!bNextArc) {//角度 AcGeVector3d vt1 = ptNew - segNext.GetEndPoint().AsAcGePoint3d(); if (vt1.y<0) { newValue *= -1; } XPoint vt2(segNext.GetLength(),0,0); vt2.Rotate(newValue); *m_polyBase[nNext] = segNext.GetEndPoint() + vt2; } else {//后弧起始角度 XArc arc = segNext.GetArc(); if (ptNew.y < arc.GetCenterPt().y) { newValue = 2.0 * PI - newValue; } if (segNext.GetBulge() < 0) { arc.SetEndAngle(newValue); arc.GetStartPoint(segNext.StartPoint()); arc.GetEndPoint(segNext.EndPoint()); m_polyBase.SetBulge(nNext, -arc.Bulge()); } else { arc.SetStarAngle(newValue); arc.GetStartPoint(segNext.StartPoint()); arc.GetEndPoint(segNext.EndPoint()); m_polyBase.SetBulge(nNext, arc.Bulge()); } *m_polyBase[nNext] = segNext.GetStartPoint(); } } break; } } return Acad::eOk; } #endif // 区域的布尔运算 Adesk::Boolean XExport2::PolyBoolOper(const XPoly2D &poly1, const XPoly2D & poly2, DList & poly, AcDb::BoolOperType operation) { int nRetCode = RTERROR; if ( XPrivate::GetGlobalConfigBase() != NULL) { nRetCode = XPrivate::GetGlobalConfigBase()->BoolOper(operation,(LPVOID)&poly1,(LPVOID)&poly2,(LPVOID)&poly); } return (nRetCode == RTNORM ? Adesk::kTrue : Adesk::kFalse); } // 区域的并集 void XExport2::Union(const DList &lstSourcePolies, const DList &lstClipPolies, DList &lstResultPolies) { //return;//zjq--- DList lstSource, lstDest, *pSource = NULL, *pDest = NULL; pSource = &lstSource; pDest = &lstDest; for (int i = 0; i 1) { acedSetStatusBarProgressMeter(_T("求并集"), 0, nPiceNum); } for (int i = 0; i1 && !(i%nStep)) { acedSetStatusBarProgressMeterPos(i); } const XPoly2D &polyClip = lstClipPolies[i]; pDest->Reset(); for (int j = 0; jLength(); j++) { XPoly2D &polySrc = *(*pSource)[j]; if ( XPrivate::GetGlobalConfigBase() != NULL) { XPrivate::GetGlobalConfigBase()->BoolOper(AcDb::kBoolUnite,(LPVOID)&polySrc,(LPVOID)&polyClip,(LPVOID)pDest); } //Union(polySrc, polyClip, *pDest); } Exchange(pSource, pDest); } if (g_bEchoSearch && nStep > 1) { acedRestoreStatusBar(); } for (int i = 0; iLength(); i++) { XPoly2D *pPoly = new XPoly2D(*(*pSource)[i]); pPoly->Compress(); lstResultPolies.Append(pPoly); } } // 区域的减法 void XExport2::Subtract(const DList &lstSourcePolies, const DList &lstClipPolies, DList &lstResultPolies) { //return;//zjq--- DList lstSource, lstDest, *pSource = NULL, *pDest = NULL; pSource = &lstSource; pDest = &lstDest; for (int i = 0; iReset(); for (int j = 0; jLength(); j++) { XPoly2D &polySrc = *(*pSource)[j]; if ( XPrivate::GetGlobalConfigBase() != NULL) { XPrivate::GetGlobalConfigBase()->BoolOper(AcDb::kBoolSubtract,(LPVOID)&polySrc,(LPVOID)&polyClip,(LPVOID)pDest); } //Subtract(polySrc, polyClip, *pDest); } Exchange(pSource, pDest); } for (int i = 0; iLength(); i++) { XPoly2D *pPoly = new XPoly2D(*(*pSource)[i]); pPoly->Compress(); lstResultPolies.Append(pPoly); } } // 区域的减法 void XExport2::Intersect(const DList &lstSourcePolies, const DList &lstClipPolies, DList &lstResultPolies) { //return;//zjq--- DList lstSource, lstDest, *pSource = NULL, *pDest = NULL; pSource = &lstSource; pDest = &lstDest; for (int i = 0; iReset(); for (int j = 0; jLength(); j++) { XPoly2D &polySrc = *(*pSource)[j]; if ( XPrivate::GetGlobalConfigBase() != NULL) { XPrivate::GetGlobalConfigBase()->BoolOper(AcDb::kBoolIntersect,(LPVOID)&polySrc,(LPVOID)&polyClip,(LPVOID)pDest); } //XExport2::Intersect(polySrc, polyClip, *pDest); } Exchange(pSource, pDest); } for (int i = 0; iLength(); i++) { XPoly2D *pPoly = new XPoly2D(*(*pSource)[i]); pPoly->Compress(); lstResultPolies.Append(pPoly); } } void XExport2::InitModel(const XMasterProperties &prop, const AcDbEntity *pEntity, AcGeMatrix3d *pMatTran, AcDbVoidPtrArray &entSet3dface) { TCHAR szMatch[256] = _T("AEC_*"); XMasterProperties subProp(prop); subProp.SetFrom(pEntity); if (pEntity->isKindOf(AcDbFace::desc())) { AcDbFace *pFace = (AcDbFace *)pEntity->clone(); ASSERT(pFace); if (pMatTran) { if (pFace->transformBy(*pMatTran) != Acad::eOk) { AcGePoint3d ptArray[4]; for (int i = 0; i<4; i++) { pFace->getVertexAt(i, ptArray[i]); ptArray[i].transformBy(*pMatTran); pFace->setVertexAt(i, ptArray[i]); } } } subProp.SetTo(pFace); entSet3dface.append(pFace); } else if (pEntity->isKindOf(AcDbPolyFaceMesh::desc()) || pEntity->isKindOf(AcDbPolygonMesh::desc())) { AcDbVoidPtrArray entSet1; VERIFY(pEntity->explode(entSet1) == Acad::eOk); InitModel(subProp, entSet1, pMatTran, entSet3dface); XExport::ReleaseEntSet(entSet1); } else if (pEntity->isKindOf(AcDbBlockReference::desc())) { AcDbBlockReference *pInsert = AcDbBlockReference::cast(pEntity); ASSERT(pInsert); AcGeMatrix3d matNew = BlockTransform(pInsert); if (pMatTran) { matNew.preMultBy(*pMatTran); } AcDbObjectId idBlock = pInsert->blockTableRecord(); OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlockTableRecord); if (pBlockTableRecord) { AcDbBlockTableRecordIterator *pBlockIterator = NULL; VERIFY(pBlockTableRecord->newIterator(pBlockIterator) == Acad::eOk && pBlockIterator); for (pBlockIterator->start(); !pBlockIterator->done();pBlockIterator->step()) { AcDbEntity *pEntNew = NULL; if (pBlockIterator->getEntity(pEntNew, AcDb::kForRead) != Acad::eOk || !pEntNew) { continue; } if (pEntNew->visibility() == AcDb::kVisible) { XExport2::InitModel(subProp, pEntNew, &matNew, entSet3dface); } pEntNew->close(); } delete pBlockIterator; } OPENOBJ_END(); } else if (ads_wcmatch(pEntity->isA()->dxfName(), szMatch) == RTNORM) { // 在2000i/20002下,$对象的分解由于调用了Region的运算导致出错有问题 AcDbVoidPtrArray entSet1; if (pEntity->explode(entSet1) == Acad::eOk) { XExport2::InitModel(subProp, entSet1, pMatTran, entSet3dface); XExport::ReleaseEntSet(entSet1); } } else if (_tcsicmp(pEntity->isA()->dxfName(), _T("3DSOLID")) == 0 || _tcsicmp(pEntity->isA()->dxfName(), _T("REGION")) == 0 || _tcsicmp(pEntity->isA()->dxfName(), _T("3DBODY")) == 0 ) { AcDbVoidPtrArray entSet; ExplodeAcis(pEntity, entSet); XExport2::InitModel(subProp, entSet, pMatTran, entSet3dface); XExport::ReleaseEntSet(entSet); } else if (_tcsicmp(pEntity->isA()->dxfName(), _T("SOLID")) == 0) { //二维物体 AcDbSolid *pClone = (AcDbSolid *)pEntity->clone(); ASSERT(pClone); if (pMatTran) { if (pClone->transformBy(*pMatTran) != Acad::eOk) { AcGePoint3d ptArray[4]; for (int i = 0; i<4; i++) { pClone->getPointAt(i, ptArray[i]); ptArray[i].transformBy(*pMatTran); pClone->setPointAt(i, ptArray[i]); } } } subProp.SetTo(pClone); entSet3dface.append(pClone); } else if (pEntity->isA() == AcDbLine::desc()) { AcDbLine *pLine = (AcDbLine *)pEntity->clone(); ASSERT(pLine); if (pMatTran) { if (pLine->transformBy(*pMatTran) != Acad::eOk) { AcGePoint3d pt1 = pLine->startPoint(); AcGePoint3d pt2 = pLine->endPoint(); AcGeVector3d vt = pLine->normal(); AcGeVector3d vtNormal = vt; vt *= pLine->thickness(); pt1.transformBy(*pMatTran); pt2.transformBy(*pMatTran); vt.transformBy(*pMatTran); vtNormal.transformBy(*pMatTran); if (vt.length()>_DIST_SNAP) { AcDbFace *pFace = new AcDbFace(pt1, pt2, pt2+vt, pt1+vt); subProp.SetTo(pFace); entSet3dface.append(pFace); delete pLine; } else { pLine->setStartPoint(pt1); pLine->setEndPoint(pt2); pLine->setThickness(0.0); vtNormal.normalize(); pLine->setNormal(vtNormal); subProp.SetTo(pLine); entSet3dface.append(pLine); } } else { subProp.SetTo(pLine); entSet3dface.append(pLine); } } else { AcGeVector3d vt = pLine->normal(); AcGeVector3d vtNormal = vt; vt *= pLine->thickness(); AcGePoint3d pt1 = pLine->startPoint(); AcGePoint3d pt2 = pLine->endPoint(); if (vt.length()>_DIST_SNAP) { AcDbFace *pFace = new AcDbFace(pt1, pt2, pt2+vt, pt1+vt); subProp.SetTo(pFace); entSet3dface.append(pFace); delete pLine; } else { pLine->setStartPoint(pt1); pLine->setEndPoint(pt2); pLine->setThickness(0.0); vtNormal.normalize(); pLine->setNormal(vtNormal); subProp.SetTo(pLine); entSet3dface.append(pLine); } } } else { //拉伸的曲线 AcDbPolyline *pline = AsPolyline(pEntity); if (pline) { if (pline->thickness()>_DIST_SNAP) { // 没有消除圆弧折线化后的不可见边 double nThick = pline->thickness(); XPoly2D poly; XExport2::PolyConvert(*pline, poly); if (poly.IsClosed() && poly.PathArea()>0.0) { poly.Reverse(); //确保逆时针 } XVector3D vtNormal; AcGeVector3d vt = pline->normal(); (AcGeVector3d &)vtNormal = vt; double nWidth = 0.0; if (pline->getConstantWidth(nWidth) != Acad::eOk) { nWidth = 0.0; } if (nWidth>_DIST_SNAP) { XPoly2D poly1, poly2; poly.Offset(-nWidth/2, poly1); poly.Offset(nWidth/2, poly2); ThickPoly2Face(subProp, poly1, vtNormal, nThick, entSet3dface, pMatTran); ThickPoly2Face(subProp, poly2, vtNormal, nThick, entSet3dface, pMatTran); if (poly.IsClosed()) { poly1.SetFlag(0); poly2.SetFlag(0); poly1.AppendNode(*poly1.Head()); poly2.AppendNode(*poly2.Head()); } XPoly2D poly3(poly1); poly2.Reverse(); for (int n = 0; n lstTris[2]; XHoleModel model; for (int k = 0; k < polygon.Length(); k++) { //model.m_outline.AppendNode(*polygon[k], TRUE); model.GetOutLine().AppendNode(*poly1[k], TRUE); } model.Triangulate(FALSE, lstTris[0]); XPoint vtN = vtNormal; vtN *= nThick; for (int n = 0; nvertex1 += vtN; pTri1->vertex2 += vtN; pTri1->vertex3 += vtN; lstTris[1].Append(pTri1); } for (int ii = 0; ii<2; ii++) { for (int jj = 0; jjvertex1 = Ecs2Wcs(triangle->vertex1, vtNormal); triangle->vertex2 = Ecs2Wcs(triangle->vertex2, vtNormal); triangle->vertex3 = Ecs2Wcs(triangle->vertex3, vtNormal); Adesk::Boolean bSide1 = !(triangle->m_nFlag&SIDE1_INVISIBLE); Adesk::Boolean bSide2 = !(triangle->m_nFlag&SIDE2_INVISIBLE); Adesk::Boolean bSide3 = !(triangle->m_nFlag&SIDE3_INVISIBLE); AcDbFace *pFace = new AcDbFace(triangle->vertex1, triangle->vertex2, triangle->vertex3, triangle->vertex1, bSide1, bSide2, bSide3); subProp.SetTo(pFace); entSet3dface.append(pFace); } } } else { ThickPoly2Face(subProp, poly, vtNormal, nThick, entSet3dface, pMatTran); } delete pline; } else { if (!pMatTran) { subProp.SetTo(pline); entSet3dface.append(pline); } else if (pline->transformBy(*pMatTran) == Acad::eOk) { subProp.SetTo(pline); entSet3dface.append(pline); } else { XPoly2D poly2d, polyDest; XExport2::PolyConvert(*pline, poly2d); poly2d.Disperse1(polyDest, _AS_SYS_UNIT(g_nCirDeviation)); AcGeVector3d vtNormal = pline->normal(); XVector3D vtN(vtNormal[0], vtNormal[1], vtNormal[2]); Groups gv(vtN), g0(0); polyDest.TransUCS((const resbuf *)&gv, (const resbuf *)&g0); ads_matrix mat; AsAdsMatrix(*pMatTran, mat); polyDest.TransUCS(mat); int nSeg = polyDest.TotalSegments(); for (int iSeg = 0; iSeg &lstSeg1In, DList &lstDest) { try { XSearchRegionFromCurve aSearch; aSearch.InitStart(lstSeg1In); if (aSearch.SearchRegions()) { aSearch.RemoveDupRegions(); for (int n = 0; nCenterPoly2D(*pNewPoly) == RTNORM) { lstDest.Append(pNewPoly); } else { delete pNewPoly; } } } } catch(...) { if (g_bEchoSearch) { XGeLib::adsout << /*UMSG*/_T("\n发生例外情况!"); } return RTERROR; } return RTNORM; }