#include "stdafx.h" #include "AcDbObjectPtr.h" #include "globalFunc.h" #include "globalDefine.h" #include "DbEquipment.h" #include "DbPipe.h" #include "PipePrototype.h" #include static double g_dPointToOriginLimitDist = 1e+6; void Matrix3D2String(const AcGeMatrix3d &mat, CString &str) { #if ADS <= 15 std::ostringstream stream; #else std::wostringstream stream; #endif for (int ln = 0; ln < 4; ++ln) { for (int col = 0; col < 4; ++col) { stream << mat.entry[ln][col]; #if ADS <= 15 stream << " "; #else stream << L" "; #endif } } str = stream.str().c_str(); } // cet2017.3.2 add 设备类型名 CString GetEquipmentName(const CDbEquipment *pEquip) { CString sName = _T("普通设备"); if (pEquip == NULL) { return sName; } if (pEquip->IsSprinkler()) { sName = _T("喷头"); } else if (pEquip->IsHydrant()) { sName = _T("消火栓"); } int nEquipType = pEquip->GetEquipmentType(); switch (nEquipType) { case 0: { sName = _T("消火栓"); break; } case 1: { sName = _T("喷头"); break; } case 2: { sName = _T("井"); break; } case 3: { sName = _T("水泵"); break; } case 4: { sName = _T("雨水口"); break; } case 5: { sName = _T("大小接头"); break; } default: break; } return sName; } extern CString ReadXdata(Entity ent, const TCHAR*szName); ACRX_DXF_DEFINE_MEMBERS(CDbEquipment, CDbPipeNode, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, AEC_ZT_EQUIPMENT, "AEC_ZT_EQUIPMENT图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); const Adesk::UInt8 CDbEquipment::g_nVersion = 3; CDbEquipment::CDbEquipment() : m_vtDirection(1, 0, 0), m_dScale(1.0), m_dDang(0.5), m_bHidePipe(TRUE), m_nMirror(0), m_dPipeLength(0) { m_visibility = TPipeSys::kVisible; m_dYScale = 0; m_dZScale = 0; m_bAutoScale = TRUE; } void CDbEquipment::CopyPropertiesFrom(AcDbEntity *pSrc, unsigned gMatchFlag) { assertWriteEnabled(); CDbPipeNode::CopyPropertiesFrom(pSrc, gMatchFlag); CDbEquipment *pEqu = CDbEquipment::cast(pSrc); if (pEqu) { //m_idBlock2d = pEqu->m_idBlock2d; //m_idBlock3d = pEqu->m_idBlock3d; //m_sSysBlock = pEqu->m_sSysBlock; //m_dScale = pEqu->m_dScale; m_bHidePipe = pEqu->m_bHidePipe; //m_nMirror = pEqu->m_nMirror; //m_dPipeLength = pEqu->m_dPipeLength; //m_dDang = pEqu->m_dDang; } } //Acad::ErrorStatus CDbEquipment::subGetClassID(CLSID* pClsid) const //{ // return Acad::eOk; //} Acad::ErrorStatus CDbEquipment::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_ptInsert); snapPoints.append(m_ptLocation); } es = CDbPipeNode::subGetOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds); return es; } // 从DWG读入数据: Acad::ErrorStatus CDbEquipment::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = CDbPipeNode::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_idBlock2d); pFiler->readItem(&m_idBlock3d); GlobalFunc::ReadString(pFiler, m_sSysBlock); pFiler->readItem((AcGePoint3d *)&m_ptLocation); pFiler->readItem((AcGePoint3d *)&m_ptInsert); pFiler->readItem((AcGeVector3d *)&m_vtDirection); pFiler->readItem(&m_dScale); //pFiler->readItem(&m_bHidePipe); GlobalFunc::FilerRead(pFiler, m_bHidePipe); pFiler->readItem(&m_nMirror); pFiler->readItem(&m_dPipeLength); pFiler->readItem(&m_dDang); if (nVer > 1) { pFiler->readItem(&m_dCircleRadius); pFiler->readItem(&m_dYScale); pFiler->readItem(&m_dZScale); pFiler->readItem(&m_dSpare); if (nVer > 2) { //pFiler->readItem(&m_bAutoScale); GlobalFunc::FilerRead(pFiler, m_bAutoScale); } } return pFiler->filerStatus(); } Acad::ErrorStatus CDbEquipment::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = CDbPipeNode::dwgOutFields(pFiler); if (es != Acad::eOk) return es; pFiler->writeItem(g_nVersion); pFiler->writeItem(m_idBlock2d); pFiler->writeItem(m_idBlock3d); pFiler->writeItem((const TCHAR *)m_sSysBlock); pFiler->writeItem((const AcGePoint3d &)m_ptLocation); pFiler->writeItem((const AcGePoint3d &)m_ptInsert); pFiler->writeItem((const AcGeVector3d &)m_vtDirection); pFiler->writeItem(m_dScale); //pFiler->writeItem(m_bHidePipe); GlobalFunc::FilerWrite(pFiler, m_bHidePipe); pFiler->writeItem(m_nMirror); pFiler->writeItem(m_dPipeLength); pFiler->writeItem(m_dDang); pFiler->writeItem(m_dCircleRadius); pFiler->writeItem(m_dYScale); pFiler->writeItem(m_dZScale); pFiler->writeItem(m_dSpare); GlobalFunc::FilerWrite(pFiler, m_bAutoScale); return pFiler->filerStatus(); } Acad::ErrorStatus CDbEquipment::dxfInFields(AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; es = CDbPipeNode::dxfInFields(pFiler); if (es != Acad::eOk) return es; if (!pFiler->atSubclassData(_T("CDbEquipment"))) { return Acad::eBadDxfSequence; } resbuf rb; while ((es == Acad::eOk) && ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) { switch (rb.restype) { case AcDb::kDxfXCoord: m_ptLocation = rb.resval.rpoint; break; case AcDb::kDxfXReal: m_dScale = rb.resval.rreal; break; case AcDb::kDxfBlockName: break; default: pFiler->pushBackItem(); es = Acad::eEndOfFile; break; } } if (es != Acad::eEndOfFile) return Acad::eInvalidResBuf; return pFiler->filerStatus(); } Acad::ErrorStatus CDbEquipment::dxfOutFields(AcDbDxfFiler* pFiler) const { Acad::ErrorStatus es = Acad::eOk; es = CDbPipeNode::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass, _T("CDbEquipment")); assert(es == Acad::eOk); pFiler->writePoint3d(AcDb::kDxfXCoord, m_ptLocation); pFiler->writeDouble(AcDb::kDxfXReal, m_dScale); CString sBlkName, sDesName; GlobalFunc::GetBlkNameById(m_idBlock2d, sBlkName, sDesName); pFiler->writeString(AcDb::kDxfBlockName, (const TCHAR*)sBlkName); // cet 2017.3.2 add 添加设备类型名,用于识别设备 CString sName = GetEquipmentName(this); pFiler->writeString(AcDb::kDxfXTextString, (const TCHAR*)sName); return es; } // 图块插入比例 AcGeScale3d CDbEquipment::GetInsertScale() const { assertReadEnabled(); double dScale(1), dScaleY(1), dScaleZ(1); if (m_bAutoScale) { dScale = m_dScale * GetPScale() / 100; dScaleY = m_dYScale * GetPScale() / 100; dScaleZ = m_dZScale * GetPScale() / 100; } else { dScale = m_dScale; dScaleY = m_dYScale; dScaleZ = m_dZScale; } if (fabs(dScaleY) < 0.001) dScaleY = dScale; if (fabs(dScaleZ) < 0.001) dScaleZ = dScale; AcGeScale3d scale(dScale, dScaleY, fabs(dScaleZ)); if (IsMirrorByY()) scale.sx *= -1; if (IsMirrorByX()) scale.sy *= -1; return scale; } Acad::ErrorStatus CDbEquipment::Draw2d(AcGiDraw &dc) const { if (Has2DBuffer()) { Draw2DBuffers(dc); return Acad::eOk; } // cet 2016.10.17 add 图层关闭时,实体不显示,不进行绘制(打印时,也不会绘制) //AcDbLayerTableRecordPointer player(this->layerId(), AcDb::kForRead); //if (player.openStatus() == Acad::eOk && player->isOff()) //{ // return Acad::eOk; //} return _ExplodeOrDraw2d(dc); } Acad::ErrorStatus CDbEquipment::_ExplodeOrDraw2d(AcGiDraw &dc, BOOL bZEqual0) const { if (!m_idBlock2d.isValid()) return Acad::eInvalidInput; if (fabs(m_vtDirection.x) < 1.0E-6 && fabs(m_vtDirection.y) < 1.0E-6) return Acad::eOk; //垂直设备 XPoint ptInsert = m_ptInsert; if (bZEqual0) ptInsert.z = 0; double dAngle = ads_angle(XPoint(), m_vtDirection); DrawBlock(dc, m_idBlock2d, m_ptInsert, GetInsertScale(), dAngle); OPENOBJ_BEGIN(m_idBlock2d, AcDb::kForRead, AcDbBlockTableRecord, pBlock); if (pBlock) { // BOOL bNewMethod=(g_nAcadVer>15.0001 && g_bMakeBlock); // sg add 091105,强制打印时,不使用新方法 // if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration()) // bNewMethod = FALSE; //2011-9-30 SBdc.DrawBlock(*pBlock,ptInsert,GetInsertScale(),dAngle,TRUE); 采用旧方法,从8.0版本开始,TRUE参数对于打印不起作用。关闭图层,仍然打印 //dc.DrawBlock(*pBlock,ptInsert,GetInsertScale(),dAngle,bNewMethod); //dc.DrawBlock(*pBlock, ptInsert, GetInsertScale(), dAngle, TRUE); } OPENOBJ_END(); return Acad::eOk; } Acad::ErrorStatus CDbEquipment::Draw3d(AcGiDraw &dc) const { if (!m_idBlock3d.isValid()) return _ExplodeOrDraw2d(dc, FALSE); OPENOBJ_BEGIN(m_idBlock3d, AcDb::kForRead, AcDbBlockTableRecord, pBlock); if (pBlock) { XVector3D vtNormal(0, 0, 1); if (fabs(m_vtDirection.z) > 1.0E-6) { //非水平面,计算法向 vtNormal = GlobalFunc::operator*(XVector3D(1, 0, 0) ,m_vtDirection); //vtNormal = XVector3D(1, 0, 0) * m_vtDirection; vtNormal.Normalize(); } //XPoint ptLoc=GlobalFunc::Wcs2Ecs(m_ptLocation, vtNormal); cet 2011.12.29 modify XPoint ptInsert = m_ptInsert; ptInsert.z = m_ptLocation.z; XPoint ptLoc = GlobalFunc::Wcs2Ecs(ptInsert, vtNormal); if (IsUpLinkHydrant()) // 上接消火栓补充一段管线 { ExplodeOrDrawPipe3d(dc); } double nRotEcs = ads_angle(XPoint(), m_vtDirection); //计算ECS下的转角 AcDbBlockReference insert(ptLoc, m_idBlock3d); insert.setRotation(nRotEcs); insert.setScaleFactors(GetInsertScale()); //if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor()) == 0) { AcGeMatrix3d mat = insert.blockTransform(); AcGiGeometry *geom = ((AcGiViewDraw &)dc).GetCommonDraw()->rawGeometry(); geom->pushModelTransform(mat); geom->draw(pBlock); geom->popModelTransform(); //} //else if (_tcscmp(dc.Desc(), XExplodeStream::Descriptor()) == 0) { // ((XExplodeStream &)dc).Append((AcDbEntity *)insert.clone()); //} } else { return Acad::eInvalidInput; } OPENOBJ_END(); return Acad::eOk; } Acad::ErrorStatus CDbEquipment::ExplodeOrDrawPipe3d(AcGiDraw &dc) const { // 获得连接管的id int nNum = GetInterfaceNum(); CPipeInterface face; AcDbObjectId idPipe; for (int i = 0; i < nNum; i++) { GetInterface(i, face); idPipe = face.m_idPipe; break; } OPENOBJ_BEGIN(idPipe, AcDb::kForRead, CDbPipe, pPipe); if (pPipe != NULL) { // 获得管道起点终点 XVector3D vtNormal(0, 0, 1); if (fabs(m_vtDirection.z) > 1.0E-6) //非水平面,计算法向 { vtNormal = GlobalFunc::operator*(XVector3D(1, 0, 0) ,m_vtDirection); //vtNormal = XVector3D(1, 0, 0) * m_vtDirection; vtNormal.Normalize(); } XPoint ptInsert = m_ptInsert; ptInsert.z = m_ptLocation.z; XPoint pt1 = GlobalFunc::Wcs2Ecs(ptInsert, vtNormal); XLine line(pPipe->StartPoint(), pPipe->EndPoint()); XPoint pt2 = GlobalFunc::Wcs2Ecs(m_ptLocation, vtNormal); m_ptLocation.Project(&line, pt2); CDbPipe *pNewPipe = (CDbPipe *)pPipe->clone(); pNewPipe->SetStartPoint(pt1); pNewPipe->SetEndPoint(pt2); pNewPipe->SetNode(0, AcDbObjectId::kNull); pNewPipe->SetNode(1, AcDbObjectId::kNull); Adesk::UInt16 color = dc.GetColor(); dc.SetColor(1); DrawBaseEx(dc, *pNewPipe); //pNewPipe->Draw3d(dc); dc.SetColor(color); } OPENOBJ_END(); return Acad::eOk; } void CDbEquipment::GetTips(DList &info) const { info.Append(new ObjInfoUnit(_T("对象类型"), _T("设备"))); CString sBlkName, sDesName; if (GlobalFunc::GetBlkNameById(m_idBlock2d, sBlkName, sDesName) && !sDesName.IsEmpty()) { info.Append(new ObjInfoUnit(_T("对象名称"), (const TCHAR*)sDesName)); } // if(sDesName.Find(_T("井")) > -1){ //检查井 // info.Append(new ObjInfoUnit(_T("井编号"), m_sSysBlock)); // info.Append(new ObjInfoUnit(_T("地面标高"), XString(_T("%.3f"), m_dDang))); // info.Append(new ObjInfoUnit(_T("井底标高"), XString("%.3f", m_dPipeLength))); // int num = GetInterfaceNum(); // for(int i=0;iGetSysLabel(); // } // OPENOBJ_END(); // csPipeName.Format("%s底标高", csPipeName); // info.Append(new ObjInfoUnit((const char*)csPipeName, csLabel)); // } // } // else info.Append(new ObjInfoUnit(_T("当量值"), GlobalFunc::Dist2Str(m_dDang))); } Acad::ErrorStatus CDbEquipment::GetGripText(int idx, CString &cs) const { Acad::ErrorStatus es = Acad::eOk; switch (idx) { case 0: cs = _T("移动设备"); break; case 1: cs = _T("移动基点"); break; case 2: cs = _T("改变消火栓开启方向"); break; // cet 2016.8.3 add default: es = Acad::eInvalidInput; } return es; } Acad::ErrorStatus CDbEquipment::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); Acad::ErrorStatus es = Acad::eOk; gripPoints.append((AcGePoint3d)m_ptInsert); gripPoints.append((AcGePoint3d)m_ptLocation); // cet 2016.8.3 add 增加消火栓右侧夹点,用于实现调整消火栓开启方向 if (m_idBlock2d.isValid() && IsHydrant()) { double dWidth = GetInsertScale().sx; double dHeight = GetInsertScale().sy; double dAngle = ads_angle(XPoint(), m_vtDirection); AcGeVector3d vtX = AcGeVector3d::kXAxis * dWidth * 0.5 + AcGeVector3d::kYAxis * dHeight * 0.55; AcGePoint3d pt = m_ptLocation + vtX.rotateBy(dAngle, AcGeVector3d::kZAxis); gripPoints.append(pt); } return es; } Acad::ErrorStatus CDbEquipment::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const { assertReadEnabled(); stretchPoints.append((AcGePoint3d)m_ptInsert); stretchPoints.append((AcGePoint3d)m_ptLocation); return Acad::eOk; } Acad::ErrorStatus CDbEquipment::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; // cet 2016.8.3 add 消火栓夹点,实现调整方向 if (indices.length() == 1 && indices[0] == 2) { // 移动前所在象限 double dWidth = GetInsertScale().sx; double dHeight = GetInsertScale().sy; double dAngleBeforeMove = AcGeVector3d::kXAxis.angleTo(AcGeVector3d::kXAxis * dWidth * 0.5 + AcGeVector3d::kYAxis * dHeight * 0.55, AcGeVector3d::kZAxis); int nDirBeforMove = -1; if (fabs(dAngleBeforeMove - PI * 2) < 0.001) { dAngleBeforeMove = 0.0; } if (dAngleBeforeMove > 0.0 + 0.001 && dAngleBeforeMove + 0.001 < PI * 0.5) // (0, 90) { nDirBeforMove = 0; } else if (dAngleBeforeMove > PI * 0.5 + 0.001 && dAngleBeforeMove + 0.001 < PI) // (90, 180) { nDirBeforMove = 1; } else if (dAngleBeforeMove > PI + 0.001 && dAngleBeforeMove + 0.001 < PI * 1.5) // (180, 270) { nDirBeforMove = 2; } else if (dAngleBeforeMove > PI * 1.5 + 0.001 && dAngleBeforeMove + 0.001 < PI * 2) // (270, 360) { nDirBeforMove = 3; } // 移动后点所在象限 AcGeVector3d vtX = AcGeVector3d::kXAxis * dWidth * 0.5 + AcGeVector3d::kYAxis * dHeight * 0.55; double dAngle = ads_angle(XPoint(), m_vtDirection); vtX.rotateBy(dAngle, AcGeVector3d::kZAxis); AcGeVector3d ptMove = m_ptLocation + vtX + offset; AcGeVector3d vtTemp = ptMove - m_ptLocation.AsAcGePoint3d(); vtTemp.z = 0.0; vtX = AcGeVector3d::kXAxis; vtX.rotateBy(dAngle, AcGeVector3d::kZAxis); double dAngleAfterMove = vtX.angleTo(vtTemp, AcGeVector3d::kZAxis); if (fabs(dAngleAfterMove - PI * 2) < 0.001) { dAngleAfterMove = 0.0; } int nDirAfterMove = -1; if (dAngleAfterMove > 0.0 + 0.001 && dAngleAfterMove + 0.001 < PI * 0.5) // (0, 90) { nDirAfterMove = 0; } else if (dAngleAfterMove > PI * 0.5 + 0.001 && dAngleAfterMove + 0.001 < PI) // (90, 180) { nDirAfterMove = 1; } else if (dAngleAfterMove > PI + 0.001 && dAngleAfterMove + 0.001 < PI * 1.5) // (180, 270) { nDirAfterMove = 2; } else if (dAngleAfterMove > PI * 1.5 + 0.001 && dAngleAfterMove + 0.001 < PI * 2) // (270, 360) { nDirAfterMove = 3; } // 根据象限变化调整方向 if (nDirAfterMove == nDirBeforMove || nDirBeforMove == -1 || nDirAfterMove == -1) { return es; } if (nDirBeforMove == 0 && nDirAfterMove == 3 || nDirBeforMove == 1 && nDirAfterMove == 2 || nDirBeforMove == 2 && nDirAfterMove == 1 || nDirBeforMove == 3 && nDirAfterMove == 0) // x轴镜像 { MirrorByX(IsMirrorByX() ? FALSE : TRUE); } else if (nDirBeforMove == 0 && nDirAfterMove == 1 || nDirBeforMove == 1 && nDirAfterMove == 0 || nDirBeforMove == 2 && nDirAfterMove == 3 || nDirBeforMove == 3 && nDirAfterMove == 2) // y轴镜像 { MirrorByY(IsMirrorByY() ? FALSE : TRUE); } else { MirrorByY(IsMirrorByY() ? FALSE : TRUE); MirrorByX(IsMirrorByX() ? FALSE : TRUE); } return es; } es = MoveGSPointsAt(indices, offset); return es; } Acad::ErrorStatus CDbEquipment::subMoveStretchPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; es = MoveGSPointsAt(indices, offset); return es; } Acad::ErrorStatus CDbEquipment::MoveGSPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { Acad::ErrorStatus es = Acad::eOk; XPoint vtOffset; (AcGeVector3d &)vtOffset = offset; vtOffset.z = 0; m_ptInsert += vtOffset; m_ptLocation += vtOffset; return es; // SR 2010-6-17 修改 拉伸不考虑z坐标 /////////////////////////////////////////////////////////////////////////////// // Acad::ErrorStatus es=Acad::eOk; // AcGeMatrix3d mat; // mat.setToTranslation(offset); // // if(m_ptLocation==m_ptInsert) { // m_ptInsert.TransformBy(mat); // m_ptLocation.TransformBy(mat); // } // else { // for (int i=0; ilayer(); // if(_tcsicmp(layer, LAY_EQUIP_HYDRANT) == 0) // 2009-7-30 SR 取消消火栓限制,其他附件也可以左右翻转了(忘记当初为什么要做这样的限制了) MirrorByY(!IsMirrorByY()); //消火栓镜像稍微麻烦点 // delete []layer; ((AcGeVector3d &)m_vtDirection).transformBy(xform); double dAng = ads_angle(XPoint(),m_vtDirection); dAng = dAng - PI; SetAngle(fabs(dAng)); return Acad::eOk; } ((AcGeVector3d &)m_vtDirection).transformBy(xform); */ ((AcGeVector3d &)m_vtDirection).transformBy(xform); if (GlobalFunc::IsMirrorMatrix(xform)) { MirrorByX(!IsMirrorByX()); } double dScale = xform.scale(); if (fabs(dScale - 1) > 1.0E-5 && fabs(dScale) > 1.0E-5) { // cet 2010.8.27 modify 将1.0E-3 改为 1.0E-5 m_dScale *= dScale; m_dYScale *= dScale; // 2009-8-3 增加Y,Z 不然用SC变比例,没有变Y,Z方向的比例 m_dZScale *= dScale; } return Acad::eOk; } void CDbEquipment::MirrorByX(BOOL bFlag) { assertWriteEnabled(); if (bFlag) m_nMirror |= MIRROR_XAXIS; else m_nMirror &= ~MIRROR_XAXIS; } void CDbEquipment::MirrorByY(BOOL bFlag) { assertWriteEnabled(); if (bFlag) m_nMirror |= MIRROR_YAXIS; else m_nMirror &= ~MIRROR_YAXIS; } Acad::ErrorStatus CDbEquipment::GetExtents(XPoint &ptLow, XPoint &ptUp) const { Acad::ErrorStatus es = Acad::eOk; es = CDbPipeNode::GetExtents(ptLow, ptUp); if (es == Acad::eOk) { if (ptLow == XPoint() && ptUp == XPoint()) { ptLow = m_ptLocation; ptUp = m_ptLocation; } else { ptLow = Min(ptLow, m_ptLocation); ptUp = Max(ptUp, m_ptLocation); } } return es; } // 判断节点是否可以连接管段. nPos: 0--start; 1--end BOOL CDbEquipment::CanLinkSide(const AcDbObjectId &idPipe, int nPos) const { BOOL bRet = FALSE; // cet 2016.6.7 modify 自定义实体中不再直接使用图层宏 // // zxl 2014.01.09 add 雨水口特殊处理 // CString sLayer = layer(); // if (sLayer.Compare(LAY_TWT_GULLY) == 0) if (GetEquipmentType() == 4) { double dMeter = 1.0; if (GlobalFunc::DocGetMeterUnitDraw()) dMeter = 1000.0; 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) < PS_SNAP / dMeter) bRet = TRUE; double nDist = ptRef.Distance(ptLoc); if (fabs(nDist - nRadius / 2) < PS_SNAP / dMeter) bRet = TRUE; } OPENOBJ_END(); return bRet; } OPENOBJ_BEGIN(idPipe, AcDb::kForRead, CDbPipePrototype, pPipe); if (pPipe) { const XPoint &ptRef = nPos ? pPipe->EndPoint() : pPipe->StartPoint(); XPoint ptLoc = GetLocation(); if (ptRef.Distance(ptLoc) < PS_SNAP) bRet = TRUE; } OPENOBJ_END(); return bRet; } //XRectAngle.Intersection 函数有缺陷,无法求交坐标过大的情况 int IntersectionRect2Line(XRectAngle &rect, XLine &line, XPoint &ptInter) { AcGeLineSeg2d ln1(line.StartPoint().AsAcGePoint2d(), line.EndPoint().AsAcGePoint2d()); XPoint lowRight(rect.upRight.x, rect.lowLeft.y, rect.upRight.z), upLeft(rect.lowLeft.x, rect.upRight.y, rect.upRight.z); XLine line1(rect.lowLeft, lowRight, LS_FINITE), line2(lowRight, rect.upRight, LS_FINITE), line3(rect.upRight, upLeft, LS_FINITE), line4(upLeft, rect.lowLeft, LS_FINITE); int intersNum = 0; XPoint intPt; XLine *ptr[4] = { &line1, &line2, &line3, &line4 }; for (int i = 0; i < 4; i++) { XPoint p1 = ptr[i]->StartPoint(); XPoint p2 = ptr[i]->EndPoint(); AcGeLineSeg2d ln2(p1.AsAcGePoint2d(), p2.AsAcGePoint2d()); if (ln1.intersectWith(ln2, ptInter)) return 1; } return intersNum; } double CDbEquipment::GetWidth(const CDbPipePrototype* pPipe) const { //待考虑三维图块... double dWidth = 0; // cet 2014.5.6 del 管线被设备遮挡的长度,通过炸开二维图块与管线求交获得 // CString csNumber = GetNumber(); // // if(csNumber.Find(_T("CIRCLE")) >= 0 && IsHidePipe()){//如果是圆设备,返回圆半径×比例 // csNumber = csNumber.Right(csNumber.GetLength() - 7); // dWidth = _tstof(csNumber)*GetScale(); // return dWidth*GetPScale()/100; // } if (m_idBlock2d.isValid()) {// 二维图块 AcDbExtents extents; AcDbBlockReference insert(AcGePoint3d(0, 0, 0), m_idBlock2d); double dScaleX(0), dScaleY(0); if (m_bAutoScale) { dScaleX = m_dScale * GetPScale() / 100; dScaleY = m_dYScale * GetPScale() / 100; } else { dScaleX = m_dScale; dScaleY = m_dYScale; } if (fabs(dScaleY) < 0.001) dScaleY = dScaleX; if (IsMirrorByY()) dScaleX = -dScaleX; if (IsMirrorByX()) dScaleY = -dScaleY; insert.setScaleFactors(AcGeScale3d(dScaleX, dScaleY, fabs(dScaleX))); // cet 2014.5.6 modify 使用外包框算法,结果有时不准备, 改为炸开实体求交 (未考虑图块嵌套情况) // if(insert.geomExtentsBestFit(extents)==Acad::eOk) { // XPoint ptMax = extents.maxPoint(); // XPoint ptMin = extents.minPoint(); // // dWidth = (ptMax.x-ptMin.x)/2;// 第一次求得的宽度值 // // if(pPipe!=NULL && pPipe->Is(CURVE_LINE)) { // 仅考虑直线管段 // XPoint ptPosition = insert.position(); // XPoint ptPlus = m_ptInsert-ptPosition; // // XPoint ptLocation=m_ptLocation; // XRectAngle rect(ptMin+ptPlus,ptMax+ptPlus); // XLine line=(XLine)*pPipe; // // double dAngle=CT_std_angle(ads_angle(XPoint(),m_vtDirection)); // if(fabs(dAngle)>1.0E-6) { // ads_matrix mat; // m_ptInsert.GetRotationMatrix(-dAngle,mat); // line.TransformBy(mat); // ptLocation.TransformBy(mat); // } // rect.SetElevation(0); // line.SetElevation(0); // ptLocation.z=0; // // int nFlag = ptLocation▭ // if(nFlag != PR_INSIDE) { // dWidth = 0; // } else { // XPoint ptIntersect; // if(IntersectionRect2Line(rect,line,ptIntersect)){ // dWidth=ptLocation.Distance(ptIntersect); // } // // if(rect.Intersection(line,ptIntersect)){//sr remove it 2007-5-9 XRectAngle.Intersection 函数有缺陷,无法求交坐标过大的情况 // // dWidth=ptLocation.Distance(ptIntersect); // // } // } // } // } insert.setPosition(m_ptInsert); double dAngle = ads_angle(XPoint(), m_vtDirection); insert.setRotation(dAngle); GeCurveSegment curve = pPipe->GetCurve(); curve.SetElevation(0.0); AcDbCurve *pPipeCurve = curve.AsAcDbCurve(); // cet 2017.3.8 add 距离原点过远时,移动到原点附近计算,防止计算出错 AcGeMatrix3d mat = AcGeMatrix3d::kIdentity; if (m_ptInsert.Distance(XPoint()) > g_dPointToOriginLimitDist) { XPoint ptTemp = m_ptInsert; ptTemp.z = 0.0; mat.setToTranslation(-ptTemp.AsAcGeVector3d()); insert.transformBy(mat); pPipeCurve->transformBy(mat); } AcDbVoidPtrArray arrEnt; AcGePoint3dArray arrIntPt, arrPoint; AcGePoint3d pt1, pt2; if (insert.explode(arrEnt) == Acad::eOk) { for (int j = 0; j < arrEnt.length(); ++j) { AcDbEntity *pEnt = (AcDbEntity*)(arrEnt[j]); if (pEnt == NULL) { continue; } AcDbCurve *pCurve = AcDbCurve::cast(pEnt); if (pCurve == NULL) { continue; } Acad::ErrorStatus st = pPipeCurve->intersectWith(pCurve, AcDb::kOnBothOperands, AcGePlane::kXYPlane, arrIntPt); for (int i = 0; i < arrIntPt.length(); ++i) { arrPoint.append(arrIntPt[i]); } arrIntPt.setLogicalLength(0); } GlobalFunc::ReleaseEntSet(arrEnt); } delete pPipeCurve; pPipeCurve = NULL; // 设备插入点在管线一端,找到与设备重合的管线端点,求出距该点最用的交点距离 XPoint ptS = pPipe->GetStartPoint(); XPoint ptE = pPipe->GetEndPoint(); AcGePoint3d pt = ptS; if (ptS.Distance2d(m_ptInsert) > ptE.Distance2d(m_ptInsert)) { pt = ptE; } pt.transformBy(mat); // cet 2017.3.8 add 考虑距离原点过远情况,移动到原点附近计算 pt.z = 0.0; for (int k = 0; k < arrPoint.length(); ++k) { double dDist = pt.distanceTo(arrPoint[k]); if (k == 0 || dWidth < dDist) { dWidth = dDist; } } } return dWidth; } // 对st类型的接口进行重新连接 void CDbEquipment::UpdateLinkage(const XPoint &ptAt, TPipeSys::SysType st, const DList &idPipes) { assertWriteEnabled(); m_ptLocation = ptAt; // cet 2016.6.7 modify 自定义实体中不再直接使用图层宏 // // zxl 2014.01.09 add 雨水口特殊处理 // CString sLayer = layer(); // if (sLayer.Compare(LAY_TWT_GULLY) == 0) if (GetEquipmentType() == 4) { DList lstInterface;//先保留一份出来,目的是得到各管底标高 for (int j = 0; j < m_lstInterface.Length(); j++) { CPipeInterface& iFace = *m_lstInterface[j]; lstInterface.Append(new CPipeInterface(iFace)); } double dMeter = 1.0; if (GlobalFunc::DocGetMeterUnitDraw()) dMeter = 1000.0; RemoveInterface(st); double nRadius = GetScale() * GetPScale(); 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(); } return; } CDbPipeNode::UpdateLinkage(ptAt, st, idPipes); /*RemoveInterface(st); for(int i=0; iGetSysLabel(); iFace.m_idPipe = id; if(m_ptLocation.Distance(pPipe->StartPoint())StartPoint(); AcGeVector3d vt; pPipe->getFirstDeriv(pPipe->StartPoint(), vt); iFace.m_vtLocation = vt; AddInterface(iFace); } else if(m_ptLocation.Distance(pPipe->EndPoint())EndPoint(); AcGeVector3d vt; pPipe->getFirstDeriv(pPipe->EndPoint(), vt); iFace.m_vtLocation = XVector3D(-vt[0], -vt[1], -vt[2]); AddInterface(iFace); } } OPENOBJ_END(); }*/ } // 2008-2-27 SB add 支持系统图块与不相关但位置贴近的管线,进行裁剪 Acad::ErrorStatus CDbEquipment::GetClipBoundary(XPoly2D& poly)const { if (m_idBlock2d.isValid() && IsHidePipe()) {// 二维图块 AcDbExtents extents; // AcDbBlockReference insert(m_ptLocation, m_idBlock2d); // double dScaleX(0), dScaleY(0); // dScaleX = m_dScale*GetPScale()/100; // dScaleY = m_dYScale*GetPScale()/100; // if(fabs(dScaleY) < 0.001) // dScaleY = dScaleX; // // if(IsMirrorByY()) // dScaleX = -dScaleX; // if(IsMirrorByX()) // dScaleY = -dScaleY; // insert.setScaleFactors(AcGeScale3d(dScaleX, dScaleY, fabs(dScaleX))); // if(insert.geomExtentsBestFit(extents)==Acad::eOk) { if (getGeomExtents(extents) == Acad::eOk) { XPoint ptMax = extents.maxPoint(); XPoint ptMin = extents.minPoint(); ptMax.z = 0; ptMin.z = 0; XRectAngle rect(ptMin, ptMax); rect.AsPoly2D(poly); poly.SetFlag(1); //poly.Make(); return Acad::eOk; } } return Acad::eInvalidInput; } BOOL CDbEquipment::IsSprinkler() const { // cet 2014.12.2 add 根据设备类型判断是否为喷头 if (GetEquipmentType() == 1) { return TRUE; } XString xsTmp1 = _T("$twtsys$00000125"); XString xsTmp2 = _T("$twtsys$00000128"); XString xsTmp3 = _T("$twtsys$00000129"); XString xsTmp4 = _T("$twtsys$00000131"); // XString xsTmp5 = _T("$twtsys$00000283"); //系统喷头 // XString xsTmp6 = _T("$twtsys$00000126"); //系统喷头 // XString xsTmp7 = _T("$twtsys$00000130"); //系统喷头 AcDbObjectId idBlk = GetBlock2d(); const TCHAR *szBlkName = NULL; OPENOBJ_BEGIN(idBlk, AcDb::kForRead, AcDbBlockTableRecord, pRecord); if (pRecord) { pRecord->getName(szBlkName); } OPENOBJ_END(); // cet 2012.6.26 modify 将块名改为小写 CString sBlkName = szBlkName; sBlkName.MakeLower(); if (_tcsicmp(sBlkName, xsTmp2) == 0 || _tcsicmp(sBlkName, xsTmp1) == 0 || _tcsicmp(sBlkName, xsTmp4) == 0 || _tcsicmp(sBlkName, xsTmp3) == 0) //是喷头 return TRUE; else return FALSE; } BOOL CDbEquipment::IsHydrant() const { // cet 2014.12.2 add 根据设备类型判断是否为消火栓 if (GetEquipmentType() == 0) { return TRUE; } XString xsTmp1 = _T("$twtsys$00000434"); XString xsTmp2 = _T("$twtsys$00000435"); XString xsTmp3 = _T("$twtsys$00000485"); XString xsTmp4 = _T("$twtsys$00000487"); XString xsTmp5 = _T("$twtsys$00000508"); XString xsTmp6 = _T("$twtsys$00000509"); const TCHAR *szBlkName = NULL; AcDbObjectId idBlk = GetBlock2d(); OPENOBJ_BEGIN(idBlk, AcDb::kForRead, AcDbBlockTableRecord, pRecord); if (pRecord) { pRecord->getName(szBlkName); } OPENOBJ_END(); // cet 2012.6.26 modify 将块名改为小写 CString sBlkName = szBlkName; sBlkName.MakeLower(); if (_tcsicmp(sBlkName, xsTmp2) == 0 || _tcsicmp(sBlkName, xsTmp1) == 0 || _tcsicmp(sBlkName, xsTmp3) == 0 || _tcsicmp(sBlkName, xsTmp4) == 0 || _tcsicmp(sBlkName, xsTmp5) == 0 || _tcsicmp(sBlkName, xsTmp6) == 0) return TRUE; else return FALSE; } BOOL CDbEquipment::IsUpLinkHydrant() const { XString xsTmp1 = _T("$twtsys$00000441"); const TCHAR *szBlkName = NULL; AcDbObjectId idBlk = GetBlock3d(); OPENOBJ_BEGIN(idBlk, AcDb::kForRead, AcDbBlockTableRecord, pRecord); if (pRecord) { pRecord->getName(szBlkName); } OPENOBJ_END(); // cet 2012.6.26 modify 将块名改为小写 CString sBlkName = szBlkName; sBlkName.MakeLower(); if (_tcsicmp(sBlkName, xsTmp1) == 0) return TRUE; else return FALSE; } void InitDbEquipment(BOOL bTrue) { if (bTrue) { CDbEquipment::rxInit(); //CDbEquipment::InitMatchProtocol(TRUE); } else { //CDbEquipment::InitMatchProtocol(FALSE); deleteAcRxClass(CDbEquipment::desc()); } } void CDbEquipment::SetEquipmentType(int nType) { assertWriteEnabled(); EntityFields &fd = Fields(); fd.SFD(_T("EquipmentType"), static_cast(nType)); } void CDbEquipment::SetEquipmentType(EquipType nType) { SetEquipmentType(static_cast(nType)); } int CDbEquipment::GetEquipmentType() const { const EntityFields &fd = GetFields(); Adesk::Int8 nType = -1; fd.GFD(_T("EquipmentType"), nType); return static_cast(nType); }