//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : 内部全局函数实现文件 // = Version : ver2.0 // = Author : tg // = CreateDate : 2002-09-09 // = Description: 全局函数的声明 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "TchPrivateGlobalFunc.h" #include "TGGeCurveSegSegEx.h" #include "TSymbolTableRecord.h" #include "TDbPolyCurveEnt.h" #include "TPushAcadVar.h" #include "TPushMemVar.h" #include "THole.h" #include "TIdPointPair.h" #include "TSortSideOnVertex.h" #include "TSearchRegionFromCurve.h" #include "TRemoveDupByLayer.h" #include "TDPtrList.h" #include "TGGeCurveSegSeg.h" #include "TSearchException.h" #include "TDupWallException.h" #include "TPickEntSet.h" #include "TGGeLineDist.h" #include "TGGiExplodeDraw.h" #include "TWPushVar.h" #include "TAcDbBlockTableRecPtr.h" #include "imgdef.h" #include "imgent.h" #include "TGGeTrianglePface.h" #include "TDbDwgLicense.h" #include "TAString.h" #include "TUString.h" #include "TConfigBase.h" #include "TchGlobalCurveFunc.h" #include "TGGeCurveInline.h" static TCHAR Are_appname[] = _T("_XG_HVAC"); // flag: TURE--add head; FALSE--add tail static void Add2Rblist(struct resbuf **tagdata, struct resbuf *n, int flag) { struct resbuf *tmptr; if(flag) { tmptr = LinkResbufList(n, *tagdata); } else { tmptr = LinkResbufList(*tagdata, n); } *tagdata = tmptr; } BOOL TchPrivate::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 TchPrivate::CompareObjectId(const AcDbObjectId *id1, const void *id2) { if (*id1 == *(const AcDbObjectId *)id2) { return 0; } return 1; } int TchPrivate::CompareObjectId(const AcDbSoftPointerId *id1, const void *id2) { if (*id1 == *(const AcDbSoftPointerId *)id2) { return 0; } return 1; } PGroups TchPrivate::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); //modify by xlc on 101217 修改输出信息 //ApplicationError(_T("\nError in fuction BuildList.No enough memory.\n")); ads_printf(_T("\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) { (*(TADSGePoint3d *)cur->point) = **(TADSGePoint3d **)PArguments; PArguments += sizeof(void *); } else if (type == RTSTR) { cur->string = _tcsdup(*(TCHAR **)PArguments); PArguments += sizeof(void *); } else if (type == RTSHORT) { cur->shortInt = *(int*)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); //modify by xlc on 101217 修改输出信息 //ApplicationError(_T("\nError in fuction BuildList.Undocumented DXFcode. code=%d\n"),code); ads_printf(_T("\n创建参数链表错误,不支持的DXF码%d\n"),code); return NULL; } } return list; } ads_real TchPrivate::GetXDirection(const TGGeCurveSegment &cv1, const TGGeCurveSegment &cv2, const TADSGePoint3d &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 = AngleRangeTo2PI(nDrt1 + PI); TGGeSector sec1(nDrt1, nDrtRev1); ads_real nRes1 = *sec1.NearAngle(0.0); ads_real nDrt2 = cv2.Direction(ptLoc); ads_real nDrtRev2 = AngleRangeTo2PI(nDrt2 + PI); TGGeSector sec2(nDrt2, nDrtRev2); ads_real nRes2 = *sec2.NearAngle(0.0); TGGeSector sec(nRes1, nRes2); nRes = *sec.NearAngle(0.0); } return nRes; } //不判断顶点 int TchPrivate::HitTestOnEdge(const AcDbFace *pFace, TADSGePoint3d 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); TGGeLine ln; AcGePoint3d pt(ln.GetStartPoint().AsAcGePoint3d()); pFace->getVertexAt(i, pt); pt = ln.GetEndPoint().AsAcGePoint3d(); pFace->getVertexAt(iNext, pt); ln.SetElevation(0.0); if ((pt & ln) == PR_INSIDE) { return i; } } return -1; } AcGeMatrix3d TchPrivate::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 TchPrivate::_RemoveDupCurves(TDPtrList &lstCurves) { //初始化消除重线的集合 int len = lstCurves.Length(); TDPtrList lstNewCurves; for (int i = 0; i < len; i++) { TGGeCurveSegment &seg = *lstCurves[i]; if (seg.GetLength() < _DIST_SNAP) //太短了 { continue; } lstNewCurves.Append(new TGGeCurveSegSegEx(seg)); } len = lstNewCurves.Length(); if (g_bEchoSearch) { TCString sMsg(256); sMsg << _T("对") << len << _T("条线进行消除重线"); acedSetStatusBarProgressMeter(sMsg, 0, len); } int nStep = len / 100; if (nStep < 1) { nStep = 1; } for (i = 0; i < len; i++) { if (g_bEchoSearch && !(i % nStep)) { acedSetStatusBarProgressMeterPos(i); } TGGeCurveSegSegEx &line1 = *lstNewCurves[i]; if (line1.IsDeleted()) { continue; } BOOL bIsLine1 = line1.Is(CURVE_LINE); for (int j = 0; j < len; j++) { TGGeCurveSegSegEx &line2 = *lstNewCurves[j]; if (j == i) { continue; } if (line2.IsDeleted() || bIsLine1 != line2.Is(CURVE_LINE)) { continue; // 线2已经被删除或者两线类型不匹配 } BOOL bPossibleDup = FALSE; TGGeArc ar1, ar2; if (bIsLine1) //对于LINE类型 { TVector3D 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 { (TGGeCircle &)ar1 = line1.GetCircle(); ar1.SetStarAngle(0.0); ar1.SetEndAngle(PI * 2.0); } if (line2.Is(CURVE_ARC)) { ar2 = line2.GetArc(); } else { (TGGeCircle &)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变成圆 { (TGGeCurveSegment &)line1 = TGGeCircle(ar1.GetCenterPt(), ar1.GetRadius()); } } else if (flg1 != PR_OUTSIDE) //Add this 2 lines on 2003/12/15 { (TGGeCurveSegment &)line1 = TGGeCircle(ar1.GetCenterPt(), ar1.GetRadius()); } else { ar1.SetEndAngle(ar2.GetEndAngle()); (TGGeCurveSegment &)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()); (TGGeCurveSegment &)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 (i = 0; i < len; i++) { TGGeCurveSegSegEx &ln = *lstNewCurves[i]; if (!ln.IsDeleted()) { lstCurves.Append(new TGGeCurveSegment(ln)); } } if (g_bEchoSearch) { acedRestoreStatusBar(); } } int TchPrivate::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 TchPrivate::GetArcData(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 = GetResbufAtCode(res2,0); if (_tcscmp(rb1->resval.rstring,_T("ARC")) != 0 && _tcscmp(rb1->resval.rstring,_T("CIRCLE")) != 0) { ads_relrb(res2); return RTERROR; } rb1 = GetResbufAtCode(res2,10); cent[X] = rb1->resval.rpoint[X]; cent[Y] = rb1->resval.rpoint[Y]; cent[Z] = rb1->resval.rpoint[Z]; rb1 = GetResbufAtCode(res2,40); *rad = rb1->resval.rreal; rb1 = GetResbufAtCode(res2,0); if ( _tcscmp(rb1->resval.rstring,_T("ARC")) == 0) { rb1 = GetResbufAtCode(res2,50); *sang = rb1->resval.rreal; rb1 = GetResbufAtCode(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 TchPrivate::operator == (TCStringList &strs1, TCStringList &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 TchPrivate::ThickPoly2Face(TMasterProperties prop, const TGGePoly2D &poly, TADSGePoint3d vtNormal, double nThick, AcDbVoidPtrArray &entSet, AcGeMatrix3d *pMatTran) { ASSERT(nThick > _DIST_SNAP); if (nThick > _DIST_SNAP && poly.Length()) { TGGePoly polygon; poly.AsOpenPoly1(polygon, _AS_SYS_UNIT(g_nCirDeviation)); int nSeg = polygon.Length() - 1; for (int n = 0; n < nSeg; n++) { TADSGePoint3d 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++) { TADSGePoint3d 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) { TGGePoly2D polyBot(poly), polyTop(poly); polyBot.Reverse(); polyTop.SetElevation(poly.Head()->z + nThick); TGGiExplodeDraw dc(entSet); TDPtrList emptyHole; dc.DrawShell(polyBot, emptyHole); dc.DrawShell(polyTop, emptyHole); } } } // 画拉伸圆 void TchPrivate::DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeCircle &cir, ads_real nHeight) { AcDbPolyline line; line.setElevation(cir.GetCenterPt().z); line.setThickness(nHeight); TADSGePoint3d 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 TchPrivate::DrawArcSeg(TGGiExplodeDrawBase &dc, const TGGeArc &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(), TGGiExplodeDraw::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; TADSGePoint3d *ptArray = new TADSGePoint3d[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 (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 TchPrivate::DrawLineSeg(TGGiExplodeDrawBase &dc, const TGGeLine &ln, ads_real nHeight, int bShowStart, int bShowEnd) { int nVertexNum = 4; TADSGePoint3d *ptArray = new TADSGePoint3d[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 TchPrivate::DrawLineSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeLine &ln) { AcGePoint3d line[2] = {ln.GetStartPoint(), ln.GetEndPoint()}; if (pWd) { pWd->geometry().polyline(2, line); } else { pVd->geometry().polyline(2, line); } } //绘制二维弧线 void TchPrivate::DrawArcSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeArc &ar) { TADSGePoint3d 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 TchPrivate::DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeCircle &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 TchPrivate::AsPolyline(const AcDbLine &line, AcDbPolyline &pline) { pline.reset(Adesk::kFalse, 0); pline.setPropertiesFrom(&line); TVector3D vtNormal; (AcGeVector3d &)vtNormal = line.normal(); TADSGePoint3d 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 TchPrivate::AsPolyline(const AcDbArc &line, AcDbPolyline &pline) { pline.reset(Adesk::kFalse, 0); TADSGePoint3d vtNormal; (AcGeVector3d &)vtNormal = line.normal(); TADSGePoint3d ptCen = Wcs2Ecs(line.center(), vtNormal); TGGeArc ar(ptCen, line.radius(), line.startAngle(), line.endAngle()); pline.setPropertiesFrom(&line); TADSGePoint3d 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 TchPrivate::AsPolyline(const AcDbCircle &line, AcDbPolyline &pline) { TADSGePoint3d vtNormal; (AcGeVector3d &)vtNormal = line.normal(); TADSGePoint3d ptCen = Wcs2Ecs(line.center(), vtNormal); TGGeCircle cir(ptCen, line.radius()); TGGeCurveSegment seg; seg = cir; TGGePoly2D 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 TchPrivate::CompNodeByEqual(const TSortWallOnPt *p1, const void *p2) { if (p1 == p2) { return 0; } return 1; } int TchPrivate::GetPointInArcType(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 TchPrivate::PointProjectToLine(ads_point src_pt, ads_point cl_pt1, ads_point cl_pt2, ads_point dest_pt) { //modify by xlc 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 STPlanePara plan; TVector3D vt; Vector3dFrom2Pt(cl_pt1, cl_pt2, vt); dest_pt[0]=src_pt[0]; dest_pt[1]=src_pt[1]; dest_pt[2]=src_pt[2]; if(GetPlaneEquation(src_pt, vt, &plan)) { LineIntersectWithPlaneA(cl_pt1, cl_pt2, &plan, dest_pt); } return RTNORM; } // 计算点到线的距离 // pt1, pt2 -- 指定线上的两点 // pt0 -- 指定点 // 返回值: 点到线的距离 ads_real TchPrivate::PointDistanceToLine(ads_point pt0, ads_point pt1,ads_point pt2) { //modify by xlc 100613 取消AcGe算法,速度慢 //AcGeLine3d lineT(asPnt3d(pt1),asPnt3d(pt2)); //AcGePointOnCurve3d ptOnCr; //lineT.getClosestPointTo(asPnt3d(pt0),ptOnCr); //return ptOnCr.point3d().distanceTo(asPnt3d(pt0)); ads_point pt4; PointProjectToLine(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 TchPrivate::GetPointOnLineType(ads_point pt, ads_point line_pt1,ads_point line_pt2) { ads_real snap0 = _DIST_SNAP; ads_point vt1, vt2; if (TchPrivate::PointDistanceToLine(pt, line_pt1, line_pt2) > snap0) { return 0; } Vector3dFrom2Pt(pt, line_pt1, vt1); Vector3dFrom2Pt(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 (RealEqual(Vector3dAngleTo(vt1, vt2), 0, _angSnap) ) { return 4; } if (RealEqual(Vector3dAngleTo(vt1, vt2), PI, _angSnap) ) { return 3; } return 0; } double TchPrivate::GetPolygonDist(const TGGePolygonEx &poly1, const TGGePolygonEx &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++) { TADSGePoint3d 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 TchPrivate::IsEqual(const AcGePoint3d pt11,const AcGePoint3d pt12,const AcGePoint3d pt21,const AcGePoint3d pt22,double tol) { if ((TchPrivate::IsEqual(pt11,pt21,tol) && TchPrivate::IsEqual(pt12,pt22,tol)) || (TchPrivate::IsEqual(pt11,pt22,tol) && TchPrivate::IsEqual(pt12,pt21,tol))) { return 1; } else { return 0; } } BOOL TchPrivate::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 TchPrivate::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 TchPrivate::Triangulate(const TDPtrList &lstHole,TDPtrList &lstRes) { THole hole; if (hole.ConstructEdgeList(lstHole)) { return (hole.GetTriangles(lstRes)); } return FALSE; } BOOL TchPrivate::Triangulate(const TDPtrList &lstHole,TDPtrList &lstRes) { THole hole; if (hole.ConstructEdgeList(lstHole)) { return (hole.GetTriangles(lstRes)); } return FALSE; } BOOL TchPrivate::Triangulate(const TGGePoly2D &out,const TDPtrList &lstHole,TDPtrList &lstRes) { THole hole; if (hole.ConstructEdgeList(out,lstHole)) { return hole.GetTriangles(lstRes); } return FALSE; } BOOL TchPrivate::Triangulate(const TGGePolygonEx &out, const TDPtrList &lstHole, TDPtrList &lstRes) { THole hole; if (hole.ConstructEdgeList(out,lstHole)) { return hole.GetTriangles(lstRes); } return FALSE; } BOOL TchPrivate::Triangulate(const TGGePolygonEx &out, const TDPtrList &lstHole, TDPtrList &lstRes) { THole hole; if (hole.ConstructEdgeList(out,lstHole)) { return hole.GetTriangles(lstRes); } return FALSE; } // 区域的减法 // lstPoly2 is inside poly1, but share edges // lstPoly2都是独立的域,不含孔洞模型 int TchPrivate::_Subtract(const TGGePoly2D &poly1, const TDPtrList &lstPoly2, TDPtrList &lstResult) { // 首先, poly1对poly2进行裁剪, 取内部 TDPtrList lstSeg2, lstSeg2In, lstSeg2Out, lstSeg2Edge ; for (int n = 0; n < lstPoly2.Length(); n++) { const TGGePoly2D &poly2 = lstPoly2[n]; ExplodePoly2D(poly2, lstSeg2); } PolyClip(lstSeg2, (TGGePoly2D &)poly1, lstSeg2In, lstSeg2Out, lstSeg2Edge); // 然后, poly2对poly1进行裁剪, 取外部 TDPtrList lstSeg1, lstSeg1In, lstSeg1Out, lstSeg1Edge ; ExplodePoly2D(poly1, lstSeg1); for (n = 0; n < lstPoly2.Length(); n++) { const TGGePoly2D &poly2 = lstPoly2[n]; lstSeg1Out.Reset(); PolyClip(lstSeg1, (TGGePoly2D &)poly2, lstSeg1In, lstSeg1Out, lstSeg1Edge); lstSeg1.Reset(); for (int k = 0; k < lstSeg1Out.Length(); k++) { lstSeg1.Append(new TGGeCurveSegment(*lstSeg1Out[k])); } } //lstSeg2In合并到lstSeg1Out for (int i = 0; i < lstSeg2In.Length(); i++) { lstSeg1Out.Append(new TGGeCurveSegment(*lstSeg2In[i])); } TDPtrList lstTemp(FALSE); int nRet = SearchRegions(lstSeg1Out, lstTemp); for (i = 0; i < lstTemp.Length(); i++) { TGGePoly2D *pTemp = lstTemp[i]; if (pTemp->IsSelfIntersect()) { delete pTemp; } else { lstResult.Append(pTemp); } } return nRet; } // 8.0补丁暂未使用 // 参考ptRef,判断在外轮廓中,应该减去pt1、pt2中的哪个点 TADSGePoint3d TchPrivate::GetAutoDelPt(TADSGePoint3d ptRef, TADSGePoint3d pt1, TADSGePoint3d pt2) { TADSGePoint3d vecXDir, vecYDir; TGGetVar(_T("UCSXDIR"), vecXDir); TGGetVar(_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 TchPrivate::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 (ADS>15) bool TchPrivate::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 TCString TchPrivate::OsMode2Str(int nMode) { TCString 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 TchPrivate::SearchPathFromCurve(const TDPtrList &curves, TGGePoly2D &polyPath) { TSearchRegionFromCurve aSearch; BOOL bInit = TRUE; try { aSearch.InitStart(curves); } catch(...) { bInit = FALSE; } if (!bInit) { return FALSE; } TDPtrList &nodes = TSearchRegionFromCurve::g_lstAllSortSides; TSortSideOnVertex *pHead = NULL; TSortSideOnVertex *pTail = NULL; for (int i = 0; i < nodes.Length(); i++) { TSortSideOnVertex &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); TSortSideOnVertex *pNode = pHead; TGGeRegionSide *pLast = NULL; while (pNode != pTail) { TGGeRegionSide *pSide1 = pNode->Head()->m_pSide; TGGeRegionSide *pSide2 = pNode->Tail()->m_pSide; TGGeRegionSide *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 TchPrivate::FixGsView() { PersistGsView(NULL); } extern Acad::ErrorStatus fromAcDbTextStyle(AcGiTextStyle& style, const AcDbObjectId& AcDbStyleId); TADSGePoint3d TchPrivate::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); TADSGePoint3d ptBox; (AcGePoint2d &)ptBox = ptExt; return ptBox; } void TchPrivate::RemoveDupNoXData() { TPushMemVar vTemp(g_bEchoSearch, TRUE); TDPtrList lstRemoveDup; TPickEntSet ss(SS_FREE); if (ss.Get(NULL, NULL, NULL, TRBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL)) == RTNORM) { long lCount = ss.Length(); for (long i = 0L;im_lstCurves.Append(new TGGeCurveSegment(ent)); } else { pData = new TRemoveDupByLayer(sLayer); pData->m_lstCurves.Append(new TGGeCurveSegment(ent)); lstRemoveDup.Append(pData); } } ss.Erase(); for (int n = 0; nm_sLayer << _T("消除重线: "); int nOldNum = pData->m_lstCurves.Length(); RemoveDupCurves(pData->m_lstCurves); TchGeLib::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 TchPrivate::RemoveExactDupLines(TDPtrList &lstCurves) { //初始化消除重线的集合 int len = lstCurves.Length(); TDPtrList lstNewCurves; for (int i = 0; i < len; i++) { TGGeCurveSegment &seg = *lstCurves[i]; if (seg.GetLength() < _DIST_SNAP) { continue; } lstNewCurves.Append(new TGGeCurveSegSeg(seg)); } len = lstNewCurves.Length(); if (g_bEchoSearch) { TCString sMsg(256); sMsg << _T("对") << len << _T("条线进行消除完全重线"); acedSetStatusBarProgressMeter(sMsg, 0, len); } int nStep = len / 100; if (nStep < 1) { nStep = 1; } for (i = 0; i < len; i++) { if (g_bEchoSearch && !(i % nStep)) { acedSetStatusBarProgressMeterPos(i); } TGGeCurveSegSeg line1 = *lstNewCurves[i]; if (line1.m_bDeleted) { continue; } ASSERT(line1.Is(CURVE_LINE)); for (int j = 0; j < len; j++) { TGGeCurveSegSeg &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 (i = 0; i < len; i++) { TGGeCurveSegSeg &ln = *lstNewCurves[i]; if (!ln.m_bDeleted) { lstCurves.Append(new TGGeCurveSegment(ln)); } } if (g_bEchoSearch) { acedRestoreStatusBar(); } } char* TchPrivate::TGh2cpy(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* TchPrivate::TGh3cpy(char *to, char *fr, int len) { if (!to || !fr) { exit(0); } char *from; for (from = fr; *from == ' '; from++) { ; } return TchPrivate::TGh2cpy(to, from, len); } void TchPrivate::TGh1cpy(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 *TchPrivate::StrDelSpace(const TCHAR *src) { if (!src) { exit(0); } char tmp[256] = ""; TchPrivate::TGh1cpy(tmp, _AS(src)); return tstrnew(TString(tmp)); } int TchPrivate::GetPickFirst(TPickEntSet &gSet, TPickEntSet &pSet) { resbuf *gset = NULL, *pset = NULL; int nRet = ads_ssgetfirst(&gset, &pset); if (gset) { if (gset->restype == RTPICKS) { TPickEntSet ss0(0); ss0 = gset->resval.rlname; gSet += ss0; ss0.Free(); } ads_relrb(gset); } if (pset) { if (pset->restype == RTPICKS) { TPickEntSet ss0(0); ss0 = pset->resval.rlname; pSet += ss0; ss0.Free(); } ads_relrb(pset); } return nRet; } double TchPrivate::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 TchPrivate::ConnectPolygonsNew(TDPtrList &lstPolygons, TGGePolygonEx &polyEx1) { if (!lstPolygons) { return RTERROR; } polyEx1 = *lstPolygons.Head(); lstPolygons.Remove(0); LAB_RESTART: if (!lstPolygons) { return RTNORM; } TGGePolyDist minDist; BOOL bInit = FALSE; int nIndex = 0; for (int i = 0; i < lstPolygons.Length(); i++) { TGGePolyDist 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) { TGGePolygonEx polyEx2; ConnectPolygon(polyEx1, *lstPolygons[nIndex], minDist, polyEx2); polyEx1 = polyEx2; lstPolygons.Remove(nIndex); goto LAB_RESTART; } return RTERROR; } int TchPrivate::ConnectPolygons(TDPtrList &lstPolygons, TGGePolygonEx &polyEx1) { if (!lstPolygons) { return RTERROR; } polyEx1 = *lstPolygons.Head(); lstPolygons.Remove(0); LAB_RESTART: for (int i = 0; i < lstPolygons.Length(); i++) { TGGeLine lnConnector; double nDist = GetConnector(polyEx1, *lstPolygons[i], lnConnector); if (IsGoodConnector(lnConnector, lstPolygons, i)) { TGGePolygonEx polyEx2; ConnectPolygon(polyEx1, *lstPolygons[i], polyEx2); polyEx1 = polyEx2; lstPolygons.Remove(i); goto LAB_RESTART; } } if (lstPolygons.Length()) { #ifndef NDEBUG TchGeLib::adsout << _T("\nCan not find good connector!"); #endif for (i = 0; i < lstPolygons.Length(); i++) { TGGePolygonEx polyEx2; ConnectPolygon(polyEx1, *lstPolygons[i], polyEx2); polyEx1 = polyEx2; } } return RTNORM; } void TchPrivate::RemoveDup() { TDPtrList lstRemoveDup; TPickEntSet ss(SS_FREE); if (ss.Get(NULL, NULL, NULL, TRBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL)) == RTNORM) { long lCount = ss.Length(); for (long i = 0L; i < lCount; i++) { TEntitySet ent = ss[i]; TCString sLayer(256); ent.GetData(8, (TCHAR *)sLayer); TRemoveDupEntByLayer *pData = lstRemoveDup.FindNode((TCHAR *)sLayer, TRemoveDupEntByLayer::CompareForFindByLayer); if (pData) { pData->m_ss += ent; } else { pData = new TRemoveDupEntByLayer(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); TchGeLib::adsout << _T("由") << int(nOldNum) << _T("变为") << (int)pData->m_ss.Length(); } } } // 判断桥接是否合适,即不和任何边有交点(位于边内) BOOL TchPrivate::IsGoodConnector(const TGGeLine &lnConnector, const TGGePolygonEx &rPolygon) { for (int j = 0; j < rPolygon.Length(); j++) { TADSGePoint3d ptInt; TGGeLine 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 TchPrivate::GetConnector(const TGGePolygonEx &poly1, const TGGePolygonEx &poly2, TGGeLine &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++) { TADSGePoint3d 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 TchPrivate::IsGoodConnector(const TGGeLine &lnConnector, const TDPtrList &lstPolygons, int idxExclude) { for (int i = 0; i < lstPolygons.Length(); i++) { if (i == idxExclude) { continue; } const TGGePolygonEx &rPolygon = lstPolygons[i]; if (!TchPrivate::IsGoodConnector(lnConnector, rPolygon)) { return FALSE; } } return TRUE; } ads_real TchPrivate::MinDistance(const TGGeLine &ln1, const TGGeLine &ln2, TADSGePoint3d &ptInt1, TADSGePoint3d &ptInt2) { assert(ln1.m_nFlag == LS_FINITE && ln2.m_nFlag == LS_FINITE); TADSGePoint3d ptInt; if (ln1.Intersection(&ln2, ptInt)) { ptInt1 = ptInt2 = ptInt; return 0.0; } TADSGePoint3d pt1, pt2; // ln1在ln2上的两垂足 ln1.GetStartPoint().Project(&ln2, pt1); ln1.GetEndPoint().Project(&ln2, pt2); int nPrFlag1 = pt1 & ln2; int nPrFlag2 = pt2 & ln2; TADSGePoint3d qt1, qt2; ln2.GetStartPoint().Project(&ln1, qt1); ln2.GetEndPoint().Project(&ln1, qt2); int nQrFlag1 = qt1 & ln1; int nQrFlag2 = qt2 & ln1; TDPtrList lstResult; ads_real pDist1 = (nPrFlag1 != PR_OUTSIDE && nPrFlag1 != PR_EXTEND) ? ads_distance(ln1.GetStartPoint(), pt1) : 0.0; lstResult.Append(new TGGeLineDist(pDist1, ln1.GetStartPoint(), pt1)); ads_real pDist2 = (nPrFlag2 != PR_OUTSIDE && nPrFlag2 != PR_EXTEND) ? ads_distance(ln1.GetEndPoint(), pt2) : 0.0; lstResult.Append(new TGGeLineDist(pDist2, ln1.GetEndPoint(), pt2)); ads_real qDist1 = (nQrFlag1 != PR_OUTSIDE && nQrFlag1 != PR_EXTEND) ? ads_distance(ln2.GetStartPoint(), qt1) : 0.0; lstResult.Append(new TGGeLineDist(qDist1, qt1, ln2.GetStartPoint())); ads_real qDist2 = (nQrFlag2 != PR_OUTSIDE && nQrFlag2 != PR_EXTEND) ? ads_distance(ln2.GetEndPoint(), qt2) : 0.0; lstResult.Append(new TGGeLineDist(qDist2, qt2, ln2.GetEndPoint())); lstResult.Append(new TGGeLineDist(ads_distance(ln1.GetStartPoint(), ln2.GetStartPoint()), ln1.GetStartPoint(), ln2.GetStartPoint())); lstResult.Append(new TGGeLineDist(ads_distance(ln1.GetStartPoint(), ln2.GetEndPoint()), ln1.GetStartPoint(), ln2.GetEndPoint())); lstResult.Append(new TGGeLineDist(ads_distance(ln1.GetEndPoint(), ln2.GetStartPoint()), ln1.GetEndPoint(), ln2.GetStartPoint())); lstResult.Append(new TGGeLineDist(ads_distance(ln1.GetEndPoint(), ln2.GetEndPoint()), ln1.GetEndPoint(), ln2.GetEndPoint())); lstResult.QuickSort(TGGeLineDist::Compare); TGGeLineDist *pp1 = lstResult[0]; ptInt1 = pp1->ptLocation1; ptInt2 = pp1->ptLocation2; return pp1->nDist; } int TchPrivate::MinDistance(TGGeLine &ln1, TGGePolygonEx &poly2, TGGePolyDist &result) { assert(ln1.m_nFlag == LS_FINITE); TDPtrList lstResult; for (int i = 0; i < poly2.Length(); i++) { TGGeLine ln2(LS_FINITE); poly2.NthLine(i, ln2); TADSGePoint3d pt1, pt2; ads_real nDist = TchPrivate::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 TGGePolyDist(nDist, 0, i, pt1, pt2)); } } lstResult.QuickSort(TGGePolyDist::Compare); result = *lstResult[0]; return RTNORM; } int TchPrivate::MinDistance(TGGePolygonEx &poly1, TGGePolygonEx &poly2, TGGePolyDist &result) { TDPtrList lstResult; for (int i = 0; i < poly1.Length(); i++) { TGGeLine ln1(LS_FINITE); poly1.NthLine(i, ln1); TGGePolyDist *pRes = new TGGePolyDist(); if (TchPrivate::MinDistance(ln1, poly2, *pRes) != RTNORM) { result = *pRes; result.nIndex1 = i; delete pRes; return RTERROR; } else { pRes->nIndex1 = i; lstResult.Append(pRes); } } lstResult.QuickSort(TGGePolyDist::Compare); result = *lstResult[0]; return RTNORM; } double TchPrivate::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 TchPrivate::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 TchPrivate::IsParaInSeg(double pa,double prec) { TWPushVar vTemp(g_fZero,prec); return UPEQUAL_ZERO(pa) && DOWNEQUAL_ZERO(pa - 1); } // 通用的函数, 要移到其他模块 Acad::ErrorStatus TchPrivate::ReadCurve(AcDbDwgFiler *pFiler, TGGeCurveSegment &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 TchPrivate::ReadCurveList(AcDbDwgFiler *pFiler, TDPtrList &lstSegs) { Adesk::UInt16 nCount = 0; pFiler->readItem(&nCount); for (Adesk::UInt16 i = 0U; ifilerStatus(); } Acad::ErrorStatus TchPrivate::WriteCurve(AcDbDwgFiler *pFiler, const TGGeCurveSegment &seg) { pFiler->writeItem((const AcGePoint3d &)seg.GetStartPoint()); pFiler->writeItem((const AcGePoint3d &)seg.GetEndPoint()); pFiler->writeItem(seg.GetBulge()); return pFiler->filerStatus(); } Acad::ErrorStatus TchPrivate::WriteCurveList(AcDbDwgFiler *pFiler, const TDPtrList &lstSegs) { Adesk::UInt16 nCount = (Adesk::UInt16)lstSegs.Length();; pFiler->writeItem(nCount); for (Adesk::UInt16 i = 0U; i < nCount; i++) { TchPrivate::WriteCurve(pFiler, lstSegs[(int)i]); } return pFiler->filerStatus(); } // 用两个区域对一曲线进行裁剪, 剩下最长的曲线作为代表 TGGeCurveSegment TchPrivate::GetMaxCurveAfterClip(const TGGeCurveSegment &cvSource, const TGGePoly2D &sPoly, const TGGePoly2D &ePoly) { TGGeCurveSegment cvOffset = cvSource; cvOffset.SetLineFlag(LS_FINITE); TDPtrList lstSource, lstIn, lstOut, lstEdge; lstSource.Append(new TGGeCurveSegment(cvOffset)); for (int nFrom = 0; nFrom < 2; nFrom++) { //起点裁剪和终点裁剪 const TGGePoly2D &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 TGGeCurveSegment(*lstOut[i])); } } } // 取裁剪后最长的边线作为代表(经验解) if (!lstSource) { cvOffset = cvSource; cvOffset.SetEndPoint(cvOffset.GetStartPoint()); } else { TGGeCurveSegment *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; } // 用两个区域对一曲线进行裁剪, 剩下的包含给定的点作为返回 TGGeCurveSegment TchPrivate::GetCurveContainPointAfterClip(TADSGePoint3d ptPick, const TGGeCurveSegment &cvSource, const TGGePoly2D &sPoly, const TGGePoly2D &ePoly) { TGGeCurveSegment cvOffset = cvSource; cvOffset.SetLineFlag(LS_FINITE); TDPtrList lstSource, lstIn, lstOut, lstEdge; lstSource.Append(new TGGeCurveSegment(cvOffset)); for (int nFrom = 0; nFrom < 2; nFrom++) { //起点裁剪和终点裁剪 const TGGePoly2D &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 TGGeCurveSegment(*lstOut[i])); } } } if (!lstSource) { cvOffset = cvSource; cvOffset.SetEndPoint(cvOffset.GetStartPoint()); } else { BOOL bFind = FALSE; for (int i = 0; i < lstSource.Length(); i++) { TGGeCurveSegment &seg = *lstSource[i]; TADSGePoint3d ptPrj; if (seg.ProjectToMe(ptPick, ptPrj) == RTNORM && (ptPrj & seg) == PR_INSIDE) { cvOffset = seg; bFind = TRUE; break; } } if (!bFind) { TGGeCurveSegment *pMax = lstSource[0]; for ( i = 1; i < lstSource.Length(); i++) { if (lstSource[i]->GetLength() > pMax->GetLength()) { pMax = lstSource[i]; } } cvOffset = *pMax; } } cvOffset.SetLineFlag(cvSource.GetLineFlag()); return cvOffset; } int TchPrivate::MakeArcWallSeg(TGGiExplodeDrawBase &dc, const TGGeArc &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; } TGGeArc iArc = arc.Offset(-iDist); TGGeArc oArc = arc.Offset(oDist); TchPrivate::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd); TchPrivate::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd); return RTNORM; } void TchPrivate::MakeArcWallSeg(TGGiExplodeDrawBase &dc, const TGGeArc &iArc, const TGGeArc &oArc, ads_real height, int bShowStart, int bShowEnd) { TchPrivate::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd); TchPrivate::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd); } // 对xBeg开始,以步长nStep共nDivNum步,高度为nHeight,进行镶嵌, // 结果存入lstSectFaces。bHasTop, bHasBot, bHasLeft, bHasRight,外围边的可见性 void TchPrivate::Tessellate(TDPtrList &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; TGGe3DFace *pFace = new TGGe3DFace; 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, TADSGePoint3d(nPrev, 0.0)); pFace->SetVertex(1, TADSGePoint3d(nNext, 0.0)); pFace->SetVertex(2, TADSGePoint3d(nNext, nHeight)); pFace->SetVertex(3, TADSGePoint3d(nPrev, nHeight)); lstSectFaces.Append(pFace); nPrev = nNext; } } // 把平面(含洞口)的模型,化解为三角形 // z坐标全部为0 int TchPrivate::AsTriangleFaces(const TGGePolygonEx &polyOut, const TDPtrList &lstHoles, TDPtrList &lstFaces) { TGGeTrianglePface lstTris; if (TchPrivate::Triangulate(polyOut, lstHoles, lstTris)) { int nFlag = 0; for (int n = 0; n < lstTris.Length(); n++) { TGGeTriangle *triangle = lstTris[n]; ASSERT(triangle); TGGe3DFace *pFace = new TGGe3DFace; 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 TchPrivate::AsTriangleFaces(const TGGePoly2D &polyOut, const TDPtrList &lstHoles, TDPtrList &lstFaces) { TGGePoly poly1; ((TGGePoly2D &)polyOut).MapToPolygon1(poly1, _AS_SYS_UNIT(g_nCirDeviation)); ASSERT(poly1.Length() > 2); TGGePolygonEx polyEx1(poly1); if (polyEx1.PathArea() > 0.0) { polyEx1.Reverse(); } return TchPrivate::AsTriangleFaces(polyEx1, lstHoles, lstFaces); } BOOL TchPrivate::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 TchPrivate::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 TchPrivate::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 TchPrivate::CreateBlock(CEntityList& entLst,CString& blockName,AcDbObjectId& blockId,AcGePoint3d org) { if (!TchPrivate::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) { TAcDbEntityPtr* pEnt = entLst.GetNext(pos); pBlockTableRecord->appendAcDbEntity(pEnt->m_pAcDbEnt); pEnt->m_pAcDbEnt->close(); } pBlockTableRecord->close(); return 1; } AcDbObjectId TchPrivate::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 TchPrivate::ReleaseC3DFaceList(TAcDbFacePtrList& c3dfaceLst) { POSITION pos = c3dfaceLst.GetHeadPosition(); while (pos != NULL) { TAcDbFacePtr* pC3DFace = c3dfaceLst.GetNext(pos); delete pC3DFace; } c3dfaceLst.RemoveAll(); } void TchPrivate::ReleaseCEntityList(CEntityList& centityLst) { POSITION pos = centityLst.GetHeadPosition(); while (pos != NULL) { TAcDbEntityPtr* pEnt = centityLst.GetNext(pos); delete pEnt; } centityLst.RemoveAll(); } void TchPrivate::SetLayerOfEntities(CEntityList& entLst,CString layerName, int colorNum) { SetLayer(layerName, colorNum); POSITION pos = entLst.GetHeadPosition(); while (pos != NULL) { TAcDbEntityPtr* pEnt = entLst.GetNext(pos); pEnt->m_pAcDbEnt->setLayer(layerName); pEnt->m_pAcDbEnt->setColorIndex(256); } } BOOL TchPrivate::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 TchPrivate::SetLayer(CString layerName, int colorNum) { layerName.TrimLeft(); layerName.TrimRight(); if (layerName == _T("")) { layerName = _T("0"); } if (TchPrivate::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 TchPrivate::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 TchPrivate::C3DFaceList2EntityList(TAcDbFacePtrList& c3dFaceLst,CEntityList& entLst) { POSITION pos = c3dFaceLst.GetTailPosition(); while (pos != NULL) { TAcDbFacePtr* pNode = c3dFaceLst.GetPrev(pos); TAcDbEntityPtr* pCEnt = new TAcDbEntityPtr(pNode->m_p3DFace); entLst.AddTail(pCEnt); } } BOOL TchPrivate::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 TchPrivate::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 TchPrivate::WCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer) { ads_point ads_pt1,ads_ret; TchPrivate::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); TchPrivate::Ads2ARXPt(ads_ret,pt); } void TchPrivate::UCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer) { ads_point ads_pt1,ads_ret; TchPrivate::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); TchPrivate::Ads2ARXPt(ads_ret,pt); } void TchPrivate::UCS2WCS(AcGePoint3d& pt,BOOL bVer) { ads_point ads_pt1,ads_ret; TchPrivate::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); TchPrivate::Ads2ARXPt(ads_ret,pt); } void TchPrivate::WCS2UCS(AcGePoint3d& pt,BOOL bVer) { ads_point ads_pt1,ads_ret; TchPrivate::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); TchPrivate::Ads2ARXPt(ads_ret,pt); } void TchPrivate::ECS2UCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer) { ads_point ads_pt1,ads_ret; TchPrivate::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); TchPrivate::Ads2ARXPt(ads_ret,pt); } void TchPrivate::ECS2WCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer) { ads_point ads_pt1,ads_ret; TchPrivate::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); TchPrivate::Ads2ARXPt(ads_ret,pt); } BOOL TchPrivate::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 TchPrivate::IsEqualSign(double x1,double x2) { if (x1 > fTOL && x2 > fTOL) { return 1; } if (x1 < fTOL && x2 < fTOL) { return 1; } return 0; } int TchPrivate::TXdataExtract(struct resbuf **rb, int *num) { if ((*rb) && ((*rb)->restype == 1070)) { *num = (*rb)->resval.rint; (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int TchPrivate::TXdataExtract(struct resbuf **rb, ads_real *num) { if ((*rb) && ((*rb)->restype == 1040)) { *num = (*rb)->resval.rreal; (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int TchPrivate::TXdataExtractPt(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 TchPrivate::TXdataExtract(struct resbuf **rb, TCHAR *str) { if ((*rb) && ((*rb)->restype == 1000)) { _tcscpy(str, (*rb)->resval.rstring); (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int TchPrivate::TXdataExtractHandle(struct resbuf **rb, TCHAR *str) { if ((*rb) && ((*rb)->restype == 1005)) { _tcscpy(str, (*rb)->resval.rstring); (*rb) = (*rb)->rbnext; return(1); } else { return(0); } } int TchPrivate::TXdataHandleAssocSingle(ads_name ent, int tag, ads_name assoc_ent) { struct resbuf *entdata, *xdata, *tmprb, *rb; GetAppXdata(ent, NULL, &entdata, &xdata); if ((entdata == NULL) || (xdata == NULL)) { ads_relrb(entdata); return(0); } if ((rb = GetXdataTagItem(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 TchPrivate::SetXdataTagItem(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 = GetXdataTagItem(*xdata, tag, &pretag_ptr)) == NULL) { if (!tag_xdata) { return; } rb = ads_newrb(1070); rb->resval.rint = tag; Add2Rblist(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 *TchPrivate::GetXdataTagItem(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 * TchPrivate::DetachXdataTagItem( struct resbuf *xdata, int tag) { struct resbuf *tmpxd, *tagptr, *pretag_ptr, *lagptr, *old_xdata; int nested_list; if ((tagptr = TchPrivate::GetXdataTagItem(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 TchPrivate::DeleteXdataTagItem(struct resbuf * xdata, int tag) { struct resbuf *tmp; tmp = TchPrivate::DetachXdataTagItem(xdata, tag); if (tmp) { ads_relrb(tmp); return(1); } else { return(0); } } void TchPrivate::AddXdataTagBraces(struct resbuf **tagdata) { struct resbuf *n; n = ads_newrb(1002); n->resval.rstring = _tcsdup(_T("{")); Add2Rblist(tagdata, n, TRUE); n = ads_newrb(1002); n->resval.rstring = _tcsdup(_T("}")); Add2Rblist(tagdata, n, FALSE); } int TchPrivate::GetAppXdata(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 TchPrivate::NewStringResbuf(struct resbuf *ebuf, const TCHAR * str,int code) { struct resbuf *rb; if ((rb = GetResbufAtCode(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 TchPrivate::ModifyXPoly2D(TGGePoly2D& poly,TGGeCurveSegment seg) { if (poly.Length() < 2) { return; } TGGeCurveSegment cv; poly.Nth(0,cv); *poly.Head() = seg.GetStartPoint(); if (cv.Is(CURVE_ARC)) { TGGeArc arc; arc = cv.GetArc(); TVector3D 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)) { TGGeArc arc; arc = cv.GetArc(); TVector3D vt = seg.GetEndPoint() - arc.GetCenterPt(); arc.SetEndAngle(vt.AsAcGeVector2d().angle()); poly.SetBulge(poly.Length() - 2, arc.Bulge()); } } void TchPrivate::ModifyXPoly2DStart(TGGePoly2D& poly,TGGeCurveSegment seg) { if (poly.Length() < 2) { return; } TGGeCurveSegment cv; poly.Nth(0,cv); *poly.Head() = seg.GetStartPoint(); if (cv.Is(CURVE_ARC)) { TGGeArc arc; arc = cv.GetArc(); TVector3D vt = seg.GetStartPoint() - arc.GetCenterPt(); arc.SetStarAngle(vt.AsAcGeVector2d().angle()); poly.SetBulge(0, arc.Bulge()); } } void TchPrivate::ModifyXPoly2DEnd(TGGePoly2D& poly,TGGeCurveSegment seg) { if (poly.Length() < 2) { return; } TGGeCurveSegment cv; poly.Nth(poly.TotalSegments() - 1,cv); *poly.Tail() = seg.GetEndPoint(); if (cv.Is(CURVE_ARC)) { TGGeArc arc; arc = cv.GetArc(); TVector3D vt = seg.GetEndPoint() - arc.GetCenterPt(); arc.SetEndAngle(vt.AsAcGeVector2d().angle()); poly.SetBulge(poly.Length() - 2, arc.Bulge()); } } void TchPrivate::StringToList(const TCHAR *s, TCStringList &res, TCHAR cSep) { const TCHAR *pBeg = s; const TCHAR *pEnd = NULL; do { pEnd = _tcschr(pBeg, cSep); TCString sTemp(1024); StrCpy(sTemp, pBeg, pEnd); res.Append(tstrnew(sTemp)); if (pEnd) { pBeg = pEnd + 1; } } while(pEnd != NULL); } int TchPrivate::MergeCurve(TGGeCurveSegment &curve, TGGeCurveSegment &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 (IsSameDrt(curve.TGGeLine::Direction(), seg.TGGeLine::Direction(), _angSnap)) { curve.SetEndPoint(seg.GetEndPoint()); bMerged = 1; } } else { TGGeArc arc1 = curve.GetArc(); TGGeArc 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 TchPrivate::CircleToPoly(const TGGeCircle &cir, TGGePoly &poly, int nDiv) { double nAng = PI * 2.0 / nDiv; poly.Reset(); for (int i = 0; i < nDiv; i++) { TADSGePoint3d ptVertex; ads_polar(cir.GetCenterPt(), i * nAng, cir.GetRadius(), ptVertex); poly.Append(new TADSGePoint3d(ptVertex)); } } AcDbObject* TchPrivate::GetDbConfigObjFromDict(AcDbDictionary *pXDict, AcDb::OpenMode mode) { Acad::ErrorStatus es=Acad::eOk; AcDbObjectId idExist; AcDbObject *pIObj = NULL; es = pXDict->getAt(_T("ATS_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("ATS_DBCONFIG"), pIObj, id); ASSERT(es == Acad::eOk); } pXDict->downgradeOpen(); } } return pIObj; } AcDbObject * TchPrivate::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 = TchPrivate::GetDbConfigObjFromDict(pNamedObj, opMode); pNamedObj->close(); } return pInitSet; } //modify by xlc on 100310 从tch_kernal工程移入 AcDbObjectId TchPrivate::InitDynTextStyle() { AcDbObjectId idRet=GetTextStyleId(_T("_TCH_DYN")); if(!idRet) { AcDbTextStyleTableRecord *pStyle=new AcDbTextStyleTableRecord; pStyle->setName(_T("_TCH_DYN")); #if ADS < 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; } TConfigBase* g_pGlobalConfigBase = NULL; TConfigBase* TchPrivate::GetGlobalConfigBase() { return NULL; if (g_pGlobalConfigBase == NULL) { AcDbObject* pObj = TchPrivate::GetDwgGlobalObj(AcDb::kForRead,g_pCurrentDb); if (pObj != NULL) { g_pGlobalConfigBase = (TConfigBase*)pObj->xData(_T("TDbConfig")); pObj->close(); } } return g_pGlobalConfigBase; } BOOL DocGetCurMeterUnitDraw() { BOOL bMeterUnitDraw = FALSE; TConfigBase* pBase = GetGlobalConfigBase(); if (pBase != NULL) { bMeterUnitDraw = pBase->DocGetMeterUnitDraw(); } return bMeterUnitDraw; }