//*****************************源程序修改情况记录***************************** // 修 改 人: 成志峰 // 修改时间: 1999/7/27 07:49:15 PM // 修改内容: 修改了function ExtendAWall() and function ExtendAndFix(),provide better ability. //**************************************************************************** #include "stdafx.h" #include "resource.h" #include "dbxutil.h" #include "actrans.h" static const TCHAR *sMsgPrompt[] = { #include "walledit.hpp" }; // extern GEOAPI int XGetCorner(const XPoint &ptCorn1, const TCHAR *pszMsg, XPoint &ptCorn2); //修墙角 static void FixTwoWall(TDbWall *&pWall1,TDbWall *&pWall2,ads_real precision); static int CanFix(XCurveSegment &seg1,XCurveSegment &seg2,XPoint pt,BOOL flag,ads_real precision); static void ExtendAndFix(XCurveSegment &seg1,XCurveSegment &seg2,TDbWall *&pWall1,TDbWall *&pWall2,XPoint ptInt,int result,AcDbObjectId &newId1,AcDbObjectId &newId2); static void ExtendAWall(XCurveSegment &seg,TDbWall *&pWall,XPoint ptInt); static BOOL ElongateAWall(XCurveSegment &seg,TDbWall *&pWall,XPoint ptInt); //static BOOL EraseObj(AcDbObjectId &rId); static void FixAllWall(PickSet &ssWalls,ads_real precision); static int GetIntPoint(DList &lstWalls,XPoint &pointInt1,XPoint &pointInt2); static void ExtendAndFix(DList &lstWall,XPoint ptInt); //倒墙角 void FilletWall(); static BOOL InputFilletWall(TDbWall *&pWalla,TDbWall *&pWallb,ads_real &filletrad,XPoint &pt1,XPoint &pt2); static int CanFillet(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pt2,ads_real &filletrad); static BOOL FilletSameEntitys(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2); //BOOL GetTempLayerId(AcDbObjectId &LayerId); //AcDbObjectId createLine(AcGePoint3d startPt,AcGePoint3d endPt,AcDbObjectId &layerId); //static AcDbObjectId createArc(TDbWall *&pWall,AcDbObjectId &layerId); Adesk::Boolean appendToDb(AcDbEntity* pEntity,AcDbObjectId& rId); //BOOL SetLayerOff(AcDbObjectId layerId,BOOL flag); //static BOOL GetEndPoint(AcDbObjectId rId,XPoint &startPt,XPoint &endPt); static int GetInterPoint(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pi); //墙齐柱边 void AlignWall(); void ChamferWall(); BOOL InputChamferWall(TDbWall *&pWalla,TDbWall *&pWallb,ads_real &chamferDistA,ads_real &chamferDistB,XPoint &pt1,XPoint &pt2); BOOL ChamferSameEntitys(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2); BOOL ChamferSameEntitys1(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2); int CanChamfer(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pt2,ads_real &chamferDistA,ads_real &chamferDistB); class XSelectSameWalls { public: DList m_lstWallsId;//返回的相关墙体ID链表 TDbWall *m_pWall;//选取的墙壁 XPoint m_ptPick;//选取点 BOOL m_flag; //当flag=TRUE,墙体指针是自己打开的,必须关闭、释放; XPoint m_deviation; protected: int AppendWall(const Entity &e, int bMinusDrt, XPoint &ptNext); public: XSelectSameWalls() { m_pWall=NULL; m_flag=FALSE; }; ~XSelectSameWalls() { if (m_flag && m_pWall) m_pWall->close(); }; void Close() { if (m_flag && m_pWall) m_pWall->close(); }; BOOL INIT(ads_name ent,ads_point pt); BOOL INIT(AcDbObjectId &rId,ads_point pt); BOOL INIT(TDbWall *&pWall,ads_point pt); int GetWalls();//得到墙壁列表 XPoint GetDeviation(); // 设置宽度 void SetWidth(ads_real nLeftWidth, ads_real nRightWidth); void GetCorners(XPointList &lstCorners); // 获得曲线段 XCurveSegment GetCurveSegment() const; }; XPoint XSelectSameWalls::GetDeviation() { XPoint pt; ads_real size,per; xg_getvar(_T("VIEWSIZE"),&size); xg_getvar(_T("SCREENSIZE"),pt); per=size/pt.y; return XPoint(per*20,per*20);//20个像素点 } BOOL XSelectSameWalls::INIT(AcDbObjectId &rId,ads_point pt) { AcDbObject *pObj=NULL; if (acdbOpenObject(pObj,rId,AcDb::kForRead) != Acad::eOk || !pObj) return FALSE; TDbWall *pWall=NULL; if ((pWall=TDbWall::cast(pObj)) == NULL) { pObj->close(); return FALSE; } if (pWall->Is(CURVE_LINE) || pWall->Is(CURVE_ARC)) { m_ptPick=pt; m_pWall=pWall; m_flag=TRUE; m_deviation=GetDeviation(); return TRUE; } ASSERT(0); return FALSE; } BOOL XSelectSameWalls::INIT(ads_name ent,ads_point pt) { AcDbObjectId rId; if (acdbGetObjectId(rId,ent) != Acad::eOk) return FALSE; return INIT(rId,pt); } BOOL XSelectSameWalls::INIT(TDbWall *&pWall,ads_point pt) { if (pWall->Is(CURVE_LINE) || pWall->Is(CURVE_ARC)) { m_ptPick=pt; m_pWall=pWall; m_deviation=GetDeviation(); return TRUE; } return FALSE; } // 得到墙壁列表并排序,圆墙不包括在内 int XSelectSameWalls::GetWalls() { AcDbObjectId rId; rId=m_pWall->objectId(); m_lstWallsId.Append(new AcDbObjectId(rId)); for (int nDrt=0; nDrt<2; nDrt++) //两个方向 { XPoint ptCorner=nDrt? m_pWall->StartPoint():m_pWall->EndPoint(); //AssureOnScreen(ptCorner, ptCorner); XPoint ptLow=ptCorner-m_deviation, ptUp=ptCorner+m_deviation; PickSet ssWallOnCorner(SS_FREE); if (GetSafeSelection(ssWallOnCorner, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) == Acad::eOk) { long ssLen=ssWallOnCorner.Length(); for (long i=0L; iobjectId()) continue; if (AppendWall(ent, nDrt, ptCorner) == RTNORM) break; } } } return RTNORM; } //递归 int XSelectSameWalls::AppendWall(const Entity &ee, int bMinusDrt, XPoint &ptNext) { if (m_lstWallsId.Length()>150) return RTERROR;//堆栈深度最大50 Entity e=ee; int bLine=m_pWall->Is(CURVE_LINE); XLine ln,ln1; XArc arc,arc1; if (bLine) ln=m_pWall->GetLine(); else arc=m_pWall->GetArc(); TDbWall *pWall=NULL; XDbObject obj(e,AcDb::kForRead); if ((pWall=TDbWall::cast(obj.m_pObject)) == NULL || pWall->Is(CURVE_CIRCLE) || pWall->Is(CURVE_LINE) != bLine) return RTERROR;//如果不是墙、是圆墙、或墙的类型不一致,退出; if (bLine) { ln1=pWall->GetLine(); if (!CT_IsSameDrt(ln.Direction(), ln1.Direction(), _angSnap)) return RTERROR; } else { arc1=pWall->GetArc(); if (fabs(arc1.GetRadius()-arc.GetRadius())>_DIST_SNAP && arc1.GetCenterPt() != arc.GetCenterPt()) return RTERROR; } XCurveSegment seg=*pWall; int nPrFlag=(ptNext & seg); if (nPrFlag != PR_ONPT1 && nPrFlag != PR_ONPT2) return RTERROR; int bOk=0; if (!bLine) { if (fabs(m_pWall->GetWidth(0)-pWall->GetWidth(0))<1.0E-5 && fabs(m_pWall->GetWidth(1)-pWall->GetWidth(1))<1.0E-5) bOk=1; } else { if (CT_IsExactSameDrt(ln.Direction(), ln1.Direction(),_angSnap) && fabs(m_pWall->GetWidth(0)-pWall->GetWidth(0))<1.0E-5 && fabs(m_pWall->GetWidth(1)-pWall->GetWidth(1))<1.0E-5) bOk=1; else if (fabs(m_pWall->GetWidth(0)-pWall->GetWidth(0))<1.0E-5 && fabs(m_pWall->GetWidth(1)-pWall->GetWidth(1))<1.0E-5) bOk=1; } if (bOk) { ptNext = nPrFlag == PR_ONPT1? pWall->EndPoint():pWall->StartPoint(); if (!bMinusDrt) m_lstWallsId.Append(new AcDbObjectId(pWall->objectId())); else { m_lstWallsId[0]; m_lstWallsId.Insert(new AcDbObjectId(pWall->objectId())); } //AssureOnScreen(ptNext, ptNext);//取下一段 XPoint ptLow=ptNext-m_deviation, ptUp=ptNext+m_deviation; PickSet ssWallOnCorner(SS_FREE); if (GetSafeSelection(ssWallOnCorner, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) == Acad::eOk) { long ssLen=ssWallOnCorner.Length(); for (long i=0L; iIs(CURVE_LINE); AcDbObjectId rId; TDbWall *pWall; for (int i=0; iXLine::Direction(), m_pWall->XLine::Direction(), _angSnap)) { pWall->SetWidth(0,nLeftWidth); pWall->SetWidth(1,nRightWidth); } else { pWall->SetWidth(0,nRightWidth); pWall->SetWidth(1,nLeftWidth); } } else { pWall->SetWidth(0,nLeftWidth); pWall->SetWidth(1,nRightWidth); } pWall->close(); } } void XSelectSameWalls::GetCorners(XPointList &lstCorners) { AcDbObjectId rId; TDbWall *pWall; for (int i=0; iStartPoint()); lstCorners.NewAppend(pWall->EndPoint()); pWall->close(); } } XCurveSegment XSelectSameWalls::GetCurveSegment() const { AcDbObjectId rId,rId1; TDbWall *pHead=NULL,*pTail=NULL; rId=*m_lstWallsId.Head(); rId1=*m_lstWallsId.Tail(); acdbOpenObject((AcDbObject *&)pHead,rId,AcDb::kForRead); acdbOpenObject((AcDbObject *&)pTail,rId1,AcDb::kForRead); ASSERT(pHead && pTail && m_pWall); XCurveSegment curve=*m_pWall; assert(!curve.Is(CURVE_CIRCLE)); if (curve.Is(CURVE_ARC)) { XArc arc=curve.GetArc(); if (pHead->objectId() != m_pWall->objectId()) // change startpoint of curve { // [2010-3-16 10:15 wubo] 移植到新Geo库 // arc.startAngle = pHead->GetArc().startAngle; arc.SetStarAngle(pHead->GetArc().GetStarAngle()); } if (pTail->objectId() != m_pWall->objectId()) // change EndPoint() of curve { // [2010-3-16 10:16 wubo] 移植到新Geo库 // arc.endAngle = pTail->GetArc().endAngle; arc.SetEndAngle(pTail->GetArc().GetEndAngle()); } curve = arc; } else if (curve.Is(CURVE_LINE)) { if (pHead->objectId() != m_pWall->objectId()) curve.StartPoint() = CT_IsExactSameDrt(pHead->XLine::Direction(), curve.XLine::Direction(), _angSnap) ? pHead->StartPoint() : pHead->EndPoint(); if (pTail->objectId() != m_pWall->objectId()) curve.EndPoint() =CT_IsExactSameDrt(pTail->XLine::Direction(), curve.XLine::Direction(), _angSnap) ? pTail->EndPoint() : pTail->StartPoint(); } pHead->close(); pTail->close(); return curve; } int CompareWallObjectId(const AcDbObjectId *id1, const void *id2) { if (*id1 == *(const AcDbObjectId *)id2) return 0; return 1; } void AlignWall() { XPoint ptPick,ptPick1; if (XGetPoint(NULL, _T("\n请点取墙边应通过的点"), ptPick) != RTNORM) return; ptPick=Ucs2Wcs(ptPick); Entity entWall,entWall1; RBList maskWall(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL); DList lstWalls,lstExclude; AcDbObjectId rId; { //限制XSelectSameWalls的作用域,因为它打开了一个实体 XSelectSameWalls Walls; do { if (ads_entsel(_T("\n请点取一段墙<退出>:"),entWall,ptPick1) != RTNORM) return; ptPick1=Ucs2Wcs(ptPick1); if (Walls.INIT (entWall,ptPick1) != TRUE) { ads_printf(sMsgPrompt[2]); continue; } XPoint pt; XDbObject obj(entWall,AcDb::kForRead); TDbWall *pWall=TDbWall::cast(obj.m_pObject); if (pWall == NULL) { ads_printf(sMsgPrompt[2]); continue; } pWall->ProjectToMe(ptPick,pt); if (ads_distance(ptPick,pt)>(pWall->GetWidth(0)+pWall->GetWidth(1)))//if dist > width of wall { if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[31],sMsgPrompt[25],MB_YESNO) != IDYES) { //add by whl on 051224 lstExclude.Append(new AcDbObjectId(pWall->objectId())); Walls.Close(); continue; } } break; }while(1); if (Walls.GetWalls() != RTNORM) { OPENOBJ_BEGIN(entWall, AcDb::kForWrite, TDbWall, pWall); if (pWall) pWall->AlignTo(ptPick1, ptPick); OPENOBJ_END(); return; } for (int i=0;iAlignTo(ptPick1, ptPick); OPENOBJ_END(); } } } class TWallTree:public WFlag { public: static AcDbObjectIdArray s_idWallArray; public: AcDbObjectId m_idWall; int m_nType;//0,起点与上层相连,1,终点与上层相连,根要区别 XPoint m_ptNew; TWallTree *m_pParent; PDList m_lstStartWallTree;//起点外的所有子树 PDList m_lstEndWallTree;//终点处的所有子树 public: TWallTree(TWallTree*pParent):m_pParent(pParent) {}; TWallTree(AcDbObjectId id); void MoveBase(XPoint ptNewBase); void ClearColor() { TDbWall*pWall=NULL; acdbOpenObject(pWall,m_idWall,AcDb::kForWrite); if (pWall != NULL) { pWall->setColorIndex(256); pWall->close(); for (m_lstStartWallTree.MoveToFirst();!m_lstStartWallTree.IsOut();m_lstStartWallTree.MoveToNext()) m_lstStartWallTree.GetCurData()->ClearColor(); for (m_lstEndWallTree.MoveToFirst();!m_lstEndWallTree.IsOut();m_lstEndWallTree.MoveToNext()) m_lstEndWallTree.GetCurData()->ClearColor(); } } void TWallTree::GetEndTree(Table &lstTree); bool IsConnect(TWallTree* pWallTree)const; bool GetNewPoint(XPoint&ptNew);//上层提供的新连接点 bool operator >(const TWallTree&)const { return false; }//ok bool operator <(const TWallTree&)const { return false; }//ok }; bool TWallTree::GetNewPoint(XPoint &ptNew) { if (m_pParent != NULL) { bool bStart=m_pParent->m_lstStartWallTree.Find(this) != NOT_FOUND; TDbWall*pWall=NULL; acdbOpenObject(pWall,m_pParent->m_idWall,AcDb::kForRead); if (pWall != NULL) { ptNew=bStart?pWall->StartPoint():pWall->EndPoint(); pWall->close(); return true; } } return false; } bool TWallTree::IsConnect(TWallTree*pWallTree)const { DList lstStyle; TDbWall* pWall=NULL; acdbOpenObject(pWall,m_idWall,AcDb::kForRead); if (pWall != NULL) { pWall->GetIdStyles(1-m_nType,lstStyle); pWall->close(); for (long i=0;im_idWall == lstStyle[i]->id) return true; } return false; } AcDbObjectIdArray TWallTree::s_idWallArray; TWallTree::TWallTree(AcDbObjectId id):m_nType(-1),m_pParent(NULL) { ListQuene quene; quene.EnQuene(this); m_idWall=id; s_idWallArray.append(id); TWallTree *pWallTree; while (quene.DeQuene(pWallTree)) { TDbWall* pWall=NULL; acdbOpenObject(pWall,pWallTree->m_idWall,AcDb::kForRead); if (pWall != NULL) { DList lstStyleStart,lstStyleEnd; pWall->GetIdStyles(0,lstStyleStart); for (long i=0;iid)) { TDbWall* pWall1=NULL; acdbOpenObject(pWall1,lstStyleStart[i]->id,AcDb::kForRead); if (pWall1 != NULL) { s_idWallArray.append(lstStyleStart[i]->id); TWallTree *pNewChild=new TWallTree(pWallTree); if (pWall1->StartPoint().Distance2d(pWall->StartPoint())EndPoint().Distance2d(pWall->StartPoint())) pNewChild->m_nType=0; else pNewChild->m_nType=1; pNewChild->m_idWall=lstStyleStart[i]->id; pWallTree->m_lstStartWallTree<close(); } } pWall->GetIdStyles(1,lstStyleEnd); for (i=0;iid)) { TDbWall* pWall1=NULL; acdbOpenObject(pWall1,lstStyleEnd[i]->id,AcDb::kForRead); if (pWall1 != NULL) { s_idWallArray.append(lstStyleEnd[i]->id); TWallTree *pNewChild=new TWallTree(pWallTree); if (pWall1->StartPoint().Distance2d(pWall->EndPoint())EndPoint().Distance2d(pWall->EndPoint())) pNewChild->m_nType=0; else pNewChild->m_nType=1; pNewChild->m_idWall=lstStyleEnd[i]->id; pWallTree->m_lstEndWallTree<close(); } } pWall->close(); } } #if ADS>16 s_idWallArray.removeAll(); #else while (!s_idWallArray.isEmpty()) s_idWallArray.removeLast(); #endif } bool operator >(const XPoint&,const XPoint&) { return false; } bool operator <(const XPoint&,const XPoint&) { return false; } void TWallTree::MoveBase(XPoint ptNewBase) { ListQuene quene; List lstOk; List lstUnconnected;//旧待连接墙,新待连接墙 quene.EnQuene(this); TWallTree*pWallTree; while (quene.DeQuene(pWallTree)) { pWallTree->GetNewPoint(ptNewBase); TDbWall*pWall=NULL; acdbOpenObject(pWall,pWallTree->m_idWall,AcDb::kForWrite); if (pWall != NULL) { XCurveSegment cvOld=*pWall; ptNewBase.z=pWall->GetElevation(); double nOffset=pWall->GetDist2Me(ptNewBase); XCurveSegment segBase=pWall->XCurveSegment::Offset(nOffset, LS_FINITE); pWall->assertWriteEnabled(); *(XCurveSegment*)pWall = segBase; pWall->SetWidth(0, pWall->GetWidth(0)+nOffset); pWall->SetWidth(1, pWall->GetWidth(1)-nOffset); if (pWallTree->m_nType == 0) pWall->StartPoint()=ptNewBase; else if (pWallTree->m_nType == 1) pWall->EndPoint()=ptNewBase; else { if (cvOld.StartPoint().Distance2d(ptNewBase)m_nType=0; pWall->StartPoint()=ptNewBase; } else { pWallTree->m_nType=1; pWall->EndPoint()=ptNewBase; } } for (pWallTree->m_lstStartWallTree.MoveToFirst();!pWallTree->m_lstStartWallTree.IsOut();pWallTree->m_lstStartWallTree.MoveToNext()) { TWallTree* pChild=pWallTree->m_lstStartWallTree.GetCurData(); quene.EnQuene(pChild); } for (pWallTree->m_lstEndWallTree.MoveToFirst();!pWallTree->m_lstEndWallTree.IsOut();pWallTree->m_lstEndWallTree.MoveToNext()) { TWallTree* pChild=pWallTree->m_lstEndWallTree.GetCurData(); quene.EnQuene(pChild); } BOOL bEnd=pWall->IsTermAt(1-pWallTree->m_nType); pWall->close(); lstUnconnected.FindAndDel(pWallTree->m_pParent); if (pWallTree->m_pParent != NULL) lstOk<m_pParent; if (!bEnd) { bool bOk=false; for (long i=0;iIsConnect(pWallTree1)&&pWallTree1->IsConnect(pWallTree)) { TDbWall*pWall=NULL; acdbOpenObject(pWall,pWallTree->m_idWall,AcDb::kForWrite); if (pWall != NULL) { TDbWall* pWall1=NULL; acdbOpenObject(pWall1,pWallTree1->m_idWall,AcDb::kForWrite); if (pWall1 != NULL) { pWall->assertWriteEnabled(); XCurveSegment cv1=*pWall; XCurveSegment cv2=*pWall1; cv1.SetLineFlag(LS_INFINITE); cv2.SetLineFlag(LS_INFINITE); XPoint pt1,pt2; int nRet=cv1.Intersection(cv2,pt1,pt2); if (nRet>0) { if ((1-pWallTree->m_nType) == 0) pWall->StartPoint()=pt1; else pWall->EndPoint()=pt1; if ((1-pWallTree1->m_nType) == 0) pWall1->StartPoint()=pt1; else pWall1->EndPoint()=pt1; } pWall1->close(); } pWall->close(); } lstUnconnected.Del(i); lstOk<m_idWall,AcDb::kForWrite); // if (pWall != NULL) // { // pWall->setColorIndex(2); // pWall->close(); // } // } // // for (long i=0;im_idWall,AcDb::kForWrite); // if (pWall != NULL) // { // pWall->setColorIndex(3); // pWall->close(); // } // } // acedGetPoint(NULL,_T("\n确定继续:"),XPoint()); // } //#endif } } // add by wlw on 150327 修墙角2增强版修墙角使用 int IsIntersect(AcDbObjectId id1,AcDbObjectId id2) { OPENOBJ_BEGIN(id1, AcDb::kForRead, TDbWall, pwall1) if (pwall1 == NULL) { return 0; } OPENOBJ_BEGIN(id2, AcDb::kForRead, TDbWall, pwall2) if (pwall2 == NULL) { return 0; } if (pwall1->StartPoint().Distance2d(pwall2->StartPoint()) < _AS_SYS_UNIT(g_nDistPrec) || pwall1->StartPoint().Distance2d(pwall2->EndPoint()) < _AS_SYS_UNIT(g_nDistPrec)) { return 1;//startpt } if (pwall1->EndPoint().Distance2d(pwall2->StartPoint()) < _AS_SYS_UNIT(g_nDistPrec) || pwall1->EndPoint().Distance2d(pwall2->EndPoint()) < _AS_SYS_UNIT(g_nDistPrec)) { return 2;//Endpt } OPENOBJ_END() OPENOBJ_END() return 0; } //add by wlw on 150327修墙角2增强版修墙角使用 int GetIntersectPt(AcDbObjectId id1,AcDbObjectId id2, TADSGePoint3d& ptInter) { AcGePoint3dArray points; OPENOBJ_BEGIN(id1, AcDb::kForRead, TDbWall, pwall1) if (pwall1 == NULL) { return 0; } OPENOBJ_BEGIN(id2, AcDb::kForRead, TDbWall, pwall2) if (pwall2 == NULL) { return 0; } AcDbLine ln1,ln2; ln1.setStartPoint(AcGePoint3d(pwall1->StartPoint().x, pwall1->StartPoint().y,0.0)); ln1.setEndPoint(AcGePoint3d(pwall1->EndPoint().x, pwall1->EndPoint().y,0.0)); ln2.setStartPoint(AcGePoint3d(pwall2->StartPoint().x, pwall2->StartPoint().y,0.0)); ln2.setEndPoint(AcGePoint3d(pwall2->EndPoint().x, pwall2->EndPoint().y,0.0)); ln1.intersectWith(&ln2,AcDb::kExtendBoth,points); if (points.length() > 0) { ptInter = points[0]; AcGePoint3d ptinter1,ptinter2; ln1.getClosestPointTo(ptInter.AsAcGePoint3d(), ptinter1); ln2.getClosestPointTo(ptInter.AsAcGePoint3d(), ptinter2); if (ptInter.Distance2d(ptinter1) > ptInter.Distance2d(ptinter2)) { return 1; } else { return 2; } } OPENOBJ_END() OPENOBJ_END() return 0; } ////////////////////////////// // add by wlw on 150327 修墙角2增强版修墙角使用 void GoEntFromInPts(AcDbObjectId idwall) { double dw = 100.0; TGGeCurveSegment cvCenter; OPENOBJ_BEGIN(idwall, AcDb::kForRead, TDbWall, pwall) if (pwall == NULL) { return; } cvCenter = pwall->OffsetGeomCenter(LS_FINITE); // 得到墙的中心线 dw = pwall->GetWidth(4); OPENOBJ_END() TADSGePoint3d pt; for (int n = 0; n < 2; n++) { if (n ==0) { pt = cvCenter.StartPoint(); } else { pt = cvCenter.EndPoint(); } RBList rbFilter = acutBuildList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL); ads_point pt1, pt2; TPickEntSet ssEnts(SS_FREE); pt1[X] = pt.x; pt1[Y] = pt.y; pt1[Z] = pt.z; acdbWcs2Ucs(pt1,pt1,false); ads_point_set(pt1,pt2); pt1[X] -= dw; pt1[Y] += dw; pt2[X] += dw; pt2[Y] -= dw; acedSSGet(_T("C"),pt1,pt2,rbFilter,ssEnts); long l = 0; TADSGePoint3d ptBase; AcDbObjectIdArray ids;//没有相交的对象 ssEnts.AsIdArray(ids); long len = ids.length(); TADSGePoint3d ptInter; int nMod = 0, i = -1; switch (len) { case 2: { if (IsIntersect(ids[0], ids[1]) == 0) {//只有两个墙,并且不想交时才处理 nMod = GetIntersectPt(ids[0], ids[1], ptInter); if (nMod == 1) { TWallGraph wGraph(ids[0]); wGraph.MoveNode(ids[0], ptInter); } if (nMod == 2) { TWallGraph wGraph(ids[1]); wGraph.MoveNode(ids[1], ptInter); } } break; } case 3: { ids.remove(idwall); if (IsIntersect(idwall, ids[0]) == 0 && (IsIntersect(idwall, ids[1]) == 0)) {//三个墙,和其它两个都没有交点 nMod = GetIntersectPt(ids[0], ids[1], ptInter); if (nMod > 0) {//其它两个墙有交点 TWallGraph wGraph(idwall); wGraph.MoveNode(idwall, ptInter); } else {//三个墙都没有交点 } } break; } case 4: case 5: { int k = 0, j = -1; if (len == 5) { for (i = 0; i < ids.length(); i++) { OPENOBJ_BEGIN(ids[i], AcDb::kForRead, TDbWall, pwallw) if (pwallw == NULL) { break; } if (pwallw->GetLength() < 200) { j = i; } OPENOBJ_END() } if (j > -1) { ids.removeAt(j); } else break; } ids.remove(idwall); for (i = 0; i < ids.length(); i++) { if (IsIntersect(idwall, ids[i]) > 0) { k++; j = i; } } if (k == 1) {//4个墙,和其它3个其中一个有交点。 AcDbObjectId idwall1 = ids[j]; ids.remove(idwall1); if (IsIntersect(ids[0], ids[1]) > 0) {//只有另外两个墙也有交点时才处理 nMod = GetIntersectPt(ids[0], ids[1], ptInter); if (nMod > 0) {//其它任意两个墙有交点,即可 TWallGraph wGraph(idwall); wGraph.MoveNode(idwall, ptInter); break; } } } if (k == 0) {//4个墙,和其它3个都没有交点 for (i = 0; i < ids.length(); i++) { j = i+1; if (j == 3) { j = 0; } if (IsIntersect(ids[i], ids[j]) > 0) { nMod = GetIntersectPt(ids[i], ids[j], ptInter); if (nMod > 0) {//其它任意两个墙有交点,即可 TWallGraph wGraph(idwall); wGraph.MoveNode(idwall, ptInter); break; } } } } break; } } } } ////////////////////////////// // Command: 修墙角2增强版修墙角,但有bug暂时不公开 // add by wlw on 150327 void BrkWallEx() { // //add by xlc on 100520 优化算法 // EndModelRecordZone(); BeginModelRecordZone(); adsout << _T("\n请小范围框选需要处理的墙角、柱子或墙体造型."); while (true) { XPoint pt1, pt2; if (XGetPoint(NULL, _T("\n请点取第一个角点"), pt1) != RTNORM || XGetCorner(pt1, _T("\n点取另一个角点<退出>:"), pt2) != RTNORM) { EndModelRecordZone(); return; } //更新裁剪 RBList maskClip(RTDXF0, _T("TCH_COLUMN,TCH_WALL_PATCH,TCH_WALL,TCH_OPENING,TCH_CORNER_WINDOW,TCH_CURTAIN_WALL"), NULL); PickSet ssClip(SS_FREE); if (ssClip.Get(_T("C"), pt1, pt2, maskClip) == RTNORM) { AcDbObjectIdArray idArray,idwalls; ssClip.AsIdArray(idArray); long lCount = idArray.length(); long lwall(0),lother(0); if (lCount != ssClip.Length()) { continue; } for (long i = 0; i< ssClip.Length(); i++) { Entity ent = ssClip[i]; if (i > 100) { continue; } //更新裁剪 if (ent.Is(_T("TCH_WALL")) || ent.Is(_T("TCH_CURTAIN_WALL"))) {// modify by wlw on 150327 丰富对象裁剪类型 lwall++; if (lwall > 30) { continue; } GoEntFromInPts(idArray[i]); idwalls.append(idArray[i]); } //更新裁剪 if (ent.Is(_T("TCH_COLUMN")) || ent.Is(_T("TCH_OPENING")) || ent.Is(_T("TCH_CORNER_WINDOW"))) { lother++; if (lother > 20) { continue; } TArchCmdReactor::AddModifiedClip(idArray[i]); TArchCmdReactor::UpdateClip(); } //更新造型 if (ent.Is(_T("TCH_WALL_PATCH"))) { OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWallPatch, pPatch); if (!pPatch) continue; XPoly2D polyOut0(1), polyOut(1); pPatch->GetOutlinePoly(polyOut0); if (!polyOut0) continue; double nFactor=polyOut0.PathArea()>0? -5.0 : 5.0; polyOut0.QuickOffset(nFactor*_DIST_SNAP, polyOut); XPoint ptLow, ptUp; polyOut.GetExtend(ptLow, ptUp); ptLow.z=ptUp.z=0; pPatch->RemoveAllLinkages(); PickSet ssWalls(SS_FREE); if (GetSafeSelection(ssWalls, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) != Acad::eOk) continue; long lWallCount=ssWalls.Length(); for (long idx=0L; idxAddPatchId(pWall->objectId()); pWall->AddPatchId(pPatch->objectId()); } OPENOBJ_END(); } OPENOBJ_END(); } TArchCmdReactor::UpdateCorners(); TArchCmdReactor::ResetAll(); } //更新墙角 std::vector segVector; lCount = idwalls.length(); if (lCount > 20) { continue; } for (long i=0; i < lCount; ++i) { OPENOBJ_BEGIN(idwalls[i], AcDb::kForRead, TDbWall, pWall) if (pWall != NULL) { XCurveSegment curSeg; curSeg = *pWall; curSeg.SetLineFlag(LS_FINITE); segVector.push_back(curSeg); } else { idwalls.removeAt(i); } OPENOBJ_END(); } lCount = idwalls.length(); if (segVector.size() != lCount) { continue; } XPoint ptInter[2], ptInt; for (long m = 0; m < lCount; m++) { for (long j = 0; j < lCount; j++) { if (m == j) { continue; } int nIntNum=segVector[m].Intersection(segVector[j], ptInter[0], ptInter[1]); if (nIntNum == 0) { continue; } if (nIntNum > 0) { ptInt = ptInter[0]; } OPENOBJ_BEGIN(idArray[m], AcDb::kForWrite, TDbWall, pWall1); if (pWall1) { pWall1->assertWriteEnabled(); pWall1->BreakAt(ptInt, AcDbObjectId()); } OPENOBJ_END(); OPENOBJ_BEGIN(idArray[j], AcDb::kForWrite, TDbWall, pWall2); if (pWall2) { pWall2->assertWriteEnabled(); pWall2->BreakAt(ptInt, AcDbObjectId()); } OPENOBJ_END(); } } TArchCmdReactor::UpdateCorners(); TArchCmdReactor::ResetAll(); } } EndModelRecordZone(); } // 基线对齐 void OffsetWallBase() { TARCH_IMPEXP void ToggleWallBase(); BOOL bShowBase=DocGetShowBase(); if (!bShowBase) ToggleWallBase(); XPoint ptNewBase; while (XGetPoint(NULL, _T("\n请点取墙基线的新端点或新连接点"), ptNewBase) == RTNORM) { ptNewBase=Ucs2Wcs(ptNewBase); PickSet ss(SS_FREE); if (SelectEntities(_T("\n请选择墙体(注意:相连墙体的基线会自动联动!)<退出>:"), ss, RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL)) == RTNORM) { AcDbObjectIdArray idArray; ss.AsIdArray(idArray); for (long i=0;i:"), pt2) != RTNORM) // { // //add by xlc on 100520 优化算法 // EndModelRecordZone(); // return; // } // // //更新裁剪 // RBList maskClip(RTDXF0, _T("TCH_COLUMN,TCH_WALL_PATCH,TCH_WALL,TCH_OPENING,TCH_CORNER_WINDOW"), NULL); // PickSet ssClip(SS_FREE); // if (ssClip.Get(_T("C"), pt1, pt2, maskClip) == RTNORM) // { // AcDbObjectIdArray idArray; // ssClip.AsIdArray(idArray); // int count=min(idArray.length(),20); // for (long i=0;iGetOutlinePoly(polyOut0); // if (!polyOut0) // continue; // double nFactor=polyOut0.PathArea()>0? -5.0 : 5.0; // polyOut0.QuickOffset(nFactor*_DIST_SNAP, polyOut); // // XPoint ptLow, ptUp; // polyOut.GetExtend(ptLow, ptUp); // ptLow.z=ptUp.z=0; // // pPatch->RemoveAllLinkages(); // PickSet ssWalls(SS_FREE); // if (GetSafeSelection(ssWalls, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) != Acad::eOk) // continue; // // long lWallCount=ssWalls.Length(); // for (long idx=0L; idxAddPatchId(pWall->objectId()); // pWall->AddPatchId(pPatch->objectId()); // } // OPENOBJ_END(); // } // OPENOBJ_END(); // } // } // // //更新墙角 // RBList mask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL); // PickSet ssWalls(SS_FREE); // if (ssWalls.Get(_T("C"), pt1, pt2, mask) != RTNORM) // continue; // XPoint ptMid; // Midpoint(pt1, pt2, ptMid); // ptMid=Ucs2Wcs(ptMid); // long lCount=ssWalls.Length(); // if (lCount>=2) // { // //if (lCount == 2) // //{ // // OPENOBJ_BEGIN(ssWalls[0L], AcDb::kForRead, TDbWall, pWall1); // // if (pWall1) // // { // // OPENOBJ_BEGIN(ssWalls[1L], AcDb::kForRead, TDbWall, pWall2); // // if (pWall2) // // { // // } // // OPENOBJ_END(); // // } // // OPENOBJ_END(); // //} // // XCurveSegment seg[2]; // for (long i=0L; i<2L; i++) // { // Entity ent=ssWalls[i]; // OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall); // if (pWall) // { // pWall->assertWriteEnabled(); // seg[i]=*pWall; // } // else // goto LABEL1; // OPENOBJ_END(); // } // // seg[0].flag=seg[1].flag=LS_FINITE; // seg[0].SetLineFlag(LS_FINITE); // seg[1].SetLineFlag(LS_FINITE); // XPoint ptInter[2], ptInt; // int nIntNum=seg[0].Intersection(seg[1], ptInter[0], ptInter[1]); // if (nIntNum == 0) // { // if (lCount>=3) // { // Entity ent3=ssWalls[2L]; // OPENOBJ_BEGIN(ent3, AcDb::kForWrite, TDbWall, pWall); // pWall->assertWriteEnabled(); // if (!pWall || pWall->Intersection(seg[0], ptInt, XPoint()) == 0) // goto LABEL1; // OPENOBJ_END(); // } // else // goto LABEL1; // } // else // { // if (nIntNum == 1) // ptInt=ptInter[0]; // else // ptInt=XLine(ptInter[0], ptInter[1]).NearPoint(ptMid); // } // // for (i=0L; iassertWriteEnabled(); // pWall->BreakAt(ptInt, AcDbObjectId()); // } // OPENOBJ_END(); // } // } // // TArchCmdReactor::UpdateCorners(); // TArchCmdReactor::ResetAll(); // } // // //add by xlc on 100520 优化算法 // EndModelRecordZone(); BeginModelRecordZone(); adsout << sMsgPrompt[4]; while (true) { XPoint pt1, pt2; ads_real precision=500;//精度范围为100; if (XGetPoint(NULL, _T("\n请点取第一个角点"), pt1) != RTNORM || XGetCorner(pt1, _T("\n点取另一个角点<退出>:"), pt2) != RTNORM) { EndModelRecordZone(); return; } //更新裁剪 RBList maskClip(RTDXF0, _T("TCH_COLUMN,TCH_WALL_PATCH,TCH_WALL,TCH_OPENING,TCH_CORNER_WINDOW"), NULL); PickSet ssClip(SS_FREE); if (ssClip.Get(_T("C"), pt1, pt2, maskClip) == RTNORM) { AcDbObjectIdArray idArray; ssClip.AsIdArray(idArray); int count=min(idArray.length(),20); for (long i=0;iGetOutlinePoly(polyOut0); if (!polyOut0) continue; double nFactor=polyOut0.PathArea()>0? -5.0 : 5.0; polyOut0.QuickOffset(nFactor*_DIST_SNAP, polyOut); XPoint ptLow, ptUp; polyOut.GetExtend(ptLow, ptUp); ptLow.z=ptUp.z=0; pPatch->RemoveAllLinkages(); PickSet ssWalls(SS_FREE); if (GetSafeSelection(ssWalls, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) != Acad::eOk) continue; long lWallCount=ssWalls.Length(); for (long idx=0L; idxAddPatchId(pWall->objectId()); pWall->AddPatchId(pPatch->objectId()); } OPENOBJ_END(); } OPENOBJ_END(); } } //更新墙角 RBList mask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL); PickSet ssWalls(SS_FREE); if (ssWalls.Get(_T("C"), pt1, pt2, mask) != RTNORM) continue; XPoint ptMid; Midpoint(pt1, pt2, ptMid); ptMid=Ucs2Wcs(ptMid); long lCount=ssWalls.Length(); if (lCount < 20) { std::vector segVector; for (long i=0L; iassertWriteEnabled(); curSeg = *pWall; segVector.push_back(curSeg); } OPENOBJ_END(); } //modify by lgy 20120213 15平台编译不通过 // for (long i = 0L; i < lCount; i++) // { // segVector[i].SetLineFlag(LS_FINITE); // } for (long j = 0L; j < lCount; j++) { segVector[j].SetLineFlag(LS_FINITE); } XPoint ptInter[2], ptInt; //ptInter记录两线交点, ptInt记录要修墙角的点 //modify by lgy 20120213 15平台编译不通过 //for (long i = 0L; i < lCount; i++) for (long m = 0L; m < lCount; m++) { for (long j = 0; j < lCount; j++) { //modify by lgy 20120213 15平台编译不通过 //if (i == j) //{ // continue; //} if (m == j) { continue; } int nIntNum=segVector[m].Intersection(segVector[j], ptInter[0], ptInter[1]); if (nIntNum == 0) { continue; } if (nIntNum > 0) { ptInt = ptInter[0]; } Entity ent=ssWalls[m]; OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall); if (pWall) { pWall->assertWriteEnabled(); pWall->BreakAt(ptInt, AcDbObjectId()); } OPENOBJ_END(); ent=ssWalls[j]; OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall); if (pWall) { pWall->assertWriteEnabled(); pWall->BreakAt(ptInt, AcDbObjectId()); } OPENOBJ_END(); } } } TArchCmdReactor::UpdateCorners(); TArchCmdReactor::ResetAll(); } EndModelRecordZone(); } /* * * * * * * * * * * * * * * 倒 墙 角 的 函 数 * * * * * * * * * * * * * * */ //使用的方法如下:1:直接计算2:按照给定的墙体填充直线以及圆弧实体,调用Autocad的命令Fillet //得到产生的圆弧以后在按照该圆弧生成弧线墙.该方法完全模仿了AUTOCAD的命令. void FilletWall() { TDbWall *pWalla=NULL,*pWallb=NULL; ads_real filletrad; XPoint pt1,pt2; if (InputFilletWall(pWalla,pWallb,filletrad,pt1,pt2) != TRUE) return;//输入错误 if (!CanFillet(pWalla,pWallb,pt1,pt2,filletrad))//如果不能倒角 { pWalla->close(); pWallb->close(); return; } FilletSameEntitys(pWalla,pWallb,(ads_real *)pt1,(ads_real *)pt2); pWalla->close(); pWallb->close(); return; } BOOL InputFilletWall(TDbWall *&pWalla,TDbWall *&pWallb,ads_real &filletrad,XPoint &pt1,XPoint &pt2) { Entity en1,en2; AcDbEntity *pEnt=NULL; AcDbObjectId WallObjId1,WallObjId2; do { int es; VERIFY(xg_getvar(_T("FilletRad"),&filletrad) == RTNORM); adsout << _T("\n选择第一段墙或 [设圆角半径(R),当前=")<: "); INITGET_BEG(0, _T("R")); es = en1.FilterSelect(_T(""), RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL),pt1); INITGET_END(); if (es == RTKWORD) { es = XGetDist(NULL,sMsgPrompt[16],filletrad,RSG_NONEG); if (es == RTNORM) xg_setvar(_T("FilletRad"),filletrad); continue; } if (es != RTNORM) return FALSE; acdbGetObjectId(WallObjId1,en1); acdbOpenAcDbEntity(pEnt,WallObjId1,AcDb::kForWrite); if (pEnt == NULL) return FALSE; pWalla = (TDbWall *)pEnt; break; }while(1); pWalla->highlight(); do { VERIFY(pWalla->downgradeOpen() == Acad::eOk); int es = en2.FilterSelect(_T("\n选择另一段墙<退出>:"),RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL),pt2); VERIFY(pWalla->upgradeOpen() == Acad::eOk); if (es != RTNORM) { pWalla->unhighlight(); pWalla->close(); return FALSE; } if (en1 == en2) { adsout << _T("\n请选择不同的两段墙!"); continue; } acdbGetObjectId(WallObjId2,en2); pEnt=NULL; acdbOpenAcDbEntity(pEnt,WallObjId2,AcDb::kForWrite); pWalla->unhighlight(); if (pEnt == NULL) return FALSE; pWallb = (TDbWall *)pEnt; break; }while(1); //保证 Undo 成功 pWalla->assertWriteEnabled(); pWallb->assertWriteEnabled(); return TRUE; } //判断墙壁能否倒角.所有不偏心的墙都可以; //如果墙体偏心,有时可以调节能得到正确的结果 int CanFillet(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pt2,ads_real &filletrad) { if (filletrad<1.0E-3) return TRUE; if (pWalla->GetStyle() != pWallb->GetStyle()) { ads_printf(sMsgPrompt[19]); return 0; } if (fabs(pWalla->GetWidth()-pWallb->GetWidth())>1.0E-3) { ads_printf(sMsgPrompt[20]); return 0; } if (fabs(pWalla->GetWidth(0)-pWalla->GetWidth (1))<1.0E-3 && fabs(pWallb->GetWidth(0)-pWallb->GetWidth (1))<1.0E-3)//如果不偏心 { return 1; } //如果是偏心墙,考虑两段墙壁的偏心情况 XPoint pi; int intn,ret1,ret2; if ((intn=GetInterPoint(pWalla,pWallb,pt1,pi)) == 0) //不相交(平行)也可以倒角,但是必须是倒角半径和相差的距离相同 { ads_printf(sMsgPrompt[23]); return 0; } XCurveSegment seg1=*pWalla; XCurveSegment seg2=*pWallb; ret1=pi&seg1; ret2=pi&seg2; if (ret1 == 3 || ret2 == 3)//如果交点在墙壁内部 { ads_real temp; BOOL flag1=FALSE,flag2=FALSE,flaga=FALSE,flagb=FALSE; if (ads_distance(pWalla->StartPoint() ,pt1)StartPoint() ,pi)) flag1=TRUE;//拾取点在起始点和交点之间; if (ads_distance(pWallb->StartPoint() ,pt2)StartPoint() ,pi)) flag2=TRUE;//拾取点在起始点和交点之间; if (pWalla->GetWidth(0)GetWidth(1)) flaga=TRUE;//左小于右 if (pWallb->GetWidth(0)GetWidth(1)) flagb=TRUE;//左小于右 if (flag1 && flag2 && flaga && flagb || flag1 && flag2 && !flaga && !flagb || flag1 && !flag2 && flaga && !flagb || flag1 && !flag2 && !flaga && flagb || !flag1 && flag2 && flaga && !flagb || !flag1 && flag2 && !flaga && flagb || !flag1 && !flag2 && flaga && flagb || !flag1 && !flag2 && !flaga && !flagb) { if (filletrad>1E-3) { if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[24],sMsgPrompt[25],MB_YESNO) != IDYES) return 0; temp=pWallb->GetWidth(0); pWallb->SetWidth(0,pWallb->GetWidth(1)); pWallb->SetWidth(1,temp); return 2; } else { return 1; } } else if (flag1 && flag2 && flaga && !flagb || flag1 && flag2 && !flaga && flagb || flag1 && !flag2 && flaga && flagb || flag1 && !flag2 && !flaga && !flagb || !flag1 && flag2 && flaga && flagb || !flag1 && flag2 && !flaga && !flagb || !flag1 && !flag2 && !flaga && flagb || !flag1 && !flag2 && flaga && !flagb) { return 1; } ads_printf(sMsgPrompt[26]); return 0; } //以下是交点在墙壁外面 if (fabs(pWalla->GetWidth (0)-pWallb->GetWidth (0))<1.0E-3 && fabs(pWalla->GetWidth (1)-pWallb->GetWidth (1))<1.0E-3) {//如果两段墙壁的左右偏心相同:必须进一步考虑交点是否在墙内. if (ads_distance(pWalla->EndPoint() ,pi)StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)EndPoint() ,pi)) return 1;//如果是第一段起点、第一段终点、交点、第二段起点、第二段终点的排列顺序,没有问题 else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi)) return 1;//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序,也没有问题 else// 否则,不是按顺序的情况:调整? { if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[24],sMsgPrompt[25],MB_YESNO) != IDYES) return 0; if (ads_distance(pWalla->StartPoint() ,pi)>ads_distance(pWalla->EndPoint() ,pi)) {//如果是第一段起点、第一段终点、交点的顺序,把第二段墙换以下顺序; XPoint pt=pWallb->StartPoint() ; pWallb->StartPoint() =pWallb->EndPoint() ; pWallb->EndPoint() =pt; } else//如果是第一段终点、第一段起点、交点的顺序,把第二段墙换以下顺序; { XPoint pt=pWallb->EndPoint() ; pWallb->EndPoint() =pWallb->StartPoint(); pWallb->StartPoint() =pt; } return 2; } } else if (fabs(pWalla->GetWidth (0)-pWallb->GetWidth (1))<1.0E-3 && fabs(pWalla->GetWidth (1)-pWallb->GetWidth (0))<1.0E-3) {//如果两段墙壁的左右偏心相刚好相反:必须进一步考虑交点是否在墙内. if (ads_distance(pWalla->EndPoint() ,pi)StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi)) return 1;//如果是第一段起点、第一段终点、交点、第二段终点、第二段起点的排列顺序,没有问题 else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)EndPoint() ,pi)) return 1;//如果是第一段终点、第一段起点、交点、第二段起点、第二段终点的排列顺序,也没有问题 else// 否则,不是按顺序的情况:调整? { AfxMessageBox(sMsgPrompt[21]); return 0; } } else //否则:如果两段墙壁的左右偏心不相同 { //del by fxj 090511 偏心不同,不能倒角 //if (ads_distance(pWalla->EndPoint() ,pi)StartPoint() ,pi) && ads_distance(pWallb->EndPoint() ,pi)StartPoint(),pi)) // return 1;//如果是第一段起点、第一段终点、交点、第二段终点、第二段起点的排列顺序,没有问题; //else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi)) // return 1;//如果是第一段终点、第一段起点、交点、第二段起点、第二段终点的排列顺序,也没有问题 //else if (filletrad<1E-6 && intn == 1)//If the filletrad=0,we can join these wall. //{ // if (ads_distance(pWalla->EndPoint() ,pi)StartPoint() ,pi)) // pWalla->EndPoint()=pi; // else // pWalla->StartPoint()=pi; // if (ads_distance(pWallb->EndPoint() ,pi)StartPoint(),pi)) // pWallb->EndPoint()=pi; // else // pWallb->StartPoint()=pi; // return FALSE; //} //else// 否则,不是按顺序的情况:调整? //{ AfxMessageBox(sMsgPrompt[21]); return 0; //} } return 0; } int GetInterPoint(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pi) { XCurveSegment seg1=*pWalla; XCurveSegment seg2=*pWallb; // seg1.flag=seg2.flag=LS_INFINITE; seg1.SetLineFlag(LS_INFINITE); seg2.SetLineFlag(LS_INFINITE); XPoint ptInt[2]; int intn=seg1.Intersection(seg2, ptInt[0], ptInt[1]); if (!intn) return 0; if (intn == 1) pi=ptInt[0]; else pi=XLine(ptInt[0], ptInt[1]).NearPoint(pt1); return 1; } BOOL FilletSameEntitys(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2) { AcDbObjectId tempLayerId,rId1,rId2; ads_name ent1,ent2; tempLayerId = GetLayerIdFromString(_T("0")); if (!tempLayerId) return FALSE; double nElevA=pWalla->GetElevation(); double nElevB=pWallb->GetElevation(); pWalla->SetElevation(0); pWallb->SetElevation(0); AcDbCurve *pCurve1=pWalla->AsAcDbCurve(); AcDbCurve *pCurve2=pWallb->AsAcDbCurve(); pCurve1->setLayer(tempLayerId); pCurve2->setLayer(tempLayerId); rId1=AddToModelSpace(pCurve1, Adesk::kTrue); rId2=AddToModelSpace(pCurve2, Adesk::kTrue); if (!rId1 || !rId2) { pWalla->SetElevation(nElevA); pWallb->SetElevation(nElevB); return FALSE; } VERIFY(acdbGetAdsName(ent1,rId1) == Acad::eOk && acdbGetAdsName(ent2,rId2) == Acad::eOk); XPushVar vOsMode(_T("OSMODE"), 0); ads_name lastent,lastent1; ads_entlast(lastent); VERIFY(pWalla->downgradeOpen() == Acad::eOk); VERIFY(pWallb->downgradeOpen() == Acad::eOk); ads_command(RTSTR,_T("FILLET"), RTLB,RTENAME,ent1,RTPOINT,pt1,RTLE, RTLB,RTENAME,ent2,RTPOINT,pt2,RTLE,RTNONE); VERIFY(pWalla->upgradeOpen() == Acad::eOk); VERIFY(pWallb->upgradeOpen() == Acad::eOk); ads_entlast(lastent1); Entity e1=ent1; XCurveSegment seg1(e1); pWalla->SetPoints(seg1.StartPoint(), seg1.EndPoint()); pWalla->SetElevation(nElevA); ads_entdel(ent1); Entity e2=ent2; XCurveSegment seg2(e2); pWallb->SetPoints(seg2.StartPoint(), seg2.EndPoint()); pWallb->SetElevation(nElevB); ads_entdel(ent2); if (lastent[0] == lastent1[0] && lastent[1] == lastent1[1])//如果没有产生新的实体 ; else { XArc arc(lastent1); ads_entdel(lastent1); //refreshed by whl on 050822; TDbWall*pWall=NULL; if (pWalla->isKindOf(TDbCurtainWall::desc())) pWall = (TDbWall *)TDbCurtainWall::desc()->create(); else pWall = (TDbWall *)TDbWall::desc()->create(); pWall->setPropertiesFrom(pWalla); XCurveSegment seg; seg=arc; *(XCurveSegment *)pWall=seg; if (pWalla->EndPoint() == pWall->StartPoint() || pWalla->StartPoint() == pWall->EndPoint()) {//如果是第一段起点、第一段终点、交点、第二段起点、第二段终点的排列顺序或完全相反 pWall->SetWidth(0, pWalla->GetWidth(0)); pWall->SetWidth(1, pWalla->GetWidth(1)); } else if (pWalla->EndPoint() == pWall->EndPoint() || pWalla->StartPoint() == pWall->StartPoint()) {//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序或完全相反 pWall->SetWidth(0, pWalla->GetWidth(1)); pWall->SetWidth(1, pWalla->GetWidth(0)); } if (pWall->isA() == TDbWall::desc()) { pWall->SetStyle(pWalla->GetStyle()); int nWallFlag = pWalla->GetWallFlag(); nWallFlag &= ~WF_POLYSHAPE; nWallFlag &= ~WF_SECTTERM; pWall->SetWallFlag(nWallFlag); } pWall->SetHeight(pWalla->GetHeight()); pWall->AddToMSpace(Adesk::kTrue); } return TRUE; } //add by xlc void ChamferWall() { TDbWall *pWalla=NULL,*pWallb=NULL; ads_real dChamferDistA,dChamferDistB; XPoint pt1,pt2; if (InputChamferWall(pWalla,pWallb,dChamferDistA,dChamferDistB,pt1,pt2) != TRUE) return;//输入错误 //del by fxj 090402 //if (!CanChamfer(pWalla,pWallb,pt1,pt2,dChamferDistA,dChamferDistB))//如果不能倒角 //{ // pWalla->close(); // pWallb->close(); // return; //} //modified by fxj 090522 if (dChamferDistA<1E-3 || dChamferDistB<1E-3) ChamferSameEntitys(pWalla,pWallb,(ads_real *)pt1,(ads_real *)pt2); else ChamferSameEntitys1(pWalla,pWallb,(ads_real *)pt1,(ads_real *)pt2); pWalla->close(); pWallb->close(); return; } BOOL InputChamferWall(TDbWall *&pWalla,TDbWall *&pWallb,ads_real &chamferDistA,ads_real &chamferDistB, XPoint &pt1,XPoint &pt2) { Entity en1,en2; AcDbEntity *pEnt=NULL; AcDbObjectId WallObjId1,WallObjId2; //确定倒角参数及第一段墙 do { int es; VERIFY(xg_getvar(_T("CHAMFERA"),&chamferDistA) == RTNORM); VERIFY(xg_getvar(_T("CHAMFERB"),&chamferDistB) == RTNORM); adsout << _T("\n选择第一段直墙或 [设距离(D),当前距离 1=")<: "); INITGET_BEG(0, _T("D")); es = en1.FilterSelect(_T(""), RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL),pt1); INITGET_END(); if (es == RTKWORD) { es = XGetDist(NULL,_T("\n指定第一个倒角距离"),chamferDistA,RSG_NONEG); if (es == RTNORM ||es == RTNONE) { xg_setvar(_T("CHAMFERA"),chamferDistA); es = XGetDist(NULL,_T("\n指定第二个倒角距离"),chamferDistB,RSG_NONEG); if (es == RTNORM) { xg_setvar(_T("CHAMFERB"),chamferDistB); } } continue; } if (es != RTNORM) return FALSE; acdbGetObjectId(WallObjId1,en1); acdbOpenAcDbEntity(pEnt,WallObjId1,AcDb::kForWrite); if (pEnt == NULL) return FALSE; pWalla = (TDbWall *)pEnt; BOOL bIsArc = pWalla->Is(CURVE_ARC); if (bIsArc) { adsout << _T("\n倒角需要直墙,不能用弧墙!"); pWalla->close(); continue; } break; }while(1); pWalla->highlight(); //确定第二段墙 do { VERIFY(pWalla->downgradeOpen() == Acad::eOk); int es = en2.FilterSelect(_T("\n选择另一段直墙<退出>:"),RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL),pt2); VERIFY(pWalla->upgradeOpen() == Acad::eOk); if (es != RTNORM) { pWalla->unhighlight(); pWalla->close(); return FALSE; } if (en1 == en2) { adsout << _T("\n请选择不同的两段墙!"); continue; } acdbGetObjectId(WallObjId2,en2); pEnt=NULL; acdbOpenAcDbEntity(pEnt,WallObjId2,AcDb::kForWrite); pWalla->unhighlight(); if (pEnt == NULL) return FALSE; pWallb = (TDbWall *)pEnt; BOOL bIsArc = pWallb->Is(CURVE_ARC); if (bIsArc) { adsout << _T("\n倒角需要直墙,不能用弧墙!"); pWallb->close(); continue; } break; }while(1); //保证 Undo 成功 pWalla->assertWriteEnabled(); pWallb->assertWriteEnabled(); return TRUE; } //如果墙体偏心,有时可以调节能得到正确的结果 int CanChamfer(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pt2,ads_real &chamferDistA, ads_real &chamferDistB) { if (chamferDistA < 1.0E-3) return TRUE; if (chamferDistB < 1.0E-3) return TRUE; if (pWalla->GetStyle() != pWallb->GetStyle()) { ads_printf(sMsgPrompt[19]); return 0; } if (fabs(pWalla->GetWidth()-pWallb->GetWidth())>1.0E-3) { ads_printf(sMsgPrompt[20]); return 0; } if (fabs(pWalla->GetWidth(0)-pWalla->GetWidth (1))<1.0E-3 && fabs(pWallb->GetWidth(0)-pWallb->GetWidth (1))<1.0E-3)//如果不偏心 { return 1; } //如果是偏心墙,考虑两段墙壁的偏心情况 XPoint pi; int intn,ret1,ret2; if ((intn=GetInterPoint(pWalla,pWallb,pt1,pi)) == 0) //不相交(平行)也可以倒角,但是必须是倒角半径和相差的距离相同 { ads_printf(sMsgPrompt[23]); return 0; } XCurveSegment seg1=*pWalla; XCurveSegment seg2=*pWallb; ret1=pi&seg1; ret2=pi&seg2; if (ret1 == 3 || ret2 == 3)//如果交点在墙壁内部 { ads_real temp; BOOL flag1=FALSE,flag2=FALSE,flaga=FALSE,flagb=FALSE; if (ads_distance(pWalla->StartPoint() ,pt1)StartPoint() ,pi)) flag1=TRUE;//拾取点在起始点和交点之间; if (ads_distance(pWallb->StartPoint() ,pt2)StartPoint() ,pi)) flag2=TRUE;//拾取点在起始点和交点之间; if (pWalla->GetWidth(0)GetWidth(1)) flaga=TRUE;//左小于右 if (pWallb->GetWidth(0)GetWidth(1)) flagb=TRUE;//左小于右 if (flag1 && flag2 && flaga && flagb || flag1 && flag2 && !flaga && !flagb || flag1 && !flag2 && flaga && !flagb || flag1 && !flag2 && !flaga && flagb || !flag1 && flag2 && flaga && !flagb || !flag1 && flag2 && !flaga && flagb || !flag1 && !flag2 && flaga && flagb || !flag1 && !flag2 && !flaga && !flagb) { if (chamferDistA>1E-3) { if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[24],sMsgPrompt[25],MB_YESNO) != IDYES) return 0; temp=pWallb->GetWidth(0); pWallb->SetWidth(0,pWallb->GetWidth(1)); pWallb->SetWidth(1,temp); return 2; } else { return 1; } } else if (flag1 && flag2 && flaga && !flagb || flag1 && flag2 && !flaga && flagb || flag1 && !flag2 && flaga && flagb || flag1 && !flag2 && !flaga && !flagb || !flag1 && flag2 && flaga && flagb || !flag1 && flag2 && !flaga && !flagb || !flag1 && !flag2 && !flaga && flagb || !flag1 && !flag2 && flaga && !flagb) { return 1; } ads_printf(sMsgPrompt[26]); return 0; } //以下是交点在墙壁外面 if (fabs(pWalla->GetWidth (0)-pWallb->GetWidth (0))<1.0E-3 && fabs(pWalla->GetWidth (1)-pWallb->GetWidth (1))<1.0E-3) { //如果两段墙壁的左右偏心相同:必须进一步考虑交点是否在墙内. if (ads_distance(pWalla->EndPoint() ,pi)StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)EndPoint() ,pi)) return 1;//如果是第一段起点、第一段终点、交点、第二段起点、第二段终点的排列顺序,没有问题 else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi)) return 1;//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序,也没有问题 else// 否则,不是按顺序的情况:调整? { if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[24],sMsgPrompt[25],MB_YESNO) != IDYES) return 0; if (ads_distance(pWalla->StartPoint() ,pi)>ads_distance(pWalla->EndPoint() ,pi)) {//如果是第一段起点、第一段终点、交点的顺序,把第二段墙换以下顺序; XPoint pt=pWallb->StartPoint() ; pWallb->StartPoint() =pWallb->EndPoint() ; pWallb->EndPoint() =pt; } else//如果是第一段终点、第一段起点、交点的顺序,把第二段墙换以下顺序; { XPoint pt=pWallb->EndPoint() ; pWallb->EndPoint() =pWallb->StartPoint(); pWallb->StartPoint() =pt; } return 2; } } else if (fabs(pWalla->GetWidth (0)-pWallb->GetWidth (1))<1.0E-3 && fabs(pWalla->GetWidth (1)-pWallb->GetWidth (0))<1.0E-3) {//如果两段墙壁的左右偏心相刚好相反:必须进一步考虑交点是否在墙内. if (ads_distance(pWalla->EndPoint() ,pi)StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi)) return 1;//如果是第一段起点、第一段终点、交点、第二段终点、第二段起点的排列顺序,没有问题 else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)EndPoint() ,pi)) return 1;//如果是第一段终点、第一段起点、交点、第二段起点、第二段终点的排列顺序,也没有问题 else// 否则,不是按顺序的情况:调整? { AfxMessageBox(sMsgPrompt[21]); return 0; } } else //否则:如果两段墙壁的左右偏心不相同 { if (ads_distance(pWalla->EndPoint() ,pi)StartPoint() ,pi) && ads_distance(pWallb->EndPoint() ,pi)StartPoint(),pi)) return 1;//如果是第一段起点、第一段终点、交点、第二段终点、第二段起点的排列顺序,没有问题; else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi)) return 1;//如果是第一段终点、第一段起点、交点、第二段起点、第二段终点的排列顺序,也没有问题 else if (chamferDistA<1E-6 && intn == 1)//If the filletrad=0,we can join these wall. { if (ads_distance(pWalla->EndPoint() ,pi)StartPoint() ,pi)) pWalla->EndPoint()=pi; else pWalla->StartPoint()=pi; if (ads_distance(pWallb->EndPoint() ,pi)StartPoint(),pi)) pWallb->EndPoint()=pi; else pWallb->StartPoint()=pi; return FALSE; } else// 否则,不是按顺序的情况:调整? { AfxMessageBox(sMsgPrompt[21]); return 0; } } return 0; } //add by fxj 090507 倒角距离以墙中线为准 BOOL ChamferSameEntitys1(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2) { AcDbObjectId tempLayerId,rId1,rId2; ads_name ent1,ent2; tempLayerId = GetLayerIdFromString(_T("0")); if (!tempLayerId) return FALSE; double nElevA=pWalla->GetElevation(); double nElevB=pWallb->GetElevation(); pWalla->SetElevation(0); pWallb->SetElevation(0); double nBaseDist1=(pWalla->GetWidth(0)-pWalla->GetWidth(1))/2.0;//第一段墙的临时虚拟基线比原基线靠左nBaseDist的距离(可正可负) XCurveSegment segBase1=pWalla->XCurveSegment::Offset(OFFSET_LEFT,nBaseDist1, LS_FINITE); double nBaseDist2=(pWallb->GetWidth(0)-pWallb->GetWidth(1))/2.0; XCurveSegment segBase2=pWallb->XCurveSegment::Offset(OFFSET_LEFT,nBaseDist2, LS_FINITE);//第二段墙的临时虚拟基线比原基线靠左nBaseDist的距离(可正可负) AcDbCurve *pCurve1=segBase1.AsAcDbCurve(); AcDbCurve *pCurve2=segBase2.AsAcDbCurve(); pCurve1->setLayer(tempLayerId); pCurve2->setLayer(tempLayerId); rId1=AddToModelSpace(pCurve1, Adesk::kTrue); rId2=AddToModelSpace(pCurve2, Adesk::kTrue); if (!rId1 || !rId2) { pWalla->SetElevation(nElevA); pWallb->SetElevation(nElevB); return FALSE; } VERIFY(acdbGetAdsName(ent1,rId1) == Acad::eOk && acdbGetAdsName(ent2,rId2) == Acad::eOk); XPushVar vOsMode(_T("OSMODE"), 0); ads_name lastent,lastent1; ads_entlast(lastent); ads_command(RTSTR,_T("CHAMFER"), RTLB,RTENAME,ent1,RTPOINT,pt1,RTLE, RTLB,RTENAME,ent2,RTPOINT,pt2,RTLE,RTNONE); ads_entlast(lastent1); Entity e1=ent1; XCurveSegment seg1(e1); ads_entdel(ent1); Entity e2=ent2; XCurveSegment seg2(e2); ads_entdel(ent2); XPoint ptTempS=seg1.StartPoint(); XPoint ptTempE=seg1.EndPoint(); if (lastent[0] == lastent1[0] && lastent[1] == lastent1[1])//如果没有产生新的实体 { } else { //modified by fxj 090522 解决两段墙不相接时倒角不正确问题。再次调用了AutoCAD的chamfer命令 XCurveSegment seg(lastent1); ads_entdel(lastent1); if (ptTempS == seg.StartPoint() || ptTempE == seg.EndPoint()) seg.Reverse(); XPoint pta,ptb; seg=seg.Offset(OFFSET_RIGHT,nBaseDist1, LS_INFINITE);//向右偏移nBaseDist1的距离, 得到新生成墙的新基线 XPoint ptStart1,ptEnd1,ptStart2,ptEnd2; pWalla->GetBaseCurve()->getStartPoint(ptStart1); pWalla->GetBaseCurve()->getEndPoint(ptEnd1); pWallb->GetBaseCurve()->getStartPoint(ptStart2); pWallb->GetBaseCurve()->getEndPoint(ptEnd2); XLine line1(ptStart1,ptEnd1,LS_INFINITE); XLine line2(ptStart2,ptEnd2,LS_INFINITE); XLine line=seg.GetLine(); int nIntNumA=line.Intersection(&line1,pta); int nIntNumB=line.Intersection(&line2,ptb); if (nIntNumA<1||nIntNumB<1) { //seg1=seg1.Offset(OFFSET_RIGHT,nBaseDist1, LS_FINITE); //seg2=seg2.Offset(OFFSET_RIGHT,nBaseDist2, LS_FINITE); //pWalla->SetPoints(seg1.StartPoint(), seg1.EndPoint()); pWalla->SetElevation(nElevA); //pWallb->SetPoints(seg2.StartPoint(), seg2.EndPoint()); pWallb->SetElevation(nElevB); return TRUE; } if (pta.Distance2d(ptb)<100) return FALSE; //------------------------------用新的距离对基线倒角 XPoint ptNode; line1.Intersection(&line2,ptNode); double chamferDistA1=pta.Distance2d(ptNode); double chamferDistB1=ptb.Distance2d(ptNode); double chamferDistA=0; double chamferDistB=0; xg_getvar(_T("CHAMFERA"),&chamferDistA);//最初用户输入的距离。(得到系统变量的旧值) xg_getvar(_T("CHAMFERB"),&chamferDistB); xg_setvar(_T("CHAMFERA"),chamferDistA1);//以基线为考虑对象的倒角距离 xg_setvar(_T("CHAMFERB"),chamferDistB1); AcDbObjectId rIda,rIdb; ads_name enta,entb; if (!tempLayerId) return FALSE; AcDbCurve *pCurvea=pWalla->AsAcDbCurve(); AcDbCurve *pCurveb=pWallb->AsAcDbCurve(); pCurvea->setLayer(tempLayerId); pCurveb->setLayer(tempLayerId); rIda=AddToModelSpace(pCurvea, Adesk::kTrue); rIdb=AddToModelSpace(pCurveb, Adesk::kTrue); if (!rIda || !rIdb) { return FALSE; } VERIFY(acdbGetAdsName(enta,rIda) == Acad::eOk && acdbGetAdsName(entb,rIdb) == Acad::eOk); XPushVar vOsMode(_T("OSMODE"), 0); ads_name lastent,lastent1; ads_entlast(lastent); VERIFY(pWalla->downgradeOpen() == Acad::eOk); VERIFY(pWallb->downgradeOpen() == Acad::eOk); ads_command(RTSTR,_T("CHAMFER"), RTLB,RTENAME,enta,RTPOINT,pt1,RTLE, RTLB,RTENAME,entb,RTPOINT,pt2,RTLE,RTNONE);//modified 090804 VERIFY(pWalla->upgradeOpen() == Acad::eOk); VERIFY(pWallb->upgradeOpen() == Acad::eOk); xg_setvar(_T("CHAMFERA"),chamferDistA);//最初用户输入的距离再次保存到系统变量 xg_setvar(_T("CHAMFERB"),chamferDistB); ads_entlast(lastent1); Entity ent1=enta; XCurveSegment s1(ent1); pWalla->SetPoints(s1.StartPoint(), s1.EndPoint()); pWalla->SetElevation(nElevA); ads_entdel(enta); Entity ent2=entb; XCurveSegment s2(ent2); pWallb->SetPoints(s2.StartPoint(), s2.EndPoint()); pWallb->SetElevation(nElevB); ads_entdel(entb); XCurveSegment segNew(lastent1); ads_entdel(lastent1); TDbWall*pWall=NULL; if (pWalla->isKindOf(TDbCurtainWall::desc())) pWall = (TDbWall *)TDbCurtainWall::desc()->create(); else pWall = (TDbWall *)TDbWall::desc()->create(); pWall->setPropertiesFrom(pWalla); *(XCurveSegment *)pWall=segNew; //--------------------------- //if (pWalla->StartPoint() == pWallb->StartPoint()) //{ // pWalla->StartPoint()=pta; // pWallb->StartPoint()=ptb; //} //else if (pWalla->StartPoint() == pWallb->EndPoint()) //{ // pWalla->StartPoint()=pta; // pWallb->EndPoint()=ptb; //} //else if (pWalla->EndPoint() == pWallb->StartPoint()) //{ // pWalla->EndPoint()=pta; // pWallb->StartPoint()=ptb; //} //else //{ // pWalla->EndPoint()=pta; // pWallb->EndPoint()=ptb; //} if (pWalla->EndPoint() == pWall->EndPoint() || pWalla->StartPoint() == pWall->StartPoint()) {//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序或完全相反 新墙首尾反转 XPoint ptTempt=pWall->StartPoint(); pWall->StartPoint()=pWall->EndPoint(); pWall->EndPoint()=ptTempt; } pWall->SetWidth(0, pWalla->GetWidth(0)); pWall->SetWidth(1, pWalla->GetWidth(1)); if (pWall->isA() == TDbWall::desc()) { pWall->SetStyle(pWalla->GetStyle()); int nWallFlag = pWalla->GetWallFlag(); nWallFlag &= ~WF_POLYSHAPE; nWallFlag &= ~WF_SECTTERM; pWall->SetWallFlag(nWallFlag); } pWall->SetHeight(pWalla->GetHeight()); pWall->AddToMSpace(Adesk::kTrue); } return TRUE; } // modified by fxj 090522 倒角距离以墙基线为准 BOOL ChamferSameEntitys(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2) { AcDbObjectId tempLayerId,rId1,rId2; ads_name ent1,ent2; tempLayerId = GetLayerIdFromString(_T("0")); if (!tempLayerId) return FALSE; double nElevA=pWalla->GetElevation(); double nElevB=pWallb->GetElevation(); pWalla->SetElevation(0); pWallb->SetElevation(0); AcDbCurve *pCurve1=pWalla->AsAcDbCurve(); AcDbCurve *pCurve2=pWallb->AsAcDbCurve(); pCurve1->setLayer(tempLayerId); pCurve2->setLayer(tempLayerId); rId1=AddToModelSpace(pCurve1, Adesk::kTrue); rId2=AddToModelSpace(pCurve2, Adesk::kTrue); if (!rId1 || !rId2) { pWalla->SetElevation(nElevA); pWallb->SetElevation(nElevB); return FALSE; } VERIFY(acdbGetAdsName(ent1,rId1) == Acad::eOk && acdbGetAdsName(ent2,rId2) == Acad::eOk); XPushVar vOsMode(_T("OSMODE"), 0); ads_name lastent,lastent1; ads_entlast(lastent); VERIFY(pWalla->downgradeOpen() == Acad::eOk); VERIFY(pWallb->downgradeOpen() == Acad::eOk); ads_command(RTSTR,_T("CHAMFER"), RTLB,RTENAME,ent1,RTPOINT,pt1,RTLE, RTLB,RTENAME,ent2,RTPOINT,pt2,RTLE,RTNONE); VERIFY(pWalla->upgradeOpen() == Acad::eOk); VERIFY(pWallb->upgradeOpen() == Acad::eOk); ads_entlast(lastent1); Entity e1=ent1; XCurveSegment seg1(e1); pWalla->SetPoints(seg1.StartPoint(), seg1.EndPoint()); pWalla->SetElevation(nElevA); ads_entdel(ent1); Entity e2=ent2; XCurveSegment seg2(e2); pWallb->SetPoints(seg2.StartPoint(), seg2.EndPoint()); pWallb->SetElevation(nElevB); ads_entdel(ent2); if (lastent[0] == lastent1[0] && lastent[1] == lastent1[1])//如果没有产生新的实体 ; else { XLine line(lastent1); ads_entdel(lastent1); TDbWall*pWall=NULL; if (pWalla->isKindOf(TDbCurtainWall::desc())) pWall = (TDbWall *)TDbCurtainWall::desc()->create(); else pWall = (TDbWall *)TDbWall::desc()->create(); pWall->setPropertiesFrom(pWalla); XCurveSegment seg; seg=line; *(XCurveSegment *)pWall=seg; if (pWalla->EndPoint() == pWall->EndPoint() || pWalla->StartPoint() == pWall->StartPoint()) {//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序或完全相反 新墙首尾反转 XPoint ptTempt=pWall->StartPoint(); pWall->StartPoint()=pWall->EndPoint(); pWall->EndPoint()=ptTempt; } pWall->SetWidth(0, pWalla->GetWidth(0));//add by fxj 090401 pWall->SetWidth(1, pWalla->GetWidth(1)); //------------------------------------------ if (pWall->isA() == TDbWall::desc()) { pWall->SetStyle(pWalla->GetStyle()); int nWallFlag = pWalla->GetWallFlag(); nWallFlag &= ~WF_POLYSHAPE; nWallFlag &= ~WF_SECTTERM; pWall->SetWallFlag(nWallFlag); } pWall->SetHeight(pWalla->GetHeight()); pWall->AddToMSpace(Adesk::kTrue); } return TRUE; }