// TDbPipeCanal.cpp: implementation of the TDbPipeCanal class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DbPipeCanal.h" #include #include #include "PipeTools.h" #include "DbFlangeFitting.h" #include #include #include #include "DbCanalFitting.h" extern void DrawWeight(XExplodeDraw &dc,double dWeight,XCurveSegment &seg,int nColorIndex, double nScale); // cet 2011.6.27 add static AcGePoint3d Mid(AcGePoint3d ptGe1, AcGePoint3d ptGe2) { return AcGePoint3d((ptGe1.x + ptGe2.x) / 2.0,(ptGe1.y + ptGe2.y) / 2.0,(ptGe1.z + ptGe2.z) / 2.0); } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// ACRX_DXF_DEFINE_MEMBERS(ATSPipeCanal, ATSPipe, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_PIPECANAL, "ATS_PIPECANAL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbPipeCanal); const Adesk::UInt8 TDbPipeCanal::g_nVersion = 1; TDbPipeCanal::TDbPipeCanal() { m_nWidth = 800; m_nHeight = 800; m_sSpare = _T(""); m_nCanalType = Canal_Corner5; m_nSpare = 0.0; m_dRate = 0.0; m_nCanalType = 0; m_nEntType = 0; } TDbPipeCanal::~TDbPipeCanal() { } Acad::ErrorStatus TDbPipeCanal::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } void TDbPipeCanal::CopyPropertiesFrom(AcDbEntity *pSrc,unsigned gMatchFlag) { assertWriteEnabled(); TDbPipe::CopyPropertiesFrom(pSrc, gMatchFlag); TDbPipeCanal *pPipe = TDbPipeCanal::cast(pSrc); if(pPipe) { m_nWidth = pPipe->m_nWidth; m_nHeight = pPipe->m_nHeight; m_nSpare = pPipe->m_nSpare; m_dRate = pPipe->m_dRate; m_nCanalType = pPipe->m_nCanalType; m_nEntType = pPipe->m_nEntType; m_sSpare = pPipe->m_sSpare; m_idDoteLayer = pPipe->m_idDoteLayer; } } Acad::ErrorStatus TDbPipeCanal::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& ptPick, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { if(IsVertical() && Is(CURVE_LINE) && GetExplodeMode()==DRAW_2D) //立管 { XPoint ptMid = MidPoint(); ptMid.z=0; snapPoints.append(ptMid); } else { snapPoints.append(StartPoint()); snapPoints.append(EndPoint()); XPoint ptMid = MidPoint(); snapPoints.append(ptMid); // 捕捉中线 XCurveSegment seg = this->GetCurve(); AcDbCurve *pCurve = seg.AsAcDbCurve(); if (pCurve != NULL) { pCurve->getOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds, viewXform); delete pCurve; } } return Acad::eOk; } // 取得所有的夹点 Acad::ErrorStatus TDbPipeCanal::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); Acad::ErrorStatus es=Acad::eOk; // es=TDbPipe::subGetGripPoints(gripPoints, osnapModes, geomIds); // cet 2010.6.9 del // cet 2010.6.9 add 删除标注点夹点 // TDbPipe::subGetGripPoints if(IsVertical() && Is(CURVE_LINE) && GetExplodeMode()==DRAW_2D) //立管 { XPoint ptMid = MidPoint(); ptMid.z=0; gripPoints.append(ptMid); } else { gripPoints.append(StartPoint()); gripPoints.append(EndPoint()); XPoint ptMid = MidPoint(); gripPoints.append(ptMid); } // TDbPipePrototype::subGetGripPoints if(!IsVertical() && g_bSPipeFDir) { XPoint ptMid = MidPoint(); double dDir(0); if(m_flowDir==TPipeSys::kFromEnd) dDir = ads_angle(GetEndPoint(), GetStartPoint()); else dDir = ads_angle(GetStartPoint(), GetEndPoint()); XPoint p1; ads_polar(ptMid, dDir, GetPScale()*2, p1); gripPoints.append(p1); } return es; } // 取得夹点说明 Acad::ErrorStatus TDbPipeCanal::GetGripText(int idx, CString &cs) const { Acad::ErrorStatus es=Acad::eOk; es = TDbPipe::GetGripText(idx,cs); return es; } // 从DWG读入数据: Acad::ErrorStatus TDbPipeCanal::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbPipe::dwgInFields(pFiler); if(es != Acad::eOk) return es; Adesk::UInt8 nVer; pFiler->readItem(&nVer); if(nVer>g_nVersion) {// Version is too new return Acad::eMakeMeProxy; } pFiler->readItem(&m_nWidth); pFiler->readItem(&m_nHeight); pFiler->readItem(&m_nSpare); pFiler->readItem(&m_idDoteLayer); pFiler->readItem(&m_dRate); pFiler->readUInt16(&m_nCanalType); pFiler->readUInt16(&m_nEntType); ReadString(pFiler,m_sSpare); return pFiler->filerStatus(); } Acad::ErrorStatus TDbPipeCanal::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbPipe::dwgOutFields(pFiler); if(es != Acad::eOk) return es; pFiler->writeItem(g_nVersion); pFiler->writeItem(m_nWidth); pFiler->writeItem(m_nHeight); pFiler->writeItem(m_nSpare); pFiler->writeItem(m_idDoteLayer); pFiler->writeItem(m_dRate); pFiler->writeItem(m_nCanalType); pFiler->writeItem(m_nEntType); pFiler->writeString(m_sSpare); return pFiler->filerStatus(); } Acad::ErrorStatus TDbPipeCanal::dxfInFields(AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es=Acad::eOk; es=TDbPipe::dxfInFields(pFiler); if(es!=Acad::eOk) return es; if (!pFiler->atSubclassData(_T("TDbPipeCanal"))) { return Acad::eBadDxfSequence; } resbuf rb; while((es==Acad::eOk) && ((es=pFiler->readResBuf(&rb))==Acad::eOk)) { switch (rb.restype) { case AcDb::kDxfXReal: m_nWidth=rb.resval.rreal; break; default: pFiler->pushBackItem(); es = Acad::eEndOfFile; break; } } if(es!=Acad::eEndOfFile) return Acad::eInvalidResBuf; return pFiler->filerStatus(); } Acad::ErrorStatus TDbPipeCanal::dxfOutFields(AcDbDxfFiler* pFiler) const { Acad::ErrorStatus es=Acad::eOk; es=TDbPipe::dxfOutFields(pFiler); assert(es==Acad::eOk); es=pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbPipeCanal")); assert(es==Acad::eOk); pFiler->writeDouble(AcDb::kDxfXReal, m_nWidth); return es; } void TDbPipeCanal::ResetDrawSpeed() { assertWriteEnabled(); double dSpeedLength=0, dSpeedSubMid=0;//初始化 if (m_nodeEnd.m_idNode.isValid()) { OPENOBJ_BEGIN(m_nodeEnd.m_idNode,AcDb::kForRead,TDbPipeNode,pNode); if(pNode!=NULL) { if(pNode->IsHidePipe()) { //是否节点遮挡管线 double dWidth = pNode->GetWidth(this); if (dWidth>1.0E-3) { dSpeedLength -= dWidth; dSpeedSubMid -= dWidth/2; } } } OPENOBJ_END(); } if (m_nodeStart.m_idNode.isValid()) { OPENOBJ_BEGIN(m_nodeStart.m_idNode,AcDb::kForRead,TDbPipeNode,pNode); if (pNode!=NULL) { if (pNode->IsHidePipe()) { double dWidth = pNode->GetWidth(this); if (dWidth>1.0E-3) { dSpeedLength -= dWidth; dSpeedSubMid += dWidth/2; } } } OPENOBJ_END(); } if(fabs(dSpeedLength)>1.0E-3 || fabs(dSpeedSubMid)>1.0E-3) { XCurveSegment cv=GetCurve(); cv.SetElevation(0);//设置为二维,z=0 double dLength = cv.GetLength(); m_dSpeedLength = dLength + dSpeedLength; m_dSpeedSubMid = dLength/2 + dSpeedSubMid; } else { m_dSpeedLength = 0; m_dSpeedSubMid = 0; } } // 通过管件附件打断的曲线,二维,z=0 void TDbPipeCanal::GetBrokenCurves(const XCurveSegment &cv, DList &lstCurve) const { lstCurve.Append(new XCurveSegment(cv)); return; } // 考虑遮挡的当前曲线,二维,z=0 void TDbPipeCanal::GetHideCurve(XCurveSegment& cvHide) const { XCurveSegment cvHideTemp=GetCurve(); cvHideTemp.SetElevation(0);//设置为二维,z=0 //该为将数据写入数据库加速二维显示速度 if (fabs(m_dSpeedLength)>1.0E-3 && fabs(m_dSpeedSubMid)>1.0E-3) { double dChordLength = cvHideTemp.GetChordLength(m_dSpeedLength); XPointDir2d ptSubMid; cvHideTemp.Polar(m_dSpeedSubMid,ptSubMid); cvHideTemp.GetSubSegment(ptSubMid,dChordLength,cvHide); return; } cvHide = cvHideTemp; } void TDbPipeCanal::ExplodeOrDrawPipeCanalCenLine(XExplodeDraw &dc) const { // cet 2016.8.15 add 有盖板不绘制中心线 if (GetCoverType() != 0) { return; } // 判断是否绘制中线 cet 2012.10.11 add TDbPsConfig *pConfig = GetDwgPsGlobal(AcDb::kForRead); if (pConfig != NULL && !pConfig->IsShowPipeCanalMidLine()) { pConfig->close(); return; } else if (pConfig != NULL) { pConfig->close(); } XCurveSegment cvHide=GetCurve();//二维,z=0 //绘制中心线 DList lstCurve; GetBrokenCurves(cvHide, lstCurve); int nCount = lstCurve.Length(); //2008-5-28 指定中心线图层,从而改变中心线的线形,这种方法不对,打印的时候仍然是实线 // SR 修改如下: 读取图层的线形,强制设置dc的线形,同时取消中心线图层 // 对于炸开,仍然采用图层 if(_tcsicmp(dc.Desc(), XExplodeStream::Descriptor())==0) { //另存旧版,炸开 2图层 AcDbObjectId idLayerOld=dc.GetLayerId(); AcDbObjectId idDoteLayer=m_idDoteLayer; if(idDoteLayer.isValid()) dc.SetLayer(idDoteLayer); dc.SetColorLayer(colorIndex(), idDoteLayer); for (int i=0; ilinetypeObjectId(); AcCmColor Color = pLayer->color(); int iColIdx = Color.colorIndex(); dc.SetColor(iColIdx); dc.SetLineType(idLineType); } OPENOBJ_END(); } for (int i=0; ilayerId(), AcDb::kForRead); if (player.openStatus() == Acad::eOk && player->isOff()) { return Acad::eOk; } XAcGiViewDraw &viewDraw = (XAcGiViewDraw &)dc; //垂直管线 XVector3D vtLocation=EndPoint()-StartPoint(); if(fabs(vtLocation.x)<1.0E-6 && fabs(vtLocation.y)<1.0E-6) //垂直管线 { return Acad::eOk; } //绘制中线 ExplodeOrDrawPipeCanalCenLine(dc); //绘制方沟上线和下线 ExplodeOrDrawPipeCanal(dc); return es; } AOLAPI double g_nAcadVer; Acad::ErrorStatus TDbPipeCanal::ExplodeOrDraw3d(XExplodeDraw &dc) const { //垂直管线 XVector3D vtLocation=EndPoint()-StartPoint(); if(fabs(vtLocation.x)<1.0E-6 && fabs(vtLocation.y)<1.0E-6) //垂直管线 { return Acad::eOk; } //绘制 Draw3dType(dc); return Acad::eOk; } //取动态属性显示数据 void TDbPipeCanal::GetTips(DList &lstInfo) const { if(IsHorizontal()) { lstInfo.Append(new TObjInfoUnit(_T("标高"), Dist2Str(GetStartPoint().z))); } else { lstInfo.Append(new TObjInfoUnit(_T("起点标高"), Dist2Str(GetStartPoint().z))); lstInfo.Append(new TObjInfoUnit(_T("终点标高"), Dist2Str(GetEndPoint().z))); } double nDist=0.0; getDistAtPoint(EndPoint(), nDist); lstInfo.Append(new TObjInfoUnit(_T("长度"), Dist2Str(nDist))); lstInfo.Append(new TObjInfoUnit(_T("宽度"), Dist2Str(m_nWidth))); lstInfo.Append(new TObjInfoUnit(_T("高度"), Dist2Str(m_nHeight))); } // 功能: 夹点操作 Acad::ErrorStatus TDbPipeCanal::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); Acad::ErrorStatus es=Acad::eOk; int nCount=indices.length(); int idx = indices[0]; if(idx == 2 && !IsVertical() && Is(CURVE_LINE)){ es=MoveGSPointsAt(indices,offset,TRUE); } else es=TDbPipePrototype::subMoveGripPointsAt(indices, offset); if(es!=Acad::eOk) return es; return es; } Acad::ErrorStatus TDbPipeCanal::MoveGSPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset, BOOL bGrip) { Acad::ErrorStatus es=Acad::eOk; AcGeVector3d vtOffset=offset; AcGeMatrix3d mat; mat.setToTranslation(vtOffset); BOOL bApply=objectId().isValid(); AcGeVector3d vtPipe(EndPoint() - StartPoint()); XPoint ptStartOld = StartPoint(); XPoint ptEndOld = EndPoint(); Transform(mat, bApply,bGrip); if(bApply == NULL || !vtOffset.isPerpendicularTo(vtPipe)) //如果平移向量不垂直于管线,就返回 return es; //联动修改所接管线 AcDbObjectId id1 = GetNode(0); AcDbObjectId id2 = GetNode(1); if (id1.isValid() && id2.isValid()) { OPENOBJ_BEGIN(id1,AcDb::kForRead,TDbPipeNode,pNode); if(pNode!=NULL) { // 节点 if(pNode->IsAutoLiving()){ // 需自动生成的节点 if(pNode->GetInterfaceNum() == 2){ XPoint ptLoc = pNode->GetLocation(); for(int j=0; j<2; j++) { // 接口 const AcDbObjectId &idPipe=pNode->GetIPipe(j); if(idPipe != objectId()) { XPoint ptStart, ptEnd; OPENOBJ_BEGIN(idPipe,AcDb::kForWrite,TDbPipeCanal,pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { ptStart = pPipe->StartPoint(); ptEnd = pPipe->EndPoint(); if(ptLoc == ptStart){ XPoint ptOffset=ptStart+offset; pPipe->SetStartPoint(ptOffset); } else if(ptLoc == ptEnd){ XPoint ptOffset=ptEnd+offset; pPipe->SetEndPoint(ptOffset); } } OPENOBJ_END(); } } } } } OPENOBJ_END(); //同上,代码直接COPY OPENOBJ_BEGIN(id2,AcDb::kForRead,TDbPipeNode,pNode); if(pNode!=NULL) { // 节点 if(pNode->IsAutoLiving()){ // 需自动生成的节点 if(pNode->GetInterfaceNum() == 2){ XPoint ptLoc = pNode->GetLocation(); for(int j=0; j<2; j++) { // 接口 const AcDbObjectId &idPipe=pNode->GetIPipe(j); if(idPipe != objectId()) { XPoint ptStart, ptEnd; OPENOBJ_BEGIN(idPipe,AcDb::kForWrite,TDbPipeCanal,pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { ptStart = pPipe->StartPoint(); ptEnd = pPipe->EndPoint(); if(ptLoc == ptStart){ XPoint ptOffset=ptStart+offset; pPipe->SetStartPoint(ptOffset); } else if(ptLoc == ptEnd){ XPoint ptOffset=ptEnd+offset; pPipe->SetEndPoint(ptOffset); } } OPENOBJ_END(); } } } } } OPENOBJ_END(); } return es; } //调整方沟位置 void TDbPipeCanal::ExplodeOrDrawPipeCanal(XExplodeDraw &dc) const { // ExplodeOrDrawCanalType1(dc); switch(m_nCanalType) { case Canal_Corner1: ExplodeOrDrawCanalType1(dc); break; case Canal_Corner2: case Canal_Corner3: case Canal_Corner4: case Canal_Corner5: ExplodeOrDrawCanalType2(dc); break; default: break; } } void TDbPipeCanal::ExplodeOrDrawCanalType1(XExplodeDraw &dc) const { // cet 2016.8.15 modify 重新实现方沟绘制 // //得到方沟两端节点 // AcDbObjectId idNode1(NULL), idNode2(NULL); // AcDbObjectIdArray arIds; // idNode1 = GetNode(0); // idNode2 = GetNode(1); // arIds.append(idNode1); // arIds.append(idNode2); // AcGePoint3d pt1,pt2,pt3,pt4; // //分别得到方沟的一端上两点 // AcArray map1,map2; // GetCannalPts(idNode1,pt1,pt2,map1); // GetCannalPts(idNode2,pt3,pt4,map2); // // XCurveSegment cenCurve = GetCurve(); // XCurveSegment segUp,segDown; // XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge()); // segUp = segDir.Offset(m_nWidth/2, LS_FINITE); // segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); // segUp.SetPoints(pt1,pt3); // segDown.SetPoints(pt2,pt4); // double dWeight = GetPScale()*m_dPipeWeight; // if (g_bPipeWeight) // { // DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale()); // DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale()); // } // else // { // dc << segUp; // dc << segDown; // } XCurveSegment cenCurve = GetCurve(); XCurveSegment segUp,segDown; XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge()); segUp = segDir.Offset(m_nWidth/2, LS_FINITE); segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); // 起点方沟边线连接点 XPoint pt1 = segUp.StartPoint(); XPoint pt2 = segDown.StartPoint(); OPENOBJ_BEGIN(GetNode(0), AcDb::kForRead, TDbPipeFitting, pFitting); if (pFitting != NULL) { TDbCanalFitting fitting(pFitting); fitting.IntersectWith(this->objectId(), pt1, pt2); } OPENOBJ_END(); // 终点方沟边线连接点 XPoint pt3 = segUp.EndPoint(); XPoint pt4 = segDown.EndPoint(); OPENOBJ_BEGIN(GetNode(1), AcDb::kForRead, TDbPipeFitting, pFitting); if (pFitting != NULL) { TDbCanalFitting fitting(pFitting); fitting.IntersectWith(this->objectId(), pt4, pt3); } OPENOBJ_END(); segUp.SetPoints(pt1, pt3); segDown.SetPoints(pt2, pt4); // 设置线型 AcDbObjectId idLineStyle = GetLinetypeIdFromString(_T("CanalDASH"), database()); // 给排水线型(linetype.dbf中)绘制方沟时已加载 if (idLineStyle.isNull()) { idLineStyle = InitLineType(_T("DASH"), database()); } AcDbObjectId idOldStyle = dc.GetLineTypeId(); if (IsBlineDrain() && idLineStyle.isValid()) // 暗沟 { dc.SetLineType(idLineStyle); } // 线宽 double dWeight = GetPScale() * m_dPipeWeight; if (!IsShowPipeCanalLineWeight(this->database())) { dWeight = 0.0; } // 绘制边线 DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale()); DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale()); // 闭合端点 cet 2018.1.16 add if (LinkedPipeCanalNum(0) == 0 && IsClosePipeCancalPointEnd()) // 闭合起点 { XCurveSegment seg(pt1, pt2, 0.0); DrawWeight(dc, dWeight, seg, colorIndex(), linetypeScale()); } if (LinkedPipeCanalNum(1) == 0 && IsClosePipeCancalPointEnd()) // 闭合终点 { XCurveSegment seg(pt3, pt4, 0.0); DrawWeight(dc, dWeight, seg, colorIndex(), linetypeScale()); } // 恢复线型 if (IsBlineDrain() && idLineStyle.isValid()) // 暗沟 { dc.SetLineType(idOldStyle); } // 绘制盖板 DrawCover(dc, segUp, segDown); } void TDbPipeCanal::ExplodeOrDrawCanalType2(XExplodeDraw &dc) const { // cet 2016.8.15 modify 重新绘制方沟 // //得到方沟两端节点 // AcDbObjectId idNode1(NULL), idNode2(NULL); // AcDbObjectIdArray arIds; // idNode1 = GetNode(0); // idNode2 = GetNode(1); // arIds.append(idNode1); // arIds.append(idNode2); // // AcGePoint3d pt1,pt2,pt3,pt4; // //分别得到方沟的一端上两点 // AcArray map1,map2; // GetCannalPts(idNode1,pt1,pt2,map1); // GetCannalPts(idNode2,pt3,pt4,map2); // // double dWeight = GetPScale()*m_dPipeWeight; // XCurveSegment cenCurve = GetCurve(); // XCurveSegment segUp,segDown; // XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge()); // segUp = segDir.Offset(m_nWidth/2, LS_FINITE); // segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); // segUp.SetPoints(pt1,pt3); // segDown.SetPoints(pt2,pt4); // // double dAng = 0.0; // // if (m_nCanalType == Canal_Corner4 || m_nCanalType == Canal_Corner5) // // dAng = -PI/4; // if (g_bPipeWeight) // { // DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale()); // DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale()); // for (int i = 0; i < map1.length(); ++i) // { // XCurveSegment segCorn(map1[i].pair.first,map1[i].pair.second,map1[i].dAng); // DrawWeight(dc, dWeight, segCorn, colorIndex(), linetypeScale()); // } // // for (int j = 0; j < map2.length(); ++j) // { // XCurveSegment segCorn(map2[j].pair.first,map2[j].pair.second,map2[j].dAng); // DrawWeight(dc, dWeight, segCorn, colorIndex(), linetypeScale()); // } // } // else // { // dc << segUp; // dc << segDown; // for (int i = 0; i < map1.length(); ++i) // { // XCurveSegment segCorn(map1[i].pair.first,map1[i].pair.second,map1[i].dAng); // dc << segCorn; // } // // for (int j = 0; j < map2.length(); ++j) // { // XCurveSegment segCorn(map2[j].pair.first,map2[j].pair.second,map2[j].dAng); // dc << segCorn; // } // } XCurveSegment cenCurve = GetCurve(); XCurveSegment segUp,segDown; XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge()); segUp = segDir.Offset(m_nWidth/2, LS_FINITE); segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); // 起点方沟边线连接点 int nSLinkedOtherCanalsNum = LinkedPipeCanalNum(0); int nELinkedOtherCanalsNum = LinkedPipeCanalNum(1); bool bSLinkedOtherCanals = nSLinkedOtherCanalsNum > 0; bool bELinkedOtherCanals = nELinkedOtherCanalsNum > 0; XPoint pt1 = segUp.StartPoint(); XPoint pt2 = segDown.StartPoint(); OPENOBJ_BEGIN(GetNode(0), AcDb::kForRead, TDbPipeFitting, pFitting); if (pFitting != NULL) { TDbCanalFitting fitting(pFitting); if (fitting.IntersectWith(this->objectId(), pt1, pt2)) { XPoint pt11 = pt1; XPoint pt22 = pt2; if (segUp.Is(CURVE_LINE)) { AcGeVector3d vtDir1 = segUp.EndPoint() - segUp.StartPoint(); AcGeVector3d vtDir2 = segDown.EndPoint() - segDown.StartPoint(); vtDir1.z = 0.0; vtDir2.z = 0.0; vtDir1.normalize(); vtDir2.normalize(); if (bELinkedOtherCanals && bSLinkedOtherCanals && segUp.GetLength() > m_nSpare * 2 + 0.001 && segDown.GetLength() > m_nSpare * 2 + 0.001 || // 两端连接着方沟,倒角半径的2倍应小于曲线长度 (bSLinkedOtherCanals ^ bELinkedOtherCanals) && segUp.GetLength() > m_nSpare + 0.001 && segDown.GetLength() > m_nSpare + 0.001) // 一端连接着方沟,倒角半径应大于曲线长度 { pt1 += vtDir1 * m_nSpare; pt2 += vtDir2 * m_nSpare; } } else { if (bELinkedOtherCanals && bSLinkedOtherCanals && segUp.GetLength() > m_nSpare * 2 + 0.001 && segDown.GetLength() > m_nSpare * 2 + 0.001 || // 两端连接着方沟,倒角半径的2倍应小于曲线长度 (bSLinkedOtherCanals ^ bELinkedOtherCanals) && segUp.GetLength() > m_nSpare + 0.001 && segDown.GetLength() > m_nSpare + 0.001) // 一端连接着方沟,倒角半径应大于曲线长度 { XArc arcUp = segUp.GetArc(); XArc arcDown = segDown.GetArc(); AcGeVector3d vtDirUp = pt1 - arcUp.GetCenterPt(); AcGeVector3d vtDirDown = pt2 - arcDown.GetCenterPt(); vtDirUp.normalize(); vtDirDown.normalize(); double dAngleUp = m_nSpare / arcUp.GetRadius(); double dAngleDown = m_nSpare / arcDown.GetRadius(); vtDirUp.rotateBy(dAngleUp, AcGeVector3d::kZAxis); vtDirDown.rotateBy(dAngleDown, AcGeVector3d::kZAxis); pt1 = arcUp.GetCenterPt() + vtDirUp * arcUp.GetRadius(); pt2 = arcDown.GetCenterPt() + vtDirDown * arcDown.GetRadius(); } } // 样式2和样式3弯头连接时 (端点只和一个方沟有连接),只有一条边线需要创建倒角半径 int nRet = NeedModifyInt(0, pFitting); if (nRet == 1) { pt1 = pt11; } else if (nRet == 2) { pt2 = pt22; } } } OPENOBJ_END(); // 终点方沟边线连接点 XPoint pt3 = segUp.EndPoint(); XPoint pt4 = segDown.EndPoint(); OPENOBJ_BEGIN(GetNode(1), AcDb::kForRead, TDbPipeFitting, pFitting); if (pFitting != NULL) { TDbCanalFitting fitting(pFitting); if (fitting.IntersectWith(this->objectId(), pt4, pt3)) { XPoint pt33 = pt3; XPoint pt44 = pt4; if (segUp.Is(CURVE_LINE)) { AcGeVector3d vtDir1 = segUp.EndPoint() - segUp.StartPoint(); AcGeVector3d vtDir2 = segDown.EndPoint() - segDown.StartPoint(); vtDir1.z = 0.0; vtDir2.z = 0.0; vtDir1.normalize(); vtDir2.normalize(); if (bELinkedOtherCanals && bSLinkedOtherCanals && segUp.GetLength() > m_nSpare * 2 + 0.001 && segDown.GetLength() > m_nSpare * 2 + 0.001 || // 两端连接着方沟,倒角半径的2倍应小于曲线长度 (bSLinkedOtherCanals ^ bELinkedOtherCanals) && segUp.GetLength() > m_nSpare + 0.001 && segDown.GetLength() > m_nSpare + 0.001) // 一端连接着方沟,倒角半径应大于曲线长度 { pt3 -= vtDir1 * m_nSpare; pt4 -= vtDir2 * m_nSpare; } } else { XArc arcUp = segUp.GetArc(); XArc arcDown = segDown.GetArc(); AcGeVector3d vtDirUp = pt3 - arcUp.GetCenterPt(); AcGeVector3d vtDirDown = pt4 - arcDown.GetCenterPt(); vtDirUp.normalize(); vtDirDown.normalize(); double dAngleUp = m_nSpare / arcUp.GetRadius(); double dAngleDown = m_nSpare / arcDown.GetRadius(); vtDirUp.rotateBy(-dAngleUp, AcGeVector3d::kZAxis); vtDirDown.rotateBy(-dAngleDown, AcGeVector3d::kZAxis); pt3 = arcUp.GetCenterPt() + vtDirUp * arcUp.GetRadius(); pt4 = arcDown.GetCenterPt() + vtDirDown * arcDown.GetRadius(); } // 样式2和样式3弯头连接时 (端点只和一个方沟有连接),只有一条边线需要创建倒角半径 int nRet = NeedModifyInt(1, pFitting); if (nRet == 1) { pt3 = pt33; } else if (nRet == 2) { pt4 = pt44; } } } OPENOBJ_END(); segUp.SetPoints(pt1, pt3); segDown.SetPoints(pt2, pt4); AcDbObjectId idLineStyle = GetLinetypeIdFromString(_T("CanalDASH"), database()); // 给排水线型(linetype.dbf中)绘制方沟时已加载 if (idLineStyle.isNull()) { idLineStyle = InitLineType(_T("DASH"), database()); } AcDbObjectId idOldStyle = dc.GetLineTypeId(); if (IsBlineDrain() && idLineStyle.isValid()) // 暗沟 { dc.SetLineType(idLineStyle); } double dWeight = GetPScale()*m_dPipeWeight; if (!IsShowPipeCanalLineWeight(this->database())) { dWeight = 0.0; } DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale()); DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale()); if (IsBlineDrain() && idLineStyle.isValid()) // 暗沟 { dc.SetLineType(idOldStyle); } // 绘制盖板 DrawCover(dc, segUp, segDown); } //对方沟按逆时针排序 void TDbPipeCanal::SortPipeCanal(const AcGePoint3d &ptOr,const AcDbObjectIdArray &arIds,AcArray > &arSeg) const { AcDbObjectId idSelf = GetSelfObjectId(); AcGeMatrix3d mat; ads_matrix matAds; GetOffsetMatrix(idSelf, mat); AcArray > arSegSort; for (int i = 0; i < arIds.length(); ++i) { if (idSelf == arIds[i]) { XCurveSegment seg; seg = GetCurve(); XCurveSegment segUp, segDown; XDirectionCurve segDir(seg.StartPoint(), seg.EndPoint(), seg.GetBulge()); segUp = segDir.Offset(GetWidth()/2, LS_FINITE); segDown = segDir.Offset(-GetWidth()/2, LS_FINITE); arSegSort.append(segUp); arSegSort.append(segDown); } else { if (arIds[i].isValid()) { //防止在三维状态下在实体内部自己打开自己 OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal != NULL) { XCurveSegment seg; seg = pCanal->GetCurve(); memcpy(matAds, &mat, sizeof(AcGeMatrix3d)); seg.TransformBy(matAds); XCurveSegment segUp, segDown; XDirectionCurve segDir(seg.StartPoint(), seg.EndPoint(), seg.GetBulge()); segUp = segDir.Offset(pCanal->GetWidth()/2, LS_FINITE); segDown = segDir.Offset(-pCanal->GetWidth()/2, LS_FINITE); arSegSort.append(segUp); arSegSort.append(segDown); } OPENOBJ_END(); } } } XPoint pt = ptOr; std::map map; double dPar = 0.0; std::vector vecT; AcDbCircle circle(ptOr,AcGeVector3d::kZAxis,m_nWidth/5); for (int j = 0; j < arSegSort.length(); ++j) { AcGePoint3d ptNear; circle.getClosestPointTo(arSegSort[j].MidPoint(),AcGeVector3d::kZAxis,ptNear); circle.getParamAtPoint(ptNear,dPar); map[dPar] = arSegSort[j]; vecT.push_back(dPar); } std::sort(vecT.begin(),vecT.end()); for (UINT k = 0; k < vecT.size(); ++k) { double dT = vecT[k]; XCurveSegment seg = map[dT]; arSeg.append(seg); } int nLen = arSeg.length(); } //求排序后方沟的交点 void TDbPipeCanal::GetInterPts(const AcArray > &arSeg,AcArray &arPts,AcArray &map1) const { BOOL bIsInter = FALSE; XPoint ptInter1,ptInter2; if (arSeg.length() > 1) { int nNext = 0; for (int i = 0; i < arSeg.length(); i++) { if (i != arSeg.length() - 1) nNext = i + 1; else nNext = 0; AcGeVector3d vt1 = arSeg[i].StartPoint() - arSeg[i].EndPoint(); AcGeVector3d vt2 = arSeg[nNext].StartPoint() - arSeg[nNext].EndPoint(); if (vt1.isParallelTo(vt2)) continue; AcGePoint3dArray arPtsT; AcGePoint3d ptS = arSeg[i].StartPoint(); AcGePoint3d ptST = arSeg[nNext].StartPoint(); AcGePoint3d ptE = arSeg[i].EndPoint(); AcGePoint3d ptET = arSeg[nNext].EndPoint(); ptS.z = 0.0; ptE.z = 0.0; ptST.z = 0.0; ptET.z = 0.0; AcDbLine line1(ptS,ptE); AcDbLine line2(ptST,ptET); line1.intersectWith(&line2,AcDb::kOnBothOperands,arPtsT); if (arPtsT.length() > 0) { if(m_nCanalType == Canal_Corner1) arPts.append(arPtsT[0]); else if (m_nCanalType == Canal_Corner2 || m_nCanalType == Canal_Corner3 || m_nCanalType == Canal_Corner4 || m_nCanalType == Canal_Corner5) { //得到类型2的交点 GetCorner2InterPts(arSeg[i],arSeg[nNext],arPtsT[0],arSeg.length(),arPts,map1); } } else { if (arSeg.length() == 4) { //弯头 AcGePoint3dArray arPtsT; AcGePoint3d ptS = arSeg[i].StartPoint(); AcGePoint3d ptST = arSeg[nNext].StartPoint(); AcGePoint3d ptE = arSeg[i].EndPoint(); AcGePoint3d ptET = arSeg[nNext].EndPoint(); ptS.z = 0.0; ptE.z = 0.0; ptST.z = 0.0; ptET.z = 0.0; AcDbLine line1(ptS,ptE); AcDbLine line2(ptST,ptET); if (line1.intersectWith(&line2,AcDb::kExtendBoth,arPtsT) == Acad::eOk) { if(m_nCanalType == Canal_Corner1 || m_nCanalType == Canal_Corner3 || m_nCanalType == Canal_Corner4) arPts.append(arPtsT[0]); else if (m_nCanalType == Canal_Corner2 || m_nCanalType == Canal_Corner5) { //得到类型2的交点 GetCorner2InterPts(arSeg[i],arSeg[nNext],arPtsT[0],arSeg.length(),arPts,map1); } } } } } } } void TDbPipeCanal::GetInterPts(const AcArray > &arSeg,AcArray &arPts) const { BOOL bIsInter = FALSE; XPoint ptInter1,ptInter2; if (arSeg.length() > 1) { int nNext = 0; for (int i = 0; i < arSeg.length(); i++) { if (i != arSeg.length() - 1) nNext = i + 1; else nNext = 0; AcGeVector3d vt1 = arSeg[i].StartPoint() - arSeg[i].EndPoint(); AcGeVector3d vt2 = arSeg[nNext].StartPoint() - arSeg[nNext].EndPoint(); if (vt1.isParallelTo(vt2)) continue; AcGePoint3dArray arPtsT; AcGePoint3d ptS = arSeg[i].StartPoint(); AcGePoint3d ptST = arSeg[nNext].StartPoint(); AcGePoint3d ptE = arSeg[i].EndPoint(); AcGePoint3d ptET = arSeg[nNext].EndPoint(); ptS.z = 0.0; ptE.z = 0.0; ptST.z = 0.0; ptET.z = 0.0; AcDbLine line1(ptS,ptE); AcDbLine line2(ptST,ptET); line1.intersectWith(&line2,AcDb::kOnBothOperands,arPtsT); if (arPtsT.length() > 0) { arPts.append(arPtsT[0]); } else { if (arSeg.length() == 4) { //弯头 AcGePoint3dArray arPtsT; AcGePoint3d ptS = arSeg[i].StartPoint(); AcGePoint3d ptST = arSeg[nNext].StartPoint(); AcGePoint3d ptE = arSeg[i].EndPoint(); AcGePoint3d ptET = arSeg[nNext].EndPoint(); ptS.z = 0.0; ptE.z = 0.0; ptST.z = 0.0; ptET.z = 0.0; AcDbLine line1(ptS,ptE); AcDbLine line2(ptST,ptET); if (line1.intersectWith(&line2,AcDb::kExtendBoth,arPtsT) == Acad::eOk) { arPts.append(arPtsT[0]); } } } } } } //调整方沟位置 void TDbPipeCanal::ChangePipeCanalPosition(const AcArray &arPts,const AcGePoint3d &ptCen,int nSegLen,AcGePoint3d &pt1,AcGePoint3d &pt2) const { double dWeight = GetPScale()*m_dPipeWeight; XCurveSegment cenCurve = GetCurve(); XCurveSegment segUp,segDown; XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge()); segUp = segDir.Offset(m_nWidth/2, LS_FINITE); segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); AcDbLine lineUp(segUp.StartPoint(),segUp.EndPoint()); AcDbLine lineDown(segDown.StartPoint(),segDown.EndPoint()); if (lineUp.startPoint().distanceTo(ptCen) > lineUp.endPoint().distanceTo(ptCen)) pt1 = lineUp.endPoint(); else pt1 = lineUp.startPoint(); if (lineDown.startPoint().distanceTo(ptCen) > lineDown.endPoint().distanceTo(ptCen)) pt2 = lineDown.endPoint(); else pt2 = lineDown.startPoint(); AcGePoint3d ptS = lineUp.startPoint(); AcGePoint3d ptST = lineDown.startPoint(); AcGePoint3d ptE = lineUp.endPoint(); AcGePoint3d ptET = lineDown.endPoint(); ptS.z = 0.0; ptE.z = 0.0; ptST.z = 0.0; ptET.z = 0.0; lineUp.setStartPoint(ptS); lineUp.setEndPoint(ptE); lineDown.setStartPoint(ptST); lineDown.setEndPoint(ptET); for (int i = 0; i < arPts.length(); ++i) { AcGePoint3d ptNear; //交点个数为2,边数为4表示生成弯头 //交点个数为4表示四通 AcGePoint3d ptTt = arPts[i]; switch(m_nCanalType) { case Canal_Corner1: if (arPts.length() == 2 && nSegLen == 4) lineUp.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue); else lineUp.getClosestPointTo(arPts[i],ptNear); break; case Canal_Corner2: case Canal_Corner3: case Canal_Corner4: case Canal_Corner5: if (arPts.length() == 3 && nSegLen == 4) lineUp.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue); else lineUp.getClosestPointTo(arPts[i],ptNear); break; default: break; } if (arPts[i].distanceTo(ptNear) < 1e-3) { pt1 = arPts[i]; } switch(m_nCanalType) { case Canal_Corner1: if (arPts.length() == 2 && nSegLen == 4) lineDown.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue); else lineDown.getClosestPointTo(arPts[i],ptNear); break; case Canal_Corner2: case Canal_Corner3: case Canal_Corner4: case Canal_Corner5: if (arPts.length() == 3 && nSegLen == 4) lineDown.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue); else lineDown.getClosestPointTo(arPts[i],ptNear); break; default: break; } if (arPts[i].distanceTo(ptNear) < 1e-3) { pt2 = arPts[i]; } } } //得到NODE方向方沟两点 void TDbPipeCanal::GetCannalPts(const AcDbObjectId &id,AcGePoint3d &pt1,AcGePoint3d &pt2,AcArray &map1) const { if (id.isValid()) { //通过节点得到几段线 AcDbObjectIdArray arCanal; OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeNode, pNode); if(pNode) { int num = pNode->GetInterfaceNum(); if (num > 0) { for (int i = 0; i < num; ++i) { TPipeInterface inter; // pNode->GetInterface(i,inter); AcDbObjectId id = pNode->GetIPipe(i); arCanal.append(id); } if (num > 3) { FilterCannal(arCanal); } //将线按逆时针排序 AcArray > arSeg; SortPipeCanal(pNode->GetLocation(),arCanal,arSeg); //求出排序后线的交点 AcArray arPts; GetInterPts(arSeg,arPts,map1); //调整方沟位置 ChangePipeCanalPosition(arPts,pNode->GetLocation(),arSeg.length(),pt1,pt2); // 如果连接点为2则判断是否要添加变径条件:1,vt 2,width if (num == 2 && arPts.length() == 0) { double dLen = 0.0;//变径长度 = b1+b2 if (MakesureCreateReducer(arCanal,dLen)) ChangePipeCanalPosition(arCanal,id,pNode->GetLocation(),dLen,pt1,pt2,map1); } } } OPENOBJ_END(); } } void TDbPipeCanal::ChangePipeCanalPosition(const AcDbObjectIdArray& arId,const AcDbObjectId& idNode,const AcGePoint3d& ptNodeLoc,double dLen,AcGePoint3d& pt1,AcGePoint3d& pt2,AcArray &map1) const { map1.setLogicalLength(0); if (arId.length() != 2) return; AcDbObjectId id1 = GetNode(0); AcDbObjectId id2 = GetNode(1); if (!id1.isValid() || !id2.isValid()) { return; } // 处理连接点 AcGeVector3d vtHor; AcGePoint3d ptT; if (id1 == idNode) { OPENOBJ_BEGIN(id2, AcDb::kForRead, TDbPipeNode, pNode); if (pNode) { ptT = pNode->GetLocation(); } OPENOBJ_END(); vtHor = ptT - ptNodeLoc; vtHor.normalize(); pt1 += vtHor * dLen / 2; pt2 += vtHor * dLen / 2; } else if (id2 == idNode) { OPENOBJ_BEGIN(id1, AcDb::kForRead, TDbPipeNode, pNode); if (pNode) { ptT = pNode->GetLocation(); } OPENOBJ_END(); vtHor = ptT - ptNodeLoc; vtHor.normalize(); pt1 += vtHor * dLen / 2; pt2 += vtHor * dLen / 2; } // 处理变径的边 double dWidth = 0.0; if (!GetAnotherCanalWidth(ptT,ptNodeLoc,arId,dWidth)) return; AcGeVector3d vtVer = vtHor; vtVer.rotateBy(PI / 2,AcGeVector3d::kZAxis); vtVer.normalize(); AcGePoint3d ptT1,ptT2; ptT1 = ptNodeLoc - vtVer * dWidth / 2; ptT1 -= vtHor * dLen / 2; ptT2 = ptNodeLoc + vtVer * dWidth / 2; ptT2 -= vtHor * dLen / 2; AppendMap(pt1,ptT1,ptT2,map1); AppendMap(pt2,ptT1,ptT2,map1); } //添加映射 void TDbPipeCanal::AppendMap(const AcGePoint3d& ptBase,const AcGePoint3d& pt1,const AcGePoint3d& pt2,AcArray &map1) const { double dLen1 = ptBase.distanceTo(pt1); double dLen2 = ptBase.distanceTo(pt2); std::pair pair; pair.first = ptBase; if (dLen1 > dLen2) pair.second = pt2; else pair.second = pt1; CornerLine corner; corner.pair = pair; corner.dAng = 0.0; map1.append(corner); } //得到另一个管子的宽度 BOOL TDbPipeCanal::GetAnotherCanalWidth(const AcGePoint3d& pt1,const AcGePoint3d& pt2,const AcDbObjectIdArray& arId,double& dWidth) const { BOOL bSuc = FALSE; AcDbObjectId idT; AcGePoint3d ptS,ptE; for (int i = 0;i < arId.length();i++) { if (arId[i].isValid()) { OPENOBJ_BEGIN(arId[i], AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal) { ptS = pCanal->StartPoint(); ptE = pCanal->EndPoint(); } OPENOBJ_END(); if (pt1.distanceTo(ptS) < 1e-3 && pt2.distanceTo(ptE) < 1e-3 ) { idT = arId[i]; bSuc = TRUE; break; } else if (pt1.distanceTo(ptE) < 1e-3 && pt2.distanceTo(ptS) < 1e-3 ) { idT = arId[i]; bSuc = TRUE; break; } } } AcDbObjectId idOther; AcDbObjectIdArray arT; if (bSuc) { arT.append(arId); arT.remove(idT); if (arT.length() > 0) idOther = arT[0]; else bSuc = FALSE; } if (bSuc) { if (idOther.isValid()) { OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal) { dWidth = pCanal->m_nWidth; } OPENOBJ_END(); } } return dWidth > 0; } //是否创建变径 BOOL TDbPipeCanal::MakesureCreateReducer(const AcDbObjectIdArray& arId,double& dTotal) const { if (arId.length() != 2) return FALSE; AcGeVector3d vt1,vt2; double dB1 = 0.0,dB2 = 0.0; if (arId[0].isValid()) { OPENOBJ_BEGIN(arId[0], AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal) { dB1 = pCanal->m_nWidth; vt1 = pCanal->EndPoint() - pCanal->StartPoint(); vt1.normalize(); } OPENOBJ_END(); } if (arId[1].isValid()) { OPENOBJ_BEGIN(arId[1], AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal) { dB2 = pCanal->m_nWidth; vt2 = pCanal->EndPoint() - pCanal->StartPoint(); vt2.normalize(); } OPENOBJ_END(); } if (fabs(dB1-dB2) < 1e-3)//等宽 return FALSE; if (!vt1.isParallelTo(vt2))//不平行 return FALSE; dTotal = dB1 + dB2; return TRUE; } void TDbPipeCanal::GetCannalPts(const AcDbObjectId &id,AcGePoint3d &pt1,AcGePoint3d &pt2) const { if (id.isValid()) { //通过节点得到几段线 AcDbObjectIdArray arCanal; OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeNode, pNode); if(pNode) { int num = pNode->GetInterfaceNum(); if (num > 0) { for (int i = 0; i < num; ++i) { TPipeInterface inter; // pNode->GetInterface(i,inter); AcDbObjectId id = pNode->GetIPipe(i); arCanal.append(id); } if (num > 3) { FilterCannal(arCanal); } //将线按逆时针排序 AcArray > arSeg; SortPipeCanal(pNode->GetLocation(),arCanal,arSeg); //求出排序后线的交点 AcArray arPts; GetInterPts(arSeg,arPts); //调整方沟位置 ChangePipeCanalPositionNor(arPts,pNode->GetLocation(),arSeg.length(),pt1,pt2); } } OPENOBJ_END(); } } //过滤掉无用的方沟 /* BOOL TDbPipeCanal::FilterCannal(AcDbObjectIdArray &arIds) const { BOOL bFilter = FALSE; PickSet ssDel(SS_FREE); for (int i = 0; i < arIds.length(); ++i) { if (arIds[i].isValid()) { OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal != NULL) { XCurveSegment seg1 = pCanal->GetCurve(); for (int j = 0; j < arIds.length(); ++j) { if (j == i) continue; OPENOBJ_BEGIN(arIds[j], AcDb::kForRead, TDbPipeCanal, pCanT); if (pCanT != NULL) { XCurveSegment seg2 = pCanT->GetCurve(); AcGeVector3d vt1 = seg1.StartPoint() - seg1.EndPoint(); AcGeVector3d vt2 = seg2.StartPoint() - seg2.EndPoint(); if (!vt1.isParallelTo(vt2)) { XCurveSegment segUp,segDown; XDirectionCurve segDir(seg2.StartPoint(), seg2.EndPoint(), seg2.bulge); segUp = segDir.Offset(m_nWidth/2, LS_FINITE); segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); XPoint pt1,pt2; AcGePoint3dArray arPts; AcDbLine line1(seg1.StartPoint(),seg1.EndPoint()); AcDbLine line2(segUp.StartPoint(),segUp.EndPoint()); AcDbLine line3(segDown.StartPoint(),segDown.EndPoint()); line1.intersectWith(&line2,AcDb::kExtendArg,arPts); line1.intersectWith(&line3,AcDb::kExtendArg,arPts); if (arPts.length() < 1) { ssDel += arIds[i]; ssDel += pCanal->GetNode(0); ssDel += pCanal->GetNode(1); bFilter = TRUE; } } } OPENOBJ_END(); } } OPENOBJ_END(); } } for (long l = 0; l < ssDel.Length(); ++l) ssDel[l].Erase(); return bFilter; } */ //过滤掉无用的方沟 BOOL TDbPipeCanal::FilterCannal(AcDbObjectIdArray &arIds) const { BOOL bFilter = FALSE; PickSet ssDel(SS_FREE); double dB = 0.0; for (int i = 0; i < arIds.length(); ++i) { if (arIds[i].isValid()) { OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal != NULL) { XCurveSegment seg1 = pCanal->GetCurve(); dB = pCanal->GetWidth(); if (seg1.GetLength() < dB/2) { ssDel += pCanal->objectId(); ssDel += pCanal->GetNode(0); ssDel += pCanal->GetNode(1); bFilter = TRUE; } } OPENOBJ_END(); } } for (long l = 0; l < ssDel.Length(); ++l) ssDel[l].Erase(); return bFilter; } //得到类型2的交点 void TDbPipeCanal::GetCorner2InterPts(const XCurveSegment &seg1,const XCurveSegment &seg2,const AcGePoint3d &pt,int nSegCount,AcGePoint3dArray &arPts,AcArray &map1) const { XPoint ptInter = pt; AcGeVector3d vtDir1,vtDir2; AcGePoint3d ptIns1,ptIns2; BOOL bMoreLen = FALSE; //用来判断弯头的弧线是朝内还是朝外 AcGeVector3d vtT; XCurveSegment seg1T,seg2T; AcGePoint3d ptSegS1,ptSegE1,ptSegS2,ptSegE2; //将曲线Z坐标置0 ptSegS1 = seg1.StartPoint(); ptSegS2 = seg2.StartPoint(); ptSegE1 = seg1.EndPoint(); ptSegE2 = seg2.EndPoint(); ptSegS1.z = 0; ptSegS2.z = 0; ptSegE1.z = 0; ptSegE2.z = 0; seg1T.SetPoints(ptSegS1,ptSegE1); seg2T.SetPoints(ptSegS2,ptSegE2); if (seg1T.StartPoint().Distance(ptInter) > seg1T.EndPoint().Distance(ptInter)) { vtDir1 = seg1T.EndPoint() - seg1T.StartPoint(); vtT = seg1T.StartPoint() - pt; } else { vtDir1 = seg1T.StartPoint() - seg1T.EndPoint(); vtT = seg1T.EndPoint() - pt; } if (vtT.length() > seg1T.GetLength()) bMoreLen = TRUE; XPoint ptT1,ptT2; vtDir1.normalize(); //判断是否是无交点的拐角 if (seg1T.Intersection(seg2T,ptT1,ptT2) == 0) // ptIns1 = pt - vtDir1*m_nWidth*tan(PI/8); ptIns1 = pt - vtDir1*(m_nWidth+m_nSpare-m_nWidth*tan(PI/8)); else ptIns1 = pt - vtDir1*m_nSpare; arPts.append(ptIns1); if (seg2T.StartPoint().Distance(ptInter) > seg2T.EndPoint().Distance(ptInter)) vtDir2 = seg2T.EndPoint() - seg2T.StartPoint(); else vtDir2 = seg2T.StartPoint() - seg2T.EndPoint(); vtDir2.normalize(); //判断是否是无交点的拐角 if (seg1T.Intersection(seg2T,ptT1,ptT2) == 0) // ptIns2 = pt - vtDir2*m_nWidth*tan(PI/8); ptIns2 = pt - vtDir2*(m_nWidth+m_nSpare-m_nWidth*tan(PI/8)); else ptIns2 = pt - vtDir2*m_nSpare; arPts.append(ptIns2); std::pair pair; pair.first = ptIns1; pair.second = ptIns2; CornerLine corner; corner.pair = pair; if (m_nCanalType == Canal_Corner2 || m_nCanalType == Canal_Corner3) { corner.dAng = 0.0; } else { if (nSegCount > 4) { corner.dAng = vtDir1.angleTo(vtDir2) - PI; } else { if (bMoreLen) corner.dAng = PI - vtDir1.angleTo(vtDir2); else corner.dAng = vtDir1.angleTo(vtDir2) - PI; } } map1.append(corner); } void TDbPipeCanal::ChangePipeCanalPositionNor(const AcArray &arPts,const AcGePoint3d &ptCen,int nSegLen,AcGePoint3d &pt1,AcGePoint3d &pt2) const { double dWeight = GetPScale()*m_dPipeWeight; XCurveSegment cenCurve = GetCurve(); XCurveSegment segUp,segDown; XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge()); segUp = segDir.Offset(m_nWidth/2, LS_FINITE); segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); AcDbLine lineUp(segUp.StartPoint(),segUp.EndPoint()); AcDbLine lineDown(segDown.StartPoint(),segDown.EndPoint()); if (lineUp.startPoint().distanceTo(ptCen) > lineUp.endPoint().distanceTo(ptCen)) pt1 = lineUp.endPoint(); else pt1 = lineUp.startPoint(); if (lineDown.startPoint().distanceTo(ptCen) > lineDown.endPoint().distanceTo(ptCen)) pt2 = lineDown.endPoint(); else pt2 = lineDown.startPoint(); AcGePoint3d ptS = lineUp.startPoint(); AcGePoint3d ptST = lineDown.startPoint(); AcGePoint3d ptE = lineUp.endPoint(); AcGePoint3d ptET = lineDown.endPoint(); ptS.z = 0.0; ptE.z = 0.0; ptST.z = 0.0; ptET.z = 0.0; lineUp.setStartPoint(ptS); lineUp.setEndPoint(ptE); lineDown.setStartPoint(ptST); lineDown.setEndPoint(ptET); for (int i = 0; i < arPts.length(); ++i) { AcGePoint3d ptNear; //交点个数为2,边数为4表示生成弯头 //交点个数为4表示四通 if (arPts.length() == 2 && nSegLen == 4) lineUp.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue); else lineUp.getClosestPointTo(arPts[i],ptNear); if (arPts[i].distanceTo(ptNear) < 1e-3) { pt1 = arPts[i]; } if (arPts.length() == 2 && nSegLen == 4) lineDown.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue); else lineDown.getClosestPointTo(arPts[i],ptNear); if (arPts[i].distanceTo(ptNear) < 1e-3) { pt2 = arPts[i]; } } } //设置方沟类型 void TDbPipeCanal::SetCannalSameType(const AcDbObjectIdArray &arIds) const { for (int i = 0; i < arIds.length(); ++i) { if (arIds[i].isValid()) { OPENOBJ_BEGIN(arIds[i], AcDb::kForWrite, TDbPipeCanal, pCanal); if (pCanal != NULL) { pCanal->SetCanalType(m_nCanalType); } OPENOBJ_END(); } } } ////////////////////////////////////////////////////////////////////////// void IniTDbPipeCanal(BOOL bTrue) { if(bTrue) { TDbPipeCanal::rxInit(); TDbPipeCanal::InitMatchProtocol(TRUE); } else { TDbPipeCanal::InitMatchProtocol(FALSE); deleteAcRxClass(TDbPipeCanal::desc()); } } AcDbObjectId TDbPipeCanal::GetSelfObjectId() const { AcDbObjectId idSelf = objectId(); if (idSelf.isValid()) { return idSelf; } //挑选 AcDbObjectIdArray arNode1,arNode2; AcDbObjectId idNode = GetNode(0); OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode); if (pNode != NULL) { AcDbObjectId id; for (int i = 0; i < pNode->GetInterfaceNum(); ++i) { id = pNode->GetIPipe(i); arNode1.append(id); } } OPENOBJ_END(); if (arNode1.length() == 1) { idSelf = arNode1.first(); return idSelf; } idNode = GetNode(1); OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode); if (pNode != NULL) { AcDbObjectId id; for (int i = 0; i < pNode->GetInterfaceNum(); ++i) { id = pNode->GetIPipe(i); arNode2.append(id); } } OPENOBJ_END(); if (arNode2.length() == 1) { idSelf = arNode2.first(); return idSelf; } for (int j = 0;j < arNode1.length();++j) { for (int p = 0;p < arNode2.length();++p) { if (arNode1[j] == arNode2[p]) { idSelf = arNode1[j]; return idSelf; } } } return idSelf; } void TDbPipeCanal::GetOffsetMatrix(const AcDbObjectId& id, AcGeMatrix3d& matOffset) const { matOffset.setToIdentity(); if (id.isValid()) { OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeCanal, pPipe); if (pPipe != NULL) { XCurveSegment seg,segSelf; seg = pPipe->GetCurve(); segSelf = GetCurve(); AcGeVector3d vt = segSelf.MidPoint() - seg.MidPoint(); matOffset.setToTranslation(vt); } OPENOBJ_END(); } } // 获取指定端坐标 XPoint TDbPipeCanal::GetVertexPt(const TPipeSys::PtLoction nSide) const { XPoint pt(GetStartPoint()); if (nSide == TPipeSys::kEndPt) { pt = EndPoint(); } return pt; } Acad::ErrorStatus TDbPipeCanal::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); Acad::ErrorStatus es = TDbPipe::subTransformBy(xform); //在transform的时候不停的打开对象,一次命令中以读方式打开超过256次,出现崩溃错误,加次判断条件,jig拖动结束时处理对象更新 if (!acedIsDragging()) { BOOL bApplyToNode(TRUE); // 是否提供变化给节点 XString &sCmd = GetCurDocData()->m_sCurCommand; if (_tcsicmp(sCmd, _T("MIRROR"))==0 || _tcsicmp(sCmd, _T("COPY"))==0 || _tcsicmp(sCmd, _T("COPYCLIP"))==0 || _tcsicmp(sCmd, _T("PASTECLIP"))==0) { bApplyToNode = FALSE; // 管线的复制、镜像操作,不提供变化给节点 } if (!bApplyToNode) { return es; } AcDbObjectId idNode; for (int i = 0;i < 2;++i) { idNode = GetNode(i); if (idNode.isValid()) { TPipeSys::PtLoction nSide = (TPipeSys::PtLoction)i; XPoint ptSide = GetVertexPt(nSide); OPENOBJ_BEGIN(GetNode(i), AcDb::kForRead, TDbPipeFitting, pFit); if (pFit != NULL) { if (pFit->upgradeOpen() == Acad::eOk) { // 更新节点 pFit->SetLocation(ptSide); // 修改m_ptLocation for (int p = 0;p < pFit->GetInterfaceNum();++p) { pFit->SetILocation(p,ptSide); } pFit->downgradeOpen(); } } OPENOBJ_END(); } } } return es; } Acad::ErrorStatus TDbPipeCanal::subGetTransformedCopy(const AcGeMatrix3d& xform, AcDbEntity*& pEnt) const { assertReadEnabled(); pEnt = new TDbPipeCanal; pEnt->copyFrom(this); pEnt->transformBy(xform); return Acad::eOk; } // 增加Node的wbclone Acad::ErrorStatus TDbPipeCanal::subWblockClone(AcRxObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { Acad::ErrorStatus es=TDbPipe::subWblockClone(pOwner, pClonedObject, idMap, isPrimary); if(es!=Acad::eOk) return es; es=subSubWblockClone(m_nodeStart.m_idNode,pOwner, pClonedObject, idMap, isPrimary); es=subSubWblockClone(m_nodeEnd.m_idNode,pOwner, pClonedObject, idMap, isPrimary); return Acad::eOk; } Acad::ErrorStatus TDbPipeCanal::subSubWblockClone(const AcDbObjectId& idCloning, AcRxObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { Acad::ErrorStatus es = Acad::eInvalidInput; if (!idCloning.isValid()) return es; AcDbIdPair idPairOpening(idCloning, (AcDbObjectId)NULL,false, isPrimary? true : false); if (idMap.compute(idPairOpening)) return es; AcDbObject *pSubObject=NULL; AcDbObject *pClonedSubObject=NULL; if (acdbOpenAcDbObject(pSubObject, idCloning, AcDb::kForRead) == Acad::eOk) { es = pSubObject->wblockClone(pOwner,pClonedSubObject,idMap, isPrimary); pSubObject->close(); if (es == Acad::eOk) { pClonedSubObject->close(); } } return Acad::eOk; } // 根据连接点点过滤相连接的方沟 BOOL TDbPipeCanal::IsHasMorePipes(const AcDbObjectId& idNode) const { int num = GetNodeCntPipeNumber(idNode); if (num > 1)// 有连接 { return FALSE; } return TRUE; } // 节点连接的管子个数 int TDbPipeCanal::GetNodeCntPipeNumber(const AcDbObjectId& idNode) const { int nNum = 0; if (idNode.isValid()) { OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode); if(pNode) { nNum = pNode->GetInterfaceNum(); } OPENOBJ_END(); } return nNum; } // 获取垂足点 BOOL TDbPipeCanal::GetVerticalFootPoint(const AcGePoint3d& pickPoint,const AcGePoint3d& lastPoint,AcGePoint3d& ptVerFoot) const { AcDbObjectId idNode1(NULL), idNode2(NULL); idNode1 = GetNode(0); idNode2 = GetNode(1); if (!idNode1.isValid() || !idNode2.isValid()) { return FALSE; } AcGePoint3d pt1,pt2,pt3,pt4; //分别得到方沟的一端上两点 AcArray map1,map2; GetCannalPts(idNode1,pt1,pt2,map1); GetCannalPts(idNode2,pt3,pt4,map2); AcArray cplCurve; AcDbLine *pLine = NULL; if (!IsHasMorePipes(idNode1)) { pLine = new AcDbLine; pLine->setStartPoint(pt1); pLine->setEndPoint(pt2); cplCurve.append(pLine); } pLine = new AcDbLine; pLine->setStartPoint(pt1); pLine->setEndPoint(pt3); cplCurve.append(pLine); if (!IsHasMorePipes(idNode2)) { pLine = new AcDbLine; pLine->setStartPoint(pt4); pLine->setEndPoint(pt3); cplCurve.append(pLine); } pLine = new AcDbLine; pLine->setStartPoint(pt4); pLine->setEndPoint(pt2); cplCurve.append(pLine); for (int t = 0;t < map1.length();t++) { pLine = new AcDbLine; pLine->setStartPoint(map1[t].pair.first); pLine->setEndPoint(map1[t].pair.second); cplCurve.append(pLine); } for (int j = 0;j < map2.length();j++) { pLine = new AcDbLine; pLine->setStartPoint(map2[j].pair.first); pLine->setEndPoint(map2[j].pair.second); cplCurve.append(pLine); } BOOL bFind = FALSE; if (cplCurve.length() > 0) { double dDisToLine = 0.0; double dDisOld = 100000.0; AcGePoint3d ptOnLine; int nIndex = -1; // 挑选离pick点最近的线 for (int i = 0;i < cplCurve.length();i++) { if (cplCurve[i]->getClosestPointTo(pickPoint, ptOnLine,Adesk::kTrue) == Acad::eOk) { dDisToLine = pickPoint.distanceTo(ptOnLine); if (dDisOld > dDisToLine) { dDisOld = dDisToLine; nIndex = i; } } } // 找到第一次取的点到该线的垂点 if (nIndex != -1) { if (cplCurve[nIndex]->getClosestPointTo(lastPoint, ptOnLine,Adesk::kTrue) == Acad::eOk) { ptVerFoot = ptOnLine; bFind = TRUE; } } } FreeBuffer(cplCurve); return bFind; } // 获取最近点 BOOL TDbPipeCanal::GetNearestPoint(const AcGePoint3d& pickPoint,AcGePoint3d& ptNear) const { AcDbObjectId idNode1(NULL), idNode2(NULL); idNode1 = GetNode(0); idNode2 = GetNode(1); if (!idNode1.isValid() || !idNode2.isValid()) { return FALSE; } AcGePoint3d pt1,pt2,pt3,pt4; //分别得到方沟的一端上两点 AcArray map1,map2; GetCannalPts(idNode1,pt1,pt2,map1); GetCannalPts(idNode2,pt3,pt4,map2); AcArray cplCurve; AcDbLine *pLine = NULL; if (!IsHasMorePipes(idNode1)) { pLine = new AcDbLine; pLine->setStartPoint(pt1); pLine->setEndPoint(pt2); cplCurve.append(pLine); } pLine = new AcDbLine; pLine->setStartPoint(pt1); pLine->setEndPoint(pt3); cplCurve.append(pLine); if (!IsHasMorePipes(idNode2)) { pLine = new AcDbLine; pLine->setStartPoint(pt4); pLine->setEndPoint(pt3); cplCurve.append(pLine); } pLine = new AcDbLine; pLine->setStartPoint(pt4); pLine->setEndPoint(pt2); cplCurve.append(pLine); for (int t = 0;t < map1.length();t++) { pLine = new AcDbLine; pLine->setStartPoint(map1[t].pair.first); pLine->setEndPoint(map1[t].pair.second); cplCurve.append(pLine); } for (int j = 0;j < map2.length();j++) { pLine = new AcDbLine; pLine->setStartPoint(map2[j].pair.first); pLine->setEndPoint(map2[j].pair.second); cplCurve.append(pLine); } BOOL bFind = FALSE; if (cplCurve.length() > 0) { double dDisToLine = 0.0; double dDisOld = 100000.0; AcGePoint3d ptOnLine; // 挑选离pick点最近的线 for (int i = 0;i < cplCurve.length();i++) { if (cplCurve[i]->getClosestPointTo(pickPoint, ptOnLine) == Acad::eOk) { dDisToLine = pickPoint.distanceTo(ptOnLine); if (dDisOld > dDisToLine) { dDisOld = dDisToLine; ptNear = ptOnLine; bFind = TRUE; } } } } FreeBuffer(cplCurve); return bFind; } // 释放内存 void TDbPipeCanal::FreeBuffer(AcArray& cplCurve) const { for (int i = 0;i < cplCurve.length();i++) { delete cplCurve[i]; } } void TDbPipeCanal::SetCoverLineWidth(double dLineWidth) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("COVER_LINEWIDTH"), dLineWidth); } double TDbPipeCanal::GetCoverLineWidth() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); double dLineWidth = 0.0; fd.GFD(_T("COVER_LINEWIDTH"), dLineWidth); return dLineWidth; } void TDbPipeCanal::SetBlindDrain(bool bVal) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("BLIND_DRAIN"), bVal ? Adesk::kTrue : Adesk::kFalse); } bool TDbPipeCanal::IsBlineDrain() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); Adesk::Boolean bFlag = Adesk::kFalse; fd.GFD(_T("BLIND_DRAIN"), bFlag); return bFlag == Adesk::kTrue ? true : false; } void TDbPipeCanal::SetCoverType(int nType) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("COVER_TYPE"), (Adesk::UInt8)nType); } int TDbPipeCanal::GetCoverType() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); Adesk::UInt8 nType = 0; fd.GFD(_T("COVER_TYPE"), nType); return (int)nType; } void TDbPipeCanal::SetCoverHorDist(double dDist) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("COVER_HOR_DIST"), dDist); } double TDbPipeCanal::GetCoverHorDist() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); double dDist = 0.0; fd.GFD(_T("COVER_HOR_DIST"), dDist); return dDist; } void TDbPipeCanal::SetCoverVerDist(double dDist) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("COVER_VER_DIST"), dDist); } double TDbPipeCanal::GetCoverVerDist() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); double dDist = 0.0; fd.GFD(_T("COVER_VER_DIST"), dDist); return dDist; } void TDbPipeCanal::DrawCover(XExplodeDraw &dc, XCurveSegment &segUp, XCurveSegment &segDown) const { double dWeight = GetPScale() * GetCoverLineWidth(); if (!IsShowPipeCanalLineWeight(this->database())) { dWeight = 0.0; } AcGePoint3d pt1 = segUp.StartPoint(); AcGePoint3d pt3 = segUp.EndPoint(); AcGePoint3d pt2 = segDown.StartPoint(); AcGePoint3d pt4 = segDown.EndPoint(); pt1.z = 0.0; pt2.z = 0.0; pt3.z = 0.0; pt4.z = 0.0; int nCoverType = GetCoverType(); if (!IsBlineDrain() && nCoverType != 0) { if (segDown.Is(CURVE_LINE)) // 直线型方沟 { // 获得两条边线平行重叠部分 AcDbLine line(pt1, pt3); AcGePoint3d pt21, pt41; line.getClosestPointTo(pt2, pt21); line.getClosestPointTo(pt4, pt41); AcGePoint3d ptS = pt1; if (fabs(pt2.distanceTo(pt21) - m_nWidth) < 0.001) { ptS = pt21; } AcGePoint3d ptE = pt3; if (fabs(pt4.distanceTo(pt41) - m_nWidth) < 0.001) { ptE = pt41; } // 绘制盖板 AcGePoint3d ptTemp; line.getClosestPointTo(pt2, ptTemp, Adesk::kTrue); AcGePoint3d ptS1 = ptS, ptS2 = ptS + pt2 - ptTemp; AcGeVector3d vtDir = pt41 - pt21; vtDir.normalize(); if (nCoverType == 1) { // 纵向 double dLen = ptS.distanceTo(ptE); double dDist = 0.0, dHorDist = GetCoverHorDist(); XCurveSegment segTemp; bool bELinkedEntity = IsLinkedEntity(1); while (dDist < dLen + 0.001) { segTemp.SetPoints(ptS1 + vtDir * dDist, ptS2 + vtDir * dDist); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); if (dDist + dHorDist > dLen + 0.001 && dDist < dLen - 0.001) // 末端 { if (bELinkedEntity) { break; } dDist = dLen; } else { dDist += dHorDist; } } } else if (nCoverType == 2) { // 纵向 XCurveSegment segTemp; if (!IsLinkedEntity(0)) // 起点未连接实体 { segTemp.SetPoints(ptS1, ptS2); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); } if (!IsLinkedEntity(1)) // 终点未连接实体 { double dLen = ptS.distanceTo(ptE); segTemp.SetPoints(ptS1 + vtDir * dLen, ptS2 + vtDir * dLen); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); } // 横向 AcDbLine line(pt1, pt3); AcDbLine lineS(pt1, pt2), lineE(pt3, pt4); AcGeVector3d vtVer = ptS2 - ptS1; vtVer.normalize(); double dDist = GetCoverVerDist(), dVerDist = dDist; AcGePoint3dArray arrPt1, arrPt2; while (dDist < m_nWidth - 0.001) { line.transformBy(vtVer * dVerDist); line.intersectWith(&lineS, AcDb::kExtendBoth, arrPt1); line.intersectWith(&lineE, AcDb::kExtendBoth, arrPt2); if (arrPt1.length() == 1 && arrPt2.length() == 1) { segTemp.SetPoints(arrPt1[0], arrPt2[0]); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); } arrPt1.setLogicalLength(0); arrPt2.setLogicalLength(0); dDist += dVerDist; } } else if (nCoverType == 3) { // 纵向 double dLen = ptS.distanceTo(ptE); double dDist = 0.0, dHorDist = GetCoverHorDist(); XCurveSegment segTemp; bool bELinkedEntity = IsLinkedEntity(1); while (dDist < dLen + 0.001) { segTemp.SetPoints(ptS1 + vtDir * dDist, ptS2 + vtDir * dDist); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); if (dDist + dHorDist > dLen + 0.001 && dDist < dLen - 0.001) // 终点 { if(bELinkedEntity) { break; } dDist = dLen; } else { dDist += dHorDist; } } // 横向 AcDbLine line(pt1, pt3); AcDbLine lineS(pt1, pt2), lineE(pt3, pt4); AcGeVector3d vtVer = ptS2 - ptS1; vtVer.normalize(); dDist = GetCoverVerDist(); double dVerDist = dDist; AcGePoint3dArray arrPt1, arrPt2; while (dDist < m_nWidth - 0.001) { line.transformBy(vtVer * dVerDist); line.intersectWith(&lineS, AcDb::kExtendBoth, arrPt1); line.intersectWith(&lineE, AcDb::kExtendBoth, arrPt2); if (arrPt1.length() == 1 && arrPt2.length() == 1) { segTemp.SetPoints(arrPt1[0], arrPt2[0]); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); } arrPt1.setLogicalLength(0); arrPt2.setLogicalLength(0); dDist += dVerDist; } } } else // 弧线型方沟 { // 获得两条边线重叠部分 XArc arcUp = segUp.GetArc(); XArc arcDown = segDown.GetArc(); XArc arcCenter = this->GetCurve().GetArc(); XPoint ptCenter = arcCenter.GetCenterPt(); ptCenter.z = 0.0; AcDbArc arc(ptCenter, arcUp.GetRadius(), arcUp.GetStarAngle(), arcUp.GetEndAngle()); double dUpRadius = arcUp.GetRadius(); double dDownRadius = arcDown.GetRadius(); double dRadius = (dUpRadius > dDownRadius ? dDownRadius : dUpRadius) + fabs(dUpRadius - dDownRadius) * 0.5; AcGePoint3d pt21, pt41; arc.getClosestPointTo(pt2, pt21); arc.getClosestPointTo(pt4, pt41); AcGePoint3d ptS = pt1; if (fabs(pt2.distanceTo(pt21) - m_nWidth) < 0.001) { ptS = pt21; } AcGePoint3d ptE = pt3; if (fabs(pt4.distanceTo(pt41) - m_nWidth) < 0.001) { ptE = pt41; } // 重叠部分端点转换到中心线上 AcGeVector3d vtS = ptS - ptCenter.AsAcGePoint3d(); AcGeVector3d vtE = ptE - ptCenter.AsAcGePoint3d(); vtS.z = 0.0; vtE.z = 0.0; vtS.normalize(); vtE.normalize(); ptS = ptCenter + vtS * dRadius; ptE = ptCenter + vtE * dRadius; double dAngle = vtS.angleTo(vtE, AcGeVector3d::kZAxis); // 重叠不错在中线处的弧线及中点 AcGeVector3d vtMid = vtS; vtMid.rotateBy(dAngle * 0.5, AcGeVector3d::kZAxis); XPoint ptMid = ptCenter + vtMid * dRadius; XArc arcTemp(ptS, ptMid, ptE); AcDbArc arcMid(arcTemp.GetCenterPt(), arcTemp.GetRadius(), arcTemp.GetStarAngle(), arcTemp.GetEndAngle()); // 确定端点node索引 if (nCoverType == 1) { // 纵向 double dLen = vtS.angleTo(vtE, AcGeVector3d::kZAxis) * dRadius; double dDist = 0.0, dHorDist = GetCoverHorDist(); XCurveSegment segTemp; bool bSLinkeEntity = IsLinkedEntity(StartPoint()); bool bELinkedEntity = IsLinkedEntity(EndPoint()); while (dDist < dLen + 0.001) { double dAngle = dDist / dRadius; AcGeVector3d vtTemp = vtS; vtTemp.rotateBy(dAngle, AcGeVector3d::kZAxis); segTemp.SetPoints(ptCenter + vtTemp * dUpRadius, ptCenter + vtTemp * dDownRadius); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); if (dDist + dHorDist > dLen + 0.001 && dDist < dLen - 0.001) // 终点 { if(bELinkedEntity) { break; } dDist = dLen; } else { dDist += dHorDist; } } } else if (nCoverType == 2) { // 纵向 XCurveSegment segTemp; if (!IsLinkedEntity(0)) // 起点未连接实体 { segTemp.SetPoints(ptCenter + vtS * dUpRadius, ptCenter + vtS * dDownRadius); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); } if (!IsLinkedEntity(1)) // 终点未连接实体 { segTemp.SetPoints(ptCenter + vtE * dUpRadius, ptCenter + vtE * dDownRadius); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); } // 横向 double dMinRadius = dDownRadius > dUpRadius ? dUpRadius : dDownRadius; double dDist = GetCoverVerDist(), dVerDist = dDist; AcGePoint3dArray arrPt1, arrPt2; while (dDist < m_nWidth - 0.001) { double dOffset = dDist + dMinRadius - dRadius; segTemp = XArc(ptCenter, dMinRadius + dDist, arcMid.startAngle(), arcMid.endAngle()); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); dDist += dVerDist; } } else if (nCoverType == 3) { // 纵向 double dLen = vtS.angleTo(vtE, AcGeVector3d::kZAxis) * dRadius; double dDist = 0.0, dHorDist = GetCoverHorDist(); XCurveSegment segTemp; bool bSLinkeEntity = IsLinkedEntity(StartPoint()); bool bELinkedEntity = IsLinkedEntity(EndPoint()); while (dDist < dLen + 0.001) { double dAngle = dDist / dRadius; AcGeVector3d vtTemp = vtS; vtTemp.rotateBy(dAngle, AcGeVector3d::kZAxis); segTemp.SetPoints(ptCenter + vtTemp * dUpRadius, ptCenter + vtTemp * dDownRadius); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); if (dDist + dHorDist > dLen + 0.001 && dDist < dLen - 0.001 ) // 终点 { if(bELinkedEntity) { break; } dDist = dLen; } else { dDist += dHorDist; } } // 横向 double dMinRadius = dDownRadius > dUpRadius ? dUpRadius : dDownRadius; dDist = GetCoverVerDist(); double dVerDist = dDist; AcGePoint3dArray arrPt1, arrPt2; while (dDist < m_nWidth - 0.001) { double dOffset = dDist + dMinRadius - dRadius; segTemp = XArc(ptCenter, dMinRadius + dDist, arcMid.startAngle(), arcMid.endAngle()); DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale()); dDist += dVerDist; } } } } } bool TDbPipeCanal::IsLinkedEntity(int nPos) const { AcDbObjectId id = GetNode(nPos); if (!id.isValid()) { return false; } OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeNode, pNode); if(pNode != NULL) { int num = pNode->GetInterfaceNum(); for (int i = 0; i < num; ++i) { const AcDbObjectId &idTemp = pNode->GetIPipe(i); if (idTemp.isValid() && idTemp != this->id()) { return true; } } } OPENOBJ_END(); return false; } bool TDbPipeCanal::IsLinkedEntity(XPoint pt) const { for (int i = 0; i < 2; ++i) { OPENOBJ_BEGIN(GetNode(i), AcDb::kForRead, TDbPipeNode, pNode); if(pNode != NULL) { XPoint ptLoc = pNode->GetLocation(); if (ptLoc.Distance2d(pt) > 0.001) { continue; } int num = pNode->GetInterfaceNum(); for (int i = 0; i < num; ++i) { const AcDbObjectId &idTemp = pNode->GetIPipe(i); if (idTemp.isValid() && idTemp != this->id()) { return true; } } } OPENOBJ_END(); } return false; } int TDbPipeCanal::LinkedPipeCanalNum(int nPos) const { AcDbObjectId id = GetNode(nPos); if (!id.isValid()) { return 0; } OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeFitting, pNode); if(pNode != NULL) { int num = pNode->GetInterfaceNum(); return num - 1; } OPENOBJ_END(); return 0; } int TDbPipeCanal::NeedModifyInt(int nPos, const TDbPipeFitting *pFitting) const { int nLinkNum = pFitting->GetInterfaceNum() - 1; // 样式2和样式3弯头连接时 (端点只和一个方沟有连接) if (nLinkNum == 1 && (m_nCanalType == 2 || m_nCanalType == 3)) { XPoint pt = nPos == 0 ? StartPoint() : EndPoint(); for (int i = 0; i < pFitting->GetInterfaceNum(); ++i) { AcDbObjectId id = pFitting->GetIPipe(i); if (id == this->objectId()) { continue; } OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal != NULL) { // 确定方沟间的夹角位置 XCurveSegment segBase = pCanal->GetCurve(); AcGeVector3d vt1; if (segBase.Is(CURVE_LINE)) // 直线 { vt1 = segBase.MidPoint() - pt; } else // 弧线 { vt1 = segBase.GetArc().GetCenterPt() - pt; vt1.z = 0.0; if (pt.Distance2d(segBase.StartPoint()) < 0.001) { vt1.rotateBy(-PI * 0.5, AcGeVector3d::kZAxis); } else { vt1.rotateBy(PI * 0.5, AcGeVector3d::kZAxis); } } XCurveSegment cenCurve = GetCurve(); AcGeVector3d vt2; if (cenCurve.Is(CURVE_LINE)) // 直线 { vt2 = cenCurve.MidPoint() - pt; } else // 弧线 { vt2 = cenCurve.GetArc().GetCenterPt() - pt; vt2.z = 0.0; vt2.rotateBy(-PI * 0.5, AcGeVector3d::kZAxis); } vt1.z = 0.0; vt2.z = 0.0; double dAngle = vt2.angleTo(vt1, AcGeVector3d::kZAxis); if (nPos == 0) // 起点 { if (dAngle < PI) { return 1; } else { return 2; } } else // 终点 { if (dAngle < PI) { return 2; } else { return 1; } } } OPENOBJ_END(); } } return 0; } void TDbPipeCanal::Draw3dType(XExplodeDraw &dc) const { XCurveSegment cenCurve = GetCurve(); XCurveSegment segUp,segDown; XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge()); segUp = segDir.Offset(m_nWidth/2, LS_FINITE); segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); // 起点方沟边线连接点 XPoint pt1 = segUp.StartPoint(); XPoint pt2 = segDown.StartPoint(); OPENOBJ_BEGIN(GetNode(0), AcDb::kForRead, TDbPipeFitting, pFitting); if (pFitting != NULL) { TDbCanalFitting fitting(pFitting); fitting.IntersectWith(this->objectId(), pt1, pt2); } OPENOBJ_END(); // 终点方沟边线连接点 XPoint pt3 = segUp.EndPoint(); XPoint pt4 = segDown.EndPoint(); OPENOBJ_BEGIN(GetNode(1), AcDb::kForRead, TDbPipeFitting, pFitting); if (pFitting != NULL) { TDbCanalFitting fitting(pFitting); fitting.IntersectWith(this->objectId(), pt4, pt3); } OPENOBJ_END(); if (cenCurve.Is(CURVE_LINE)) // 直线方沟 { XLine lineUp1 = segUp.GetLine(); XLine lineDown1 = segDown.GetLine(); pt1 = ProjectAlongZAxis(lineUp1, pt1); pt3 = ProjectAlongZAxis(lineUp1, pt3); pt2 = ProjectAlongZAxis(lineDown1, pt2); pt4 = ProjectAlongZAxis(lineDown1, pt4); // 底面 AcGePoint3dArray arrPts; arrPts.append(pt1); arrPts.append(pt3); arrPts.append(pt2); arrPts.append(pt4); dc.DrawMesh(2, 2, arrPts.asArrayPtr()); // 根据起始点高度,计算顶面边线 XPoint ptUpS = segUp.StartPoint(), ptUpE = segUp.EndPoint(); XPoint ptDownS = segDown.StartPoint(), ptDownE = segDown.EndPoint(); ptUpS.z += GetStartHeight(); ptDownS.z = ptUpS.z; ptUpE.z += GetEndHeight(); ptDownE.z = ptUpE.z; XLine lineUp2(ptUpS, ptUpE); XLine lineDown2(ptDownS, ptDownE); XPoint pt11 = ProjectAlongZAxis(lineUp2, pt1); XPoint pt33 = ProjectAlongZAxis(lineUp2, pt3); XPoint pt22 = ProjectAlongZAxis(lineDown2, pt2); XPoint pt44 = ProjectAlongZAxis(lineDown2, pt4); // 绘制边界面 arrPts.setLogicalLength(0); arrPts.append(pt1); arrPts.append(pt11); arrPts.append(pt3); arrPts.append(pt33); dc.DrawMesh(2, 2, arrPts.asArrayPtr()); arrPts.setLogicalLength(0); arrPts.append(pt2); arrPts.append(pt22); arrPts.append(pt4); arrPts.append(pt44); dc.DrawMesh(2, 2, arrPts.asArrayPtr()); } else // 弧线方沟 { XArc arcUp1 = segUp.GetArc(); XArc arcDown1 = segDown.GetArc(); // 计算融合前底面边线 XPoint ptUpS1, ptUpE1; arcUp1.GetStartPoint(ptUpS1); arcUp1.GetEndPoint(ptUpE1); XPoint ptUpMid1 = arcUp1.MidPoint(); ptUpS1.z = StartPoint().z; ptUpE1.z = EndPoint().z; ptUpMid1.z = (ptUpS1.z + ptUpE1.z) * 0.5; AcGeCircArc3d cirUp1(ptUpS1, ptUpMid1, ptUpE1); XPoint ptDownS1, ptDownE1; arcDown1.GetStartPoint(ptDownS1); arcDown1.GetEndPoint(ptDownE1); XPoint ptDownMid1 = arcDown1.MidPoint(); ptDownS1.z = StartPoint().z ; ptDownE1.z = EndPoint().z; ptDownMid1.z = (ptDownS1.z + ptDownE1.z) * 0.5; AcGeCircArc3d cirDown1(ptDownS1, ptDownMid1, ptDownE1); // 融合后底面边线 pt1 = ProjectAlongZAxis(cirUp1, pt1); pt3 = ProjectAlongZAxis(cirUp1, pt3); pt2 = ProjectAlongZAxis(cirDown1, pt2); pt4 = ProjectAlongZAxis(cirDown1, pt4); // 中点 AcGeVector3d vt1 = pt1 - arcUp1.GetCenterPt(); AcGeVector3d vt2 = pt3 - arcUp1.GetCenterPt(); vt1.z = 0.0; vt2.z = 0.0; double dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis); vt1.rotateBy(dAngle * 0.5, AcGeVector3d::kZAxis); vt1.normalize(); XPoint pt5 = arcUp1.GetCenterPt() + vt1 * arcUp1.GetRadius(); pt5 = ProjectAlongZAxis(cirUp1, pt5); AcGeVector3d vt3 = pt2 - arcDown1.GetCenterPt(); AcGeVector3d vt4 = pt4 - arcDown1.GetCenterPt(); vt3.z = 0.0; vt4.z = 0.0; dAngle = vt3.angleTo(vt4, AcGeVector3d::kZAxis); vt3.rotateBy(dAngle * 0.5, AcGeVector3d::kZAxis); vt3.normalize(); XPoint pt6 = arcDown1.GetCenterPt() + vt3 * arcDown1.GetRadius(); pt6 = ProjectAlongZAxis(cirDown1, pt6); AcGeCircArc3d arc1(pt1, pt5, pt3); AcGeCircArc3d arc2(pt2, pt6, pt4); // 绘制底面 int nSplitNum = 10; AcGePoint3dArray arr1, arr2, arr; arc1.getSamplePoints(nSplitNum, arr1); arc2.getSamplePoints(nSplitNum, arr2); for (int i = 0; i < arr1.length(); ++i) { arr.append(arr1.at(i)); arr.append(arr2.at(i)); } dc.DrawMesh(arr.length() / 2, 2, arr.asArrayPtr()); // 边界面 XPoint ptUpS2 = ptUpS1; XPoint ptUpE2 = ptUpE1; ptUpS2.z += GetStartHeight(); ptUpE2.z += GetEndHeight(); XPoint ptUpMid2 = ptUpMid1; ptUpMid2.z = (ptUpS2.z + ptUpE2.z) * 0.5; AcGeCircArc3d cirUp2(ptUpS2, ptUpMid2, ptUpE2); XPoint ptDownS2 = ptDownS1; XPoint ptDownE2 = ptDownE1; ptDownS2.z += GetStartHeight(); ptDownE2.z += GetEndHeight(); XPoint ptDownMid2 = ptDownMid1; ptDownMid2.z = (ptDownS2.z + ptDownE2.z) * 0.5; AcGeCircArc3d cirDown2(ptDownS2, ptDownMid2, ptDownE2); pt1 = ProjectAlongZAxis(cirUp2, pt1); pt3 = ProjectAlongZAxis(cirUp2, pt3); pt5 = ProjectAlongZAxis(cirUp2, pt5); pt2 = ProjectAlongZAxis(cirDown2, pt2); pt4 = ProjectAlongZAxis(cirDown2, pt4); pt6 = ProjectAlongZAxis(cirDown2, pt6); AcGeCircArc3d arc3(pt1, pt5, pt3); AcGeCircArc3d arc4(pt2, pt6, pt4); // 绘制边界面 AcGePoint3dArray arr3, arr4; arc3.getSamplePoints(nSplitNum, arr3); arc4.getSamplePoints(nSplitNum, arr4); arr.setLogicalLength(0); for (int i = 0; i < arr3.length(); ++i) { arr.append(arr1.at(i)); arr.append(arr3.at(i)); } dc.DrawMesh(arr.length() * 0.5, 2, arr.asArrayPtr()); arr.setLogicalLength(0); for (int i = 0; i < arr4.length(); ++i) { arr.append(arr2.at(i)); arr.append(arr4.at(i)); } dc.DrawMesh(arr.length() * 0.5, 2, arr.asArrayPtr()); } } double TDbPipeCanal::GetStartHeight() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); double dHeight = m_nHeight; fd.GFD(_T("START_HEIGHT"), dHeight); return dHeight; } void TDbPipeCanal::SetStartHeight(double dHeight) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("START_HEIGHT"), dHeight); } double TDbPipeCanal::GetEndHeight() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); double dHeight = m_nHeight; fd.GFD(_T("END_HEIGHT"), dHeight); return dHeight; } void TDbPipeCanal::SetEndHeight(double dHeight) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("END_HEIGHT"), dHeight); } XPoint TDbPipeCanal::ProjectAlongZAxis(XLine &line, const XPoint &pt) const { XPoint ptRet = pt; AcDbLine lineTemp(line.StartPoint(), line.EndPoint()); lineTemp.getClosestPointTo(pt, AcGeVector3d::kZAxis, ptRet, Adesk::kTrue); return ptRet; } AcGePoint3d TDbPipeCanal::ProjectAlongZAxis(AcGeCircArc3d &cir, const XPoint &pt) const { AcGePoint3d ptRet = pt; AcGePlane plane(cir.center(), cir.normal()); AcGeLine3d line(pt, AcGeVector3d::kZAxis); AcGePoint3d ptInt; if (plane.intersectWith(line, ptInt) == Adesk::kTrue) { ptRet = ptInt; } return ptRet; } double TDbPipeCanal::GetGradient() const { assertReadEnabled(); double dSEle = this->StartPoint().z; double dEEle = this->EndPoint().z; double dGradient = 0.0; if (fabs(dSEle - dEEle) > 0.000001) { double dLen = this->StartPoint().Distance2d(this->EndPoint()); dGradient = (dSEle - dEEle) / dLen; } return dGradient; } void TDbPipeCanal::SetGradient(double dGradient) { assertWriteEnabled(); if (fabs(dGradient) < 0.000001) { EndPoint().z = StartPoint().z; } else { double dLen = this->StartPoint().Distance2d(this->EndPoint()); if (dGradient > 0.0) { EndPoint().z += dLen * dGradient; } else { StartPoint().z += dLen * dGradient; } } }