#include "stdafx.h" #include "PickEntSet.h" #include "PushProperty.h" #include "AecDbText.h" #include "AcDbObjectPtr.h" #include "DbWell.h" #include "DbPipe.h" #include extern BOOL Is2DView(); // cet 2017.8.10 add 彻底炸开实体 void FullExplode(const AcDbEntity *pEnt, AcDbVoidPtrArray &entitySet) { AcDbVoidPtrArray arrTemp, arrExplode; if (pEnt->explode(arrTemp) != Acad::eOk) { return; } while (!arrTemp.isEmpty()) { AcDbEntity *pTemp = (AcDbEntity*)arrTemp[0]; arrTemp.removeAt(0); if (pTemp == NULL) { continue; } arrExplode.removeAll(); if (pTemp->explode(arrExplode) == Acad::eOk) { arrTemp.append(arrExplode); delete pTemp; } else { entitySet.append((void*)pTemp); } } } namespace { Acad::ErrorStatus DrawPolyMesh(XPoint ptSt, XPoint ptEn, double nRadius, AcGiDraw &dc) { AcGePoint3d ptS = ptSt; AcGePoint3d ptE = ptEn; AcGeVector3d vtDirect = ptE - ptS; AcGeVector3d vtNormal = vtDirect.perpVector(); vtDirect.normalize(); double dMinAngle = PI / 15.0; int nPartNum = int(PI * 2 / dMinAngle) + 1; dMinAngle = PI * 2.0 / nPartNum; double dDiaMet = nRadius * 2; AcGePoint3dArray ptArr, ptArrT, ptArrD; AcGeVector3d vtNow = vtNormal * -1; // 每组顶点法向 int i(0); for (i = 0; i < nPartNum * 2; i += 2) { ptArr.append(ptS + dDiaMet * 0.5 * vtNow); ptArr.append(ptE + dDiaMet * 0.5 * vtNow); ptArrT.append(ptS + dDiaMet * 0.5 * vtNow); ptArrT.append(ptS); ptArrD.append(ptE + dDiaMet * 0.5 * vtNow); ptArrD.append(ptE); vtNow.rotateBy(dMinAngle, vtDirect); } // 单独设置末点,防止误差 ptArr.append(ptArr.at(0)); ptArr.append(ptArr.at(1)); ptArrT.append(ptArrT.at(0)); ptArrT.append(ptArrT.at(1)); ptArrD.append(ptArrD.at(0)); ptArrD.append(ptArrD.at(1)); // 圆柱体 dc.DrawMesh(nPartNum + 1, 2, ptArr.asArrayPtr()); // 上面 dc.DrawMesh(nPartNum + 1, 2, ptArrT.asArrayPtr()); // 下面 dc.DrawMesh(nPartNum + 1, 2, ptArrD.asArrayPtr()); return Acad::eOk; } // 管道与井求交 bool IntersectWith(const AecXDbWell *pWell, const AcDbEntity* pEntCurve, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points) { // cet 2018.1.31 modify 只有二维图形计算交点 // pWell->explode(entSet1); AcGiViewDraw dc; pWell->Draw2d(dc); const AcDbVoidPtrArray &entSet1 = pWell->Get2DBuffer(); for (int i = 0; i < entSet1.length(); ++i) { AcDbEntity *pEnt = (AcDbEntity *)entSet1[i]; if (pEnt->isKindOf(CDbEquipment::desc())) { AcDbVoidPtrArray entSet2; pEnt->explode(entSet2); for (int j = 0; j < entSet2.length(); ++j) { AcDbBlockReference *pBlkRef = NULL; if (pBlkRef = AcDbBlockReference::cast((AcDbEntity*)entSet2[j])) { AcDbVoidPtrArray entSet3; pBlkRef->explode(entSet3); for (int k = 0; k < entSet3.length(); k++) { AcDbEntity *pEnt3 = (AcDbEntity *)entSet3[k]; if (pEnt3->isKindOf(AcDbCurve::desc())) { AcGePoint3dArray arrPt; pEntCurve->intersectWith((AcDbCurve*)pEnt3, intType, projPlane, arrPt); for (int i = 0; i < arrPt.length(); ++i) { points.append(arrPt[i]); } } } GlobalFunc::ReleaseEntSet(entSet3); } } GlobalFunc::ReleaseEntSet(entSet2); } } // 交点多于2个,求最远两点 if (points.length() > 2) { AcGePoint3d pt1 = points[0]; AcGePoint3d pt2 = points[1]; double dDist = pt1.distanceTo(pt2); for (int i = 0; i < points.length(); ++i) { for (int j = i + 1; j < points.length(); ++j) { if (points[i].distanceTo(points[j]) > dDist) { pt1 = points[i]; pt2 = points[j]; dDist = points[i].distanceTo(points[j]); } } } points.removeAll(); points.append(pt1); points.append(pt2); } return points.length() != 0; } } extern void Matrix3D2String(const AcGeMatrix3d &mat, CString &str); ACRX_DXF_DEFINE_MEMBERS(AecXDbWell, CDbEquipment, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, AEC_ZT_WELL, "AEC_ZT_WELL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); const Adesk::UInt8 AecXDbWell::g_nVersion = 2; AecXDbWell::AecXDbWell() { m_visibility = TPipeSys::kVisible; m_bHidePipe = TRUE; m_bDrawProperty = FALSE; m_dDang = 0; m_nWellDn = 8; m_bIsModify = false; SetEquipmentType(2); // cet 2014.12.2 设备类型 } void AecXDbWell::CopyPropertiesFrom(AcDbEntity *pSrc, unsigned gMatchFlag) { assertWriteEnabled(); CDbEquipment::CopyPropertiesFrom(pSrc, gMatchFlag); AecXDbWell *pEqu = AecXDbWell::cast(pSrc); if (pEqu) { m_idBlock2d = pEqu->m_idBlock2d; } } //Acad::ErrorStatus AecXDbWell::subGetClassID(CLSID* pClsid) const //{ // return Acad::eOk; //} Acad::ErrorStatus AecXDbWell::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& ptPick, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { Acad::ErrorStatus es = Acad::eOk; // if( osnapMode == AcDb::kOsModeIns || // osnapMode == AcDb::kOsModeCen || // osnapMode == AcDb::kOsModeNode) { // snapPoints.append(m_ptLocation); // } snapPoints.append(m_ptLocation); snapPoints.append(m_ptLabel); // cet 2017.8.9 add 可以捕捉井边界 if (Is2DView()) { AcDbVoidPtrArray blockArray; FullExplode(this, blockArray); int nCount = blockArray.length(); for (int i = 0; i < nCount; ++i) { AcDbEntity *pEntity = (AcDbEntity *)blockArray[i]; if (pEntity != NULL) { pEntity->getOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds); } } GlobalFunc::ReleaseEntSet(blockArray); } return es; } Acad::ErrorStatus AecXDbWell::GetGripText(int idx, CString &cs) const { Acad::ErrorStatus es = Acad::eOk; switch (idx) { case 0: cs = _T("移动井"); break; case 1: cs = _T("移动标注"); break; default: es = Acad::eInvalidInput; } return es; } Acad::ErrorStatus AecXDbWell::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); Acad::ErrorStatus es = Acad::eOk; gripPoints.append((AcGePoint3d)m_ptLocation); gripPoints.append((AcGePoint3d)m_ptLabel); // zxl 2013.12.12 add 虚显Space acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, true); Entity ent; ads_name name; acdbGetAdsName(name, GetSpaceId()); ent = name; ent.Redraw(3); acDocManager->unlockDocument(curDoc()); return es; } Acad::ErrorStatus AecXDbWell::subGetGripPoints(AcDbGripDataPtrArray & grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d & curViewDir, const int bitflags) const { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecXDbWell::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const { assertReadEnabled(); stretchPoints.append((AcGePoint3d)m_ptLocation); stretchPoints.append((AcGePoint3d)m_ptLabel); return Acad::eOk; } Acad::ErrorStatus AecXDbWell::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; es = MoveGSPointsAt(indices, offset); return es; } Acad::ErrorStatus AecXDbWell::subMoveStretchPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; es = MoveGSPointsAt(indices, offset, false); return es; } Acad::ErrorStatus AecXDbWell::MoveGSPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset, bool bGripMove) { Acad::ErrorStatus es = Acad::eOk; AcGeMatrix3d mat; mat.setToTranslation(offset); BOOL bMove = FALSE; bool bMovedLabel = false; // cet 2011.5.31 add 记录井标注点是否已经移动一次,避免多次移动标注点 for (int i = 0; i < indices.length(); i++) { int idx = indices[i]; switch (idx) { case 0: m_ptInsert.TransformBy(mat); m_ptLocation.TransformBy(mat); m_ptLabel.TransformBy(mat); bMove = TRUE; bMovedLabel = true; // cet 2011.5.31 add m_bIsModify = true; // zxl 2013.9.29 break; case 1: if (bMovedLabel) // cet 2011.5.31 add { break; } if (m_ptLabel != m_ptLocation) m_ptLabel.TransformBy(mat); break; default: es = Acad::eInvalidInput; } } // cet 2012.4.23 add 拉伸时不移动关联管线 if (!bGripMove) { return es; } if (bMove) { int num = GetInterfaceNum(); if (num < 1) return es; ads_name name; // cet 2012.4.23 add for (int m = 0; m < num; m++) { CPipeInterface face; GetInterface(m, face); // cet 2012.4.23 add 管线自身完成拉伸时,不再在此处理 acdbGetAdsName(name, face.m_idPipe); Entity ent(name); if (GlobalFunc::DocGetPickFirst().IsInclude(ent)) { continue; } OPENOBJ_BEGIN(face.m_idPipe, AcDb::kForWrite, CDbPipe, pPipe); if (pPipe && !pPipe->IsVertical()) { XPoint ptStart, ptEnd; pPipe->getStartPoint(ptStart); pPipe->getEndPoint(ptEnd); XPoint ptNew = m_ptLocation; if (pPipe->GetNode(0) == objectId()) { // cet 2016.4.8 modify 偏移管道及管道上的实体,原代码只是修改了管道位置,未处理管道上的实体 // ptNew.z = ptStart.z; // pPipe->SetStartPoint(ptNew); AcGePoint3dArray gripPoints; AcDbIntArray osnapModes; AcDbIntArray geomIds; pPipe->subGetGripPoints(gripPoints, osnapModes, geomIds); for (int i = 0; i < gripPoints.length(); ++i) { if (ptStart.Distance(gripPoints[i]) < 0.001) { AcDbIntArray arr; arr.append(i); pPipe->subMoveGripPointsAt(arr, ptNew - ptStart); break; } } } if (pPipe->GetNode(1) == objectId()) { // cet 2016.4.8 modify 偏移管道及管道上的实体,原代码只是修改了管道位置,未处理管道上的实体 // ptNew.z = ptEnd.z; // pPipe->SetEndPoint(ptNew); AcGePoint3dArray gripPoints; AcDbIntArray osnapModes; AcDbIntArray geomIds; pPipe->subGetGripPoints(gripPoints, osnapModes, geomIds); for (int i = 0; i < gripPoints.length(); ++i) { if (ptEnd.Distance(gripPoints[i]) < 0.001) { AcDbIntArray arr; arr.append(i); pPipe->subMoveGripPointsAt(arr, ptNew - ptEnd); break; } } } } OPENOBJ_END(); } } return es; } //移动夹点管线联动,如果移动井,则管线不联动。因为大量移动井和管线时会出错。 Acad::ErrorStatus AecXDbWell::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); CDbEquipment::subTransformBy(xform); m_ptLabel.TransformBy(xform); return Acad::eOk; } // 从DWG读入数据: Acad::ErrorStatus AecXDbWell::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = CDbEquipment::dwgInFields(pFiler); if (es != Acad::eOk) return es; es = CLabelStyle::dwgInFields(pFiler); if (es != Acad::eOk) return es; Adesk::UInt8 nVer; pFiler->readItem(&nVer); GlobalFunc::ReadString(pFiler, m_sWellName); pFiler->readItem((AcGePoint3d *)&m_ptLabel); pFiler->readItem(&m_nEleDown); pFiler->readItem(&m_nEleUp); pFiler->readItem(&m_nWellDn); //pFiler->readItem(&m_bDrawLabel); GlobalFunc::FilerRead(pFiler, m_bDrawLabel); pFiler->readItem(&m_idLabelLayer); return pFiler->filerStatus(); } Acad::ErrorStatus AecXDbWell::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = CDbEquipment::dwgOutFields(pFiler); if (es != Acad::eOk) return es; es = CLabelStyle::dwgOutFields(pFiler); if (es != Acad::eOk) return es; pFiler->writeItem(g_nVersion); pFiler->writeItem((const TCHAR *)m_sWellName); pFiler->writeItem((const AcGePoint3d &)m_ptLabel); pFiler->writeItem(m_nEleDown); pFiler->writeItem(m_nEleUp); pFiler->writeItem(m_nWellDn); //pFiler->writeItem(m_bDrawLabel); GlobalFunc::FilerWrite(pFiler, m_bDrawLabel); pFiler->writeItem(m_idLabelLayer); return pFiler->filerStatus(); } Acad::ErrorStatus AecXDbWell::dxfInFields(AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; es = CDbEquipment::dxfInFields(pFiler); if (es != Acad::eOk) return es; if (!pFiler->atSubclassData(_T("AecXDbWell"))) { return Acad::eBadDxfSequence; } resbuf rb; while ((es == Acad::eOk) && ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) { switch (rb.restype) { case AcDb::kDxfXTextString: m_sWellName = rb.resval.rstring; break; case AcDb::kDxfXCoord: m_ptLabel = rb.resval.rpoint; break; case AcDb::kDxfXReal: m_nWellDn = rb.resval.rreal; break; default: pFiler->pushBackItem(); es = Acad::eEndOfFile; break; } } if (es != Acad::eEndOfFile) return Acad::eInvalidResBuf; return pFiler->filerStatus(); } Acad::ErrorStatus AecXDbWell::dxfOutFields(AcDbDxfFiler* pFiler) const { Acad::ErrorStatus es = Acad::eOk; es = CDbEquipment::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass, _T("AecXDbWell")); assert(es == Acad::eOk); pFiler->writeString(AcDb::kDxfXTextString, (const TCHAR*)m_sWellName); pFiler->writePoint3d(AcDb::kDxfXCoord, m_ptLabel); pFiler->writeDouble(AcDb::kDxfXReal, m_nWellDn); // zxl 2013.12.13 取消虚显 if (GlobalFunc::IsKeyPressed(VK_ESCAPE)) { acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, true); ads_name name; acdbGetAdsName(name, GetSpaceId()); Entity ent = name; ent.Redraw(4); acDocManager->unlockDocument(curDoc()); } return es; } Acad::ErrorStatus AecXDbWell::Draw3d(AcGiDraw &dc) const { Acad::ErrorStatus es = Acad::eOk; XPoint pt1, pt2; pt1 = pt2 = m_ptLocation; if (GlobalFunc::DocGetMeterUnitDraw()) { pt1.z = m_nEleDown; pt2.z = m_nEleUp; } else { pt1.z = m_nEleDown * 1000; pt2.z = m_nEleUp * 1000; } if (fabs(m_nEleDown) > 0.01) DrawPolyMesh(pt1, pt2, GetScale() * GetPScale() / 2.0, dc); //es=CDbEquipment::ExplodeOrDraw3d(dc); return es; } Acad::ErrorStatus AecXDbWell::Draw2d(AcGiDraw &dc) const { // cet 2016.10.17 add 图层关闭时,实体不显示,不进行绘制(打印时,也不会绘制) //AcDbLayerTableRecordPointer player(this->layerId(), AcDb::kForRead); //if (player.openStatus() == Acad::eOk && player->isOff()) //{ // return Acad::eOk; //} Acad::ErrorStatus es = Acad::eOk; CDbEquipment pEquip; pEquip.SetBlock2d(m_idBlock2d); pEquip.SetLocation(m_ptLocation); pEquip.SetDirection(m_vtDirection); pEquip.SetScale(GetScale() * 100); pEquip.SetHidePipe(m_bHidePipe); pEquip.setPropertiesFrom(this); DrawBaseEx(dc, pEquip); //dc.DrawEntity(pEquip); if (m_bDrawLabel) // 绘制标注 DrawLabelText(dc); return Acad::eOk; } Acad::ErrorStatus AecXDbWell::DrawLabelText(AcGiDraw &dc) const { AcDbObjectId idLayerOld = dc.GetLayerId(); if (m_idLabelLayer.isValid()) dc.SetLayer(m_idLabelLayer); CString csDimText = (LPCTSTR)m_sWellName; if (IsShowPropertyText()) { CString csEle; csEle.Format(_T("(%.2f,%.2f)"), m_nEleUp, m_nEleDown); if (fabs(m_nEleUp) < 0.001 && fabs(m_nEleDown) < 0.001) csEle = _T("(无信息)"); csDimText += csEle; } AecXDbText text; text.setPropertiesFrom(this); text.setLayer(m_idLabelLayer); text.setColorIndex(GetTextColor()); // cet 2018.2.6 add 可修改文字颜色 text.SetStyleId(m_idTextStyle); text.SetText((const TCHAR*)csDimText); text.SetLocation(XPoint(m_ptLabel.x, m_ptLabel.y, 0)); text.SetHeight(m_dTextHeight); text.SetAlignment(AcGiDraw::kMiddleCenter); text.SetRotation(GetDimAngle()); // cet 2011.8.25 add 设置标注角度 PushProperty vProp(&text, dc); DrawBaseEx(dc, text); dc.SetLayer(idLayerOld); return Acad::eOk; } // 根据管线初始化管线标注位置 void AecXDbWell::InitLabelLocation(double nScale) { assertWriteEnabled(); double Len = GetScale() * GetPScale(); double nLenText = Len / 2 * nScale; double nAng = GlobalFunc::Ucs2Wcs(PI / 2); ads_polar(m_ptLocation, nAng, nLenText, m_ptLabel); } void AecXDbWell::GetTips(DList &info) const { info.Append(new ObjInfoUnit(_T("对象类型"), _T("室外井"))); info.Append(new ObjInfoUnit(_T("井编号"), m_sWellName)); info.Append(new ObjInfoUnit(_T("地面标高"), XString(_T("%.3f"), m_nEleUp))); info.Append(new ObjInfoUnit(_T("井底标高"), XString(_T("%.3f"), m_nEleDown))); int num = GetInterfaceNum(); info.Append(new ObjInfoUnit(_T("接管"), XString(_T("%d"), num))); for (int i = 0; i < num; i++) { CPipeInterface iFace; GetInterface(i, iFace); CString csPipeName, csLabel; csLabel = GetISysLabel(i); if (csLabel == _T("")) continue; OPENOBJ_BEGIN(iFace.m_idPipe, AcDb::kForRead, CDbPipePrototype, pPipe); if (pPipe) { csPipeName = pPipe->GetSysLabel(); } OPENOBJ_END(); csPipeName.Format(_T("%s底标高"), csPipeName); info.Append(new ObjInfoUnit((const TCHAR*)csPipeName, (const TCHAR*)csLabel)); } } //设置室外管道管底标高 void AecXDbWell::SetPipeEndEle(AcDbObjectId id, const TCHAR* szEle) { assertWriteEnabled(); int nCount = GetInterfaceNum(); for (int i = 0; i < nCount; i++) { CPipeInterface iFace; GetInterface(i, iFace); if (id == iFace.m_idPipe) { SetISysLabel(i, szEle); return; } } } double AecXDbWell::GetWidth(const CDbPipePrototype* pPipe) const { double dWidth = 0.0; // if (Is2DView()) cet 2018.1.31 del 三维下修改对象时,无法更新该值,会导致二维遮挡错误 { // 有时管道与井(尤其是圆)有交点却求交失败,先将管道投影到与xy平面上再进行操作 // 可解决一些发现的此类问题 AcDbCurve *pCurve = pPipe->GetCurve().AsAcDbCurve(); AcDbCurve *pRetCurve = NULL; if (pCurve->getProjectedCurve(AcGePlane::kXYPlane, AcGeVector3d::kZAxis, pRetCurve) == Acad::eOk) { delete pCurve; pCurve = pRetCurve; pRetCurve = NULL; } // 管道与井交点 AcGePoint3dArray arrPt; ::IntersectWith(this, pCurve, AcDb::kOnBothOperands, AcGePlane::kXYPlane, arrPt); delete pCurve; // 距离井最远的管道端点 XPoint ptS = pPipe->StartPoint(); XPoint ptE = pPipe->EndPoint(); XPoint ptLoc = m_ptLocation; XPoint pt = ptS; if (ptS.Distance2d(ptLoc) < ptE.Distance2d(ptLoc)) { pt = ptE; } // 获得交点距离pt点的最近的点 double dMinDist = -1; for (int i = 0; i < arrPt.length(); ++i) { double dDist = pt.Distance2d(arrPt[i]); if (dMinDist < 0.0 || dMinDist > dDist) { dMinDist = dDist; } } // 遮挡距离 if (dMinDist > 0.0) { dWidth = ptS.Distance2d(ptE) - dMinDist; } } return dWidth; } // 判断节点是否可以连接管段. nPos: 0--start; 1--end BOOL AecXDbWell::CanLinkSide(const AcDbObjectId &idPipe, int nPos) const { // cet 2010.8.27 add 点相等误差容许范围 double dTol = GlobalFunc::EqualPointTol(); BOOL bRet = FALSE; double nRadius = GetScale() * GetPScale(); OPENOBJ_BEGIN(idPipe, AcDb::kForRead, CDbPipePrototype, pPipe); if (pPipe) { XPoint ptRef = nPos ? pPipe->EndPoint() : pPipe->StartPoint(); XPoint ptLoc = GetLocation(); ptLoc.z = 0;// ptRef.z = 0;// if (ptRef.Distance(ptLoc) < dTol) bRet = TRUE; double nDist = ptRef.Distance(ptLoc); if (fabs(nDist - nRadius / 2) < dTol) bRet = TRUE; } OPENOBJ_END(); return bRet; } // 对st类型的接口进行重新连接 void AecXDbWell::UpdateLinkage(const XPoint &ptAt, TPipeSys::SysType st, const DList &idPipes) { assertWriteEnabled(); DList lstInterface;//先保留一份出来,目的是得到各管底标高 for (int j = 0; j < m_lstInterface.Length(); j++) { CPipeInterface& iFace = *m_lstInterface[j]; lstInterface.Append(new CPipeInterface(iFace)); } // cet 2010.8.27 add double dMeter = 1.0; if (GlobalFunc::DocGetMeterUnitDraw()) dMeter = 1000.0; RemoveInterface(st); double nRadius = GetScale() * GetPScale() * 0.8; // 适当减小半径,避免恰好在半径上的管线自动连接到插入点,以支持管道可直接连接在井边 for (int i = 0; i < idPipes.Length(); i++) { const AcDbObjectId &id = idPipes[i]; OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipe, pPipe); if (pPipe) { CPipeInterface iFace; iFace.m_sysType = st; iFace.m_faceType = CPipeInterface::kNodeLocation; for (j = 0; j < lstInterface.Length(); j++) { CPipeInterface& iFace2 = *lstInterface[j]; if (iFace2.m_idPipe == id) { iFace.m_sSysLabel = iFace2.m_sSysLabel; break; } } iFace.m_idPipe = id; XPoint ptS, ptE; ptS = pPipe->StartPoint(); ptE = pPipe->EndPoint(); ptS.z = 0; ptE.z = 0; XPoint ptLoc = m_ptLocation; ptLoc.z = 0; double nDist1 = ptLoc.Distance(ptS); double nDist2 = ptLoc.Distance(ptE); if (nDist1 < PS_SNAP / dMeter || fabs(nDist1 - nRadius / 2) < PS_SNAP / dMeter) { if (fabs(nDist1 - nRadius / 2) < PS_SNAP / dMeter) { if (pPipe->upgradeOpen() == Acad::eOk) { pPipe->SetStartPoint(m_ptLocation); pPipe->downgradeOpen(); } } iFace.m_ptLocation = pPipe->StartPoint(); AcGeVector3d vt; pPipe->getFirstDeriv(pPipe->StartPoint(), vt); iFace.m_vtLocation = vt; AddInterface(iFace); } else if (nDist2 < PS_SNAP / dMeter || fabs(nDist2 - nRadius / 2) < PS_SNAP / dMeter) { if (fabs(nDist2 - nRadius / 2) < PS_SNAP / dMeter) { if (pPipe->upgradeOpen() == Acad::eOk) { pPipe->SetEndPoint(m_ptLocation); pPipe->downgradeOpen(); } } iFace.m_ptLocation = pPipe->EndPoint(); AcGeVector3d vt; pPipe->getFirstDeriv(pPipe->EndPoint(), vt); iFace.m_vtLocation = XVector3D(-vt[0], -vt[1], -vt[2]); AddInterface(iFace); } } OPENOBJ_END(); } // lstInterface中未加到接口中,但与井实际相连的管线 for (int i = 0; i < lstInterface.Length(); ++i) { CPipeInterface& iFace1 = *lstInterface[i]; bool bFind = false; for (int j = 0; j < m_lstInterface.Length(); ++j) { CPipeInterface& iFace2 = *m_lstInterface[j]; if (iFace1.m_idPipe == iFace2.m_idPipe) { bFind = true; break; } } // 已经添加 if (bFind) { continue; } // 添加上与井实际相连的接口 OPENOBJ_BEGIN(iFace1.m_idPipe, AcDb::kForRead, CDbPipe, pPipe); if (pPipe != NULL) { if (pPipe->StartPoint().Distance2d(m_ptLocation) < 0.001 || pPipe->EndPoint().Distance2d(m_ptLocation) < 0.001) { AddInterface(iFace1); } } OPENOBJ_END(); } } // zxl 2013.06.07 add 根据管线 获取当前标注位置 XPoint AecXDbWell::GetWellDimPosByPipe(const AcDbObjectId &idPipe) { XPoint ptS, ptE, ptLoc, ptTurn; OPENOBJ_BEGIN(idPipe, AcDb::kForWrite, CDbPipe, pPipe); if (pPipe != NULL) { ptLoc = GetLocation(); downgradeOpen(); pPipe->ResetDrawSpeed(); upgradeOpen(); XCurveSegment cv; pPipe->GetHideCurve(cv); ptS = cv.GetStartPoint(); ptE = cv.GetEndPoint(); if (ptS.Distance2d(ptLoc) < ptE.Distance2d(ptLoc)) { ptLoc = ptS; } else if (ptS.Distance2d(ptLoc) > ptE.Distance2d(ptLoc)) { ptLoc = ptE; } } OPENOBJ_END(); return ptLoc; } // zxl 2013.06.07 add 实时更新单一管底标注位置 void AecXDbWell::ModifyWellDimPos(const AcDbObjectId &idPipe) { XPoint ptLoc = GetWellDimPosByPipe(idPipe); // 遍历块表记录,获取当前井的管底标注 AcDbBlockTableRecord *pRecord = NULL; AcDbBlockTable* pBlockTable = NULL; acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead); if (pBlockTable == NULL) return; if (Acad::eOk != pBlockTable->getAt(ACDB_MODEL_SPACE, pRecord, AcDb::kForRead)) { pBlockTable->close(); return; } pBlockTable->close(); AcDbBlockTableRecordIterator *pIterator = NULL; pRecord->newIterator(pIterator); pRecord->close(); AcDbEntity *pEnt = NULL; //TDbWellDim *pDim = NULL; //for (pIterator->start(); !pIterator->done(); pIterator->step()) //{ // pIterator->getEntity(pEnt, AcDb::kForRead); // if (pEnt != NULL) // { // pDim = TDbWellDim::cast(pEnt); // if (pDim != NULL && pDim->GetIsNewDim() && pDim->GetPipeId() == idPipe && pDim->GetWellId() == id()) // { // AcGeVector3d vt = ptLoc - pDim->GetStartPoint(); // if (pDim->upgradeOpen() == Acad::eOk) // { // pDim->SetStartPoint(ptLoc); // XPoint ptTurn = pDim->GetTurnPoint() + vt; // pDim->SetTurnPoint(ptTurn); // pDim->downgradeOpen(); // } // } // pEnt->close(); // } //} //delete pIterator; } //zxl 2013.07.23 add Acad::ErrorStatus AecXDbWell::subClose() { Acad::ErrorStatus es = CDbEquipment::subClose(); if (es != Acad::eOk) { return es; } // 优化速度,不更新汇流面积和井底标注,此开关在应用层设置 if (!GetUpdatable()) { SetUpdatable(TRUE); return es; } // zxl 2013.12.12 add CString sName = (LPCTSTR)m_sWellName; AcDbObjectId idSpace = GetSpaceId(); if (idSpace != NULL) { //OPENOBJ_BEGIN(idSpace, AcDb::kForWrite, TDbSpace, pSpace); //if (pSpace != NULL) //{ // if (sName.Find(_T("(")) > 0) // { // sName = sName.Left(sName.Find(_T("("))); // } // pSpace->m_sName = sName + _T("汇流面积"); //} //OPENOBJ_END(); } if (m_bIsModify && !GlobalFunc::IsTransformCmd()) { m_bIsModify = false; if (isModified() && database() == acdbCurDwg()) { int nCount = m_lstInterface.Length(); for (int i = 0; i < nCount; i++) { CPipeInterface &iFace = *m_lstInterface[i]; AcDbObjectId id = iFace.m_idPipe; ModifyWellDimPos(id); } } } return es; } Acad::ErrorStatus AecXDbWell::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/) const { return CDbEquipment::subIntersectWith(pEnt, intType, points, thisGsMarker, otherGsMarker); } Acad::ErrorStatus AecXDbWell::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/) const { if (::IntersectWith(this, pEnt, intType, projPlane, points)) { return Acad::eOk; } return CDbEquipment::subIntersectWith(pEnt, intType, projPlane, points, thisGsMarker, otherGsMarker); } void InitDbWell(BOOL bTrue) { if (bTrue) { AecXDbWell::rxInit(); //AecXDbWell::InitMatchProtocol(TRUE); } else { //AecXDbWell::InitMatchProtocol(FALSE); deleteAcRxClass(AecXDbWell::desc()); } }