//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, SH Software Co. Ltd. // = FileName : 内部全局函数实现文件 // = Version : ver2.0 // = Author : // = CreateDate : 2002-09-09 // = Description: 全局函数的声明 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "XPrivateGlobalFunc.h" #include "XCurveObjectEx.h" #include "SymbolTable.h" #include "AecDbPolyCurveEnt.h" #include "XPushVar.h" #include "XPushMemVar.h" #include "CHole.h" #include "IdPointPair.h" #include "XSortSideOnVertex.h" #include "XSearchRegionFromCurve.h" #include "XRemoveDupByLayer.h" #include "DList.h" #include "XCurveObject.h" #include "SearchException.h" #include "DupWallException.h" #include "PickSet.h" #include "XLineDist.h" #include "XExplodeStream.h" #include "WPushVar.h" #include "XBlockTableRecPtr.h" #include "imgdef.h" #include "imgent.h" #include "XTrianglePface.h" #include "AString.h" #include "UString.h" #include "XConfigBase.h" #include "XGlobalCurveFunc.h" #include "XCurveInline.h" static TCHAR Are_appname[] = _T("_XG_HVAC"); // flag: TURE--add head; FALSE--add tail static void add_2_rblist(struct resbuf **tagdata, struct resbuf *n, int flag) { struct resbuf *tmptr; if(flag) { tmptr = AT_link_list(n, *tagdata); } else { tmptr = AT_link_list(*tagdata, n); } *tagdata = tmptr; } BOOL XPrivate::SkipSubErase(const TCHAR *szCmd) { const TCHAR *szSkip[] = { _T("UNDO"), _T("U"), _T("REDO"), _T("BLOCK"), _T("-BLOCK"), _T("BMAKE"), _T("WBLOCK"), _T("REFCLOSE"), }; int num = ELEMENTS(szSkip); for (int i = 0; i < num; i++) { if (_tcsicmp(szCmd, szSkip[i]) == 0) { return TRUE; } } return FALSE; } int XPrivate::CompareObjectId(const AcDbObjectId *id1, const void *id2) { if (*id1 == *(const AcDbObjectId *)id2) { return 0; } return 1; } int XPrivate::CompareObjectId(const AcDbSoftPointerId *id1, const void *id2) { if (*id1 == *(const AcDbSoftPointerId *)id2) { return 0; } return 1; } PGroups XPrivate::VBuildList(int *parguments) { PGroups list = NULL; PGroups cur = NULL; char *PArguments = (char *)parguments; int type; int code = *(int *)PArguments; #ifdef _WIN64 PArguments += sizeof(void*); #else PArguments += sizeof(int); #endif while (code) { if (code == RTDXF0) { code = 0; } if (code > -5 && code < 1072 ) { if (!cur) { list = cur = (PGroups)ads_newrb(code); } else { cur->next = (PGroups)ads_newrb(code); cur = cur->next; } if (!cur) { Release(list); ApplicationError(_T("\nError in fuction BuildList.No enough memory.\n")); } cur->next = NULL; cur->type = code; type = TypeOfCode(code); if (type == RTENAME || type == RTPICKS) { memcpy(cur->adsName,*(ads_name**)PArguments,sizeof(ads_name)); //(*(ADSName *)cur->adsName) = **(ADSName **)PArguments; PArguments += sizeof(void *); } else if (type == RT3DPOINT || type == RTPOINT) { (*(XPoint *)cur->point) = **(XPoint **)PArguments; PArguments += sizeof(void *); } else if (type == RTSTR) { cur->string = _tcsdup(*(TCHAR **)PArguments); PArguments += sizeof(void *); } else if (type == RTSHORT) { cur->shortInt = *(HALF_PTR*)PArguments; #ifdef _WIN64 PArguments += sizeof(void*); #else PArguments += sizeof(int); #endif } else if (type == RTREAL || type == RTANG || type == RTORINT) { cur->real = *(ads_real *)PArguments; #ifdef _WIN64 PArguments += sizeof(void*); #else PArguments += sizeof(ads_real); #endif } else if (type == RTLONG) { cur->longInt = *(long *)PArguments; #ifdef _WIN64 PArguments += sizeof(void*); #else PArguments += sizeof(long); #endif } else { ads_abort(_T("Bad Type")); } code = *(int *)PArguments; #ifdef _WIN64 PArguments += sizeof(void*); #else PArguments += sizeof(int); #endif } else { Release(list); ApplicationError(_T("\nError in fuction BuildList.Undocumented DXFcode. code=%d\n"),code); return NULL; } } return list; } ads_real XPrivate::GetXDirection(const XCurveSegment &cv1, const XCurveSegment &cv2, const XPoint &ptLoc) { ads_real nRes = 0.0; if (cv1.Is(CURVE_ARC)) { nRes = cv1.Direction(ptLoc); } else if (cv2.Is(CURVE_ARC)) { nRes = cv2.Direction(ptLoc); } else { ads_real nDrt1 = cv1.Direction(ptLoc); ads_real nDrtRev1 = CT_std_angle(nDrt1 + PI); XSector sec1(nDrt1, nDrtRev1); ads_real nRes1 = *sec1.NearAngle(0.0); ads_real nDrt2 = cv2.Direction(ptLoc); ads_real nDrtRev2 = CT_std_angle(nDrt2 + PI); XSector sec2(nDrt2, nDrtRev2); ads_real nRes2 = *sec2.NearAngle(0.0); XSector sec(nRes1, nRes2); nRes = *sec.NearAngle(0.0); } return nRes; } //不判断顶点 int XPrivate::HitTestOnEdge(const AcDbFace *pFace, XPoint pt, bool bDiscardHideEdge) { pt.z = 0; for (int i = 0; i < 4; i++) { Adesk::Boolean bVisible = Adesk::kTrue; pFace->isEdgeVisibleAt(i, bVisible); if (bDiscardHideEdge && !bVisible) { continue; } int iNext = DePeriod(4, i + 1); XLine ln; AcGePoint3d pt1, pt2; pFace->getVertexAt(i, pt1); pFace->getVertexAt(iNext, pt2); ln.SetStartPoint(pt1); ln.SetEndPoint(pt2); ln.SetElevation(0.0); if ((pt & ln) == PR_INSIDE) { return i; } } return -1; } AcGeMatrix3d XPrivate::BlockTransform(const AcDbBlockReference *pInsert) { AcGePoint3d ptBase, ptInsert = pInsert->position(); AcGeScale3d s = pInsert->scaleFactors(); double rot = pInsert->rotation(); AcDbObjectId idBlock = pInsert->blockTableRecord(); AcDbBlockTableRecord *pBlock = NULL; // 打开的时候碰到有打不开的情况(如对象被删除了的情况),因此要支持删除的也能打开,并且对指针判断 ---wyg20090710 // acdbOpenObject(pBlock, idBlock, AcDb::kForRead); // ASSERT(pBlock); acdbOpenObject(pBlock, idBlock, AcDb::kForRead, true); if (NULL != pBlock) { ptBase = pBlock->origin(); pBlock->close(); } AcGeMatrix3d result = pInsert->blockTransform(); // 先移动base到原点, Scale, Rotation, 再平移到insPt AcGeMatrix3d mvMat1; mvMat1.setToTranslation(AcGeVector3d(-ptBase.x, -ptBase.y, -ptBase.z)); result.postMultBy(mvMat1); return result; } void XPrivate::_RemoveDupCurves(DList &lstCurves) { //初始化消除重线的集合 int len = lstCurves.Length(); DList lstNewCurves; for (int i = 0; i < len; i++) { XCurveSegment &seg = *lstCurves[i]; if (seg.GetLength() < _DIST_SNAP) //太短了 { continue; } lstNewCurves.Append(new XCurveObjectEx(seg)); } len = lstNewCurves.Length(); if (g_bEchoSearch) { XString sMsg(256); sMsg << _T("对") << len << _T("条线进行消除重线"); acedSetStatusBarProgressMeter(sMsg, 0, len); } int nStep = len / 100; if (nStep < 1) { nStep = 1; } for (int i = 0; i < len; i++) { if (g_bEchoSearch && !(i % nStep)) { acedSetStatusBarProgressMeterPos(i); } XCurveObjectEx &line1 = *lstNewCurves[i]; if (line1.IsDeleted()) { continue; } BOOL bIsLine1 = line1.Is(CURVE_LINE); for (int j = 0; j < len; j++) { XCurveObjectEx &line2 = *lstNewCurves[j]; if (j == i) { continue; } if (line2.IsDeleted() || bIsLine1 != line2.Is(CURVE_LINE)) { continue; // 线2已经被删除或者两线类型不匹配 } BOOL bPossibleDup = FALSE; XArc ar1, ar2; if (bIsLine1) //对于LINE类型 { XVector3D vt1 = line1.GetStartPoint() - line1.GetEndPoint(), //向量1 vt2 = line2.GetStartPoint() - line2.GetEndPoint(); //向量2 ads_real len1 = vt1.Length(), len2 = vt2.Length(); if (len1 > 1.0E-6) { vt1.Scale(1.0 / len1); } if (len2 > 1.0E-6) { vt2.Scale(1.0 / len2); } double nSweepAng = acos(vt1 & vt2); //单位向量的点积确定夹角 //同一方向, 旧的算法没有考虑夹角精度 bPossibleDup = (nSweepAng < _angSnap || fabs(PI - nSweepAng) < _angSnap); } else //对于Arc/Circle类型 { if (line1.Is(CURVE_ARC)) { ar1 = line1.GetArc(); } else { (XCircle &)ar1 = line1.GetCircle(); ar1.SetStarAngle(0.0); ar1.SetEndAngle(PI * 2.0); } if (line2.Is(CURVE_ARC)) { ar2 = line2.GetArc(); } else { (XCircle &)ar2 = line2.GetCircle(); ar2.SetStarAngle(0.0); ar2.SetEndAngle(PI * 2.0); } bPossibleDup = (ar1.GetCenterPt().Distance(ar2.GetCenterPt()) < _DIST_SNAP && fabs(ar1.GetRadius() - ar2.GetRadius()) < _DIST_SNAP); if (bPossibleDup) { if (line1.Is(CURVE_CIRCLE)) { line2.m_bDel = TRUE; continue; } if (line2.Is(CURVE_CIRCLE)) { line1 = line2; line2.m_bDel = TRUE; continue; } } } if (bPossibleDup) { int flg = bIsLine1 ? (line2.GetStartPoint() & line1) : ar1.AngleFlag(ar2.GetStarAngle()); int flg1 = bIsLine1 ? (line2.GetEndPoint() & line1) : ar1.AngleFlag(ar2.GetEndAngle()); if (flg == PR_ONPT1 || flg == PR_ONPT2 || flg == PR_INSIDE) { // 线2起点在线1内(包括端点) line2.m_bDel = TRUE; //线2要合并到线1内 if (!bIsLine1 || flg1 == PR_EXTEND) { // 线2的终点在线1的延长线上, 判断在起始延长还是终止延长 if (bIsLine1) { double *pNearPoint = line1.NearPoint(line2.GetEndPoint()); BOOL bIncludeLine1Start = (pNearPoint == &(line1.StartPoint().x)); if (bIncludeLine1Start) //线1的起点在线2内 { line1.StartPoint() = line2.GetEndPoint(); //因此改变线1的起点 } else { line1.SetEndPoint(line2.GetEndPoint()); //否则线1的终点在线2内,因此改变线1的终点 } } else { if (flg1 == PR_INSIDE) //需要判断是否构成封闭的圆 { if (ar2.AngleFlag(ar1.GetStarAngle()) == PR_INSIDE) //ar1变成圆 { (XCurveSegment &)line1 = XCircle(ar1.GetCenterPt(), ar1.GetRadius()); } } else if (flg1 != PR_OUTSIDE) //Add this 2 lines on 2003/12/15 { (XCurveSegment &)line1 = XCircle(ar1.GetCenterPt(), ar1.GetRadius()); } else { ar1.SetEndAngle(ar2.GetEndAngle()); (XCurveSegment &)line1 = ar1; } } } else { // 否则线2整个位于线1内部, 仅仅删除就可以了 ASSERT(bIsLine1); } } else if (flg1 == PR_ONPT1 || flg1 == PR_ONPT2 || flg1 == PR_INSIDE) { // 线2终点线1内(包括端点) line2.m_bDel = TRUE; if (!bIsLine1 || flg == PR_EXTEND) { // 线2的起点在线1的延长线上, 判断在起始延长还是终止延长 if (bIsLine1) { double *pNearPoint = line1.NearPoint(line2.GetStartPoint()); if (pNearPoint == &(line1.StartPoint().x)) { line1.SetStartPoint(line2.GetStartPoint()); } else { line1.SetEndPoint(line2.GetEndPoint()); } } else { ar1.SetStarAngle(ar2.GetStarAngle()); (XCurveSegment &)line1 = ar1; } } else { // 否则线2整个位于线1内部, 仅仅删除就可以了 ASSERT(bIsLine1); } } else if (bIsLine1 && (flg == PR_EXTEND && flg1 == PR_EXTEND)) //线2的两端都在线一的外边 { int flg2 = bIsLine1 ? (line1.GetStartPoint() & line2) : ar2.AngleFlag(ar1.GetStarAngle()); if (flg2 == PR_INSIDE) { line1.SetStartPoint(line2.GetStartPoint()); line1.SetEndPoint(line2.GetEndPoint()); line2.m_bDel = TRUE; } } } } } lstCurves.Reset(); for (int i = 0; i < len; i++) { XCurveObjectEx &ln = *lstNewCurves[i]; if (!ln.IsDeleted()) { lstCurves.Append(new XCurveSegment(ln)); } } if (g_bEchoSearch) { acedRestoreStatusBar(); } } int XPrivate::GetApplicationPath(TCHAR *vPath,HINSTANCE hInstance) { TCHAR fileName[128] = _T(""); GetModuleFileName(hInstance, fileName, 127); TCHAR drive[_MAX_DRIVE] = _T(""), dir[_MAX_DIR] = _T(""), fname[_MAX_FNAME] = _T(""), ext[_MAX_EXT] = _T(""); _tsplitpath(fileName, drive, dir, fname, ext); _tcscpy(vPath, drive); _tcscat(vPath, dir); return 1; } int XPrivate::AT_get_cirarcp(ads_name arc_ent, ads_point cent, ads_real *rad, ads_real *sang, ads_real *eang) { struct resbuf *res2, *rb1; res2 = ads_entget(arc_ent); rb1 = AT_get_resbuf(res2,0); if (_tcscmp(rb1->resval.rstring,_T("ARC")) != 0 && _tcscmp(rb1->resval.rstring,_T("CIRCLE")) != 0) { ads_relrb(res2); return RTERROR; } rb1 = AT_get_resbuf(res2,10); cent[X] = rb1->resval.rpoint[X]; cent[Y] = rb1->resval.rpoint[Y]; cent[Z] = rb1->resval.rpoint[Z]; rb1 = AT_get_resbuf(res2,40); *rad = rb1->resval.rreal; rb1 = AT_get_resbuf(res2,0); if ( _tcscmp(rb1->resval.rstring,_T("ARC")) == 0) { rb1 = AT_get_resbuf(res2,50); *sang = rb1->resval.rreal; rb1 = AT_get_resbuf(res2,51); *eang = rb1->resval.rreal; ads_relrb(res2); return 1; } if ( _tcscmp(rb1->resval.rstring,_T("CIRCLE")) == 0) { ads_relrb(res2); *sang = 0.0; *eang = 2.0 * PI; return 1; } return RTERROR; } int XPrivate::operator == (XStringList &strs1, XStringList &strs2) { if (strs1.Length() != strs2.Length()) { return 0; } int len = strs1.Length(); for (int i = 0; i < len; i++) { if (_tcscmp(strs1[i], strs2[i]) == 0) { ; } else { return 0; } } return 1; } void XPrivate::ThickPoly2Face(XMasterProperties prop, const XPoly2D &poly, XPoint vtNormal, double nThick, AcDbVoidPtrArray &entSet, AcGeMatrix3d *pMatTran) { ASSERT(nThick > _DIST_SNAP); if (nThick > _DIST_SNAP && poly.Length()) { XPoly polygon; poly.AsOpenPoly1(polygon, _AS_SYS_UNIT(g_nCirDeviation)); int nSeg = polygon.Length() - 1; for (int n = 0; n < nSeg; n++) { XPoint verts[4]; verts[0] = *polygon[n]; verts[1] = *polygon[n+1]; verts[2] = verts[1]; verts[2].z += nThick; verts[3] = verts[0]; verts[3].z += nThick; AcDbFace *pFace = new AcDbFace; for (int idx = 0; idx < 4; idx++) { XPoint ptVert = Ecs2Wcs(verts[idx], vtNormal); if (pMatTran) { ((AcGePoint3d &)ptVert).transformBy(*pMatTran); } pFace->setVertexAt(idx, ptVert); } prop.SetTo(pFace); entSet.append(pFace); } // Modify on 2004/4/6, 增加顶面和底面 if (poly.IsClosed() && g_bSlabThickPolyline) { XPoly2D polyBot(poly), polyTop(poly); polyBot.Reverse(); polyTop.SetElevation(poly.Head()->z + nThick); XExplodeStream dc(entSet); DList emptyHole; dc.DrawShell(polyBot, emptyHole); dc.DrawShell(polyTop, emptyHole); } } } // 画拉伸圆 void XPrivate::DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XCircle &cir, ads_real nHeight) { AcDbPolyline line; line.setElevation(cir.GetCenterPt().z); line.setThickness(nHeight); XPoint ptStart, ptEnd; ads_polar(cir.GetCenterPt(), 0.0, cir.GetRadius(), ptStart); ads_polar(cir.GetCenterPt(), PI, cir.GetRadius(), ptEnd); line.addVertexAt(0, ptStart, tan(PI / 4.0)); line.addVertexAt(1, ptEnd, tan(PI / 4.0)); line.setClosed(Adesk::kTrue); if (pWd) { line.worldDraw(pWd); } else { line.viewportDraw(pVd); } } // 显示3d弧段 // 参数: pWd, pVd -- 必须有一个非NULL // ar -- 待显示的弧段 // nHeight -- 厚度 // bShowStart -- 是否绘制起始边界线 // bShowEnd -- 是否绘制终止边界线 void XPrivate::DrawArcSeg(XExplodeDraw &dc, const XArc &ar, ads_real nHeight, int bShowStart, int bShowEnd) { // Modify on 2002/4/12 by , 避免大圆弧的出现 if (ar.Bulge() > 2 * PI - _angSnap || ar.GetLength() < _DIST_SNAP) { return; } if (_tcsicmp(dc.Desc(), XExplodeStream::Descriptor()) == 0) { dc.DrawArc(ar, nHeight); return; //希望有渐变线 } int nCirDiv = GetCirDivNum(ar.GetRadius(), _AS_SYS_UNIT(g_nCirDeviation)); ads_real intAng = fabs(ar.Bulge()); int n = AS_INT(intAng / PI / 2.0 * nCirDiv); //一个圆分解为50份 if (n < 1) { n = 1; } ads_real ang = intAng / n; int nVertexNum = 2 * n + 2; XPoint *ptArray = new XPoint[nVertexNum]; for (int i = 0; i < n + 1; i++) { ads_real drt = ar.GetStarAngle() + i * ang; ads_polar(ar.GetCenterPt(), drt, ar.GetRadius(), ptArray[i]); ptArray[i + n + 1] = ptArray[i]; ptArray[i + n + 1].z += nHeight; } AcGiEdgeData edge; Adesk::UInt8 *visibleData = new Adesk::UInt8[3 * n + 1]; for (int j = 0; j < 2 * n; j++) { visibleData[j] = kAcGiVisible; } visibleData[2 * n] = bShowStart ? kAcGiVisible:kAcGiInvisible; visibleData[3 * n] = bShowEnd ? kAcGiVisible:kAcGiInvisible; for (int j = 2 * n + 1; j < 3 * n; j++) { visibleData[j] = kAcGiInvisible; } edge.setVisibility(visibleData); dc.DrawMesh(2, n + 1, (AcGePoint3d *)ptArray, &edge); delete [] ptArray; delete [] visibleData; } // 显示3d线段 // 参数: pWd, pVd -- 必须有一个非NULL // ln -- 待显示的线段 // nHeight -- 厚度 // bShowStart -- 是否绘制起始边界线 // bShowEnd -- 是否绘制终止边界线 void XPrivate::DrawLineSeg(XExplodeDraw &dc, const XLine &ln, ads_real nHeight, int bShowStart, int bShowEnd) { int nVertexNum = 4; XPoint *ptArray = new XPoint[nVertexNum]; ptArray[0] = ln.GetStartPoint(); ptArray[1] = ln.GetEndPoint(); ptArray[2] = ln.GetStartPoint(); ptArray[2].z += nHeight; ptArray[3] = ln.GetEndPoint(); ptArray[3].z += nHeight; AcGiEdgeData edge; Adesk::UInt8 *visibleData = new Adesk::UInt8[4]; for (int j = 0; j < 2; j++) { visibleData[j] = kAcGiVisible; } visibleData[2] = bShowStart ? kAcGiVisible : kAcGiInvisible; visibleData[3] = bShowEnd ? kAcGiVisible : kAcGiInvisible; edge.setVisibility(visibleData); dc.DrawMesh(2, 2, (AcGePoint3d *)ptArray, &edge); delete [] ptArray; delete [] visibleData; } //绘制二维直线 void XPrivate::DrawLineSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XLine &ln) { AcGePoint3d line[2] = {ln.GetStartPoint(), ln.GetEndPoint()}; if (pWd) { pWd->geometry().polyline(2, line); } else { pVd->geometry().polyline(2, line); } } //绘制二维弧线 void XPrivate::DrawArcSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XArc &ar) { XPoint ptStart, ptEnd, ptMid; ar.GetStartPoint(ptStart); ar.GetEndPoint(ptEnd); ar.MidPoint(ptMid); if (pWd) { pWd->geometry().circularArc(ptStart, ptMid, ptEnd); } else { pVd->geometry().circularArc(ptStart, ptMid, ptEnd); } } // 绘制二维圆 void XPrivate::DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XCircle &cir) { if (pWd) { pWd->geometry().circle(cir.GetCenterPt(), cir.GetRadius(), AcGeVector3d(0.0,0.0,1.0)); } else { pVd->geometry().circle(cir.GetCenterPt(), cir.GetRadius(), AcGeVector3d(0.0,0.0,1.0)); } } void XPrivate::AsPolyline(const AcDbLine &line, AcDbPolyline &pline) { pline.reset(Adesk::kFalse, 0); pline.setPropertiesFrom(&line); XVector3D vtNormal; (AcGeVector3d &)vtNormal = line.normal(); XPoint ptStart = Wcs2Ecs(line.startPoint(), vtNormal), ptEnd = Wcs2Ecs(line.endPoint(), vtNormal); pline.addVertexAt(0, ptStart); pline.addVertexAt(1, ptEnd); pline.setNormal(line.normal()); pline.setElevation(ptStart.z); double nThick = line.thickness(); pline.setThickness(nThick); } void XPrivate::AsPolyline(const AcDbArc &line, AcDbPolyline &pline) { pline.reset(Adesk::kFalse, 0); XPoint vtNormal; (AcGeVector3d &)vtNormal = line.normal(); XPoint ptCen = Wcs2Ecs(line.center(), vtNormal); XArc ar(ptCen, line.radius(), line.startAngle(), line.endAngle()); pline.setPropertiesFrom(&line); XPoint ptStart, ptEnd; ar.GetStartPoint(ptStart); ar.GetEndPoint(ptEnd); pline.addVertexAt(0, ptStart, tan(ar.Bulge() / 4.0)); pline.addVertexAt(1, ptEnd); pline.setNormal(line.normal()); double nThick = line.thickness(); pline.setElevation(ptCen.z); pline.setThickness(nThick); } void XPrivate::AsPolyline(const AcDbCircle &line, AcDbPolyline &pline) { XPoint vtNormal; (AcGeVector3d &)vtNormal = line.normal(); XPoint ptCen = Wcs2Ecs(line.center(), vtNormal); XCircle cir(ptCen, line.radius()); XCurveSegment seg; seg = cir; XPoly2D poly; seg.AsPoly2D(poly); PolyConvert(poly, pline); pline.setPropertiesFrom(&line); pline.setNormal(line.normal()); pline.setElevation(ptCen.z); double nThick = line.thickness(); pline.setThickness(nThick); } int XPrivate::CompNodeByEqual(const XSortWallOnPt *p1, const void *p2) { if (p1 == p2) { return 0; } return 1; } int XPrivate::AT_in_arc(ads_point pt, ads_point cenpt, ads_real rad, ads_real ang1, ads_real ang2) { ads_real ang; int tag; ads_point ptStart, ptEnd; if ( fabs(pt[2]-cenpt[2]) > _DIST_SNAP || fabs(ads_distance(cenpt,pt) - rad) > _DIST_SNAP ) { return 0; } ang = ads_angle(cenpt,pt); ads_polar(cenpt, ang1, rad, ptStart); ads_polar(cenpt, ang2, rad, ptEnd); if (ads_distance(ptStart, pt) < _DIST_SNAP) { return 1; } if (ads_distance(ptEnd, pt) < _DIST_SNAP) { return 2; } if (ang1 < ang2 ) { if (ang > ang1 && ang < ang2) { tag = 3; } else { tag = 0; } } else { if (ang > ang1 || ang < ang2) { tag = 3; } else { tag = 0; } } return tag; } // 点到线的投影 // src_pt -- 源点 // cl_pt1, cl_pt2 -- 投影线 // dest_pt -- 投影点 // 返回值: // RTNOMR -- 正常 // RTERROR -- 错误 // Modify by Z on 2002/1/5, return RTNORM always int XPrivate::AT_pt_ProjectLine(ads_point src_pt, ads_point cl_pt1, ads_point cl_pt2, ads_point dest_pt) { //modify by zjq 100613 取消AcGe算法,速度慢 //AcGeLine3d lineT(asPnt3d(cl_pt1),asPnt3d(cl_pt2)); //AcGePointOnCurve3d ptOnCr; //lineT.getClosestPointTo(asPnt3d(src_pt),ptOnCr); //asPnt3d(dest_pt) = ptOnCr.point3d(); //return RTNORM; struct plan_para plan; XVector3D vt; CT_Vector(cl_pt1, cl_pt2, vt); dest_pt[0]=src_pt[0]; dest_pt[1]=src_pt[1]; dest_pt[2]=src_pt[2]; if(CT_plan_equation(src_pt, vt, &plan)) { CT_inter_line_plan1(cl_pt1, cl_pt2, &plan, dest_pt); } return RTNORM; } // 计算点到线的距离 // pt1, pt2 -- 指定线上的两点 // pt0 -- 指定点 // 返回值: 点到线的距离 ads_real XPrivate::AT_Dist_PtLine2(ads_point pt0, ads_point pt1,ads_point pt2) { //modify by zjq 100613 取消AcGe算法,速度慢 //AcGeLine3d lineT(asPnt3d(pt1),asPnt3d(pt2)); //AcGePointOnCurve3d ptOnCr; //lineT.getClosestPointTo(asPnt3d(pt0),ptOnCr); //return ptOnCr.point3d().distanceTo(asPnt3d(pt0)); ads_point pt4; AT_pt_ProjectLine(pt0, pt1, pt2, pt4); double dist = ads_distance(pt0, pt4); return dist; } // 点与线的位置关系 // pt1, pt2 -- 线的两个端点 // pt -- 指定点 // 返回值: // 0 -- 线外; 1 -- 在端点line_pt1上; // 2 -- 在端点line_pt2上; 3 -- 线上. // 4 -- 延长线上; int XPrivate::AT_in_line(ads_point pt, ads_point line_pt1,ads_point line_pt2) { ads_real snap0 = _DIST_SNAP; ads_point vt1, vt2; if (XPrivate::AT_Dist_PtLine2(pt, line_pt1, line_pt2) > snap0) { return 0; } CT_Vector(pt, line_pt1, vt1); CT_Vector(pt, line_pt2, vt2); if (fabs(vt1[0]) <= snap0 && fabs(vt1[1]) <= snap0 && fabs(vt1[2]) <= snap0) { return 1; } if (fabs(vt2[0]) <= snap0 && fabs(vt2[1]) <= snap0 && fabs(vt2[2]) <= snap0) { return 2; } if (CT_RealEqual(CT_VectorAngle(vt1, vt2), 0, _angSnap) ) { return 4; } if (CT_RealEqual(CT_VectorAngle(vt1, vt2), PI, _angSnap) ) { return 3; } return 0; } double XPrivate::GetPolygonDist(const XPolygonEx &poly1, const XPolygonEx &poly2) { int nIndex1 = 0; int num1 = poly1.Length(); int nIndex2 = 0; //poly2与pt最近的顶点 double nMinDist = 0.0; int num2 = poly2.Length(); for (int j = 0; j < num1; j++) { XPoint pt = poly1[j]; for (int i = 0; i < num2; i++) { double nDist = pt.Distance(poly2[i]); if (i == 0 && j == 0) { nMinDist = nDist; } else if (nDist < nMinDist) { nMinDist = nDist; nIndex2 = i; nIndex1 = j; } } } return nMinDist; } BOOL XPrivate::IsEqual(const AcGePoint3d pt11,const AcGePoint3d pt12,const AcGePoint3d pt21,const AcGePoint3d pt22,double tol) { if ((XPrivate::IsEqual(pt11,pt21,tol) && XPrivate::IsEqual(pt12,pt22,tol)) || (XPrivate::IsEqual(pt11,pt22,tol) && XPrivate::IsEqual(pt12,pt21,tol))) { return 1; } else { return 0; } } BOOL XPrivate::IsOverlap(AcGePoint3d& pt11,AcGePoint3d& pt12,AcGePoint3d& pt21,AcGePoint3d& pt22) { AcGeLine3d line(pt11,pt12); AcGeTol tol1; tol1.setEqualPoint(TOL); if (line.isOn(pt21,tol1) && line.isOn(pt22,tol1)) { return 1; } else { return 0; } } int XPrivate::PtAtWhichSide(const AcGePoint3d& pt0,const AcGePoint3d& pt1,const AcGePoint3d& pt2,double tol) { AcGePoint3d pt00, pt11, pt22; double L01, L02, L12, Lmax; L01 = pt0.distanceTo(pt1); L02 = pt0.distanceTo(pt2); L12 = pt1.distanceTo(pt2); if (L01 <= TOL || L02 <= TOL || L12 < TOL) { return 0; } if (L01 >= L02) { if (L02 >= L12) { pt00 = pt0; pt11 = pt1; pt22 = pt2; } else if (L01 >= L12) { pt00 = pt1; pt11 = pt0; pt22 = pt2; } else { pt00 = pt1; pt11 = pt2; pt22 = pt0; } } else { if (L01 >= L12) { pt00 = pt0; pt11 = pt2; pt22 = pt1; } else if (L02 >= L12) { pt00 = pt2; pt11 = pt0; pt22 = pt1; } else { pt00 = pt2; pt11 = pt1; pt22 = pt0; } } double Ang1, Ang2, DltAng, DltAng_TOL; Lmax = max(L01, L02); Lmax = max(Lmax, L12); DltAng_TOL = tol / Lmax; Ang1 = AngleToX(pt00, pt11); Ang2 = AngleToX(pt00, pt22); while (Ang1 >= 2.0 * PI) { Ang1 -= 2.0 * PI; } while (Ang1 < 0) { Ang1 += 2.0 * PI; } while (Ang2 >= 2.0 * PI) { Ang2 -= 2.0 * PI; } while (Ang2 < 0) { Ang2 += 2.0 * PI; } DltAng = fabs(Ang2 - Ang1); if (fabs(DltAng) <= DltAng_TOL || fabs(DltAng - 2.0 * PI) <= DltAng_TOL || fabs(DltAng - PI) <= DltAng_TOL) { return 0; } double s = 0; s = pt0.x * (pt1.y - pt2.y) + pt1.x * (pt2.y - pt0.y) + pt2.x * (pt0.y - pt1.y); if (s > 0) { return 1; } else { return 2; } } //三角化 BOOL XPrivate::Triangulate(const DList &lstHole,DList &lstRes) { CHole hole; if (hole.ConstructEdgeList(lstHole)) { return (hole.GetTriangles(lstRes)); } return FALSE; } BOOL XPrivate::Triangulate(const DList &lstHole,DList &lstRes) { CHole hole; if (hole.ConstructEdgeList(lstHole)) { return (hole.GetTriangles(lstRes)); } return FALSE; } BOOL XPrivate::Triangulate(const XPoly2D &out,const DList &lstHole,DList &lstRes) { CHole hole; if (hole.ConstructEdgeList(out,lstHole)) { return hole.GetTriangles(lstRes); } return FALSE; } BOOL XPrivate::Triangulate(const XPolygonEx &out, const DList &lstHole, DList &lstRes) { CHole hole; if (hole.ConstructEdgeList(out,lstHole)) { return hole.GetTriangles(lstRes); } return FALSE; } BOOL XPrivate::Triangulate(const XPolygonEx &out, const DList &lstHole, DList &lstRes) { CHole hole; if (hole.ConstructEdgeList(out,lstHole)) { return hole.GetTriangles(lstRes); } return FALSE; } // 区域的减法 // lstPoly2 is inside poly1, but share edges // lstPoly2都是独立的域,不含孔洞模型 int XPrivate::_Subtract(const XPoly2D &poly1, const DList &lstPoly2, DList &lstResult) { // 首先, poly1对poly2进行裁剪, 取内部 DList lstSeg2, lstSeg2In, lstSeg2Out, lstSeg2Edge ; for (int n = 0; n < lstPoly2.Length(); n++) { const XPoly2D &poly2 = lstPoly2[n]; ExplodePoly2D(poly2, lstSeg2); } PolyClip(lstSeg2, (XPoly2D &)poly1, lstSeg2In, lstSeg2Out, lstSeg2Edge); // 然后, poly2对poly1进行裁剪, 取外部 DList lstSeg1, lstSeg1In, lstSeg1Out, lstSeg1Edge ; ExplodePoly2D(poly1, lstSeg1); for (int n = 0; n < lstPoly2.Length(); n++) { const XPoly2D &poly2 = lstPoly2[n]; lstSeg1Out.Reset(); PolyClip(lstSeg1, (XPoly2D &)poly2, lstSeg1In, lstSeg1Out, lstSeg1Edge); lstSeg1.Reset(); for (int k = 0; k < lstSeg1Out.Length(); k++) { lstSeg1.Append(new XCurveSegment(*lstSeg1Out[k])); } } //lstSeg2In合并到lstSeg1Out for (int i = 0; i < lstSeg2In.Length(); i++) { lstSeg1Out.Append(new XCurveSegment(*lstSeg2In[i])); } DList lstTemp(FALSE); int nRet = SearchRegions(lstSeg1Out, lstTemp); for (int i = 0; i < lstTemp.Length(); i++) { XPoly2D *pTemp = lstTemp[i]; if (pTemp->IsSelfIntersect()) { delete pTemp; } else { lstResult.Append(pTemp); } } return nRet; } // 8.0补丁暂未使用 // 参考ptRef,判断在外轮廓中,应该减去pt1、pt2中的哪个点 XPoint XPrivate::GetAutoDelPt(XPoint ptRef, XPoint pt1, XPoint pt2) { XPoint vecXDir, vecYDir; xg_getvar(_T("UCSXDIR"), vecXDir); xg_getvar(_T("UCSYDIR"), vecYDir); // 当前视图下的Z轴 AcGeVector3d vecZDir = vecXDir.AsAcGeVector3d().crossProduct(vecYDir.AsAcGeVector3d()); AcGePoint3d point1 = pt1.AsAcGePoint3d(), point2 = pt2.AsAcGePoint3d(), pointRef = ptRef.AsAcGePoint3d(); AcGeVector3d vec1 = point1 - pointRef, vec2 = point2 - pointRef; double dAngle = vec1.angleTo(vec2, vecZDir); // 角度范围为[0, 2PI] // pt1、pt2距离小于1,角度通常趋近于0或2PI,此判断无需精确度 if (dAngle > PI * 1.5) { return pt2; } return pt1; } BOOL XPrivate::IsPointAtSameSide(const AcGePlane& plane, const AcGePoint3d& pt1, const AcGePoint3d& pt2) { if (plane.isOn(pt1) || plane.isOn(pt2)) { return 1; } AcGePoint3d ptPrj1 = pt1.project(plane, plane.normal()); AcGePoint3d ptPrj2 = pt2.project(plane, plane.normal()); if ((pt1 - ptPrj1).isCodirectionalTo(pt2 - ptPrj2)) { return 2; } return 0; } #if (ARX>15) bool XPrivate::RemoveRT_MANIFEST(const TCHAR* fullPath,int resId) { HANDLE hUpdateRes = BeginUpdateResource(fullPath,FALSE); if (hUpdateRes == NULL) { return false; } if (!UpdateResource(hUpdateRes,RT_MANIFEST,MAKEINTRESOURCE(resId), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),NULL,NULL)) { return false; } if (!EndUpdateResource(hUpdateRes, FALSE)) { return false; } return true; } #endif XString XPrivate::OsMode2Str(int nMode) { XString sMode; if (nMode & 0x4000) { return sMode; } if (nMode & 1) { sMode << _T("END,"); } if (nMode & 2) { sMode << _T("MID,"); } if (nMode & 4) { sMode << _T("CEN,"); } if (nMode & 8) { sMode << _T("NOD,"); } if (nMode & 16) { sMode << _T("QUA,"); } if (nMode & 32) { sMode << _T("INT,"); } if (nMode & 64) { sMode << _T("INS,"); } if (nMode & 128) { sMode << _T("PER,"); } if (nMode & 256) { sMode << _T("TAN,"); } if (nMode & 512) { sMode << _T("NEA,"); } int nLen = sMode.Length(); if (nLen) { sMode[nLen - 1] = 0; } return sMode; } BOOL XPrivate::SearchPathFromCurve(const DList &curves, XPoly2D &polyPath) { XSearchRegionFromCurve aSearch; BOOL bInit = TRUE; try { aSearch.InitStart(curves); } catch(...) { bInit = FALSE; } if (!bInit) { return FALSE; } DList &nodes = XSearchRegionFromCurve::g_lstAllSortSides; XSortSideOnVertex *pHead = NULL; XSortSideOnVertex *pTail = NULL; for (int i = 0; i < nodes.Length(); i++) { XSortSideOnVertex &node = *nodes[i]; if (node.Length() > 2 || !node) { return FALSE; } if (node.Length() == 1) { if (!pHead) { pHead = &node; } else if (!pTail) { pTail = &node; } else { return FALSE; } } } if (!pHead || !pTail) { return FALSE; } polyPath.Reset(); polyPath.SetFlag(0); XSortSideOnVertex *pNode = pHead; XRegionSide *pLast = NULL; while (pNode != pTail) { XRegionSide *pSide1 = pNode->Head()->m_pSide; XRegionSide *pSide2 = pNode->Tail()->m_pSide; XRegionSide *pSide = NULL; if (!pLast) { ASSERT(pSide1 == pSide2); pSide = pSide1; } else if (pSide1 == pLast) { pSide = pSide2; } else if (pSide2 == pLast) { pSide = pSide1; } else { ASSERT(0); return FALSE; } if (pSide->GetStartNode() == pNode) //正向搜索 { polyPath.AppendNode(pSide->StartPoint(), pSide->GetBulge()); pNode = pSide->GetEndNode(); } else //逆向搜索 { polyPath.AppendNode(pSide->EndPoint(), -pSide->GetBulge()); pNode = pSide->GetStartNode(); } pLast = pSide; } polyPath.AppendNode(pTail->m_ptLoc); return TRUE; } void XPrivate::FixGsView() { PersistGsView(NULL); } extern Acad::ErrorStatus fromAcDbTextStyle(AcGiTextStyle& style, const AcDbObjectId& AcDbStyleId); XPoint XPrivate::GetTextExtend(AcDbObjectId idTextStyle, const TCHAR *pszText, double nHeight, BOOL penups) { AcGiTextStyle txtStyle; VERIFY(fromAcDbTextStyle(txtStyle, idTextStyle) == Acad::eOk); int nRetFlag = txtStyle.loadStyleRec(); txtStyle.setTextSize(nHeight); AcGePoint2d ptExt = txtStyle.extents(pszText, penups, -1, Adesk::kFalse); XPoint ptBox; (AcGePoint2d &)ptBox = ptExt; return ptBox; } void XPrivate::RemoveDupNoXData() { XPushMemVar vTemp(g_bEchoSearch, TRUE); DList lstRemoveDup; PickSet ss(SS_FREE); if (ss.Get(NULL, NULL, NULL, RBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL)) == RTNORM) { long lCount = ss.Length(); for (long i = 0L;im_lstCurves.Append(new XCurveSegment(ent)); } else { pData = new XRemoveDupByLayer(sLayer); pData->m_lstCurves.Append(new XCurveSegment(ent)); lstRemoveDup.Append(pData); } } ss.Erase(); for (int n = 0; nm_sLayer << _T("消除重线: "); int nOldNum = pData->m_lstCurves.Length(); RemoveDupCurves(pData->m_lstCurves); XGeLib::adsout << _T("由") << int(nOldNum) << _T("变为") << pData->m_lstCurves.Length(); for (int k = 0; km_lstCurves.Length(); k++) { pData->m_lstCurves[k]->Make(pData->m_sLayer); } } } } void XPrivate::RemoveExactDupLines(DList &lstCurves) { //初始化消除重线的集合 int len = lstCurves.Length(); DList lstNewCurves; for (int i = 0; i < len; i++) { XCurveSegment &seg = *lstCurves[i]; if (seg.GetLength() < _DIST_SNAP) { continue; } lstNewCurves.Append(new XCurveObject(seg)); } len = lstNewCurves.Length(); if (g_bEchoSearch) { XString sMsg(256); sMsg << _T("对") << len << _T("条线进行消除完全重线"); acedSetStatusBarProgressMeter(sMsg, 0, len); } int nStep = len / 100; if (nStep < 1) { nStep = 1; } for (int i = 0; i < len; i++) { if (g_bEchoSearch && !(i % nStep)) { acedSetStatusBarProgressMeterPos(i); } XCurveObject line1 = *lstNewCurves[i]; if (line1.m_bDeleted) { continue; } ASSERT(line1.Is(CURVE_LINE)); for (int j = 0; j < len; j++) { XCurveObject &line2 = *lstNewCurves[j]; if (j == i) { continue; } if (line2.m_bDeleted) { // 线2已经被删除 continue; } ASSERT(line2.Is(CURVE_LINE)); if ( (line1.GetStartPoint().Distance2d(line2.StartPoint()) < _DIST_SNAP && line1.GetEndPoint().Distance2d(line2.EndPoint()) < _DIST_SNAP) || (line1.GetStartPoint().Distance(line2.EndPoint()) < _DIST_SNAP && line1.GetEndPoint().Distance2d(line2.StartPoint()) < _DIST_SNAP) ) { line2.m_bDeleted = TRUE; //线2要合并到线1内 } } } lstCurves.Reset(); for (int i = 0; i < len; i++) { XCurveObject &ln = *lstNewCurves[i]; if (!ln.m_bDeleted) { lstCurves.Append(new XCurveSegment(ln)); } } if (g_bEchoSearch) { acedRestoreStatusBar(); } } char* XPrivate::xh2cpy(char *to, char *from, int len) { if (!to || !from) { exit(0); } char *p; int len1 = strlen(from); int i = 0; p = to; memcpy(to, from, len1); to[len] = 0; to += len1; for (i = len1; i < len; i++) { *to++ = ' '; } return p; } char* XPrivate::xh3cpy(char *to, char *fr, int len) { if (!to || !fr) { exit(0); } char *from; for (from = fr; *from == ' '; from++) { ; } return XPrivate::xh2cpy(to, from, len); } void XPrivate::xh1cpy(char *to, const char *src) { if (!to || !src) { exit(0); } if (!src) { *to = 0; return; } char sDup[1000]; strcpy(sDup, src); char *p = sDup; while(*p == ' ' || *p == '\t') { p++; } char *q = &sDup[strlen(sDup)]; while (q != p) { q--; if (*q == ' ' || *q == '\t') { *q = 0; } else { break; } } strcpy(to, p); } TCHAR *XPrivate::strnew_delspace(const TCHAR *src) { if (!src) { exit(0); } char tmp[256] = ""; XPrivate::xh1cpy(tmp, _AS(src)); return tstrnew(TString(tmp)); } int XPrivate::GetPickFirst(PickSet &gSet, PickSet &pSet) { resbuf *gset = NULL, *pset = NULL; int nRet = ads_ssgetfirst(&gset, &pset); if (gset) { if (gset->restype == RTPICKS) { PickSet ss0(0); ss0 = gset->resval.rlname; gSet += ss0; ss0.Free(); } ads_relrb(gset); } if (pset) { if (pset->restype == RTPICKS) { PickSet ss0(0); ss0 = pset->resval.rlname; pSet += ss0; ss0.Free(); } ads_relrb(pset); } return nRet; } double XPrivate::GetViewportPScale(int cvport) { AcDbBlockTable *pTable = NULL; acdbCurDwg()->getSymbolTable(pTable, AcDb::kForRead); if (pTable == NULL) { return 0; } AcDbBlockTableIterator *pBlockTableIter = NULL; pTable->newIterator(pBlockTableIter); pTable->close(); if (pBlockTableIter == NULL) { return 0; } for (pBlockTableIter->start(); !pBlockTableIter->done(); pBlockTableIter->step()) { AcDbBlockTableRecord *pRecord = NULL; pBlockTableIter->getRecord(pRecord, AcDb::kForRead); if (pRecord == NULL) { continue; } AcDbBlockTableRecordIterator *pIter = NULL; pRecord->newIterator(pIter); pRecord->close(); if (pIter == NULL) { continue; } for (pIter->start(); !pIter->done(); pIter->step()) { AcDbEntity*pEnt = NULL; pIter->getEntity(pEnt,AcDb::kForRead); if (pEnt != NULL) { AcDbViewport*pVP = AcDbViewport::cast(pEnt); if (pVP != NULL && pVP->number() == cvport) { double s = pVP->centerPoint().z; pEnt->close(); delete pIter; delete pBlockTableIter; return s; } pEnt->close(); } } delete pIter; } delete pBlockTableIter; return 0; } int XPrivate::ConnectPolygonsNew(DList &lstPolygons, XPolygonEx &polyEx1) { if (!lstPolygons) { return RTERROR; } polyEx1 = *lstPolygons.Head(); lstPolygons.Remove(0); LAB_RESTART: if (!lstPolygons) { return RTNORM; } XPolyDist minDist; BOOL bInit = FALSE; int nIndex = 0; for (int i = 0; i < lstPolygons.Length(); i++) { XPolyDist polyDist; int nRet = MinDistance(polyEx1, *lstPolygons[i], polyDist); if (nRet == RTNORM) { if (!bInit) { minDist = polyDist; nIndex = i; bInit = TRUE; } else if (minDist.nDist > polyDist.nDist) { minDist = polyDist; int nIndex = i; } } else { ASSERT(0); } } if (bInit) { XPolygonEx polyEx2; ConnectPolygon(polyEx1, *lstPolygons[nIndex], minDist, polyEx2); polyEx1 = polyEx2; lstPolygons.Remove(nIndex); goto LAB_RESTART; } return RTERROR; } int XPrivate::ConnectPolygons(DList &lstPolygons, XPolygonEx &polyEx1) { if (!lstPolygons) { return RTERROR; } polyEx1 = *lstPolygons.Head(); lstPolygons.Remove(0); LAB_RESTART: for (int i = 0; i < lstPolygons.Length(); i++) { XLine lnConnector; double nDist = GetConnector(polyEx1, *lstPolygons[i], lnConnector); if (IsGoodConnector(lnConnector, lstPolygons, i)) { XPolygonEx polyEx2; ConnectPolygon(polyEx1, *lstPolygons[i], polyEx2); polyEx1 = polyEx2; lstPolygons.Remove(i); goto LAB_RESTART; } } if (lstPolygons.Length()) { #ifndef NDEBUG XGeLib::adsout << _T("\nCan not find good connector!"); #endif for (int i = 0; i < lstPolygons.Length(); i++) { XPolygonEx polyEx2; ConnectPolygon(polyEx1, *lstPolygons[i], polyEx2); polyEx1 = polyEx2; } } return RTNORM; } void XPrivate::RemoveDup() { DList lstRemoveDup; PickSet ss(SS_FREE); if (ss.Get(NULL, NULL, NULL, RBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL)) == RTNORM) { long lCount = ss.Length(); for (long i = 0L; i < lCount; i++) { Entity ent = ss[i]; XString sLayer(256); ent.GetData(8, (TCHAR *)sLayer); XRemoveDupEntByLayer *pData = lstRemoveDup.FindNode((TCHAR *)sLayer, XRemoveDupEntByLayer::CompareForFindByLayer); if (pData) { pData->m_ss += ent; } else { pData = new XRemoveDupEntByLayer(sLayer); pData->m_ss += ent; lstRemoveDup.Append(pData); } } for (int n = 0; nm_sLayer << _T("消除重线: "); long nOldNum = pData->m_ss.Length(); HandleCurveDup(pData->m_ss); XGeLib::adsout << _T("由") << int(nOldNum) << _T("变为") << (int)pData->m_ss.Length(); } } } // 判断桥接是否合适,即不和任何边有交点(位于边内) BOOL XPrivate::IsGoodConnector(const XLine &lnConnector, const XPolygonEx &rPolygon) { for (int j = 0; j < rPolygon.Length(); j++) { XPoint ptInt; XLine lnSide(rPolygon.GetVertex(j), rPolygon.GetVertex(j + 1)); if (ads_inters(lnConnector.GetStartPoint(), lnConnector.GetEndPoint(), lnSide.GetStartPoint(), lnSide.GetEndPoint(), 1, ptInt) == RTNORM) { int nHit1 = lnSide.HitTest2d(ptInt); if (nHit1 == 5) //点在线内 { return FALSE; } } } return FALSE; } // 取得连接桥 int XPrivate::GetConnector(const XPolygonEx &poly1, const XPolygonEx &poly2, XLine &lnConnector) { if (!poly1.Length() || !poly2.Length()) { ASSERT(0); return RTERROR; } int nIndex1 = 0; int num1 = poly1.Length(); int nIndex2 = 0; //poly2与pt最近的顶点 double nMinDist = 0.0; int num2 = poly2.Length(); for (int j = 0; j < num1; j++) { XPoint pt = poly1[j]; for (int i = 0; i < num2; i++) { double nDist = pt.Distance(poly2[i]); if (i == 0 && j == 0) { nMinDist = nDist; } else if (nDist < nMinDist) { nMinDist = nDist; nIndex2 = i; nIndex1 = j; } } } lnConnector.SetStartPoint(*poly1[nIndex1]); lnConnector.SetEndPoint(*poly1[nIndex2]); return RTNORM; } // 判断桥接是否合适 BOOL XPrivate::IsGoodConnector(const XLine &lnConnector, const DList &lstPolygons, int idxExclude) { for (int i = 0; i < lstPolygons.Length(); i++) { if (i == idxExclude) { continue; } const XPolygonEx &rPolygon = lstPolygons[i]; if (!XPrivate::IsGoodConnector(lnConnector, rPolygon)) { return FALSE; } } return TRUE; } ads_real XPrivate::MinDistance(const XLine &ln1, const XLine &ln2, XPoint &ptInt1, XPoint &ptInt2) { assert(ln1.m_nFlag == LS_FINITE && ln2.m_nFlag == LS_FINITE); XPoint ptInt; if (ln1.Intersection(&ln2, ptInt)) { ptInt1 = ptInt2 = ptInt; return 0.0; } XPoint pt1, pt2; // ln1在ln2上的两垂足 ln1.GetStartPoint().Project(&ln2, pt1); ln1.GetEndPoint().Project(&ln2, pt2); int nPrFlag1 = pt1 & ln2; int nPrFlag2 = pt2 & ln2; XPoint qt1, qt2; ln2.GetStartPoint().Project(&ln1, qt1); ln2.GetEndPoint().Project(&ln1, qt2); int nQrFlag1 = qt1 & ln1; int nQrFlag2 = qt2 & ln1; DList lstResult; ads_real pDist1 = (nPrFlag1 != PR_OUTSIDE && nPrFlag1 != PR_EXTEND) ? ads_distance(ln1.GetStartPoint(), pt1) : 0.0; lstResult.Append(new XLineDist(pDist1, ln1.GetStartPoint(), pt1)); ads_real pDist2 = (nPrFlag2 != PR_OUTSIDE && nPrFlag2 != PR_EXTEND) ? ads_distance(ln1.GetEndPoint(), pt2) : 0.0; lstResult.Append(new XLineDist(pDist2, ln1.GetEndPoint(), pt2)); ads_real qDist1 = (nQrFlag1 != PR_OUTSIDE && nQrFlag1 != PR_EXTEND) ? ads_distance(ln2.GetStartPoint(), qt1) : 0.0; lstResult.Append(new XLineDist(qDist1, qt1, ln2.GetStartPoint())); ads_real qDist2 = (nQrFlag2 != PR_OUTSIDE && nQrFlag2 != PR_EXTEND) ? ads_distance(ln2.GetEndPoint(), qt2) : 0.0; lstResult.Append(new XLineDist(qDist2, qt2, ln2.GetEndPoint())); lstResult.Append(new XLineDist(ads_distance(ln1.GetStartPoint(), ln2.GetStartPoint()), ln1.GetStartPoint(), ln2.GetStartPoint())); lstResult.Append(new XLineDist(ads_distance(ln1.GetStartPoint(), ln2.GetEndPoint()), ln1.GetStartPoint(), ln2.GetEndPoint())); lstResult.Append(new XLineDist(ads_distance(ln1.GetEndPoint(), ln2.GetStartPoint()), ln1.GetEndPoint(), ln2.GetStartPoint())); lstResult.Append(new XLineDist(ads_distance(ln1.GetEndPoint(), ln2.GetEndPoint()), ln1.GetEndPoint(), ln2.GetEndPoint())); lstResult.QuickSort(XLineDist::Compare); XLineDist *pp1 = lstResult[0]; ptInt1 = pp1->ptLocation1; ptInt2 = pp1->ptLocation2; return pp1->nDist; } int XPrivate::MinDistance(XLine &ln1, XPolygonEx &poly2, XPolyDist &result) { assert(ln1.m_nFlag == LS_FINITE); DList lstResult; for (int i = 0; i < poly2.Length(); i++) { XLine ln2(LS_FINITE); poly2.NthLine(i, ln2); XPoint pt1, pt2; ads_real nDist = XPrivate::MinDistance(ln1, ln2, pt1, pt2); if (nDist < _DIST_SNAP) { result.ptLocation1 = pt1; result.ptLocation2 = pt2; result.nDist = nDist; result.nIndex2 = i; return RTERROR; } else { lstResult.Append(new XPolyDist(nDist, 0, i, pt1, pt2)); } } lstResult.QuickSort(XPolyDist::Compare); result = *lstResult[0]; return RTNORM; } int XPrivate::MinDistance(XPolygonEx &poly1, XPolygonEx &poly2, XPolyDist &result) { DList lstResult; for (int i = 0; i < poly1.Length(); i++) { XLine ln1(LS_FINITE); poly1.NthLine(i, ln1); XPolyDist *pRes = new XPolyDist(); if (XPrivate::MinDistance(ln1, poly2, *pRes) != RTNORM) { result = *pRes; result.nIndex1 = i; delete pRes; return RTERROR; } else { pRes->nIndex1 = i; lstResult.Append(pRes); } } lstResult.QuickSort(XPolyDist::Compare); result = *lstResult[0]; return RTNORM; } double XPrivate::GetAnglePrecFromRadius(double radius) { double newAngPrec = 2 * asin(0.5 * g_distZero / radius); if (newAngPrec > 0.1) { newAngPrec = 0.1; } else if (newAngPrec < 1E-18) { newAngPrec = 1E-18; } return newAngPrec; } double XPrivate::GetParaPrecFromLength(double length) { double newPrec = g_distZero / length; if (newPrec > 0.1) { newPrec = 0.1; } else if (newPrec < 1E-18) { newPrec = 1E-18; } return newPrec; } bool XPrivate::IsParaInSeg(double pa,double prec) { WPushVar vTemp(g_fZero,prec); return UPEQUAL_ZERO(pa) && DOWNEQUAL_ZERO(pa - 1); } // 通用的函数, 要移到其他模块 Acad::ErrorStatus XPrivate::ReadCurve(AcDbDwgFiler *pFiler, XCurveSegment &seg) { pFiler->readItem(&(AcGePoint3d &)seg.GetStartPoint()); pFiler->readItem(&(AcGePoint3d &)seg.GetEndPoint()); double dBulge = 0; pFiler->readItem(&dBulge); seg.SetBulge(dBulge); return pFiler->filerStatus(); } Acad::ErrorStatus XPrivate::ReadCurveList(AcDbDwgFiler *pFiler, DList &lstSegs) { Adesk::UInt16 nCount = 0; pFiler->readItem(&nCount); for (Adesk::UInt16 i = 0U; ifilerStatus(); } Acad::ErrorStatus XPrivate::WriteCurve(AcDbDwgFiler *pFiler, const XCurveSegment &seg) { pFiler->writeItem((const AcGePoint3d &)seg.GetStartPoint()); pFiler->writeItem((const AcGePoint3d &)seg.GetEndPoint()); pFiler->writeItem(seg.GetBulge()); return pFiler->filerStatus(); } Acad::ErrorStatus XPrivate::WriteCurveList(AcDbDwgFiler *pFiler, const DList &lstSegs) { Adesk::UInt16 nCount = (Adesk::UInt16)lstSegs.Length();; pFiler->writeItem(nCount); for (Adesk::UInt16 i = 0U; i < nCount; i++) { XPrivate::WriteCurve(pFiler, lstSegs[(int)i]); } return pFiler->filerStatus(); } // 用两个区域对一曲线进行裁剪, 剩下最长的曲线作为代表 XCurveSegment XPrivate::GetMaxCurveAfterClip(const XCurveSegment &cvSource, const XPoly2D &sPoly, const XPoly2D &ePoly) { XCurveSegment cvOffset = cvSource; cvOffset.SetLineFlag(LS_FINITE); DList lstSource, lstIn, lstOut, lstEdge; lstSource.Append(new XCurveSegment(cvOffset)); for (int nFrom = 0; nFrom < 2; nFrom++) { //起点裁剪和终点裁剪 const XPoly2D &poly = nFrom ? ePoly : sPoly; if (!!poly) { lstOut.Reset(); PolyClip(lstSource, poly, lstIn, lstOut, lstEdge); lstSource.Reset(); for (int i = 0; i < lstOut.Length(); i++) { lstSource.Append(new XCurveSegment(*lstOut[i])); } } } // 取裁剪后最长的边线作为代表(经验解) if (!lstSource) { cvOffset = cvSource; cvOffset.SetEndPoint(cvOffset.GetStartPoint()); } else { XCurveSegment *pMax = lstSource[0]; for (int i = 1; i < lstSource.Length(); i++) { if (lstSource[i]->GetLength() > pMax->GetLength()) { pMax = lstSource[i]; } } cvOffset = *pMax; } cvOffset.SetLineFlag(cvSource.GetLineFlag()); return cvOffset; } // 用两个区域对一曲线进行裁剪, 剩下的包含给定的点作为返回 XCurveSegment XPrivate::GetCurveContainPointAfterClip(XPoint ptPick, const XCurveSegment &cvSource, const XPoly2D &sPoly, const XPoly2D &ePoly) { XCurveSegment cvOffset = cvSource; cvOffset.SetLineFlag(LS_FINITE); DList lstSource, lstIn, lstOut, lstEdge; lstSource.Append(new XCurveSegment(cvOffset)); for (int nFrom = 0; nFrom < 2; nFrom++) { //起点裁剪和终点裁剪 const XPoly2D &poly = nFrom ? ePoly : sPoly; if (!!poly) { lstOut.Reset(); PolyClip(lstSource, poly, lstIn, lstOut, lstEdge); lstSource.Reset(); for (int i = 0; i < lstOut.Length(); i++) { lstSource.Append(new XCurveSegment(*lstOut[i])); } } } if (!lstSource) { cvOffset = cvSource; cvOffset.SetEndPoint(cvOffset.GetStartPoint()); } else { BOOL bFind = FALSE; for (int i = 0; i < lstSource.Length(); i++) { XCurveSegment &seg = *lstSource[i]; XPoint ptPrj; if (seg.ProjectToMe(ptPick, ptPrj) == RTNORM && (ptPrj & seg) == PR_INSIDE) { cvOffset = seg; bFind = TRUE; break; } } if (!bFind) { XCurveSegment *pMax = lstSource[0]; for ( int i = 1; i < lstSource.Length(); i++) { if (lstSource[i]->GetLength() > pMax->GetLength()) { pMax = lstSource[i]; } } cvOffset = *pMax; } } cvOffset.SetLineFlag(cvSource.GetLineFlag()); return cvOffset; } int XPrivate::MakeArcWallSeg(XExplodeDraw &dc, const XArc &arc, ads_real height, ads_real iDist, ads_real oDist, int bShowStart, int bShowEnd) { if (height <= 0) { height = 0; } if (iDist >= arc.GetRadius() || oDist >= arc.GetRadius()) { return RTERROR; } XArc iArc = arc.Offset(-iDist); XArc oArc = arc.Offset(oDist); XPrivate::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd); XPrivate::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd); return RTNORM; } void XPrivate::MakeArcWallSeg(XExplodeDraw &dc, const XArc &iArc, const XArc &oArc, ads_real height, int bShowStart, int bShowEnd) { XPrivate::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd); XPrivate::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd); } // 对xBeg开始,以步长nStep共nDivNum步,高度为nHeight,进行镶嵌, // 结果存入lstSectFaces。bHasTop, bHasBot, bHasLeft, bHasRight,外围边的可见性 void XPrivate::Tessellate(DList &lstSectFaces, double xBeg, double nStep, int nDivNum, double nHeight, BOOL bHasTop, BOOL bHasBot, BOOL bHasLeft, BOOL bHasRight) { double nPrev = xBeg; for (int n = 1; n <= nDivNum; n++) { double nNext = xBeg + n * nStep; X3DFace *pFace = new X3DFace; int nFlag = pFace->GetFlag(); // 底-右-顶-左 if (!bHasBot) { nFlag |= 0x01; } if (bHasRight && n == nDivNum) { ; } else { nFlag |= 0x02; } if (!bHasTop) { nFlag |= 0x04; } if (bHasLeft && n == 1) { ; } else { nFlag |= 0x08; } pFace->SetFlag(nFlag); pFace->SetVertex(0, XPoint(nPrev, 0.0)); pFace->SetVertex(1, XPoint(nNext, 0.0)); pFace->SetVertex(2, XPoint(nNext, nHeight)); pFace->SetVertex(3, XPoint(nPrev, nHeight)); lstSectFaces.Append(pFace); nPrev = nNext; } } // 把平面(含洞口)的模型,化解为三角形 // z坐标全部为0 int XPrivate::AsTriangleFaces(const XPolygonEx &polyOut, const DList &lstHoles, DList &lstFaces) { XTrianglePface lstTris; if (XPrivate::Triangulate(polyOut, lstHoles, lstTris)) { int nFlag = 0; for (int n = 0; n < lstTris.Length(); n++) { XTriangle *triangle = lstTris[n]; ASSERT(triangle); X3DFace *pFace = new X3DFace; nFlag = triangle->m_nFlag; pFace->SetVertex(0, triangle->vertex1); pFace->SetVertex(1, triangle->vertex2); pFace->SetVertex(2, triangle->vertex3); pFace->SetVertex(3, triangle->vertex1); nFlag |= FLAG_TRIANGLE; pFace->SetFlag(nFlag); lstFaces.Append(pFace); } return RTNORM; } return RTERROR; } // 把平面(含洞口)的模型,化解为三角形 // z坐标全部为0 int XPrivate::AsTriangleFaces(const XPoly2D &polyOut, const DList &lstHoles, DList &lstFaces) { XPoly poly1; ((XPoly2D &)polyOut).MapToPolygon1(poly1, _AS_SYS_UNIT(g_nCirDeviation)); ASSERT(poly1.Length() > 2); XPolygonEx polyEx1(poly1); if (polyEx1.PathArea() > 0.0) { polyEx1.Reverse(); } return XPrivate::AsTriangleFaces(polyEx1, lstHoles, lstFaces); } BOOL XPrivate::CreateReference(AcGePoint3d org,CString& BlockTableRecordName,double rotAng,CString layerName) { AcDbBlockReference* pNewBlkRef; AcDbObjectId newEntId; AcDbObjectId newBlockId; AcDbBlockTable* pBlockTable; acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead); Acad::ErrorStatus es = pBlockTable->getAt(BlockTableRecordName,newBlockId); if (es != Acad::eOk) { pBlockTable->close(); return 0; } pBlockTable->close(); AcDbObjectId layerId = NULL; if (layerName != _T("")) { if (!IsLayerExistInDb(layerName)) { NewLayer(layerName); } SetLayerFrozen(layerName,false); SetLayerOff(layerName,false); layerId = GetLayerRecordId(layerName); } pNewBlkRef = new AcDbBlockReference; AcGeVector3d normal = AcGeVector3d(0.0,0.0,1.0); AcGePoint3d basePt = org; UCS2WCS(basePt); AcGeMatrix3d mat; acdbUcsMatrix(mat); AcGeMatrix3d mat1; mat1(0,0) = cos(rotAng); mat1(0,1) = -sin(rotAng); mat1(1,0) = sin(rotAng); mat1(1,1) = cos(rotAng); mat = mat * mat1; pNewBlkRef->setBlockTableRecord(newBlockId); pNewBlkRef->setNormal(normal); pNewBlkRef->setBlockTransform(mat); pNewBlkRef->setPosition(basePt); if (layerId != NULL) { pNewBlkRef->setLayer(layerId); } acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord* pBlockTableRec; es = pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRec,AcDb::kForWrite); if (es != Acad::eOk) { pBlockTable->close(); delete pNewBlkRef; return 0; } pBlockTable->close(); es = pBlockTableRec->appendAcDbEntity(newEntId,pNewBlkRef); if (es != Acad::eOk) { pBlockTableRec->close(); return 0; } pBlockTableRec->close(); pNewBlkRef->close(); return 1; } CString XPrivate::GetEnityLayer(AcDbObjectId objId) { CString layer = _T(""); if (objId == NULL) { return _T(""); } AcDbEntity* pEnt = NULL; acdbOpenObject(pEnt,objId,AcDb::kForRead); if (pEnt == NULL) { return _T(""); } TCHAR* str = pEnt->layer(); layer = str; delete str; pEnt->close(); return layer; } BOOL XPrivate::BlockName(CString& blockName) { static unsigned long Block_Num = 0; CString temp; Block_Num++; temp.Format(_T("%ld"),Block_Num); blockName = blockName + temp; return 1; } BOOL XPrivate::CreateBlock(CEntityList& entLst,CString& blockName,AcDbObjectId& blockId,AcGePoint3d org) { if (!XPrivate::BlockName(blockName)) { return 0; } AcDbBlockTable *pBlockTable = NULL; Acad::ErrorStatus ret = acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForWrite); if (ret != Acad::eOk) { return 0; } AcDbBlockTableRecord *pBlockTableRecord = new AcDbBlockTableRecord; pBlockTableRecord->setOrigin(org); pBlockTableRecord->setName(blockName); pBlockTable->add(blockId,pBlockTableRecord); pBlockTable->close(); POSITION pos = entLst.GetHeadPosition(); while (pos != NULL) { CEntity* pEnt = entLst.GetNext(pos); pBlockTableRecord->appendAcDbEntity(pEnt->m_pAcDbEnt); pEnt->m_pAcDbEnt->close(); } pBlockTableRecord->close(); return 1; } AcDbObjectId XPrivate::GetLayerRecordId(CString layerName) { layerName.TrimLeft(); layerName.TrimRight(); if (layerName == _T("")) { return NULL; } AcDbLayerTable *pLayerTable; if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForRead) != Acad::eOk) { return NULL; } AcDbObjectId recordId = NULL; if (pLayerTable->getAt(layerName, recordId) != Acad::eOk) { pLayerTable->close(); return NULL; } pLayerTable->close(); return recordId; } void XPrivate::ReleaseC3DFaceList(C3DFaceList& c3dfaceLst) { POSITION pos = c3dfaceLst.GetHeadPosition(); while (pos != NULL) { C3DFace* pC3DFace = c3dfaceLst.GetNext(pos); delete pC3DFace; } c3dfaceLst.RemoveAll(); } void XPrivate::ReleaseCEntityList(CEntityList& centityLst) { POSITION pos = centityLst.GetHeadPosition(); while (pos != NULL) { CEntity* pEnt = centityLst.GetNext(pos); delete pEnt; } centityLst.RemoveAll(); } void XPrivate::SetLayerOfEntities(CEntityList& entLst,CString layerName, int colorNum) { SetLayer(layerName, colorNum); POSITION pos = entLst.GetHeadPosition(); while (pos != NULL) { CEntity* pEnt = entLst.GetNext(pos); pEnt->m_pAcDbEnt->setLayer(layerName); pEnt->m_pAcDbEnt->setColorIndex(256); } } BOOL XPrivate::IsLayerExistInDb(CString layerName) { layerName.TrimLeft(); layerName.TrimRight(); if (layerName == _T("")) { return 0; } AcDbLayerTable *pLayerTable; if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForRead) != Acad::eOk) { return 0; } BOOL ret = pLayerTable->has(layerName); pLayerTable->close(); return ret; } BOOL XPrivate::SetLayer(CString layerName, int colorNum) { layerName.TrimLeft(); layerName.TrimRight(); if (layerName == _T("")) { layerName = _T("0"); } if (XPrivate::IsLayerExistInDb(layerName)) { AcDbLayerTable *pLayerTable; if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk) { return 0; } AcDbLayerTableRecord* pLayerTableRecord; if (pLayerTable->getAt(layerName, pLayerTableRecord,AcDb::kForWrite) == Acad::eOk) { pLayerTable->close(); if (pLayerTableRecord->isFrozen()) { pLayerTableRecord->setIsFrozen(false); } if (pLayerTableRecord->isOff()) { pLayerTableRecord->setIsOff(false); } if (colorNum > 0 && colorNum < 256) { AcCmColor color; color.setColorIndex(colorNum); pLayerTableRecord->setColor(color); } pLayerTableRecord->close(); return 1; } else { pLayerTable->close(); return 0; } } return NewLayer(layerName, colorNum); } BOOL XPrivate::NewLayer(CString& layerName, int colorNum, BOOL bFreeze) { layerName.TrimLeft(); layerName.TrimRight(); if (layerName == _T("")) { layerName = _T("0"); return 0; } AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord; if (!pLayerTableRecord) { return 0; } pLayerTableRecord->setName(layerName); if (colorNum > 0 && colorNum < 256) { AcCmColor color; color.setColorIndex(colorNum); pLayerTableRecord->setColor(color); } if (bFreeze) { pLayerTableRecord->setIsFrozen(1); } AcDbLayerTable *pLayerTable; if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForWrite) != Acad::eOk) { delete pLayerTableRecord; return 0; } AcDbObjectId recordId; if (pLayerTable->add(recordId,pLayerTableRecord) != Acad::eOk) { pLayerTable->close(); delete pLayerTableRecord; return 0; } pLayerTable->close(); pLayerTableRecord->close(); return 1; } void XPrivate::C3DFaceList2EntityList(C3DFaceList& c3dFaceLst,CEntityList& entLst) { POSITION pos = c3dFaceLst.GetTailPosition(); while (pos != NULL) { C3DFace* pNode = c3dFaceLst.GetPrev(pos); CEntity* pCEnt = new CEntity(pNode->m_p3DFace); entLst.AddTail(pCEnt); } } BOOL XPrivate::SetLayerFrozen(CString layerName, bool bFreeze) { layerName.TrimLeft(); layerName.TrimRight(); if (layerName == _T("")) { return 0; } AcDbLayerTable *pLayerTable; if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk) { return 0; } AcDbLayerTableRecord* pLayerTableRecord; if (pLayerTable->getAt(layerName, pLayerTableRecord, AcDb::kForWrite) != Acad::eOk) { pLayerTable->close(); return 0; } pLayerTable->close(); if (bFreeze) { if (!pLayerTableRecord->isFrozen()) { pLayerTableRecord->setIsFrozen(true); } } else { if (pLayerTableRecord->isFrozen()) { pLayerTableRecord->setIsFrozen(false); } } pLayerTableRecord->close(); return 1; } BOOL XPrivate::SetLayerOff(CString layerName, bool bOff) { layerName.TrimLeft(); layerName.TrimRight(); if (layerName == _T("")) { return 0; } AcDbLayerTable *pLayerTable; if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk) { return 0; } AcDbLayerTableRecord* pLayerTableRecord; if (pLayerTable->getAt(layerName, pLayerTableRecord, AcDb::kForWrite) != Acad::eOk) { pLayerTable->close(); return 0; } pLayerTable->close(); if (bOff) { if (!pLayerTableRecord->isOff()) { pLayerTableRecord->setIsOff(true); } } else { if (pLayerTableRecord->isOff()) { pLayerTableRecord->setIsOff(false); } } pLayerTableRecord->close(); return 1; } void XPrivate::WCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer) { ads_point ads_pt1,ads_ret; XPrivate::ARX2AdsPt(pt,ads_pt1); ads_name pEntName; acdbGetAdsName(pEntName,objId); struct resbuf from,to; from.restype = RTSHORT; from.resval.rint = 0; to.restype = RTENAME; ads_name_set(pEntName,to.resval.rlname); //ECS acedTrans(ads_pt1,&from,&to,bVer,ads_ret); XPrivate::Ads2ARXPt(ads_ret,pt); } void XPrivate::UCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer) { ads_point ads_pt1,ads_ret; XPrivate::ARX2AdsPt(pt,ads_pt1); ads_name pEntName; acdbGetAdsName(pEntName,objId); struct resbuf from,to; from.restype = RTSHORT; from.resval.rint = 1; to.restype = RTENAME; ads_name_set(pEntName,to.resval.rlname); //ECS acedTrans(ads_pt1,&from,&to,bVer,ads_ret); XPrivate::Ads2ARXPt(ads_ret,pt); } void XPrivate::UCS2WCS(AcGePoint3d& pt,BOOL bVer) { ads_point ads_pt1,ads_ret; XPrivate::ARX2AdsPt(pt,ads_pt1); struct resbuf from,to; from.restype = RTSHORT; from.resval.rint = 1; //UCS to.restype = RTSHORT; to.resval.rint = 0; int ret = RTNORM; ret = acedTrans(ads_pt1,&from,&to,bVer,ads_ret); XPrivate::Ads2ARXPt(ads_ret,pt); } void XPrivate::WCS2UCS(AcGePoint3d& pt,BOOL bVer) { ads_point ads_pt1,ads_ret; XPrivate::ARX2AdsPt(pt,ads_pt1); struct resbuf from,to; from.restype = RTSHORT; from.resval.rint = 0; //WCS to.restype = RTSHORT; to.resval.rint = 1; //UCS acedTrans(ads_pt1,&from,&to,bVer,ads_ret); XPrivate::Ads2ARXPt(ads_ret,pt); } void XPrivate::ECS2UCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer) { ads_point ads_pt1,ads_ret; XPrivate::ARX2AdsPt(pt,ads_pt1); ads_name pEntName; acdbGetAdsName(pEntName,objId); struct resbuf from,to; from.restype = RTENAME; ads_name_set(pEntName,from.resval.rlname); //ECS to.restype = RTSHORT; to.resval.rint = 1; acedTrans(ads_pt1,&from,&to,bVer,ads_ret); XPrivate::Ads2ARXPt(ads_ret,pt); } void XPrivate::ECS2WCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer) { ads_point ads_pt1,ads_ret; XPrivate::ARX2AdsPt(pt,ads_pt1); ads_name pEntName; acdbGetAdsName(pEntName,objId); struct resbuf from,to; from.restype = RTENAME; ads_name_set(pEntName,from.resval.rlname); //ECS to.restype = RTSHORT; to.resval.rint = 0; acedTrans(ads_pt1,&from,&to,bVer,ads_ret); XPrivate::Ads2ARXPt(ads_ret,pt); } BOOL XPrivate::IsOverlap(AcGeLine3d& line1,AcGeLineSeg3d& lineSeg2,const AcGeTol& tol) { if (line1.isOn(lineSeg2.startPoint(),tol) && line1.isOn(lineSeg2.endPoint(),tol)) { return 1; } else { return 0; } } BOOL XPrivate::IsEqualSign(double x1,double x2) { if (x1 > fTOL && x2 > fTOL) { return 1; } if (x1 < fTOL && x2 < fTOL) { return 1; } return 0; } int XPrivate::xdata_extract_str(struct resbuf **rb, int *num) { if ((*rb) && ((*rb)->restype == 1070)) { *num = (*rb)->resval.rint; (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int XPrivate::xdata_extract_str(struct resbuf **rb, ads_real *num) { if ((*rb) && ((*rb)->restype == 1040)) { *num = (*rb)->resval.rreal; (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int XPrivate::xdata_extract_strPt(struct resbuf **rb, ads_point pt) { if ((*rb) && ((*rb)->restype == 1010)) { Cpoint(pt, (*rb)->resval.rpoint); (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int XPrivate::xdata_extract_str(struct resbuf **rb, TCHAR *str) { if ((*rb) && ((*rb)->restype == 1000)) { _tcscpy(str, (*rb)->resval.rstring); (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int XPrivate::xdata_extract_handle(struct resbuf **rb, TCHAR *str) { if ((*rb) && ((*rb)->restype == 1005)) { _tcscpy(str, (*rb)->resval.rstring); (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int XPrivate::xdata_handle_assoc_single(ads_name ent, int tag, ads_name assoc_ent) { struct resbuf *entdata, *xdata, *tmprb, *rb; get_app_xdata(ent, NULL, &entdata, &xdata); if ((entdata == NULL) || (xdata == NULL)) { ads_relrb(entdata); return(0); } if ((rb = get_xdata_tag_item(xdata, tag, &tmprb)) == NULL) { ads_relrb(entdata); return(0); } else { if (ads_handent(rb->rbnext->resval.rstring, assoc_ent) != RTNORM) { ads_printf(_T("\nSPY: Stale handle!")); ads_relrb(entdata); return(0); } else { ads_relrb(entdata); return(1); } } } void XPrivate::set_xdata_tag_item(struct resbuf **xdata, int tag, struct resbuf *tag_xdata, const TCHAR *appname) { struct resbuf *tmpxd, *old_xdata, *rb, *lagptr, *pretag_ptr; int nested_list; if (*xdata == NULL) { if ((appname == NULL) || (appname[0] == _T('\0'))) { *xdata = ads_buildlist(-3, 1001, Are_appname, 0); } else { *xdata = ads_buildlist(-3, 1001, appname, 0); } } if ((tmpxd = get_xdata_tag_item(*xdata, tag, &pretag_ptr)) == NULL) { if (!tag_xdata) { return; } rb = ads_newrb(1070); rb->resval.rint = tag; add_2_rblist(xdata, rb, FALSE); append_rblists(xdata, tag_xdata); return; } lagptr = tmpxd; nested_list = 0; if (tmpxd->rbnext) { tmpxd = tmpxd->rbnext; } while (tmpxd->rbnext) { if (tmpxd->restype == 1002) { if (!_tcscmp(tmpxd->resval.rstring, PRIV_STR(_T("{")))) { nested_list++; } else if (!_tcscmp(tmpxd->resval.rstring, PRIV_STR(_T("}")))) { nested_list--; } } if (nested_list == 0) { break; } tmpxd = tmpxd->rbnext; } old_xdata = lagptr->rbnext; if (!tag_xdata) { pretag_ptr->rbnext = tmpxd->rbnext; tmpxd->rbnext = NULL; } else { lagptr->rbnext = tag_xdata; rb = tag_xdata; while (rb->rbnext) { rb = rb->rbnext; } rb->rbnext = tmpxd->rbnext; tmpxd->rbnext = NULL; } ads_relrb(old_xdata); } struct resbuf *XPrivate::get_xdata_tag_item(struct resbuf * xdata, int tag, struct resbuf **lagptr) { struct resbuf *xptr, *tmp_lagptr; int nested_list = 0; tmp_lagptr = NULL; tmp_lagptr = xptr = xdata; while (xptr) { if (xptr->restype == 1002) { if (!_tcscmp(xptr->resval.rstring, PRIV_STR(_T("{")))) { nested_list++; } else if (!_tcscmp(xptr->resval.rstring, PRIV_STR(_T("}")))) { nested_list--; } } else if (xptr->restype == 1070) { if (nested_list == 0) { if (xptr->resval.rint == tag) { if (lagptr) { *lagptr = tmp_lagptr; } return(xptr); } else { if (xptr->rbnext) { xptr = xptr->rbnext; if (tmp_lagptr->rbnext != xptr) { tmp_lagptr = tmp_lagptr->rbnext; } if (xptr->restype == 1002) { continue; } if (!xptr->rbnext) { return(NULL); } } else { return(NULL); } } } } xptr = xptr->rbnext; if (tmp_lagptr->rbnext != xptr) { tmp_lagptr = tmp_lagptr->rbnext; } } return(NULL); } struct resbuf * XPrivate::detach_xdata_tag_item( struct resbuf *xdata, int tag) { struct resbuf *tmpxd, *tagptr, *pretag_ptr, *lagptr, *old_xdata; int nested_list; if ((tagptr = XPrivate::get_xdata_tag_item(xdata, tag, &pretag_ptr)) == NULL) { return(NULL); } tmpxd = tagptr; if (tagptr->rbnext && (tagptr->rbnext->restype != 1002)) { tmpxd = tmpxd->rbnext; pretag_ptr->rbnext = tmpxd->rbnext; tmpxd->rbnext = NULL; tagptr->rbnext = NULL; ads_relrb(tagptr); return(tmpxd); } if (tagptr->rbnext && (tagptr->rbnext->restype == 1002)) { tmpxd = tagptr->rbnext; if ((tmpxd->rbnext && (tmpxd->rbnext->restype == 1002)) && (!_tcscmp(tmpxd->rbnext->resval.rstring, _T("}")))) { pretag_ptr->rbnext = tmpxd->rbnext->rbnext; tmpxd->rbnext->rbnext = NULL; ads_relrb(tagptr); return(NULL); } } nested_list = 0; if (!tagptr->rbnext) { return(NULL); } tmpxd = tagptr->rbnext; while (tmpxd) { if (tmpxd->restype == 1002) { if (!_tcscmp(tmpxd->resval.rstring, PRIV_STR(_T("{")))) { nested_list++; } else if (!_tcscmp(tmpxd->resval.rstring, PRIV_STR(_T("}")))) { nested_list--; } } if (nested_list == 0) { break; } lagptr = tmpxd; tmpxd = tmpxd->rbnext; } pretag_ptr->rbnext = tmpxd->rbnext; lagptr->rbnext = NULL; tmpxd->rbnext = NULL; ads_relrb(tmpxd); old_xdata = tagptr->rbnext->rbnext; tagptr->rbnext->rbnext = NULL; ads_relrb(tagptr); return(old_xdata); } int XPrivate::delete_xdata_tag_item(struct resbuf * xdata, int tag) { struct resbuf *tmp; tmp = XPrivate::detach_xdata_tag_item(xdata, tag); if (tmp) { ads_relrb(tmp); return(1); } else { return(0); } } void XPrivate::add_xdata_tag_braces(struct resbuf **tagdata) { struct resbuf *n; n = ads_newrb(1002); n->resval.rstring = _tcsdup(_T("{")); add_2_rblist(tagdata, n, TRUE); n = ads_newrb(1002); n->resval.rstring = _tcsdup(_T("}")); add_2_rblist(tagdata, n, FALSE); } int XPrivate::get_app_xdata(ads_name ent, const TCHAR *apps, struct resbuf **entdata, struct resbuf ** xdata) { struct resbuf *apps_rb; apps_rb = ads_newrb(RTSTR); if ((apps == NULL) || (apps[0] == _T('\0'))) { apps_rb->resval.rstring = _tcsdup(Are_appname); } else { apps_rb->resval.rstring = _tcsdup(apps); } *entdata = ads_entgetx(ent, apps_rb); if (*entdata == NULL) { ads_printf(_T("\nentgetx error!")); *entdata = ads_entget(ent); if (*entdata == NULL) { ads_printf(_T("\nentget error!")); ads_relrb(apps_rb); return(0); } } ads_relrb(apps_rb); *xdata = *entdata; while ((*xdata) && ((*xdata)->restype != -3)) { *xdata = (*xdata)->rbnext; } if (*xdata) { *xdata = (*xdata)->rbnext; } return(1); } int XPrivate::AT_setstr_resbuf(struct resbuf *ebuf, const TCHAR * str,int code) { struct resbuf *rb; if ((rb = AT_get_resbuf(ebuf,code)) == NULL) { return RTNONE; } if (rb->restype != RTSTR) { return RTERROR; } if (_tcslen(rb->resval.rstring)<_tcslen(str)) { if ((rb->resval.rstring = (TCHAR *)realloc(rb->resval.rstring,_tcslen(str) + 1)) == NULL) { return RTERROR; } } _tcscpy(rb->resval.rstring,str); return RTNORM; } //不封闭pline的裁剪延伸操作,seg与poly同向同心! void XPrivate::ModifyXPoly2D(XPoly2D& poly,XCurveSegment seg) { if (poly.Length() < 2) { return; } XCurveSegment cv; poly.Nth(0,cv); *poly.Head() = seg.GetStartPoint(); if (cv.Is(CURVE_ARC)) { XArc arc; arc = cv.GetArc(); XVector3D vt = seg.GetStartPoint() - arc.GetCenterPt(); arc.SetStarAngle(vt.AsAcGeVector2d().angle()); poly.SetBulge(0, arc.Bulge()); } poly.Nth(poly.TotalSegments() - 1,cv); *poly.Tail() = seg.GetEndPoint(); if (cv.Is(CURVE_ARC)) { XArc arc; arc = cv.GetArc(); XVector3D vt = seg.GetEndPoint() - arc.GetCenterPt(); arc.SetEndAngle(vt.AsAcGeVector2d().angle()); poly.SetBulge(poly.Length() - 2, arc.Bulge()); } } void XPrivate::ModifyXPoly2DStart(XPoly2D& poly,XCurveSegment seg) { if (poly.Length() < 2) { return; } XCurveSegment cv; poly.Nth(0,cv); *poly.Head() = seg.GetStartPoint(); if (cv.Is(CURVE_ARC)) { XArc arc; arc = cv.GetArc(); XVector3D vt = seg.GetStartPoint() - arc.GetCenterPt(); arc.SetStarAngle(vt.AsAcGeVector2d().angle()); poly.SetBulge(0, arc.Bulge()); } } void XPrivate::ModifyXPoly2DEnd(XPoly2D& poly,XCurveSegment seg) { if (poly.Length() < 2) { return; } XCurveSegment cv; poly.Nth(poly.TotalSegments() - 1,cv); *poly.Tail() = seg.GetEndPoint(); if (cv.Is(CURVE_ARC)) { XArc arc; arc = cv.GetArc(); XVector3D vt = seg.GetEndPoint() - arc.GetCenterPt(); arc.SetEndAngle(vt.AsAcGeVector2d().angle()); poly.SetBulge(poly.Length() - 2, arc.Bulge()); } } void XPrivate::StringToList(const TCHAR *s, XStringList &res, TCHAR cSep) { const TCHAR *pBeg = s; const TCHAR *pEnd = NULL; do { pEnd = _tcschr(pBeg, cSep); XString sTemp(1024); StrCpy(sTemp, pBeg, pEnd); res.Append(tstrnew(sTemp)); if (pEnd) { pBeg = pEnd + 1; } } while(pEnd != NULL); } int XPrivate::MergeCurve(XCurveSegment &curve, XCurveSegment &seg, int bMinusCurve, int bMinusSeg) { int bMerged = 0; int bLine1 = curve.Is(CURVE_LINE), bLine2 = seg.Is(CURVE_LINE); //曲线类型相同, 走向相同 if (bLine1 == bLine2 && bMinusCurve == bMinusSeg) { if (bLine1) { if (CT_IsSameDrt(curve.XLine::Direction(), seg.XLine::Direction(), _angSnap)) { curve.SetEndPoint(seg.GetEndPoint()); bMerged = 1; } } else { XArc arc1 = curve.GetArc(); XArc arc2 = seg.GetArc(); if (fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt()) { if (bMinusSeg) { arc1.SetStarAngle(arc2.GetStarAngle()); } else { arc1.SetEndAngle(arc2.GetEndAngle()); } if (fabs(arc1.Bulge()) < _angSnap || fabs(arc1.Bulge() - 2 * PI) < _angSnap) { ; } else { curve = arc1; bMerged = 1; } } } } return bMerged; } void XPrivate::CircleToPoly(const XCircle &cir, XPoly &poly, int nDiv) { double nAng = PI * 2.0 / nDiv; poly.Reset(); for (int i = 0; i < nDiv; i++) { XPoint ptVertex; ads_polar(cir.GetCenterPt(), i * nAng, cir.GetRadius(), ptVertex); poly.Append(new XPoint(ptVertex)); } } AcDbObject* XPrivate::GetDbConfigObjFromDict(AcDbDictionary *pXDict, AcDb::OpenMode mode) { Acad::ErrorStatus es=Acad::eOk; AcDbObjectId idExist; AcDbObject *pIObj = NULL; es = pXDict->getAt(_T("AEC_DBCONFIG"), idExist); if (es == Acad::eOk) { es=acdbOpenObject(pIObj, idExist, mode); if (es == Acad::eOk) return pIObj; } else { mode = AcDb::kForWrite; } if(mode==AcDb::kForWrite) { if(pXDict->upgradeOpen()==Acad::eOk) { AcRxClass* pDbConfigRx = AcRxClass::cast(acrxClassDictionary->at(_T("TDbConfig"))); if (pDbConfigRx != NULL) { pIObj = (AcDbObject*)pDbConfigRx->create(); //初始化线型 struct resbuf rb,rbNext; rb.restype = RTSTR; rb.resval.rstring = _tcsdup(_T("InitLineType")); rb.rbnext = &rbNext; rbNext.restype = RTSTR; rbNext.resval.rstring = (TCHAR*)pXDict->database(); pIObj->setXData(&rb); AcDbObjectId id; es = pXDict->setAt(_T("AEC_DBCONFIG"), pIObj, id); ASSERT(es == Acad::eOk); } pXDict->downgradeOpen(); } } return pIObj; } AcDbObject * XPrivate::GetDwgGlobalObj(AcDb::OpenMode opMode, AcDbDatabase *pDb) { AcDbObject* pInitSet = NULL; AcDbDictionary* pNamedObj = NULL; if(!pDb) { pDb=acdbCurDwg(); } if(pDb && pDb->getNamedObjectsDictionary(pNamedObj, AcDb::kForRead) == Acad::eOk && pNamedObj) { pInitSet = XPrivate::GetDbConfigObjFromDict(pNamedObj, opMode); pNamedObj->close(); } return pInitSet; } //modify by zjq on 100310 从AEC_KERNAL工程移入 AcDbObjectId XPrivate::InitDynTextStyle() { AcDbObjectId idRet=GetTextStyleId(_T("_AEC_DYN")); if(!idRet) { AcDbTextStyleTableRecord *pStyle=new AcDbTextStyleTableRecord; pStyle->setName(_T("_AEC_DYN")); #if ARX < 21 int iCharSet = 0, iPitchFamily = 0; if (pStyle->setFont(_T("宋体"), Adesk::kFalse, Adesk::kFalse, iCharSet, iPitchFamily) == Acad::eOk) #else Autodesk::AutoCAD::PAL::FontUtils::FontPitch pitch; Autodesk::AutoCAD::PAL::FontUtils::FontFamily family; Charset charset; if (pStyle->setFont(_T("宋体"), Adesk::kFalse, Adesk::kFalse, charset, pitch, family) == Acad::eOk) #endif idRet=AddTextStyle(pStyle, TRUE); else delete pStyle; } return idRet; } XConfigBase* g_pGlobalConfigBase = NULL; XConfigBase* XPrivate::GetGlobalConfigBase() { if (g_pGlobalConfigBase == NULL) { AcDbObject* pObj = XPrivate::GetDwgGlobalObj(AcDb::kForRead,g_pCurrentDb); if (pObj != NULL) { g_pGlobalConfigBase = (XConfigBase*)pObj->xData(_T("TDbConfig"));//AecConfig pObj->close(); } } return g_pGlobalConfigBase; } BOOL DocGetCurMeterUnitDraw() { BOOL bMeterUnitDraw = FALSE; XConfigBase* pBase = GetGlobalConfigBase(); if (pBase != NULL) { bMeterUnitDraw = pBase->DocGetMeterUnitDraw(); } return bMeterUnitDraw; }